如何在使用GeoJSON行字符串的Leaflet中使用polyline-decorator?

时间:2018-07-18 09:05:01

标签: javascript leaflet geojson polyline-decorator

我根本不能将多线装饰器与GeoJSON行字符串一起使用。我只遵循了一条直线和直接坐标的教程,它可以正常工作,但是当我尝试使用GeoJSON时,它是行不通的。

这是我的GeoJSON行字符串声明:

var geoJsonLie = {
  "type": "FeatureCollection",
  "features": [{
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 150
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.28, -2.86
            ],
            [
              108.168, -2.97
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.168, -2.97
            ],
            [
              108.06399, -3.23
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 100
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.06399, -3.23
            ],
            [
              107.899, -3.09
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.899, -3.09
            ],
            [
              107.65099, -3.13039
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.65099, -3.13039
            ],
            [
              107.58299, -3.04692
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 350
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.58299, -3.04692
            ],
            [
              107.63576, -2.72322
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.63576, -2.72322
            ],
            [
              107.65699, -2.7366
            ]
          ]
        }
      }
    ]
  }]
};

这是我的代码来调用行字符串:

var arrow = L.geoJSON(geoJsonLie, {
  style: function(feature) {
    return {
      stroke: true,
      weight: 5
    };
  },
  onEachFeature: function(feature, layer) {
    layer.bindPopup("owner: " + feature.properties.owner + "<br>Bandwidth: " + feature.properties.bandwidth);
  }

}).addTo(map);
var arrowHead = L.polylineDecorator(arrow, {
  patterns: [{
    offset: '50%',
    repeat: 0,
    symbol: L.Symbol.arrowHead({
      pixelSize: 10
    })
  }]
}).addTo(map);

如果我在变量arrow中使用直接坐标,则效果很好,当我使用L.geoJSON时,它不起作用。我使用GeoJSON是因为我想在弹出窗口上显示properties属性。

1 个答案:

答案 0 :(得分:0)

似乎该库需要折线或多边形图层,而不是geojson图层。如果我们查看装饰源中的注释,则可以确认这一点:

/**
* Deals with all the different cases. input can be one of these types:
* array of LatLng, array of 2-number arrays, Polyline, Polygon,
* array of one of the previous.
*/

我没有仔细查看源代码,所以我不确定添加geojson支持有多容易。 但是,您可以通过一些操作将geojson转换为折线图层(并且仍然保留弹出窗口的数据,请参见下文):

var lines = geojson.features
    .filter(function(feature) { return feature.geometry.type == "LineString" })
    .map(function(feature) {
        var coordinates = feature.geometry.coordinates;
        coordinates.forEach(function(coordinate) { coordinate.reverse(); })
        return L.polyline(coordinates);
    })

您的geojson具有嵌套在另一个嵌套要素集合中的要素集合,在下面的示例中,我已删除了嵌套,如果没有,则需要扫描geojson.features来查找要素集合,如下所示:以及折线。通过删除嵌套的要素集合,代码会更简单

上面的代码在geojson中查找折线,颠倒坐标顺序(geojson为[long,lat],传单需要[lat,long]),并返回一个图层数组。如果需要,可以在此处将图层添加到地图上:return L.polyline(coordinates).addTo(map)

现在,我们可以按照记录的方式和您的方式应用折线装饰器(我在下面应用了两种装饰):

enter image description here

这是一个演示:

	var geojson = {
  "type": "FeatureCollection",
  "features": [{
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 150
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.28, -2.86
            ],
            [
              108.168, -2.97
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.168, -2.97
            ],
            [
              108.06399, -3.23
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 100
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.06399, -3.23
            ],
            [
              107.899, -3.09
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.899, -3.09
            ],
            [
              107.65099, -3.13039
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.65099, -3.13039
            ],
            [
              107.58299, -3.04692
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 350
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.58299, -3.04692
            ],
            [
              107.63576, -2.72322
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.63576, -2.72322
            ],
            [
              107.65699, -2.7366
            ]
          ]
        }
      }
    ]
};




	var mymap = L.map('mapid').setView([ -2.8,108], 9);

	L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
		maxZoom: 18,
		attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
			'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
			'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
		id: 'mapbox.streets'
	}).addTo(mymap);


	var lines = geojson.features
	    .filter(function(feature) { return feature.geometry.type == "LineString" })
		.map(function(feature) {
		    var coordinates = feature.geometry.coordinates;
			coordinates.forEach(function(coordinate) { coordinate.reverse(); })
		    return L.polyline(coordinates);
    	})

    var decorator = L.polylineDecorator(lines, {
      patterns: [
        {offset: 0, repeat: 20, symbol: L.Symbol.dash({pixelSize: 5})}
      ]
    }).addTo(mymap);

	
var arrowHead = L.polylineDecorator(lines, {
  patterns: [{
    offset: 0,
    repeat: 40,
    symbol: L.Symbol.arrowHead({
      pixelSize: 10,
	  pathOptions: {fillOpacity: 1, weight: 0}
    })
  }]
}).addTo(mymap);
 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>
 <script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js" integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q==" crossorigin=""></script>

<script src="http://bbecquet.github.io/Leaflet.PolylineDecorator/dist/leaflet.polylineDecorator.js"></script>


<div id="mapid" style="width: 600px; height: 400px;"></div>

好吧,那如何访问弹出窗口的属性呢?如果我们有一条实线,上面有间隔的标记(我相信您有),那么我们可以在创建线串时添加一个弹出窗口,然后将其添加到地图中:

var lines = geojson.features
    .filter(function(feature) { return feature.geometry.type == "LineString" })
    .map(function(feature) {
      var coordinates = feature.geometry.coordinates;
      coordinates.forEach(function(coordinate) { coordinate.reverse(); })
      return L.polyline(coordinates)
        .addTo(mymap)
        .bindPopup("<b>" + feature.properties.owner + "</b><br />" + feature.properties.bandwidth)
     })

var geojson = {
  "type": "FeatureCollection",
  "features": [{
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 150
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.28, -2.86
            ],
            [
              108.168, -2.97
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.168, -2.97
            ],
            [
              108.06399, -3.23
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 100
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.06399, -3.23
            ],
            [
              107.899, -3.09
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.899, -3.09
            ],
            [
              107.65099, -3.13039
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.65099, -3.13039
            ],
            [
              107.58299, -3.04692
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 350
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.58299, -3.04692
            ],
            [
              107.63576, -2.72322
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.63576, -2.72322
            ],
            [
              107.65699, -2.7366
            ]
          ]
        }
      }
    ]
};




	var mymap = L.map('mapid').setView([ -2.8,108], 9);

	L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
		maxZoom: 18,
		attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
			'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
			'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
		id: 'mapbox.streets'
	}).addTo(mymap);


var lines = geojson.features
	.filter(function(feature) { return feature.geometry.type == "LineString" })
	.map(function(feature) {
     var coordinates = feature.geometry.coordinates;
     coordinates.forEach(function(coordinate) { coordinate.reverse(); })
     return L.polyline(coordinates)
            .addTo(mymap)
            .bindPopup("<b>" + feature.properties.owner + "</b><br />" + feature.properties.bandwidth)
     })


var arrowHead = L.polylineDecorator(lines, {
  patterns: [{
    offset: 0,
    repeat: 40,
    symbol: L.Symbol.arrowHead({
      pixelSize: 10,
	  pathOptions: {fillOpacity: 1, weight: 0}
    })
  }]
}).addTo(mymap);
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>
 <script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js" integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q==" crossorigin=""></script>

<script src="http://bbecquet.github.io/Leaflet.PolylineDecorator/dist/leaflet.polylineDecorator.js"></script>


<div id="mapid" style="width: 600px; height: 400px;"></div>

缺点是标记本身没有弹出窗口,但是我们也可以向其添加弹出窗口,只需在遍历每条geojson行时将标记添加到地图即可。

var geojson = {
  "type": "FeatureCollection",
  "features": [{
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 150
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.28, -2.86
            ],
            [
              108.168, -2.97
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.168, -2.97
            ],
            [
              108.06399, -3.23
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 100
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              108.06399, -3.23
            ],
            [
              107.899, -3.09
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.899, -3.09
            ],
            [
              107.65099, -3.13039
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.65099, -3.13039
            ],
            [
              107.58299, -3.04692
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 350
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.58299, -3.04692
            ],
            [
              107.63576, -2.72322
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {
          "owner": "TSEL",
          "bandwidth": 200
        },
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              107.63576, -2.72322
            ],
            [
              107.65699, -2.7366
            ]
          ]
        }
      }
    ]
};




	var mymap = L.map('mapid').setView([ -2.8,108], 9);

	L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
		maxZoom: 18,
		attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
			'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
			'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
		id: 'mapbox.streets'
	}).addTo(mymap);


geojson.features
    .filter(function(feature) { return feature.geometry.type == "LineString" })
	.map(function(feature) {
	    var coordinates = feature.geometry.coordinates;
		coordinates.forEach(function(coordinate) { coordinate.reverse(); })
	    var line = L.polyline(coordinates).addTo(mymap).bindPopup("<b>" + feature.properties.owner + "</b><br />" + feature.properties.bandwidth);
		arrowify(line,feature);
	})

function arrowify(line,feature) {
	L.polylineDecorator(line, {
		  patterns: [{
			offset: 0,
			repeat: 30,
			symbol: L.Symbol.arrowHead({
			  pixelSize: 10,
			  pathOptions: {fillOpacity: 1, weight: 0}
			})
		  }]
		}).addTo(mymap).addTo(mymap).bindPopup("<b>" + feature.properties.owner + "</b><br />" + feature.properties.bandwidth);	
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>
 <script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js" integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q==" crossorigin=""></script>

<script src="http://bbecquet.github.io/Leaflet.PolylineDecorator/dist/leaflet.polylineDecorator.js"></script>


<div id="mapid" style="width: 600px; height: 400px;"></div>