0

リーフレット マップに SVG オーバーレイを追加したいと考えています。SVG を追加するオーバーレイ ペインに SVG コンテナを追加します。これは機能しますが、私の SVG コンテナはマップと共にスクロールし続けます。SVG を適切に表示するには、コンテナーが常にマップの現在のビュー (現在のマップ ビューの左上から右下まで) にまたがるようにします。

概要

svg-container の原点を現在のマップ ビューの左上にリセットするにはどうすればよいですか?

これは私のコード スニペットです。SVG オーバーレイのディレクティブを示しています。私はリーフレット角度ディレクティブを使用しています:

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
            // ...
          }
        };
      }
    };
  }]);
4

1 に答える 1

0

これは私がそれを修正した方法です:

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;
}
于 2015-06-20T15:23:13.077 に答える