将 svg 容器重置为当前视图
Reset svg container to current view
我想将 SVG-overlays 添加到传单地图。我将 SVG-container 添加到我附加 SVG 的覆盖窗格。这行得通,但是我的 SVG-container 一直随着地图滚动。为了正确显示我的 SVG,我希望容器始终跨越我当前的地图视图(从我当前地图视图的 top-left 到 bottom-right)。
如何将 svg-container 的原点重置为当前地图视图的 top-left?
这是我的代码片段,它显示了 SVG-overlay 的指令。我正在使用 leaflet-angular-directive:
angular.module('app')
.directive('cluster', ['lodash', function() {
return {
link: function(scope, element, attrs, leafletController) {
scope.$watch('cluster', function(newCluster, oldCluster) {
leafletController.getMap()
.then(function(map) {
return scope.render(newCluster, map);
});
});
scope.render = function(cluster, map) {
var overlayPane = d3.select(map.getPanes().overlayPane);
var svg = overlayPane.append("svg").attr("class", "leaflet-zoom-hide cluster");
var g = svg.append("g");
// append features (circles) to g
// ...
map.on("viewreset", update);
update();
function update() {
// update svg
svg.attr("width", map.getSize().x);
svg.attr("height", map.getSize().y);
// update features
// ...
}
};
}
};
}]);
我是这样修复的:
svg 容器的大小是所有圆的边界。您还必须将圆的半径作为偏移量,因为圆的边界取决于圆心。
/* Update size and scaling of svgs on mapchange */
function update() {
var bounds = getBounds(features);
var offset = 20 / 1400 * Math.pow(2, map.getZoom());
var width = Math.abs((bounds.max[0] - bounds.min[0]) + 2 * radius);
var height = Math.abs((bounds.max[1] - bounds.min[1]) + 2 * radius);
var left = bounds.min[0] - radius;
var top = bounds.min[1] - radius;
svg.attr('width', width).attr('height', height)
.style("left", left + 'px')
.style("top", top + 'px');
g .attr("transform", "translate(" + -bounds.min[0] + "," + -bounds.min[1] + ")");
g.selectAll('circle')
.attr("cx", function(d) { return map.latLngToLayerPoint(d.LatLng).x + radius; })
.attr("cy", function(d) { return map.latLngToLayerPoint(d.LatLng).y + radius;})
.attr("r", radius);
}
/* Get the min and max bounds of all features */
function getBounds(features) {
var bounds = { min: [999, 999], max: [-999, -999] };
_.each(features, function(element) {
var point = map.latLngToLayerPoint(element.LatLng);
bounds.min[0] = Math.min(bounds.min[0], point.x);
bounds.min[1] = Math.min(bounds.min[1], point.y);
bounds.max[0] = Math.max(bounds.max[0], point.x);
bounds.max[1] = Math.max(bounds.max[1], point.y);
});
return bounds;
}
我想将 SVG-overlays 添加到传单地图。我将 SVG-container 添加到我附加 SVG 的覆盖窗格。这行得通,但是我的 SVG-container 一直随着地图滚动。为了正确显示我的 SVG,我希望容器始终跨越我当前的地图视图(从我当前地图视图的 top-left 到 bottom-right)。
如何将 svg-container 的原点重置为当前地图视图的 top-left?
这是我的代码片段,它显示了 SVG-overlay 的指令。我正在使用 leaflet-angular-directive:
angular.module('app')
.directive('cluster', ['lodash', function() {
return {
link: function(scope, element, attrs, leafletController) {
scope.$watch('cluster', function(newCluster, oldCluster) {
leafletController.getMap()
.then(function(map) {
return scope.render(newCluster, map);
});
});
scope.render = function(cluster, map) {
var overlayPane = d3.select(map.getPanes().overlayPane);
var svg = overlayPane.append("svg").attr("class", "leaflet-zoom-hide cluster");
var g = svg.append("g");
// append features (circles) to g
// ...
map.on("viewreset", update);
update();
function update() {
// update svg
svg.attr("width", map.getSize().x);
svg.attr("height", map.getSize().y);
// update features
// ...
}
};
}
};
}]);
我是这样修复的:
svg 容器的大小是所有圆的边界。您还必须将圆的半径作为偏移量,因为圆的边界取决于圆心。
/* Update size and scaling of svgs on mapchange */
function update() {
var bounds = getBounds(features);
var offset = 20 / 1400 * Math.pow(2, map.getZoom());
var width = Math.abs((bounds.max[0] - bounds.min[0]) + 2 * radius);
var height = Math.abs((bounds.max[1] - bounds.min[1]) + 2 * radius);
var left = bounds.min[0] - radius;
var top = bounds.min[1] - radius;
svg.attr('width', width).attr('height', height)
.style("left", left + 'px')
.style("top", top + 'px');
g .attr("transform", "translate(" + -bounds.min[0] + "," + -bounds.min[1] + ")");
g.selectAll('circle')
.attr("cx", function(d) { return map.latLngToLayerPoint(d.LatLng).x + radius; })
.attr("cy", function(d) { return map.latLngToLayerPoint(d.LatLng).y + radius;})
.attr("r", radius);
}
/* Get the min and max bounds of all features */
function getBounds(features) {
var bounds = { min: [999, 999], max: [-999, -999] };
_.each(features, function(element) {
var point = map.latLngToLayerPoint(element.LatLng);
bounds.min[0] = Math.min(bounds.min[0], point.x);
bounds.min[1] = Math.min(bounds.min[1], point.y);
bounds.max[0] = Math.max(bounds.max[0], point.x);
bounds.max[1] = Math.max(bounds.max[1], point.y);
});
return bounds;
}