1

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?

1 Answer 1

1

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

3
  • Thank you. I did try before, but for some reason this only works when where is one country within the radius. For example, given a point (54 N, 22 E) and a radius of 30 km returns only Poland, as expected. But given the same point, and a radius of 50 km, the returned SimpleFeatureCollection is empty.
    – Greg A
    Commented Feb 16, 2021 at 21:52
  • Would you so kind as to post a Gist of bufferPoint method code (including the imports) - I think I may have messed up my imports and that could be causing this. Thank you!
    – Greg A
    Commented Feb 16, 2021 at 22:05
  • it should be intersects not contains in the filter - and I've added a full gist
    – Ian Turton
    Commented Feb 17, 2021 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.