def _read(self, stream: Stream, version): self.color = stream.read_object('color') number_layers = stream.read_int('layers') for i in range(number_layers): stream.consume_padding() layer = stream.read_object('symbol layer {}/{}'.format( i + 1, number_layers)) self.levels.extend([layer]) # the next section varies in size. To handle this we jump forward to a known anchor # point, and then move back by a known amount # burn up to the 02 stream.log('burning up to 02...') while not binascii.hexlify(stream.read(1)) == b'02': pass # jump back a known amount stream.rewind(8 * number_layers + 1) for l in self.levels: l.read_enabled(stream) for l in self.levels: l.read_locked(stream)
def read(self, stream: Stream, version): self.color = stream.read_object('color') self.unicode = stream.read_int('unicode') self.angle = stream.read_double('angle') self.size = stream.read_double('size') self.x_offset = stream.read_double('x offset') self.y_offset = stream.read_double('y offset') stream.read_double('unknown 1') stream.read_double('unknown 2') self.read_0d_terminator(stream) if binascii.hexlify(stream.read(2)) != b'ffff': raise UnreadableSymbolException('Expected ffff') self.font = stream.read_string('font name') # lot of unknown stuff stream.read_double('unknown 3') # or object? stream.read_double('unknown 4') # or object? if binascii.hexlify(stream.read(2)) != b'9001': raise UnreadableSymbolException('Expected 9001') stream.read(4) stream.read(6) # std OLE font .. maybe contains useful stuff like bold/etc, but these aren't exposed in ArcGIS anyway.. self.std_font = stream.read_object('font')
def read(self, stream: Stream, version): stream.read_int('unknown') stream.read_int('unknown 2') self.file = stream.read_embedded_file('image') self.color_foreground = stream.read_object('color 1') self.color_background = stream.read_object('color 2') self.color_transparent = stream.read_object('color 3') self.angle = stream.read_double('angle') self.size = stream.read_double('size') self.x_offset = stream.read_double('x offset') self.y_offset = stream.read_double('y offset') stream.read_double('unknown') stream.read_double('unknown') stream.read_0d_terminator() self.swap_fb_gb = bool(stream.read_uchar('swap fgbg')) check = binascii.hexlify(stream.read(2)) if check != b'ffff': raise UnreadableSymbolException( 'Expected ffff at {}, got {}'.format(check, hex(stream.tell() - 2))) # unknown stream.read(6)
def read(self, stream: Stream, version): if not stream.read_0d_terminator(): raise UnreadableSymbolException('Could not find 0d terminator at {}'.format(hex(stream.tell() - 8))) # consume unused properties - MultiLayerMarkerSymbol implements IMarkerSymbol # so that the size/offsets/angle are required properties. But they aren't used # or exposed anywhere for MultiLayerMarkerSymbol _ = stream.read_double('unused marker size') _ = stream.read_double('unused marker x/y/offset or angle') _ = stream.read_double('unused marker x/y/offset or angle') _ = stream.read_double('unused marker x/y/offset or angle') _ = stream.read_object('unused color') self.halo = stream.read_int() == 1 self.halo_size = stream.read_double('halo size') self.halo_symbol = stream.read_object('halo') # useful stuff number_layers = stream.read_int('layers') for i in range(number_layers): layer = stream.read_object('symbol layer {}/{}'.format(i + 1, number_layers)) self.levels.extend([layer]) for l in self.levels: l.read_enabled(stream) for l in self.levels: l.read_locked(stream) _ = stream.read_double('unknown size') _ = stream.read_double('unknown size') if version >= 3: for l in self.levels: l.read_tags(stream)
def read(self, stream: Stream, version): self.angle = stream.read_double('angle') self.cap = self.read_cap(stream) unknown = binascii.hexlify(stream.read(3)) if unknown != b'000000': raise UnreadableSymbolException( 'Differing unknown string {}'.format(unknown)) self.join = self.read_join(stream) unknown = binascii.hexlify(stream.read(3)) if unknown != b'000000': raise UnreadableSymbolException( 'Differing unknown string {}'.format(unknown)) self.width = stream.read_double('width') stream.read(1) self.offset = stream.read_double('offset') self.line = stream.read_object('line') self.color = stream.read_object('color') self.template = stream.read_object('template') self.decoration = stream.read_object('decoration') stream.read_0d_terminator() _ = stream.read_uchar('unknown char') _ = stream.read_double('unknown') _ = stream.read_double('unknown')
def read(self, stream: Stream, version): self.cap = self.read_cap(stream) stream.log('read cap of {}'.format(self.cap), 1) self.offset = stream.read_double('offset') self.pattern_marker = stream.read_object('pattern marker') self.template = stream.read_object('template') self.decoration = stream.read_object('decoration') self.read_0d_terminator(stream)
def read(self, stream: Stream, version): # first bit is either an entire LineSymbol or just a LineSymbolLayer outline = stream.read_object('outline') if outline is not None: if issubclass(outline.__class__, SymbolLayer): self.outline_layer = outline else: self.outline_symbol = outline self.color = stream.read_object('color') self.read_0d_terminator(stream)
def read(self, stream: Stream, version): self.color = stream.read_object('color') self.width = stream.read_double('width') self.line_type = self.read_line_type(stream) stream.log('read line type of {}'.format(self.line_type)) self.read_0d_terminator(stream)
def run_symbol_checks(self, path): """ Checks all bin symbols against expectations """ blobs = [] for fn in os.listdir(path): file = os.path.join(path, fn) if os.path.isfile(file): blobs.append(file) for file in blobs: print(file) group, symbol_name = os.path.split(file) path, group = os.path.split(group) with open(file, 'rb') as f: expected_symbol = expected[group][symbol_name] if 'skip' in expected_symbol: continue stream = Stream(f, debug=False) color = stream.read_object() self.assertEqual(color.to_dict(), expected_symbol['color']) self.assertEqual(color.model, expected_symbol['model'])
def read(self, stream: Stream, version): """ Reads the decoration information """ self.fixed_angle = not bool(stream.read_uchar()) stream.log('detected {}'.format( 'fixed angle' if self.fixed_angle else 'not fixed angle')) self.flip_first = bool(stream.read_uchar()) stream.log('detected {}'.format( 'flip first' if self.flip_first else 'no flip first')) self.flip_all = bool(stream.read_uchar()) stream.log('detected {}'.format( 'flip all' if self.flip_all else 'no flip all')) stream.read(2) # unknown -- maybe includes position as ratio? self.marker = stream.read_object('marker') # next bit is the number of doubles coming next marker_number_positions = stream.read_uint('marker positions') # next bit is the positions themselves -- maybe we can infer this from the number of positions # alone. E.g. 2 positions = 0, 1. 3 positions = 0, 0.5, 1 for _ in range(marker_number_positions): self.marker_positions.append(stream.read_double()) stream.log('marker positions are {}'.format(self.marker_positions))
def _read(self, stream: Stream, version): number_layers = stream.read_uint('layer count') for i in range(number_layers): layer = stream.read_object('symbol layer {}/{}'.format( i + 1, number_layers)) self.levels.extend([layer]) # the next section varies in size. To handle this we jump forward to a known anchor # point, and then move back by a known amount # burn up to the 02 stream.log('burning up to 02...') while not binascii.hexlify(stream.read(1)) == b'02': pass # jump back a known amount stream.rewind(8 * number_layers + 1) # TODO - replace the fragile bit above! # stream.read(1) # stream.read_double('unknown size') # stream.read_double('unknown size') for l in self.levels: l.read_enabled(stream) for l in self.levels: l.read_locked(stream)
def read(self, stream: Stream, version): self.ramp = stream.read_object('Color ramp') _ = stream.read_object('unused color') # either an entire LineSymbol or just a LineSymbolLayer outline = stream.read_object('outline') if outline is not None: if issubclass(outline.__class__, SymbolLayer): self.outline_layer = outline else: self.outline_symbol = outline self.percent = stream.read_double('percent') self.intervals = stream.read_uint('intervals') self.angle = stream.read_double('angle') self.type = stream.read_uint('Gradient type') stream.read_0d_terminator()
def processAlgorithm(self, parameters, context, feedback): # pylint: disable=missing-docstring,too-many-locals,too-many-statements input_file = self.parameterAsString(parameters, self.INPUT, context) output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context) mdbtools_folder = ProcessingConfig.getSetting('MDB_PATH') results = {} colors = [] _, file_name = os.path.split(input_file) file_name, _ = os.path.splitext(file_name) feedback.pushInfo('Importing colors from {}'.format(input_file)) raw_colors = Extractor.extract_styles(input_file, Extractor.COLORS, mdbtools_path=mdbtools_folder) feedback.pushInfo('Found {} colors'.format(len(raw_colors))) unreadable = 0 for index, raw_color in enumerate(raw_colors): feedback.setProgress(index / len(raw_colors) * 100) if feedback.isCanceled(): break name = raw_color[Extractor.NAME] feedback.pushInfo('{}/{}: {}'.format(index + 1, len(raw_colors), name)) handle = BytesIO(raw_color[Extractor.BLOB]) stream = Stream(handle) try: color = stream.read_object() except InvalidColorException: feedback.reportError('Error reading color {}'.format(name)) unreadable += 1 continue qcolor = symbol_color_to_qcolor(color) colors.append((name, qcolor)) results[self.COLOR_COUNT] = len(raw_colors) results[self.UNREADABLE_COLOR_COUNT] = unreadable with open(output_file, 'wt') as f: f.write('GIMP Palette\n') f.write('Name: {}\n'.format(file_name)) f.write('Columns: 4\n') f.write('#\n') for c in colors: f.write('{} {} {} {}\n'.format(c[1].red(), c[1].green(), c[1].blue(), c[0])) results[self.OUTPUT] = output_file return results
def read_symbol(_io_stream, debug=False): """ Reads a symbol from the specified file """ stream = Stream(_io_stream, debug) try: symbol_object = stream.read_object('symbol') except InvalidColorException: raise UnreadableSymbolException() return symbol_object
def read(self, stream: Stream, version): """ Reads the decoration information """ # next bit is probably number of decorations? count = stream.read_uint('count of decorations') for i in range(count): decoration = stream.read_object('decoration element {}/{}'.format( i, count)) self.decorations.append(decoration)
def read(self, stream: Stream, version): if version == 4: self.picture = stream.read_object('picture') elif version == 7: _ = stream.read_ushort('pic version?') _ = stream.read_uint('picture type?') self.picture = stream.read_object('picture') elif version == 8: self.picture = stream.read_picture('picture') self.color_background = stream.read_object('color bg') self.color_foreground = stream.read_object('color fg') self.color_transparent = stream.read_object('color trans') # either an entire LineSymbol or just a LineSymbolLayer outline = stream.read_object('outline') if outline is not None: if issubclass(outline.__class__, SymbolLayer): self.outline_layer = outline else: self.outline_symbol = outline self.angle = stream.read_double('angle') self.scale_x = stream.read_double('scale_x') self.scale_y = stream.read_double('scale_y') self.offset_x = stream.read_double('offset x') self.offset_y = stream.read_double('offset y') self.separation_x = stream.read_double('separation x') self.separation_y = stream.read_double('separation y') stream.read(16) stream.read_0d_terminator() self.swap_fb_gb = bool(stream.read_uchar('swap fgbg')) if version <= 4: return stream.read(6) if version < 8: stream.read(4)
def read(self, stream: Stream, version): _ = stream.read_double('unused double') _ = stream.read_double('unused double') self.line = stream.read_object('pattern line') # either an entire LineSymbol or just a LineSymbolLayer outline = stream.read_object('outline') if outline is not None: if issubclass(outline.__class__, SymbolLayer): self.outline_layer = outline else: self.outline_symbol = outline self.angle = stream.read_double('angle') self.offset = stream.read_double('offset') self.separation = stream.read_double('separation') stream.read_0d_terminator()
def _read(self, stream: Stream, version): # consume section of unknown purpose _ = stream.read_double('unknown size') unknown_object = stream.read_object('unknown') if unknown_object is not None: assert False, unknown_object _ = stream.read_double('unknown size') self.color = stream.read_object('color') self.halo = stream.read_int() == 1 self.halo_size = stream.read_double('halo size') self.halo_symbol = stream.read_object('halo') # not sure about this - there's an extra 02 here if a full fill symbol is used for the halo if False and isinstance(self.halo_symbol, Symbol): check = binascii.hexlify(stream.read(1)) if check != b'02': raise UnreadableSymbolException( 'Found unexpected value {} at {}, expected x02'.format( check, hex(stream.tell() - 1))) stream.read(1) if isinstance(self.halo_symbol, SymbolLayer): stream.read(4) # useful stuff number_layers = stream.read_int('layers') for i in range(number_layers): layer = stream.read_object('symbol layer {}/{}'.format( i + 1, number_layers)) self.levels.extend([layer]) for l in self.levels: l.read_enabled(stream) for l in self.levels: l.read_locked(stream) _ = stream.read_double('unknown size') _ = stream.read_double('unknown size')
def check_handle(self, file_handle): try: stream = Stream(file_handle) o = stream.read_object() if o is not None: return PersistentMatch(file_handle.tell() - 1, 1, o) else: return None except: # nopep8, pylint: disable=bare-except pass return None
def read(self, stream: Stream, version): if not stream.read_0d_terminator(): raise UnreadableSymbolException('Could not find 0d terminator at {}'.format(hex(stream.tell() - 8))) _ = stream.read_object('unused color') number_layers = stream.read_int('layers') for i in range(number_layers): layer = stream.read_object('symbol layer {}/{}'.format(i + 1, number_layers)) self.levels.extend([layer]) # stream.read(4) for l in self.levels: l.read_enabled(stream) for l in self.levels: l.read_locked(stream) if version >= 2: for l in self.levels: l.read_tags(stream)
def check_handle(self, file_handle): try: start = file_handle.tell() stream = Stream(file_handle) color = stream.read_object() if issubclass(color.__class__, Color): return ColorMatch(start, file_handle.tell() - start, color.color_model, color) else: return None except: # nopep8, pylint: disable=bare-except pass return None
def read(self, stream: Stream, version): self.color = stream.read_object('color') self.size = stream.read_double('size') type_code = stream.read_int() type_dict = { 0: 'circle', 1: 'square', 2: 'cross', 3: 'x', 4: 'diamond' } if type_code not in type_dict: raise UnreadableSymbolException( 'Unknown marker type at {}, got {}'.format( hex(stream.tell() - 4), type_code)) stream.log('found a {}'.format(type_dict[type_code]), 4) self.type = type_dict[type_code] # look for 0d terminator if not binascii.hexlify(stream.read(8)) == b'0d00000000000000': raise UnreadableSymbolException() stream.read_double('unknown') self.x_offset = stream.read_double('x offset') self.y_offset = stream.read_double('y offset') has_outline = stream.read_uchar() if has_outline == 1: self.outline_enabled = True self.outline_width = stream.read_double('outline width') self.outline_color = stream.read_object('outline color') check = binascii.hexlify(stream.read(2)) if check != b'ffff': raise UnreadableSymbolException( 'Expected ffff at {}, got {}'.format(check, hex(stream.tell() - 2)))
def read(self, stream: Stream, version): if version in (4, 5): self.picture = stream.read_object('picture') elif version == 8: _ = stream.read_ushort('pic version?') _ = stream.read_uint('picture type?') self.picture = stream.read_object('picture') elif version == 9: self.picture = stream.read_picture('picture') if version <= 8: _ = stream.read_object() self.color_foreground = stream.read_object('color 1') self.color_background = stream.read_object('color 2') if version >= 9: self.color_transparent = stream.read_object('color 3') self.angle = stream.read_double('angle') self.size = stream.read_double('size') self.x_offset = stream.read_double('x offset') self.y_offset = stream.read_double('y offset') stream.read_double('unknown') stream.read_double('unknown') stream.read_0d_terminator() self.swap_fb_gb = bool(stream.read_uchar('swap fgbg')) check = binascii.hexlify(stream.read(2)) if check != b'ffff': raise UnreadableSymbolException('Expected ffff at {}, got {}'.format(check, hex(stream.tell() - 2))) if version < 6: return stream.read(6) if version <= 8: stream.read(4)
def read(self, stream: Stream, version): self.random = bool(stream.read_int('random')) self.offset_x = stream.read_double('offset x') self.offset_y = stream.read_double('offset y') self.separation_x = stream.read_double('separation x') self.separation_y = stream.read_double('separation y') _ = stream.read_double('unused double') _ = stream.read_double('unused double') self.marker = stream.read_object('fill marker') # either an entire LineSymbol or just a LineSymbolLayer outline = stream.read_object('outline') if outline is not None: if issubclass(outline.__class__, SymbolLayer): self.outline_layer = outline else: self.outline_symbol = outline stream.read_0d_terminator() _ = stream.read_double('unused double')
def read(self, stream: Stream, version): self.cap = self.read_cap(stream) stream.log('read cap of {}'.format(self.cap), 1) self.offset = stream.read_double('offset') self.pattern_marker = stream.read_object('pattern marker') self.template = stream.read_object('template') self.decoration = stream.read_object('decoration') stream.read_0d_terminator() _ = stream.read_double('unknown double') _ = stream.read_int('unknown int') _ = stream.read_uchar('unknown char') self.join = self.read_join(stream) unknown = binascii.hexlify(stream.read(3)) if unknown != b'000000': raise UnreadableSymbolException( 'Differing unknown string {}'.format(unknown)) _ = stream.read_double('unknown double')
def read(self, stream: Stream, version): self.color = stream.read_object('color') self.size = stream.read_double('size') self.width = stream.read_double('width') self.angle = stream.read_double('angle') # 12 bytes unknown purpose stream.log('skipping 12 unknown bytes') _ = stream.read_uint('unknown') stream.read_0d_terminator() self.x_offset = stream.read_double('x offset') self.y_offset = stream.read_double('y offset') check = binascii.hexlify(stream.read(2)) if check != b'ffff': raise UnreadableSymbolException('Expected ffff at {}, got {}'.format(check, hex(stream.tell() - 2)))
def read(self, stream: Stream, version): self.color = stream.read_object('color') stream.read_0d_terminator()
def processAlgorithm(self, parameters, context, feedback): # pylint: disable=missing-docstring,too-many-locals,too-many-statements input_file = self.parameterAsString(parameters, self.INPUT, context) output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context) mdbtools_folder = ProcessingConfig.getSetting('MDB_PATH') style = QgsStyle() results = {} symbol_names = set() def make_name_unique(name): """ Ensures that the symbol name is unique (in a case insensitive way) """ counter = 0 candidate = name while candidate.lower() in symbol_names: # make name unique if counter == 0: candidate += '_1' else: candidate = candidate[:candidate.rfind('_') + 1] + str(counter) counter += 1 symbol_names.add(candidate.lower()) return candidate for type_index, symbol_type in enumerate( (Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS, Extractor.MARKER_SYMBOLS)): feedback.pushInfo('Importing {} from {}'.format( symbol_type, input_file)) raw_symbols = Extractor.extract_styles( input_file, symbol_type, mdbtools_path=mdbtools_folder) feedback.pushInfo('Found {} symbols of type "{}"\n\n'.format( len(raw_symbols), symbol_type)) if feedback.isCanceled(): break unreadable = 0 for index, raw_symbol in enumerate(raw_symbols): feedback.setProgress(index / len(raw_symbols) * 33.3 + 33.3 * type_index) if feedback.isCanceled(): break name = raw_symbol[Extractor.NAME] feedback.pushInfo('{}/{}: {}'.format(index + 1, len(raw_symbols), name)) unique_name = make_name_unique(name) if name != unique_name: feedback.pushInfo( 'Corrected to unique name of {}'.format(unique_name)) handle = BytesIO(raw_symbol[Extractor.BLOB]) stream = Stream(handle) try: symbol = stream.read_object() except UnreadableSymbolException as e: feedback.reportError('Error reading symbol {}: {}'.format( name, e)) unreadable += 1 continue except NotImplementedException as e: feedback.reportError( 'Parsing {} is not supported: {}'.format(name, e)) unreadable += 1 continue except UnsupportedVersionException as e: feedback.reportError('Cannot read {} version: {}'.format( name, e)) unreadable += 1 continue try: qgis_symbol = Symbol_to_QgsSymbol(symbol) except NotImplementedException as e: feedback.reportError(str(e)) unreadable += 1 continue style.addSymbol(unique_name, qgis_symbol) if symbol_type == Extractor.FILL_SYMBOLS: results[self.FILL_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_FILL_SYMBOLS] = unreadable elif symbol_type == Extractor.LINE_SYMBOLS: results[self.LINE_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_LINE_SYMBOLS] = unreadable elif symbol_type == Extractor.MARKER_SYMBOLS: results[self.MARKER_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_MARKER_SYMBOLS] = unreadable style.exportXml(output_file) results[self.OUTPUT] = output_file return results
def processAlgorithm(self, # pylint:disable=missing-docstring,too-many-locals,too-many-statements,too-many-branches parameters, context, feedback): input_file = self.parameterAsString(parameters, self.INPUT, context) output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context) embed_pictures = self.parameterAsBool(parameters, self.EMBED_PICTURES, context) convert_fonts = self.parameterAsBool(parameters, self.CONVERT_FONTS, context) parameterize = self.parameterAsBool(parameters, self.PARAMETERIZE, context) units = self.parameterAsEnum(parameters, self.UNITS, context) force_svg = self.parameterAsBool(parameters, self.FORCE_SVG, context) relative_paths = self.parameterAsBool(parameters, self.RELATIVE_PATHS, context) picture_folder = self.parameterAsString(parameters, self.PICTURE_FOLDER, context) if not picture_folder: picture_folder, _ = os.path.split(output_file) mdbtools_folder = ProcessingConfig.getSetting('MDB_PATH') fields = QgsFields() fields.append(QgsField('name', QVariant.String, '', 60)) fields.append(QgsField('warning', QVariant.String, '', 250)) sink, dest = self.parameterAsSink(parameters, self.REPORT, context, fields) style = QgsStyle() style.createMemoryDatabase() results = {} symbol_names = set() def make_name_unique(name): """ Ensures that the symbol name is unique (in a case insensitive way) """ counter = 0 candidate = name while candidate.lower() in symbol_names: # make name unique if counter == 0: candidate += '_1' else: candidate = candidate[:candidate.rfind('_') + 1] + str(counter) counter += 1 symbol_names.add(candidate.lower()) return candidate for type_index, symbol_type in enumerate( (Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS, Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS)): feedback.pushInfo('Importing {} from {}'.format(symbol_type, input_file)) raw_symbols = Extractor.extract_styles(input_file, symbol_type, mdbtools_path=mdbtools_folder) feedback.pushInfo('Found {} symbols of type "{}"\n\n'.format(len(raw_symbols), symbol_type)) if feedback.isCanceled(): break unreadable = 0 for index, raw_symbol in enumerate(raw_symbols): feedback.setProgress(index / len(raw_symbols) * 33.3 + 33.3 * type_index) if feedback.isCanceled(): break name = raw_symbol[Extractor.NAME] tags = raw_symbol[Extractor.TAGS].split(';') feedback.pushInfo('{}/{}: {}'.format(index + 1, len(raw_symbols), name)) unique_name = make_name_unique(name) if name != unique_name: feedback.pushInfo('Corrected to unique name of {}'.format(unique_name)) handle = BytesIO(raw_symbol[Extractor.BLOB]) stream = Stream(handle) f = QgsFeature() try: symbol = stream.read_object() except UnreadableSymbolException as e: feedback.reportError('Error reading symbol {}: {}'.format(name, e)) unreadable += 1 if sink: f.setAttributes([name, 'Error reading symbol: {}'.format(e)]) sink.addFeature(f) continue except NotImplementedException as e: feedback.reportError('Parsing {} is not supported: {}'.format(name, e)) unreadable += 1 if sink: f.setAttributes([name, 'Parsing not supported: {}'.format(e)]) sink.addFeature(f) continue except UnsupportedVersionException as e: feedback.reportError('Cannot read {} version: {}'.format(name, e)) unreadable += 1 if sink: f.setAttributes([name, 'Version not supported: {}'.format(e)]) sink.addFeature(f) continue except UnknownGuidException as e: feedback.reportError(str(e)) unreadable += 1 if sink: f.setAttributes([name, 'Unknown object: {}'.format(e)]) sink.addFeature(f) continue except UnreadablePictureException as e: feedback.reportError(str(e)) unreadable += 1 if sink: f.setAttributes([name, 'Unreadable picture: {}'.format(e)]) sink.addFeature(f) continue self.check_for_unsupported_property(name, symbol, feedback, sink) context = Context() context.symbol_name = unique_name context.picture_folder = picture_folder context.embed_pictures = embed_pictures context.convert_fonts = convert_fonts context.parameterise_svg = parameterize context.force_svg_instead_of_raster = force_svg context.relative_paths = relative_paths context.style_folder, _ = os.path.split(output_file) context.units = QgsUnitTypes.RenderPoints if units == 0 else QgsUnitTypes.RenderMillimeters try: qgis_symbol = Symbol_to_QgsSymbol(symbol, context) except NotImplementedException as e: feedback.reportError(str(e)) unreadable += 1 if sink: f.setAttributes([name, str(e)]) sink.addFeature(f) continue if isinstance(qgis_symbol, QgsSymbol): self.check_for_missing_fonts(qgis_symbol, feedback) style.addSymbol(unique_name, qgis_symbol, True) elif isinstance(qgis_symbol, QgsColorRamp): style.addColorRamp(unique_name, qgis_symbol, True) if tags: if isinstance(qgis_symbol, QgsSymbol): assert style.tagSymbol(QgsStyle.SymbolEntity, unique_name, tags) elif isinstance(qgis_symbol, QgsColorRamp): assert style.tagSymbol(QgsStyle.ColorrampEntity, unique_name, tags) if symbol_type == Extractor.FILL_SYMBOLS: results[self.FILL_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_FILL_SYMBOLS] = unreadable elif symbol_type == Extractor.LINE_SYMBOLS: results[self.LINE_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_LINE_SYMBOLS] = unreadable elif symbol_type == Extractor.MARKER_SYMBOLS: results[self.MARKER_SYMBOL_COUNT] = len(raw_symbols) results[self.UNREADABLE_MARKER_SYMBOLS] = unreadable elif symbol_type == Extractor.COLOR_RAMPS: results[self.COLOR_RAMP_COUNT] = len(raw_symbols) results[self.UNREADABLE_COLOR_RAMPS] = unreadable style.exportXml(output_file) results[self.OUTPUT] = output_file results[self.REPORT] = dest return results