Ejemplo n.º 1
0
    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)]
Ejemplo n.º 2
0
    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)]
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
 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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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)]
Ejemplo n.º 10
0
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)