added Map objekt polygon
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import { useMapStore } from "_store/mapStore";
|
||||
import { MapPinned, Search } from "lucide-react";
|
||||
import { useEffect } from "react";
|
||||
import { Popup, useMap } from "react-leaflet";
|
||||
|
||||
export const ContextMenu = () => {
|
||||
const map = useMap();
|
||||
const { popup, map: mapStore, setPopup } = useMapStore();
|
||||
const { popup, setSearchElements, setPopup } = useMapStore();
|
||||
|
||||
useEffect(() => {
|
||||
map.on("contextmenu", (e) => {
|
||||
@@ -17,9 +18,9 @@ export const ContextMenu = () => {
|
||||
return (
|
||||
<Popup position={[popup.lat, popup.lng]}>
|
||||
{/* // TODO: maske: */}
|
||||
<div>
|
||||
<div className="absolute transform -translate-y-1/2 z-1000 opacity-100 pointer-events-auto p-3">
|
||||
<button
|
||||
className="btn btn-sm"
|
||||
className="btn btn-sm rounded-full bg-amber-600 hover:bg-amber-700 aspect-square"
|
||||
onClick={async () => {
|
||||
const address = await fetch(
|
||||
`https://nominatim.openstreetmap.org/reverse?lat=${popup.lat}&lon=${popup.lng}&format=json`,
|
||||
@@ -51,7 +52,48 @@ export const ContextMenu = () => {
|
||||
};
|
||||
}}
|
||||
>
|
||||
Neues Einsatz hier Erstellen
|
||||
<MapPinned size={20} />
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-sm rounded-full bg-amber-600 hover:bg-amber-700 aspect-square"
|
||||
onClick={async () => {
|
||||
const res = await fetch(
|
||||
`https://overpass-api.de/api/interpreter?data=${encodeURIComponent(`
|
||||
[out:json];
|
||||
(
|
||||
way["building"](around:50, ${popup.lat}, ${popup.lng});
|
||||
relation["building"](around:50, ${popup.lat}, ${popup.lng});
|
||||
);
|
||||
out body;
|
||||
>;
|
||||
out skel qt;
|
||||
`)}`,
|
||||
);
|
||||
const data = await res.json();
|
||||
setSearchElements(
|
||||
data.elements
|
||||
.filter((e: any) => e.type === "way")
|
||||
.map((e: any) => {
|
||||
return {
|
||||
id: e.id,
|
||||
nodes: e.nodes.map((nodeId: string) => {
|
||||
const node = data.elements.find(
|
||||
(element: any) => element.id === nodeId,
|
||||
);
|
||||
return {
|
||||
lat: node.lat,
|
||||
lon: node.lon,
|
||||
};
|
||||
}),
|
||||
tags: e.tags,
|
||||
type: e.type,
|
||||
};
|
||||
}),
|
||||
);
|
||||
console.log(data);
|
||||
}}
|
||||
>
|
||||
<Search size={20} />
|
||||
</button>
|
||||
</div>
|
||||
</Popup>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { MapContainer } from "react-leaflet";
|
||||
import { BaseMaps } from "(dispatch)/_components/map/BaseMaps";
|
||||
import { ContextMenu } from "(dispatch)/_components/map/ContextMenu";
|
||||
import { MissionMarkers } from "(dispatch)/_components/map/MissionMarkers";
|
||||
import { SearchElements } from "(dispatch)/_components/map/SearchElements";
|
||||
|
||||
export default ({}) => {
|
||||
const { map } = useMapStore();
|
||||
@@ -12,6 +13,7 @@ export default ({}) => {
|
||||
return (
|
||||
<MapContainer className="flex-1" center={map.center} zoom={map.zoom}>
|
||||
<BaseMaps />
|
||||
<SearchElements />
|
||||
<ContextMenu />
|
||||
<MissionMarkers />
|
||||
</MapContainer>
|
||||
|
||||
@@ -15,7 +15,7 @@ export const MissionMarker = ({
|
||||
const markerRef = useRef<LMarker<any>>(null);
|
||||
|
||||
useEffect(() => {
|
||||
markerRef.current?.openPopup();
|
||||
// markerRef.current?.openPopup();
|
||||
|
||||
const handleZoom = () => {
|
||||
setZoom(map.getZoom());
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { useMapStore } from "_store/mapStore";
|
||||
import { Marker as LMarker } from "leaflet";
|
||||
import { Ref, use, useEffect, useRef } from "react";
|
||||
import { Marker, Polygon, Polyline, Popup } from "react-leaflet";
|
||||
import L from "leaflet";
|
||||
|
||||
export const SearchElements = () => {
|
||||
const { searchElements, searchPopup, setSearchPopup } = useMapStore();
|
||||
const poppupRef = useRef<LMarker>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (searchPopup?.isOpen) {
|
||||
poppupRef.current?.openPopup();
|
||||
} else {
|
||||
poppupRef.current?.closePopup();
|
||||
}
|
||||
}, [searchPopup]);
|
||||
|
||||
const SearchElement = ({
|
||||
element,
|
||||
}: {
|
||||
element: (typeof searchElements)[1];
|
||||
}) => {
|
||||
const ref = useRef<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
console.log(ref.current);
|
||||
ref.current.on("click", () => {
|
||||
console.log("click");
|
||||
const center = ref.current.getBounds().getCenter();
|
||||
setSearchPopup({
|
||||
isOpen: true,
|
||||
lat: center.lat,
|
||||
lng: center.lng,
|
||||
elementId: element.id,
|
||||
});
|
||||
console.log(element);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Polygon
|
||||
key={element.id}
|
||||
positions={element.nodes.map((node) => [node.lat, node.lon])}
|
||||
color="#46b7a3"
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{searchElements.map((element) => {
|
||||
return <SearchElement key={element.id} element={element} />;
|
||||
})}
|
||||
{searchPopup && (
|
||||
<Marker
|
||||
position={[searchPopup.lat, searchPopup.lng]}
|
||||
ref={poppupRef}
|
||||
icon={new L.DivIcon()}
|
||||
opacity={0}
|
||||
>
|
||||
<Popup>
|
||||
<div className="absolute z-1000 opacity-100 pointer-events-auto w-[500px] text-white">
|
||||
<div className="bg-red-600 w-7 h-6">test</div>
|
||||
</div>
|
||||
</Popup>
|
||||
</Marker>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -11,7 +11,33 @@ interface MapStore {
|
||||
center: L.LatLngExpression;
|
||||
zoom: number;
|
||||
};
|
||||
searchElements: {
|
||||
id: number;
|
||||
nodes: {
|
||||
lat: number;
|
||||
lon: number;
|
||||
}[];
|
||||
tags: {
|
||||
addr: {
|
||||
city?: string;
|
||||
housenumber?: string;
|
||||
postcode?: string;
|
||||
street?: string;
|
||||
suburb?: string;
|
||||
};
|
||||
building?: string;
|
||||
};
|
||||
type: string;
|
||||
}[];
|
||||
setSearchElements: (elements: MapStore["searchElements"]) => void;
|
||||
setPopup: (popup: MapStore["popup"]) => void;
|
||||
searchPopup?: {
|
||||
isOpen: boolean;
|
||||
lat: number;
|
||||
lng: number;
|
||||
elementId: number;
|
||||
};
|
||||
setSearchPopup: (popup: MapStore["searchPopup"]) => void;
|
||||
}
|
||||
|
||||
export const useMapStore = create<MapStore>((set, get) => ({
|
||||
@@ -19,9 +45,18 @@ export const useMapStore = create<MapStore>((set, get) => ({
|
||||
center: [51.5, 10.5],
|
||||
zoom: 6,
|
||||
},
|
||||
searchElements: [],
|
||||
setSearchPopup: (popup) =>
|
||||
set((state) => ({
|
||||
searchPopup: popup,
|
||||
})),
|
||||
popup: null,
|
||||
setPopup: (popup) =>
|
||||
set((state) => ({
|
||||
popup: popup,
|
||||
})),
|
||||
setSearchElements: (elements) =>
|
||||
set((state) => ({
|
||||
searchElements: elements,
|
||||
})),
|
||||
}));
|
||||
|
||||
@@ -12,6 +12,7 @@ export default {
|
||||
colors: {
|
||||
background: "var(--background)",
|
||||
foreground: "var(--foreground)",
|
||||
rescuetrack: "#46b7a3",
|
||||
},
|
||||
transitionProperty: {
|
||||
width: "width",
|
||||
|
||||
Reference in New Issue
Block a user