Fix missing Address, rename Btns, add copy coords #5

This commit is contained in:
nocnico
2025-05-22 17:40:36 +02:00
parent eb86b8407e
commit 56fb51e6b8

View File

@@ -1,28 +1,25 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import { OSMWay } from "@repo/db"; import { OSMWay } from "@repo/db";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
import { useMapStore } from "_store/mapStore"; import { useMapStore } from "_store/mapStore";
import { usePannelStore } from "_store/pannelStore"; import { usePannelStore } from "_store/pannelStore";
import { import { MapPin, MapPinned, Radius, Ruler, Search, RulerDimensionLine, Scan } from "lucide-react";
MapPin,
MapPinned,
Radius,
Ruler,
Search,
RulerDimensionLine,
Scan,
} from "lucide-react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { Popup, useMap } from "react-leaflet"; import { Popup, useMap } from "react-leaflet";
export const ContextMenu = () => { export const ContextMenu = () => {
const map = useMap(); const map = useMap();
const { contextMenu, setContextMenu, setSearchElements, setSearchPopup } = const { contextMenu, setContextMenu, setSearchElements, setSearchPopup } = useMapStore();
useMapStore(); const { missionFormValues, setMissionFormValues, setOpen, isOpen } = usePannelStore(
const { setMissionFormValues, setOpen } = usePannelStore((state) => state); (state) => state,
);
const [showRulerOptions, setShowRulerOptions] = useState(false); const [showRulerOptions, setShowRulerOptions] = useState(false);
const [rulerHover, setRulerHover] = useState(false); const [rulerHover, setRulerHover] = useState(false);
const [rulerOptionsHover, setRulerOptionsHover] = useState(false); const [rulerOptionsHover, setRulerOptionsHover] = useState(false);
const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected";
useEffect(() => { useEffect(() => {
setShowRulerOptions(rulerHover || rulerOptionsHover); setShowRulerOptions(rulerHover || rulerOptionsHover);
}, [rulerHover, rulerOptionsHover]); }, [rulerHover, rulerOptionsHover]);
@@ -45,7 +42,9 @@ export const ContextMenu = () => {
}; };
}, [map, contextMenu, setContextMenu, setSearchPopup]); }, [map, contextMenu, setContextMenu, setSearchPopup]);
if (!contextMenu) return null; if (!contextMenu || !dispatcherConnected) return null;
const einsatzBtnText = missionFormValues && isOpen ? "Position übernehmen" : "Einsatz erstellen";
const addOSMobjects = async () => { const addOSMobjects = async () => {
const res = await fetch( const res = await fetch(
@@ -67,9 +66,7 @@ export const ContextMenu = () => {
return { return {
wayID: e.id, wayID: e.id,
nodes: e.nodes.map((nodeId: string) => { nodes: e.nodes.map((nodeId: string) => {
const node = data.elements.find( const node = data.elements.find((element: any) => element.id === nodeId);
(element: any) => element.id === nodeId,
);
return { return {
lat: node.lat, lat: node.lat,
lon: node.lon, lon: node.lon,
@@ -100,45 +97,44 @@ export const ContextMenu = () => {
{/* Top Button */} {/* Top Button */}
<button <button
className="btn btn-circle bg-rescuetrack w-10 h-10 absolute left-1/2 top-0 pointer-events-auto opacity-80 tooltip tooltip-top tooltip-accent" className="btn btn-circle bg-rescuetrack w-10 h-10 absolute left-1/2 top-0 pointer-events-auto opacity-80 tooltip tooltip-top tooltip-accent"
data-tip="Nächstes Element übernehmen" data-tip={einsatzBtnText}
style={{ transform: "translateX(-50%)" }} style={{ transform: "translateX(-50%)" }}
onClick={async () => { onClick={async () => {
const address = await fetch( const address = await fetch(
`https://nominatim.openstreetmap.org/reverse?lat=${contextMenu.lat}&lon=${contextMenu.lng}&format=json`, `https://nominatim.openstreetmap.org/reverse?lat=${contextMenu.lat}&lon=${contextMenu.lng}&format=json`,
); );
const data = (await address.json()) as { const data = (await address.json()) as {
address: { address?: {
ISO3166_2_lvl4: string; ISO3166_2_lvl4?: string;
country: string; country?: string;
country_code: string; country_code?: string;
county: string; county?: string;
house_number: string; house_number?: string;
municipality: string; municipality?: string;
postcode: string; postcode?: string;
road: string; road?: string;
state: string; state?: string;
city: string; city?: string;
town: string; town?: string;
}; };
display_name: string; display_name?: string;
importance: number; importance?: number;
lat: string; lat?: string;
licence: string; licence?: string;
lon: string; lon?: string;
name: string; name?: string;
osm_id: number; osm_id?: number;
osm_type: string; osm_type?: string;
place_id: number; place_id?: number;
place_rank: number; place_rank?: number;
type: string; type?: string;
}; };
const addressObj = data.address ?? {};
const objects = await addOSMobjects(); const objects = await addOSMobjects();
const exactAddress = objects.find((object) => { const exactAddress = objects.find((object) => {
return ( return (
object.tags["addr:street"] == data.address.road && object.tags["addr:street"] == addressObj.road &&
object.tags["addr:housenumber"]?.includes( object.tags["addr:housenumber"]?.includes(addressObj.house_number ?? "")
data.address.house_number,
)
); );
}); });
const closestToContext = objects.reduce((prev, curr) => { const closestToContext = objects.reduce((prev, curr) => {
@@ -147,24 +143,21 @@ export const ContextMenu = () => {
const currLat = curr.nodes?.[0]?.lat ?? 0; const currLat = curr.nodes?.[0]?.lat ?? 0;
const currLon = curr.nodes?.[0]?.lon ?? 0; const currLon = curr.nodes?.[0]?.lon ?? 0;
const prevDistance = Math.sqrt( const prevDistance = Math.sqrt(
Math.pow(prevLat - contextMenu.lat, 2) + Math.pow(prevLat - contextMenu.lat, 2) + Math.pow(prevLon - contextMenu.lng, 2),
Math.pow(prevLon - contextMenu.lng, 2),
); );
const currDistance = Math.sqrt( const currDistance = Math.sqrt(
Math.pow(currLat - contextMenu.lat, 2) + Math.pow(currLat - contextMenu.lat, 2) + Math.pow(currLon - contextMenu.lng, 2),
Math.pow(currLon - contextMenu.lng, 2),
); );
return prevDistance < currDistance ? prev : curr; return prevDistance < currDistance ? prev : curr;
}); }, [] as any);
setOpen(true); setOpen(true);
console.log(data.address.road);
setMissionFormValues({ setMissionFormValues({
addressLat: contextMenu.lat, addressLat: contextMenu.lat,
addressLng: contextMenu.lng, addressLng: contextMenu.lng,
addressCity: data.address.city || data.address.town || "", addressCity: addressObj.city || addressObj.town || "",
addressStreet: `${data.address.road || "keine Straße"}, ${data.address.house_number || "keine HN"}`, addressStreet: `${addressObj.road || "keine Straße"}, ${addressObj.house_number || "keine HN"}`,
addressZip: data.address.postcode || "", addressZip: addressObj.postcode || "",
state: "draft", state: "draft",
addressOSMways: [(exactAddress || closestToContext) as any], addressOSMways: [(exactAddress || closestToContext) as any],
}); });
@@ -187,70 +180,9 @@ export const ContextMenu = () => {
data-tip="Koordinaten kopieren" data-tip="Koordinaten kopieren"
style={{ transform: "translateX(-50%)" }} style={{ transform: "translateX(-50%)" }}
onClick={async () => { onClick={async () => {
const address = await fetch( const coords = `${contextMenu.lat}, ${contextMenu.lng}`;
`https://nominatim.openstreetmap.org/reverse?lat=${contextMenu.lat}&lon=${contextMenu.lng}&format=json`, await navigator.clipboard.writeText(coords);
); toast.success("Koordinaten in die Zwischenablage kopiert!");
const data = (await address.json()) as {
address: {
ISO3166_2_lvl4: string;
country: string;
country_code: string;
county: string;
house_number: string;
municipality: string;
postcode: string;
road: string;
state: string;
city: string;
town: string;
};
display_name: string;
importance: number;
lat: string;
licence: string;
lon: string;
name: string;
osm_id: number;
osm_type: string;
place_id: number;
place_rank: number;
type: string;
};
const objects = await addOSMobjects();
const exactAddress = objects.find((object) => {
return (
object.tags["addr:street"] == data.address.road &&
object.tags["addr:housenumber"]?.includes(
data.address.house_number,
)
);
});
const closestToContext = objects.reduce((prev, curr) => {
const prevLat = prev.nodes?.[0]?.lat ?? 0;
const prevLon = prev.nodes?.[0]?.lon ?? 0;
const currLat = curr.nodes?.[0]?.lat ?? 0;
const currLon = curr.nodes?.[0]?.lon ?? 0;
const prevDistance = Math.sqrt(
Math.pow(prevLat - contextMenu.lat, 2) +
Math.pow(prevLon - contextMenu.lng, 2),
);
const currDistance = Math.sqrt(
Math.pow(currLat - contextMenu.lat, 2) +
Math.pow(currLon - contextMenu.lng, 2),
);
return prevDistance < currDistance ? prev : curr;
}, [] as any);
setOpen(true);
setMissionFormValues({
addressLat: contextMenu.lat,
addressLng: contextMenu.lng,
addressCity: data.address.city || data.address.town || "",
addressStreet: `${data.address.road || "keine Straße"}, ${data.address.house_number || "keine HN"}`,
addressZip: data.address.postcode || "",
state: "draft",
addressOSMways: [(exactAddress || closestToContext) as any],
});
}} }}
> >
<MapPin size={20} /> <MapPin size={20} />