fix: symbols/text stay fixed on compass rotation, polygon area display in label box
This commit is contained in:
@@ -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)} m²` : `${(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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user