def fetch_raster(self, projection, extent, target_resolution): """ Fetch SRTM elevation for the given projection and approximate extent. """ if not self.validate_projection(projection): raise ValueError(f'Unsupported projection for the ' f'SRTM{self._resolution} source.') min_x, max_x, min_y, max_y = extent min_x, min_y = np.floor([min_x, min_y]) nx = int(np.ceil(max_x) - min_x) ny = int(np.ceil(max_y) - min_y) skip = False if nx > self._max_tiles[0]: warnings.warn( f'Required SRTM{self._resolution} tile count ({nx}) exceeds ' f'maximum ({self._max_tiles[0]}). Increase max_nx limit.') skip = True if ny > self._max_tiles[1]: warnings.warn( f'Required SRTM{self._resolution} tile count ({ny}) exceeds ' f'maximum ({self._max_tiles[1]}). Increase max_ny limit.') skip = True if skip: return [] else: img, _, extent = self.combined(min_x, min_y, nx, ny) return [LocatedImage(np.flipud(img), extent)]
def fetch_raster(self, projection, extent, target_resolution): target_resolution = np.array(target_resolution, dtype=int) x = np.linspace(extent[0], extent[1], target_resolution[0]) y = np.linspace(extent[2], extent[3], target_resolution[1]) xs, ys = np.meshgrid(x, y) xyz_sample = self._geocent.transform_points( projection, xs.flatten(), ys.flatten()) start = time.time() _, node_indices = self._kd.query(xyz_sample, k=1) end = time.time() logging.info('Query of {} points: {}'.format( np.prod(target_resolution), end - start)) # Clip to valid node indices: can get =N-points for NaN or inf. points. n_points = self._node_faces.shape[0] node_indices[(node_indices < 0) | (node_indices >= n_points)] = 0 start = time.time() face_indices = fmgc.search_faces_for_points( target_points_xyz=xyz_sample, i_nodes_nearest=node_indices, nodes_xyz_array=self._nodes_xyz, face_nodes_array=self._face_nodes, node_faces_array=self._node_faces ) end = time.time() logging.info('Face search of {} points: {}'.format( np.prod(target_resolution), end - start)) result = self.img[face_indices].reshape(target_resolution[1], target_resolution[0]) return [LocatedImage(result, extent)]
def fetch_raster(self, projection, extent, target_resolution): matrix_set_name = self._matrix_set_name(projection) wmts_projection = _URN_TO_CRS[ self.wmts.tilematrixsets[matrix_set_name].crs] if wmts_projection == projection: wmts_extents = [extent] else: # Calculate (possibly multiple) extents in the given projection. wmts_extents = _target_extents(extent, projection, wmts_projection) # Bump resolution by a small factor, as a weak alternative to # delivering a minimum projected resolution. # Generally, the desired area is smaller than the enclosing extent # in projection space and may have varying scaling, so the ideal # solution is a hard problem ! resolution_factor = 1.4 target_resolution = np.array(target_resolution) * resolution_factor width, height = target_resolution located_images = [] for wmts_desired_extent in wmts_extents: # Calculate target resolution for the actual polygon. Note that # this gives *every* polygon enough pixels for the whole result, # which is potentially excessive! min_x, max_x, min_y, max_y = wmts_desired_extent if wmts_projection == projection: max_pixel_span = min((max_x - min_x) / width, (max_y - min_y) / height) else: # X/Y orientation is arbitrary, so use a worst-case guess. max_pixel_span = (min(max_x - min_x, max_y - min_y) / max(width, height)) # Fetch a suitable image and its actual extent. wmts_image, wmts_actual_extent = self._wmts_images( self.wmts, self.layer, matrix_set_name, extent=wmts_desired_extent, max_pixel_span=max_pixel_span) # Return each (image, extent) as a LocatedImage. if wmts_projection == projection: located_image = LocatedImage(wmts_image, wmts_actual_extent) else: # Reproject the image to the desired projection. located_image = _warped_located_image( wmts_image, wmts_projection, wmts_actual_extent, output_projection=projection, output_extent=extent, target_resolution=target_resolution) located_images.append(located_image) return located_images
def fetch_raster(self, projection, extent, target_resolution): matrix_set_name = self._matrix_set_name(projection) min_x, max_x, min_y, max_y = extent width, height = target_resolution max_pixel_span = min((max_x - min_x) / width, (max_y - min_y) / height) image, extent = self._wmts_images(self.wmts, self.layer, matrix_set_name, extent, max_pixel_span) return [LocatedImage(image, extent)]
def fill_and_shade(located_elevations): """ Given an array of elevations in a LocatedImage, fill any holes in the data and add a relief (shadows) to give a realistic 3d appearance. """ new_elevations = srtm.fill_gaps(located_elevations.image, max_distance=15) new_img = srtm.add_shading(new_elevations, azimuth=135, altitude=15) return LocatedImage(new_img, located_elevations.extent)
def shade(located_elevations): """ Given an array of elevations in a LocatedImage, add a relief (shadows) to give a realistic 3d appearance. """ new_img = srtm.add_shading(located_elevations.image, azimuth=135, altitude=15) return LocatedImage(new_img, located_elevations.extent)
def _warped_located_image(image, source_projection, source_extent, output_projection, output_extent, target_resolution): """ Reproject an Image from one source-projection and extent to another. Returns ------- LocatedImage A reprojected LocatedImage, the extent of which is >= the requested 'output_extent'. """ if source_projection == output_projection: extent = output_extent else: # Convert Image to numpy array (flipping so that origin # is 'lower'). img, extent = warp_array(np.asanyarray(image)[::-1], source_proj=source_projection, source_extent=source_extent, target_proj=output_projection, target_res=np.asarray(target_resolution, dtype=int), target_extent=output_extent, mask_extrapolated=True) # Convert arrays with masked RGB(A) values to non-masked RGBA # arrays, setting the alpha channel to zero for masked values. # This avoids unsightly grey boundaries appearing when the # extent is limited (i.e. not global). if np.ma.is_masked(img): if img.shape[2:3] == (3,): # RGB old_img = img img = np.zeros(img.shape[:2] + (4,), dtype=img.dtype) img[:, :, 0:3] = old_img img[:, :, 3] = ~ np.any(old_img.mask, axis=2) if img.dtype.kind == 'u': img[:, :, 3] *= 255 elif img.shape[2:3] == (4,): # RGBA img[:, :, 3] = np.where(np.any(img.mask, axis=2), 0, img[:, :, 3]) img = img.data # Convert warped image array back to an Image, undoing the # earlier flip. image = Image.fromarray(img[::-1]) return LocatedImage(image, extent)
def _image_and_extent(self, wms_proj, wms_srs, wms_extent, output_proj, output_extent, target_resolution): min_x, max_x, min_y, max_y = wms_extent wms_image = self.service.getmap(layers=self.layers, srs=wms_srs, bbox=(min_x, min_y, max_x, max_y), size=target_resolution, format='image/png', **self.getmap_extra_kwargs) wms_image = Image.open(io.BytesIO(wms_image.read())) if wms_proj == output_proj: extent = output_extent else: # Convert Image to numpy array (flipping so that origin # is 'lower'). img, extent = warp_array(np.asanyarray(wms_image)[::-1], source_proj=wms_proj, source_extent=wms_extent, target_proj=output_proj, target_res=target_resolution, target_extent=output_extent, mask_extrapolated=True) # Convert arrays with masked RGB(A) values to non-masked RGBA # arrays, setting the alpha channel to zero for masked values. # This avoids unsightly grey boundaries appearing when the # extent is limited (i.e. not global). if np.ma.is_masked(img): if img.shape[2:3] == (3, ): # RGB old_img = img img = np.zeros(img.shape[:2] + (4, ), dtype=img.dtype) img[:, :, 0:3] = old_img img[:, :, 3] = ~np.any(old_img.mask, axis=2) if img.dtype.kind == 'u': img[:, :, 3] *= 255 elif img.shape[2:3] == (4, ): # RGBA img[:, :, 3] = np.where(np.any(img.mask, axis=2), 0, img[:, :, 3]) img = img.data # Convert warped image array back to an Image, undoing the # earlier flip. wms_image = Image.fromarray(img[::-1]) return LocatedImage(wms_image, extent)
def fetch_raster(self, projection, extent, target_resolution): """ Fetch SRTM3 elevation for the given projection and approximate extent. """ if not self.validate_projection(projection): raise ValueError('Unsupported projection for the SRTM3 source.') min_x, max_x, min_y, max_y = extent min_x, min_y = np.floor([min_x, min_y]) nx = int(np.ceil(max_x) - min_x) ny = int(np.ceil(max_y) - min_y) if nx > self._max_tiles[0] or ny > self._max_tiles[1]: return [] else: img, _, extent = self.combined(min_x, min_y, nx, ny) return [LocatedImage(np.flipud(img), extent)]
def _warped_located_image(image, source_projection, source_extent, output_projection, output_extent, target_resolution): """ Reproject an Image from one source-projection and extent to another. Returns ------- LocatedImage A reprojected LocatedImage, the extent of which is >= the requested 'output_extent'. """ if source_projection == output_projection: extent = output_extent else: # Convert Image to numpy array (flipping so that origin # is 'lower'). # Convert to RGBA to keep the color palette in the regrid process # if any img, extent = warp_array(np.asanyarray(image.convert('RGBA'))[::-1], source_proj=source_projection, source_extent=source_extent, target_proj=output_projection, target_res=np.asarray(target_resolution, dtype=int), target_extent=output_extent, mask_extrapolated=True) # Convert arrays with masked RGB(A) values to non-masked RGBA # arrays, setting the alpha channel to zero for masked values. # This avoids unsightly grey boundaries appearing when the # extent is limited (i.e. not global). if np.ma.is_masked(img): img[:, :, 3] = np.where(np.any(img.mask, axis=2), 0, img[:, :, 3]) img = img.data # Convert warped image array back to an Image, undoing the # earlier flip. image = Image.fromarray(img[::-1]) return LocatedImage(image, extent)