Java 如何生成仅海洋坐标并将其显示在可视地图中
How to generate only-ocean coordinates and display them in a visual map in Java
我正在制作一种跟踪应用程序,它需要为不同的船只生成坐标并在地图中可视化它们的位置。
我研究过类似的问题,但都是关于仅限陆地的坐标。另外,我见过如此不同的框架,如 GeoTools 或 Unfolding,但文档太大,我找不到我要找的东西。
我只需要在海洋生成坐标,然后在地图上显示标签即可。
在 Python 中有一个库可以检查某个点是否在陆地上(因此您可以检查它是否在海洋上),然后您可以使用 Folium 添加带有附加信息的标记。
不知道是否有与 Java 类似的方法。
下载我的海洋坐标网格:
https://djinesse.com/public/coordinates_ocean.json
该文件可能会在不久的将来被删除。
使用方法:
String fromFile = FileUtils.readFileToString( new File( "c:/users/you/downloads/coordinates.json" ), "UTF-8" );
JSONArray coordinates = new JSONArray( fromFile );
// pull random coordinates from the array:
int index = (int) (Math.random() * coordinates.length() );
JSONObject randomCoordinate = coordinates.getJSONObject( index );
double longitude = randomCoordinate.getDouble( "lo" );
double latitude = randomCoordinate.getDouble( "la" );
必需的 pom.xml
依赖项:
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
我会这样做:
下载一组陆地多边形
将它们存储在空间索引中
生成一个随机点并测试它是否落在陆地上
继续生成直到它不落在陆地上
重复直到你有足够的分数
public class PointInSea {
private static final FilterFactory2 FF = CommonFactoryFinder.getFilterFactory2();
private SimpleFeatureCollection features;
public static void main(String[] args) throws IOException {
URL url = new URL("https://datahub.io/core/geo-countries/r/countries.geojson");
Map<String, Object> params = new HashMap<>();
params.put(GeoJSONDataStoreFactory.URL_PARAM.key, url);
DataStore ds = DataStoreFinder.getDataStore(params);
PointInSea me = new PointInSea();
me.setFeatures(ds.getFeatureSource(ds.getTypeNames()[0]).getFeatures());
List<Point> ret = me.getPoints(10);
for (Point p : ret) {
System.out.println(p);
}
}
private void setFeatures(SimpleFeatureCollection features2) throws IOException {
features = new SpatialIndexFeatureCollection(features2);
}
private List<Point> getPoints(int i) {
List<Point> ret = new ArrayList<>(i);
for (int count = 0; count < i; count++) {
Point p = createRandomPoint();
Contains filter = FF.contains(FF.property(features.getSchema().getGeometryDescriptor().getLocalName()),
FF.literal(p));
while (features.subCollection(filter).size() != 0) {
p = createRandomPoint();
filter = FF.contains(FF.property(features.getSchema().getGeometryDescriptor().getLocalName()), FF.literal(p));
}
ret.add(p);
}
return ret;
}
public static Point createRandomPoint() {
double latitude = (Math.random() * 180.0) - 90.0;
double longitude = (Math.random() * 360.0) - 180.0;
GeometryFactory geometryFactory = new GeometryFactory();
Point point;
if (CRS.getAxisOrder(DefaultGeographicCRS.WGS84) == CRS.AxisOrder.EAST_NORTH) {
/* Longitude (= x coord) first ! */
point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
} else {
point = geometryFactory.createPoint(new Coordinate(latitude, longitude));
}
return point;
}
}
我正在制作一种跟踪应用程序,它需要为不同的船只生成坐标并在地图中可视化它们的位置。
我研究过类似的问题,但都是关于仅限陆地的坐标。另外,我见过如此不同的框架,如 GeoTools 或 Unfolding,但文档太大,我找不到我要找的东西。
我只需要在海洋生成坐标,然后在地图上显示标签即可。
在 Python 中有一个库可以检查某个点是否在陆地上(因此您可以检查它是否在海洋上),然后您可以使用 Folium 添加带有附加信息的标记。
不知道是否有与 Java 类似的方法。
下载我的海洋坐标网格:
https://djinesse.com/public/coordinates_ocean.json 该文件可能会在不久的将来被删除。
使用方法:
String fromFile = FileUtils.readFileToString( new File( "c:/users/you/downloads/coordinates.json" ), "UTF-8" );
JSONArray coordinates = new JSONArray( fromFile );
// pull random coordinates from the array:
int index = (int) (Math.random() * coordinates.length() );
JSONObject randomCoordinate = coordinates.getJSONObject( index );
double longitude = randomCoordinate.getDouble( "lo" );
double latitude = randomCoordinate.getDouble( "la" );
必需的 pom.xml
依赖项:
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
我会这样做:
下载一组陆地多边形
将它们存储在空间索引中
生成一个随机点并测试它是否落在陆地上
继续生成直到它不落在陆地上
重复直到你有足够的分数
public class PointInSea { private static final FilterFactory2 FF = CommonFactoryFinder.getFilterFactory2(); private SimpleFeatureCollection features; public static void main(String[] args) throws IOException { URL url = new URL("https://datahub.io/core/geo-countries/r/countries.geojson"); Map<String, Object> params = new HashMap<>(); params.put(GeoJSONDataStoreFactory.URL_PARAM.key, url); DataStore ds = DataStoreFinder.getDataStore(params); PointInSea me = new PointInSea(); me.setFeatures(ds.getFeatureSource(ds.getTypeNames()[0]).getFeatures()); List<Point> ret = me.getPoints(10); for (Point p : ret) { System.out.println(p); } } private void setFeatures(SimpleFeatureCollection features2) throws IOException { features = new SpatialIndexFeatureCollection(features2); } private List<Point> getPoints(int i) { List<Point> ret = new ArrayList<>(i); for (int count = 0; count < i; count++) { Point p = createRandomPoint(); Contains filter = FF.contains(FF.property(features.getSchema().getGeometryDescriptor().getLocalName()), FF.literal(p)); while (features.subCollection(filter).size() != 0) { p = createRandomPoint(); filter = FF.contains(FF.property(features.getSchema().getGeometryDescriptor().getLocalName()), FF.literal(p)); } ret.add(p); } return ret; } public static Point createRandomPoint() { double latitude = (Math.random() * 180.0) - 90.0; double longitude = (Math.random() * 360.0) - 180.0; GeometryFactory geometryFactory = new GeometryFactory(); Point point; if (CRS.getAxisOrder(DefaultGeographicCRS.WGS84) == CRS.AxisOrder.EAST_NORTH) { /* Longitude (= x coord) first ! */ point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); } else { point = geometryFactory.createPoint(new Coordinate(latitude, longitude)); } return point; } }