2

I am trying to perform reverse geocoding in Java using GeoTools and Natural Earth Shapefiles. I just want to pass latitude longitude and get the corresponding country name + state name. I have searched entire internet and all the posts on this forum but couldn't find an answer for my specific use case. I am not sure how to pass the latitude longitude value and use Natural Earth shape files to get the country name and state name. I don't want to display anything on the map. Just the country and state name would be enough.

1

I'm not entirely clear on which part of your question you can't find an answer as all of these steps are pretty well documented on this site (mostly by me :-)) as well as in the tutorials and documentation. But here you go, first open the shapefiles and store the features in a memory store:

  SpatialIndexFeatureCollection countries;
  final static FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
  final static public String countryFile = "/data/natural_earth/10m_cultural/10m_admin_0_countries.shp";

  public SimpleGeoCoder() throws IOException {
    // load the country shapefile
    URL countryURL = DataUtilities.fileToURL(new File(countryFile));
    HashMap<String, Object> params = new HashMap<>();
    params.put("url", countryURL);
    DataStore ds = DataStoreFinder.getDataStore(params);
    if (ds == null) {
      throw new IOException("couldn't open " + params.get("url"));
    }
    Name name = ds.getNames().get(0);
    countries = new SpatialIndexFeatureCollection(ds.getFeatureSource(name).getFeatures());
  }

Then create a lon/lat point (as Natural Earth stores its coordinates in that order):

GeometryFactory gf = new GeometryFactory();
Point london = gf.createPoint(new Coordinate(0.0, 51.0));

Finally look up the the point in the stored features:

 public SimpleFeatureCollection lookup(Point p) {
    Filter f = ff.contains(ff.property("the_geom"), ff.literal(p));
    return countries.subCollection(f);

  }

Then print out the name (or other attributes):

SimpleFeatureIterator itr = features.features();
try {
  while (itr.hasNext()) {
    SimpleFeature f = itr.next();
    System.out.println(f.getAttribute("NAME"));
  }
} finally {
  itr.close();
}

I've put all the code into a gist for you to download. Adding administrative sub units is left as an exercise for the reader.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy