Beispiel #1
0
    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')
Beispiel #2
0
    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')
Beispiel #3
0
 def read(self, stream: Stream, version):
     self.color = stream.read_object('color')
     stream.read_0d_terminator()
Beispiel #4
0
    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
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
    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)))
Beispiel #8
0
    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)
Beispiel #9
0
    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')