class Label(Symbolizer): """ Symbolizer for labelling a geometry. The ``property`` argument specifies the field or attribute with which to generate labels from. The ``font`` and ``color`` arguments specify the label font and color respectively. >>> Label('foo') Label(property=foo) """ def __init__(self, property, font=None, color=None, priority=None, options=None): Symbolizer.__init__(self) self.property = Property(property) self.color = Color(color) if color else None self.priority = Property(priority) if priority else None self.options = options if options else {} self._font = Font(font) if font else None self._halo = None self._icon = None self._placement = None def font(self, font): """ Sets the font for this label. The ``font`` argument is a string describing the font attributes. See :class:`Font <geoscript.style.font.Font>` for supported syntax. >>> label = Label('foo').font('italic bold 12px "Times New Roman"') """ self._font = Font(font) return self def halo(self, fill=None, radius=None): """ Generates a halo for this label. The ``fill`` and ``radius`` arguments specify the :class:`Fill` and radius to use for the halo. >>> from geoscript.style import Fill >>> label = Label('foo').halo(Fill('#ffffff'), 2) """ self._halo = Halo(fill, radius) return self def point(self, anchor=(0.5,0.5), displace=(0,0), rotate=0): """ Sets the label placement relative to a point. The ``anchor`` argument is a tuple that specifies how the label should be anchored along an xy axis relative to the geometry being labeled. Allowable values range from (0,0) to (1,1) ordered from the bottom left corner to the top right corner of the label. The ``displacement`` argument is a tuple that specifies how the label should be displaced along an xy axis. The ``rotate`` argument specifies in degrees the angle at which to rotate the label. >>> label = Label('foo').point((0.5,0), (0,5)) """ self._placement = self._pointPlacement(anchor, displace, rotate) return self def icon(self, url, format=None, size=None): """ Composes this label as an :class:`Icon <geoscript.style.icon.Icon>`. The ``url`` argument is the url/file containing the image. The ``format`` argument is the format or mime type of the image. """ self._icon = Icon(url, format, size) return self @deprecated def linear(self, offset=0, gap=None, igap=None, align=False, follow=False, group=False, displace=None, repeat=None): """Use :func:`geoscript.style.Label.line`""" return self.line(offset, gap, igap, align, follow, group, displace, repeat) def line(self, offset=0, gap=None, igap=None, align=False, follow=False, group=False, displace=None, repeat=None): """ Sets the label placement relative to a line. The ``offset`` argument specifies the perpindicular distance from the line at which to position the label. The ``align`` argument specifies whether to align the label along the line. The ``follow`` argument specifies whether to curve the label in order to force it to follow the line. >>> label = Label('foo').linear(align=True, follow=True) """ f = self.factory lp = f.createLinePlacement(Expression(offset).expr) lp.setAligned(align) #lp.setRepeated(repeat) if gap: lp.setGap(Expression(gap).expr) if igap: lp.setInitialGap(Expression(igap).expr) self._placement = lp self.options['followLine'] = follow self.options['group'] = group if displace: self.options['maxDisplacement'] = displace if repeat: self.options['repeat'] = repeat return self def polygon(self, anchor=(0.5,0.5), displace=(0,0), rotate=0, wrap=None): self._placement = self._pointPlacement(anchor, displace, rotate) if wrap: self.options['autoWrap'] = wrap return self def _pointPlacement(self, anchor, displace, rotate): f = self.factory ap = f.createAnchorPoint( Expression(anchor[0]).expr,Expression(anchor[1]).expr) dp = f.createDisplacement( Expression(displace[0]).expr, Expression(displace[1]).expr) return f.createPointPlacement(ap, dp, Expression(rotate).expr) def _prepare(self, rule): syms = util.symbolizers(rule, TextSymbolizer) for sym in syms: self._apply(sym) def _apply(self, sym): Symbolizer._apply(self, sym) sym.setLabel(self.property.expr) if self._font: self._font._apply(sym) if self._halo: self._halo._apply(sym) if self._icon: self._icon._apply(sym) if self.color: sym.setFill(Fill(self.color)._fill()) if self.priority: sym.setPriority(self.priority.expr) if self._placement: sym.setLabelPlacement(self._placement) else: sym.setLabelPlacement(None) def __repr__(self): return self._repr('property')
class Fill(Symbolizer): """ Symbolizer for area / polygonal geometries that fill consists of a ``color`` and ``opacity``. >>> Fill('#ff0000', 0.5) Fill(color=(255,0,0),opacity=0.5) The ``color`` argument may also be specified as either a well known name or as an rgb tuple. >>> fill = Fill('red') >>> fill = Fill((255,0,0)) """ def __init__(self, color=None, opacity=1.0): Symbolizer.__init__(self) self.color = Color(color) if color else None self.opacity = Expression(opacity) self._icon = None self._hatch = None def icon(self, url, format): """ Composes this fill as an :class:`Icon <geoscript.style.icon.Icon>`. The ``url`` argument is the url/file containing the image. The ``format`` argument is the format or mime type of the image. >>> fill = Fill().icon('work/colorblocks.png', 'image/png') """ self._icon = Icon(url, format) return self def hatch(self, name, stroke=None, size=None): """ Composes this fill with a hatch pattern. The ``name`` argument is the well known name of the hatch pattern. See :class:`Hatch <geoscript.style.hatch.Hatch>` for the list of supported names. The ``stroke`` and ``size`` argument specify the :class:`Stroke` and size to use for the hatch pattern respectively. >>> fill = Fill().hatch('slash') """ self._hatch = Hatch(name, stroke, size) return self def interpolate(self, fill, n=10): return [Fill(col) for col in self.color.interpolate(fill.color, n)] def _prepare(self, rule): syms = util.symbolizers(rule, PolygonSymbolizer) for sym in syms: self._apply(sym) def _apply(self, sym): Symbolizer._apply(self, sym) sym.setFill(self._fill()) if self._icon: self._icon._apply(sym) def _fill(self): f = self.factory fill = f.createFill() if self.color: fill.setColor(self.color.expr) if self._hatch: fill.setGraphicFill(self._hatch._hatch()) fill.setOpacity(self.opacity.expr) return fill def __repr__(self): return self._repr('color', 'opacity')
class Stroke(Symbolizer): """ Symbolizer for linear geometries that consists of a ``color`` and a ``width``. >>> Stroke('#00ff00', 4) Stroke(color=(0,255,0),width=4) The ``color`` argument may also be specified as a well known name or as an rgb tuple. >>> stroke = Stroke('green', 4) >>> stroke = Stroke((0,255,0), 4) The ``dash`` argument specifies a dashed stroke pattern as a list of values. Oddly positioned elements specify the length in pixels of the dash. Evenly positioned elements specify the spaces. >>> stroke = Stroke('green', 4, [2,1,3,2]) The ``dash`` argument may also be specified as a tuple in which the first element is specifies the dash pattern described above, and the second element is an offset into the array which specifies where to begin the pattern from. >>> stroke = Stroke('green', 4, ([2,1,3,2], 2)) The ``cap`` argument specifies how lines should be capped. Supported values include "butt", "round", and "square". The ``join``argument specifies how two lines should be joined. Supported values include "miter", "round", and "bevel". The ``opacity`` argument is a float between 0 and 1 specifying the opaqueness of the stroke. """ def __init__(self, color='#000000', width=1, dash=None, cap=None, join=None, opacity=1.0): Symbolizer.__init__(self) self.color = Color(color) self.width = Expression(width) self.opacity = Expression(opacity) self.dash = dash self.cap = Expression(cap) if cap else None self.join = Expression(join) if join else None self._hatch = None self._icon = None def hatch(self, name, stroke=None, size=None): """ Composes the stroke with a hatched pattern. The ``name`` argument is the well known name of the hatch pattern. See :class:`Hatch <geoscript.style.hatch.Hatch>` for the list of supported names. The ``stroke`` and ``size`` argument specify the :class:`Stroke <geoscript.style.stroke.Stroke>` and size to use for the hatch pattern respectively. >>> stroke = Stroke().hatch('vertline') """ self._hatch = Hatch(name, stroke, size) return self def icon(self, url, format=None, size=None): """ Composes this stroke as an :class:`Icon <geoscript.style.icon.Icon>`. The ``url`` argument is the url/file containing the image. The ``format`` argument is the format or mime type of the image. """ self._icon = Icon(url, format, size) return self def interpolate(self, stroke, n=10): colors = self.color.interpolate(stroke.color, n) w1 = self.width.literal() w2 = stroke.width.literal() if w1 != None and w2 != None: widths = interpolate(w1, w2, n, 'linear') else: widths = [self.width] * n return map(lambda x: Stroke(x[0], x[1]), zip(colors, widths)) def _prepare(self, rule): sym = self.factory.createLineSymbolizer() self._apply(sym) rule.addSymbolizer(sym) def _apply(self, sym): Symbolizer._apply(self, sym) sym.setStroke(self._stroke()) if self._icon: self._icon._apply(sym) def _stroke(self): f = self.factory stroke = f.createStroke(self.color.expr, self.width.expr, self.opacity.expr) #stroke = f.createStroke(f.filter.literal(util.color(self.color)), # f.filter.literal(self.width)) if self.dash: if isinstance(self.dash, tuple): stroke.setDashArray(self.dash[0]) stroke.setDashOffset(f.filter.literal(self.dash[1])) else: stroke.setDashArray(self.dash) if self.cap: #stroke.setLineCap(f.filter.literal(self.cap)) stroke.setLineCap(self.cap.expr) if self.join: stroke.setLineJoin(self.join.expr) #stroke.setLineJoin(f.filter.literal(self.join)) if self._hatch: stroke.setGraphicStroke(self._hatch._hatch()) return stroke def __repr__(self): return self._repr('color', 'width')
class Label(Symbolizer): """ Symbolizer for labelling a geometry. The ``property`` argument specifies the field or attribute with which to generate labels from. The ``font`` and ``color`` arguments specify the label font and color respectively. >>> Label('foo') Label(property=foo) """ def __init__(self, property, font=None, color=None, priority=None, options=None): Symbolizer.__init__(self) self.property = Property(property) self.color = Color(color) if color else None self.priority = Property(priority) if priority else None self.options = options if options else {} self._font = Font(font) if font else None self._halo = None self._icon = None self._placement = None def font(self, font): """ Sets the font for this label. The ``font`` argument is a string describing the font attributes. See :class:`Font <geoscript.style.font.Font>` for supported syntax. >>> label = Label('foo').font('italic bold 12px "Times New Roman"') """ self._font = Font(font) return self def halo(self, fill=None, radius=None): """ Generates a halo for this label. The ``fill`` and ``radius`` arguments specify the :class:`Fill` and radius to use for the halo. >>> from geoscript.style import Fill >>> label = Label('foo').halo(Fill('#ffffff'), 2) """ self._halo = Halo(fill, radius) return self def point(self, anchor=(0.5, 0.5), displace=(0, 0), rotate=0): """ Sets the label placement relative to a point. The ``anchor`` argument is a tuple that specifies how the label should be anchored along an xy axis relative to the geometry being labeled. Allowable values range from (0,0) to (1,1) ordered from the bottom left corner to the top right corner of the label. The ``displacement`` argument is a tuple that specifies how the label should be displaced along an xy axis. The ``rotate`` argument specifies in degrees the angle at which to rotate the label. >>> label = Label('foo').point((0.5,0), (0,5)) """ self._placement = self._pointPlacement(anchor, displace, rotate) return self def icon(self, url, format=None, size=None): """ Composes this label as an :class:`Icon <geoscript.style.icon.Icon>`. The ``url`` argument is the url/file containing the image. The ``format`` argument is the format or mime type of the image. """ self._icon = Icon(url, format, size) return self @deprecated def linear(self, offset=0, gap=None, igap=None, align=False, follow=False, group=False, displace=None, repeat=None): """Use :func:`geoscript.style.Label.line`""" return self.line(offset, gap, igap, align, follow, group, displace, repeat) def line(self, offset=0, gap=None, igap=None, align=False, follow=False, group=False, displace=None, repeat=None): """ Sets the label placement relative to a line. The ``offset`` argument specifies the perpindicular distance from the line at which to position the label. The ``align`` argument specifies whether to align the label along the line. The ``follow`` argument specifies whether to curve the label in order to force it to follow the line. >>> label = Label('foo').linear(align=True, follow=True) """ f = self.factory lp = f.createLinePlacement(Expression(offset).expr) lp.setAligned(align) #lp.setRepeated(repeat) if gap: lp.setGap(Expression(gap).expr) if igap: lp.setInitialGap(Expression(igap).expr) self._placement = lp self.options['followLine'] = follow self.options['group'] = group if displace: self.options['maxDisplacement'] = displace if repeat: self.options['repeat'] = repeat return self def polygon(self, anchor=(0.5, 0.5), displace=(0, 0), rotate=0, wrap=None): self._placement = self._pointPlacement(anchor, displace, rotate) if wrap: self.options['autoWrap'] = wrap return self def _pointPlacement(self, anchor, displace, rotate): f = self.factory ap = f.createAnchorPoint( Expression(anchor[0]).expr, Expression(anchor[1]).expr) dp = f.createDisplacement( Expression(displace[0]).expr, Expression(displace[1]).expr) return f.createPointPlacement(ap, dp, Expression(rotate).expr) def _prepare(self, rule): syms = util.symbolizers(rule, TextSymbolizer) for sym in syms: self._apply(sym) def _apply(self, sym): Symbolizer._apply(self, sym) sym.setLabel(self.property.expr) if self._font: self._font._apply(sym) if self._halo: self._halo._apply(sym) if self._icon: self._icon._apply(sym) if self.color: sym.setFill(Fill(self.color)._fill()) if self.priority: sym.setPriority(self.priority.expr) if self._placement: sym.setLabelPlacement(self._placement) else: sym.setLabelPlacement(None) def __repr__(self): return self._repr('property')
class Fill(Symbolizer): """ Symbolizer for area / polygonal geometries that fill consists of a ``color`` and ``opacity``. >>> Fill('#ff0000', 0.5) Fill(color=(255,0,0),opacity=0.5) The ``color`` argument may also be specified as either a well known name or as an rgb tuple. >>> fill = Fill('red') >>> fill = Fill((255,0,0)) """ def __init__(self, color=None, opacity=1.0): Symbolizer.__init__(self) self.color = Color(color) if color else None self.opacity = Expression(opacity) self._icon = None self._hatch = None def icon(self, url, format=None, size=None): """ Composes this fill as an :class:`Icon <geoscript.style.icon.Icon>`. The ``url`` argument is the url/file containing the image. The ``format`` argument is the format or mime type of the image. >>> fill = Fill().icon('work/colorblocks.png', 'image/png') """ self._icon = Icon(url, format, size) return self def hatch(self, name, stroke=None, size=None): """ Composes this fill with a hatch pattern. The ``name`` argument is the well known name of the hatch pattern. See :class:`Hatch <geoscript.style.hatch.Hatch>` for the list of supported names. The ``stroke`` and ``size`` argument specify the :class:`Stroke` and size to use for the hatch pattern respectively. >>> fill = Fill().hatch('slash') """ self._hatch = Hatch(name, stroke, size) return self def interpolate(self, fill, n=10, method='linear'): return [ Fill(col) for col in self.color.interpolate(fill.color, n, method) ] def _prepare(self, rule): syms = util.symbolizers(rule, PolygonSymbolizer) for sym in syms: self._apply(sym) def _apply(self, sym): Symbolizer._apply(self, sym) sym.setFill(self._fill()) if self._icon: self._icon._apply(sym) def _fill(self): f = self.factory fill = f.createFill() if self.color: fill.setColor(self.color.expr) if self._hatch: fill.setGraphicFill(self._hatch._hatch()) fill.setOpacity(self.opacity.expr) return fill def __repr__(self): return self._repr('color', 'opacity')
class Stroke(Symbolizer): """ Symbolizer for linear geometries that consists of a ``color`` and a ``width``. >>> Stroke('#00ff00', 4) Stroke(color=(0,255,0),width=4) The ``color`` argument may also be specified as a well known name or as an rgb tuple. >>> stroke = Stroke('green', 4) >>> stroke = Stroke((0,255,0), 4) The ``dash`` argument specifies a dashed stroke pattern as a list of values. Oddly positioned elements specify the length in pixels of the dash. Evenly positioned elements specify the spaces. >>> stroke = Stroke('green', 4, [2,1,3,2]) The ``dash`` argument may also be specified as a tuple in which the first element is specifies the dash pattern described above, and the second element is an offset into the array which specifies where to begin the pattern from. >>> stroke = Stroke('green', 4, ([2,1,3,2], 2)) The ``cap`` argument specifies how lines should be capped. Supported values include "butt", "round", and "square". The ``join``argument specifies how two lines should be joined. Supported values include "miter", "round", and "bevel". The ``opacity`` argument is a float between 0 and 1 specifying the opaqueness of the stroke. """ def __init__(self, color='#000000', width=1, dash=None, cap=None, join=None, opacity=1.0): Symbolizer.__init__(self) self.color = Color(color) self.width = Expression(width) self.opacity = Expression(opacity) self.dash = dash self.cap = Expression(cap) if cap else None self.join = Expression(join) if join else None self._hatch = None self._icon = None def hatch(self, name, stroke=None, size=None): """ Composes the stroke with a hatched pattern. The ``name`` argument is the well known name of the hatch pattern. See :class:`Hatch <geoscript.style.hatch.Hatch>` for the list of supported names. The ``stroke`` and ``size`` argument specify the :class:`Stroke <geoscript.style.stroke.Stroke>` and size to use for the hatch pattern respectively. >>> stroke = Stroke().hatch('vertline') """ self._hatch = Hatch(name, stroke, size) return self def icon(self, url, format=None, size=None): """ Composes this stroke as an :class:`Icon <geoscript.style.icon.Icon>`. The ``url`` argument is the url/file containing the image. The ``format`` argument is the format or mime type of the image. """ self._icon = Icon(url, format, size) return self def interpolate(self, stroke, n=10, method='linear'): colors = self.color.interpolate(stroke.color, n, method) w1 = self.width.literal() w2 = stroke.width.literal() if w1 != None and w2 != None: widths = interpolate(w1, w2, n, method) else: widths = [self.width] * n return map(lambda x: Stroke(x[0], x[1]), zip(colors, widths)) def _prepare(self, rule): sym = self.factory.createLineSymbolizer() self._apply(sym) rule.addSymbolizer(sym) def _apply(self, sym): Symbolizer._apply(self, sym) sym.setStroke(self._stroke()) if self._icon: self._icon._apply(sym) def _stroke(self): f = self.factory stroke = f.createStroke(self.color.expr, self.width.expr, self.opacity.expr) #stroke = f.createStroke(f.filter.literal(util.color(self.color)), # f.filter.literal(self.width)) if self.dash: if isinstance(self.dash, tuple): stroke.setDashArray(self.dash[0]) stroke.setDashOffset(f.filter.literal(self.dash[1])) else: stroke.setDashArray(self.dash) if self.cap: #stroke.setLineCap(f.filter.literal(self.cap)) stroke.setLineCap(self.cap.expr) if self.join: stroke.setLineJoin(self.join.expr) #stroke.setLineJoin(f.filter.literal(self.join)) if self._hatch: stroke.setGraphicStroke(self._hatch._hatch()) return stroke def __repr__(self): return self._repr('color', 'width')