在传单中的标记之间画线

Posted

技术标签:

【中文标题】在传单中的标记之间画线【英文标题】:Draw lines between markers in leaflet 【发布时间】:2016-02-01 19:43:43 【问题描述】:

我正在尝试在传单中的标记(由 JSON 数据生成)之间插入线条。我看到了一个例子,但它不适用于 JSON 数据。我可以看到标记,但没有出现线条。

var style = 
  color: 'red',
  fillColor: "#ff7800",
  opacity: 1.0,
  fillOpacity: 0.8,
  weight: 2
;

$.getJSON('./server?id_dispositivo=' + id_device + '', function(data) 
  window.geojson = L.geoJson(data, 
    onEachFeature: function (feature, layer) 
      var Icon = L.icon(
        iconUrl: './images/mymarker.png',
        iconSize: [18, 28], // size of the icon
        style: style,
      );
      layer.setIcon(Icon);
      layer.bindPopup(feature.properties.date + '<br />' + feature.properties.id);
    
  );
);
map.addLayer(geojson);

我的 JSON 数据:


  "type": "FeatureCollection",
  "features": [
    
      "type": "Feature",
      "geometry": 
        "type": "Point",
        "coordinates": [
          -70.219841,
          8.6310997
        ]
      ,
      "properties": 
        "id": 336,
        "id_user": 1,
        "id_device": 1,
        "timestamp": 1446571154,
        "date": "12:49PM 03-11-2015",
        "Latitude": 8.6310997,
        "Longitude": -70.219841,
        "speedKPH": 0,
        "heading": "",
        "Name": "N\/D",
        "City": "N\/D",
        "estatus": "Stop"
      
    
  ]

【问题讨论】:

如何格式化该代码以使其可读。如果你做这件事太费力了,那么任何人试图帮助你让它发挥作用都可能太费力了。适当的问题描述也会有所帮助,其中包括错误和正在发生的事情的描述 对不起,我的英语不好,我试图更好地解释发生了什么,谢谢。 您的 json 似乎有问题。当我将它插入jsonlint.com 时,它表明它存在错误。 我已编辑问题以尝试提高可读性。有点第一个代码sn-p,但主要是英文文本。请注意,将来如果您要发布 JSON 数据或其他任何很长的行,如果您首先将其重新格式化为可读形式,这将非常有帮助。人们很难阅读缩小的 JSON 并理解它,而帮助人们阅读您的问题有助于更快地获得答案。我已经这样做了,但如果你这样做会更好。 @BruceP 原始 JSON 无效,因为缺少结束 ]。省略右括号是一个常见的粘贴错误,所以我添加了它们。如果 JSON 数据仍然不完整,OP 将不得不编辑问题。正如现在所写,它验证了。 【参考方案1】:

有很多方法可以通过迭代原始 GeoJSON 或生成的 L.GeoJson 层来生成折线几何图形。这是一个简单的函数,它将点的L.geoJson 层转换为可以传递给L.polyline 的坐标数组:

function connectTheDots(data)
    var c = [];
    for(i in data._layers) 
        var x = data._layers[i]._latlng.lat;
        var y = data._layers[i]._latlng.lng;
        c.push([x, y]);
    
    return c;

这是一个小提琴,展示了它在一些合成 GeoJSON 数据上的作用:

http://jsfiddle.net/nathansnider/36twhxux/

假设您的 GeoJSON 数据仅包含点几何,您应该能够在您的 window.geojson 中定义 window.geojson 后使用它,如下所示:

pathCoords = connectTheDots(window.geojson);
var pathLine = L.polyline(pathCoords).addTo(map)

如果您的 GeoJSON 数据更复杂,您可能需要添加一些条件来检查几何类型等,但这至少应该让您大致了解如何继续。

【讨论】:

谨慎迭代data._layers 对象属性:不保证按照JS 规范的迭代顺序。生成的折线可以按任何顺序连接点……尽管我有机会进行的所有测试都给出了一致的顺序。 感谢您的回复,如果我想要添加此选项我需要您做什么。再次感谢颜色:'红色',重量:10,不透明度:.7,dashArray:'20,15',lineJoin:'round' 使用此代码时 pathCoords = connectTheDots(window.geojson); var pathLine = L.polyline(pathCoords).addTo(map) 我得到一个错误 connectTheDots is not defined 非常感谢我明白了,感谢您的帮助,另一个问题如何隐藏线条,再次感谢您 @nathansnider 我可以根据特定的 geojson 属性加入积分吗?例如基于状态。如果状态为是,则应连接具有相同状态的点。【参考方案2】:

编辑:

Nathan 的想法是正确的,因为您必须自己构建一条折线(标记之间的线)。

严格来说,您必须在点列表仍然是一个数组时使用您的数据(并假设数组顺序是您想要获得的线连接的顺序)。这意味着您必须直接处理您的 GeoJSON 数据。

例如,你会这样做:

function connectDots(data) 
    var features = data.features,
        feature,
        c = [],
        i;

    for (i = 0; i < features.length; i += 1) 
        feature = features[i];
        // Make sure this feature is a point.
        if (feature.geometry === "Point") 
            c.push(feature.geometry.coordinates);
        
    
    return c;


L.polyline(connectDots(data)).addTo(map);

Leaflet 会将 GeoJSON 数据转换为 vectors 用于折线、多边形等,以及 ma​​rkers 用于点特征。 请参阅传单tutorial 和reference。

当您想指定 Leaflet 应如何设置 向量 的样式时,您确实应该创建一个包含 path options 的对象(例如第一行的 style 变量),但您应该给出它是L.geoJson 层的style option,而不是图标内。

当您想指定 Leaflet 应如何设置 标记 的样式时,您确实可以设置一个特定的图标,该图标仅适用于点特征。您最好使用pointToLayer option,因为代码实际上只应用于点,而不是尝试将其应用于向量(例如,没有方法setIcon)。

最后,当您想要执行一些适用于向量和标记的操作时,您可以使用onEachFeature option,例如绑定您的弹出窗口。

所以你最终会得到类似的东西:

var myIcon = L.icon(
    iconUrl: './images/mymarker.png',
    iconSize: [18, 28]
);

var geojson = L.geoJson(data, 

    style: style, // only applies to vectors.

    // only applies to point features
    pointToLayer: function(feature, latlng) 
        return L.marker(latlng, icon: myIcon);
    ,

    // will be run for each feature (vectors and points)
    onEachFeature: function(feature, layer) 
        layer.bindPopup(feature.properties.date + '<br />' + feature.properties.id);
    

);

正如 cmets 中所指出的,每当您寻求其他人的帮助时,如果您花时间正确陈述您的问题,并附上描述/屏幕截图,您会更轻松地完成他们的任务(因此您会获得更好更快的支持)出了什么问题并发布了一些干净的代码。例如,客户端代码的一个非常好的做法是在 jsFiddle 上重现该问题。

【讨论】:

非常感谢,我放了一张可以更好地解释我的问题的图片 哇,这和我最初的理解真的很不一样!在我看来,您的 GeoJSON 中缺少数据(但您没有显示它,所以我不能确定)。您似乎只有点数据,但没有折线。所以你必须自己建立路径,可能假设点顺序是正确的...... 谢谢你的回复如果我想要添加这个选项我需要你做什么再次谢谢你颜色:'红色',重量:10,不透明度:0.7,dashArray:'20,15 ', lineJoin: '圆形' 请参阅传单Polyline API,它接受Path options。您只需在坐标后添加样式定义对象:L.polyline(connectDots(data), color: "red" /* etc. */ ) 当我测试你的代码时,我得到 TypeError: features is undefined

以上是关于在传单中的标记之间画线的主要内容,如果未能解决你的问题,请参考以下文章

使折线捕捉到传单中的道路

R传单中的标记鼠标单击事件以实现闪亮

为传单中的标记分配 ID

单击反应传单 v.3.x 中的标记时如何动态更改地图缩放?

以编程方式触发 R 传单中的标记鼠标单击事件以实现闪亮

在角度传单指令中旋转标记