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.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.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,too-many-branches input_file = self.parameterAsString(parameters, self.INPUT, context) output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context) mdbtools_folder = ProcessingConfig.getSetting('MDB_PATH') 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) 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 except UnknownGuidException as e: feedback.reportError(str(e)) unreadable += 1 continue self.check_for_unsupported_property(symbol, feedback) try: qgis_symbol = Symbol_to_QgsSymbol(symbol) except NotImplementedException as e: feedback.reportError(str(e)) unreadable += 1 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 return results
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): 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.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] if not stream.read_0d_terminator(): raise UnreadableSymbolException('Could not find 0d terminator at {}'.format(hex(stream.tell() - 8))) 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.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') if version == 2: self.std_font = stream.read_object('font') self.font = self.std_font.font_name stream.read_0d_terminator() if binascii.hexlify(stream.read(2)) != b'ffff': raise UnreadableSymbolException('Expected ffff') if version >= 3: 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? stream.read_uchar('unknown') stream.read_uchar('unknown') stream.read(4) stream.read(6) if version >= 4: # 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')