从 shp 文件中读取坐标并计算距离
read coordinates from shp file and compute distance
我想根据自然地球数据计算从一个点到 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
geometry.Do 组成,我必须以某种方式计算每个点与参考点,然后 select 最近的点?
功能有一个 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());
}
我想根据自然地球数据计算从一个点到 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
geometry.Do 组成,我必须以某种方式计算每个点与参考点,然后 select 最近的点?
功能有一个 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());
}