def revertFeatures(fname,actions,layername): layerDeletes = QgsVectorLayer(fname+"|layername=geogig_deleted_rows") request = QgsFeatureRequest() request.setFilterFids(actions["addDeleted"]) featuresToInsert1 = list(layerDeletes.getFeatures(request)) sip.delete(layerDeletes) del layerDeletes layerUpdates = QgsVectorLayer(fname + "|layername=geogig_updated_rows_orig") request = QgsFeatureRequest() request.setFilterFids(actions["addUpdated"]) featuresToInsert2 = list(layerUpdates.getFeatures(request)) sip.delete(layerUpdates) del layerUpdates # do delete layer = QgsVectorLayer(fname + "|layername="+layername) provider = layer.dataProvider() r=provider.deleteFeatures(actions["delete"]) r=provider.addFeatures(featuresToInsert1) r=provider.addFeatures(featuresToInsert2) sip.delete(layer) del layer
def test_sql2(self): l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False) self.assertEqual(l2.isValid(), True) QgsMapLayerRegistry.instance().addMapLayer(l2) query = toPercent("SELECT * FROM france_parts") l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual") self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().wkbType(), 3) self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326) n = 0 r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086)) for f in l4.getFeatures(r): self.assertEqual(f.geometry() is not None, True) self.assertEqual(f.attributes()[0], 2661) n += 1 self.assertEqual(n, 1) # use uid query = toPercent("SELECT * FROM france_parts") l5 = QgsVectorLayer( "?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query, "tt", "virtual") self.assertEqual(l5.isValid(), True) idSum = sum(f.id() for f in l5.getFeatures()) self.assertEqual(idSum, 10659) r = QgsFeatureRequest(2661) idSum2 = sum(f.id() for f in l5.getFeatures(r)) self.assertEqual(idSum2, 2661) r = QgsFeatureRequest() r.setFilterFids([2661, 2664]) self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664) # test attribute subset r = QgsFeatureRequest() r.setFlags(QgsFeatureRequest.SubsetOfAttributes) r.setSubsetOfAttributes([1]) s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)] self.assertEqual(sum([x[0] for x in s]), 10659) self.assertEqual(sum([x[1] for x in s]), 3064.0) # test NoGeometry # by request flag r = QgsFeatureRequest() r.setFlags(QgsFeatureRequest.NoGeometry) self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]), True) # test subset self.assertEqual(l5.dataProvider().featureCount(), 4) l5.setSubsetString("ObjectId = 2661") idSum2 = sum(f.id() for f in l5.getFeatures(r)) self.assertEqual(idSum2, 2661) self.assertEqual(l5.dataProvider().featureCount(), 1)
def get_nearest_point_name(self, point): # Check for projection c_proj = self.iface.mapCanvas().mapSettings().destinationCrs().authid() if c_proj not in self.allowed_projections: raise Exception( f'Your canvas projection {c_proj} is not allowed with plugin pub-tools;\ allowed projections: {self.allowed_projections}') elif c_proj == "EPSG:4326": point = QgsPoint(point) point.transform(self.pj_transformer) point = QgsPointXY(point) nearest_id = self.index.nearestNeighbor(point, 1) request = QgsFeatureRequest() request.setFilterFids(nearest_id) #TODO: Check if vector layer is activated! features = self.iface.activeLayer().getFeatures(request) # https://qgis.org/pyqgis/master/core/QgsSpatialIndex.html?highlight=spatialindex#module-QgsSpatialIndex elem = next(features, False) if not elem: raise Exception("No pub close") #TODO: Check if feature has Name attribute! return elem.attribute("Name")
def find_start_end_nodes_sindex(params, sindex, link_geom): # Find node FIDs that intersect the link bounding box bb = link_geom.boundingBox() # We grow slighlty the bb to prevent rounding errors: 10% of the link's length bb.grow(link_geom.length() * 0.1) cand_fids = sindex.intersects(bb) request = QgsFeatureRequest() request.setFilterFids(cand_fids) # Find features that intersect te link bb (from 3 possible layers) j_cands = params.junctions_vlay.getFeatures(request) r_cands = params.reservoirs_vlay.getFeatures(request) t_cands = params.tanks_vlay.getFeatures(request) intersecting_fts = [None, None] cands = [] for j_cand in j_cands: cands.append(j_cand) for r_cand in r_cands: cands.append(r_cand) for t_cand in t_cands: cands.append(t_cand) # Check if any candidates are actually start or end nodes for node_ft in cands: if node_ft.geometry().distance(QgsGeometry.fromPoint(link_geom.asPolyline()[0])) < params.tolerance: intersecting_fts[0] = node_ft if node_ft.geometry().distance(QgsGeometry.fromPoint(link_geom.asPolyline()[-1])) < params.tolerance: intersecting_fts[1] = node_ft return intersecting_fts
def get_new_electorates(self) -> Dict[int, int]: """ Returns a dictionary of pending changes from meshblock number to new electorate id """ assert self.task is not None electorate_field_name = '{}_id'.format(self.task) electorate_field_idx = self.meshblock_scenario_layer.fields( ).lookupField(electorate_field_name) assert electorate_field_idx >= 0 if self.meshblock_layer.editBuffer() is None: return {} # get list of affected features changed_attribute_values = self.meshblock_layer.editBuffer( ).changedAttributeValues() request = QgsFeatureRequest() request.setSubsetOfAttributes([self.meshblock_number_idx]) request.setFlags(QgsFeatureRequest.NoGeometry) request.setFilterFids(list(changed_attribute_values.keys())) meshblock_features = { f.id(): f for f in self.meshblock_layer.getFeatures(request) } # dict of meshblock number to new electorate new_electorates = {} for source_id, changes in changed_attribute_values.items(): new_electorate = changes[self.staged_electorate_idx] meshblock_number = int( meshblock_features[source_id][self.meshblock_number_idx]) new_electorates[meshblock_number] = new_electorate return new_electorates
def testFilterFids(self): req = QgsFeatureRequest().setFilterFids([5, 6]) self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids) self.assertEqual(req.spatialFilterType(), Qgis.SpatialFilterType.NoFilter) self.assertEqual(req.filterFid(), -1) self.assertCountEqual(req.filterFids(), [5, 6]) self.assertTrue(req.filterRect().isNull()) self.assertTrue(req.referenceGeometry().isNull()) # filter rect doesn't affect fids filter req.setFilterRect(QgsRectangle(1, 2, 3, 4)) self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids) self.assertEqual(req.filterFid(), -1) self.assertCountEqual(req.filterFids(), [5, 6]) self.assertEqual(req.spatialFilterType(), Qgis.SpatialFilterType.BoundingBox) self.assertEqual(req.filterRect(), QgsRectangle(1, 2, 3, 4)) self.assertTrue(req.referenceGeometry().isNull()) req.setFilterFids([8, 9]) self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids) self.assertEqual(req.filterFid(), -1) self.assertCountEqual(req.filterFids(), [8, 9]) self.assertEqual(req.spatialFilterType(), Qgis.SpatialFilterType.BoundingBox) self.assertEqual(req.filterRect(), QgsRectangle(1, 2, 3, 4)) self.assertTrue(req.referenceGeometry().isNull())
def clone_layer(layer, keep_selection=True): """Duplicate the layer by taking the same source and copying keywords. :param keep_selection: If we should keep the selection. Default to true. :type keep_selection: bool :param layer: Layer to be duplicated. :type layer: QgsMapLayer :return: The new QgsMapLayer object. :rtype: QgsMapLayer """ if is_vector_layer(layer): new_layer = QgsVectorLayer( layer.source(), layer.name(), layer.providerType()) if keep_selection and layer.selectedFeatureCount() > 0: request = QgsFeatureRequest() request.setFilterFids(layer.selectedFeatureIds()) request.setFlags(QgsFeatureRequest.NoGeometry) iterator = layer.getFeatures(request) new_layer.setSelectedFeatures([k.id() for k in iterator]) else: new_layer = QgsRasterLayer( layer.source(), layer.name(), layer.providerType()) new_layer.keywords = copy_layer_keywords(layer.keywords) return layer
def clone_layer(layer, keep_selection=True): """Duplicate the layer by taking the same source and copying keywords. :param keep_selection: If we should keep the selection. Default to true. :type keep_selection: bool :param layer: Layer to be duplicated. :type layer: QgsMapLayer :return: The new QgsMapLayer object. :rtype: QgsMapLayer """ if is_vector_layer(layer): new_layer = QgsVectorLayer(layer.source(), layer.name(), layer.providerType()) if keep_selection and layer.selectedFeatureCount() > 0: request = QgsFeatureRequest() request.setFilterFids(layer.selectedFeaturesIds()) request.setFlags(QgsFeatureRequest.NoGeometry) iterator = layer.getFeatures(request) new_layer.setSelectedFeatures([k.id() for k in iterator]) else: new_layer = QgsRasterLayer(layer.source(), layer.name(), layer.providerType()) new_layer.keywords = copy_layer_keywords(layer.keywords) return layer
def copy_layer(source, target): """Copy a vector layer to another one. :param source: The vector layer to copy. :type source: QgsVectorLayer :param target: The destination. :type source: QgsVectorLayer """ out_feature = QgsFeature() target.startEditing() request = QgsFeatureRequest() if source.keywords.get('layer_purpose') == 'aggregation': try: use_selected_only = source.use_selected_features_only except AttributeError: use_selected_only = False # We need to check if the user wants selected feature only and if there # is one minimum selected. if use_selected_only and source.selectedFeatureCount() > 0: request.setFilterFids(source.selectedFeaturesIds()) for i, feature in enumerate(source.getFeatures(request)): geom = feature.geometry() out_feature.setGeometry(QgsGeometry(geom)) out_feature.setAttributes(feature.attributes()) target.addFeature(out_feature) target.commitChanges()
def explode_multi_parts(self, address=False): request = QgsFeatureRequest() if address: refs = {self.get_id(ad) for ad in address.getFeatures()} fids = [ f.id() for f in self.getFeatures() if f["localId"] not in refs ] request.setFilterFids(fids) super(ConsLayer, self).explode_multi_parts(request)
def test_sql2(self): l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False) self.assertEqual(l2.isValid(), True) QgsProject.instance().addMapLayer(l2) query = toPercent("SELECT * FROM france_parts") l4 = QgsVectorLayer("?query=%s&uid=ObjectId" % query, "tt", "virtual") self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().wkbType(), 3) self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326) n = 0 r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086)) for f in l4.getFeatures(r): self.assertEqual(f.geometry() is not None, True) self.assertEqual(f.attributes()[0], 2661) n += 1 self.assertEqual(n, 1) # use uid query = toPercent("SELECT * FROM france_parts") l5 = QgsVectorLayer("?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query, "tt", "virtual") self.assertEqual(l5.isValid(), True) idSum = sum(f.id() for f in l5.getFeatures()) self.assertEqual(idSum, 10659) r = QgsFeatureRequest(2661) idSum2 = sum(f.id() for f in l5.getFeatures(r)) self.assertEqual(idSum2, 2661) r = QgsFeatureRequest() r.setFilterFids([2661, 2664]) self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664) # test attribute subset r = QgsFeatureRequest() r.setFlags(QgsFeatureRequest.SubsetOfAttributes) r.setSubsetOfAttributes([1]) s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)] self.assertEqual(sum([x[0] for x in s]), 10659) self.assertEqual(sum([x[1] for x in s]), 3064.0) # test NoGeometry # by request flag r = QgsFeatureRequest() r.setFlags(QgsFeatureRequest.NoGeometry) self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]), True) # test subset self.assertEqual(l5.dataProvider().featureCount(), 4) l5.setSubsetString("ObjectId = 2661") idSum2 = sum(f.id() for f in l5.getFeatures(r)) self.assertEqual(idSum2, 2661) self.assertEqual(l5.dataProvider().featureCount(), 1)
def modifyFeatures(self, geogiglayer, transactionid): if geogiglayer.modifiedFeatures: modifiedFeatures = [ fid for fid in geogiglayer.modifiedFeatures if fid >= 0 ] request = QgsFeatureRequest() request.setFilterFids(modifiedFeatures) features = [f for f in geogiglayer.layer.getFeatures(request)] self.addFeaturesToWorking(features, geogiglayer.user, geogiglayer.repo, geogiglayer.layername, transactionid)
def _useAlgorithm(self, x, y): elevationPoint = QgsGeometry().fromPoint( QgsPoint(x, y ) ) featureIds = self._getClosestNodeFeatureIds(x,y) values = {featureId: {'height': self.featuresHeights[0][featureId-1] } for featureId in featureIds} request = QgsFeatureRequest() request.setFilterFids(featureIds) nearestFourGridNodes = self.gridLayer.getFeatures( request ) for gridNode in nearestFourGridNodes: values[gridNode.id()]['distance'] = gridNode.geometry().distance(elevationPoint) return self._inverseDistanceWeighted(values)
def testFilterFids(self): req = QgsFeatureRequest().setFilterFids([5, 6]) self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids) self.assertEqual(req.filterFid(), -1) self.assertCountEqual(req.filterFids(), [5, 6]) # filter rect doesn't affect fids filter req.setFilterRect(QgsRectangle(1, 2, 3, 4)) self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids) self.assertEqual(req.filterFid(), -1) self.assertCountEqual(req.filterFids(), [5, 6]) req.setFilterFids([8, 9]) self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids) self.assertEqual(req.filterFid(), -1) self.assertCountEqual(req.filterFids(), [8, 9]) self.assertEqual(req.filterRect(), QgsRectangle(1, 2, 3, 4))
def getChangeSet(fname): raw = getChangeSetRaw(fname) layer = QgsVectorLayer(fname) request = QgsFeatureRequest() request.setFilterFids(raw["inserted_fids"]) features_inserted = layer.getFeatures(request) request = QgsFeatureRequest() request.setFilterFids(raw["updated_fids"]) features_updated = list(layer.getFeatures(request)) origLayer = QgsVectorLayer(fname + "|layername=geogig_updated_rows_orig") layerDeletes = QgsVectorLayer(fname+"|layername=geogig_deleted_rows") result = [] deleted_features = getFeaturesFromGeogigIds(raw["deleted_geogigids"],layerDeletes) for geogigid in raw["deleted_geogigids"]: result.append({"ID": geogigid, "old": deleted_features[geogigid], "new": None, "geogig.changeType": 2}) for newFeature in features_inserted: result.append({"ID": newFeature[GEOGIGID_FIELD], "old": None, "new": newFeature, "geogig.changeType": 0}) origFeatures = getFeaturesFromGeogigIds([f[GEOGIGID_FIELD] for f in features_updated],origLayer) for newFeature in features_updated: id = newFeature[GEOGIGID_FIELD] result.append({"ID": id, # "old": _getOldFeature(newFeature[GEOGIGID_FIELD], origLayer), "old": origFeatures[id] , "new": newFeature, "geogig.changeType": 1}) sip.delete(layer) del layer sip.delete(origLayer) del origLayer sip.delete(layerDeletes) del layerDeletes return result
def getImagesByCanvas(): def getSourceDate(feat): return { 'source': feat[self.nameFieldSource], 'date': feat[self.nameFieldDate] } def getSource(feat): return {'source': feat[self.nameFieldSource]} images = [] selectedImage = self.layer.selectedFeatureCount() > 0 rectLayer = self.layer.extent( ) if not selectedImage else self.layer.boundingBoxOfSelected() crsLayer = self.layer.crs() crsCanvas = self.canvas.mapSettings().destinationCrs() ct = QgsCoordinateTransform(crsCanvas, crsLayer) rectCanvas = self.canvas.extent( ) if crsCanvas == crsLayer else ct.transform(self.canvas.extent()) if not rectLayer.intersects(rectCanvas): return (True, images) fr = QgsFeatureRequest() if selectedImage: fr.setFilterFids(self.layer.selectedFeaturesIds()) index = QgsSpatialIndex(self.layer.getFeatures(fr)) fids = index.intersects(rectCanvas) del fr del index fr = QgsFeatureRequest() fr.setFilterFids(fids) numImages = len(fids) del fids[:] it = self.layer.getFeatures(fr) f = QgsFeature() getF = getSourceDate if not self.nameFieldDate is None else getSource while it.nextFeature(f): if f.geometry().intersects(rectCanvas): images.append(getF(f)) return (True, images) if len(images) > 0 else (False, numImages)
def _useAlgorithm(self, x, y): featureIds = self._getClosestNodeFeatureIds(x, y) values = { featureId: { 'height': self.featuresHeights[0][featureId - 1] } for featureId in featureIds } request = QgsFeatureRequest() request.setFilterFids(featureIds) nearestFourGridNodes = self.gridLayer.getFeatures(request) for gridNode in nearestFourGridNodes: values[gridNode.id()]['geometry'] = gridNode.geometry().asPoint() return self._bilinearInterpolation(x, y, values)
def get_fk_set(layerName, fkName, skipFirst=1, fids=None, useProvider=False): """ skipFirst: number of initial lines to skip (header lines in excel) """ layer = layer_from_name(layerName) freq = QgsFeatureRequest() if fids is not None: freq.setFilterFids(fids) if not useProvider: feats = [f for f in layer.getFeatures(freq)] else: feats = [f for f in layer.dataProvider().getFeatures(freq)] fkSet = [] for f in feats[skipFirst:]: fk = f.attribute(fkName) if fk: # Skip NULL ids that may be reported from excel files fkSet.append(fk) return fkSet
def copy_layer(source, target): """Copy a vector layer to another one. :param source: The vector layer to copy. :type source: QgsVectorLayer :param target: The destination. :type source: QgsVectorLayer """ out_feature = QgsFeature() target.startEditing() request = QgsFeatureRequest() aggregation_layer = False if source.keywords.get('layer_purpose') == 'aggregation': try: use_selected_only = source.use_selected_features_only except AttributeError: use_selected_only = False # We need to check if the user wants selected feature only and if there # is one minimum selected. if use_selected_only and source.selectedFeatureCount() > 0: request.setFilterFids(source.selectedFeatureIds()) aggregation_layer = True for i, feature in enumerate(source.getFeatures(request)): geom = feature.geometry() if aggregation_layer and feature.hasGeometry(): # See issue https://github.com/inasafe/inasafe/issues/3713 # and issue https://github.com/inasafe/inasafe/issues/3927 # Also handle if feature has no geometry. was_valid, geom = geometry_checker(geom) if not geom: LOGGER.info( 'One geometry in the aggregation layer is still invalid ' 'after cleaning.') out_feature.setGeometry(geom) out_feature.setAttributes(feature.attributes()) target.addFeature(out_feature) target.commitChanges()
def inverser_canalisation(*args): id_canalisation = int(args[0]) id_layer = args[1] layer = QgsProject.instance().mapLayer(id_layer) # materialized feature in new layer request = QgsFeatureRequest() request.setFilterFids([id_canalisation]) mat = layer.materialize(request) # run the processing alg "reverse line direction" params = { 'INPUT': mat, 'OUTPUT': 'memory:test' } try: out = processing.run('native:reverselinedirection', params) except QgsProcessingException: QgsMessageLog.logMessage('Erreur dans les logs de Processing/PostGIS.', 'RAEPA', Qgis.Critical) iface.messageBar().pushMessage( 'Erreur dans les logs de Processing/PostGIS.', level=Qgis.Critical, duration=2) return vout = out['OUTPUT'] for feat in vout.getFeatures(): if layer.changeGeometry(id_canalisation, feat.geometry()): # message iface.messageBar().pushMessage( "Line direction has been reversed", level=Qgis.Success, duration=2 ) iface.mapCanvas().refresh() else: iface.messageBar().pushMessage( "Line direction has NOT been reversed. Check if the layer is editable", level=Qgis.Critical, duration=2 )
def buildTopology(self, axial, unlinks, links): index = createIndex(axial) axial_links = [] unlinks_list = [] links_list = [] # get unlinks pairs if unlinks: features = unlinks.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(['line1', 'line2'], unlinks.fields())) for feature in features: unlinks_list.append((feature.attribute('line1'), feature.attribute('line2'))) # get links pairs if links: features = links.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(['line1', 'line2'], links.fields())) for feature in features: links_list.append((feature.attribute('line1'), feature.attribute('line2'))) # get axial intersections features = axial.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([])) for feature in features: geom = feature.geometry() id = feature.id() box = geom.boundingBox() request = QgsFeatureRequest() if index: # should be faster to retrieve from index (if available) ints = index.intersects(box) request.setFilterFids(ints) else: # can retrieve objects using bounding box request.setFilterRect(box) request.setSubsetOfAttributes([]) targets = axial.getFeatures(request) for target in targets: geom_b = target.geometry() id_b = target.id() if not id_b == id and geom.intersects(geom_b): # check if in the unlinks if (id, id_b) not in unlinks_list and (id, id_b) not in unlinks_list: axial_links.append((id, id_b)) return axial_links
def feature_difference(self, layer): # Get the intersects polygons and difference from neihghboor start = time.time() mem_layer = self.MemoryPolygonLayer(layer) index = self.SpatialIndex(mem_layer) for f1 in mem_layer.getFeatures(): geom1 = f1.geometry() intersecting_ids = index.intersects(geom1.boundingBox()) request = QgsFeatureRequest() request.setFilterFids(intersecting_ids) features = mem_layer.getFeatures(request) for f2 in features: if f1['id'] != f2['id'] and f2['id'] is not None: geom2 = f2.geometry() new_geom = geom1.difference(geom2) if new_geom.area() != geom1.area(): if new_geom.type() == QgsWkbTypes.UnknownGeometry: print("Unknown Geometry Type Detected !", "in id: ", f1['id']) new_geom = self.GeometryControl(new_geom) new_geom = new_geom if new_geom.isEmpty( ) == False else geom1 mem_layer.dataProvider().changeGeometryValues( {f1.id(): new_geom}) geom1 = new_geom mem_layer.updateFields() end = time.time() print(round(end - start, 6), " time elapsed for difference") return mem_layer
def _assignFuel(self, points): index = QgsSpatialIndex() for feat in self._fuel_layer.getFeatures(): index.addFeature(feat) intersecting_fuels = dict() intersecting_points = list() for pt in points: pt.fuelModel = '1' geom = pt.feature.geometry() intersects = index.intersects(geom.boundingBox()) if len(intersects) > 0: request = QgsFeatureRequest() request.setFilterFids([intersects[0]]) fuels = [f for f in self._fuel_layer.getFeatures(request)] for fuel in fuels: if not fuel.id() in intersecting_fuels: intersecting_fuels[fuel.id()] = fuel intersecting_points.append(pt) if len(intersecting_fuels) > 0: for pt in intersecting_points: for k, feat in intersecting_fuels.items(): if feat.geometry().contains(pt.feature.geometry()): pt.fuelModel = feat.attributes()[1] break
def findAtPoint(self, layer, point, canvas, onlyTheClosestOne=True, onlyIds=False): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # recupera il valore del raggio di ricerca settings = QgsSettings() radius = settings.value( "/Map/searchRadiusMM", Qgis.DEFAULT_SEARCH_RADIUS_MM, type=float) if radius <= 0: radius = Qgis.DEFAULT_SEARCH_RADIUS_MM radius = canvas.extent().width() * radius/100 # crea il rettangolo da usare per la ricerca rect = QgsRectangle() rect.setXMinimum(point.x() - radius) rect.setXMaximum(point.x() + radius) rect.setYMinimum(point.y() - radius) rect.setYMaximum(point.y() + radius) rect = canvas.mapSettings().mapToLayerCoordinates(layer, rect) # recupera le feature che intersecano il rettangolo ret = None if onlyTheClosestOne: request=QgsFeatureRequest() request.setFilterRect(rect) minDist = -1 featureId = None rect = QgsGeometry.fromRect(rect) count = 0 for f in layer.getFeatures(request): if onlyTheClosestOne: geom = f.geometry() distance = geom.distance(rect) if minDist < 0 or distance < minDist: minDist = distance featureId = f.id() if onlyIds: ret = featureId elif featureId != None: f = QgsFeature() feats = layer.getFeature( QgsFeatureRequest(featureId) ) feats.nextFeature(f) ret = f else: IDs = [] for f in layer.getFeatures(): IDs.append( f.id() ) if onlyIds: ret = IDs else: ret = [] request = QgsFeatureRequest() QgsFeatureRequest.setFilterFids(IDs) for f in layer.getFeatures( request ): ret.append( f ) QApplication.restoreOverrideCursor() return ret
def run_checks(): self.assertEqual([f.name() for f in vl.fields()], ['fid', 'type', 'value']) # expression req = QgsFeatureRequest() req.setFilterExpression("value=16") it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter fid req = QgsFeatureRequest() req.setFilterFid(5) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter fids req = QgsFeatureRequest() req.setFilterFids([5]) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # check with subset of attributes req = QgsFeatureRequest() req.setFilterFids([5]) req.setSubsetOfAttributes([2]) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes()[2], 16) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter rect and expression req = QgsFeatureRequest() req.setFilterExpression("value=16 or value=14") req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5)) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter rect and fids req = QgsFeatureRequest() req.setFilterFids([3, 5]) req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5)) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed req = QgsFeatureRequest() req.setSubsetOfAttributes([]) it = vl.getFeatures(req) ids = [] geoms = {} while it.nextFeature(f): ids.append(f.id()) geoms[f.id()] = f.geometry().asWkt() self.assertCountEqual(ids, [3, 4, 5]) self.assertEqual(geoms, { 3: 'Point (3 3)', 4: 'Point (4 4)', 5: 'Point (5 5)' })
def run_checks(): self.assertEqual([f.name() for f in vl.fields()], ['fid', 'type', 'value']) # expression req = QgsFeatureRequest() req.setFilterExpression("value=16") it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter fid req = QgsFeatureRequest() req.setFilterFid(5) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter fids req = QgsFeatureRequest() req.setFilterFids([5]) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # check with subset of attributes req = QgsFeatureRequest() req.setFilterFids([5]) req.setSubsetOfAttributes([2]) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes()[2], 16) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter rect and expression req = QgsFeatureRequest() req.setFilterExpression("value=16 or value=14") req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5)) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter rect and fids req = QgsFeatureRequest() req.setFilterFids([3, 5]) req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5)) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed req = QgsFeatureRequest() req.setSubsetOfAttributes([]) it = vl.getFeatures(req) ids = [] geoms = {} while it.nextFeature(f): ids.append(f.id()) geoms[f.id()] = f.geometry().asWkt() self.assertCountEqual(ids, [3, 4, 5]) self.assertEqual(geoms, {3: 'Point (3 3)', 4: 'Point (4 4)', 5: 'Point (5 5)'})
def processAlgorithm(self, parameters, context, feedback): #pylint: disable=unused-argument,missing-docstring layer = self.parameterAsSource(parameters, self.INPUT, context) metric_field = self.parameterAsString(parameters, self.METRIC_FIELD, context) ordering_field = self.parameterAsString(parameters, self.ORDERING_FIELD, context) dissolve = self.parameterAsBool(parameters, self.DISSOLVE, context) feedback.pushInfo('Create metric sequence...') sequence = [] total = 100.0 / layer.featureCount() if layer.featureCount() else 0 for current, feature in enumerate(layer.getFeatures()): if feedback.isCanceled(): break distance = feature.attribute(ordering_field) value = feature.attribute(metric_field) if value != NULL: sequence.append([distance, value, feature.id()]) feedback.setProgress(int(current * total)) sequence = sorted(sequence) feedback.pushInfo('Perform Hubert-Kehagias Segmentation ...') serie = np.array([float(item[1]) for item in sequence]) segmentation = HubertKehagiasSegmentation(serie) kopt = segmentation.kopt(len(sequence) // 3) feedback.pushInfo('Output aggregated features') if dissolve: layer_fields = layer.fields() metric_field_idx = layer_fields.lookupField(metric_field) mean_field = layer_fields.at(metric_field_idx) std_field = QgsField(mean_field) std_field.setName('STD') fields = QgsFields() fields.append(QgsField('ID_AGO', QVariant.Int, len=10, prec=0)) fields.append(mean_field) fields.append(std_field) (sink, dest_id) = self.parameterAsSink( parameters, self.OUTPUT, context, fields, # QgsWkbTypes.MultiPolygon, layer.wkbType(), layer.sourceCrs()) def output_feature(geometry, seg_idx, mean, std): """ Emit output feature """ outfeature = QgsFeature() outfeature.setGeometry(geometry) outfeature.setAttributes([seg_idx, float(mean), float(std)]) sink.addFeature(outfeature) srclayer = context.getMapLayer(layer.sourceName()) breakpoints = segmentation.breakpoints(kopt) current = 0 for seg_idx, (start, stop) in enumerate( zip(breakpoints[:-1], breakpoints[1:])): geometries = list() request = QgsFeatureRequest() request.setFilterFids( [item[2] for item in sequence[start:stop]]) for feature in srclayer.getFeatures(request): geometries.append(feature.geometry()) current += 1 geometry = QgsGeometry.unaryUnion(geometries) mean = serie[start:stop].mean() std = serie[start:stop].std() if QgsWkbTypes.flatType( geometry.wkbType()) == QgsWkbTypes.MultiLineString: for linestring in geometry.mergeLines( ).asGeometryCollection(): output_feature(linestring, seg_idx, mean, std) elif QgsWkbTypes.flatType( geometry.wkbType()) == QgsWkbTypes.MultiPolygon: for polygon in geometry.asGeometryCollection(): output_feature(polygon, seg_idx, mean, std) else: output_feature(geometry, seg_idx, mean, std) feedback.setProgress(int(current * total)) else: fields = QgsFields(layer.fields()) fields.append(QgsField('ID_AGO', QVariant.Int, len=10, prec=0)) (sink, dest_id) = self.parameterAsSink( parameters, self.OUTPUT, context, fields, layer.wkbType(), # QgsWkbTypes.MultiPolygon, layer.sourceCrs()) segments = segmentation.segments(kopt) feature_segments = { sequence[i][2]: int(segment) for i, segment in enumerate(segments) } for current, feature in enumerate(layer.getFeatures()): if feedback.isCanceled(): break outfeature = QgsFeature() outfeature.setGeometry(QgsGeometry(feature.geometry())) outfeature.setAttributes( feature.attributes() + [feature_segments.get(feature.id(), None)]) sink.addFeature(outfeature) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def __init__(self, layer, parent=None): """Constructor :param layer: QGIS layer with selected entities :type layer: QgsVectorLayer :param parent: Parent object :type parent: QWidget """ super(SOSPlotDialog, self).__init__(parent) # Set up the user interface from Designer. self.layer = layer if type(self.layer) <> type (QgsVectorLayer()) : raise TypeError(self.tr("Selector layer isn't a vector layer")) if self.layer.selectedFeatureCount() == 0: raise ValueError (self.tr("No features selected")) self.setupUi(self) map (lambda w: w.setRange(-maxFloat,maxFloat),[self.xMinFloat, self.xMaxFloat, self.yMinFloat, self.yMaxFloat]) def DateTimeEdit2SpinBox (widget): widget.setValue = lambda value: widget.setDateTime(mpdates.num2date(value)) widget.value = lambda: mpdates.date2num(widget.dateTime().toPyDateTime()) map(DateTimeEdit2SpinBox, [self.xMinTime, self.xMaxTime, self.yMinTime, self.yMaxTime]) request = QgsFeatureRequest() request.setFlags(QgsFeatureRequest.NoGeometry) request.setFilterFids(self.layer.selectedFeaturesIds()) self.foiList = set([f.attribute("foi") for f in layer.getFeatures(request)]) self.foiList = list(self.foiList) self.foiList.sort() self.plotWidget.genColorMap (len(self.foiList)) self.xProperty.addItems([str(f.name()) for f in list(layer.pendingFields())[2:]]) self.yProperty.addItems([str(f.name()) for f in list(layer.pendingFields())[2:]]) self.xProperty.setCurrentIndex (0) self.yProperty.setCurrentIndex (1) self.draw() self.plotWidget.title = self.layer.name() self.plotWidget.xLabel = self.xProperty.currentText() self.plotWidget.yLabel = self.yProperty.currentText() self.plotWidget.picked.connect (self.dataSeriePicked) self.plotWidget.axisChanged.connect (self.axisLimChanged) self.title.editingFinished.connect(lambda: self.optionsToPlot(option='title')) self.legendChk.stateChanged.connect(lambda v: self.optionsToPlot(option='legend')) self.legendPos.currentIndexChanged.connect(lambda v: self.optionsToPlot(option='legend')) self.legendCols.valueChanged.connect(lambda v: self.optionsToPlot(option='legend')) self.gridChk.stateChanged.connect(lambda v: self.optionsToPlot(option='grid')) self.xSorted.toggled.connect(self.optionsToPlot) self.ySorted.toggled.connect(self.optionsToPlot) self.timeFormat.editingFinished.connect(self.optionsToPlot) self.xProperty.currentIndexChanged.connect(lambda v: self.optionsToPlot(option='xProperty')) self.xLabel.editingFinished.connect(lambda: self.optionsToPlot(option='xLabel')) self.xMinFloat.editingFinished.connect(lambda: self.optionsToPlot(option='xRange')) self.xMaxFloat.editingFinished.connect(lambda: self.optionsToPlot(option='xRange')) self.xMinTime.editingFinished.connect(lambda: self.optionsToPlot(option='xRange')) self.xMaxTime.editingFinished.connect(lambda: self.optionsToPlot(option='xRange')) self.yProperty.currentIndexChanged.connect(lambda v: self.optionsToPlot(option='yProperty')) self.yLabel.editingFinished.connect(lambda: self.optionsToPlot(option='yLabel')) self.yMinFloat.editingFinished.connect(lambda: self.optionsToPlot(option='yRange')) self.yMaxFloat.editingFinished.connect(lambda: self.optionsToPlot(option='yRange')) self.yMinTime.editingFinished.connect(lambda: self.optionsToPlot(option='yRange')) self.yMaxTime.editingFinished.connect(lambda: self.optionsToPlot(option='yRange')) map (lambda k: self.lineStyle.addItem(k, self.StylesTable.lineStyles[k]), sorted(self.StylesTable.lineStyles)) map (lambda k: self.marker.addItem(k, self.StylesTable.markers[k]), sorted(self.StylesTable.markers)) self.defaultStyle.button(QtGui.QDialogButtonBox.Reset).clicked.connect(self.restoreDefaultStyle) self.defaultStyle.button(QtGui.QDialogButtonBox.Apply).clicked.connect(lambda: self.optionsToPlot (option='defaultStyle')) map(lambda b: b.setAutoDefault(False), self.defaultStyle.buttons()) self.optionsFromPlot() self.stylesTable.setItemDelegateForColumn (1, ColorButtonDelegate(self)) self.stylesTable.setItemDelegateForColumn (2, ComboBoxDelegate(self,self.StylesTable.lineStyles)) self.stylesTable.setItemDelegateForColumn (3, DoubleSpinBoxDelegate(self, (0,100))) self.stylesTable.setItemDelegateForColumn (4, ComboBoxDelegate(self,self.StylesTable.markers)) self.stylesTable.setItemDelegateForColumn (5, DoubleSpinBoxDelegate(self, (0,100))) self.stylesTable.setItemDelegateForColumn (6, SliderDelegate(self, (0.0,1.0)))
def query_layer_for_fids(layerName, fids): layer = layer_from_name(layerName) freq = QgsFeatureRequest() freq.setFilterFids(list(fids)) return list(layer.getFeatures(freq))
def qgisGeometryTopologyTest(self, axial, index, unlinks): # this function checks the geometric validity of geometry using QGIS length = self.verification_settings['ax_min'] threshold = self.verification_settings['ax_dist'] axial_links = [] unlinks_list = [] # get unlinks pairs if not self.running: return if unlinks: if lfh.fieldExists(unlinks, 'line1') and lfh.fieldExists( unlinks, 'line2'): features = unlinks.getFeatures( QgsFeatureRequest().setSubsetOfAttributes( ['line1', 'line2'], unlinks.fields())) for feature in features: unlinks_list.append((feature.attribute('line1'), feature.attribute('line2'))) if not self.running: return if self.user_id == '': features = axial.getFeatures( QgsFeatureRequest().setSubsetOfAttributes([])) else: field = lfh.getFieldIndex(axial, self.user_id) features = axial.getFeatures( QgsFeatureRequest().setSubsetOfAttributes([field])) steps = 85.0 / float(axial.featureCount()) progress = 5.0 start_buff = QgsGeometry() end_buff = QgsGeometry() for i, feature in enumerate(features): if not self.running: break has_problem = False geom = feature.geometry() if self.user_id == '': fid = feature.id() else: fid = feature.attribute(self.user_id) # has no geometry, skip rest of the checks if not feature.hasGeometry(): self.axial_errors['invalid geometry'].append(fid) self.problem_nodes.append(fid) progress += steps continue # geometry is valid (generally), skip rest of the checks if not geom.isGeosValid() or geom.isEmpty() or ( geom.isMultipart() and len(geom.asMultiPolyline()) > 1): has_problem = True self.axial_errors['invalid geometry'].append(fid) continue if geom.isMultipart(): poly_geom = geom.asMultiPolyline()[0] else: poly_geom = geom.asPolyline() # geometry is polyline if len(poly_geom) > 2: has_problem = True self.axial_errors['polyline'].append(fid) # has two coinciding points if geom.length() == 0: has_problem = True self.axial_errors['coinciding points'].append(fid) # small lines, with small length if geom.length() < length: has_problem = True self.axial_errors['small line'].append(fid) # testing against other lines in the layer if threshold > 0: start_buff = QgsGeometry.fromPointXY(poly_geom[0]).buffer( threshold, 4) end_buff = QgsGeometry.fromPointXY(poly_geom[1]).buffer( threshold, 4) buff = geom.buffer(threshold, 4) box = buff.boundingBox() else: box = geom.boundingBox() request = QgsFeatureRequest() if index: # should be faster to retrieve from index (if available) ints = index.intersects(box) request.setFilterFids(ints) else: # can retrieve objects using bounding box request.setFilterRect(box) if self.user_id == '': request.setSubsetOfAttributes([]) else: field = lfh.getFieldIndex(axial, self.user_id) request.setSubsetOfAttributes([field]) targets = axial.getFeatures(request) for target in targets: if not self.running: break geom_b = target.geometry() if self.user_id == '': id_b = target.id() else: id_b = target.attribute(self.user_id) if not id_b == fid: # duplicate geometry if geom.isGeosEqual(geom_b): has_problem = True self.axial_errors['duplicate geometry'].append(fid) # geometry overlaps if geom.overlaps(geom_b): has_problem = True self.axial_errors['overlap'].append(fid) # short lines, just about touch without intersecting if (geom_b.intersects(start_buff) or geom_b.intersects(end_buff) ) and not geom_b.intersects(geom): has_problem = True self.axial_errors['short line'].append(fid) if geom.intersects(geom_b): # check if in the unlinks if (fid, id_b) not in unlinks_list and ( id_b, fid) not in unlinks_list: # build the topology if has_networkx: axial_links.append((fid, id_b)) if has_problem: self.problem_nodes.append(fid) progress += steps self.verificationProgress.emit(int(progress)) return axial_links
def __build_data(self): req = QgsFeatureRequest() req.setFilterFids(self.__feature_ids) self.__x_values = [] self.__y_values = [] current_data_range = None for f in self.__layer.getFeatures(req): raw_data = f[self.__y_fieldname] if self.__x_start_fieldname is not None: x_start = f[self.__x_start_fieldname] x_delta = f[self.__x_delta_fieldname] else: x_start = self.__x_start x_delta = self.__x_delta if isinstance(raw_data, list): # QGIS 3 natively reads array values # Null values still have to be filtered out # WARNING: extracting list from PostgreSQL's arrays seem very sloowww y_values = [ None if isinstance(x, QVariant) else x for x in raw_data ] elif isinstance(raw_data, str): # We assume values are separated by a ',' y_values = [ None if value == 'NULL' else float(value) for value in raw_data.split(",") ] else: print("Unsupported data format: {}".format(raw_data.__class__)) x_values = np.linspace(x_start, x_start + x_delta * (len(y_values) - 1), len(y_values)).tolist() data_range = (x_start, x_start + x_delta * (len(y_values) - 1)) if current_data_range is None: current_data_range = data_range self.__x_values = x_values self.__y_values = y_values else: # look for overlap if (current_data_range[0] < data_range[0] < current_data_range[1]) or \ (current_data_range[0] < data_range[1] < current_data_range[1]): print("Overlap in data around feature #{}".format(f.id())) continue if current_data_range[0] > data_range[1]: # new data are "on the left" self.__x_values = x_values + self.__x_values self.__y_values = y_values + self.__y_values else: # new data are "on the right" self.__x_values = self.__x_values + x_values self.__y_values = self.__y_values + y_values current_data_range = (self.__x_values[0], self.__x_values[-1]) self.__x_min, self.__x_max = ((min( self.__x_values), max(self.__x_values)) if self.__x_values else (None, None)) self.__y_min, self.__y_max = ((min( y for y in self.__y_values if y is not None), max(y for y in self.__y_values if y is not None)) if self.__y_values else (None, None)) self.data_modified.emit()
def findAtPoint(self, layer, point, canvas, onlyTheClosestOne=True, onlyIds=False): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # recupera il valore del raggio di ricerca settings = QgsSettings() radius = settings.value("/Map/searchRadiusMM", Qgis.DEFAULT_SEARCH_RADIUS_MM, type=float) if radius <= 0: radius = Qgis.DEFAULT_SEARCH_RADIUS_MM radius = canvas.extent().width() * radius / 100 # crea il rettangolo da usare per la ricerca rect = QgsRectangle() rect.setXMinimum(point.x() - radius) rect.setXMaximum(point.x() + radius) rect.setYMinimum(point.y() - radius) rect.setYMaximum(point.y() + radius) rect = canvas.mapSettings().mapToLayerCoordinates(layer, rect) # recupera le feature che intersecano il rettangolo ret = None if onlyTheClosestOne: request = QgsFeatureRequest() request.setFilterRect(rect) minDist = -1 featureId = None rect = QgsGeometry.fromRect(rect) count = 0 for f in layer.getFeatures(request): if onlyTheClosestOne: geom = f.geometry() distance = geom.distance(rect) if minDist < 0 or distance < minDist: minDist = distance featureId = f.id() if onlyIds: ret = featureId elif featureId != None: f = QgsFeature() feats = layer.getFeature(QgsFeatureRequest(featureId)) feats.nextFeature(f) ret = f else: IDs = [] for f in layer.getFeatures(): IDs.append(f.id()) if onlyIds: ret = IDs else: ret = [] request = QgsFeatureRequest() QgsFeatureRequest.setFilterFids(IDs) for f in layer.getFeatures(request): ret.append(f) QApplication.restoreOverrideCursor() return ret
def canvasPressEvent(self, event): """ handle click event on the canvas when tool is active """ x = event.pos().x() y = event.pos().y() pos = self.toMapCoordinates(QPoint(x, y)) # search for parcel layer poly_layers = QgsProject.instance().mapLayersByName(self.main.parcel) if len(poly_layers) == 0: QMessageBox.warning( None, self.tr("Area ratio"), self.tr("{} layer not found".format(self.main.parcel))) return poly_layer = poly_layers[0] # remove | layer: 0 tag from the end TODO not always good! poly_path = poly_layer.dataProvider().dataSourceUri().split('|')[0] # build index for polygon layer if self.index is None: self.index = QgsSpatialIndex() for feat in poly_layer.getFeatures(): self.index.insertFeature(feat) in_poly_layers = self.main.buildings # find polygons which MBR cover point fids = self.index.nearestNeighbor(pos) request = QgsFeatureRequest() request.setFilterFids(fids) features = poly_layer.getFeatures(request) p_geom = QgsGeometry.fromPointXY(pos) f = None for feat in features: if feat.geometry().intersects(p_geom): f = feat break else: # No poly found QMessageBox.warning( None, self.tr("Area ratio"), self.tr("Feature not found on layer {} ".format( self.main.parcel))) return # remove previous selection poly_layer.removeSelection() # select polygon clicked poly_layer.select(f.id()) area1 = f.geometry().area() # parcel area area2 = 0 # sum area for in_poly_layers msg = self.main.parcel + ": {:.1f}\n".format(area1) # go through building layers for name in in_poly_layers: layers = QgsProject.instance().mapLayersByName(name) if len(layers) == 0: QMessageBox.warning(None, self.tr("Area ratio"), self.tr("{} layer not found".format(name))) continue layer = layers[0] # remove | layer: 0 tag from the end layer_path = layer.dataProvider().dataSourceUri().split('|')[0] # select intersecting building processing.run( "native:selectbylocation", { 'INPUT': layer_path, 'INTERSECT': QgsProcessingFeatureSourceDefinition(poly_path, True), 'METHOD': 0, 'PREDICATE': [0] }) features = layer.selectedFeatures() n = 0 area3 = 0 # sum area for actual layer for feat in features: # accept intersecting buildings if an internal point is in the parcel p = feat.geometry().pointOnSurface() if p.intersects(f.geometry()): warea = feat.geometry().area() n += 1 area3 += warea # total area in this layer area2 += warea # total area in all layers if n > 0: msg = msg + "\n{:d} {}: {:.1f}".format(n, name, area3) layer.removeSelection() msg = msg + "\n\n{:.1f} %".format(area2 / area1 * 100.0) QMessageBox.information(None, self.tr("Area ratio"), msg)
def data( self ): if self._dataLoaded: return self._x, self._y, self._z self._dataLoaded=True self._x = None self._y = None self._z = None self._gridShape=None self._gridTested=False self._dataLoaded=True source=self._source zField=self._zField if source is None or zField is None or zField == '': return self._x, self._y, self._z discardTolerance=self._discardTolerance feedback=self._feedback total = source.featureCount() percent = 100.0 / total if total > 0 else 0 count = 0 x = list() y = list() z = list() try: if source.fields().lookupField(zField) >= 0: zField='"'+zField.replace('"','""')+'"' expression=QgsExpression(zField) if expression.hasParserError(): raise ContourError(tr("Cannot parse")+" "+zField) fields=source.fields() context=QgsExpressionContext() context.setFields(fields) if not expression.prepare(context): raise ContourError(tr("Cannot evaluate value")+ " "+zField) request = QgsFeatureRequest() request.setSubsetOfAttributes( expression.referencedColumns(),fields) if self._sourceFids is not None: request.setFilterFids(self._sourceFids) for current,feat in enumerate(source.getFeatures( request )): try: if feedback.isCanceled(): raise ContourError('Cancelled by user') feedback.setProgress(int(current * percent)) context.setFeature(feat) zval=expression.evaluate(context) try: zval=float(zval) except ValueError: raise ContourError(tr("Z value {0} is not number") .format(zval)) if zval is not None: fgeom = feat.geometry() if QgsWkbTypes.flatType(fgeom.wkbType()) != QgsWkbTypes.Point: raise ContourError(tr("Invalid geometry type for contouring - must be point geometry")) geom=fgeom.asPoint() x.append(geom.x()) y.append(geom.y()) z.append(zval) except Exception as ex: raise count = count + 1 npt=len(x) if npt > 0: x=np.array(x) y=np.array(y) z=np.array(z) if discardTolerance > 0: index=ContourUtils.discardDuplicatePoints( x,y,discardTolerance,self.crs().isGeographic()) npt1=len(index) if npt1 < npt: x=x[index] y=y[index] z=z[index] feedback.pushInfo(tr("{0} near duplicate points discarded - tolerance {1}") .format(npt-npt1,discardTolerance)) except ContourError as ce: feedback.reportError(ce.message()) feedback.setProgress(0) return self._x,self._y,self._z finally: feedback.setProgress(0) if len(x) < 3: feedback.reportError(tr("Too few points to contour")) return self._x, self._y, self._z self._x=x self._y=y self._z=z return self._x, self._y, self._z
farmacies = csv.reader(file, delimiter=',') i = 0 index = QgsSpatialIndex() for feat in grid: index.addFeature(feat) groups[feat.id()] = list() for farmacia in farmacies: if i > 0: punt = QgsGeometry.fromPointXY( QgsPointXY(float(farmacia[16]), float(farmacia[17]))) intersects = index.intersects(punt.boundingBox()) if len(intersects) > 0: request = QgsFeatureRequest() request.setFilterFids(intersects) feats = [f for f in layer.getFeatures(request)] found = False for feat in feats: if punt.intersects(feat.geometry()): groups[feat.id()].append(farmacia) found = True if not found: print('Error') else: print('Error') if i % 100 == 0: print(i) i += 1
def __init__(self, layer, parent=None): """Constructor :param layer: QGIS layer with selected entities :type layer: QgsVectorLayer :param parent: Parent object :type parent: QWidget """ super(SOSPlotDialog, self).__init__(parent) # Set up the user interface from Designer. self.layer = layer if type(self.layer) <> type(QgsVectorLayer()): raise TypeError(self.tr("Selector layer isn't a vector layer")) if self.layer.selectedFeatureCount() == 0: raise ValueError(self.tr("No features selected")) self.setupUi(self) map(lambda w: w.setRange(-maxFloat, maxFloat), [self.xMinFloat, self.xMaxFloat, self.yMinFloat, self.yMaxFloat]) def DateTimeEdit2SpinBox(widget): widget.setValue = lambda value: widget.setDateTime( mpdates.num2date(value)) widget.value = lambda: mpdates.date2num(widget.dateTime(). toPyDateTime()) map(DateTimeEdit2SpinBox, [self.xMinTime, self.xMaxTime, self.yMinTime, self.yMaxTime]) request = QgsFeatureRequest() request.setFlags(QgsFeatureRequest.NoGeometry) request.setFilterFids(self.layer.selectedFeaturesIds()) self.foiList = set( [f.attribute("foi") for f in layer.getFeatures(request)]) self.foiList = list(self.foiList) self.foiList.sort() self.plotWidget.genColorMap(len(self.foiList)) self.xProperty.addItems( [str(f.name()) for f in list(layer.pendingFields())[2:]]) self.yProperty.addItems( [str(f.name()) for f in list(layer.pendingFields())[2:]]) self.xProperty.setCurrentIndex(0) self.yProperty.setCurrentIndex(1) self.draw() self.plotWidget.title = self.layer.name() self.plotWidget.xLabel = self.xProperty.currentText() self.plotWidget.yLabel = self.yProperty.currentText() self.plotWidget.picked.connect(self.dataSeriePicked) self.plotWidget.axisChanged.connect(self.axisLimChanged) self.title.editingFinished.connect( lambda: self.optionsToPlot(option='title')) self.legendChk.stateChanged.connect( lambda v: self.optionsToPlot(option='legend')) self.legendPos.currentIndexChanged.connect( lambda v: self.optionsToPlot(option='legend')) self.legendCols.valueChanged.connect( lambda v: self.optionsToPlot(option='legend')) self.gridChk.stateChanged.connect( lambda v: self.optionsToPlot(option='grid')) self.xSorted.toggled.connect(self.optionsToPlot) self.ySorted.toggled.connect(self.optionsToPlot) self.timeFormat.editingFinished.connect(self.optionsToPlot) self.xProperty.currentIndexChanged.connect( lambda v: self.optionsToPlot(option='xProperty')) self.xLabel.editingFinished.connect( lambda: self.optionsToPlot(option='xLabel')) self.xMinFloat.editingFinished.connect( lambda: self.optionsToPlot(option='xRange')) self.xMaxFloat.editingFinished.connect( lambda: self.optionsToPlot(option='xRange')) self.xMinTime.editingFinished.connect( lambda: self.optionsToPlot(option='xRange')) self.xMaxTime.editingFinished.connect( lambda: self.optionsToPlot(option='xRange')) self.yProperty.currentIndexChanged.connect( lambda v: self.optionsToPlot(option='yProperty')) self.yLabel.editingFinished.connect( lambda: self.optionsToPlot(option='yLabel')) self.yMinFloat.editingFinished.connect( lambda: self.optionsToPlot(option='yRange')) self.yMaxFloat.editingFinished.connect( lambda: self.optionsToPlot(option='yRange')) self.yMinTime.editingFinished.connect( lambda: self.optionsToPlot(option='yRange')) self.yMaxTime.editingFinished.connect( lambda: self.optionsToPlot(option='yRange')) map( lambda k: self.lineStyle.addItem(k, self.StylesTable.lineStyles[k] ), sorted(self.StylesTable.lineStyles)) map(lambda k: self.marker.addItem(k, self.StylesTable.markers[k]), sorted(self.StylesTable.markers)) self.defaultStyle.button(QtGui.QDialogButtonBox.Reset).clicked.connect( self.restoreDefaultStyle) self.defaultStyle.button(QtGui.QDialogButtonBox.Apply).clicked.connect( lambda: self.optionsToPlot(option='defaultStyle')) map(lambda b: b.setAutoDefault(False), self.defaultStyle.buttons()) self.optionsFromPlot() self.stylesTable.setItemDelegateForColumn(1, ColorButtonDelegate(self)) self.stylesTable.setItemDelegateForColumn( 2, ComboBoxDelegate(self, self.StylesTable.lineStyles)) self.stylesTable.setItemDelegateForColumn( 3, DoubleSpinBoxDelegate(self, (0, 100))) self.stylesTable.setItemDelegateForColumn( 4, ComboBoxDelegate(self, self.StylesTable.markers)) self.stylesTable.setItemDelegateForColumn( 5, DoubleSpinBoxDelegate(self, (0, 100))) self.stylesTable.setItemDelegateForColumn( 6, SliderDelegate(self, (0.0, 1.0)))