在leaflet中标记之间画线

29

我正在尝试在leaflet中在标记之间插入线条(这些标记是从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"
      }
    }
  ]
}

1
那么,将代码格式化为可读格式怎么样?如果这对你来说太费力了,那么对于任何人来说,尝试帮助你使其正常工作也可能是太费力了。一个适当的问题描述也会有所帮助,其中包括错误和发生情况的描述。 - charlietfl
抱歉,你是对的,我的英语不好,我试图更好地解释发生了什么,谢谢。 - user4131013
你的JSON似乎有问题。当我将它插入http://jsonlint.com/时,它指出其中存在错误。 - Bruce P
我已经编辑了问题,试图提高可读性。第一个代码片段有一点修改,但大部分是英文文本。需要注意的是,如果您将来发布JSON数据或任何其他单行非常长的内容,最好先重新格式化为可读形式。人们很难阅读压缩过的JSON并理解其含义,帮助人们阅读您的问题可以更快地获得答案。我已经这样做了,但如果您自己这样做会更好。 - Dan Lowe
@BruceP 原始的JSON无效,因为缺少闭合的]}。省略闭合括号是常见的粘贴错误,所以我添加了它们。如果JSON数据仍然不完整,OP将不得不编辑问题。按照现在的写法,它是有效的。 - Dan Lowe
谢谢Dan Lowe,感谢您的帮助。 - user4131013
2个回答

22

您可以通过迭代原始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$.getJSON 函数之后使用它,就像这样:

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

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


1
当迭代 data._layers 对象属性时要小心:根据 JS 规范,迭代顺序不被保证。因此,结果的折线可能以任何顺序连接点…即使我有机会进行的所有测试都给出了一致的顺序。 - ghybs
谢谢您的回复。如果我想添加这些选项,我需要您做什么。再次感谢您。 { color: 'red', weight: 10, opacity: .7, dashArray: '20,15', lineJoin: 'round' } - user4131013
当我使用这段代码 pathCoords = connectTheDots(window.geojson); var pathLine = L.polyline(pathCoords).addTo(map) 时,我得到了一个错误:connectTheDots未定义。 - user4131013
非常感谢,我懂了。感谢你的帮助。另一个问题是如何隐藏这些行?再次感谢。 - user4131013
@nathansnider 我能否根据特定的geojson属性连接点?例如,基于状态。如果状态为“是”,则具有相同状态的点应该连接起来。 - Bruce

7

编辑:

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);

GeoJSON数据将被转换为Leaflet中的折线、多边形等矢量和点要素标记。
当您想指定Leaflet如何设置矢量的样式时,确实应该构建一个包含路径选项(就像第一行上的变量style)的对象,但是您应该将其作为L.geoJson层的样式选项,而不是在图标内部。
当您想指定Leaflet如何设置标记的样式时,确实可以设置特定的图标,这仅适用于点要素。您最好使用pointToLayer选项,因为该代码仅适用于点,而不是尝试将其应用于矢量(例如没有setIcon方法)。
最后,当您想执行某些对矢量和标记都适用的操作时,可以使用onEachFeature选项,例如绑定您的弹出窗口。
因此,您最终会得到类似以下内容:
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);
    }

});

正如评论中所指出的,每当你向其他人寻求帮助时,如果你花时间详细说明问题,并附上描述/屏幕截图以及一些干净的代码,那么你会使他们的任务更容易(因此你会得到更好,更快的支持)。对于客户端代码来说,一个很好的做法是在例如 jsFiddle 上复现该问题。


非常感谢您。我上传了一张图片,更好地解释了我的问题。 - user4131013
哇,这与我最初的理解完全不同!在我看来,你的GeoJSON中似乎有缺失的数据(但你没有展示出来,所以我不能确定)。你似乎只有点数据,而没有折线。因此,你可能需要自己构建路径,可能要假设点的顺序是正确的... - ghybs
谢谢您的回复,如果我想添加这些选项,我需要您做什么,再次感谢。{ 颜色:'红色', 重量:10, 不透明度:0.7, 虚线数组:'20,15', 线条连接方式:'圆角' } - user4131013
请参考 Leaflet Polyline API,该API接受Path options。您只需在坐标后添加样式定义对象即可:L.polyline(connectDots(data), { color: "red" /* etc. */ }) - ghybs
当我测试你的代码时,出现了 TypeError: features 未定义。 - user4131013
我正在尝试以以下方式调用函数:$.getJSON('data.php', function(data) { connectDots(data); window.geojson = L.geoJson(data, { - user4131013

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接