|
@@ -0,0 +1,152 @@
|
|
|
|
|
+"use client"
|
|
|
|
|
+
|
|
|
|
|
+import {useRef} from "react"
|
|
|
|
|
+import {Circle, LayersControl, MapContainer, Marker, Popup, TileLayer} from "react-leaflet"
|
|
|
|
|
+import L from "leaflet"
|
|
|
|
|
+import "leaflet/dist/leaflet.css"
|
|
|
|
|
+
|
|
|
|
|
+// 修复默认图标问题
|
|
|
|
|
+delete (L.Icon.Default.prototype as any)._getIconUrl
|
|
|
|
|
+L.Icon.Default.mergeOptions({
|
|
|
|
|
+ iconRetinaUrl: "/placeholder.svg?height=25&width=25",
|
|
|
|
|
+ iconUrl: "/placeholder.svg?height=25&width=25",
|
|
|
|
|
+ shadowUrl: "/placeholder.svg?height=25&width=25",
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+interface MapViewProps {
|
|
|
|
|
+ type?: "overview" | "waterlogging" | "pipeline" | "pump"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export default function MapView({ type = "overview" }: MapViewProps) {
|
|
|
|
|
+ const mapRef = useRef<L.Map>(null)
|
|
|
|
|
+
|
|
|
|
|
+ // 模拟数据
|
|
|
|
|
+ const waterloggingPoints = [
|
|
|
|
|
+ { id: 1, lat: 31.2304, lng: 121.4737, level: 0.8, threshold: 0.5, name: "人民路积水点" },
|
|
|
|
|
+ { id: 2, lat: 31.2404, lng: 121.4837, level: 0.3, threshold: 0.5, name: "南京路积水点" },
|
|
|
|
|
+ { id: 3, lat: 31.2204, lng: 121.4637, level: 0.6, threshold: 0.5, name: "淮海路积水点" },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const pipelinePoints = [
|
|
|
|
|
+ { id: 1, lat: 31.2304, lng: 121.4737, flow: 2.5, capacity: 3.0, name: "主干道管网" },
|
|
|
|
|
+ { id: 2, lat: 31.2404, lng: 121.4837, flow: 1.8, capacity: 2.5, name: "支线管网" },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const pumpStations = [
|
|
|
|
|
+ { id: 1, lat: 31.2504, lng: 121.4937, status: "running", name: "第一泵站" },
|
|
|
|
|
+ { id: 2, lat: 31.2104, lng: 121.4537, status: "stopped", name: "第二泵站" },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ const getMarkerColor = (type: string, data: any) => {
|
|
|
|
|
+ switch (type) {
|
|
|
|
|
+ case "waterlogging":
|
|
|
|
|
+ return data.level > data.threshold ? "red" : data.level > data.threshold * 0.8 ? "orange" : "blue"
|
|
|
|
|
+ case "pipeline":
|
|
|
|
|
+ return data.flow > data.capacity * 0.9 ? "red" : data.flow > data.capacity * 0.7 ? "orange" : "green"
|
|
|
|
|
+ case "pump":
|
|
|
|
|
+ return data.status === "running" ? "green" : data.status === "stopped" ? "gray" : "red"
|
|
|
|
|
+ default:
|
|
|
|
|
+ return "blue"
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="h-full w-full">
|
|
|
|
|
+ <MapContainer center={[31.2304, 121.4737]} zoom={13} className="h-full w-full" ref={mapRef}>
|
|
|
|
|
+ <TileLayer
|
|
|
|
|
+ attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
|
|
|
+ url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <LayersControl position="topright">
|
|
|
|
|
+ {(type === "overview" || type === "waterlogging") && (
|
|
|
|
|
+ <LayersControl.Overlay checked name="易积水点">
|
|
|
|
|
+ <>
|
|
|
|
|
+ {waterloggingPoints.map((point) => (
|
|
|
|
|
+ <Marker key={point.id} position={[point.lat, point.lng]}>
|
|
|
|
|
+ <Popup>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <h4>{point.name}</h4>
|
|
|
|
|
+ <p>当前液位: {point.level}m</p>
|
|
|
|
|
+ <p>报警阈值: {point.threshold}m</p>
|
|
|
|
|
+ <p>状态: {point.level > point.threshold ? "报警" : "正常"}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Popup>
|
|
|
|
|
+ </Marker>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ {waterloggingPoints.map((point) => (
|
|
|
|
|
+ <Circle
|
|
|
|
|
+ key={`circle-${point.id}`}
|
|
|
|
|
+ center={[point.lat, point.lng]}
|
|
|
|
|
+ radius={200}
|
|
|
|
|
+ color={getMarkerColor("waterlogging", point)}
|
|
|
|
|
+ fillOpacity={0.3}
|
|
|
|
|
+ />
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </>
|
|
|
|
|
+ </LayersControl.Overlay>
|
|
|
|
|
+ )}
|
|
|
|
|
+
|
|
|
|
|
+ {(type === "overview" || type === "pipeline") && (
|
|
|
|
|
+ <LayersControl.Overlay checked name="管网监测点">
|
|
|
|
|
+ <>
|
|
|
|
|
+ {pipelinePoints.map((point) => (
|
|
|
|
|
+ <Marker key={point.id} position={[point.lat, point.lng]}>
|
|
|
|
|
+ <Popup>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <h4 className="font-bold">{point.name}</h4>
|
|
|
|
|
+ <p>当前流量: {point.flow}m³/s</p>
|
|
|
|
|
+ <p>设计流量: {point.capacity}m³/s</p>
|
|
|
|
|
+ <p>负荷率: {((point.flow / point.capacity) * 100).toFixed(1)}%</p>
|
|
|
|
|
+ <p>状态:
|
|
|
|
|
+ <span className={
|
|
|
|
|
+ point.flow > point.capacity * 0.9
|
|
|
|
|
+ ? "text-red-600 font-bold"
|
|
|
|
|
+ : point.flow > point.capacity * 0.7
|
|
|
|
|
+ ? "text-orange-600 font-bold"
|
|
|
|
|
+ : "text-green-600"
|
|
|
|
|
+ }>
|
|
|
|
|
+ {point.flow > point.capacity * 0.9
|
|
|
|
|
+ ? " 高负荷"
|
|
|
|
|
+ : point.flow > point.capacity * 0.7
|
|
|
|
|
+ ? " 中负荷"
|
|
|
|
|
+ : " 正常"}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Popup>
|
|
|
|
|
+ </Marker>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </>
|
|
|
|
|
+ </LayersControl.Overlay>
|
|
|
|
|
+ )}
|
|
|
|
|
+
|
|
|
|
|
+ {(type === "overview" || type === "pump") && (
|
|
|
|
|
+ <LayersControl.Overlay checked name="泵站">
|
|
|
|
|
+ <>
|
|
|
|
|
+ {pumpStations.map((station) => (
|
|
|
|
|
+ <Marker key={`marker-${station.id}`} position={[station.lat, station.lng]}>
|
|
|
|
|
+ <Popup>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <h4 className="font-bold">{station.name}</h4>
|
|
|
|
|
+ <p>运行状态:
|
|
|
|
|
+ <span className={
|
|
|
|
|
+ station.status === "running"
|
|
|
|
|
+ ? "text-green-600 font-bold"
|
|
|
|
|
+ : "text-gray-600"
|
|
|
|
|
+ }>
|
|
|
|
|
+ {station.status === "running" ? " 运行中" : " 停止"}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Popup>
|
|
|
|
|
+ </Marker>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </>
|
|
|
|
|
+ </LayersControl.Overlay>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </LayersControl>
|
|
|
|
|
+ </MapContainer>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|