Geotools:wgs84 中缓冲区的边界框

问题描述 投票:0回答:4

我需要一个 Java 函数来在缓冲区周围生成一个边界框(矩形)。缓冲区由中心点(WGS84 坐标)和半径(以米为单位)定义。

在 JTS 中获取缓冲区的边界框似乎非常简单:

Point center = ....
Geometry boundingBox = center.buffer(...).getEnvelope();

然而,这是纯平面几何。有没有办法使用坐标参考系来做到这一点,距离以米为单位?

最适合使用 Geotools,但其他 Java 解决方案也可以使用...

java geospatial geotools jts
4个回答
5
投票

虽然您以另一种方式处理它,但我有另一种解决方案。结果将比您提出的解决方案更精确。

GeometryFactory GEOMETRY_FACTORY = JTSFactoryFinder.getGeometryFactory();

// Remember, order is (longitude, latitude)
Coordinate center = Coordinate(2.29443, 48.85816);
Point point = GEOMETRY_FACTORY.createPoint(center);

// Buffer 50KM around the point, then get the envelope
Envelope envelopeInternal = buffer(point, 50000).getEnvelopeInternal();

// Then you can play with the envelope, e.g.,
double minX = envelopeInternal.getMinX();
double maxX = envelopeInternal.getMaxX();

// The buffer using distanceInMeters
private Geometry buffer(Geometry geometry, double distanceInMeters) throws FactoryException, TransformException {
     String code = "AUTO:42001," + geometry.getCentroid().getCoordinate().x + "," + geometry.getCentroid().getCoordinate().y;
     CoordinateReferenceSystem auto = CRS.decode(code);

     MathTransform toTransform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
     MathTransform fromTransform = CRS.findMathTransform(auto, DefaultGeographicCRS.WGS84);

     Geometry pGeom = JTS.transform(geometry, toTransform);
     Geometry pBufferedGeom = pGeom.buffer(distanceInMeters);
     return JTS.transform(pBufferedGeom, fromTransform);
}

这是带有结果的地图,缓冲区为红色,信封为黑色。


1
投票

我最终使用

GeodeticCalculator
手动找到盒子的角。坦率地说,结果不是很精确,但这是我迄今为止找到的最佳解决方案:

 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
 CoordinateReferenceSystem wgs84 = DefaultGeographicCRS.WGS84;
 GeodeticCalculator geodeticCalculator = new GeodeticCalculator(wgs84);
 geodeticCalculator.setStartingGeographicPoint(center.getX(), center.getY());
 Coordinate[] coordinates = new Coordinate[5];
 for (int i = 0; i < 4; i++) {
    geodeticCalculator.setDirection(-180 + i * 90 + 45, bufferRadiusMeters * Math.sqrt(2));
    Point2D point2D = geodeticCalculator.getDestinationGeographicPoint();
    coordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
 }
 coordinates[4] = coordinates[0];
 Polygon box = geometryFactory.createPolygon(coordinates);

0
投票

这是一个简单的解决方案,我用它来生成边界框坐标,我将其与 GeoNames citieJSON API 一起使用,以从 GPS 十进制坐标获取附近的大城市。

这是我的 GitHub 存储库中的 Java 方法:FusionTableModifyJava

我有一个十进制 GPS 位置,我需要找到该位置“附近”最大的城市/州。我需要一个相对准确的边界框来传递到 carsJSON GeoNames Web 服务,以获取该边界框中最大的城市。我传递了我感兴趣的位置和“半径”(以公里为单位),它返回了传递给城市所需的北、南、东、西十进制坐标。

(我发现这些资源对我的研究很有用:

计算纬度/经度点之间的距离、方位等。

经度 - 维基百科

它不是超级准确,但对于我使用它的用途来说已经足够准确了:

    // Compute bounding Box coordinates for use with Geonames API.
    class BoundingBox
    {
        public double north, south, east, west;
        public BoundingBox(String location, float km)
        {
             //System.out.println(location + " : "+ km);
            String[] parts = location.replaceAll("\\s","").split(","); //remove spaces and split on ,

            double lat = Double.parseDouble(parts[0]);
            double lng = Double.parseDouble(parts[1]);

            double adjust = .008983112; // 1km in degrees at equator.
            //adjust = 0.008983152770714983; // 1km in degrees at equator.

            //System.out.println("deg: "+(1.0/40075.017)*360.0);


            north = lat + ( km * adjust);
            south = lat - ( km * adjust);

            double lngRatio = 1/Math.cos(Math.toRadians(lat)); //ratio for lng size
            //System.out.println("lngRatio: "+lngRatio);

            east = lng + (km * adjust) * lngRatio;
            west = lng - (km * adjust) * lngRatio;
        }

    }

0
投票

这是一个老问题,但有人可能仍然在谷歌中找到它。

我们创建了一个

jts-geometry-utils
库,用于将 JTS 与 WGS84 坐标一起使用。它使用 geotools 包来检测最合适的本地 CRS,将几何图形投影到其中,执行需要以米为单位的距离(面积、长度、缓冲区、距离等)的几何操作,然后根据需要将操作结果重新投影回 WGS84

例如缓冲的工作原理就像

Geometry wgsGeometry = ...
Geometry bufferedWgs = ProjectionUtils.bufferProjected(wgsGeometry, 100);

查看https://github.com/Urban-Research-Lab/jts-geometry-utils

© www.soinside.com 2019 - 2024. All rights reserved.