|
@@ -455,82 +455,82 @@ WHERE pac like '{pac}%';"""
|
|
|
# detail=str(e)
|
|
|
# )
|
|
|
|
|
|
-TILE_EXTENT = 4096 # 标准 MVT 精度
|
|
|
-# ---------- 纯 Python 坐标转换 ----------
|
|
|
-def lonlat2xy(lon: float, lat: float) -> tuple[float, float]:
|
|
|
- """4326 -> 3857"""
|
|
|
- x = lon * 20037508.34 / 180
|
|
|
- y = math.log(math.tan((90 + lat) * math.pi / 360)) / (math.pi / 180)
|
|
|
- y = y * 20037508.34 / 180
|
|
|
- return x, y
|
|
|
-
|
|
|
-import mercantile
|
|
|
-from mapbox_vector_tile import encode
|
|
|
-from shapely.geometry import shape
|
|
|
-@router.get("/tile/{option}/{z}/{x}/{y}.pbf")
|
|
|
-async def get_tile(
|
|
|
- option: str = Path(..., regex="^(zj|cj)$"),
|
|
|
- z: int = Path(..., ge=0, le=22),
|
|
|
- x: int = Path(..., ge=0),
|
|
|
- y: int = Path(..., ge=0),
|
|
|
- db: Session = Depends(get_db),
|
|
|
-):
|
|
|
- """
|
|
|
- 根据 Slippy Map 标准 XYZ 返回 MVT 二进制。
|
|
|
- 前端 layer.url = '/tile/zj/{z}/{x}/{y}.pbf'
|
|
|
- """
|
|
|
- table = "tp_geojson_data_zj" if option == "zj" else "tp_geojson_data_cj_sq"
|
|
|
-
|
|
|
- # 1. 计算瓦片 bbox (4326)
|
|
|
- tile_bounds = mercantile.bounds(mercantile.Tile(x, y, z))
|
|
|
- xmin, ymin, xmax, ymax = tile_bounds.west, tile_bounds.south, tile_bounds.east, tile_bounds.north
|
|
|
- print(xmin, ymin, xmax, ymax)
|
|
|
- # 2. 查相交要素
|
|
|
- sql = text(
|
|
|
- f"""
|
|
|
- SELECT id, name, pac, properties,
|
|
|
- ST_AsGeoJSON(geometry) AS geojson
|
|
|
- FROM {table}
|
|
|
- WHERE ST_Intersects(
|
|
|
- geometry,
|
|
|
- ST_GeomFromText(
|
|
|
- 'POLYGON((
|
|
|
-{ymin} {xmin},
|
|
|
-{ymin} {xmax},
|
|
|
-{ymax} {xmax},
|
|
|
-{ymax} {xmin},
|
|
|
-{ymin} {xmin}))',
|
|
|
- 4326
|
|
|
- )
|
|
|
- );
|
|
|
- """
|
|
|
- )
|
|
|
- rows = db.execute(sql).fetchall()
|
|
|
- if not rows:
|
|
|
- raise HTTPException(status_code=204)
|
|
|
-
|
|
|
- # 3. 构造 MVT features
|
|
|
- features: List[Dict[str, Any]] = []
|
|
|
- bounds_3857 = mercantile.xy_bounds(mercantile.Tile(x, y, z))
|
|
|
- bx, by, bw, bh = bounds_3857.left, bounds_3857.bottom, \
|
|
|
- bounds_3857.right - bounds_3857.left, \
|
|
|
- bounds_3857.top - bounds_3857.bottom
|
|
|
-
|
|
|
- for r in rows:
|
|
|
- # 直接用原始 GeoJSON,不做任何坐标变换
|
|
|
- geo = json.loads(r.geojson)
|
|
|
- features.append({
|
|
|
- "geometry": geo, # 必须是 4326 坐标
|
|
|
- "properties": json.loads(r.properties),
|
|
|
- })
|
|
|
-
|
|
|
- # 4. 生成 MVT
|
|
|
- mvt_bytes = encode([
|
|
|
- {
|
|
|
- "name": "layer",
|
|
|
- "features": features,
|
|
|
- "extent": TILE_EXTENT,
|
|
|
- }
|
|
|
- ])
|
|
|
-
|
|
|
- return Response(content=mvt_bytes, media_type="application/x-protobuf")
|
|
|
+# TILE_EXTENT = 4096 # 标准 MVT 精度
|
|
|
+# # ---------- 纯 Python 坐标转换 ----------
|
|
|
+# def lonlat2xy(lon: float, lat: float) -> tuple[float, float]:
|
|
|
+# """4326 -> 3857"""
|
|
|
+# x = lon * 20037508.34 / 180
|
|
|
+# y = math.log(math.tan((90 + lat) * math.pi / 360)) / (math.pi / 180)
|
|
|
+# y = y * 20037508.34 / 180
|
|
|
+# return x, y
|
|
|
+#
|
|
|
+# import mercantile
|
|
|
+# from mapbox_vector_tile import encode
|
|
|
+# from shapely.geometry import shape
|
|
|
+# @router.get("/tile/{option}/{z}/{x}/{y}.pbf")
|
|
|
+# async def get_tile(
|
|
|
+# option: str = Path(..., regex="^(zj|cj)$"),
|
|
|
+# z: int = Path(..., ge=0, le=22),
|
|
|
+# x: int = Path(..., ge=0),
|
|
|
+# y: int = Path(..., ge=0),
|
|
|
+# db: Session = Depends(get_db),
|
|
|
+# ):
|
|
|
+# """
|
|
|
+# 根据 Slippy Map 标准 XYZ 返回 MVT 二进制。
|
|
|
+# 前端 layer.url = '/tile/zj/{z}/{x}/{y}.pbf'
|
|
|
+# """
|
|
|
+# table = "tp_geojson_data_zj" if option == "zj" else "tp_geojson_data_cj_sq"
|
|
|
+#
|
|
|
+# # 1. 计算瓦片 bbox (4326)
|
|
|
+# tile_bounds = mercantile.bounds(mercantile.Tile(x, y, z))
|
|
|
+# xmin, ymin, xmax, ymax = tile_bounds.west, tile_bounds.south, tile_bounds.east, tile_bounds.north
|
|
|
+# print(xmin, ymin, xmax, ymax)
|
|
|
+# # 2. 查相交要素
|
|
|
+# sql = text(
|
|
|
+# f"""
|
|
|
+# SELECT id, name, pac, properties,
|
|
|
+# ST_AsGeoJSON(geometry) AS geojson
|
|
|
+# FROM {table}
|
|
|
+# WHERE ST_Intersects(
|
|
|
+# geometry,
|
|
|
+# ST_GeomFromText(
|
|
|
+# 'POLYGON((
|
|
|
+# {ymin} {xmin},
|
|
|
+# {ymin} {xmax},
|
|
|
+# {ymax} {xmax},
|
|
|
+# {ymax} {xmin},
|
|
|
+# {ymin} {xmin}))',
|
|
|
+# 4326
|
|
|
+# )
|
|
|
+# );
|
|
|
+# """
|
|
|
+# )
|
|
|
+# rows = db.execute(sql).fetchall()
|
|
|
+# if not rows:
|
|
|
+# raise HTTPException(status_code=204)
|
|
|
+#
|
|
|
+# # 3. 构造 MVT features
|
|
|
+# features: List[Dict[str, Any]] = []
|
|
|
+# bounds_3857 = mercantile.xy_bounds(mercantile.Tile(x, y, z))
|
|
|
+# bx, by, bw, bh = bounds_3857.left, bounds_3857.bottom, \
|
|
|
+# bounds_3857.right - bounds_3857.left, \
|
|
|
+# bounds_3857.top - bounds_3857.bottom
|
|
|
+#
|
|
|
+# for r in rows:
|
|
|
+# # 直接用原始 GeoJSON,不做任何坐标变换
|
|
|
+# geo = json.loads(r.geojson)
|
|
|
+# features.append({
|
|
|
+# "geometry": geo, # 必须是 4326 坐标
|
|
|
+# "properties": json.loads(r.properties),
|
|
|
+# })
|
|
|
+#
|
|
|
+# # 4. 生成 MVT
|
|
|
+# mvt_bytes = encode([
|
|
|
+# {
|
|
|
+# "name": "layer",
|
|
|
+# "features": features,
|
|
|
+# "extent": TILE_EXTENT,
|
|
|
+# }
|
|
|
+# ])
|
|
|
+#
|
|
|
+# return Response(content=mvt_bytes, media_type="application/x-protobuf")
|