fix: symbols/text stay fixed on compass rotation, polygon area display in label box

This commit is contained in:
Pepe Ziberi
2026-02-21 22:55:31 +01:00
parent 8ef2cbe68e
commit 0376e71066

View File

@@ -23,6 +23,19 @@ function formatDistance(meters: number): string {
return `${(meters / 1000).toFixed(2)} km`
}
// Approximate polygon area in m² using the Shoelace formula on spherical coordinates
function polygonArea(ring: number[][]): number {
const toRad = Math.PI / 180
const R = 6371000
let area = 0
const n = ring.length - 1 // exclude closing duplicate
for (let i = 0; i < n; i++) {
const j = (i + 1) % n
area += (ring[j][0] - ring[i][0]) * toRad * (2 + Math.sin(ring[i][1] * toRad) + Math.sin(ring[j][1] * toRad))
}
return Math.abs(area * R * R / 2)
}
// Point-to-segment distance in screen pixels (for click detection on lines)
function pointToSegmentDist(px: number, py: number, x1: number, y1: number, x2: number, y2: number): number {
const dx = x2 - x1, dy = y2 - y1
@@ -1396,7 +1409,7 @@ export function MapView({
pointer-events: none;
`
const marker = new maplibregl.Marker({ element: arrowEl, anchor: 'center' })
const marker = new maplibregl.Marker({ element: arrowEl, anchor: 'center', rotationAlignment: 'viewport' })
.setLngLat(p2 as [number, number])
.addTo(map.current)
markersRef.current.push(marker)
@@ -1468,7 +1481,21 @@ export function MapView({
el.appendChild(labelLine)
el.appendChild(infoLine)
} else {
el.textContent = label
// Polygon: show label + area
const ring = (f.geometry.coordinates as number[][][])[0]
const area = polygonArea(ring)
const areaText = area < 10000 ? `${Math.round(area)}` : `${(area / 10000).toFixed(2)} ha`
const labelLine = document.createElement('div')
labelLine.textContent = label
labelLine.style.cssText = 'font-size:11px;font-weight:600;line-height:1.2;'
const infoLine = document.createElement('div')
infoLine.textContent = areaText
infoLine.style.cssText = 'font-size:8px;opacity:0.8;line-height:1.2;font-weight:400;'
el.appendChild(labelLine)
el.appendChild(infoLine)
}
// Double-click to edit label — only in select mode
@@ -1481,7 +1508,7 @@ export function MapView({
})
}
const marker = new maplibregl.Marker({ element: el, anchor: 'center' })
const marker = new maplibregl.Marker({ element: el, anchor: 'center', rotationAlignment: 'viewport' })
.setLngLat(midpoint)
.addTo(map.current)
markersRef.current.push(marker)
@@ -1568,7 +1595,7 @@ export function MapView({
}
try {
const marker = new maplibregl.Marker({ element: wrapper, draggable: canEdit, anchor: 'center' })
const marker = new maplibregl.Marker({ element: wrapper, draggable: canEdit, anchor: 'center', rotationAlignment: 'viewport' })
.setLngLat(coords)
.addTo(map.current)
@@ -1634,7 +1661,7 @@ export function MapView({
el.textContent = (f.properties.text as string) || ''
wrapper.appendChild(el)
const marker = new maplibregl.Marker({ element: wrapper, draggable: canEdit, anchor: 'center' })
const marker = new maplibregl.Marker({ element: wrapper, draggable: canEdit, anchor: 'center', rotationAlignment: 'viewport' })
.setLngLat(coords)
.addTo(map.current)