diff --git a/src/org/myworldgis/netlogo/GISExtension.java b/src/org/myworldgis/netlogo/GISExtension.java index 99c7a2a..deb1eac 100644 --- a/src/org/myworldgis/netlogo/GISExtension.java +++ b/src/org/myworldgis/netlogo/GISExtension.java @@ -155,7 +155,7 @@ public void load (PrimitiveManager primitiveManager) { primitiveManager.addPrimitive("have-relationship?", new SpatialRelationship.GeneralTest()); primitiveManager.addPrimitive("relationship-of", new SpatialRelationship.GetRelationship()); primitiveManager.addPrimitive("intersecting", new SpatialRelationship.Intersecting()); - + primitiveManager.addPrimitive("min-distance-of", new VectorDataset.GetMinimumDistanceFromDataset()); primitiveManager.addPrimitive("width-of", new RasterDataset.GetWidth()); primitiveManager.addPrimitive("height-of", new RasterDataset.GetHeight()); primitiveManager.addPrimitive("raster-value", new RasterDataset.GetValue()); diff --git a/src/org/myworldgis/netlogo/VectorDataset.java b/src/org/myworldgis/netlogo/VectorDataset.java index a17fa55..d446aed 100644 --- a/src/org/myworldgis/netlogo/VectorDataset.java +++ b/src/org/myworldgis/netlogo/VectorDataset.java @@ -15,6 +15,9 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Iterator; +import org.nlogo.api.Agent; +import org.nlogo.api.AgentSet; import org.nlogo.api.Argument; import org.nlogo.api.Context; import org.nlogo.api.ExtensionException; @@ -60,6 +63,89 @@ public Object reportInternal (Argument args[], Context context) } } + /** */ + public static final class GetMinimumDistanceFromDataset extends GISExtension.Reporter { + + public String getAgentClassString() { + return "OTPL"; + } + + public Syntax getSyntax() { + return SyntaxJ.reporterSyntax(new int[] { Syntax.WildcardType(), Syntax.WildcardType() }, + Syntax.WildcardType()); + } + + public Object reportInternal (Argument args[], Context context) + throws ExtensionException, LogoException { + try { + Double distance = Double.NaN; + Double temp_distance = Double.NaN; + Geometry obj_geom = null; + if( args.length != 2) { + throw new ExtensionException("function needs two parameters"); + } + + if ( args[1].get() instanceof VectorFeature) { + obj_geom = ((VectorFeature)args[1].get()).getGeometry(); + } else if (args[1].get() instanceof Agent) { + obj_geom = GISExtension.getState().agentGeometry((Agent)args[1].get()); + } + + if( obj_geom == null ) { + throw new ExtensionException("not a VectorFeature, Agent: " + args[1].get()); + } + + if ( args[0].get() instanceof VectorDataset ) { + VectorDataset dataset = VectorDataset.getDataset(args[0]); + + + for (Iterator i = dataset.getFeatures().iterator(); i.hasNext();) { + VectorFeature feature = i.next(); + + Geometry geom = feature.getGeometry(); + if( geom != null && !geom.isEmpty() ) { + temp_distance = obj_geom.distance(geom); + } + if(Double.isNaN(distance)) { + distance = temp_distance; + } + else if( distance > temp_distance) { + distance = temp_distance; + } + } + return distance; + } + else if (args[0].get() instanceof AgentSet) { + + AgentSet set = (AgentSet)args[0].get(); + + for (Iterator i = set.agents().iterator(); i.hasNext();) { + Geometry geom = GISExtension.getState().agentGeometry(i.next()); + if( geom != null && !geom.isEmpty() ) { + temp_distance = obj_geom.distance(geom); + } + if(Double.isNaN(distance)) { + distance = temp_distance; + } + else if( distance > temp_distance) { + distance = temp_distance; + } + } + return distance; + } + else { + return Double.NaN; + } + } catch (ExtensionException e) { + throw e; + } catch (Throwable t) { + ExtensionException e = new ExtensionException("error parsing envelope"); + e.initCause(t); + throw e; + } + } + } + /** */ public static final class GetPropertyNames extends GISExtension.Reporter { diff --git a/src/org/myworldgis/netlogo/VectorFeature.java b/src/org/myworldgis/netlogo/VectorFeature.java index 8dc79a0..dd2ff61 100644 --- a/src/org/myworldgis/netlogo/VectorFeature.java +++ b/src/org/myworldgis/netlogo/VectorFeature.java @@ -252,6 +252,14 @@ public Envelope getEnvelope () { return _geometry.getEnvelopeInternal(); } + /** */ + public Double getDistance (Geometry geometry) { + if (_geometry == null || geometry == null || geometry.isEmpty()) { + return null; + } + return _geometry.distance(geometry); + } + /** */ public Geometry getGeometry () { return _geometry;