在Leaflet地图上缩放/缩放D3图层到图层边界

时间:2015-11-24 18:26:52

标签: javascript d3.js leaflet

我正在使用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中自动设置setViewsetZoom以适合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);
    }

});

1 个答案:

答案 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可以看到完整的实现。