Ниже приводится фактическая цель.
- Рисование надписей на многоугольниках (например, отображение названия страны или штата).
-Эти имена должны быть выровнены по центру центру многоугольника.
- Избегайте перекрытия надписей (перед тем, как визуализировать маркер, мы проверяем, будет ли этот маркер перекрываться с любым уже отрисованным маркером. Если да, он не должен отображать маркер)
Мы написали образец, и все вышеперечисленные пункты решены. После кода.
- метки отображаются на карте с помощью функции маркера. мы генерируем классы 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
? Есть ли другой способ достижения цели?