【问题标题】:HERE Traffic incidents integration in Leaflet.jsLeaflet.js 中的 HERE 交通事件集成
【发布时间】:2021-02-02 10:56:51
【问题描述】:

背景:

我目前正在将 HERE 地图集成到我们基于 Web 的应用程序中。我正在尝试两者 - HERE 同时提供了 Javascript API 和 Leaflet,以便为我们的用例找到最佳方法。

虽然 HERE 地图提供的 JavaScript API 没问题,但在使用光栅图块时,Leaflet 的渲染效果要好得多。

问题:

我可以使用光栅图块 + 传单,但我们的应用程序还需要显示交通事件数据。

交通事故数据由 HERE 以 JSON 和 XML 格式(Documentation linkExample JSON)提供。他们提供[Z]/[X]/[Y]quadkeyproxbboxcorridor过滤器,可用于检索过滤后的数据集。

我尝试使用[Z]/[X]/[Y] 寻址和自定义L.TileLayer 实现,该实现加载适当的JSON,将其转换为GeoJSON 并在地图上显示GeoJSON。然而,这种方法效率非常低,并且可以看到明显的性能下降。

问题:

也许有人已经解决了这个问题,并且可以分享有关如何在Leaflet 地图上显示 HERE 交通事件而不会遇到性能问题的任何见解?

【问题讨论】:

  • 一些问题需要为外行澄清一些问题:来自 HERE 的 JSON 显示了各种 GEOLOC 字段,这些字段具有 ORIGINTO 字段,基本上是 latlngs。您是否只是试图将这些渲染为点,而大量的点会导致性能问题?或者数据是否包含其他形状?如果它只是点,您是否在单独渲染点上死心塌地(而不是对它们进行聚类或使用热图)?澄清这些事情可能有助于我们了解您想要做什么。您的设置示例代码也会对我们有所帮助(如果不是至关重要的话)。
  • 基本上,在有ORIGINTO 的地方,我只画了两个标记——一个在ORIGIN,一个在TO。由于数据是交通事故,我需要单独渲染它们,因为聚类并不是这种数据可视化的好方法。我知道常规标记不起作用,因此我正在寻找一种更有效的解决方案,我可以在其中呈现自定义图标并在单击标记时显示一个包含更多详细信息的弹出窗口。

标签: javascript leaflet here-api traffic


【解决方案1】:

我创建了以下脚本,它没有任何性能问题:

var fg = L.featureGroup().addTo(map);
function loadTraffic(data) {
  fg.clearLayers();
  var d = data.TRAFFICITEMS.TRAFFICITEM.map((r) => {
    var latlngs = [];
    
    if (r.LOCATION.GEOLOC) {
      if (r.LOCATION.GEOLOC.ORIGIN) {
        latlngs.push(L.latLng(r.LOCATION.GEOLOC.ORIGIN.LATITUDE, r.LOCATION.GEOLOC.ORIGIN.LONGITUDE));
      }

      if (r.LOCATION.GEOLOC.TO) {
        if (L.Util.isArray(r.LOCATION.GEOLOC.TO)) {
          r.LOCATION.GEOLOC.TO.forEach((latlng) => {
            latlngs.push(L.latLng(latlng.LATITUDE, latlng.LONGITUDE));
          })
        } else {
          latlngs.push(L.latLng(r.LOCATION.GEOLOC.TO.LATITUDE, r.LOCATION.GEOLOC.TO.LONGITUDE));
        }
      }
    }
    var desc = r.TRAFFICITEMDESCRIPTION.find(x => x.TYPE === "short_desc").content;

    return {
      latlngs,
      desc
    }
  })
  console.log(d);

  d.forEach((road)=>{
    L.polyline(road.latlngs,{color: 'red'}).addTo(fg).bindPopup(road.desc);
  });
  map.fitBounds(fg.getBounds())
}

如果此脚本不适合您,请分享您的 json 文件。

【讨论】:

  • 如果是单个数据集就可以了,但是在这种情况下,每个缩放级别的每个图块的交通事件数据都是不同的,导致放大/缩放后设置的标记非常大出去。那就是发生性能下降的时候。我需要一种有效加载/卸载大量标记的方法。
  • 我认为您要做的就是在每次运行该函数时删除之前的功能组。 @Falke,你能修改代码来做到这一点吗?如果你把它加进去,我想你会有这个位置。这听起来不太复杂
  • 我更新了代码,以便在重新调用函数 f.ex 时删除旧层。在movend 事件中,这是在缩放和拖动地图后调用的。但我不知道这是否是@hockeyman 需要的。否则@hockeyman,您可以使用画布标记和/或 Leaflet 的canvas renderer,这会使性能也更好。
【解决方案2】:

好的,所以我找到了这个任务的解决方案。显然我走的很好,我只需要优化我的实现。

为了获得适当的表现,我必须做的是:

  • 创建自定义 CircleMarker 扩展,该扩展将在画布上绘制自定义图标
  • 创建 JS worker,它会从给定的 URL 获取数据,将其转换为 GeoJSON 并将 GeoJSON 返回给它的侦听器
  • 创建自定义GridLayer 实现,在fetchTile 函数中,创建worker 实例,向其传递已设置适当[Z]/[X]/[Y] 坐标的链接,添加侦听器,侦听worker 的done 事件并返回空磁贴
  • 在工作人员的 done 事件中,自定义 GridLayer 实现创建 GeoJSON 图层,将其添加到字典中,并以坐标为键,如果缩放级别仍然相同 - 将该图层添加到地图中
  • map 上添加zoomend 观察者,这会从地图中移除与当前缩放级别不匹配的所有图层

现在地图绝对可用,并且比原来的 HERE JS API 运行得更快。

P.S.很抱歉,由于我们公司的政策,我无法分享实施本身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-24
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    相关资源
    最近更新 更多