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`
|
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)
|
// 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 {
|
function pointToSegmentDist(px: number, py: number, x1: number, y1: number, x2: number, y2: number): number {
|
||||||
const dx = x2 - x1, dy = y2 - y1
|
const dx = x2 - x1, dy = y2 - y1
|
||||||
@@ -1396,7 +1409,7 @@ export function MapView({
|
|||||||
pointer-events: none;
|
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])
|
.setLngLat(p2 as [number, number])
|
||||||
.addTo(map.current)
|
.addTo(map.current)
|
||||||
markersRef.current.push(marker)
|
markersRef.current.push(marker)
|
||||||
@@ -1468,7 +1481,21 @@ export function MapView({
|
|||||||
el.appendChild(labelLine)
|
el.appendChild(labelLine)
|
||||||
el.appendChild(infoLine)
|
el.appendChild(infoLine)
|
||||||
} else {
|
} 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
|
// 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)
|
.setLngLat(midpoint)
|
||||||
.addTo(map.current)
|
.addTo(map.current)
|
||||||
markersRef.current.push(marker)
|
markersRef.current.push(marker)
|
||||||
@@ -1568,7 +1595,7 @@ export function MapView({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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)
|
.setLngLat(coords)
|
||||||
.addTo(map.current)
|
.addTo(map.current)
|
||||||
|
|
||||||
@@ -1634,7 +1661,7 @@ export function MapView({
|
|||||||
el.textContent = (f.properties.text as string) || ''
|
el.textContent = (f.properties.text as string) || ''
|
||||||
wrapper.appendChild(el)
|
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)
|
.setLngLat(coords)
|
||||||
.addTo(map.current)
|
.addTo(map.current)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user