Skip to content

Commit

Permalink
delatin mesh sort of working with averaged heights/normals but doesn'…
Browse files Browse the repository at this point in the history
…t look good yet
  • Loading branch information
tebben committed Jan 26, 2024
1 parent f27bbb9 commit 5afdb33
Show file tree
Hide file tree
Showing 4 changed files with 501 additions and 12 deletions.
2 changes: 1 addition & 1 deletion ctod/core/cog/cog_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def _set_safe_level(self):
dataset_wgs_width = dataset_bounds.right - dataset_bounds.left
pixels_per_wgs = dataset_width / dataset_wgs_width
pixels_per_tile_downsampled = 256 * max(self.rio_reader.dataset.overviews(1))

for z in range(0, 24):
tile_bounds = self.tms.xy_bounds(Tile(x=0, y=0, z=z))
tile_wgs = tile_bounds.right - tile_bounds.left
Expand Down
57 changes: 54 additions & 3 deletions ctod/core/cog/processor/cog_processor_quantized_mesh_delatin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import json
import logging
import numpy as np

from ctod.core.cog.cog_request import CogRequest
from ctod.core.cog.processor.cog_processor import CogProcessor
from ctod.core.normals import calculate_normals
Expand All @@ -18,6 +22,7 @@ class CogProcessorQuantizedMeshDelatin(CogProcessor):
def __init__(self, request: web.RequestHandler):
super().__init__()
self.ellipsoid: Ellipsoid = WGS84
self._load_settings(request)

def process(self, cog_request: CogRequest) -> tuple:
"""Process a CogRequest and return the vertices, triangles and normals created with PyDelatin.
Expand All @@ -29,9 +34,55 @@ def process(self, cog_request: CogRequest) -> tuple:
tuple: vertices, triangles and normals
"""

tin = Delatin(cog_request.data.data[0], max_error=1)
rescaled = rescale_positions(tin.vertices, cog_request.tile_bounds, flip_y=False)
max_error = self._get_error(cog_request.z)
tin = Delatin(cog_request.data.data[0], max_error=max_error)

vertices = tin.vertices
vertices = vertices.reshape(-1, 3).astype('int32')

## Extract x, y, and z columns
x = vertices[:, 0].astype(int)
y = vertices[:, 1].astype(int)
z = np.round(vertices[:, 2], decimals=4)

# Combine x, y, and z into a new array
vertices = np.column_stack((x, y, z))

rescaled = rescale_positions(vertices, cog_request.tile_bounds, flip_y=False)
cartesian = to_ecef(rescaled, ellipsoid=self.ellipsoid)
normals = calculate_normals(cartesian, tin.triangles) if cog_request.generate_normals else None

return (tin.vertices, tin.triangles, normals)
return (vertices, tin.triangles, normals)

def _load_settings(self, request: web.RequestHandler):
"""Parse the config
Args:
config (dict): The config
"""

self.default_error = int(request.get_argument_ignore_case("defaultGridSize", default=3))
self.zoom_errors = {"15": 5, "16": 4, "17": 3, "18": 2, "19": 0.7, "20": 0.3, "21": 0.15, "22": 0.1}

zoom_errors_string = request.get_argument_ignore_case("zoomErrors", default=None)
if zoom_errors_string:
try:
self.zoom_errors_string = json.loads(zoom_errors_string)
except json.JSONDecodeError as e:
logging.warning("Error parsing zoomErrors:")

def _get_error(self, zoom: int) -> int:
"""Get the grid size for a specific zoom level
Args:
zoom (int): The zoom level
Returns:
int: The grid size
"""

zoom = str(zoom)
if self.zoom_errors is not None and zoom in self.zoom_errors:
return self.zoom_errors[zoom]
else:
return self.default_error
Loading

0 comments on commit 5afdb33

Please sign in to comment.