2015-11-24 9 views
0

Я использую Листовку, чтобы создать карту с добавленным слоем D3 сверху. Я хочу автоматически масштабировать и масштабировать до слоя наложения, подобно тому, как вы можете автоматически вставлять гео-объекты в свой контейнер в чистом D3 (see example).Масштаб/зум D3 слой на карте Листовки к границам слоев

В процессе листовка и 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 на листовку карты без усилий, но я остался без понятия о том, как для определения широты/долготы для моей карты слоев. Мне нужны эти координаты, чтобы установить центр, тогда мне также необходимо установить уровень масштабирования.

Как я могу установить автоматически 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); 
    } 

}); 

ответ

2

я смог реализовать решение с использованием Leaflet.D3SvgOverlay, библиотекой для использования D3 с листовкой, которая автоматизирует гео преобразования.

Сначала я записал границы пройденного пути с помощью proj.pathFromGeojson.bounds(d). Эта библиотека имела удобный метод, который преобразовывал точки слоя в широту/долготу, proj.layerPointToLatLng. Затем я смог использовать D3's 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.

Смежные вопросы