def test_errors(png_fname, encoding): """Test errors output from martini.create_tile(terrain) """ # Generate errors output in Python path = this_dir() / f'data/{png_fname}.png' png = imread(path) terrain = decode_ele(png, encoding=encoding) martini = Martini(png.shape[0] + 1) tile = martini.create_tile(terrain) errors = np.asarray(tile.errors_view, dtype=np.float32) # Load JS errors output path = this_dir() / f'data/{png_fname}_errors' with open(path, 'rb') as f: exp_errors = np.frombuffer(f.read(), dtype=np.float32) assert np.array_equal(errors, exp_errors), 'errors not matching expected'
def test_mesh(png_fname, max_error, encoding): # Generate mesh output in Python path = this_dir() / f'data/{png_fname}.png' png = imread(path) terrain = decode_ele(png, encoding=encoding) martini = Martini(png.shape[0] + 1) tile = martini.create_tile(terrain) vertices, triangles = tile.get_mesh(max_error) # Load JS mesh output path = this_dir() / f'data/{png_fname}_vertices_{max_error}' with open(path, 'rb') as f: exp_vertices = np.frombuffer(f.read(), dtype=np.uint16) path = this_dir() / f'data/{png_fname}_triangles_{max_error}' with open(path, 'rb') as f: exp_triangles = np.frombuffer(f.read(), dtype=np.uint32) assert np.array_equal(vertices, exp_vertices), 'vertices not matching expected' assert np.array_equal(triangles, exp_triangles), 'triangles not matching expected'
from imageio import imread from pymartini import Martini, decode_ele path = './test/data/fuji.png' fuji = imread(path) terrain = decode_ele(fuji, 'mapbox') start = time() martini = Martini(fuji.shape[0] + 1) end = time() print(f'init tileset: {(end - start) * 1000:.3f}ms') start = time() tile = martini.create_tile(terrain) end = time() print(f'create tile: {(end - start) * 1000:.3f}ms') start = time() vertices, triangles = tile.get_mesh(30) end = time() print(f'mesh (max_error=30): {(end - start) * 1000:.3f}ms') print(f'vertices: {len(vertices) / 2}, triangles: {len(triangles) / 3}') all_meshes_start = time() for i in range(21): start = time() tile.get_mesh(i) end = time() print(f'mesh {i}: {(end - start) * 1000:.3f}ms')
def _mesh( z: int = None, x: int = None, y: int = None, scale: int = 1, url: str = None, mesh_max_error: float = 10, pixel_selection: str = "first", resampling_method: str = "nearest", mesh_algorithm: str = "pydelatin", flip_y: str = "True", ) -> Tuple: """Handle tile requests.""" if not url: return ("NOK", "text/plain", "Missing URL parameter") # Coerce flip_y to bool if not isinstance(flip_y, bool): flip_y = flip_y in ['True', 'true'] use_delatin = 'delatin' in mesh_algorithm.lower() tile_size = 256 * int(scale) assets = find_assets(x, y, z, url, tile_size) if assets is None: return ("NOK", "text/plain", "no assets found") tile = load_assets( x, y, z, assets, tile_size, # Only need to backfill for martini, not delatin backfill=not use_delatin, input_format=url, pixel_selection=pixel_selection, resampling_method=resampling_method) # Need to transpose; must be before passing to Martini tile = tile.T if tile is None: return ("EMPTY", "text/plain", "empty tiles") bounds = mercantile.bounds(mercantile.Tile(x, y, z)) mesh_max_error = float(mesh_max_error) if use_delatin: tin = Delatin(tile, max_error=mesh_max_error) vertices, triangles = tin.vertices, tin.triangles.flatten() rescaled = delatin_rescale_positions(vertices, bounds, flip_y=flip_y) else: martini = Martini(tile_size + 1) mar_tile = martini.create_tile(tile) vertices, triangles = mar_tile.get_mesh(mesh_max_error) rescaled = martini_rescale_positions(vertices, tile, bounds=bounds, flip_y=flip_y) with BytesIO() as f: quantized_mesh_encoder.encode(f, rescaled, triangles) f.seek(0) return ("OK", "application/vnd.quantized-mesh", f.read())