Jelajahi Sumber

选址提示词修改

liutao 1 bulan lalu
induk
melakukan
322ef79a0e

+ 53 - 0
landsite_agent/gistools/geo_analysis.py

@@ -0,0 +1,53 @@
+import json
+from shapely import wkt
+from database import Database
+from typing import Any, List, Dict
+
+database = Database()
+
+async def _intersect_query(
+    geom: str,
+    distance: float,
+    sql_template: str,
+    srid: int = 4490
+) -> List[Dict[str, Any]]:
+    """
+    通用的空间相交查询函数。
+
+    :param geom: WKT格式的几何对象字符串
+    :param distance: 缓冲区距离(米)
+    :param sql_template: SQL模板,需包含 {bufWkt} 占位符
+    :param srid: 空间参考ID,默认为4490
+    :return: 查询结果列表
+    """
+    geometry = wkt.loads(geom)
+    buf = geometry.buffer(distance / 111194)
+    bufWkt = buf.wkt
+    if not bufWkt.startswith(f'SRID={srid}'):
+        bufWkt = f'SRID={srid};' + bufWkt
+    sql = sql_template.format(bufWkt=bufWkt)
+    # logging.debug(sql)
+    dataList = await database.execute_query(sql)
+    # logging.debug(dataList)
+    return dataList
+
+async def intersect_kfq(geom: str) -> List[Dict[str, Any]]:
+    """
+    查询缓冲区内的开发区信息
+    """
+    sql_template = (
+        "select kfqmc as name, gljgdz as address, zdcy as primaryIndustry, "
+        "kfqjb1 as kfqjb, st_asgeojson(shape) as geom "
+        "from sde.kfq where st_intersects(shape, '{bufWkt}')"
+    )
+    return await _intersect_query(geom, distance=5000, sql_template=sql_template)
+
+async def intersect_gyyd(geom: str) -> List[Dict[str, Any]]:
+    """
+    查询缓冲区内的工业用地信息
+    """
+    sql_template = (
+        "select tdqlr as name, tdzl as address, st_asgeojson(shape) as geom "
+        "from sde.zjgyydc where st_intersects(shape, '{bufWkt}')"
+    )
+    return await _intersect_query(geom, distance=1000, sql_template=sql_template)

+ 5 - 5
landsite_agent/main.py

@@ -9,11 +9,11 @@ from typing import AsyncGenerator, List, Dict, Any
 import uvicorn
 import traceback
 import asyncio
-
+from xuanzhi_query import router as xz_router
 from sql_generator import SQLGenerator
 
 app = FastAPI(title="Land Analysis API")
-
+app.include_router(xz_router)
 # 配置CORS
 app.add_middleware(
     CORSMiddleware,
@@ -65,7 +65,7 @@ async def stream_land_analysis(request: QueryRequest):
                     if result["status"] == "error":
                         yield json.dumps({
                             "type": "error",
-                            "message": result["message"]
+                            "content": result["content"]
                         }, ensure_ascii=False) + "\n"
                         return
 
@@ -84,7 +84,7 @@ async def stream_land_analysis(request: QueryRequest):
             traceback.print_exc()
             yield json.dumps({
                 "type": "error",
-                "message": str(e)
+                "content": str(e)
             }, ensure_ascii=False) + "\n"
 
     return StreamingResponse(
@@ -136,5 +136,5 @@ async def shutdown_event():
 
 
 if __name__ == "__main__":
-    uvicorn.run(app, host="0.0.0.0", port=8001)
+    uvicorn.run(app, host="0.0.0.0", port=8521)
 

+ 6 - 5
landsite_agent/prompt_template.py

@@ -60,10 +60,9 @@ PROMPT_TEMPLATE = """
    - 不允许使用 SELECT * 或其他字段
    - 示例:SELECT id FROM table WHERE condition;
 
-5. 结果数量限制:
-   - 所有查询必须使用 LIMIT 5 限制返回结果数量
-   - 最多只返回5条数据
-   - 示例:SELECT id FROM table WHERE condition LIMIT 5;
+5. 使用LIMIT进行数量限制,具体规则如下:
+   - 如果用户问题中指定了数量(如3宗、5块),则SQL中使用对应的LIMIT值
+   - 如果未限定数量或限定数量大于5,则SQL中使用LIMIT 5
 
 6. 其他注意事项:
    - 确保SQL语句的语法正确性
@@ -81,7 +80,9 @@ PROMPT_TEMPLATE = """
 2. 只查询id字段
 3. 包含shape is not null条件
 4. 正确使用面积字段和单位
-5. 使用LIMIT 5限制返回结果数量
+5. 使用LIMIT进行数量限制,具体规则如下:
+   - 如果用户问题中指定了数量(如3宗、5块),则SQL中使用对应的LIMIT值
+   - 如果未限定数量或限定数量大于5,则SQL中使用LIMIT 5
 6. 遵循其他注意事项
 
 请按照以下格式输出,每个部分之间用空行分隔:

+ 64 - 0
landsite_agent/xuanzhi_query.py

@@ -0,0 +1,64 @@
+import json
+from fastapi import APIRouter, Query
+from typing import List, Any
+
+from gistools.geo_analysis import intersect_kfq, intersect_gyyd
+from database import Database
+
+router = APIRouter()
+database = Database()
+
+@router.get("/kg-query")
+async def kg_query(id: str = Query(..., description="ID列表, 逗号分隔")) -> List[Any]:
+    """
+    查询控制性详细规划信息
+    """
+    sql = (
+        "select id, xzqmc, xzqdm, dymc, yddm, ydxz, ydmj, rjlsx, rjlxx, jzmdsx, jzmdxx, "
+        "jzgdsx, jzgdxx, ldlsx, ldlxx, pfwh, pfsj, st_area(shape::geography) as pfmarea, "
+        "st_astext(shape) as geom, st_astext(st_centroid(shape)) as center_wkt "
+        "from sde.kzxxxgh where id in ({id})"
+    )
+    result = await database.execute_query(sql.format(id=id))
+    return result
+
+@router.get("/klyzy-query")
+async def klyzy_query(id: str = Query(..., description="ID列表, 逗号分隔")) -> List[Any]:
+    """
+    查询可利用资源信息
+    """
+    sql = (
+        "select *, st_astext(shape) as geom, st_astext(st_centroid(shape)) as center_wkt "
+        "from sde.ecgap_klyzy where id in ({id})"
+    )
+    result = await database.execute_query(sql.format(id=id))
+    return result
+
+@router.get("/population")
+async def population_query(name: str = Query(..., description="地名")) -> List[Any]:
+    """
+    查询人口信息
+    """
+    sql = (
+        "select pop_age_o as 老年人口, pop_age_m as 中青年人口, pop_sex_m as 男性人口, "
+        "pop_sex_f as 女性人口, pop as 人口总量 "
+        "from sde.layer_poi_population where name = '{name}'"
+    )
+    result = await database.execute_query(sql.format(name=name))
+    return result
+
+@router.get("/kfq-intersect")
+async def kfq_intersect(wkt: str = Query(..., description="WKT字符串")) -> List[Any]:
+    """
+    查询缓冲区内的开发区信息
+    """
+    result = await intersect_kfq(wkt)
+    return result
+
+@router.get("/gyyd-intersect")
+async def gyyd_intersect(wkt: str = Query(..., description="WKT字符串")) -> List[Any]:
+    """
+    查询缓冲区内的工业用地信息
+    """
+    result = await intersect_gyyd(wkt)
+    return result