1

I want to compute the nearest distance from a point to a shp file (ports.shp) from natural earth data.

For example, I am loading the features of the file:

...
String filename = "10m_cultural/ne_10m_ports.shp";
...


 public static void Calcs(String filename) 
    throws IOException, NoSuchAuthorityCodeException, FactoryException, TransformException {

    HashMap<String, Object> params = new HashMap<>();
    params.put("url", DataUtilities.fileToURL(new File(filename)));
    DataStore ds = DataStoreFinder.getDataStore(params);

    String name = ds.getTypeNames()[0];
    SimpleFeatureSource source = ds.getFeatureSource(name);
    SimpleFeatureCollection features = source.getFeatures();

}

Now, a point for example from which I want to compute the distance is:

GeometryFactory gf = JTSFactoryFinder.getGeometryFactory();
Point p = gf.createPoint(new Coordinate(43, 18));

I know that to compute the distance I will do:

     CoordinateReferenceSystem crs = CRS.decode("EPSG:4326");           


      Point start = gf.createPoint(new Coordinate(43, 18));
      Point dest = gf.createPoint(new Coordinate(?????));

      GeodeticCalculator gc = new GeodeticCalculator(crs);
      gc.setStartingPosition(JTS.toDirectPosition(start.getCoordinate(), crs));
      gc.setDestinationPosition(JTS.toDirectPosition(dest.getCoordinate(), crs));


      double distance = gc.getOrthodromicDistance();

but I don't know how to find the coordinates of the destination point (the ports.shp file):

Point dest = gf.createPoint(new Coordinate(?????));

I have the features from loading the file but it doesn't have any getCoordinates() method.

Also, as i can see ports.shp consists of many POINT geometry.Do I have to compute somehow every point with the reference point and then select the nearest?

George
  • 5,808
  • 15
  • 83
  • 160
  • This looks like it would be more on-topic at the [gis.se] Stack Exchange. – PolyGeo Jul 19 '17 at 21:02
  • By "destination" you mean the closest point to the start coordinate? If it is so you will indeed have to check against all other points. How is it you decide to move? – DarkCygnus Jul 19 '17 at 21:03
  • @GrayCygnus:Yes, I mean the nearest point (from the ports.shp) from the start point.My problem is how to properly read the coordinates form the ports.shp file.Then , I will just put to the destination position every point and find the closest to the starting point. – George Jul 20 '17 at 06:29
  • @polygeo actually as a programing question it is better here – Ian Turton Jul 20 '17 at 06:46

1 Answers1

1

Feature has a getDefaultGeometry method which will give you the point you need. Then you can get the coordinates from the point.

EDIT

Your problem was a units mismatch, you were setting MinDist to the width of the bounding box (in degrees, so about 360) but comparing it to distances in metres (so about 7800000) so you never found a point close enough to save.

I started playing with making the search more efficient by limiting the initial search bounds but it is sufficiently fast even when using the populated places data set that I can't really tell if it helps.

    final double MAX_SEARCH_DISTANCE = Math.max(index.getBounds().getWidth(), index.getBounds().getHeight());
    double searchDist = 0.01;

    while (searchDist < MAX_SEARCH_DISTANCE) {
        // start point (user input)
        Coordinate coordinate = p.getCoordinate();

        ReferencedEnvelope search = new ReferencedEnvelope(new Envelope(coordinate),
                index.getSchema().getCoordinateReferenceSystem());

        search.expandBy(searchDist);
        BBOX bbox = ff.bbox(ff.property(index.getSchema().getGeometryDescriptor().getName()), (BoundingBox) search);
        SimpleFeatureCollection candidates = index.subCollection(bbox);

        double minDist = Double.POSITIVE_INFINITY; // can't use
                                                    // MAX_Search_dist here
                                                    // as it is degrees and
                                                    // dists are meters
        Coordinate minDistPoint = null;
        double dist = 0;
        Point dest = null;
        SimpleFeatureIterator itr = candidates.features();
        CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
        try {
            SimpleFeature feature = null;
            while (itr.hasNext()) {
                feature = itr.next();

                // destination point
                dest = (Point) feature.getDefaultGeometry();
                GeodeticCalculator gc = new GeodeticCalculator(crs);
                gc.setStartingPosition(JTS.toDirectPosition(p.getCoordinate(), crs));
                gc.setDestinationPosition(JTS.toDirectPosition(dest.getCoordinate(), crs));
                // Calculate distance between points
                dist = gc.getOrthodromicDistance();
                // System.out.println(feature.getID()+": "+dist);
                if (dist < minDist) {
                    minDist = dist;
                    minDistPoint = dest.getCoordinate();
                    lastMatched = feature;
                }
            }

        } finally {
            itr.close();
        }
        Point ret = null;

        if (minDistPoint == null) {
            searchDist *= 2.0;
            System.out.println("repeat search");
        } else {
            ret = gf.createPoint(minDistPoint);
            return ret;
        }
    }
    return gf.createPoint(new Coordinate());
}
Ian Turton
  • 10,018
  • 1
  • 28
  • 47
  • Ok, thanks!I saw that.I have written a small running example.I am using "ports.shp" file.I am finding the distance (dist) between the reference point and the ports.shp points.But `minDistPoint` is null even though `dest.getCoordinate()` is not.Could you kindly please let me know if I am on right path?[**Codeis here**](https://pastebin.com/gU0R6dam).Thanks!(upvoted!) – George Jul 20 '17 at 10:22
  • If you think you can help me with the above, I will be grateful! [**the code is available here now**](https://pastebin.com/nV9G6vyg) – George Jul 21 '17 at 10:30