Spaces:
Sleeping
Sleeping
projection removed
Browse files
app.py
CHANGED
|
@@ -141,45 +141,20 @@ async def generate_model(request: GenerateRequest):
|
|
| 141 |
# PyPRT expects flat list or specific structure depending on version
|
| 142 |
# Using simple approach: create initial shape from vertices
|
| 143 |
|
| 144 |
-
#
|
| 145 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
bounds = shape.bounds
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
# Project to Web Mercator (EPSG:3857)
|
| 154 |
-
# User requested usage of projected web mercator
|
| 155 |
-
logger.info("Projecting to Web Mercator (EPSG:3857)...")
|
| 156 |
-
|
| 157 |
-
proj_str = "epsg:3857"
|
| 158 |
-
|
| 159 |
-
project = functools.partial(
|
| 160 |
-
pyproj.transform,
|
| 161 |
-
pyproj.Proj(init='epsg:4326'), # Source: WGS84
|
| 162 |
-
pyproj.Proj(init='epsg:3857') # Target: Web Mercator
|
| 163 |
-
)
|
| 164 |
-
|
| 165 |
-
shape = transform(project, shape)
|
| 166 |
-
logger.info(f"Projected geometry bounds: {shape.bounds}")
|
| 167 |
-
|
| 168 |
-
# Re-center geometry to (0,0) for model generation
|
| 169 |
-
# This ensures the local origin of the GLB is the center of the building
|
| 170 |
-
projected_centroid = shape.centroid
|
| 171 |
-
shape = translate(shape, xoff=-projected_centroid.x, yoff=-projected_centroid.y)
|
| 172 |
-
|
| 173 |
-
# We need to return the original Lat/Lon centroid for placement
|
| 174 |
-
# Actually we already have it: `lat` and `lon` from earlier
|
| 175 |
-
centroid_lat = lat
|
| 176 |
-
centroid_lon = lon
|
| 177 |
-
else:
|
| 178 |
-
# If already metric, assume centroid is 0,0 or we take existing?
|
| 179 |
-
# For simplicity, if not projected, we assume it's already local/centered or user handles it.
|
| 180 |
-
# But we can still calculate centroid to be safe if wanted.
|
| 181 |
-
centroid_lat = 0.0
|
| 182 |
-
centroid_lon = 0.0
|
| 183 |
|
| 184 |
coords = list(shape.exterior.coords)
|
| 185 |
# Remove last point if duplicate (closed loop)
|
|
@@ -248,31 +223,9 @@ async def generate_model(request: GenerateRequest):
|
|
| 248 |
raise HTTPException(status_code=500, detail=f"GLB Conversion failed: {str(e)}")
|
| 249 |
|
| 250 |
if os.path.exists(glb_path):
|
| 251 |
-
#
|
| 252 |
-
#
|
| 253 |
-
|
| 254 |
-
convergence_angle = 0.0
|
| 255 |
-
try:
|
| 256 |
-
# Create a pipeline to get factors
|
| 257 |
-
# We need the projection object
|
| 258 |
-
proj_target = pyproj.Proj(init='epsg:3857')
|
| 259 |
-
|
| 260 |
-
# Calculate convergence
|
| 261 |
-
factors = proj_target.get_factors(centroid_lon, centroid_lat)
|
| 262 |
-
convergence_angle = factors.meridian_convergence
|
| 263 |
-
logger.info(f"Calculated convergence angle: {convergence_angle} degrees")
|
| 264 |
-
|
| 265 |
-
except Exception as e:
|
| 266 |
-
logger.warning(f"Could not calculate convergence angle: {e}")
|
| 267 |
-
|
| 268 |
-
# We return the GLB file.
|
| 269 |
-
# Note: The temp dir will be cleaned up by OS eventually or we should handle it better.
|
| 270 |
-
headers = {
|
| 271 |
-
"X-Centroid-Lat": str(centroid_lat),
|
| 272 |
-
"X-Centroid-Lon": str(centroid_lon),
|
| 273 |
-
"X-Convergence-Angle": str(convergence_angle)
|
| 274 |
-
}
|
| 275 |
-
return FileResponse(glb_path, media_type="model/gltf-binary", filename="output.glb", headers=headers)
|
| 276 |
else:
|
| 277 |
logger.error(f"GLB file not created at {glb_path}")
|
| 278 |
raise HTTPException(status_code=500, detail="GLB generation failed: Conversion produced no output")
|
|
|
|
| 141 |
# PyPRT expects flat list or specific structure depending on version
|
| 142 |
# Using simple approach: create initial shape from vertices
|
| 143 |
|
| 144 |
+
# Coordinate Processing for Local Tangent Plane
|
| 145 |
+
# The frontend now sends coordinates in proper local meters (ENU frame).
|
| 146 |
+
# We do NOT project or transform them. We explicitly trust the frontend input.
|
| 147 |
+
|
| 148 |
+
# We also don't need to re-center, as the frontend sends relative coordinates from the centroid (0,0).
|
| 149 |
+
# But to be safe, we can ensure centering if the frontend doesn't perfectly center around 0,0.
|
| 150 |
+
# Actually, DrawTools sends vectors from center, so they are practically centered.
|
| 151 |
+
# We'll calculate bounds just for logging.
|
| 152 |
bounds = shape.bounds
|
| 153 |
+
logger.info(f"Received geometry bounds: {bounds}")
|
| 154 |
+
|
| 155 |
+
# Centroid should be near 0,0
|
| 156 |
+
centroid = shape.centroid
|
| 157 |
+
logger.info(f"Geometry Centroid: {centroid.x}, {centroid.y}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
|
| 159 |
coords = list(shape.exterior.coords)
|
| 160 |
# Remove last point if duplicate (closed loop)
|
|
|
|
| 223 |
raise HTTPException(status_code=500, detail=f"GLB Conversion failed: {str(e)}")
|
| 224 |
|
| 225 |
if os.path.exists(glb_path):
|
| 226 |
+
# No headers needed for placement logic anymore.
|
| 227 |
+
# The frontend reconstructs placement from its own state.
|
| 228 |
+
return FileResponse(glb_path, media_type="model/gltf-binary", filename="output.glb")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
else:
|
| 230 |
logger.error(f"GLB file not created at {glb_path}")
|
| 231 |
raise HTTPException(status_code=500, detail="GLB generation failed: Conversion produced no output")
|