Skip to content

Commit

Permalink
Corrects an issue where adding species would not return a IPopulationSet
Browse files Browse the repository at this point in the history
- Changes the spatial queries model into an interactive one
- Fixes sub-issue in #3153
  • Loading branch information
AlexisDrogoul committed Aug 16, 2021
1 parent dc1c643 commit 95689dc
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 45 deletions.
Expand Up @@ -66,25 +66,12 @@ public void remove(final Envelope3D previous, final IAgent agent) {
ISpatialIndex index = spatialIndexes.getIfPresent(agent.getPopulation());
if (index != null) { index.remove(previous, agent); }
}
//
// @Override
// public boolean removeOrUpdate(final Envelope3D previous, final Envelope3D current, final IAgent agent) {
// if (disposed || agent == null) return false;
// ISpatialIndex index = spatialIndexes.getIfPresent(agent.getPopulation());
// if (index != null) return index.removeOrUpdate(previous, current, agent);
// return false;
// }

@Override
public IAgent firstAtDistance(final IScope scope, final IShape source, final double dist, final IAgentFilter f) {
if (disposed) return null;
ISpatialIndex index = add(scope, f);
if (index != null) {
for (final double step : steps) {
IAgent first = index.firstAtDistance(scope, source, step, f);
if (first != null) return first;
}
} else {
if (index == null) {
try (final Collector.AsList<IAgent> shapes = Collector.getList()) {
for (final double step : steps) {
for (final ISpatialIndex si : spatialIndexes.asMap().values()) {
Expand All @@ -109,6 +96,10 @@ public IAgent firstAtDistance(final IScope scope, final IShape source, final dou
return min_agent;
}
}
for (final double step : steps) {
IAgent first = index.firstAtDistance(scope, source, step, f);
if (first != null) return first;
}
return null;
}

Expand Down Expand Up @@ -151,10 +142,8 @@ public Collection<IAgent> firstAtDistance(final IScope scope, final IShape sourc
final IAgentFilter f, final int number, final Collection<IAgent> alreadyChosen) {
if (disposed) return null;
ISpatialIndex index = add(scope, f);
if (index != null)
return nFirstAtDistanceInSpatialIndex(scope, source, f, number, alreadyChosen, index);
else
return nFirstAtDistanceInAllSpatialIndexes(scope, source, f, number, alreadyChosen);
if (index != null) return nFirstAtDistanceInSpatialIndex(scope, source, f, number, alreadyChosen, index);
return nFirstAtDistanceInAllSpatialIndexes(scope, source, f, number, alreadyChosen);
}

@Override
Expand Down
41 changes: 19 additions & 22 deletions msi.gama.core/src/msi/gaml/operators/Containers.java
Expand Up @@ -43,7 +43,6 @@
import msi.gama.metamodel.population.IPopulationSet;
import msi.gama.metamodel.population.MetaPopulation;
import msi.gama.metamodel.shape.GamaPoint;

import msi.gama.metamodel.shape.IShape;
import msi.gama.metamodel.topology.ITopology;
import msi.gama.metamodel.topology.grid.IGrid;
Expand All @@ -59,7 +58,6 @@
import msi.gama.runtime.GAMA;
import msi.gama.runtime.IScope;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.Collector;
import msi.gama.util.GamaColor;
import msi.gama.util.GamaListFactory;
import msi.gama.util.GamaListFactory.GamaListSupplier;
Expand Down Expand Up @@ -182,7 +180,7 @@ public static abstract class Range {
special_cases = "Passing 0 will return a singleton list with 0.")
@test ("range(2) = [0,1,2]")
public static IList range(final IScope scope, final Integer end) {
if (end == 0) return GamaListFactory.wrap(Types.INT, Integer.valueOf(0));
if (end == 0) return GamaListFactory.wrap(Types.INT, 0);
return range(scope, 0, end);
}

Expand Down Expand Up @@ -223,10 +221,8 @@ public static IList range(final IScope scope, final Integer start, final Integer
if (end > start) {
if (step < 0)
throw GamaRuntimeException.error("Negative step would result in an infinite range", scope);
} else {
if (step > 0)
throw GamaRuntimeException.error("Positive step would result in an infinite range", scope);
}
} else if (step > 0)
throw GamaRuntimeException.error("Positive step would result in an infinite range", scope);
return IntStreamEx.rangeClosed(start, end, step).boxed().toCollection(listOf(Types.INT));

}
Expand Down Expand Up @@ -418,7 +414,7 @@ public boolean validate(final IDescription context, final EObject emfContext, fi
if (Types.FILE.isAssignableFrom(type)) { type = type.getWrappedType(); }
final IType keyType = type.getKeyType();
final boolean wrongKey = keyType != Types.NO_TYPE && !indexType.isTranslatableInto(keyType)
&& !(Types.MATRIX.isAssignableFrom(type) && indexType == Types.INT);
&& (!Types.MATRIX.isAssignableFrom(type) || (indexType != Types.INT));
if (wrongKey) {
context.error("The contents of this " + type.getGamlType().getName() + " can only be accessed with "
+ type.getKeyType() + " keys", IGamlIssue.WRONG_TYPE, emfContext);
Expand Down Expand Up @@ -656,8 +652,7 @@ public static Boolean in(final IScope scope, final Object o, final IContainer c)
masterDoc = true)
@no_test
public static Integer index_of(final IScope scope, final ISpecies s, final Object o) {
if (!(o instanceof IAgent)) return -1;
if (!((IAgent) o).isInstanceOf(notNull(scope, s), true)) return -1;
if (!(o instanceof IAgent) || !((IAgent) o).isInstanceOf(notNull(scope, s), true)) return -1;
return ((IAgent) o).getIndex();
}

Expand Down Expand Up @@ -1005,7 +1000,7 @@ public static IList of_species(final IScope scope, final IContainer agents, fina
private static IList of_species(final IScope scope, final IContainer agents, final ISpecies s,
final boolean generic) {
return (IList) agents.stream(scope)
.filter((each) -> each instanceof IAgent && ((IAgent) each).isInstanceOf(s, !generic))
.filter(each -> each instanceof IAgent && ((IAgent) each).isInstanceOf(s, !generic))
.toCollection(listOf(scope.getType(s.getName())));
}

Expand Down Expand Up @@ -1058,6 +1053,7 @@ public static IContainer plus(final IScope scope, final IContainer c1, final ICo
final MetaPopulation mp = new MetaPopulation();
mp.addPopulationSet((IPopulationSet) c1);
mp.addPopulationSet((IPopulationSet) c2);
return mp;
}
return (IContainer) stream(scope, c1).append(stream(scope, c2)).toCollection(listLike(c1, c2));
}
Expand Down Expand Up @@ -1323,27 +1319,28 @@ public static double sum(final IScope scope, final IGraph g) {
if (g == null) return 0.0;
return g.computeTotalWeight();
}

@operator (
value = "cartesian_product",
//can_be_const = true,
// can_be_const = true,
doc = @doc ("Returns the cartesian product of elements in all given sub-lists"),
expected_content_type = { IType.LIST },
category = { IOperatorCategory.CONTAINER },
concept = { IConcept.CONTAINER }
)
concept = { IConcept.CONTAINER })
@test ("cartesian_product([['A','B'],['C','D']]) = [['A','C'],['A','D'],['B','C'],['B','D']]")
public static Object cart_prod(final IScope scope, final IList list) {
IType ct = list.getGamlType().getContentType();
if (!ct.isContainer()) { GamaRuntimeException.error("Must be a list of list", scope); }

final IList<IList> l = notNull(scope, list).listValue(scope, list.getGamlType().getContentType(), false);
List<? extends Set<Object>> setOfSet = l.stream(scope).map(ilist -> new LinkedHashSet<>(ilist)).collect(Collectors.toList());
List<? extends Set<Object>> setOfSet = l.stream(scope).map(LinkedHashSet::new).collect(Collectors.toList());

IList<IList> res = GamaListFactory.create(ct);
Set<List<Object>> cp = Sets.cartesianProduct(setOfSet);
for (List cartList : cp) { res.add(GamaListFactory.create(scope, ct.getContentType(), cartList)); }

for (List cartList : cp) {
res.add(GamaListFactory.create(scope, ct.getContentType(), cartList));
}

return res;
}

Expand Down Expand Up @@ -1953,7 +1950,7 @@ public static IMap index_by(final IScope scope, final IContainer original, final

final StreamEx s = original.stream(scope);
final IType contentsType = original.getGamlType().getContentType();
return (IMap) s.collect(Collectors.toMap(with(scope, keyProvider), (a) -> a, (a, b) -> a,
return (IMap) s.collect(Collectors.toMap(with(scope, keyProvider), a -> a, (a, b) -> a,
asMapOf(keyProvider.getGamlType(), contentsType)));
}

Expand Down Expand Up @@ -1982,7 +1979,7 @@ public static IMap as_map(final IScope scope, final IContainer original, final I
if (!(filter instanceof BinaryOperator))
throw GamaRuntimeException.error("'as_map' expects a pair as second argument", scope);
final BinaryOperator pair = (BinaryOperator) filter;
if (!pair.getName().equals("::"))
if (!"::".equals(pair.getName()))
throw GamaRuntimeException.error("'as_map' expects a pair as second argument", scope);
final IExpression key = pair.arg(0);
final IExpression value = pair.arg(1);
Expand Down
Expand Up @@ -17,7 +17,7 @@ global {
* closest_to: the geometry closest to the source geometry
* farthest_to: the geometry farthest to the source geometry
*/
string type_query <- "overlapping" among: ["overlapping", "inside", "touching", "crossing", "covering", "closest_to", "farthest_to"] parameter:"Type of queries";
string type_query <- "overlapping" among: ["overlapping", "inside", "touching", "crossing", "covering", "closest_to", "farthest_to"] ;
agent_base selected_agent;

init {
Expand All @@ -36,9 +36,8 @@ global {
do apply_query;
}

reflex change_agent {
selected_agent <- one_of(polygon_agent + polyline_agent + point_agent);

action change_agent {
selected_agent <- (polygon_agent + polyline_agent + point_agent) closest_to #user_location;
do apply_query;
}

Expand Down Expand Up @@ -104,19 +103,20 @@ species point_agent parent:agent_base {
rgb color <- #green;
aspect default {
if (self = selected_agent) {

draw circle(1.5) color: #magenta;
}
draw circle(1.0) color:is_concerned ? #red : color border: #black;
}
}

experiment Spatialqueries type: gui {
parameter Query var: type_query on_change: {ask simulation{do apply_query;} do update_outputs();};
output {
display map {
species polygon_agent;
species point_agent;
species polyline_agent;
event #mouse_down {ask simulation{do change_agent;}}
}
}
}

0 comments on commit 95689dc

Please sign in to comment.