【问题标题】:Leaflet do not display points of a particular color from a layerGroup传单不显示图层组中特定颜色的点
【发布时间】:2016-10-22 20:01:06
【问题描述】:

我正在使用传单绘制与车辆相关的路径。每条车辆路径都由一个 layerGroup 组成,以便在路径中具有不同的颜色(因为颜色取决于温度)。数据以以下格式从 Web 套接字接收(由 chromium 的调试控制台显示):

Object {color: "#cc0099", legende: "<someHtmlCode.TheSameForEveryPieceOfData>", data: {lat: 48.77905, lon: -3.44891}, c2a_id: "vehicle_1"}

我的问题是,对于某些颜色值(不同深浅的蓝色),路径没有绘制在地图上,但对于其他颜色值,它可以正常工作。在我更改缩放级别的情况下,所有内容都会显示(我使用的每种颜色)。

您可以看到第二张图片上出现了一些蓝色(在之前的路径上),它应该被淹没而无需更改缩放级别。

我将数据添加到图层的代码。

var idAllLayers;
if (_data != null && _data['data'] != null) {
    current_lon = _data['data']['lon'];
    current_lat = _data['data']['lat'];

    // checking if there is already a layer associated to the vehicle _id_
    if (!(this.layer_group_real_time.hasLayer(id))) {
        var multi_polyline = L.layerGroup([]);  //create a layer for this vehicle
        multi_polyline._leaflet_id = id;
        //add a sublayer to this one (for a sub path to have different colors)
        multi_polyline.addLayer(this.newLayer(id, _data['color']));
        this.layer_group_real_time.addLayer(multi_polyline);
    }

    // get the differents layers of the layerGroup for the vehicle _id_
    idAllLayers = this.layer_group_real_time.getLayer(id).getLayers();
    currentLayerLatLng = idAllLayers[idAllLayers.length-1].getLatLngs();
    if (current_lat != null && current_lon != null) {
        // if previous elements have been stored
        if (this.previousDataPoints[id] != null && this.previousColor[id] != null) {
            oldDataPoint = this.previousDataPoints[id]['data'];
            delta = this.measure(current_lat, current_lon, oldDataPoint['lat'], oldDataPoint['lon']);
            if (delta > MAX_DIST || _data['color'] != this.previousColor[id]) { 
                if (delta < MAX_DIST){  // case where color has changed but we still need to add the point to the previous subpath
                    currentLayerLatLng.push(L.latLng(current_lat, current_lon));
                }                                     
                this.layer_group_real_time.getLayer(id).addLayer(this.newLayer(id, _data['color']));
                idAllLayers = this.layer_group_real_time.getLayer(id).getLayers();
                currentLayerLatLng = idAllLayers[idAllLayers.length - 1].getLatLngs();
             }
         }
         currentLayerLatLng.push(L.latLng(current_lat, current_lon));
         idAllLayers[idAllLayers.length - 1].setLatLngs(currentLayerLatLng);  // setting up the new coords
         this.previousDataPoints[id] = _data;
         this.previousColor[id] = _data['color'];
     }
 }

newLayer: function (_id, _color) {
        var nl = L.polyline([],
            {
                color: _color,
                opacity: 0.7,
                stroke: true,
                weight: 6,
                vehicle_id: _id
            });
        nl.on('click', this.traceOnClick);
        return nl;
    },

[编辑]

这是我在Github 上上传的“最小、完整且可验证的示例”(至少我希望如此)。它包含一个地图,其中显示了一些路径。加载时显示的路径应为绿色和粉红色,但如果您更改缩放级别,则应出现蓝色路径。我已经整合了@Jieter 和@snkashis 的建议,但问题仍然存在。

【问题讨论】:

  • 您的示例有点难以阅读,但我注意到您分配了_leaflet_ids。这不是您应该做的事情,它可能会起作用,但也可能会引入一些难以跟踪的错误。你可能有 id-collisions 吗?
  • 我这样做是为了轻松找到与一辆车关联的 layerGroup(如果它不存在,我会为一辆车创建 multi_polyline)。它是针对每个车辆层完成的,但不是在子层级别(我添加到multi_polyline 的那些)。我不认为我有 id-collisions,我对这样的事情没有错误,也没有任何点被添加到错误的路径中。我必须承认我不知道如何确定这一点。但是我会尝试改变我处理每辆车不同层的方式,而不分配_leaflet_id
  • Leaflet 以_leaflet_ids 作为键将图层保存在对象中。如果您的图层消失了,我怀疑某些内容会因为 id 不再唯一而被覆盖。
  • 我已经更改了我的代码,所以_leaflet_id 不再被直接编辑。我使用一些关联数组轻松找到与我的车辆关联的layerGroup。不幸的是,什么都没有改变:“蓝色”子图层在添加点时仍然不显示,仅在更改缩放级别时出现。令人不安的一点是,只有在我的路径的“蓝色”段添加一个点时才会出现问题。
  • 如果我们可以查看minimal, complete and verifiable example 会更容易调试

标签: javascript leaflet


【解决方案1】:

我仍然在您的示例中看到 multi_polyline._leaflet_id = id;..为什么您不使用 L.Util.setOptions 来标记您自己的内部标识符(车辆 ID 等)?

【讨论】:

  • 当我拿到这段代码时,它就是这样完成的,我不知道 L.Util.setOptions。我已经更改了我的代码以使用它,但问题仍然存在。我已经用 GitHub 上的示例更新了我的帖子。
  • 您是否有特定原因不能使用预建插件来实现此功能,例如 iosphere.github.io/Leaflet.hotline/demo 而不是创建另一个实现?
  • 我不知道这个插件的存在。我试过了。它做了一些很好的事情,但对我来说似乎有点沉重(地图/浏览器在显示实时数据几分钟后变得非常慢)并且它也是地图控件的一些问题的根源(例如拖动地图)。
【解决方案2】:

最后我想到了将车辆层的类型从L.layerGroup 更改为L.geoJson。它奏效了!即使我不知道为什么。

我已经用我的解决方案更新了Git repository


(正如之前在 cmets 中所说,我也停止使用 multi_polyline._leaflet_id = id;,现在使用 L.Util.setOptions(vehicleLayer, {vehicle_id: id});。顺便说一下,我已将 multi_polyline 重命名为 vehicleLayer。)

【讨论】:

  • 我在将您的解决方案转换为可行的解决方案方面有点慢(因为注意到您可以使用它,所以停止了它的工作),一些说明:
  • L.LatLng 有一个 distanceTo 方法,它可以完成您的 measure 函数的工作。使用完整的 latlng 对象可以稍微减少代码中的混乱,因为您现在需要的变量减少了 2 倍。
  • 您的示例在 18k 的 JS 代码中并不完全是最小的,您可以用 10 段来说明问题。
  • 我已经用distanceTo 替换了我的`measure` 函数。它工作得很好,代码更容易阅读。我会记住你在下一篇文章中的第二条建议。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
相关资源
最近更新 更多