TransWikia.com

Reverse Geocoding within a Radius with Geotools using Natural Earth Shapefiles

Geographic Information Systems Asked by Greg A on March 22, 2021

The problem I’m trying to solve is: given a latitude, longitude, and a radius, get all the countries contained within in an area with that radius. My approach is to first, buffer my point by a radius using the bufferPoint method (https://gis.stackexchange.com/a/311333/176526). Next, I modified the lookup method (https://gis.stackexchange.com/a/182469/176526) work with Geometry coordinates rather than a point:

public List<SimpleFeatureCollection> lookup(Geometry g, SpatialIndexFeatureCollection countries) {
    GeometryFactory gf = new GeometryFactory();
    
    Coordinate[] bufferedCoordinates = g.getCoordinates();
    Point[] points = new Point[bufferedCoordinates.length];
    
    int i = 0;
    for (Coordinate c : bufferedCoordinates) {
        points[i] = gf.createPoint(c);
        i++;
    }
    
    List<SimpleFeatureCollection> simpleFeatures = new ArrayList<>();
    for (int j = 0; j < points.length; j++) {
        Filter f = ff.contains(ff.property("the_geom"), ff.literal(points[j]));
        simpleFeatures.add(countries.subCollection(f));
    }
    
    return simpleFeatures;
}

Finally, I iterate over the list of features:

    int i = 0;
    for (SimpleFeatureCollection simpleFeature : simpleFeaturesList) {
        SimpleFeatureIterator itr = simpleFeature.features();
        try {

            while (itr.hasNext()) {
                SimpleFeature f = itr.next();
                //System.out.println(f.getAttribute("NAME"));
                i++;
            }
        } finally {
            itr.close();
        }
    }

I do realize this is sloppy, but problem is that it’s also wrong – given a large enough radius, none of the Geometry’s coordinates will fall into some smaller country contained within the radius.

How do I do this correctly?

One Answer

There is no (good) reason to limit yourself to points, you can see if your buffer intersects with the countries directly:

public SimpleFeatureCollection lookup(Geometry g, SpatialIndexFeatureCollection countries) {
    GeometryFactory gf = new GeometryFactory();
    
    Filter f = ff.intersects(ff.property("the_geom"), ff.literal(g));
    ret = countries.subCollection(f);
    
    
    return ret;
}

Full gist

Correct answer by Ian Turton on March 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP