def test_allow_to_edit(self, server_iface, DBSession,
                           test_data2):  # noqa: ignore=N803
        session = DBSession()
        ogcserver_accesscontrol = OGCServerAccessControl(
            server_iface, "qgisserver", "no_project", 21781, lambda: session)
        ogcserver_accesscontrol.project = test_data2["project"]

        for user_name, expected, geometry in [
            ["user_no_access", False, geom_in],
            ["user_full_access", True, geom_in],
            ["user_area_access", True, geom_in],
            ["user_no_access", False, geom_intersects],
            ["user_full_access", True, geom_intersects],
            ["user_area_access", True, geom_intersects],
            ["user_no_access", False, geom_out],
            ["user_full_access", True, geom_out],
            ["user_area_access", False, geom_out],
        ]:
            user = test_data2["users"][user_name]
            set_request_parameters(
                server_iface,
                {
                    "USER_ID": str(user["id"]),
                    "ROLE_IDS": ",".join([str(e) for e in user["role_ids"]])
                },
            )

            layer = test_data2["project"].mapLayersByName("private_layer")[0]
            feature = QgsFeature()
            geom = QgsGeometry()
            geom.fromWkb(geometry.wkb)
            feature.setGeometry(geom)
            result = ogcserver_accesscontrol.allowToEdit(layer, feature)
            assert expected == result, "allowToEdit with '{}', should return '{}'.".format(
                user_name, expected)
Ejemplo n.º 2
0
 def update_from_geojson(self,
                         geojson,
                         crs_src='epsg:4326',
                         datatype='polygon',
                         wrap=False):
     log('Setting up AOI with geojson. Wrap is {}.'.format(wrap))
     self.datatype = datatype
     # Note geojson is assumed to be in 4326
     l = QgsVectorLayer(
         "{datatype}?crs={crs}".format(datatype=self.datatype, crs=crs_src),
         "calculation boundary", "memory")
     ds = ogr.Open(json.dumps(geojson))
     layer_in = ds.GetLayer()
     feats_out = []
     for i in range(0, layer_in.GetFeatureCount()):
         feat_in = layer_in.GetFeature(i)
         feat = QgsFeature(l.fields())
         geom = QgsGeometry()
         geom.fromWkb(feat_in.geometry().ExportToWkb())
         feat.setGeometry(geom)
         feats_out.append(feat)
     l.dataProvider().addFeatures(feats_out)
     l.commitChanges()
     if not l.isValid():
         QtWidgets.QMessageBox.critical(
             None, tr("Error"),
             tr("Failed to add geojson to temporary layer."))
         log("Failed to add geojson to temporary layer.")
         return
     self.l = transform_layer(l,
                              self.crs_dst,
                              datatype=self.datatype,
                              wrap=wrap)
Ejemplo n.º 3
0
 def startOrEndIntersectionsDict(self, layer):
     pointsDictWkb = {}
     for line1 in layer.getFeatures():
         line1Geom = line1.geometry()
         if line1Geom.isMultipart():
             for geometry in line1Geom.constGet():
                 ptLast = QgsGeometry().fromPointXY(QgsPointXY(
                     geometry[-1]))
                 ptFirst = QgsGeometry().fromPointXY(QgsPointXY(
                     geometry[0]))
         else:
             geometry = line1Geom.asPolyline()
             ptLast = QgsGeometry().fromPointXY(QgsPointXY(geometry[-1]))
             ptFirst = QgsGeometry().fromPointXY(QgsPointXY(geometry[0]))
         points = [ptFirst, ptLast]
         for pt in points:
             AreaOfInterest = pt.boundingBox()
             request = QgsFeatureRequest().setFilterRect(AreaOfInterest)
             for line2 in layer.getFeatures(request):
                 line2Geom = line2.geometry()
                 if line1Geom.equals(line2Geom):
                     continue
                 if line1Geom.touches(line2Geom):
                     try:
                         pointsDictWkb[pt.asWkb()].append(line2)
                     except KeyError:
                         pointsDictWkb[pt.asWkb()] = [line2]
     pointsDict = {}
     for pt in pointsDictWkb:
         geom = QgsGeometry()
         geom.fromWkb(pt)
         pointsDict[geom] = pointsDictWkb[pt]
     return pointsDict
Ejemplo n.º 4
0
    def fetchFeature(self, feature):
        try:
            obj = next(self._iterator)
            feature.setId(obj.pk)  # Only integers supported
            if self._source.dj_geo_field:
                dj_geo = getattr(obj, self._source.dj_geo_field.name)
                qgs_geo = QgsGeometry()
                qgs_geo.fromWkb(dj_geo.wkb.tobytes())
                feature.setGeometry(qgs_geo)
                self.geometryToDestinationCrs(feature, self._transform)
            else:
                feature.setGeometry(None)

            feature.setFields(self._source.qgs_fields)

            # TODO: attributes subset
            for idx, qgs_field in enumerate(self._source.qgs_fields):
                value = getattr(obj,
                                qgs_field.name())  # field names are the same
                # TODO: value conversion required?
                feature.setAttribute(idx, value)
            feature.setValid(True)
            return True
        except StopIteration as e:
            feature.setValid(False)
            return False
Ejemplo n.º 5
0
    def unserialize(self, st):
        style = None
        orig_geom = None
        geom = None

        try:
            t = pickle.loads(st)
        except Exception as e:
            try:
                t = pickle.loads(st, encoding='utf-8')
                # strange, Exception says : No module named 'PyQt4'
            except Exception as e:
                for m in e.args:
                    QgsMessageLog.logMessage(str(m), 'Extensions')

                raise Exception("Mask - Error when loading mask")

        if len(t) == 12:  # older version
            (self.do_buffer,
             self.buffer_units,
             self.buffer_segments,
             self.do_simplify,
             self.simplify_tolerance,
             self.do_save_as,
             self.file_path,
             self.file_format,
             self.limited_layers_obsolete,
             style,
             self.polygon_mask_method,
             self.line_mask_method) = t
        else:
            (self.do_buffer,
             self.buffer_units,
             self.buffer_segments,
             self.do_simplify,
             self.simplify_tolerance,
             self.do_save_as,
             self.file_path,
             self.file_format,
             self.limited_layers_obsolete,
             style,
             self.polygon_mask_method,
             self.line_mask_method,
             orig_geom,
             geom
             ) = t
        self.style = None
        self.geometry = None
        if style is not None:
            self.style = style
        if geom is not None:
            self.geometry = QgsGeometry()
            self.geometry.fromWkb(geom)
        if orig_geom is not None:
            gl = []
            for g in orig_geom:
                geo = QgsGeometry()
                geo.fromWkb(g)
                gl.append(geo)
            self.orig_geometry = gl
Ejemplo n.º 6
0
    def writerecords(self, records):
        """Stages multiple records."""

        if type(records) != list:
            raise ValueError('list expected, got {0}'.format(type(records)))
        if len(self) == 0:
            nr = 0
        else:
            nr = next(reversed(self.ordered_dict)) + 1

        for record in records:
            record['id'] = nr
            self.ordered_dict[nr] = record

            # rtree
            # self._spatial_index.insert(nr, geom)
            # QGIS:
            feature = QgsFeature()
            feature.setFeatureId(nr)
            try:
                geom = shape(record['geometry'])
                qgeom = QgsGeometry()
                qgeom.fromWkb(geom.to_wkb())

            except:
                wkt = "{}({})".format(
                    record['geometry']['type'],
                    ",".join(["{} {}".format(*c) for c in record['geometry']['coordinates']]))
                qgeom = QgsGeometry()
                qgeom.fromWkt(wkt)

            feature.setGeometry(qgeom)
            self._spatial_index.insertFeature(feature)
            nr += 1
Ejemplo n.º 7
0
    def create_feature_from_record(self, record):
        """
        Create feature in temporary layer from record returned from query.
        :param record: QSqlQuery record describing feature
        """
        feature = QgsFeature()
        wkb = record.value('geom')
        if type(wkb) == QByteArray:
            geometry = QgsGeometry()
            geometry.fromWkb(wkb)
            feature.setGeometry(geometry)
        else:
            "NOT a byte"

        feature.setAttributes([
            record.value('esu_id'),
            record.value('usrn'),
            record.value('rec_type'),
            record.value('desctxt'),
            record.value('locality'),
            record.value('town'),
            record.value('entry_date'),
            record.value('type_3_usrn'),
            record.value('type_3_desc'),
            record.value('type_4_usrn'),
            record.value('type_4_desc')
        ])
        return feature
Ejemplo n.º 8
0
    def create_feature_from_record(self, record):
        """
        Create feature in temporary layer from record returned from query.
        :param record: QSqlQuery record describing feature
        """
        feature = QgsFeature()
        wkb = record.value('geom')
        if type(wkb) == QByteArray:
            geometry = QgsGeometry()
            geometry.fromWkb(wkb)
            feature.setGeometry(geometry)
        else:
            "NOT a byte"

        feature.setAttributes([
            record.value('poly_id'),
            record.value('RefNo'),
            record.value('rec_type'),
            record.value('desctxt'),
            record.value('locality'),
            record.value('town'),
            record.value('LocTxt'),
            record.value('RdStatus'),
            record.value('Swa_org'),
            QDate().fromString(str(record.value('Adopt_Date')), 'yyyyMMdd'),
            QDate().fromString(str(record.value('Entry_Date')), 'yyyyMMdd'),
            record.value('lor_no'),
            record.value('route'),
            record.value('symbol'),
            record.value('element'),
            record.value('hierarchy')
        ])
        return feature
Ejemplo n.º 9
0
 def find(self, to_find):
     catLimit = self.settings.value("categoryLimit")
     totalLimit = self.settings.value("totalLimit")
     hasProjectSearches = len(self.settings.value("postgisSearches"))
     catFound = {}
     self._searches = self.readSearches()
     for searchId, search in self._searches.items():
         if (not hasProjectSearches
                 or searchId in self.settings.value("postgisSearches")):
             # Expression example:
             # SELECT textfield, ST_AsBinary(wkb_geometry)::geometry
             #   FROM searchtable
             #   WHERE textfield LIKE %(search)s
             #   LIMIT %(limit)s
             self.cur.execute(search.expression, {
                 'search': to_find,
                 'limit': catLimit
             })
             for row in self.cur.fetchall():
                 if searchId in catFound:
                     if catFound[searchId] >= catLimit:
                         continue
                     catFound[searchId] += 1
                 else:
                     catFound[searchId] = 1
                 content, wkb_geom = row
                 geometry = QgsGeometry()
                 geometry.fromWkb(binascii.a2b_hex(wkb_geom))
                 self.result_found.emit(self, search.searchName, content,
                                        geometry, search.srid)
                 if sum(catFound.values()) >= totalLimit:
                     break
Ejemplo n.º 10
0
    def ewkb2gqgis(self, ewkb):
        geom = QgsGeometry()

        geomType = int("0x" + self.decodeBinary(ewkb[2:10]), 0)
        if geomType & SRID_FLAG:
            ewkb = ewkb[:2] + self.encodeBinary(geomType ^ SRID_FLAG) + ewkb[18:]
        geom.fromWkb(binascii.a2b_hex(ewkb))
        return geom
Ejemplo n.º 11
0
def get_geometry_from_record(record):
    geometry = QgsGeometry()
    wkb = record.value('geometry')
    if wkb.isNull():
        msg = "rd_pol_id {} has NULL geometry".format(
            record.value('rd_pol_id'))
        raise rn_except.RdPolyNullGeometryError(msg)
    geometry.fromWkb(str(wkb))  # Convert variant to string
    return geometry
def createQGISFeature(f):
    qfeat = QgsFeature()
    qgeom = QgsGeometry()
    qgeom.fromWkb(f.geom)
    qfeat.setGeometry(qgeom)
    atts = [getValue(a) for a in f.value]
    atts.insert(0, f.ID)
    qfeat.setAttributes(atts)
    return qfeat
Ejemplo n.º 13
0
    def ewkb2gqgis(self, ewkb):
        geom = QgsGeometry()

        geomType = int("0x" + self.decodeBinary(ewkb[2:10]), 0)
        if geomType & SRID_FLAG:
            ewkb = ewkb[:2] + self.encodeBinary(geomType
                                                ^ SRID_FLAG) + ewkb[18:]
        geom.fromWkb(binascii.a2b_hex(ewkb))
        return geom
Ejemplo n.º 14
0
    def _qgs_memory_layer(self, style, features=None):
        """ Create QgsVectorLayer with memory backend and load
        features into it """

        result = QgsVectorLayer(style.parent.geometry_type, None, 'memory')
        provider = result.dataProvider()

        # Setup layer fields
        fldmap = {}
        for fld in style.parent.fields:
            provider.addAttributes(
                [QgsField(fld.keyname, *FIELD_TYPE_TO_QGIS[fld.datatype])])
            fldmap[fld.keyname] = len(fldmap)
        qgsfields = provider.fields()
        result.updateFields()

        # Load style from qml file
        result.loadNamedStyle(self.env.file_storage.filename(
            style.qml_fileobj))

        # Disable read only flag when it was set via qml file
        result.setReadOnly(False)

        # Load features into layers if needed
        if features is not None:
            result.startEditing()

            for feat in features:
                qgsfeat = QgsFeature(qgsfields)
                fattrs = [None] * len(fldmap)
                for k, v in feat.fields.iteritems():
                    if v is None:
                        continue
                    elif isinstance(v, date):
                        v = QDate(v.year, v.month, v.day)
                    elif isinstance(v, time):
                        v = QTime(v.hour, v.minute, v.second)
                    elif isinstance(v, datetime):
                        v = QDateTime(v.year, v.month, v.day, v.hour, v.minute,
                                      v.second)
                    fattrs[fldmap[k]] = v
                qgsfeat.setAttributes(fattrs)

                # Method fromWkb() is much faster constructor fromWkt()
                # TODO: QGIS 3 have constructor fromWkb()
                qgsgeom = QgsGeometry()
                qgsgeom.fromWkb(feat.geom.wkb)
                qgsfeat.setGeometry(qgsgeom)

                result.addFeature(qgsfeat)

            result.commitChanges()

        result.setCrs(QgsCoordinateReferenceSystem(style.parent.srs.id))

        return result
Ejemplo n.º 15
0
 def wkb2qgis(self, wkb):
     geom = QgsGeometry()
     try:
         geomType = int("0x" + self.decodeBinary(wkb[2:10]), 0)
         if geomType & SRID_FLAG:
             wkb = wkb[:2] + self.encodeBinary(geomType ^ SRID_FLAG) + wkb[18:]
         geom.fromWkb(binascii.a2b_hex(wkb))
     except TypeError:
         pass
     return geom
Ejemplo n.º 16
0
 def snapToDtm(self):
     player = self.edit3d_pointlayerbox.currentLayer()
     llayer = self.edit3d_linelayerbox.currentLayer()
     rlayer = self.edit3d_dtmlayerbox.currentLayer()
     llayer.startEditing()
     points = list(player.getFeatures())
     pointid = self.edit3d_currPointId.value()
     if points:
         point = points[pointid]
         pointGeom = point.geometry()
         if pointGeom.asMultiPoint():
             pointGeom = pointGeom.asMultiPoint()[0]
         else:
             pointGeom = pointGeom.asPoint()
         pid, feat = closestpoint(llayer, QgsGeometry.fromPoint(pointGeom))
         linegeom = feat.geometry().asWkb().data()
         olinegeom = ogr.CreateGeometryFromWkb(linegeom)
         dx = rlayer.rasterUnitsPerPixelX()
         dy = rlayer.rasterUnitsPerPixelY()
         xpos = pointGeom.x()
         ypos = pointGeom.y()
         # assume pixel = center
         xll = rlayer.extent().xMinimum() + 0.5 * dx
         yll = rlayer.extent().yMinimum() + 0.5 * dy
         xoffs = (pointGeom.x() - xll) % dx
         yoffs = (pointGeom.y() - yll) % dy
         dtm_val_ll = rlayer.dataProvider().identify(
             QgsPoint(xpos - dx / 2, ypos - dy / 2),
             QgsRaster.IdentifyFormatValue).results()[1]
         dtm_val_ur = rlayer.dataProvider().identify(
             QgsPoint(xpos + dx / 2, ypos + dy / 2),
             QgsRaster.IdentifyFormatValue).results()[1]
         dtm_val_lr = rlayer.dataProvider().identify(
             QgsPoint(xpos + dx / 2, ypos - dy / 2),
             QgsRaster.IdentifyFormatValue).results()[1]
         dtm_val_ul = rlayer.dataProvider().identify(
             QgsPoint(xpos - dx / 2, ypos + dy / 2),
             QgsRaster.IdentifyFormatValue).results()[1]
         a00 = dtm_val_ll
         a10 = dtm_val_lr - dtm_val_ll
         a01 = dtm_val_ul - dtm_val_ll
         a11 = dtm_val_ur + dtm_val_ll - (dtm_val_lr + dtm_val_ul)
         dtm_bilinear = a00 + a10 * xoffs + a01 * yoffs + a11 * xoffs * yoffs
         x, y = olinegeom.GetPoint_2D(pid)
         olinegeom.SetPoint(pid, x, y, dtm_bilinear)
         llayer.beginEditCommand("Snap point height to DTM")
         updatedGeom = QgsGeometry()
         updatedGeom.fromWkb(olinegeom.ExportToWkb())
         llayer.dataProvider().changeGeometryValues(
             {feat.id(): updatedGeom})
         llayer.endEditCommand()
         # refresh vertex editor
         self.showProblemPoint()
Ejemplo n.º 17
0
    def find(self, to_find):
        if self.settings.value("qftsfilepath") == '':
            return
        if not self.isValid:
            self.message.emit("Cannot search in project. QuickFinder file is probably currently in use.",QgsMessageBar.WARNING)
            return
        # add star after each word except numbers
        to_find = to_find.split(' ')
        for i,word in enumerate(to_find):
            try:
                int(word)
            except ValueError:
                to_find[i] = '%%%s%%' % word
        to_find = ' '.join(to_find)
        # FTS request
        sql = "SELECT search_id,content,x,y,wkb_geom FROM quickfinder_data WHERE content LIKE ?"
        cur = self.conn.cursor()

        catLimit = self.settings.value("categoryLimit")
        totalLimit = self.settings.value("totalLimit")
        catFound = {}
        for row in cur.execute(sql, [to_find]):
            search_id, content, x, y, wkb_geom = row
            if search_id in catFound:
                if catFound[search_id] >= catLimit:
                    continue
                catFound[search_id] += 1
            else:
                catFound[search_id] = 1

            if search_id not in self._searches:
                continue

            gs = self._searches[search_id].geometryStorage
            geometry = QgsGeometry()
            if gs == 'wkb':
                geometry.fromWkb(binascii.a2b_hex(wkb_geom))
            else:
                # wkt or extent are stored as wkt
                geometry = geometry.fromWkt(wkb_geom)

            crs = QgsCoordinateReferenceSystem()
            crs.createFromString(self._searches[search_id].srid)
            self.result_found.emit(self,
                                  self._searches[search_id].searchName,
                                  content,
                                  geometry,
                                  crs.postgisSrid())

            if sum(catFound.values()) >= totalLimit:
                break
Ejemplo n.º 18
0
    def find(self, to_find):
        if self.settings.value("qftsfilepath") == '':
            return
        if not self.isValid:
            self.message.emit("Cannot search in project. QuickFinder file is probably currently in use.",QgsMessageBar.WARNING)
            return
        # add star after each word except numbers
        to_find = to_find.split(' ')
        for i,word in enumerate(to_find):
            try:
                int(word)
            except ValueError:
                to_find[i] = '%s*' % word
        to_find = ' '.join(to_find)
        # FTS request
        sql = "SELECT search_id,content,x,y,wkb_geom FROM quickfinder_data WHERE content MATCH ?"
        cur = self.conn.cursor()

        catLimit = self.settings.value("categoryLimit")
        totalLimit = self.settings.value("totalLimit")
        catFound = {}
        for row in cur.execute(sql, [to_find]):
            search_id, content, x, y, wkb_geom = row
            if catFound.has_key(search_id):
                if catFound[search_id] >= catLimit:
                    continue
                catFound[search_id] += 1
            else:
                catFound[search_id] = 1

            if not self._searches.has_key(search_id):
                continue

            gs = self._searches[search_id].geometryStorage
            geometry = QgsGeometry()
            if gs == 'wkb':
                geometry.fromWkb(binascii.a2b_hex(wkb_geom))
            else:
                # wkt or extent are stored as wkt
                geometry = geometry.fromWkt(wkb_geom)

            crs = QgsCoordinateReferenceSystem()
            crs.createFromString(self._searches[search_id].srid)
            self.result_found.emit(self,
                                  self._searches[search_id].searchName,
                                  content,
                                  geometry,
                                  crs.postgisSrid())

            if sum(catFound.values()) >= totalLimit:
                break
Ejemplo n.º 19
0
    def find(self, toFind):
        if self.settings.value("qftsfilepath") == "":
            return
        if not self.isValid:
            self.message.emit(
                "Cannot search in project. QuickFinder file is probably currently in use.", QgsMessageBar.WARNING
            )
            return
        # add star after each word except numbers
        toFind = toFind.split(" ")
        for i, word in enumerate(toFind):
            try:
                int(word)
            except ValueError:
                toFind[i] = "%s*" % word
        toFind = " ".join(toFind)
        # FTS request
        sql = "SELECT search_id,content,x,y,wkb_geom FROM quickfinder_data WHERE content MATCH ?"
        cur = self.conn.cursor()
        cur.execute(sql, [toFind])
        catLimit = self.settings.value("categoryLimit")
        totalLimit = self.settings.value("totalLimit")
        nFound = 0
        catFound = {}
        while True:
            s = cur.fetchone()
            if s is None:
                return
            search_id, content, x, y, wkb_geom = s
            if catFound.has_key(search_id):
                if catFound[search_id] >= catLimit:
                    continue
                catFound[search_id] += 1
            else:
                catFound[search_id] = 1

            if not self._searches.has_key(search_id):
                continue

            geometry = QgsGeometry()
            geometry.fromWkb(binascii.a2b_hex(wkb_geom))

            crs = QgsCoordinateReferenceSystem()
            crs.createFromString(self._searches[search_id].srid)
            self.resultFound.emit(self, self._searches[search_id].searchName, content, geometry, crs.postgisSrid())

            nFound += 1
            if nFound >= totalLimit:
                break
Ejemplo n.º 20
0
def ewkb_to_geom(ewkb_str):
    if ewkb_str is None:
        return QgsGeometry()
    # get type + flags
    header = ewkb_str[2:10]
    has_srid = int(header[6], 16) & 2 > 0
    if has_srid:
        # remove srid flag
        header = header[:6] + "%X" % (int(header[6], 16) ^ 2) + header[7]
        # remove srid
        ewkb_str = ewkb_str[:2] + header + ewkb_str[18:]
    w = ewkb_str.decode('hex')
    g = QgsGeometry()
    g.fromWkb(w)
    return g
Ejemplo n.º 21
0
 def flagFeature(self, flagGeom, flagText, fromWkb=False, sink=None):
     """
     Creates and adds to flagSink a new flag with the reason.
     :param flagGeom: (QgsGeometry) geometry of the flag;
     :param flagText: (string) Text of the flag
     """
     flagSink = self.flagSink if sink is None else sink
     newFeat = QgsFeature(self.getFlagFields())
     newFeat['reason'] = flagText
     if fromWkb:
         geom = QgsGeometry()
         geom.fromWkb(flagGeom)
         newFeat.setGeometry(geom)
     else:
         newFeat.setGeometry(flagGeom)
     flagSink.addFeature(newFeat, QgsFeatureSink.FastInsert)
Ejemplo n.º 22
0
 def processLiteral(self,literal,literaltype,reproject):
     QgsMessageLog.logMessage("Process literal: "+str(literal)+" "+str(literaltype))
     geom=None
     if "literaltype" in self.triplestoreconf:
         literaltype=self.triplestoreconf["literaltype"]
     if literal.startswith("http"):
         res=self.handleURILiteral(literal)
         if res==None:
             return "{\"geometry\":null}"
         return json.dumps(res[0])
     if literaltype=="":
         literaltype=self.detectLiteralType(literal)
     if "wkt" in literaltype.lower():
         literal=literal.strip()
         if literal.startswith("<http"):
             index=literal.index(">")+1
             slashindex=literal.rfind("/")+1
             reproject=literal[slashindex:(index-1)]
             geom=QgsGeometry.fromWkt(literal[index:])
         else:
             geom=QgsGeometry.fromWkt(literal)
     #elif "gml" in literaltype.lower():
     #    geom=QgsGeometry.fromWkb(ogr.CreateGeometryFromGML(literal).ExportToWkb())
     elif "geojson" in literaltype.lower():
         return literal
     elif "wkb" in literaltype.lower():
         geom=QgsGeometry.fromWkb(bytes.fromhex(literal))
     if geom!=None and reproject!="":
         sourceCrs = QgsCoordinateReferenceSystem(reproject)
         destCrs = QgsCoordinateReferenceSystem(4326)
         tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
         geom.transform(tr)
     if geom!=None:
         return geom.asJson()
     return None
Ejemplo n.º 23
0
    def find(self, toFind):
        if not self.isValid:
            self.message.emit("Cannot search in project. QuickFinder file is probably currently in used.",QgsMessageBar.WARNING)
            return
        # add star after each word except numbers
        toFind = toFind.split(' ')
        for i,word in enumerate(toFind):
            try:
                int(word)
            except ValueError:
                toFind[i] = '%s*' % word
        toFind = ' '.join(toFind)
        # FTS request
        sql = "SELECT search_id,content,x,y,wkb_geom FROM quickfinder_data WHERE content MATCH ?"
        cur = self.conn.cursor()
        cur.execute(sql, [toFind])
        catLimit = self.settings.value("categoryLimit")
        totalLimit = self.settings.value("totalLimit")
        nFound = 0
        catFound = {}
        while True:
            s = cur.fetchone()
            if s is None:
                return
            search_id, content, x, y, wkb_geom = s
            if catFound.has_key(search_id):
                if catFound[search_id] >= catLimit:
                    continue
                catFound[search_id] += 1
            else:
                catFound[search_id] = 1

            if not self._searches.has_key(search_id):
                continue

            geometry = QgsGeometry()
            geometry.fromWkb(binascii.a2b_hex(wkb_geom))

            self.resultFound.emit(self,
                                  self._searches[search_id].searchName,
                                  content,
                                  geometry,
                                  self._searches[search_id].srid)

            nFound += 1
            if nFound >= totalLimit:
                break
Ejemplo n.º 24
0
def ogr_feature_as_qgis_feature(ogr_feature, qgs_vector_lyr):

    # start_time = time.perf_counter()
    # f = open("C:\\Users\\leendert.vanwolfswin\\Downloads\\ogr_feature_as_qgis_feature.log", "a+")
    # f.write('action; time\n')

    # geometry
    ogr_geom_ref = ogr_feature.GetGeometryRef()
    tgt_wkb_type = qgs_vector_lyr.wkbType()
    if not QgsWkbTypes.hasZ(tgt_wkb_type):
        ogr_geom_ref.FlattenTo2D()
    ogr_geom_wkb = ogr_geom_ref.ExportToWkb()
    qgs_geom = QgsGeometry()
    qgs_geom.fromWkb(ogr_geom_wkb)

    # delta_time=time.perf_counter() - start_time
    # f.write('Create QgsGeometry;{}\n'.format(str(delta_time)))

    # attributes
    # attributes = {}
    # for idx, field in enumerate(qgs_vector_lyr.fields()):
    #     ogr_field_idx = ogr_feature.GetFieldIndex(field.name())
    #     ogr_field_value = ogr_feature.GetField(ogr_field_idx)
    #     attributes[idx] = ogr_field_value
    attributes = []
    for field in qgs_vector_lyr.fields():
        ogr_field_idx = ogr_feature.GetFieldIndex(field.name())
        ogr_field_value = ogr_feature.GetField(ogr_field_idx)
        attributes.append(ogr_field_value)

    # delta_time=time.perf_counter() - start_time
    # f.write('Make attribute dict;{}\n'.format(str(delta_time)))

    qgs_feature = QgsFeature()
    qgs_feature.setGeometry(qgs_geom)
    qgs_feature.setAttributes(attributes)
    # qgs_feature = QgsVectorLayerUtils.createFeature(layer=qgs_vector_lyr,
    #                                                 geometry=qgs_geom,
    #                                                 attributes=attributes
    #                                                 )

    # delta_time=time.perf_counter() - start_time
    # f.write('Create QgsFeature;{}\n'.format(str(delta_time)))
    #
    # f.close()

    return qgs_feature
Ejemplo n.º 25
0
    def test_read(self):
        model = Point
        uri = '%s' % self.get_model_full_name(model)
        error_prefix = '%s' % self.get_model_full_name(model)

        print('model %s: %s objects' %
              (self.get_model_full_name(model), model.objects.all().count()))
        object_iterator = model.objects.all().iterator()

        print('create django provider')
        provider = QgsProviderRegistry.instance().createProvider(
            'django', uri, QgsDataProvider.ProviderOptions())
        self.assertTrue(provider.isValid())
        print('provider valid: %s' % provider.isValid())
        print('provider feature count: %s' % (provider.featureCount()))

        feature_iterator = provider.getFeatures(QgsFeatureRequest())
        for obj in object_iterator:
            feature = next(feature_iterator)
            obj_error_prefix = '%s.%s' % (error_prefix, obj.pk)
            self.assertTrue(
                feature.id() == obj.pk,
                '%s: feature id does not match, expected %s, found %s' %
                (obj_error_prefix, obj.pk + 1, feature.id()))
            for qgs_field in feature.fields():
                qgs_value = feature.attribute(qgs_field.name())
                dj_value = getattr(obj, qgs_field.name())
                # print('%s %s: %s x %s' % (obj_error_prefix, qgs_field.name(), dj_value, qgs_value))
                self.assertTrue(
                    qgs_value == dj_value,
                    '%s attribute %s value does not match, expected %s (type %s), found %s (type %s)'
                    % (obj_error_prefix, qgs_field.name(), dj_value,
                       type(dj_value), qgs_value, type(dj_value)))

                qgs_geo = QgsGeometry()
                qgs_geo.fromWkb(obj.geo_field.wkb.tobytes())
                self.assertTrue(
                    feature.geometry().equals(qgs_geo),
                    '%s geometry does not match, expected %s, found %s' %
                    (obj_error_prefix, obj.geo_field.wkt,
                     feature.geometry().asWkt()))

        print('create django layer')
        layer = QgsVectorLayer(uri, 'test', 'django')
        print('layer valid: %s' % layer.isValid())
        self.assertTrue(layer.isValid())
Ejemplo n.º 26
0
 def _ogr_feat_to_row(self, feat: ogr.Feature) -> dict:
     ''' ogr feature to table row (dict with field names as keys and field
     values as values) '''
     if self.field_names is not None:
         items = OrderedDict([(f, feat[f]) for f in self.field_names
                              if hasattr(feat, f)])
     else:
         items = OrderedDict(self._cursor.items())
     items[self.id_field] = feat.GetFID()
     geom = feat.geometry()
     if geom:
         qgeom = QgsGeometry()
         qgeom.fromWkb(geom.ExportToWkb())
         if not qgeom.isGeosValid():
             qgeom = qgeom.makeValid()
         geom = qgeom
     items[self.geom_field] = geom
     return items
Ejemplo n.º 27
0
 def route_transfer_nodes(self):
     '''
     routing between transfer nodes and area connectors
     '''
     self.links.table.truncate()
     project_epsg = settings.EPSG
     #route_ids = {}
     otp_router = OTPRouter(epsg=project_epsg)
     transform = QgsCoordinateTransform(
         QgsCoordinateReferenceSystem(OTPRouter.router_epsg),
         QgsCoordinateReferenceSystem(project_epsg),
         QgsProject.instance()
     )
     for i, area in enumerate(self.areas):
         self.log(f'Suche Routen zwischen Teilfläche {area.name} und den '
                  'Herkunfts-/Zielpunkten...')
         connector = self.connectors.get(id_teilflaeche=area.id)
         qpoint = connector.geom.asPoint()
         pcon = Point(id=area.id, x=qpoint.x(), y=qpoint.y(),
                      epsg=project_epsg)
         pcon.transform(OTPRouter.router_epsg)
         for transfer_node in self.transfer_nodes:
             qpoint = transfer_node.geom.asPoint()
             pnode = Point(id=transfer_node.id, x=qpoint.x(), y=qpoint.y(),
                           epsg=project_epsg)
             pnode.transform(otp_router.router_epsg)
             out_route = otp_router.route(pcon, pnode)
             in_route = otp_router.route(pnode, pcon)
             for route in out_route, in_route:
                 if not route:
                     continue
                 for link in route.links:
                     geom = QgsGeometry()
                     from_id = link.from_node.node_id
                     to_id = link.to_node.node_id
                     lg = link.get_geom()
                     if from_id == to_id or not lg:
                         continue
                     geom.fromWkb(lg.ExportToWkb())
                     geom.transform(transform)
                     self.links.add(from_node_id=from_id, to_node_id=to_id,
                                    transfer_node_id=transfer_node.id,
                                    area_id=area.id, geom=geom)
         self.set_progress(80 * (i + 1) / len(self.areas))
def getValue(val):
    value_type = val.WhichOneof('value_type')
    if value_type == 'null_value':
        return None
    elif value_type == 'string_value':
        return val.string_value
    elif value_type == 'int_value':
        return val.int_value
    elif value_type == 'long_value':
        return val.long_value
    elif value_type == 'bool_value':
        return val.bool_value
    elif value_type == 'double_value':
        return val.double_value
    elif value_type == 'float_value':
        return val.foat_value
    elif value_type == "geom_value":
        if len(val.geom_value) == 0:
            return None
        qgeom = QgsGeometry()
        qgeom.fromWkb(val.geom_value)
        return qgeom
    elif value_type == "byte_value":
        return val.byte_value
    elif value_type == "short_value":
        return val.short_value
    elif value_type == "char_value":
        return (val.char_value)
    elif value_type == "uuid_value":
        return QUuid(val.uuid_value)
    elif value_type == "datetime_value":
        return QDateTime.fromMSecsSinceEpoch(val.datetime_value)
    elif value_type == "date_value":
        dt = QDateTime.fromMSecsSinceEpoch(val.date_value)
        return dt.date()
    elif value_type == "time_value":
        dt = QDateTime.fromMSecsSinceEpoch(val.time_value)
        return dt.time()
    elif value_type == "timestamp_value":
        ts = val.timestamp_value
        dt = QDateTime.fromMSecsSinceEpoch(ts.seconds * 1000)
        dt.addMSecs(ts.nanos / 1000000)
        return dt.time()
Ejemplo n.º 29
0
def _wkbFromGml(tree, swap_xy):
    # extract the srid
    srid = None
    srid_axis_swapped = False

    srs_name = _get_srs_name(tree)
    if srs_name is None:
        # No SRID found, force to 4326
        srid = 4326
        srid_axis_swapped = True
    else:
        sr = osr.SpatialReference()
        # EPSG:4326
        # urn:EPSG:geographicCRS:4326
        # urn:ogc:def:crs:EPSG:4326
        # urn:ogc:def:crs:EPSG::4326
        # urn:ogc:def:crs:EPSG:6.6:4326
        # urn:x-ogc:def:crs:EPSG:6.6:4326
        # http://www.opengis.net/gml/srs/epsg.xml#4326
        # http://www.epsg.org/6.11.2/4326
        # get the last number
        m = re.search('([0-9]+)/?$', srs_name)
        srid = int(m.group(1))
        sr.ImportFromEPSGA(srid)
        srid_axis_swapped = sr.EPSGTreatsAsLatLong(
        ) or sr.EPSGTreatsAsNorthingEasting()

# inversion
    swap_xy = swap_xy ^ srid_axis_swapped

    # call ogr for GML parsing
    s = ET.tostring(tree, encoding="unicode")
    g = ogr.CreateGeometryFromGML(s)
    if g is None:
        return None, None

    qgsgeom = QgsGeometry()
    wkb = g.ExportToWkb()
    qgsgeom.fromWkb(wkb)

    if swap_xy:
        qgsgeom = _swap_qgs_geometry(qgsgeom)
    return qgsgeom, srid
Ejemplo n.º 30
0
    def readLayer(self, layer):
        ds = self._dstream
        dp = layer.dataProvider()
        if dp.featureCount() > 0:
            raise ValueError("Memory layer " + id + " is already loaded")
        attr = dp.attributeIndexes()
        dp.deleteAttributes(attr)
        ss = ""
        if self._version > 1:
            ss = ds.readQString()
        nattr = ds.readInt16()
        attr = list(range(nattr))
        for i in attr:
            name = ds.readQString()
            qtype = ds.readInt16()
            typename = ds.readQString()
            length = ds.readInt16()
            precision = ds.readInt16()
            comment = ds.readQString()
            fld = QgsField(name, qtype, typename, length, precision, comment)
            dp.addAttributes([fld])

        nullgeom = QgsGeometry()
        fields = dp.fields()
        while ds.readBool():
            feat = QgsFeature(fields)
            for i in attr:
                value = ds.readQVariant()
                if value is not None:
                    feat[i] = value

            wkbSize = ds.readUInt32()
            if wkbSize == 0:
                feat.setGeometry(nullgeom)
            else:
                geom = QgsGeometry()
                geom.fromWkb(ds.readRawData(wkbSize))
                feat.setGeometry(geom)
            dp.addFeatures([feat])
        layer.setSubsetString(ss)
        layer.updateFields()
        layer.updateExtents()
Ejemplo n.º 31
0
 def showSectionsInOverview(self):
     # clear existing rubberbands
     for rb in self.sectionsRbs:
         self.iface.mapCanvas().scene().removeItem(rb)
     self.sectionsRbs = []
     # add new rubberbands
     for id, sec in enumerate(self.WSMProj.sections):
         rb = QgsRubberBand(self.iface.mapCanvas(), False)
         rb_geom = QgsGeometry()
         rb_geom.fromWkb(sec.aoi)
         rb.setToGeometry(rb_geom, None)
         if id == self.currbox.value():
             fc = QtGui.QColor(self.colors[-1])
         else:
             fc = QtGui.QColor(self.colors[min(sec.status, 1)])
         rb.setColor(fc)
         fc.setAlpha(128)
         rb.setFillColor(fc)
         rb.setWidth(1)
         self.sectionsRbs.append(rb)
Ejemplo n.º 32
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        spatialRealtionsHandler = SpatialRelationsHandler()
        inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context)
        if inputLyr is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))
        onlySelected = self.parameterAsBool(parameters, self.SELECTED, context)
        heightFieldName = self.parameterAsFields(parameters, self.CONTOUR_ATTR,
                                                 context)[0]
        threshold = self.parameterAsDouble(parameters, self.CONTOUR_INTERVAL,
                                           context)
        geoBoundsLyr = self.parameterAsVectorLayer(parameters,
                                                   self.GEOGRAPHIC_BOUNDS,
                                                   context)
        point_flagSink, point_flag_id = self.prepareAndReturnFlagSink(
            parameters, inputLyr, QgsWkbTypes.Point, context, self.POINT_FLAGS)
        line_flagSink, line_flag_id = self.prepareAndReturnFlagSink(
            parameters, inputLyr, QgsWkbTypes.LineString, context,
            self.LINE_FLAGS)

        invalidDict = spatialRealtionsHandler.validateTerrainModel(
            contourLyr=inputLyr,
            onlySelected=onlySelected,
            heightFieldName=heightFieldName,
            threshold=threshold,
            geoBoundsLyr=geoBoundsLyr,
            feedback=feedback)

        for flagGeom, text in invalidDict.items():
            geom = QgsGeometry()
            geom.fromWkb(flagGeom)
            flagSink = line_flagSink if geom.type(
            ) == QgsWkbTypes.LineGeometry else point_flagSink
            self.flagFeature(geom, text, fromWkb=False, sink=flagSink)

        return {self.POINT_FLAGS: point_flag_id, self.LINE_FLAGS: line_flag_id}
def check_waypoints_not_excluded(waypoints_layer, exclusion_areas_layer=None):
    """Check if the input waypoints are contained in the exclusion areas.
    Check user mistake
    """
    if exclusion_areas_layer is None:
        return True
    else:
        polygon_wkb = exclusion_areas_fn.exclusion_areas_geoms(
            exclusion_areas_layer)

        waypoints_coords_list = waypoints_list(waypoints_layer)

        included_points = []
        for geom_ent in polygon_wkb:
            exclusion_geom = QgsGeometry()
            exclusion_geom.fromWkb(geom_ent)
            for point in waypoints_coords_list:
                point_coord = QgsPoint(point[0], point[1])
                if exclusion_geom.contains(point_coord):
                    included_points.append(point_coord)

        return included_points == []
Ejemplo n.º 34
0
    def find(self, toFind):
        if not self.isValid:
            return
        sql = "SELECT search_id,content,x,y,wkb_geom FROM quickfinder_data WHERE content MATCH ?"
        cur = self.conn.cursor()
        cur.execute(sql, [toFind])
        catLimit = self.settings.value("categoryLimit")
        totalLimit = self.settings.value("totalLimit")
        nFound = 0
        catFound = {}
        while True:
            s = cur.fetchone()
            if s is None:
                return
            search_id, content, x, y, wkb_geom = s
            if catFound.has_key(search_id):
                if catFound[search_id] >= catLimit:
                    continue
                catFound[search_id] += 1
            else:
                catFound[search_id] = 1

            if not self._searches.has_key(search_id):
                continue

            geometry = QgsGeometry()
            geometry.fromWkb(binascii.a2b_hex(wkb_geom))

            self.resultFound.emit(self,
                                  self._searches[search_id].searchName,
                                  content,
                                  geometry,
                                  self._searches[search_id].srid)

            nFound += 1
            if nFound >= totalLimit:
                break
def _wkbFromGml(tree, swap_xy, default_srs=None):
    # extract the srid
    srid = None
    srid_axis_swapped = False

    srs_name = _get_srs_name(tree)
    if srs_name is None and default_srs is not None:
        srid, srid_axis_swapped = _get_srid_from_name(default_srs)
    elif srs_name is not None:
        srid, srid_axis_swapped = _get_srid_from_name(srs_name)
    else:
        # No SRID found, force to 4326
        srid, srid_axis_swapped = 4326, True

# inversion
    swap_xy = swap_xy ^ srid_axis_swapped

    # call ogr for GML parsing
    s = ET.tostring(tree, encoding="unicode")
    g = ogr.CreateGeometryFromGML(s)
    if g is None:
        return None

    wkb = g.ExportToWkb()
    if g.GetGeometryType() in (ogr.wkbPolyhedralSurface, ogr.wkbTIN):
        # Polyhedral and TIN are not supported by QGIS
        # So we convert them to multipolygon by poking the geometry type
        # It works only because the memory structure is the same
        wkb = wkb[:4] + b"\x06" + wkb[5:]

    qgsgeom = QgsGeometry()
    qgsgeom.fromWkb(wkb)

    if swap_xy:
        qgsgeom = _swap_qgs_geometry(qgsgeom)
    return qgsgeom, srid
def _wkbFromGml(tree, swap_xy, default_srs = None):
    # extract the srid
    srid = None
    srid_axis_swapped = False

    srs_name = _get_srs_name(tree)
    if srs_name is None and default_srs is not None:
        srid, srid_axis_swapped = _get_srid_from_name(default_srs)
    elif srs_name is not None:
        srid, srid_axis_swapped = _get_srid_from_name(srs_name)
    else:
        # No SRID found, force to 4326
        srid, srid_axis_swapped = 4326, True

	# inversion
    swap_xy = swap_xy ^ srid_axis_swapped
            
    # call ogr for GML parsing
    s = ET.tostring(tree, encoding="unicode")
    g = ogr.CreateGeometryFromGML(s)
    if g is None:
        return None

    wkb = g.ExportToWkb()
    if g.GetGeometryType() in (ogr.wkbPolyhedralSurface, ogr.wkbTIN):
        # Polyhedral and TIN are not supported by QGIS
        # So we convert them to multipolygon by poking the geometry type
        # It works only because the memory structure is the same
        wkb = wkb[:4] + b"\x06" + wkb[5:]

    qgsgeom = QgsGeometry()
    qgsgeom.fromWkb(wkb)

    if swap_xy:
        qgsgeom = _swap_qgs_geometry(qgsgeom)
    return qgsgeom, srid
Ejemplo n.º 37
0
 def __qgPntFromShplyPnt(self, shapelyPnt):
     wkbPnt = dumps(shapelyPnt)
     qgGeom = QgsGeometry()
     qgGeom.fromWkb(wkbPnt)
     return qgGeom.asPoint()
Ejemplo n.º 38
0
 def addFeatures(self, layerid, features, fields, points=None, lines=None, polygons=None, permissions={}, add_empty=False, addToMap=True):
     """ Add DIVI layer to QGIS """
     qgis_fields = [ QgsField(field['key'], self.TYPES_MAP.get(field['type'], QVariant.String)) for field in fields ]
     #print (qgis_fields)
     #print (points, lines, polygons)
     if points is not None:
         points_pr = points.dataProvider()
         if points_pr.fields():
             points_pr.deleteAttributes(list(range(len(points_pr.fields()))))
         points_pr.addAttributes(qgis_fields)
         points.updateFields()
     if lines is not None:
         lines_pr = lines.dataProvider()
         if lines_pr.fields():
             lines_pr.deleteAttributes(list(range(len(lines_pr.fields()))))
         lines_pr.addAttributes(qgis_fields)
         lines.updateFields()
     if polygons is not None:
         polygons_pr = polygons.dataProvider()
         if polygons_pr.fields():
             polygons_pr.deleteAttributes(list(range(len(polygons_pr.fields()))))
         x = polygons_pr.addAttributes(qgis_fields)
         polygons.updateFields()
     #Lists of QGIS features
     points_list = []
     lines_list = []
     polygons_list = []
     count = float(len(features))
     points_ids = []
     lines_ids = []
     polygons_ids = []
     for i, feature in enumerate(features, start=1):
         #Geometria w formacie WKB zakodowanym przez base64
         geom = QgsGeometry()
         geom.fromWkb(b64decode(feature['geometry']))
         f = QgsFeature()
         f.setGeometry(geom)
         f.setAttributes([ feature['properties'].get(field['key']) for field in fields ])
         #Add feature to list by geometry type
         if geom.type() == QgsWkbTypes.PointGeometry:
             points_list.append(f)
             points_ids.append(feature['id'])
         elif geom.type() == QgsWkbTypes.LineGeometry:
             lines_list.append(f)
             lines_ids.append(feature['id'])
         elif geom.type() == QgsWkbTypes.PolygonGeometry:
             polygons_list.append(f)
             polygons_ids.append(feature['id'])
         else:
             continue
         if self.msgBar is not None:
             #self.msgBar.setProgress(i/count)
             pass
             QgsApplication.processEvents()
             if self.msgBar.aborted:
                 #Użytkownik anulował operację
                 return []
     #Add only layers that have features
     result = []
     register = partial(self.registerLayer, layerid=layerid, permissions=permissions,
         addToMap=addToMap, fields=fields)
     if points is not None and (points_list or add_empty):
         lyr, added = register(layer=points, features=points_list)
         result.append(lyr)
         self.ids_map[points.id()] = dict(list(zip(added, points_ids)))
     if lines is not None and (lines_list or add_empty):
         lyr, added = register(layer=lines, features=lines_list)
         result.append(lyr)
         self.ids_map[lines.id()] = dict(list(zip(added, lines_ids)))
     if polygons is not None and (polygons_list or add_empty):
         lyr, added = register(layer=polygons, features=polygons_list)
         result.append(lyr)
         self.ids_map[polygons.id()] = dict(list(zip(added, polygons_ids)))
     return result
Ejemplo n.º 39
0
class MaskParameters:
    def __init__(self):
        # selection | mask
        self.do_buffer = False
        self.buffer_units = 1
        self.buffer_segments = 5
        self.do_simplify = True
        self.simplify_tolerance = 1.0
        self.do_save_as = False
        self.file_path = None
        self.file_format = None
        self.style = None
        # polygon mask method : 0: exact, 1: centroid, 2: pointOnSurface
        self.polygon_mask_method = 2
        # line mask method = 0: intersects, 1: contains
        self.line_mask_method = 0
        # layers (list of id) where labeling has to be limited
        self.limited_layers_obsolete = []
        self.orig_geometry = None
        self.geometry = None

    def serialize(self, with_style=True, with_geometry=True):
        if with_style:
            style = self.style
        else:
            style = None

        if with_geometry:
            t = pickle.dumps([
                self.do_buffer,
                self.buffer_units,
                self.buffer_segments,
                self.do_simplify,
                self.simplify_tolerance,
                self.do_save_as,
                self.file_path,
                self.file_format,
                self.limited_layers_obsolete,
                style,
                self.polygon_mask_method,
                self.line_mask_method,
                [g.asWkb() for g in self.orig_geometry]
                if self.orig_geometry is not None else None,
                self.geometry.asWkb() if self.geometry is not None else None],
                protocol=0,
                fix_imports=True
                )
        else:
            t = pickle.dumps([self.do_buffer,
                             self.buffer_units,
                             self.buffer_segments,
                             self.do_simplify,
                             self.simplify_tolerance,
                             self.do_save_as,
                             self.file_path,
                             self.file_format,
                             self.limited_layers_obsolete,
                             style,
                             self.polygon_mask_method,
                             self.line_mask_method],
                             protocol=0,
                             fix_imports=True
                             )
        return t

    def unserialize(self, st):
        style = None
        orig_geom = None
        geom = None

        try:
            t = pickle.loads(st)
        except Exception as e:
            try:
                t = pickle.loads(st, encoding='utf-8')
                # strange, Exception says : No module named 'PyQt4'
            except Exception as e:
                for m in e.args:
                    QgsMessageLog.logMessage(str(m), 'Extensions')

                raise Exception("Mask - Error when loading mask")

        if len(t) == 12:  # older version
            (self.do_buffer,
             self.buffer_units,
             self.buffer_segments,
             self.do_simplify,
             self.simplify_tolerance,
             self.do_save_as,
             self.file_path,
             self.file_format,
             self.limited_layers_obsolete,
             style,
             self.polygon_mask_method,
             self.line_mask_method) = t
        else:
            (self.do_buffer,
             self.buffer_units,
             self.buffer_segments,
             self.do_simplify,
             self.simplify_tolerance,
             self.do_save_as,
             self.file_path,
             self.file_format,
             self.limited_layers_obsolete,
             style,
             self.polygon_mask_method,
             self.line_mask_method,
             orig_geom,
             geom
             ) = t
        self.style = None
        self.geometry = None
        if style is not None:
            self.style = style
        if geom is not None:
            self.geometry = QgsGeometry()
            self.geometry.fromWkb(geom)
        if orig_geom is not None:
            gl = []
            for g in orig_geom:
                geo = QgsGeometry()
                geo.fromWkb(g)
                gl.append(geo)
            self.orig_geometry = gl

    def have_same_layer_options(self, other):
        """ Returns true if the other parameters have the same layer options
           (file path, file format) than self
        """
        if not self.do_save_as:
            return not other.do_save_as
        else:
            if not other.do_save_as:
                return False
            else:
                return self.file_path == other.file_path and self.file_format == other.file_format

    def save_to_project(self):
        serialized = base64.b64encode(self.serialize())
        try:
            QgsProject.instance().writeEntry("Mask", "parameters", serialized)
        except:
            # strange behaviour, pickle change his format ?
            QgsProject.instance().writeEntry("Mask", "parameters", str(serialized)[2:-1])

        return True

    def load_from_project(self):
        st, ok = QgsProject.instance().readEntry("Mask", "parameters")
        if st == '':
            return False

        self.unserialize(base64.b64decode(st))
        return True

    # try to load parameters from a mask layer
    # for compatibility with older versions where parameters were saved in
    # attributes of the mask layer
    def load_from_layer(self, layer):
        # return False on failure
        pr = layer.dataProvider()
        fields = pr.fields()
        if fields.size() < 1:
            return False
        field = None
        for i, f in enumerate(fields):
            if f.name() == "params":
                field = i
        if field is None:
            return False

        it = pr.getFeatures()
        fet = QgsFeature()
        it.nextFeature(fet)
        st = fet.attribute(field)

        self.unserialize(base64.b64decode(st))

        if self.geometry is None:
            self.geometry = QgsGeometry(fet.geometry())
            self.orig_geometry = [QgsGeometry(fet.geometry())]

        return True