Browse Source

使用路由访问

tangbengaoyuan 2 months ago
parent
commit
ca67f534d1
3 changed files with 130 additions and 1 deletions
  1. 13 0
      app/api/point_unit_grouping.py
  2. 4 1
      app/main.py
  3. 113 0
      app/services/point_unit_grouping_service.py

+ 13 - 0
app/api/point_unit_grouping.py

@@ -0,0 +1,13 @@
+from fastapi import APIRouter, Depends
+from sqlalchemy.orm import Session
+from app.database import get_db
+from app.services import point_unit_grouping_service
+
+router = APIRouter(prefix="/point-unit-grouping", tags=["point-unit-grouping"])
+
+@router.get("/get-h-xtfx-result")
+def get_h_xtfx_result(db: Session = Depends(get_db)):
+    """接口:返回单元 h_xtfx结果"""
+    unit_rows, point_rows = point_unit_grouping_service.fetch_unit_and_point_data(db)
+    result = point_unit_grouping_service.check_h_xtfx_values(unit_rows, point_rows)
+    return result

+ 4 - 1
app/main.py

@@ -1,5 +1,6 @@
 from fastapi import FastAPI
-from .api import vector, raster
+
+from .api import vector, raster,point_unit_grouping
 from .database import engine, Base
 
 # 创建数据库表
@@ -24,6 +25,8 @@ app = FastAPI(
 # 注册路由
 app.include_router(vector.router, prefix="/api/vector", tags=["vector"])
 app.include_router(raster.router, prefix="/api/raster", tags=["raster"])
+app.include_router(point_unit_grouping.router, prefix="/api/point-unit-grouping", tags=["point-unit-grouping"])
+
 
 @app.get("/")
 async def root():

+ 113 - 0
app/services/point_unit_grouping_service.py

@@ -0,0 +1,113 @@
+import psycopg2
+from flask import Flask, jsonify
+from shapely import wkb
+from collections import Counter
+from app.database import engine  
+from sqlalchemy.orm import Session  
+from sqlalchemy import text  
+app = Flask(__name__)
+
+# 定义 h_xtfx 值的映射关系(数值用于插值计算)
+h_xtfx_mapping = {
+    "优先保护类": 1,
+    "安全利用类": 2,
+    "严格管控类": 3
+}
+reverse_h_xtfx_mapping = {v: k for k, v in h_xtfx_mapping.items()}
+
+
+
+def fetch_unit_and_point_data(db: Session):
+    """获取单元和点位数据(使用 SQLAlchemy ORM Session)"""
+    try:
+        # 查询单元信息(GID 和 几何图形)
+        unit_query = text("SELECT gid, geom FROM unit_ceil")
+        unit_result = db.execute(unit_query).fetchall()
+
+        # 查询点位信息(ID、几何图形、h_xtfx 值)
+        point_query = text("SELECT id, geom, h_xtfx FROM fifty_thousand_survey_data")
+        point_result = db.execute(point_query).fetchall()
+
+        return unit_result, point_result
+    except Exception as error:
+        print("数据查询失败:", error)
+        return [], []
+
+
+def idw_interpolation(points, target_point):
+    """反距离加权插值函数"""
+    total_weight = 0
+    weighted_sum = 0
+    power = 2  # 距离权重的幂
+    for point, value in points:
+        distance = point.distance(target_point)
+        if distance == 0:
+            return value  # 距离为0时直接返回该点值
+        weight = 1 / (distance ** power)
+        total_weight += weight
+        weighted_sum += weight * value
+    return weighted_sum / total_weight if total_weight != 0 else None
+
+
+def check_h_xtfx_values(unit_rows, point_rows):
+    """核心逻辑:判断单元的 h_xtfx 值"""
+    unit_point_mapping = {}
+    for unit_id, unit_geom_wkb in unit_rows:
+        try:
+            unit_geom = wkb.loads(unit_geom_wkb, hex=True)
+            unit_points = []
+            for point_id, point_geom_wkb, h_xtfx in point_rows:
+                point_geom = wkb.loads(point_geom_wkb, hex=True)
+                if unit_geom.contains(point_geom):
+                    unit_points.append((point_geom, h_xtfx))  # 存储几何坐标和 h_xtfx 值
+            unit_point_mapping[unit_id] = unit_points
+        except Exception as e:
+            print(f"处理单元 {unit_id} 失败:", e)
+
+    result = {}
+    for unit_id, points in unit_point_mapping.items():
+        if not points:
+            result[unit_id] = None
+            continue  # 无点位,直接设为 None
+
+        has_strict_control = any(h_xtfx == "严格管控类" for _, h_xtfx in points)
+        h_xtfx_list = [h_xtfx for _, h_xtfx in points]
+
+        if not has_strict_control:
+            # 无严格管控类:先判断比例是否 ≥80%
+            counter = Counter(h_xtfx_list)
+            most_common, count = counter.most_common(1)[0]
+            if count / len(points) >= 0.8:
+                result[unit_id] = most_common
+                continue  # 比例达标,直接输出
+
+            # 比例不达标:对优先保护类和安全利用类进行插值
+            valid_points = [(geom, h_xtfx_mapping[h_xtfx]) 
+                           for geom, h_xtfx in points 
+                           if h_xtfx in ["优先保护类", "安全利用类"]]
+            if len(valid_points) < 2:
+                # 有效点位不足,取最常见值(避免插值错误)
+                result[unit_id] = most_common
+            else:
+                unit_center = unit_geom.centroid
+                interpolated = idw_interpolation(valid_points, unit_center)
+                result[unit_id] = (
+                    "优先保护类" if interpolated <= 1.5 
+                    else "安全利用类" if interpolated <= 2.5 
+                    else "严格管控类"  # 理论上不会出现,因无严格管控类点位
+                )
+        else:
+            # 存在严格管控类:对所有点位(含严格管控类)进行插值
+            point_coords = [(geom, h_xtfx_mapping[h_xtfx]) for geom, h_xtfx in points]
+            unit_center = unit_geom.centroid
+            interpolated = idw_interpolation(point_coords, unit_center)
+            result[unit_id] = (
+                "优先保护类" if interpolated <= 1.5 
+                else "安全利用类" if interpolated <= 2.5 
+                else "严格管控类"
+            )
+
+    return result
+
+
+