/**
* Name: Spatialqueries
* Author: Patrick Taillandier
* Description: A model which shows how to use spatial queries - in magenta the source geometry, in red the agents concerned by the spatial query
* Tags: topology, spatial_computation, spatial_queries
*/
model Spatialqueries
global {
/*
* overlapping: the geometries have at least one point in common with the source geometry
* inside: the geometries are completely within the source geometry (no touching edges)
* touhcing: the geometries only touch edges of the source geometry and do not overlap it in any way
* crossing: the geometries do more than touch the source geometry, they actually overlap edges of it
* covering: the geometries completely cover the source geometry (no touching edges)
* closest_to: the geometry closest to the source geometry
* farthest_to: the geometry farthest to the source geometry
*/
string type_query <- "overlapping" among: ["overlapping", "partially_overlapping", "intersecting", "inside", "touching", "crossing", "covering", "closest_to", "farthest_to"] ;
agent_base selected_agent;
init {
create polygon_agent number:10 {
shape <- square(20);
}
create polyline_agent number:10 {
shape <- line([any_location_in(world),any_location_in(world)]);
}
create point_agent number: 10 {
shape <-any_location_in(world);
}
selected_agent <- one_of (polygon_agent);
do apply_query;
}
action change_agent {
selected_agent <- (polygon_agent + polyline_agent + point_agent) closest_to #user_location;
do apply_query;
}
action apply_query {
list agents_concerned;
switch type_query {
match "overlapping" {
agents_concerned <- (polygon_agent + polyline_agent + point_agent) overlapping selected_agent;
}
match "partially_overlapping" {
agents_concerned <- (polygon_agent + polyline_agent + point_agent) partially_overlapping selected_agent;
}
match "intersecting" {
agents_concerned <- (polygon_agent + polyline_agent + point_agent) intersecting selected_agent;
}
match "inside" {
agents_concerned <- (polygon_agent + polyline_agent + point_agent) inside selected_agent;
}
match "touching" {
agents_concerned <- (polygon_agent + polyline_agent + point_agent) touching selected_agent;
}
match "crossing" {
agents_concerned <- (polygon_agent + polyline_agent + point_agent) crossing selected_agent;
}
match "covering" {
agents_concerned <- (polygon_agent + polyline_agent + point_agent) covering selected_agent;
}
match "closest_to" {
agents_concerned <- [polygon_agent closest_to selected_agent,polyline_agent closest_to selected_agent,point_agent closest_to selected_agent];
}
match "farthest_to" {
agents_concerned <- [polygon_agent farthest_to selected_agent,polyline_agent farthest_to selected_agent,point_agent farthest_to selected_agent];
}
}
ask polygon_agent + polyline_agent + point_agent{
is_concerned <- false;
}
ask agents_concerned {
is_concerned <- true;
}
}
}
species agent_base {
bool is_concerned <- false;
}
species polygon_agent parent:agent_base {
rgb color <- #gray;
aspect default {
if (self = selected_agent) {
draw shape + 1.0 color: #magenta;
}
draw shape color: is_concerned ? #red : color border: #black;
}
}
species polyline_agent parent:agent_base {
rgb color <- #black;
aspect default {
if (self = selected_agent) {
draw shape + 0.5 color: #magenta;
}
draw shape color: is_concerned ? #red : color;
}
}
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;}}
}
}
}