Как мы получаем информацию о объектах (например, о центроидах) после рендеринга карты и вызова метода fitToBounds - PullRequest
1 голос
/ 10 июля 2019

Ниже приводится фактическая цель.

- Рисование надписей на многоугольниках (например, отображение названия страны или штата). -Эти имена должны быть выровнены по центру центру многоугольника. - Избегайте перекрытия надписей (перед тем, как визуализировать маркер, мы проверяем, будет ли этот маркер перекрываться с любым уже отрисованным маркером. Если да, он не должен отображать маркер)

Мы написали образец, и все вышеперечисленные пункты решены. После кода.

  • метки отображаются на карте с помощью функции маркера. мы генерируем классы HTML и flex для центрирования текста по центру многоугольника.
  • , чтобы избежать наложения, мы делаем пиксельные координаты записки созданными маркерами. Каждый div - это прямоугольник с координатами minX, minY, maxX, maxY, и мы проверяем, пересекаются ли прямоугольники.
var geojson_layer = new L.geoJson(geojson_data, {
  onEachFeature: function(feature, layer) {
    if (feature.geometry.type.toLowerCase() === "multipolygon") {
      var largest = _.maxBy(
        feature.geometry.coordinates,
        r => r[0].length
      );
      p = polylabel(largest, 1.0);
    } else {
      p = polylabel(feature.geometry.coordinates, 1.0);
      console.log(p.toString());
    }
    lon = p[0];
    lat = p[1];
    if (lat && lon) {
      var latLng = L.latLng([lat, lon]);
      var point = mymap.latLngToContainerPoint(latLng);
      var titleText =
        '<svg width="300" height="14"><text x="50%" y="8" fill="black" text-anchor="middle">' +
        feature.properties.name +
        ":more text added" +
        "</text></svg>";
      var rectArea = new RectangleArea(
        point.x - 150,
        point.x + 150,
        point.y,
        point.y + 14
      );
      var canRender = true;
      labelRects.forEach(element => {
        if (element.rectanglesIntersect(rectArea)) {
          canRender = false;
          return;
        }
      });
      if (canRender) {
        labelRects.push(rectArea);
        var label2 = L.marker([lat, lon], {
          icon: L.divIcon({
            iconSize: null,
            zIndexOffset: 100000,
            html:
              "<div style='position: relative; left:-50%; display: flex; align-items:center; flex-direction: column; justify-content: center;'>" +
              titleText +
              "</div>"
          })
        }).addTo(mymap);
      }
    }
  }
}).addTo(mymap);

Все это прекрасно работает, за исключением одной проблемы. В этом примере мы устанавливаем центр карты и уровень масштабирования следующим образом.

var mymap = L.map("map", { center: [41, -98], zoom: 5 });

В реальном приложении мы не устанавливаем такой уровень масштабирования. Мы вызываем fitToBounds метод на слое. Эта проблема заключается в том, что выше не дает нам точки пикселя, если мы не устанавливаем уровень масштабирования заранее.

Кто-нибудь имеет представление о том, как мы можем получить коллекцию объектов и ее центр тяжести после рендеринга слоя и вызова метода fitToBounds? Есть ли другой способ достижения цели?

...