维护 MultiLineString 上的拓扑

Posted

技术标签:

【中文标题】维护 MultiLineString 上的拓扑【英文标题】:Maintaining the topology on a MultiLineString 【发布时间】:2021-09-09 11:46:26 【问题描述】:

我正在尝试通过使用 TopoJSON 的 Leaflet-Geoman 插件来获得线条的拓扑移动。有一个 method 叫 topojson.mesh ,它

返回 GeoJSON MultiLineString 几何对象,表示给定拓扑中指定对象的网格。这对于有效地在复杂对象中渲染笔触很有用,因为由多个特征共享的边缘只被描边一次。如果未指定object,则返回整个拓扑的网格。

感谢在this 帖子中的回答,我已经能够使用topojson.mesh 返回 MultiLineString。由于 Leaflet-Geoman 支持 MultiLineString,我想到了可以使用 Leaflet-Geoman 编辑返回的网格,同时保持拓扑属性。

但是当我尝试完成它时,当我尝试使用 geoman 插件对其进行编辑时,返回的 MultiLineString 会分成两部分。我的问题是它是否真的是从topojson.mesh 返回的网格,为什么这些线会分开?这是由geoman插件引起的吗?如果是这样,我怎样才能完成它?有什么方法可以在保持拓扑的同时通过拖动来改变节点的位置?

我会附上下面的代码

<!DOCTYPE html>
<html>

<head>
    <title>Topology Test</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="src/css/leaflet.css" />
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
    <link rel="stylesheet" href="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.css" />

    <style>
        #mapdiv 
            height: 899px;
            background-color: #acd6e2;
        
    </style>

</head>

<body>
    <div id="mapdiv"></div>
    <script src="https://unpkg.com/topojson@3"></script>
    <script src="src/js/leaflet-src.js"></script>
    <script src="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.min.js"></script>
    <script>
        var mymap = L.map('mapdiv', 
            layers: [
                new L.TileLayer('https://s.tile.openstreetmap.org/z/x/y.png', 
                    'attribution': 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
                )
            ],
        );

        mymap.pm.addControls(
            position: 'topleft',
            drawCircle: false,
        );


        fetch("data/data.geojson")
            .then(res => res.json())
            .then(json => 

                //var layer = L.geoJSON(json).addTo(map);
                var topo = topojson.topology([json]);

                console.log(json, topo, topojson.mesh(topo));

                var layerLines = L.geoJson(topojson.mesh(topo), 
                    fill: false,
                ).addTo(mymap);


                mymap.fitBounds(layerLines.getBounds());

            );
    </script>


</body>

</html>

data.geojson

 
  "type": "FeatureCollection",
  "features": [
    
      "type": "Feature",
      "properties": ,
      "geometry": 
        "type": "Polygon",
        "coordinates": [
          [
            [
              -113,
              37
            ],
            [
              -113,
              40
            ],
            [
              -109,
              40
            ],
            [
              -109,
              37
            ],
            [
              -113,
              37
            ]
          ]
        ]
      
    ,
    
      "type": "Feature",
      "properties": ,
      "geometry": 
        "type": "Polygon",
        "coordinates": [
          [
            [
              -109,
              37
            ],
            [
              -109,
              39
            ],
            [
              -104,
              39
            ],
            [
              -104,
              37
            ],
            [
              -109,
              37
            ]
          ]
        ]
      
    ,
    
      "type": "Feature",
      "properties": ,
      "geometry": 
        "type": "Polygon",
        "coordinates": [
          [
            [
              -109,
              34
            ],
            [
              -109,
              37
            ],
            [
              -102,
              37
            ],
            [
              -102,
              34
            ],
            [
              -109,
              34
            ]
          ]
        ]
      
    ,
    
      "type": "Feature",
      "properties": ,
      "geometry": 
        "type": "Polygon",
        "coordinates": [
          [
            [
              -104,
              37
            ],
            [
              -104,
              40
            ],
            [
              -100,
              40
            ],
            [
              -100,
              37
            ],
            [
              -104,
              37
            ]
          ]
        ]
      
    
  ]

【问题讨论】:

正如名字所说的MultiLineString,形状中有多条线,所以它们已经被分割但显示为一条。但在编辑时,Geoman allwos 编辑 MultiLineString 个体的每一行。你认为 Geoman 应该怎么做? @FalkeDesign 我的假设是,保持一切都像一个网格并移动所有节点,而不是将它们分成多行。这就是我在这里使用 topoJSON 的原因。 但移动对我有用,只有编辑会显示分隔线 @FalkeDesign 是的,我需要的是在编辑时,行不应该分开。那可能吗?还是我错过了什么? 不可能,因为topojson.mesh 已经创建了两行。您只能尝试找到一种方法将其合并到一行。但我不知道如何 【参考方案1】:

对于正在寻找此类问题答案的任何人,我找到了一种使用 OpenLayers v6.5.0 的方法。他们是Draw and Modify Features的一个例子,可以维护线和多边形的拓扑结构。

希望这对某人有所帮助:)

【讨论】:

以上是关于维护 MultiLineString 上的拓扑的主要内容,如果未能解决你的问题,请参考以下文章

在 GeoJson MultiLineString 中查询哪个 LineString

访问与 LINESTRING M 和 MULTILINESTRING M 几何相关的 M 值

显示目录拓扑的页面

维护网站上的链接

cogs1958 菜肴制作 拓扑排序

发现环 (拓扑或dfs)