123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- # -*- coding: utf-8 -*-
- __author__ = 'wanger'
- __date__ = '2024-08-20'
- __copyright__ = '(C) 2024 by siwei'
- __revision__ = '1.0'
- # inbuilt libraries
- from typing import Dict, Iterable, List, Union
- # third-party libraries
- import seaborn as sns
- from matplotlib.colors import rgb2hex
- def coverage_style_colormapentry(
- color_ramp: Union[List, Dict, Iterable],
- min_value: float,
- max_value: float,
- number_of_classes: int = None,
- ):
- style_append = ""
- n = len(color_ramp)
- if isinstance(color_ramp, list):
- if n != number_of_classes:
- number_of_classes = n
- interval = (max_value - min_value) / (number_of_classes - 1)
- for i, color in enumerate(color_ramp):
- value = min_value + interval * i
- value = round(value, 1)
- style_append += (
- '<sld:ColorMapEntry color="{}" label="{}" quantity="{}"/>'.format(
- color, value, value
- )
- )
- elif isinstance(color_ramp, dict):
- if n != number_of_classes:
- number_of_classes = n
- interval = (max_value - min_value) / (number_of_classes - 1)
- for name, color, i in zip(color_ramp.keys(), color_ramp.values(), range(n)):
- value = min_value + interval * i
- style_append += (
- '<sld:ColorMapEntry color="{}" label=" {}" quantity="{}"/>'.format(
- color, name, value
- )
- )
- else:
- for i, color in enumerate(color_ramp):
- interval = (max_value - min_value) / (number_of_classes - 1)
- value = min_value + interval * i
- style_append += (
- '<sld:ColorMapEntry color="{}" label="{}" quantity="{}"/>'.format(
- color, value, value
- )
- )
- return style_append
- def coverage_style_xml(
- color_ramp, style_name, cmap_type, min_value, max_value, number_of_classes, opacity
- ):
- min_max_difference = max_value - min_value
- style_append = ""
- interval = min_max_difference / (number_of_classes - 1) # noqa
- # The main style of the coverage style
- if isinstance(color_ramp, str):
- palette = sns.color_palette(color_ramp, int(number_of_classes))
- color_ramp = [rgb2hex(i) for i in palette]
- style_append += coverage_style_colormapentry(
- color_ramp, min_value, max_value, number_of_classes
- )
- style = """
- <StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:sld="http://www.opengis.net/sld">
- <UserLayer>
- <sld:LayerFeatureConstraints>
- <sld:FeatureTypeConstraint/>
- </sld:LayerFeatureConstraints>
- <sld:UserStyle>
- <sld:Name>{2}</sld:Name>
- <sld:FeatureTypeStyle>
- <sld:Rule>
- <sld:RasterSymbolizer>
- <sld:Opacity>{3}</sld:Opacity>
- <sld:ChannelSelection>
- <sld:GrayChannel>
- <sld:SourceChannelName>1</sld:SourceChannelName>
- </sld:GrayChannel>
- </sld:ChannelSelection>
- <sld:ColorMap type="{0}">
- {1}
- </sld:ColorMap>
- </sld:RasterSymbolizer>
- </sld:Rule>
- </sld:FeatureTypeStyle>
- </sld:UserStyle>
- </UserLayer>
- </StyledLayerDescriptor>
- """.format(
- cmap_type, style_append, style_name, opacity
- )
- with open("style.sld", "w") as f:
- f.write(style)
- def outline_only_xml(color, width, geom_type="polygon"):
- if geom_type == "point":
- symbolizer = """
- <PointSymbolizer>
- <Graphic>
- <Mark>
- <WellKnownName>circle</WellKnownName>
- <Fill>
- <CssParameter name="fill">{}</CssParameter>
- </Fill>
- </Mark>
- <Size>8</Size>
- </Graphic>
- </PointSymbolizer>
- """.format(
- color
- )
- elif geom_type == "line":
- symbolizer = """
- <LineSymbolizer>
- <Stroke>
- <CssParameter name="stroke">{}</CssParameter>
- <CssParameter name="stroke-width"{}</CssParameter>
- </Stroke>
- </LineSymbolizer>
- """.format(
- color, width
- )
- elif geom_type == "polygon":
- symbolizer = """
- <PolygonSymbolizer>
- <Stroke>
- <CssParameter name="stroke">{}</CssParameter>
- <CssParameter name="stroke-width">{}</CssParameter>
- </Stroke>
- </PolygonSymbolizer>
- """.format(
- color, width
- )
- else:
- print("Error: Invalid geometry type")
- return
- style = """
- <StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:se="http://www.opengis.net/se" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <NamedLayer>
- <se:Name>Layer name</se:Name>
- <UserStyle>
- <se:Name>Layer name</se:Name>
- <se:FeatureTypeStyle>
- <se:Rule>
- <se:Name>Single symbol</se:Name>
- {}
- </se:Rule>
- </se:FeatureTypeStyle>
- </UserStyle>
- </NamedLayer>
- </StyledLayerDescriptor>
- """.format(
- symbolizer
- )
- with open("style.sld", "w") as f:
- f.write(style)
- def catagorize_xml(
- column_name: str,
- values: List[float],
- color_ramp: str = None,
- geom_type: str = "polygon",
- ):
- n = len(values)
- palette = sns.color_palette(color_ramp, int(n))
- palette_hex = [rgb2hex(i) for i in palette]
- rule = ""
- for value, color in zip(values, palette_hex):
- if geom_type == "point":
- rule += """
- <Rule>
- <Name>{0}</Name>
- <Title>{1}</Title>
- <ogc:Filter>
- <ogc:PropertyIsEqualTo>
- <ogc:PropertyName>{0}</ogc:PropertyName>
- <ogc:Literal>{1}</ogc:Literal>
- </ogc:PropertyIsEqualTo>
- </ogc:Filter>
- <PointSymbolizer>
- <Graphic>
- <Mark>
- <WellKnownName>circle</WellKnownName>
- <Fill>
- <CssParameter name="fill">{2}</CssParameter>
- </Fill>
- </Mark>
- <Size>5</Size>
- </Graphic>
- </PointSymbolizer>
- </Rule>
- """.format(
- column_name, value, color
- )
- elif geom_type == "line":
- rule += """
- <Rule>
- <Name>{1}</Name>
- <ogc:Filter>
- <ogc:PropertyIsEqualTo>
- <ogc:PropertyName>{0}</ogc:PropertyName>
- <ogc:Literal>{1}</ogc:Literal>
- </ogc:PropertyIsEqualTo>
- </ogc:Filter>
- <LineSymbolizer>
- <Stroke>
- <CssParameter name="stroke">{2}</CssParameter>
- <CssParameter name="stroke-width">1</CssParameter>
- </Stroke>
- </LineSymbolizer>
- </Rule>
- """.format(
- column_name, value, color
- )
- elif geom_type == "polygon":
- rule += """
- <Rule>
- <Name>{0}</Name>
- <Title>{1}</Title>
- <ogc:Filter>
- <ogc:PropertyIsEqualTo>
- <ogc:PropertyName>{0}</ogc:PropertyName>
- <ogc:Literal>{1}</ogc:Literal>
- </ogc:PropertyIsEqualTo>
- </ogc:Filter>
- <PolygonSymbolizer>
- <Fill>
- <CssParameter name="fill">{2}</CssParameter>
- </Fill>
- <Stroke>
- <CssParameter name="stroke">{3}</CssParameter>
- <CssParameter name="stroke-width">0.5</CssParameter>
- </Stroke>
- </PolygonSymbolizer>
- </Rule>
- """.format(
- column_name, value, color, "#000000"
- )
- else:
- print("Error: Invalid geometry type")
- return
- style = """
- <StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:se="http://www.opengis.net/se" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <NamedLayer>
- <se:Name>Layer name</se:Name>
- <UserStyle>
- <se:Name>Layer name</se:Name>
- <FeatureTypeStyle>
- {}
- </FeatureTypeStyle>
- </UserStyle>
- </NamedLayer>
- </StyledLayerDescriptor>
- """.format(
- rule
- )
- with open("style.sld", "w") as f:
- f.write(style)
- def classified_xml(
- style_name: str,
- column_name: str,
- values: List[float],
- color_ramp: str = None,
- geom_type: str = "polygon",
- ):
- max_value = max(values)
- min_value = min(values)
- diff = max_value - min_value
- n = 5
- interval = diff / 5
- palette = sns.color_palette(color_ramp, int(n))
- palette_hex = [rgb2hex(i) for i in palette]
- # interval = N/4
- # color_values = [{value: color} for value, color in zip(values, palette_hex)]
- # print(color_values)
- rule = ""
- for i, color in enumerate(palette_hex):
- print(i)
- rule += """
- <se:Rule>
- <se:Name>{1}</se:Name>
- <se:Description>
- <se:Title>{4}</se:Title>
- </se:Description>
- <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
- <ogc:And>
- <ogc:PropertyIsGreaterThan>
- <ogc:PropertyName>{0}</ogc:PropertyName>
- <ogc:Literal>{5}</ogc:Literal>
- </ogc:PropertyIsGreaterThan>
- <ogc:PropertyIsLessThanOrEqualTo>
- <ogc:PropertyName>{0}</ogc:PropertyName>
- <ogc:Literal>{4}</ogc:Literal>
- </ogc:PropertyIsLessThanOrEqualTo>
- </ogc:And>
- </ogc:Filter>
- <se:PolygonSymbolizer>
- <se:Fill>
- <se:SvgParameter name="fill">{2}</se:SvgParameter>
- </se:Fill>
- <se:Stroke>
- <se:SvgParameter name="stroke">{3}</se:SvgParameter>
- <se:SvgParameter name="stroke-width">1</se:SvgParameter>
- <se:SvgParameter name="stroke-linejoin">bevel</se:SvgParameter>
- </se:Stroke>
- </se:PolygonSymbolizer>
- </se:Rule>
- """.format(
- column_name,
- style_name,
- color,
- "#000000",
- min_value + interval * i,
- min_value + interval * (i + 1),
- )
- style = """
- <StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc" version="1.1.0" xmlns:se="http://www.opengis.net/se" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
- <NamedLayer>
- <se:Name>{0}</se:Name>
- <UserStyle>
- <se:Name>{0}</se:Name>
- <se:FeatureTypeStyle>
- {1}
- </se:FeatureTypeStyle>
- </UserStyle>
- </NamedLayer>
- </StyledLayerDescriptor>
- """.format(
- style_name, rule
- )
- with open("style.sld", "w") as f:
- f.write(style)
|