我正在使用Leaflet创建一个顶部添加了D3图层的地图。我想自动缩放和缩放到叠加层,类似于在纯D3(see example)中自动将geo对象放入其容器中的方式。
在制作Leaflet和D3时,我必须按this example使用自定义地理转换:
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
var transform = d3.geo.transform({point: projectPoint}),
path = d3.geo.path().projection(transform);
这样可以毫不费力地将D3投影到Leaflet地图上,但是我没有任何关于如何确定我的图层地图的纬度/经度的线索。我需要这些坐标来设置中心,然后我还需要设置缩放级别。
如何在Leaflet中自动设置setView
和setZoom
以适合D3覆盖层?
这是我的实施:
var map = new L.Map("map", {
// Initialize map with arbitrary center/zoom
center: [37.8, -96.9],
zoom: 4
})
var layer = map
.addLayer(new L.TileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"));
var figure = d3.select('figure');
var width = figure.node().clientWidth;
var height = figure.node().clientHeight;
var svg = d3.select(map.getPanes().overlayPane)
.append("svg")
.style('width', width)
.style('height', height);
var g = svg.append("g").attr("class", "leaflet-zoom-hide");
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
var transform = d3.geo.transform({ point: projectPoint });
var path = d3.geo.path().projection(transform);
d3.json('conway-ar.json', function(error, collection) {
if (error) console.warn(error);
var city = g.append('path')
.datum(collection.city.geometry)
.attr('fill', 'none')
.attr('stroke', 'blue')
.attr('d', path);
// Update center/zoom based on location of "city"
// map.setView([someLat, someLng]);
// map.setZoom(someZoomLevel);
map.on('viewreset', update);
update();
function update() {
city.attr('d', path);
}
});
答案 0 :(得分:2)
我能够使用Leaflet.D3SvgOverlay实现一个解决方案,这是一个使用D3和Leaflet自动化地理变换的库。
首先,我用proj.pathFromGeojson.bounds(d)
记录了渲染路径的边界。这个库有一个方便的方法,可以将图层点转换为纬度/经度proj.layerPointToLatLng
。然后我可以使用D3 map.fitBounds
根据记录的边界同时调整中心/缩放。请参阅以下代码:
var bounds = [];
var city = sel.append('path')
.datum(cityGeo)
.attr('d', function(d) {
bounds = proj.pathFromGeojson.bounds(d);
return proj.pathFromGeojson(d);
});
var b = [proj.layerPointToLatLng(bounds[0]),
proj.layerPointToLatLng(bounds[1])];
map.fitBounds(b);
我的bl.ock可以看到完整的实现。