Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -8,7 +8,6 @@ import shapely.geometry
|
|
| 8 |
import pyprt
|
| 9 |
import glob
|
| 10 |
import shutil
|
| 11 |
-
import pyproj
|
| 12 |
from shapely.ops import transform
|
| 13 |
from shapely.affinity import translate
|
| 14 |
import functools
|
|
@@ -569,15 +568,13 @@ async def generate_i3s(request: GenerateRequest):
|
|
| 569 |
if not shape.is_valid:
|
| 570 |
shape = shape.buffer(0)
|
| 571 |
|
| 572 |
-
# 2.
|
| 573 |
-
#
|
| 574 |
-
|
| 575 |
-
if ecef_center:
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
else:
|
| 580 |
-
logger.warning("No ECEF center — I3S placed at 3857 origin (incorrect)")
|
| 581 |
|
| 582 |
centroid = shape.centroid
|
| 583 |
shape_centered = translate(shape, xoff=-centroid.x, yoff=-centroid.y)
|
|
@@ -585,8 +582,8 @@ async def generate_i3s(request: GenerateRequest):
|
|
| 585 |
if coords[0] == coords[-1]:
|
| 586 |
coords = coords[:-1]
|
| 587 |
|
| 588 |
-
#
|
| 589 |
-
#
|
| 590 |
flattened_coords = []
|
| 591 |
for p in coords:
|
| 592 |
flattened_coords.extend([p[0], 0, -p[1]])
|
|
@@ -600,17 +597,19 @@ async def generate_i3s(request: GenerateRequest):
|
|
| 600 |
|
| 601 |
initial_shape = pyprt.InitialShape(flattened_coords, indices, face_counts)
|
| 602 |
|
| 603 |
-
# 3. Encoder Options — Global scene,
|
|
|
|
|
|
|
| 604 |
layer_id = str(uuid.uuid4())
|
| 605 |
output_dir = os.path.join(LAYERS_DIR, layer_id)
|
| 606 |
os.makedirs(output_dir, exist_ok=True)
|
| 607 |
|
| 608 |
-
slpk_name = f"SceneLayer_{layer_id[:
|
| 609 |
enc_options = {
|
| 610 |
'sceneType': 'Global',
|
| 611 |
-
|
| 612 |
-
#
|
| 613 |
-
|
| 614 |
'baseName': slpk_name,
|
| 615 |
'writePackage': False, # unzipped folder; fallback extracts .slpk if unsupported
|
| 616 |
'layerTextureEncoding': ['2'],
|
|
|
|
| 8 |
import pyprt
|
| 9 |
import glob
|
| 10 |
import shutil
|
|
|
|
| 11 |
from shapely.ops import transform
|
| 12 |
from shapely.affinity import translate
|
| 13 |
import functools
|
|
|
|
| 568 |
if not shape.is_valid:
|
| 569 |
shape = shape.buffer(0)
|
| 570 |
|
| 571 |
+
# 2. ecef_center from Cesium is already EPSG:4978 (ECEF X/Y/Z in metres).
|
| 572 |
+
# Use it directly as globalOffset — no projection conversion needed.
|
| 573 |
+
# Vertices stay in ENU-local CGA format (small offsets, same as GLB).
|
| 574 |
+
if not ecef_center:
|
| 575 |
+
logger.warning("No ECEF center — I3S placed at Earth origin (incorrect)")
|
| 576 |
+
ecef_center = (0.0, 0.0, 0.0)
|
| 577 |
+
logger.info(f"I3S ECEF anchor: ({ecef_center[0]:.1f}, {ecef_center[1]:.1f}, {ecef_center[2]:.1f})")
|
|
|
|
|
|
|
| 578 |
|
| 579 |
centroid = shape.centroid
|
| 580 |
shape_centered = translate(shape, xoff=-centroid.x, yoff=-centroid.y)
|
|
|
|
| 582 |
if coords[0] == coords[-1]:
|
| 583 |
coords = coords[:-1]
|
| 584 |
|
| 585 |
+
# ENU-local CGA vertices: X=east, Y=height=0, Z=-north (same as /generate GLB).
|
| 586 |
+
# The encoder rotates these local axes to ECEF using globalOffset as the anchor.
|
| 587 |
flattened_coords = []
|
| 588 |
for p in coords:
|
| 589 |
flattened_coords.extend([p[0], 0, -p[1]])
|
|
|
|
| 597 |
|
| 598 |
initial_shape = pyprt.InitialShape(flattened_coords, indices, face_counts)
|
| 599 |
|
| 600 |
+
# 3. Encoder Options — Global scene, ECEF (EPSG:4978).
|
| 601 |
+
# sceneWkid 4978 is required for sceneType 'Global'.
|
| 602 |
+
# globalOffset = ECEF anchor; encoder rotates local CGA axes to ECEF at that point.
|
| 603 |
layer_id = str(uuid.uuid4())
|
| 604 |
output_dir = os.path.join(LAYERS_DIR, layer_id)
|
| 605 |
os.makedirs(output_dir, exist_ok=True)
|
| 606 |
|
| 607 |
+
slpk_name = f"SceneLayer_{layer_id[:8]}"
|
| 608 |
enc_options = {
|
| 609 |
'sceneType': 'Global',
|
| 610 |
+
'sceneWkid': '4978',
|
| 611 |
+
# ECEF anchor — places the local CGA origin at the drawn polygon centroid
|
| 612 |
+
'globalOffset': list(ecef_center),
|
| 613 |
'baseName': slpk_name,
|
| 614 |
'writePackage': False, # unzipped folder; fallback extracts .slpk if unsupported
|
| 615 |
'layerTextureEncoding': ['2'],
|