Search code examples
javamapsgeospatialgeographygeotools

Determining whether geographic point is within X meters of a state border (using shapefile for border data)


So I'm writing a Java app, and I've got an ESRI Shapefile which contains the borders of all the U.S. states. What I need is to be able to determine whether any given lat/lon point is within a specified distance from ANY state border line - i.e., I will not be specifying a particular border line, just need to see whether the point is close to any of them.

The solution does NOT have to be very precise at all; e.g. I don't need to be dealing with measuring perpendicular to the border, or whatever. Just checking to see if going X meters north, south, east or west would result in crossing a border would be more than sufficient. The solution DOES have to be computationally efficient, as I'll be performing a huge number of these calculations.

I'm planning to use the GeoTools library (though if there's a simpler option, I'm all for it) with the Shapefile plugin. What I don't really understand is: Once I've got the shapefile loaded into memory, how do I check to see whether I'm near a border?

Thanks! -Dan


Solution

  • Assuming JTS for Geometry which is what is included in GeoTools:

    public boolean pointIsClose( File file, Point targetPoint,double distance) {
    
    
      boolean ret = false;
      Map connect = new HashMap();
      connect.put("url", file.toURL());
      DataStore dataStore = DataStoreFinder.getDataStore(connect);
    
    
      FeatureSource featureSource = dataStore.getFeatureSource(typeName);
      FeatureCollection collection = featureSource.getFeatures();
      FeatureIterator iterator = collection.features();
    
    
    
      try {
        while (iterator.hasNext()) {
          Feature feature = iterator.next();
          Geometry sourceGeometry = feature.getDefaultGeometry();
          ret= sourceGeometry.isWithinDistance(targetPoint, distance );
        }
      } finally {
        iterator.close();
      }
      return ret;
    }
    

    The double number will have to come from the CRS which will define the units in which the calculation will be performed.

    These are the geotools imports:

    import org.geotools.data.DataStore;
    import org.geotools.data.DataStoreFinder;
    import org.geotools.data.FeatureSource;
    import org.geotools.feature.Feature;
    import org.geotools.feature.FeatureCollection;
    import org.geotools.feature.FeatureIterator;
    import org.geotools.geometry.jts.JTS;
    import org.geotools.referencing.CRS;
    import org.opengis.referencing.crs.CoordinateReferenceSystem;