Bläddra i källkod

feat(test5): 使用 react-leaflet 实现地图功能

- 替换静态地图图片为互动式地图
- 添加 OpenStreetMap 地图瓦片
- 使用 Marker组件替代静态标记
- 引入 Popup 组件显示标记信息- 修复 Leaflet 默认图标问题
nahida 9 månader sedan
förälder
incheckning
1c0d0833cf
1 ändrade filer med 36 tillägg och 30 borttagningar
  1. 36 30
      app/(other)/test5/page.tsx

+ 36 - 30
app/(other)/test5/page.tsx

@@ -40,7 +40,6 @@ import {
   Gauge,
   Layers3,
   LineChartIcon,
-  MapIcon,
   Moon,
   Settings2,
   ShieldCheck,
@@ -54,6 +53,17 @@ import EChart from "@/components/echarts"
 import dayjs from "dayjs"
 import "dayjs/locale/zh-cn"
 import zhCN from "antd/es/locale/zh_CN"
+import {MapContainer, Marker, Popup, TileLayer} from 'react-leaflet'
+import 'leaflet/dist/leaflet.css'
+import L from 'leaflet'
+
+// 修复Leaflet默认图标问题
+delete (L.Icon.Default.prototype as any)._getIconUrl;
+L.Icon.Default.mergeOptions({
+  iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png',
+  iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png',
+  shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png',
+});
 
 dayjs.locale("zh-cn")
 
@@ -627,35 +637,31 @@ export default function Page() {
 
                 <Card title="监测分布(示意)" extra={<span className="text-xs text-slate-500">标注颜色代表风险等级</span>}>
                   <div className="relative w-full h-[380px] rounded-md overflow-hidden bg-slate-100">
-                    <img
-                      src="/images/city-map.png"
-                      alt="城市简化地图"
-                      className="absolute inset-0 w-full h-full object-cover opacity-90"
-                    />
-                    {markers.map((m) => (
-                      <AntdTooltip key={m.id} title={m.title}>
-                        <div
-                          className="absolute w-2.5 h-2.5 rounded-full ring-2 ring-white/70"
-                          style={{ top: m.top, left: m.left, backgroundColor: m.color }}
-                        />
-                      </AntdTooltip>
-                    ))}
-                    <div className="absolute right-3 top-3 bg-white/90 backdrop-blur rounded-md p-2 text-xs shadow">
-                      <div className="font-medium mb-1 flex items-center gap-1">
-                        <MapIcon size={14} /> 覆盖与风险
-                      </div>
-                      <div className="flex items-center gap-3">
-                        <div className="flex items-center gap-1">
-                          <span className="inline-block w-2.5 h-2.5 rounded-full" style={{ background: danger }} /> 高
-                        </div>
-                        <div className="flex items-center gap-1">
-                          <span className="inline-block w-2.5 h-2.5 rounded-full" style={{ background: warn }} /> 中
-                        </div>
-                        <div className="flex items-center gap-1">
-                          <span className="inline-block w-2.5 h-2.5 rounded-full" style={{ background: ok }} /> 低
-                        </div>
-                      </div>
-                    </div>
+                    {/* 替换为react-leaflet地图 */}
+                    <MapContainer 
+                      center={[28.1941, 112.9873]} // 长沙市坐标
+                      zoom={12} 
+                      style={{ height: '100%', width: '100%' }}
+                      zoomControl={true}
+                    >
+                      <TileLayer
+                        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
+                        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+                      />
+                      {markers.map((m) => (
+                        <Marker 
+                          key={m.id} 
+                          position={[
+                            28.1941 + (parseFloat(m.top) - 50) / 100, 
+                            112.9873 + (parseFloat(m.left) - 50) / 100
+                          ]}
+                        >
+                          <Popup>
+                            {m.title}
+                          </Popup>
+                        </Marker>
+                      ))}
+                    </MapContainer>
                   </div>
                 </Card>
               </section>