Beispiel #1
0
 def get_tile_range(self):
     """
     Compute a xyz tile range from the query parameters. If no bbox
     parameter is found, the range defaults to the maximum extent of
     all input raster layers.
     """
     # Get raster layers
     layers = RasterLayer.objects.filter(id__in=self.get_ids().values())
     # Establish zoom level
     if self.request.GET.get('zoom', None):
         zlevel = int(self.request.GET.get('zoom'))
     else:
         # Get highest zoom level of all input layers
         zlevel = max([layer.metadata.max_zoom for layer in layers])
     # Use bounding box to compute tile range
     if self.request.GET.get('bbox', None):
         bbox = Polygon.from_bbox(self.request.GET.get('bbox').split(','))
         bbox.srid = 4326
         bbox.transform(WEB_MERCATOR_SRID)
         tile_range = tile_index_range(bbox.extent, zlevel)
     else:
         # Get list of tile ranges
         layer_ranges = []
         for layer in layers:
             layer_ranges.append(tile_index_range(layer.extent(), zlevel))
         # Estabish overlap of tile index ranges
         tile_range = [
             min([rng[0] for rng in layer_ranges]),
             min([rng[1] for rng in layer_ranges]),
             max([rng[2] for rng in layer_ranges]),
             max([rng[3] for rng in layer_ranges]),
         ]
     return [
         zlevel,
     ] + tile_range
Beispiel #2
0
 def get_tile_range(self):
     """
     Compute a xyz tile range from the query parameters. If no bbox
     parameter is found, the range defaults to the maximum extent of
     all input raster layers.
     """
     # Get raster layers
     layers = RasterLayer.objects.filter(id__in=self.get_ids().values())
     # Establish zoom level
     if self.request.GET.get('zoom', None):
         zlevel = int(self.request.GET.get('zoom'))
     else:
         # Get highest zoom level of all input layers
         zlevel = max([layer.metadata.max_zoom for layer in layers])
     # Use bounding box to compute tile range
     if self.request.GET.get('bbox', None):
         bbox = Polygon.from_bbox(self.request.GET.get('bbox').split(','))
         bbox.srid = 4326
         bbox.transform(WEB_MERCATOR_SRID)
         tile_range = tile_index_range(bbox.extent, zlevel)
     else:
         # Get list of tile ranges
         layer_ranges = []
         for layer in layers:
             layer_ranges.append(tile_index_range(layer.extent(), zlevel))
         # Estabish overlap of tile index ranges
         tile_range = [
             min([rng[0] for rng in layer_ranges]),
             min([rng[1] for rng in layer_ranges]),
             max([rng[2] for rng in layer_ranges]),
             max([rng[3] for rng in layer_ranges]),
         ]
     return [zlevel, ] + tile_range
Beispiel #3
0
 def test_tile_index_range(self):
     bounds = tile_bounds(43, 67, 8)
     geom = OGRGeometry.from_bbox(bounds)
     # With the default tolerance 0, the edging tiles are
     # included.
     idx = tile_index_range(geom.extent, 11)
     self.assertEqual(idx[2] - idx[0], 2**3)
     self.assertEqual(idx[3] - idx[1], 2**3)
     # With a larger tolerance, the strictly overlaping tiles are included.
     idx = tile_index_range(geom.extent, 11, tolerance=1e-3)
     self.assertEqual(idx[2] - idx[0], 2**3 - 1)
     self.assertEqual(idx[3] - idx[1], 2**3 - 1)
Beispiel #4
0
 def test_tile_index_range(self):
     bounds = tile_bounds(43, 67, 8)
     geom = OGRGeometry.from_bbox(bounds)
     # With the default tolerance 0, the edging tiles are
     # included.
     idx = tile_index_range(geom.extent, 11)
     self.assertEqual(idx[2] - idx[0], 2 ** 3)
     self.assertEqual(idx[3] - idx[1], 2 ** 3)
     # With a larger tolerance, the strictly overlaping tiles are included.
     idx = tile_index_range(geom.extent, 11, tolerance=1e-3)
     self.assertEqual(idx[2] - idx[0], 2 ** 3 - 1)
     self.assertEqual(idx[3] - idx[1], 2 ** 3 - 1)
Beispiel #5
0
 def nr_of_tiles(self, zoom):
     """
     Compute the number of tiles for the rasterlayer on a given zoom level.
     """
     bbox = self.dataset.extent
     indexrange = utils.tile_index_range(bbox, zoom)
     return (indexrange[2] - indexrange[0] + 1) * (indexrange[3] - indexrange[1] + 1)
Beispiel #6
0
 def nr_of_tiles(self, zoom):
     """
     Compute the number of tiles for the rasterlayer on a given zoom level.
     """
     bbox = self.dataset.extent
     indexrange = utils.tile_index_range(bbox, zoom)
     return (indexrange[2] - indexrange[0] + 1) * (indexrange[3] - indexrange[1] + 1)
Beispiel #7
0
    def get_tile(self, layer_id, zlevel=None):
        """
        Returns a tile for rendering. If the tile does not exists, higher
        level tiles are searched and warped to lower level if found.
        """
        if self.is_pixel_request:
            tilez = self.max_zoom
            # Derive the tile index from the input coordinates.
            xcoord = float(self.kwargs.get('xcoord'))
            ycoord = float(self.kwargs.get('ycoord'))
            bbox = [xcoord, ycoord, xcoord, ycoord]
            indexrange = tile_index_range(bbox, tilez)
            tilex = indexrange[0]
            tiley = indexrange[1]
        else:
            # Get tile indices from the request url parameters.
            tilez = int(self.kwargs.get('z'))
            tilex = int(self.kwargs.get('x'))
            tiley = int(self.kwargs.get('y'))

        return get_raster_tile(layer_id, tilez, tilex, tiley)
Beispiel #8
0
    def __init__(self, layer_dict, formula, zoom=None, geom=None, acres=True,
                 grouping='auto', all_touched=True, memory_efficient=False, hist_range=None):
        # Set defining parameter for this aggregator
        self.layer_dict = layer_dict
        self.formula = formula
        self.geom = geom
        self.acres = acres
        self.rastgeom = None
        self.all_touched = all_touched
        self.memory_efficient = memory_efficient
        self.hist_range = hist_range

        # Get layers from input dict
        self.layers = RasterLayer.objects.filter(id__in=layer_dict.values())

        # Compute zoom if not provided
        if zoom is None:
            zoom = min(self.layers.values_list('metadata__max_zoom', flat=True))
        self.zoom = zoom

        # Compute tilerange for this area and the given zoom level
        if geom:
            # Transform geom to web mercator
            if geom.srid != WEB_MERCATOR_SRID:
                geom.transform(WEB_MERCATOR_SRID)

            # Clip against max extent for limiting nr of tiles.
            # This is important for requests on large areas for small rasters.
            max_extent = MultiPolygon([Polygon.from_bbox(lyr.extent()) for lyr in self.layers]).envelope
            max_extent = geom.intersection(max_extent)

            # Abort if there is no spatial overlay
            if max_extent.empty:
                self.tilerange = None
                return
            else:
                # Compute tile index range for geometry and given zoom level
                self.tilerange = tile_index_range(max_extent.extent, zoom)
        else:
            # Get index range set for the input layers
            index_ranges = [tile_index_range(lyr.extent(), zoom) for lyr in self.layers]

            # Compute intersection of index ranges
            self.tilerange = [
                max([dat[0] for dat in index_ranges]),
                max([dat[1] for dat in index_ranges]),
                min([dat[2] for dat in index_ranges]),
                min([dat[3] for dat in index_ranges])
            ]

        # Auto determine grouping based on input data
        if grouping == 'auto':
            all_discrete = all((lyr.datatype in (RasterLayer.CATEGORICAL, RasterLayer.MASK) for lyr in self.layers))
            grouping = 'discrete' if all_discrete else 'continuous'
        elif grouping in ('discrete', 'continuous'):
            pass
        else:
            try:
                legend_id = int(grouping)
                grouping = Legend.objects.get(id=legend_id)
            except ValueError:
                pass
            except ObjectDoesNotExist:
                raise RasterAggregationException(
                    'Invalid legend ID found in grouping value for valuecount.'
                )
        self.grouping = grouping
Beispiel #9
0
    def __init__(self,
                 layer_dict,
                 formula,
                 zoom=None,
                 geom=None,
                 acres=True,
                 grouping='auto'):
        # Set defining parameter for this aggregator
        self.layer_dict = layer_dict
        self.formula = formula
        self.geom = geom
        self.acres = acres
        self.rastgeom = None

        # Get layers from input dict
        self.layers = RasterLayer.objects.filter(id__in=layer_dict.values())

        # Compute zoom if not provided
        if zoom is None:
            zoom = min(self.layers.values_list('metadata__max_zoom',
                                               flat=True))
        self.zoom = zoom

        # Compute tilerange for this area and the given zoom level
        if geom:
            # Transform geom to web mercator
            if geom.srid != WEB_MERCATOR_SRID:
                geom.transform(WEB_MERCATOR_SRID)

            # Clip against max extent for limiting nr of tiles.
            # This is important for requests on large areas for small rasters.
            max_extent = MultiPolygon([
                Polygon.from_bbox(lyr.extent()) for lyr in self.layers
            ]).envelope
            max_extent = geom.intersection(max_extent)

            # Abort if there is no spatial overlay
            if max_extent.empty:
                self.tilerange = None
                return
            else:
                # Compute tile index range for geometry and given zoom level
                self.tilerange = tile_index_range(max_extent.extent, zoom)
        else:
            # Get index range set for the input layers
            index_ranges = [
                tile_index_range(lyr.extent(), zoom) for lyr in self.layers
            ]

            # Compute intersection of index ranges
            self.tilerange = [
                max([dat[0] for dat in index_ranges]),
                max([dat[1] for dat in index_ranges]),
                min([dat[2] for dat in index_ranges]),
                min([dat[3] for dat in index_ranges])
            ]

        # Auto determine grouping based on input data
        if grouping == 'auto':
            all_discrete = all(
                [lyr.datatype in ['ca', 'ma'] for lyr in self.layers])
            grouping = 'discrete' if all_discrete else 'continuous'
        elif grouping in ('discrete', 'continuous'):
            pass
        else:
            try:
                legend_id = int(grouping)
                grouping = Legend.objects.get(id=legend_id)
            except ValueError:
                pass
            except ObjectDoesNotExist:
                raise RasterAggregationException(
                    'Invalid legend ID found in grouping value for valuecount.'
                )
        self.grouping = grouping