【问题标题】:Display relation (trail) in leaflet在传单中显示关系(轨迹)
【发布时间】:2021-07-06 00:16:33
【问题描述】:

全部,

当我转到这个网址:OpenStreetMap 时,我看到一张地图,上面有一个“关系”(我假设这是正在显示的路径的术语)。

我试图让这条线索也显示在我使用 django-leaflet 的 Django 网站上。

目前我的代码如下所示:

<script>
    function map_init_basic (map, options) {
        map.setZoom(16);
        map.setView([51.6020, 4.8514]);
    }
</script>
{% leaflet_map "trailmap" callback="window.map_init_basic" %}

这会将地图设置到正确的区域,但如何添加实际路径?

致以最诚挚的问候。

【问题讨论】:

    标签: leaflet openstreetmap django-leaflet


    【解决方案1】:

    使用OSMPythonTools,您可以使用 Overpass API 从 OSM 数据库中获取轨迹关系,并将其几何图形提取为坐标数组:

    from OSMPythonTools.overpass import Overpass
    overpass = Overpass()
    
    def fetch_relation_coords(relation): 
        rel = overpass.query('rel(%s); (._;>;); out;' % relation)
        coords = [el.geometry().coordinates for el in rel.elements() if el.type() == 'node']
    
        # Convert (lng, lat) to (lat, lng)
        latlngs = [[x[1], x[0]] for x in coords]
    
        return latlngs
    
    latlngs = fetch_relation_coords("6754945")
    
    # [[51.602685, 4.861282], [51.60629, 4.851437], [51.599504, 4.838481], [51.599561, 4.839231], ...]
    

    我对 Django 不够熟悉,无法理解如何将生成的坐标数组放到您的网页上,但是一旦您在 Javascript 中使用了它,您就可以将它作为折线添加到您的 Leaflet 地图中:

     L.polyline(latlngs).addTo(map);
    

    【讨论】:

    • 这太棒了,我绝对可以从这里拿走thanx!当它起作用时,我会实施并接受答案!
    • 我确实遇到了一个问题,节点是排序的,但是按照“方式”,所以选择一个随机的顺序会使路径充满纵横交错的线条,如果这是有道理的。按 ID 对方式进行排序,然后按该顺序使用节点列表会降低效果,但是,仍然有两条线通过中心连接两个相对的节点。我希望这是有道理的,我不能在这里粘贴任何图像......
    • 好的,我解决了这个问题。在elements 对象中有一个叫做“relation”的对象,这个对象包含了对象应该被排序的顺序。当您按照定义对“方式”对象进行排序时,可以按顺序提取节点并用于绘制整个轨迹而不会产生怪异。我在这里删除了2个以前的答案,因为我很困惑。如何最好地将我的发现添加到此页面?
    • 好吧,关系似乎并不总是包含正确的方式顺序。我在这里发布了一个后续问题:stackoverflow.com/questions/68375034/…
    【解决方案2】:

    在地图上添加路径非常简单。您应该能够在map_init_basic() 函数的底部添加一行代码,例如L.polyline(latlngs).addTo(map);(其中latlngs 是一组[lat, lng] 坐标对,用于定义您的路线);或L.geoJSON(trail).addTo(map);(其中trail 是描述轨迹的GeoJSON 格式对象)。有关详细信息,请参阅 PolylineGeoJSON 的传单文档。

    更复杂的部分是如何获取轨迹的 lat/lng 数据。一种方法是使用Overpass Turbo 在线API 从OpenStreetMap 检索数据。在 Overpass 窗口左侧输入以下查询,点击“运行”,然后切换到“数据”选项卡查看结果:

    rel(6754945);  // Id number of the OSM Relation to fetch.
    (._;>;);
    out;
    

    数据选项卡应显示构成编码为 OSM XML 文件的轨迹的点。您可以复制它并操作文本以提取坐标,或者使用 Overpass 中的“导出”菜单将数据下载为 GeoGSON 或各种其他格式。将数据放到地图上的最佳方式取决于应用程序的详细信息,但如果 data 是一个字符串,其中包含用于跟踪的 GeoJSON,那么这会将其添加到地图上:

    L.geoJSON(JSON.parse(data)).addTo(map);
    

    How to convert an OSM relation to a list of lat/lng points?的回答中描述了获取轨迹坐标的其他一些选项

    【讨论】:

    • 谢谢,这很有帮助。我注意到其他网站都是这样做的(代码中包含纬度/经度列表),但我希望避免这种情况,因为该关系已经在 OpenStreetMap 上。但也许我误解了 OSM 和 Leaflet 的含义。我已经能够使用 OSMPythonTools 通过 OSM API 为这种关系提取数据,也许我可以使用 Django 动态获取 lon/lats 列表。不过,这感觉像是一种解决方法。
    • 也许我应该将所有这些关系拉入我的本地数据库并不时检查更新。这也可以保护我免受意外。
    • 虽然 OSM 基于矢量,但它的设计目的是在服务器端呈现并作为光栅图块使用,格式化以显示感兴趣的特征。因此,我不确定是否有一个特别方便的 API 可以动态获取单个功能。但是,OSMPythonTools 可以自动执行我上面建议的操作。我将添加另一个答案...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 2012-12-08
    • 1970-01-01
    相关资源
    最近更新 更多