예제 #1
0
def _create_geometry_class(color_name, background_color_name=None,
                           fill_opacity=None):
    cls_obj = ms.classObj()
    outline_style_obj = ms.styleObj()

    try:
        color = ms.colorObj(*BASE_COLORS[color_name])
    except KeyError:
        raise  # TODO

    outline_style_obj.outlinecolor = color
    cls_obj.insertStyle(outline_style_obj)

    if fill_opacity is not None:
        fill_style_obj = ms.styleObj()
        fill_style_obj.color = ms.colorObj(
            color.red, color.green, color.blue, int(255 * fill_opacity)
        )
        cls_obj.insertStyle(fill_style_obj)

    if background_color_name:
        outline_style_obj.backgroundcolor = ms.colorObj(
            *BASE_COLORS[background_color_name]
        )

    cls_obj.group = color_name
    return cls_obj
예제 #2
0
 def apply_styles(self, layer, fill=False, default=None):
     """ Add style metadata. """
     for name, r, g, b in self.STYLES:
         cls = ms.classObj()
         style = ms.styleObj()
         style.outlinecolor = ms.colorObj(r, g, b)
         if fill:
             style.color = ms.colorObj(r, g, b)
         style.opacity = 50
         cls.insertStyle(style)
         cls.group = name
         layer.insertClass(cls)
     layer.classgroup = (default or self.DEFAULT_STYLE)
예제 #3
0
    def apply_styles(self, layer, fill=False):
        # add style info
        for name, r, g, b in self.STYLES:
            cls = ms.classObj()
            style = ms.styleObj()
            style.outlinecolor = ms.colorObj(r, g, b)
            if fill:
                style.color = ms.colorObj(r, g, b)
            cls.insertStyle(style)
            cls.group = name

            layer.insertClass(cls)

        layer.classgroup = self.DEFAULT_STYLE
예제 #4
0
    def apply_styles(self, layer, fill=False):
        # add style info
        for name, r, g, b in self.STYLES:
            cls = ms.classObj()
            style = ms.styleObj()
            style.outlinecolor = ms.colorObj(r, g, b)
            if fill:
                style.color = ms.colorObj(r, g, b)
            cls.insertStyle(style)
            cls.group = name

            layer.insertClass(cls)

        layer.classgroup = self.DEFAULT_STYLE
예제 #5
0
def _create_raster_layer_objs(map_obj, extent, sr, data, filename_generator,
                              resample=None):
    layer_obj = ms.layerObj(map_obj)
    layer_obj.type = ms.MS_LAYER_RASTER
    layer_obj.status = ms.MS_ON

    layer_obj.data = data

    layer_obj.offsite = ms.colorObj(0, 0, 0)

    if extent:
        layer_obj.setMetaData("wms_extent", "%f %f %f %f" % extent)
        layer_obj.setExtent(*extent)

        if sr.srid is not None:
            short_epsg = "EPSG:%d" % sr.srid
            layer_obj.setMetaData("ows_srs", short_epsg)
            layer_obj.setMetaData("wms_srs", short_epsg)

    layer_obj.setProjection(sr.proj)

    if resample:
        layer_obj.setProcessingKey('RESAMPLE', resample)

    if extent and sr.srid and extent_crosses_dateline(extent, sr.srid):
        wrapped_extent = wrap_extent_around_dateline(extent, sr.srid)

        wrapped_layer_obj = ms.layerObj(map_obj)
        wrapped_layer_obj.type = ms.MS_LAYER_RASTER
        wrapped_layer_obj.status = ms.MS_ON

        wrapped_data = filename_generator.generate()
        vrt.with_extent(data, wrapped_extent, wrapped_data)
        wrapped_layer_obj.data = wrapped_data

        wrapped_layer_obj.offsite = ms.colorObj(0, 0, 0)

        wrapped_layer_obj.setMetaData("ows_srs", short_epsg)
        wrapped_layer_obj.setMetaData("wms_srs", short_epsg)
        wrapped_layer_obj.setProjection(sr.proj)

        wrapped_layer_obj.setExtent(*wrapped_extent)
        wrapped_layer_obj.setMetaData(
            "wms_extent", "%f %f %f %f" % wrapped_extent
        )
        return [layer_obj, wrapped_layer_obj]
    else:
        return [layer_obj]
 def create_polygon_layer(self, coverage, name): 
     layer = self._create_layer(coverage, name, coverage.extent)
     self._set_projection(layer, coverage.spatial_reference)
     layer.type = ms.MS_LAYER_POLYGON
     layer.dump = True
     layer.offsite = ms.colorObj(0, 0, 0)
     return layer
예제 #7
0
 def create_polygon_layer(self, coverage, name):
     layer = self._create_layer(coverage, name, coverage.extent)
     self._set_projection(layer, coverage.spatial_reference)
     layer.type = ms.MS_LAYER_POLYGON
     layer.dump = True
     layer.offsite = ms.colorObj(0, 0, 0)
     return layer
예제 #8
0
    def offsite_color_from_range_type(self, range_type, band_indices=None):
        """ Helper function to create an offsite color for a given range type
            and optionally band indices.
        """
        if band_indices is None:
            if len(range_type) == 1:
                band_indices = [0, 0, 0]
            elif len(range_type) >= 3:
                band_indices = [0, 1, 2]
            else:
                # no offsite color possible
                return None

        if len(band_indices) != 3:
            raise ValueError(
                "Wrong number of band indices to calculate offsite color."
            )

        values = []
        for index in band_indices:
            band = range_type[index]
            nil_value_set = band.nil_value_set
            if nil_value_set and len(nil_value_set) > 0:
                values.append(nil_value_set[0].value)
            else:
                return None

        return ms.colorObj(*values)
예제 #9
0
    def _create_polygon_layer(self, name):
        layer = ms.layerObj()
        layer.name = name
        layer.type = ms.MS_LAYER_POLYGON

        self.apply_styles(layer)

        srid = 4326
        layer.setProjection(crss.asProj4Str(srid))
        layer.setMetaData("ows_srs", crss.asShortCode(srid))
        layer.setMetaData("wms_srs", crss.asShortCode(srid))

        layer.dump = True

        layer.header = os.path.join(settings.PROJECT_DIR, "conf", "outline_template_header.html")
        layer.template = os.path.join(settings.PROJECT_DIR, "conf", "outline_template_dataset.html")
        layer.footer = os.path.join(settings.PROJECT_DIR, "conf", "outline_template_footer.html")

        layer.setMetaData("gml_include_items", "all")
        layer.setMetaData("wms_include_items", "all")

        layer.addProcessing("ITEMS=identifier")

        layer.offsite = ms.colorObj(0, 0, 0)

        return layer
예제 #10
0
    def offsite_color_from_range_type(self, range_type, band_indices=None):
        """ Helper function to create an offsite color for a given range type
            and optionally band indices.
        """
        if band_indices is None:
            if len(range_type) == 1:
                band_indices = [0, 0, 0]
            elif len(range_type) >= 3:
                band_indices = [0, 1, 2]
            else:
                # no offsite color possible
                return None

        if len(band_indices) != 3:
            raise ValueError(
                "Wrong number of band indices to calculate offsite color."
            )

        values = []
        for index in band_indices:
            band = range_type[index]
            nil_value_set = band.nil_value_set

            # we only support offsite colors for "Byte" bands
            if nil_value_set and nil_value_set.data_type != gdal.GDT_Byte:
                return None

            if nil_value_set and len(nil_value_set) > 0:
                values.append(nil_value_set[0].value)
            else:
                return None

        return ms.colorObj(*values)
예제 #11
0
    def _create_polygon_layer(self, name):
        layer = ms.layerObj()
        layer.name = name
        layer.type = ms.MS_LAYER_POLYGON

        self.apply_styles(layer)

        srid = 4326
        layer.setProjection(crss.asProj4Str(srid))
        layer.setMetaData("ows_srs", crss.asShortCode(srid))
        layer.setMetaData("wms_srs", crss.asShortCode(srid))

        layer.dump = True

        layer.header = os.path.join(settings.PROJECT_DIR, "conf", "outline_template_header.html")
        layer.template = os.path.join(settings.PROJECT_DIR, "conf", "outline_template_dataset.html")
        layer.footer = os.path.join(settings.PROJECT_DIR, "conf", "outline_template_footer.html")

        layer.setMetaData("gml_include_items", "all")
        layer.setMetaData("wms_include_items", "all")

        layer.addProcessing("ITEMS=identifier")

        layer.offsite = ms.colorObj(0, 0, 0)

        return layer
예제 #12
0
    def _offsite_color(range_type, indices=None):
        """
        Cretate an offsite color for a given range type and optional list
        of band indices.
        The bands' offise colors are set either from the nil-values of the
        range type or set to zero if there is no nil-value available.
        """
        # TODO: Review the offsite color method.
        if indices == None:
            if len(range_type) >= 3:
                band_indices = [0, 1, 2]
            elif len(range_type) == 2:
                band_indices = [0, 1, 1]
            elif len(range_type) == 1:
                band_indices = [0, 0, 0]
            else:
                # no offsite color possible
                return None
        else:
            band_indices = [v-1 for v in indices]

        if len(band_indices) < 3 or len(band_indices) > 4:
            raise ValueError("Wrong number of band indices to calculate"
                             " the offsite color.")
        values = []
        for index in band_indices:
            nilvalset = range_type[index].nil_value_set
            values.append(nilvalset[0].value if nilvalset else 0)

        return ms.colorObj(*values)
예제 #13
0
def _create_polygon_layer(map_obj):
    layer_obj = ms.layerObj(map_obj)
    layer_obj.type = ms.MS_LAYER_POLYGON
    layer_obj.status = ms.MS_ON

    layer_obj.offsite = ms.colorObj(0, 0, 0)

    srid = 4326
    layer_obj.setProjection(crss.asProj4Str(srid))
    layer_obj.setMetaData("ows_srs", crss.asShortCode(srid))
    layer_obj.setMetaData("wms_srs", crss.asShortCode(srid))

    layer_obj.dump = True

    return layer_obj
예제 #14
0
def _create_raster_style(name, layer, minvalue=0, maxvalue=255,
                         nil_values=None):
    colors = COLOR_SCALES[name]

    nil_values = [float(nil_value) for nil_value in nil_values or []]

    if nil_values:
        offsite = ms.colorObj(*OFFSITE_COLORS.get(name, (0, 0, 0)))
        layer.offsite = offsite

        for nil_value in nil_values:
            cls = ms.classObj()
            cls.setExpression("([pixel] = %s)" % nil_value)
            cls.group = name

            style = ms.styleObj()
            style.color = offsite
            style.opacity = 0
            style.rangeitem = ""
            cls.insertStyle(style)
            layer.insertClass(cls)

    low_nil_values = [
        nil_value for nil_value in nil_values
        if nil_value <= minvalue
    ]
    high_nil_values = [
        nil_value for nil_value in nil_values
        if nil_value >= maxvalue
    ]

    # Create style for values below range, but make sure to not collide
    # with nil-values
    if low_nil_values:
        low_nil = max(low_nil_values)
        cls = ms.classObj()
        cls.setExpression(
            "([pixel] <= %s AND [pixel] > %s)" % (minvalue, low_nil)
        )
        cls.group = name
        style = ms.styleObj()
        style.color = ms.colorObj(*colors[0][1])
        cls.insertStyle(style)
        layer.insertClass(cls)
    else:
        cls = ms.classObj()
        cls.setExpression("([pixel] <= %s)" % (minvalue))
        cls.group = name
        style = ms.styleObj()
        style.color = ms.colorObj(*colors[0][1])
        cls.insertStyle(style)
        layer.insertClass(cls)

    interval = (maxvalue - minvalue)
    for prev_item, next_item in pairwise_iterative(colors):
        prev_perc, prev_color = prev_item
        next_perc, next_color = next_item

        cls = ms.classObj()
        cls.setExpression("([pixel] >= %s AND [pixel] < %s)" % (
            (minvalue + prev_perc * interval),
            (minvalue + next_perc * interval)
        ))
        cls.group = name

        style = ms.styleObj()
        style.mincolor = ms.colorObj(*prev_color)
        style.maxcolor = ms.colorObj(*next_color)
        style.minvalue = minvalue + prev_perc * interval
        style.maxvalue = minvalue + next_perc * interval
        style.rangeitem = ""
        cls.insertStyle(style)
        layer.insertClass(cls)

    # Create style for values above range, but make sure to not collide with
    # nil-values
    if high_nil_values:
        high_nil = min(high_nil_values)
        cls = ms.classObj()
        cls.setExpression(
            "([pixel] > %s AND [pixel] < %s)" % (maxvalue, high_nil)
        )
        cls.group = name
        style = ms.styleObj()
        style.color = ms.colorObj(*colors[0][1])
        cls.insertStyle(style)
        layer.insertClass(cls)
    else:
        cls = ms.classObj()
        cls.setExpression("([pixel] > %s)" % (maxvalue))
        cls.group = name
        style = ms.styleObj()
        style.color = ms.colorObj(*colors[-1][1])
        cls.insertStyle(style)
        layer.insertClass(cls)
예제 #15
0
    def create_coverage_layer(self, map_obj, coverage, fields,
                              style=None, ranges=None):
        """ Creates a mapserver layer object for the given coverage
        """
        filename_generator = FilenameGenerator(
            '/vsimem/{uuid}.{extension}', 'vrt'
        )

        field_locations = [
            (field, coverage.get_location_for_field(field))
            for field in fields
        ]
        locations = [
            location
            for _, location in field_locations
        ]

        # TODO: apply subsets in time/elevation dims
        num_locations = len(set(locations))
        if num_locations == 1:
            if not coverage.grid.is_referenceable:
                location = field_locations[0][1]
                data = location.path
                ms.set_env(map_obj, location.env, True)
            else:
                vrt_path = filename_generator.generate()
                e = map_obj.extent
                resx = (e.maxx - e.minx) / map_obj.width
                resy = (e.maxy - e.miny) / map_obj.height

                wkt = osr.SpatialReference(map_obj.getProjection()).wkt

                # TODO: env?
                reftools.create_rectified_vrt(
                    field_locations[0][1].path, vrt_path,
                    order=1, max_error=10,
                    resolution=(resx, -resy), srid_or_wkt=wkt
                )
                data = vrt_path

        elif num_locations > 1:
            paths_set = set(
                field_location[1].path for field_location in field_locations
            )
            if len(paths_set) == 1:
                location = field_locations[0][1]
                data = location.path
                ms.set_env(map_obj, location.env, True)

            else:
                # TODO
                _build_vrt(coverage.size, field_locations)

        if not coverage.grid.is_referenceable:
            extent = coverage.extent
            sr = coverage.grid.spatial_reference
        else:
            map_extent = map_obj.extent
            extent = (
                map_extent.minx, map_extent.miny,
                map_extent.maxx, map_extent.maxy
            )
            sr = osr.SpatialReference(map_obj.getProjection())

        layer_objs = _create_raster_layer_objs(
            map_obj, extent, sr, data, filename_generator
        )

        for i, layer_obj in enumerate(layer_objs):
            layer_obj.name = '%s__%d' % (coverage.identifier, i)
            layer_obj.setProcessingKey("CLOSE_CONNECTION", "CLOSE")

        if num_locations == 1:
            for layer_obj in layer_objs:
                layer_obj.setProcessingKey("BANDS", ",".join([
                    str(coverage.get_band_index_for_field(field))
                    for field in fields
                ]))
        elif num_locations > 1:
            for layer_obj in layer_objs:
                if len(field_locations) == 3:
                    layer_obj.setProcessingKey("BANDS", "1,2,3")
                else:
                    layer_obj.setProcessingKey("BANDS", "1")

        # make a color-scaled layer
        if len(fields) == 1:
            field = fields[0]
            if ranges:
                range_ = ranges[0]
            else:
                range_ = _get_range(field)

            for layer_obj in layer_objs:
                _create_raster_style(
                    style or "blackwhite", layer_obj, range_[0], range_[1], [
                        nil_value[0] for nil_value in field.nil_values
                    ]
                )
        elif len(fields) in (3, 4):
            for i, field in enumerate(fields, start=1):
                if ranges:
                    if len(ranges) == 1:
                        range_ = ranges[0]
                    else:
                        range_ = ranges[i - 1]
                else:
                    range_ = _get_range(field)

                for layer_obj in layer_objs:
                    layer_obj.setProcessingKey(
                        "SCALE_%d" % i,
                        "%s,%s" % range_
                    )
                    layer_obj.offsite = ms.colorObj(0, 0, 0)

        else:
            raise Exception("Too many bands specified")

        return filename_generator