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)
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)
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
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
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 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
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
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
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
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
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
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
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
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()
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
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
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
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
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)
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
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
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
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())
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
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()
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
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()
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)
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 == []
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
def __qgPntFromShplyPnt(self, shapelyPnt): wkbPnt = dumps(shapelyPnt) qgGeom = QgsGeometry() qgGeom.fromWkb(wkbPnt) return qgGeom.asPoint()
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
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