java - 随机地理坐标(在陆地上,避开海洋)

标签 java gis geocoding

关于如何生成地球上各个地点的随机坐标(纬度/经度)的任何巧妙想法?纬度/经度。精确到 5 点,避免水体。

    double minLat = -90.00;
    double maxLat = 90.00;      
    double latitude = minLat + (double)(Math.random() * ((maxLat - minLat) + 1));
    double minLon = 0.00;
    double maxLon = 180.00;     
    double longitude = minLon + (double)(Math.random() * ((maxLon - minLon) + 1));
    DecimalFormat df = new DecimalFormat("#.#####");        
    log.info("latitude:longitude --> " + df.format(latitude) + "," + df.format(longitude));

也许我生活在一个梦想的世界里,水的话题是不可避免的……但希望有更好、更清洁、更有效的方法来做到这一点?

编辑

一些很棒的答案/想法——但是,在规模上,假设我需要生成 25,000 个坐标。由于延迟、成本和其他一些因素,寻求外部服务提供商可能不是最佳选择。

最佳答案

处理水体问题将主要是一个数据问题,例如你只想想念海洋还是想念小溪流。您需要使用具有所需数据质量的服务,或者您需要自己获取数据并在本地运行。根据您的编辑,听起来您想走本地数据路线,所以我将重点介绍一种方法。

一种方法是获取陆地区域或水域的 shapefile。然后,您可以生成一个随机点并确定它是否与陆地区域相交(或者,不与水域相交)。

首先,您可能会得到一些低分辨率数据 here然后得到更高分辨率的数据here当您想在海岸线或湖泊/河流/等处获得更好的答案时。您提到您希望将点精确到小数点后 5 位,即 1m 多一点。请注意,如果您获得与该精度匹配的数据,您将拥有一个庞大的数据集。而且,如果您想要真正好的数据,请准备好为此付费。

获得形状数据后,您需要一些工具来帮助您确定随机点的交点。 Geotools是一个很好的起点,可能会满足您的需求。您最终还将查看 opengis 代码(geotools 站点下的文档 - 不确定他们是否使用了它们或什么)和 JTS用于几何处理。使用它,您可以快速打开 shapefile 并开始执行一些交集查询。

    File f = new File ( "world.shp" );
    ShapefileDataStore dataStore = new ShapefileDataStore ( f.toURI ().toURL () );
    FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = 
        dataStore.getFeatureSource ();
    String geomAttrName = featureSource.getSchema ()
        .getGeometryDescriptor ().getLocalName ();

    ResourceInfo resourceInfo = featureSource.getInfo ();
    CoordinateReferenceSystem crs = resourceInfo.getCRS ();
    Hints hints = GeoTools.getDefaultHints ();
    hints.put ( Hints.JTS_SRID, 4326 );
    hints.put ( Hints.CRS, crs );

    FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2 ( hints );
    GeometryFactory gf = JTSFactoryFinder.getGeometryFactory ( hints );

    Coordinate land = new Coordinate ( -122.0087, 47.54650 );
    Point pointLand = gf.createPoint ( land );
    Coordinate water = new Coordinate ( 0, 0 );
    Point pointWater = gf.createPoint ( water );

    Intersects filter = ff.intersects ( ff.property ( geomAttrName ), 
        ff.literal ( pointLand ) );
    FeatureCollection<SimpleFeatureType, SimpleFeature> features = featureSource
            .getFeatures ( filter );

    filter = ff.intersects ( ff.property ( geomAttrName ), 
        ff.literal ( pointWater ) );
    features = featureSource.getFeatures ( filter );

快速解释:

  1. 这假设你得到的 shapefile 是多边形数据。线或点的交点不会给你想要的。
  2. 第一部分打开 shapefile - 没什么有趣的
  3. 您必须获取给定文件的几何属性名称
  4. 坐标系的东西 - 您在帖子中指定了纬度/经度,但 GIS 可能要复杂得多。一般来说,我指给你的数据是geographic, wgs84 ,而且,这就是我在这里设置的。但是,如果您不是这种情况,那么您需要确保您在正确的坐标系中处理数据。如果这一切听起来像是胡言乱语,请在谷歌周围搜索有关 GIS/坐标系/基准面/椭球的教程。
  5. 生成坐标几何图形和过滤器是不言自明的。生成的要素集要么是空的,这意味着如果您的数据是土地覆盖,坐标在水中,或者不是空的,这意味着相反。

注意:如果你用一组非常随机的点来做这个,你会经常碰到水,你可能需要一段时间才能达到 25k 点。您可能想尝试比真正随机的更好地确定您的点生成范围(例如删除大西洋/太平洋/印度洋的大块区域)。

另外,您可能会发现您的交叉点查询太慢了。如果是这样,您可能需要考虑使用 GDAL 之类的工具创建四叉树索引 (qix) .不过,我不记得 geotools 支持哪些索引类型。

关于java - 随机地理坐标(在陆地上,避开海洋),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9104908/

相关文章:

c# - 如何在 C# 中将复杂的 geo-json 转换为 wkt?

c# - 将纬度/经度转换为 MGRS

node.js - 如何使用 Twitter 通过地理编码进行搜索?

java - OpenstreetMap 如何验证帖子地址

java - 项目无法执行Findbugs : java. lang.ArrayIndexOutOfBoundsException

java - 下载图像时 BitmapFactory.decodeStream 返回空值

java - java中递归生成字符串的所有排列

java - RSA加解密Java

快速点查找和视线遍历算法

jquery - 反向地理编码将坐标转换为地址?