def append_LineSymbolLayer(symbol, layer): """ Appends a LineSymbolLayer to a QgsSymbol """ if isinstance(layer, SimpleLineSymbolLayer): append_SimpleLineSymbolLayer(symbol, layer) elif isinstance(layer, CartographicLineSymbolLayer): append_CartographicLineSymbolLayer(symbol, layer) elif isinstance(layer, MarkerLineSymbolLayer): append_MarkerLineSymbolLayer(symbol, layer) elif isinstance(layer, HashLineSymbolLayer): raise NotImplementedException( 'QGIS does not have a hash line symbol type (considering sponsoring this feature!)') else: raise NotImplementedException('Converting {} not implemented yet'.format(layer.__class__.__name__))
def SimpleFillSymbolLayer_to_QgsSimpleFillSymbolLayer(layer): """ Converts a SimpleFillSymbolLayer to a QgsSimpleFillSymbolLayer """ fill_color = symbol_color_to_qcolor(layer.color) out = QgsSimpleFillSymbolLayer(fill_color) if layer.outline_layer: if isinstance(layer.outline_layer, (SimpleLineSymbolLayer, CartographicLineSymbolLayer)): out.setStrokeColor( symbol_color_to_qcolor(layer.outline_layer.color)) out.setStrokeWidth(points_to_mm(layer.outline_layer.width)) if isinstance(layer.outline_layer, SimpleLineSymbolLayer): out.setStrokeStyle( symbol_pen_to_qpenstyle(layer.outline_layer.line_type)) if isinstance(layer.outline_layer, CartographicLineSymbolLayer): out.setPenJoinStyle( symbol_pen_to_qpenjoinstyle(layer.outline_layer.join)) # better matching of null stroke color to QGIS symbology if out.strokeColor().alpha() == 0: out.setStrokeStyle(Qt.NoPen) # todo - change to new symbol layer if outline offset set else: # todo - outline symbol layer raise NotImplementedException('Outline symbol layer not implemented') return out
def append_CartographicLineSymbolLayer(symbol, layer): """ Appends a CartographicLineSymbolLayer to a symbol """ color = symbol_color_to_qcolor(layer.color) out = QgsSimpleLineSymbolLayer(color) out.setEnabled(layer.enabled) out.setLocked(layer.locked) out.setWidth(points_to_mm(layer.width)) out.setPenJoinStyle(symbol_pen_to_qpenjoinstyle(layer.join)) out.setPenCapStyle(symbol_pen_to_qpencapstyle(layer.cap)) if layer.pattern_parts: interval = layer.pattern_interval dash_vector = [] for part in layer.pattern_parts: dash_vector.append(points_to_mm(part[0] * interval)) dash_vector.append(points_to_mm(part[1] * interval)) out.setCustomDashVector(dash_vector) out.setUseCustomDashPattern(True) # better matching of null stroke color to QGIS symbology if out.color().alpha() == 0: out.setPenStyle(Qt.NoPen) if layer.marker_positions or layer.marker: raise NotImplementedException( 'Cartographic line start/end markers are not yet supported') # todo - change to new symbol layer if outline offset set symbol.appendSymbolLayer(out)
def FillSymbolLayer_to_QgsFillSymbolLayer(layer): """ Converts a FillSymbolLayer to a QgsFillSymbolLayer """ if isinstance(layer, SimpleFillSymbolLayer): return SimpleFillSymbolLayer_to_QgsSimpleFillSymbolLayer(layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def append_FillSymbolLayer(symbol, layer): """ Appends a FillSymbolLayer to a symbol """ if isinstance(layer, SimpleFillSymbolLayer): append_SimpleFillSymbolLayer(symbol, layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def convert_fill_symbol_layer(self, layer: FillSymbolLayer) -> dict: """ Converts a FillSymbolLayer """ if isinstance(layer, SimpleFillSymbolLayer): return self.convert_simple_fill_symbol_layer(layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def append_Decorations(symbol, decorations: LineDecoration): """ Appends decorations to the given symbol """ if len(decorations.decorations) > 1: raise NotImplementedException('Multiple line decorations are not yet supported') elif not decorations.decorations: return decoration = decorations.decorations[0] positions = decoration.marker_positions[:] marker = Symbol_to_QgsSymbol(decoration.marker) if decoration.flip_all: marker.setAngle(270) else: marker.setAngle(90) if 0 in positions: # start marker line = QgsMarkerLineSymbolLayer(not decoration.fixed_angle) start_marker = marker.clone() if decoration.flip_first: start_marker.setAngle(270) line.setSubSymbol(start_marker) # TODO - maybe need to offset this by marker width / 4? seems a better match to ESRI line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex) symbol.appendSymbolLayer(line) if 1 in positions: # end marker line = QgsMarkerLineSymbolLayer(not decoration.fixed_angle) line.setSubSymbol(marker.clone()) line.setPlacement(QgsMarkerLineSymbolLayer.LastVertex) # TODO - maybe need to offset this by marker width / 4? seems a better match to ESRI symbol.appendSymbolLayer(line) # TODO other positions other_positions = [p for p in positions if p not in (0, 1)] if other_positions: # Would need to use data defined marker placement distance, e.g. $length/3 # and offset first marker by $length/3 to avoid placing a marker at the start # of the line raise NotImplementedException('Non start/end decoration positions are not implemented')
def append_MarkerSymbolLayer(symbol, layer): """ Appends a MarkerSymbolLayer to a QgsSymbol """ if isinstance(layer, SimpleMarkerSymbolLayer): append_SimpleMarkerSymbolLayer(symbol, layer) elif isinstance(layer, CharacterMarkerSymbolLayer): append_CharacterMarkerSymbolLayer(symbol, layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def append_LineSymbolLayer(symbol, layer): """ Appends a LineSymbolLayer to a QgsSymbol """ if isinstance(layer, SimpleLineSymbolLayer): append_SimpleLineSymbolLayer(symbol, layer) elif isinstance(layer, CartographicLineSymbolLayer): append_CartographicLineSymbolLayer(symbol, layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def SymbolLayer_to_QgsSymbolLayer(layer): """ Converts a SymbolLayer to a QgsSymbolLayer """ if issubclass(layer.__class__, FillSymbolLayer): out = FillSymbolLayer_to_QgsFillSymbolLayer(layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__)) out.setEnabled(layer.enabled) out.setLocked(layer.locked) return out
def append_FillSymbolLayer(symbol, layer): """ Appends a FillSymbolLayer to a symbol """ if isinstance(layer, (SimpleFillSymbolLayer, ColorSymbol)): append_SimpleFillSymbolLayer(symbol, layer) elif isinstance(layer, LineFillSymbolLayer): append_LineFillSymbolLayer(symbol, layer) elif isinstance(layer, MarkerFillSymbolLayer): append_MarkerFillSymbolLayer(symbol, layer) else: raise NotImplementedException('Converting {} not implemented yet'.format(layer.__class__.__name__))
def ColorRamp_to_QgsColorRamp(ramp: ColorRamp): """ Converts a ColorRamp to a QgsColorRamp """ if isinstance(ramp, PresetColorRamp): return PresetColorRamp_to_QgsColorRamp(ramp) elif isinstance(ramp, RandomColorRamp): return RandomColorRamp_to_QgsColorRamp(ramp) elif isinstance(ramp, AlgorithmicColorRamp): return AlgorithmicColorRamp_to_QgsColorRamp(ramp) else: raise NotImplementedException('Converting {} not implemented yet'.format(ramp.__class__.__name__))
def convert_line_symbol_layer(layer: LineSymbolLayer) -> dict: """ Converts a LineSymbolLayer """ if isinstance(layer, SimpleLineSymbolLayer): return DictionaryConverter.convert_simple_line_symbol_layer(layer) if isinstance(layer, CartographicLineSymbolLayer): return DictionaryConverter.convert_cartographic_line_symbol_layer( layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def convert_marker_symbol_layer(layer: MarkerSymbolLayer) -> dict: """ Converts a MarkerSymbolLayer """ if isinstance(layer, SimpleMarkerSymbolLayer): return DictionaryConverter.convert_simple_marker_symbol_layer( layer) elif isinstance(layer, CharacterMarkerSymbolLayer): return DictionaryConverter.convert_character_marker_symbol_layer( layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def Symbol_to_QgsSymbol(symbol): """ Converts a raw Symbol to a QgsSymbol """ if issubclass(symbol.__class__, (FillSymbol, FillSymbolLayer)): out = QgsFillSymbol() elif issubclass(symbol.__class__, (LineSymbol, LineSymbolLayer)): out = QgsLineSymbol() elif issubclass(symbol.__class__, (MarkerSymbol, MarkerSymbolLayer)): out = QgsMarkerSymbol() try: if symbol.halo: raise NotImplementedException( 'Mark halos are not yet supported') except AttributeError: pass else: raise NotImplementedException() add_symbol_layers(out, symbol) return out
def convert_gradient_type(gradient_type: int) -> str: """ Converts a gradient type to string """ if gradient_type == GradientFillSymbolLayer.LINEAR: return 'linear' elif gradient_type == GradientFillSymbolLayer.CIRCULAR: return 'circular' elif gradient_type == GradientFillSymbolLayer.BUFFERED: return 'buffered' elif gradient_type == GradientFillSymbolLayer.RECTANGULAR: return 'rectangular' raise NotImplementedException( 'Gradient type {} not implemented yet'.format(gradient_type))
def append_PictureMarkerSymbolLayer(symbol, layer: PictureMarkerSymbolLayer, context: Context): """ Appends a PictureMarkerSymbolLayer to a symbol """ picture = layer.picture if issubclass(picture.__class__, StdPicture): picture = picture.picture if layer.swap_fb_gb: raise NotImplementedException('Swap FG/BG color not implemented') if issubclass(picture.__class__, EmfPicture): path = symbol_name_to_filename(context.symbol_name, context.picture_folder, 'emf') with open(path, 'wb') as f: f.write(picture.content) svg_path = symbol_name_to_filename(context.symbol_name, context.picture_folder, 'svg') emf_to_svg(path, svg_path) svg_path = context.convert_path(svg_path) else: svg = PictureUtils.to_embedded_svg( picture.content, symbol_color_to_qcolor(layer.color_foreground), symbol_color_to_qcolor(layer.color_background), symbol_color_to_qcolor(layer.color_transparent)) if context.embed_pictures: svg_base64 = base64.b64encode(svg.encode('UTF-8')).decode('UTF-8') svg_path = 'base64:{}'.format(svg_base64) else: svg_path = write_svg(svg, context.symbol_name, context.picture_folder) svg_path = context.convert_path(svg_path) out = QgsSvgMarkerSymbolLayer(svg_path, context.convert_size(layer.size), layer.angle) out.setSizeUnit(context.units) out.setEnabled(layer.enabled) out.setLocked(layer.locked) out.setOffset( adjust_offset_for_rotation( QPointF(context.convert_size(layer.x_offset), -context.convert_size(layer.y_offset)), layer.angle)) out.setOffsetUnit(context.units) symbol.appendSymbolLayer(out)
def marker_type_to_qgis_type(marker_type): """ Converts simple marker types to corresponding QGIS types """ if marker_type == 'circle': return QgsSimpleMarkerSymbolLayerBase.Circle elif marker_type == 'square': return QgsSimpleMarkerSymbolLayerBase.Square elif marker_type == 'cross': return QgsSimpleMarkerSymbolLayerBase.Cross elif marker_type == 'x': return QgsSimpleMarkerSymbolLayerBase.Cross2 elif marker_type == 'diamond': return QgsSimpleMarkerSymbolLayerBase.Diamond else: raise NotImplementedException('Marker type {} not implemented'.format(marker_type))
def Symbol_to_QgsSymbol(symbol): """ Converts a raw Symbol to a QgsSymbol """ if issubclass(symbol.__class__, (FillSymbol, FillSymbolLayer)): out = QgsFillSymbol() elif issubclass(symbol.__class__, (LineSymbol, LineSymbolLayer)): out = QgsLineSymbol() elif issubclass(symbol.__class__, (MarkerSymbol, MarkerSymbolLayer)): out = QgsMarkerSymbol() else: raise NotImplementedException() add_symbol_layers(out, symbol) return out
def append_MarkerSymbolLayer(symbol, layer, context: Context): """ Appends a MarkerSymbolLayer to a QgsSymbol """ if isinstance(layer, SimpleMarkerSymbolLayer): append_SimpleMarkerSymbolLayer(symbol, layer, context) elif isinstance(layer, ArrowMarkerSymbolLayer): append_ArrowMarkerSymbolLayer(symbol, layer, context) elif isinstance(layer, CharacterMarkerSymbolLayer): append_CharacterMarkerSymbolLayer(symbol, layer, context) elif isinstance(layer, PictureMarkerSymbolLayer): append_PictureMarkerSymbolLayer(symbol, layer, context) else: raise NotImplementedException( 'Converting {} not implemented yet'.format( layer.__class__.__name__))
def append_SymbolLayer_to_QgsSymbolLayer(symbol, layer): """ Appends a SymbolLayer to a QgsSymbolLayer """ if issubclass(layer.__class__, SymbolLayer): if issubclass(layer.__class__, FillSymbolLayer): append_FillSymbolLayer(symbol, layer) elif issubclass(layer.__class__, LineSymbolLayer): append_LineSymbolLayer(symbol, layer) elif issubclass(layer.__class__, MarkerSymbolLayer): append_MarkerSymbolLayer(symbol, layer) else: raise NotImplementedException('Converting {} not implemented yet'.format(layer.__class__.__name__)) else: for l in layer.levels: append_SymbolLayer_to_QgsSymbolLayer(symbol, l)
def convert_fill_symbol_layer(self, layer: FillSymbolLayer) -> dict: """ Converts a FillSymbolLayer """ if isinstance(layer, SimpleFillSymbolLayer): return self.convert_simple_fill_symbol_layer(layer) elif isinstance(layer, ColorSymbol): return self.convert_color_symbol(layer) elif isinstance(layer, GradientFillSymbolLayer): return self.convert_gradient_fill_symbol_layer(layer) elif isinstance(layer, LineFillSymbolLayer): return self.convert_line_fill_symbol_layer(layer) elif isinstance(layer, MarkerFillSymbolLayer): return self.convert_marker_fill_symbol_layer(layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__))
def convert_symbol_layer(self, layer: SymbolLayer) -> dict: """ Converts a SymbolLayer """ if issubclass(layer.__class__, FillSymbolLayer): out = self.convert_fill_symbol_layer(layer) elif issubclass(layer.__class__, LineSymbolLayer): out = DictionaryConverter.convert_line_symbol_layer(layer) elif issubclass(layer.__class__, MarkerSymbolLayer): out = DictionaryConverter.convert_marker_symbol_layer(layer) else: raise NotImplementedException('{} not implemented yet'.format( layer.__class__)) out['type'] = type(layer).__name__ out['enabled'] = layer.enabled out['locked'] = layer.locked return out
def convert_picture(picture: Picture) -> Optional[dict]: """ Converts a picture """ if picture is None: return None if issubclass(picture.__class__, StdPicture): picture = picture.picture out = { 'type': picture.__class__.__name__, } if issubclass(picture.__class__, BmpPicture): out['content'] = PictureUtils.to_base64_png(picture.content) elif issubclass(picture.__class__, EmfPicture): out['content'] = PictureUtils.to_base64(picture.content) else: raise NotImplementedException( '{} picture conversion not implemented'.format( picture.__class__.__name__)) return out
def append_PictureFillSymbolLayer(symbol, layer: PictureFillSymbolLayer, context: Context): """ Appends a PictureFillSymbolLayer to a symbol """ picture = layer.picture if issubclass(picture.__class__, StdPicture): picture = picture.picture if layer.swap_fb_gb: raise NotImplementedException('Swap FG/BG color not implemented') if issubclass(picture.__class__, EmfPicture) or context.force_svg_instead_of_raster: if issubclass(picture.__class__, EmfPicture): path = symbol_name_to_filename(context.symbol_name, context.picture_folder, 'emf') with open(path, 'wb') as f: f.write(picture.content) svg_path = symbol_name_to_filename(context.symbol_name, context.picture_folder, 'svg') emf_to_svg(path, svg_path) svg_path = context.convert_path(svg_path) else: svg = PictureUtils.to_embedded_svg( picture.content, symbol_color_to_qcolor(layer.color_foreground), symbol_color_to_qcolor(layer.color_background), symbol_color_to_qcolor(layer.color_transparent)) if context.embed_pictures: svg_base64 = base64.b64encode( svg.encode('UTF-8')).decode('UTF-8') svg_path = 'base64:{}'.format(svg_base64) else: svg_path = write_svg(svg, context.symbol_name, context.picture_folder) svg_path = context.convert_path(svg_path) width_in_pixels = layer.scale_x * PictureUtils.width_pixels( picture.content) width_in_in_points = width_in_pixels / 96 * 72 out = QgsSVGFillSymbolLayer(svg_path, context.convert_size(width_in_in_points), convert_angle(layer.angle)) out.setPatternWidthUnit(context.units) else: # use raster fill image_path = write_picture(picture, context.symbol_name, context.picture_folder, layer.color_foreground, layer.color_background, layer.color_transparent) out = QgsRasterFillSymbolLayer(image_path) # convert to points, so that print layouts work nicely. It's a better match for Arc anyway width_in_pixels = layer.scale_x * PictureUtils.width_pixels( picture.content) width_in_in_points = width_in_pixels / 96 * 72 out.setWidth(context.convert_size(width_in_in_points)) out.setWidthUnit(context.units) out.setAngle(convert_angle(layer.angle)) symbol.appendSymbolLayer(out) if layer.outline_layer: append_SymbolLayer_to_QgsSymbolLayer(symbol, layer.outline_layer, context) elif layer.outline_symbol: # get all layers from outline append_SymbolLayer_to_QgsSymbolLayer(symbol, layer.outline_symbol, context)
def append_SimpleFillSymbolLayer( symbol, # pylint: disable=too-many-branches layer: SimpleFillSymbolLayer, context: Context): """ Appends a SimpleFillSymbolLayer to a symbol """ fill_color = symbol_color_to_qcolor(layer.color) out = QgsSimpleFillSymbolLayer(fill_color) out.setEnabled(layer.enabled) out.setLocked(layer.locked) if isinstance(layer, SimpleFillSymbolLayer): if layer.outline_layer: if isinstance( layer.outline_layer, (SimpleLineSymbolLayer, CartographicLineSymbolLayer)): out.setStrokeColor( symbol_color_to_qcolor(layer.outline_layer.color)) out.setStrokeWidth( context.convert_size(layer.outline_layer.width)) out.setStrokeWidthUnit(context.units) if isinstance(layer.outline_layer, SimpleLineSymbolLayer): out.setStrokeStyle( symbol_pen_to_qpenstyle(layer.outline_layer.line_type)) if isinstance(layer.outline_layer, CartographicLineSymbolLayer): out.setPenJoinStyle( symbol_pen_to_qpenjoinstyle(layer.outline_layer.join)) # better matching of null stroke color to QGIS symbology if out.strokeColor().alpha() == 0: out.setStrokeStyle(Qt.NoPen) # TODO try: if layer.outline_layer.offset: raise NotImplementedException( 'Fill outline offset not supported') except AttributeError: pass try: if layer.outline_layer.template: raise NotImplementedException( 'Fill outline template not supported') except AttributeError: pass try: if layer.outline_layer.decoration: raise NotImplementedException( 'Fill outline decoration not supported') except AttributeError: pass symbol.appendSymbolLayer(out) elif layer.outline_symbol: # outline is a symbol itself out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out) # get all layers from outline append_SymbolLayer_to_QgsSymbolLayer(symbol, layer.outline_symbol, context) else: out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out) elif isinstance(layer, ColorSymbol): out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out)