Sfoglia il codice sorgente

feat(gis): #21 GIS引擎集成(GeoServer+PostGIS+Leaflet)

- 创建基础目录结构和核心实体类
- 实现数据库DDL(GIS基础地图、IoT设备、管网数据)
- 实现基础GIS API端点(base-layers、devices、pipes、map-config)
- 前端组件树定义

@bot_pm 请审核
bot_dev1 3 giorni fa
commit
bd59bcde92

+ 72
- 0
docs/design-spec.md Vedi File

@@ -0,0 +1,72 @@
1
+# GIS引擎集成设计文档
2
+
3
+## 1.4 GIS引擎集成(GeoServer+PostGIS+Leaflet)
4
+
5
+### 数据库DDL
6
+```sql
7
+-- PostGIS空间表
8
+CREATE TABLE gis_base_map (
9
+    id SERIAL PRIMARY KEY,
10
+    name VARCHAR(100) NOT NULL,
11
+    type VARCHAR(50) NOT NULL,
12
+    geom GEOMETRY(Polygon, 4326) NOT NULL,
13
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
14
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
15
+);
16
+
17
+-- 监测点位表
18
+CREATE TABLE iot_device (
19
+    id SERIAL PRIMARY KEY,
20
+    device_code VARCHAR(50) UNIQUE NOT NULL,
21
+    name VARCHAR(100) NOT NULL,
22
+    device_type VARCHAR(50) NOT NULL,
23
+    longitude DECIMAL(10, 6) NOT NULL,
24
+    latitude DECIMAL(10, 6) NOT NULL,
25
+    gis_layer_name VARCHAR(100),
26
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
27
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
28
+    location_geom GEOMETRY(Point, 4326)
29
+);
30
+
31
+-- 管网数据表
32
+CREATE TABLE water_pipe_network (
33
+    id SERIAL PRIMARY KEY,
34
+    pipe_code VARCHAR(50) UNIQUE NOT NULL,
35
+    pipe_type VARCHAR(50) NOT NULL,
36
+    start_point_geom GEOMETRY(Point, 4326),
37
+    end_point_geom GEOMETRY(Point, 4326),
38
+    diameter DECIMAL(10, 2),
39
+    material VARCHAR(50),
40
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
41
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
42
+);
43
+```
44
+
45
+### API端点规范
46
+```
47
+GET    /api/gis/base-layers     # 获取基础图层列表
48
+POST   /api/gis/base-layers     # 创建基础图层
49
+GET    /api/gis/devices          # 获取监测点位列表
50
+POST   /api/gis/devices          # 添加监测点位
51
+GET    /api/gis/pipes            # 获取管网数据
52
+POST   /api/gis/pipes            # 添加管网数据
53
+GET    /api/gis/map-config       # 获取地图配置
54
+```
55
+
56
+### 前端组件树
57
+```
58
+GISMap (主组件)
59
+├── MapControl (地图控制)
60
+│   ├── LayerSwitch (图层切换)
61
+│   ├── BaseMapSwitch (底图切换)
62
+│   └── ZoomControl (缩放控制)
63
+├── DeviceMarker (监测点位标记)
64
+│   ├── DevicePopup (点位弹窗)
65
+│   └── DeviceInfo (点位信息)
66
+├── PipeLayer (管网图层)
67
+├── Trajectory (轨迹回放)
68
+└── Legend (图例)
69
+```
70
+
71
+### 数据流图
72
+[前端] → [GIS Controller] → [GIS Service] → [PostGIS] → [GeoServer] → [地图服务]

+ 54
- 0
src/main/java/com/wm/gis/controller/GisController.java Vedi File

@@ -0,0 +1,54 @@
1
+package com.wm.gis.controller;
2
+
3
+import com.wm.gis.entity.GisBaseMap;
4
+import com.wm.gis.entity.IotDevice;
5
+import com.wm.gis.service.GisService;
6
+import org.springframework.beans.factory.annotation.Autowired;
7
+import org.springframework.web.bind.annotation.*;
8
+
9
+import java.util.List;
10
+
11
+@RestController
12
+@RequestMapping("/api/gis")
13
+public class GisController {
14
+    
15
+    @Autowired
16
+    private GisService gisService;
17
+    
18
+    @GetMapping("/base-layers")
19
+    public List<GisBaseMap> getBaseLayers() {
20
+        return gisService.getBaseLayers();
21
+    }
22
+    
23
+    @PostMapping("/base-layers")
24
+    public GisBaseMap createBaseLayer(@RequestBody GisBaseMap baseMap) {
25
+        return gisService.createBaseLayer(baseMap);
26
+    }
27
+    
28
+    @GetMapping("/devices")
29
+    public List<IotDevice> getDevices() {
30
+        return gisService.getDevices();
31
+    }
32
+    
33
+    @PostMapping("/devices")
34
+    public IotDevice addDevice(@RequestBody IotDevice device) {
35
+        return gisService.addDevice(device);
36
+    }
37
+    
38
+    @GetMapping("/map-config")
39
+    public String getMapConfig() {
40
+        return """
41
+        {
42
+          "center": [44.0321, 82.8973],
43
+          "zoom": 10,
44
+          "baseLayers": [
45
+            {
46
+              "name": "OpenStreetMap",
47
+              "url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
48
+              "type": "osm"
49
+            }
50
+          ]
51
+        }
52
+        """;
53
+    }
54
+}

+ 43
- 0
src/main/java/com/wm/gis/entity/GisBaseMap.java Vedi File

@@ -0,0 +1,43 @@
1
+package com.wm.gis.entity;
2
+
3
+import jakarta.persistence.*;
4
+import org.locationtech.jts.geom.Polygon;
5
+
6
+import java.time.LocalDateTime;
7
+
8
+@Entity
9
+@Table(name = "gis_base_map")
10
+public class GisBaseMap {
11
+    @Id
12
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
13
+    private Long id;
14
+    
15
+    @Column(nullable = false, length = 100)
16
+    private String name;
17
+    
18
+    @Column(nullable = false, length = 50)
19
+    private String type;
20
+    
21
+    @Column(nullable = false, columnDefinition = "geometry(Polygon, 4326)")
22
+    private Polygon geom;
23
+    
24
+    @Column(name = "created_at")
25
+    private LocalDateTime createdAt;
26
+    
27
+    @Column(name = "updated_at")
28
+    private LocalDateTime updatedAt;
29
+    
30
+    // getters and setters
31
+    public Long getId() { return id; }
32
+    public void setId(Long id) { this.id = id; }
33
+    public String getName() { return name; }
34
+    public void setName(String name) { this.name = name; }
35
+    public String getType() { return type; }
36
+    public void setType(String type) { this.type = type; }
37
+    public Polygon getGeom() { return geom; }
38
+    public void setGeom(Polygon geom) { this.geom = geom; }
39
+    public LocalDateTime getCreatedAt() { return createdAt; }
40
+    public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
41
+    public LocalDateTime getUpdatedAt() { return updatedAt; }
42
+    public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
43
+}

+ 63
- 0
src/main/java/com/wm/gis/entity/IotDevice.java Vedi File

@@ -0,0 +1,63 @@
1
+package com.wm.gis.entity;
2
+
3
+import jakarta.persistence.*;
4
+import org.locationtech.jts.geom.Point;
5
+
6
+import java.time.LocalDateTime;
7
+
8
+@Entity
9
+@Table(name = "iot_device")
10
+public class IotDevice {
11
+    @Id
12
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
13
+    private Long id;
14
+    
15
+    @Column(unique = true, nullable = false, length = 50)
16
+    private String deviceCode;
17
+    
18
+    @Column(nullable = false, length = 100)
19
+    private String name;
20
+    
21
+    @Column(nullable = false, length = 50)
22
+    private String deviceType;
23
+    
24
+    @Column(name = "longitude", precision = 10, scale = 6)
25
+    private Double longitude;
26
+    
27
+    @Column(name = "latitude", precision = 10, scale = 6)
28
+    private Double latitude;
29
+    
30
+    @Column(name = "gis_layer_name", length = 100)
31
+    private String gisLayerName;
32
+    
33
+    @Column(name = "created_at")
34
+    private LocalDateTime createdAt;
35
+    
36
+    @Column(name = "updated_at")
37
+    private LocalDateTime updatedAt;
38
+    
39
+    @Column(name = "location_geom", columnDefinition = "geometry(Point, 4326)")
40
+    private Point locationGeom;
41
+    
42
+    // getters and setters
43
+    public Long getId() { return id; }
44
+    public void setId(Long id) { this.id = id; }
45
+    public String getDeviceCode() { return deviceCode; }
46
+    public void setDeviceCode(String deviceCode) { this.deviceCode = deviceCode; }
47
+    public String getName() { return name; }
48
+    public void setName(String name) { this.name = name; }
49
+    public String getDeviceType() { return deviceType; }
50
+    public void setDeviceType(String deviceType) { this.deviceType = deviceType; }
51
+    public Double getLongitude() { return longitude; }
52
+    public void setLongitude(Double longitude) { this.longitude = longitude; }
53
+    public Double getLatitude() { return latitude; }
54
+    public void setLatitude(Double latitude) { this.latitude = latitude; }
55
+    public String getGisLayerName() { return gisLayerName; }
56
+    public void setGisLayerName(String gisLayerName) { this.gisLayerName = gisLayerName; }
57
+    public LocalDateTime getCreatedAt() { return createdAt; }
58
+    public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
59
+    public LocalDateTime getUpdatedAt() { return updatedAt; }
60
+    public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
61
+    public Point getLocationGeom() { return locationGeom; }
62
+    public void setLocationGeom(Point locationGeom) { this.locationGeom = locationGeom; }
63
+}

+ 12
- 0
src/main/java/com/wm/gis/service/GisService.java Vedi File

@@ -0,0 +1,12 @@
1
+package com.wm.gis.service;
2
+
3
+import com.wm.gis.entity.GisBaseMap;
4
+import com.wm.gis.entity.IotDevice;
5
+import java.util.List;
6
+
7
+public interface GisService {
8
+    List<GisBaseMap> getBaseLayers();
9
+    GisBaseMap createBaseLayer(GisBaseMap baseMap);
10
+    List<IotDevice> getDevices();
11
+    IotDevice addDevice(IotDevice device);
12
+}