прочитать координаты из файла shp и вычислить расстояние

Я хочу вычислить ближайшее расстояние от точки до файла shp (ports.shp) из данных о естественной земле.

Например, я загружаю функции файла:

...
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();

}

Теперь, например, точка, от которой я хочу вычислить расстояние:

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

Я знаю, что для вычисления расстояния сделаю:

     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();

но я не знаю, как найти координаты точки назначения (файл ports.shp):

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

У меня есть features от загрузки файла, но нет метода getCoordinates().

Кроме того, как я вижу, ports.shp состоит из множества POINT геометрии. Должен ли я каким-то образом вычислять каждую точку с опорной точкой, а затем выбирать ближайшую?


person George    schedule 19.07.2017    source источник
comment
Похоже, это будет больше по теме на географических информационных системах Stack Exchange.   -  person PolyGeo    schedule 20.07.2017
comment
Под пунктом назначения вы подразумеваете ближайшую точку к начальной координате? Если это так, вам действительно придется проверить по всем другим пунктам. Как вы решили переехать?   -  person DarkCygnus    schedule 20.07.2017
comment
@GrayCygnus: Да, я имею в виду ближайшую точку (из ports.shp) от начальной точки. Моя проблема в том, как правильно читать координаты из файла ports.shp. Затем я просто помещаю каждую точку в конечную позицию. и найдите ближайший к отправной точке.   -  person George    schedule 20.07.2017
comment
@polygeo вообще-то как вопрос программирования здесь лучше   -  person Ian Turton    schedule 20.07.2017


Ответы (1)


В Feature есть getDefaultGeometry метод, который даст вам нужную точку. Тогда вы можете получить координаты от точки.

ИЗМЕНИТЬ

Ваша проблема заключалась в несоответствии единиц измерения, вы устанавливали MinDist на ширину ограничивающей рамки (в градусах, то есть около 360), но сравнивали ее с расстояниями в метрах (то есть около 7800000), поэтому вы никогда не находили точку, достаточно близкую для сохранения.

Я начал экспериментировать с тем, чтобы сделать поиск более эффективным, ограничив начальные границы поиска, но он достаточно быстрый даже при использовании набора данных о населенных пунктах, и я не могу сказать, помогает ли это.

    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());
}
person Ian Turton    schedule 20.07.2017
comment
Хорошо, спасибо! Я это видел. Я написал небольшой рабочий пример. Я использую файл ports.shp. Я нахожу расстояние (dist) между контрольной точкой и точками ports.shp. Но minDistPoint имеет значение null, хотя dest.getCoordinate() Не могли бы вы сообщить мне, на правильном ли я пути? Здесь коде .Спасибо! (проголосовало за!) - person George; 20.07.2017