java - 从路线坐标构建 GeoTools 几何图形 "segments"

标签 java algorithm geotools

根据一组定义路线的坐标,我想绘制一个模拟该轨道的理论高速公路的几何图形,给定任意米宽(例如 20 米)

我不知道 GeoTools 是否提供了用这样的输入构造一个 Geometry 的工具,所以我最初的想法是将轨道坐标(几千个)成对分割(coord0, coord1), (coord1, coord2), ...., (coordN, coordN-1) 和每对,构建一个矩形,假设这两个点是 20 米宽线段的中点(如 Knowing two points of a rectangle, how can I figure out the other two? 中所示),并连接所有生成的几何图形

也许这有点矫枉过正,但我​​还没有找到更便宜的方法来做到这一点

任何想法将不胜感激!

最佳答案

执行此操作的简单方法是在根据您的点创建的线周围使用 20 米的缓冲区。所以像这样的一些代码从点创建一条线(:

String[] wkt = {
    "Point (-0.13666168754467312 50.81919869153657743)",
    "Point (-0.13622277073931291 50.82205165077141373)",
    "Point (-0.13545466632993253 50.82512406840893959)",
    "Point (-0.13457683271921211 50.82687973563037787)",
    "Point (-0.13413791591385191 50.82907431965718104)",
    "Point (-0.13951464677951447 50.8294035072611976)",
    "Point (-0.14346489802775639 50.83082998687861931)",
    "Point (-0.14697623247063807 50.83072025767727808)",
    "Point (-0.15004865010815954 50.83390240451614517)",
    "Point (-0.15740050659794308 50.8349996965295432)",
    "Point (-0.16486209228906662 50.83741373895902171)",
    "Point (-0.17276259478555042 50.83894994777778464)",
    "Point (-0.18549118214099652 50.8387304893751022)"
    };

    //build line
    WKTReader2 reader = new WKTReader2();
    GeometryFactory gf = new GeometryFactory();
    Coordinate[] points = new Coordinate[wkt.length];
    int i=0;
    for(String w:wkt) {
      Point p;
  try {
    p = (Point) reader.read(w);
    points[i++]=p.getCoordinate();
  } catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }

    }
    LineString line = gf.createLineString(points);
    SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema);
    builder.set("locations", line);
    SimpleFeature feature = builder.buildFeature("1");

然后是 BufferLine 方法,例如:

public SimpleFeature bufferFeature(SimpleFeature feature, Measure<Double, Length> distance) {
    // extract the geometry
    GeometryAttribute gProp = feature.getDefaultGeometryProperty();
    CoordinateReferenceSystem origCRS = gProp.getDescriptor().getCoordinateReferenceSystem();

    Geometry geom = (Geometry) feature.getDefaultGeometry();
    Geometry pGeom = geom;
    MathTransform toTransform, fromTransform = null;
    // reproject the geometry to a local projection
    if (!(origCRS instanceof ProjectedCRS)) {

        Point c = geom.getCentroid();
        double x = c.getCoordinate().x;
        double y = c.getCoordinate().y;

        String code = "AUTO:42001," + x + "," + y;
        // System.out.println(code);
        CoordinateReferenceSystem auto;
        try {
            auto = CRS.decode(code);
            toTransform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
            fromTransform = CRS.findMathTransform(auto, DefaultGeographicCRS.WGS84);
            pGeom = JTS.transform(geom, toTransform);
        } catch (MismatchedDimensionException | TransformException | FactoryException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    // buffer
    Geometry out = buffer(pGeom, distance.doubleValue(SI.METER));
    Geometry retGeom = out;
    // reproject the geometry to the original projection
    if (!(origCRS instanceof ProjectedCRS)) {
        try {
            retGeom = JTS.transform(out, fromTransform);
        } catch (MismatchedDimensionException | TransformException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    // return a new feature containing the geom
    SimpleFeatureType schema = feature.getFeatureType();
    SimpleFeatureTypeBuilder ftBuilder = new SimpleFeatureTypeBuilder();
    ftBuilder.setCRS(origCRS);
    // ftBuilder.setDefaultGeometry("buffer");
    ftBuilder.addAll(schema.getAttributeDescriptors());
    ftBuilder.setName(schema.getName());

    SimpleFeatureType nSchema = ftBuilder.buildFeatureType();
    SimpleFeatureBuilder builder = new SimpleFeatureBuilder(nSchema);
    List<Object> atts = feature.getAttributes();
    for (int i = 0; i < atts.size(); i++) {
        if (atts.get(i) instanceof Geometry) {
            atts.set(i, retGeom);
        }
    }
    SimpleFeature nFeature = builder.buildFeature(null, atts.toArray());
    return nFeature;
}

/**
 * create a buffer around the geometry, assumes the geometry is in the same
 * units as the distance variable.
 * 
 * @param geom
 *          a projected geometry.
 * @param dist
 *          a distance for the buffer in the same units as the projection.
 * @return
 */
private Geometry buffer(Geometry geom, double dist) {

    Geometry buffer = geom.buffer(dist);

    return buffer;

}

棘手的部分是重新投影到局部平坦的 CRS 中,以便您可以使用米作为缓冲区大小。如果您知道局部良好的投影,您可以使用它(在这种情况下,我们可以使用 OSGB (EPSG:27700) 以获得更好的结果)。

这给出了以下 map :

enter image description here

关于java - 从路线坐标构建 GeoTools 几何图形 "segments",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43934957/

相关文章:

java - 找不到 Activity 异常

JavaFX:ImageView 仅显示图像一次

c++ - 更大图中最大二分匹配的有效技巧

java - 在 map 上显示线串的方向 - 在 map 上自动缩放

Hadoop 和地理服务器

java - Reactor - 为两个流编写值检查的更好方法

java - 如何修复 limax.zdb.XError : dbhome "zdb" not exist?

c++ - LeetCode问题:改进执行时间而不使用哈希吗?

algorithm - 从 POP3 服务器高效地获取未检索到的消息 ID

java - 在 map 上显示连接点的线 - 接收空 map