fix(map): Pfeilspitze zeigt exakt entlang der Linie (v1.8.10)
Die Pfeilspitze wurde mit dem geografischen Winkel (atan2 auf lng/lat) gedreht, der wegen der Mercator-Verzerrung nicht mit der auf dem Bildschirm gezeichneten Linie übereinstimmt (v.a. bei nördlichen Breiten). Jetzt aus den projizierten Pixeln berechnet (viewport- ausgerichtet) → Spitze zeigt korrekt in Linienrichtung. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lageplan",
|
"name": "lageplan",
|
||||||
"version": "1.8.9",
|
"version": "1.8.10",
|
||||||
"description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation",
|
"description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1489,27 +1489,31 @@ export function MapView({
|
|||||||
const lineCoords = f.geometry.coordinates as number[][]
|
const lineCoords = f.geometry.coordinates as number[][]
|
||||||
if (lineCoords.length < 2) return
|
if (lineCoords.length < 2) return
|
||||||
|
|
||||||
// Geographic bearing from p1 to p2 (works for short distances)
|
|
||||||
const p1 = lineCoords[lineCoords.length - 2]
|
const p1 = lineCoords[lineCoords.length - 2]
|
||||||
const p2 = lineCoords[lineCoords.length - 1]
|
const p2 = lineCoords[lineCoords.length - 1]
|
||||||
const dLng = p2[0] - p1[0]
|
// Bildschirm-Winkel aus projizierten Pixeln berechnen — der geografische Winkel
|
||||||
const dLat = p2[1] - p1[1]
|
// (atan2 auf lng/lat) stimmt wegen der Mercator-Verzerrung NICHT mit der auf dem
|
||||||
// atan2(dLng, dLat) gives angle from north (up), clockwise — matches CSS triangle ▲ default
|
// Bildschirm gezeichneten Linie überein (v.a. bei nördlichen Breiten). So zeigt die
|
||||||
const geoBearing = Math.atan2(dLng, dLat) * (180 / Math.PI)
|
// Spitze exakt entlang der Linie.
|
||||||
|
const a = map.current.project(p1 as [number, number])
|
||||||
|
const b = map.current.project(p2 as [number, number])
|
||||||
|
// CSS-Dreieck zeigt nach oben (−y). Winkel im Uhrzeigersinn von „oben".
|
||||||
|
const screenAngle = Math.atan2(b.x - a.x, -(b.y - a.y)) * (180 / Math.PI)
|
||||||
|
|
||||||
const color = (f.properties.color as string) || '#000000'
|
const color = (f.properties.color as string) || '#000000'
|
||||||
const arrowEl = document.createElement('div')
|
const arrowEl = document.createElement('div')
|
||||||
arrowEl.style.cssText = `
|
arrowEl.style.cssText = `
|
||||||
width: 0; height: 0;
|
width: 0; height: 0;
|
||||||
border-left: 12px solid transparent;
|
border-left: 10px solid transparent;
|
||||||
border-right: 12px solid transparent;
|
border-right: 10px solid transparent;
|
||||||
border-bottom: 24px solid ${color};
|
border-bottom: 20px solid ${color};
|
||||||
transform: rotate(${geoBearing}deg);
|
transform: rotate(${screenAngle}deg);
|
||||||
transform-origin: center center;
|
transform-origin: center center;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
`
|
`
|
||||||
|
|
||||||
const marker = new maplibregl.Marker({ element: arrowEl, anchor: 'center', rotationAlignment: 'map' })
|
// Viewport-ausgerichtet (Bildschirm), passend zum bildschirm-basierten Winkel.
|
||||||
|
const marker = new maplibregl.Marker({ element: arrowEl, anchor: 'center' })
|
||||||
.setLngLat(p2 as [number, number])
|
.setLngLat(p2 as [number, number])
|
||||||
.addTo(map.current)
|
.addTo(map.current)
|
||||||
markersRef.current.push(marker)
|
markersRef.current.push(marker)
|
||||||
|
|||||||
Reference in New Issue
Block a user