def merge(feature, features_input): """ Merge geometries from features list that touch given feature. """ count = 0 features_output = [ feature ] geom = QgsGeometry(feature.geometry()) #geom = QgsGeometry.fromPolygon(feature.geometry()) while True: breakloop = True for f in features_input: if f in features_output: continue g = f.geometry() #if geom.equals(g): # continue if geom.contains(g): continue if geom.within(g): geom = QgsGeometry(g) features_output.append(f) breakloop = False break if not geom.disjoint(g) or geom.touches(g) or geom.overlaps(g): geom = QgsGeometry(geom.combine(g)) features_output.append(f) breakloop = False break if breakloop: break return (geom, features_output)
def testContains(self): myPoly = QgsGeometry.fromPolygon([[QgsPoint(0, 0),QgsPoint(2, 0),QgsPoint(2, 2),QgsPoint(0, 2), QgsPoint(0, 0)]]) myPoint = QgsGeometry.fromPoint(QgsPoint(1, 1)) containsGeom = QgsGeometry.contains(myPoly, myPoint) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", containsGeom)) assert containsGeom == True, myMessage
def processAlgorithm(self, progress): polyLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) classFieldName = self.getParameterValue(self.CLASSFIELD) polyProvider = polyLayer.dataProvider() fields = polyProvider.fields() fields.append(QgsField(fieldName, QVariant.Int)) classFieldIndex = pointLayer.fieldNameIndex(classFieldName) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), polyProvider.geometryType(), polyProvider.crs()) spatialIndex = vector.spatialindex(pointLayer) ftPoint = QgsFeature() outFeat = QgsFeature() geom = QgsGeometry() current = 0 hasIntersections = False features = vector.features(polyLayer) total = 100.0 / float(len(features)) for ftPoly in features: geom = ftPoly.geometry() attrs = ftPoly.attributes() classes = [] hasIntersections = False points = spatialIndex.intersects(geom.boundingBox()) if len(points) > 0: hasIntersections = True if hasIntersections: for i in points: request = QgsFeatureRequest().setFilterFid(i) ftPoint = pointLayer.getFeatures(request).next() tmpGeom = QgsGeometry(ftPoint.geometry()) if geom.contains(tmpGeom): clazz = ftPoint.attributes()[classFieldIndex] if clazz not in classes: classes.append(clazz) outFeat.setGeometry(geom) if idxCount == len(attrs): attrs.append(len(classes)) else: attrs[idxCount] = len(classes) outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(current / total) del writer
def testContains(self): myPoly = QgsGeometry.fromPolygon([[ QgsPoint(0, 0), QgsPoint(2, 0), QgsPoint(2, 2), QgsPoint(0, 2), QgsPoint(0, 0) ]]) myPoint = QgsGeometry.fromPoint(QgsPoint(1, 1)) containsGeom = QgsGeometry.contains(myPoly, myPoint) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", containsGeom)) assert containsGeom == True, myMessage
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 processAlgorithm(self, progress): target = dataobjects.getObjectFromUri( self.getParameterValue(self.TARGET)) join = dataobjects.getObjectFromUri( self.getParameterValue(self.JOIN)) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) summary = self.getParameterValue(self.SUMMARY) == 1 keep = self.getParameterValue(self.KEEP) == 1 sumList = self.getParameterValue(self.STATS).lower().split(',') targetFields = target.fields() joinFields = join.fields() fieldList = QgsFields() if not summary: joinFields = vector.testForUniqueness(targetFields, joinFields) seq = list(range(len(targetFields) + len(joinFields))) targetFields.extend(joinFields) targetFields = dict(list(zip(seq, targetFields))) else: numFields = {} for j in range(len(joinFields)): if joinFields[j].type() in [QVariant.Int, QVariant.Double, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong]: numFields[j] = [] for i in sumList: field = QgsField(i + str(joinFields[j].name()), QVariant.Double, '', 24, 16) fieldList.append(field) field = QgsField('count', QVariant.Double, '', 24, 16) fieldList.append(field) joinFields = vector.testForUniqueness(targetFields, fieldList) targetFields.extend(fieldList) seq = list(range(len(targetFields))) targetFields = dict(list(zip(seq, targetFields))) fields = QgsFields() for f in list(targetFields.values()): fields.append(f) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, target.wkbType(), target.crs()) outFeat = QgsFeature() inFeatB = QgsFeature() inGeom = QgsGeometry() index = vector.spatialindex(join) mapP2 = dict() features = vector.features(join) for f in features: mapP2[f.id()] = QgsFeature(f) features = vector.features(target) total = 100.0 / len(features) for c, f in enumerate(features): atMap1 = f.attributes() outFeat.setGeometry(f.geometry()) inGeom = vector.snapToPrecision(f.geometry(), precision) none = True joinList = [] if inGeom.type() == QgsWkbTypes.PointGeometry: bbox = inGeom.buffer(10, 2).boundingBox() else: bbox = inGeom.boundingBox() bufferedBox = vector.bufferedBoundingBox(bbox, 0.51 * precision) joinList = index.intersects(bufferedBox) if len(joinList) > 0: count = 0 for i in joinList: inFeatB = mapP2[i] inGeomB = vector.snapToPrecision(inFeatB.geometry(), precision) res = False for predicate in predicates: if predicate == 'intersects': res = inGeom.intersects(inGeomB) elif predicate == 'contains': res = inGeom.contains(inGeomB) elif predicate == 'equals': res = inGeom.equals(inGeomB) elif predicate == 'touches': res = inGeom.touches(inGeomB) elif predicate == 'overlaps': res = inGeom.overlaps(inGeomB) elif predicate == 'within': res = inGeom.within(inGeomB) elif predicate == 'crosses': res = inGeom.crosses(inGeomB) if res: break if res: count = count + 1 none = False atMap2 = inFeatB.attributes() if not summary: atMap = atMap1 atMap2 = atMap2 atMap.extend(atMap2) atMap = dict(list(zip(seq, atMap))) break else: for j in list(numFields.keys()): numFields[j].append(atMap2[j]) if summary and not none: atMap = atMap1 for j in list(numFields.keys()): for k in sumList: if k == 'sum': atMap.append(sum(self._filterNull(numFields[j]))) elif k == 'mean': try: nn_count = sum(1 for _ in self._filterNull(numFields[j])) atMap.append(sum(self._filterNull(numFields[j])) / nn_count) except ZeroDivisionError: atMap.append(NULL) elif k == 'min': try: atMap.append(min(self._filterNull(numFields[j]))) except ValueError: atMap.append(NULL) elif k == 'median': atMap.append(self._median(numFields[j])) else: try: atMap.append(max(self._filterNull(numFields[j]))) except ValueError: atMap.append(NULL) numFields[j] = [] atMap.append(count) atMap = dict(list(zip(seq, atMap))) if none: outFeat.setAttributes(atMap1) else: outFeat.setAttributes(list(atMap.values())) if keep: writer.addFeature(outFeat) else: if not none: writer.addFeature(outFeat) progress.setPercentage(int(c * total)) del writer
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) filename2 = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename2) predicates = self.getParameterValue(self.PREDICATE) oldSelection = set(inputLayer.selectedFeaturesIds()) inputLayer.removeSelection() index = vector.spatialindex(inputLayer) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(inputLayer): disjoinSet.append(feat.id()) geom = QgsGeometry() selectedSet = [] current = 0 features = vector.features(selectLayer) total = 100.0 / float(len(features)) for f in features: geom = QgsGeometry(f.geometry()) intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) feat = inputLayer.getFeatures(request).next() tmpGeom = QgsGeometry(feat.geometry()) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: if predicate == 'intersects': res = tmpGeom.intersects(geom) elif predicate == 'contains': res = tmpGeom.contains(geom) elif predicate == 'equals': res = tmpGeom.equals(geom) elif predicate == 'touches': res = tmpGeom.touches(geom) elif predicate == 'overlaps': res = tmpGeom.overlaps(geom) elif predicate == 'within': res = tmpGeom.within(geom) elif predicate == 'crosses': res = tmpGeom.crosses(geom) if res: selectedSet.append(feat.id()) break current += 1 progress.setPercentage(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet if method == 1: selectedSet = list(oldSelection.union(selectedSet)) elif method == 2: selectedSet = list(oldSelection.difference(selectedSet)) inputLayer.setSelectedFeatures(selectedSet) self.setOutputValue(self.OUTPUT, filename)
def processAlgorithm(self, progress): polyLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) polyProvider = polyLayer.dataProvider() fields = polyProvider.fields() fields.append(QgsField(fieldName, QVariant.Int)) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), polyProvider.geometryType(), polyProvider.crs()) spatialIndex = vector.spatialindex(pointLayer) ftPoly = QgsFeature() ftPoint = QgsFeature() outFeat = QgsFeature() geom = QgsGeometry() current = 0 hasIntersections = False features = vector.features(polyLayer) total = 100.0 / float(len(features)) for ftPoly in features: geom = ftPoly.geometry() attrs = ftPoly.attributes() count = 0 hasIntersections = False points = spatialIndex.intersects(geom.boundingBox()) if len(points) > 0: hasIntersections = True if hasIntersections: for i in points: request = QgsFeatureRequest().setFilterFid(i) ftPoint = pointLayer.getFeatures(request).next() tmpGeom = QgsGeometry(ftPoint.geometry()) if geom.contains(tmpGeom): count += 1 outFeat.setGeometry(geom) if idxCount == len(attrs): attrs.append(count) else: attrs[idxCount] = count outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename) predicates = self.getParameterValue(self.PREDICATE) oldSelection = set(inputLayer.selectedFeaturesIds()) inputLayer.removeSelection() index = vector.spatialindex(inputLayer) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(inputLayer): disjoinSet.append(feat.id()) geom = QgsGeometry() selectedSet = [] current = 0 features = vector.features(selectLayer) total = 100.0 / float(len(features)) for f in features: geom = QgsGeometry(f.geometry()) intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) feat = inputLayer.getFeatures(request).next() tmpGeom = QgsGeometry(feat.geometry()) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: if predicate == 'intersects': res = tmpGeom.intersects(geom) elif predicate == 'contains': res = tmpGeom.contains(geom) elif predicate == 'equals': res = tmpGeom.equals(geom) elif predicate == 'touches': res = tmpGeom.touches(geom) elif predicate == 'overlaps': res = tmpGeom.overlaps(geom) elif predicate == 'within': res = tmpGeom.within(geom) elif predicate == 'crosses': res = tmpGeom.crosses(geom) if res: selectedSet.append(feat.id()) break current += 1 progress.setPercentage(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet if method == 1: selectedSet = list(oldSelection.union(selectedSet)) elif method == 2: selectedSet = list(oldSelection.difference(selectedSet)) inputLayer.setSelectedFeatures(selectedSet) self.setOutputValue(self.OUTPUT, filename)
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename) predicates = self.getParameterValue(self.PREDICATE) index = vector.spatialindex(layer) output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(layer.pendingFields(), layer.dataProvider().geometryType(), layer.crs()) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(layer): disjoinSet.append(feat.id()) geom = QgsGeometry() selectedSet = [] current = 0 features = vector.features(selectLayer) featureCount = len(features) total = 100.0 / float(len(features)) for current, f in enumerate(features): geom = QgsGeometry(f.geometry()) intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) feat = layer.getFeatures(request).next() tmpGeom = QgsGeometry(feat.geometry()) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: if predicate == 'intersects': res = tmpGeom.intersects(geom) elif predicate == 'contains': res = tmpGeom.contains(geom) elif predicate == 'equals': res = tmpGeom.equals(geom) elif predicate == 'touches': res = tmpGeom.touches(geom) elif predicate == 'overlaps': res = tmpGeom.overlaps(geom) elif predicate == 'within': res = tmpGeom.within(geom) elif predicate == 'crosses': res = tmpGeom.crosses(geom) if res: selectedSet.append(feat.id()) break progress.setPercentage(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet for i, f in enumerate(vector.features(layer)): if f.id() in selectedSet: writer.addFeature(f) progress.setPercentage(100 * i / float(featureCount)) del writer
def processAlgorithm(self, progress): polyLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) fieldIdx = pointLayer.fieldNameIndex(self.getParameterValue(self.WEIGHT)) polyProvider = polyLayer.dataProvider() fields = polyProvider.fields() fields.append(QgsField(fieldName, QVariant.Int)) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), polyProvider.geometryType(), polyProvider.crs()) spatialIndex = vector.spatialindex(pointLayer) ftPoint = QgsFeature() outFeat = QgsFeature() geom = QgsGeometry() current = 0 hasIntersections = False features = vector.features(polyLayer) total = 100.0 / float(len(features)) for ftPoly in features: geom = ftPoly.geometry() attrs = ftPoly.attributes() count = 0 hasIntersections = False points = spatialIndex.intersects(geom.boundingBox()) if len(points) > 0: hasIntersections = True if hasIntersections: progress.setText(str(len(points))) for i in points: request = QgsFeatureRequest().setFilterFid(i) ftPoint = pointLayer.getFeatures(request).next() tmpGeom = QgsGeometry(ftPoint.geometry()) if geom.contains(tmpGeom): weight = str(ftPoint.attributes()[fieldIdx]) try: count += float(weight) except: # Ignore fields with non-numeric values pass outFeat.setGeometry(geom) if idxCount == len(attrs): attrs.append(count) else: attrs[idxCount] = count outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def createGeom(self, coords): crsDest = self.__layer.crs() rc = ReprojectCoordinates(self.crsId, crsDest.srsid(), self.__hasZ, self.__hasM) if self.crsId != crsDest.srsid(): coordsPoint = list(rc.reproject(coords, True)) else: coordsPoint = list(rc.copyCoordstoPoints(coords)) # Point and multipoint Geometry # Always 1 part, 0 element of matrix if self.__layergeometryType == QgsWkbTypes.PointGeometry: if self.__isMultiType: multipoint = QgsMultiPoint() for coords_item in coordsPoint[0][1]: multipoint.addGeometry(coords_item) geom = QgsGeometry(multipoint) self.createFeature(geom) else: geom = QgsGeometry(coordsPoint[0][1][0]) self.createFeature(geom) elif self.__layergeometryType == QgsWkbTypes.LineGeometry: if self.__isMultiType: multiline = QgsGeometry(QgsMultiLineString()) for j in range(len(coordsPoint)): line = QgsLineString(coordsPoint[j][1]) multiline.addPart(line) self.createFeature(multiline) else: line = QgsGeometry(QgsLineString(coordsPoint[0][1])) self.createFeature(line) elif self.__layergeometryType == QgsWkbTypes.PolygonGeometry: if self.__isMultiType: multipoly = QgsGeometry(QgsMultiPolygon()) for i in range(len(coordsPoint)): if int(coordsPoint[i][0]) > 0: mycurve = QgsLineString(coordsPoint[i][1]) poly = QgsPolygon() poly.setExteriorRing(mycurve) polyGeometry = QgsGeometry(QgsPolygon(poly)) for j in range(len(coordsPoint)): if int(coordsPoint[j][0]) < 0: containsAllPoints = True for k in range(len(coordsPoint[j][1])): containsAllPoints = True curPoint = coordsPoint[j][1][k].clone() containsAllPoints = containsAllPoints \ and polyGeometry.contains(QgsPointXY(curPoint.x(), curPoint.y())) if containsAllPoints: mycurve = QgsLineString(coordsPoint[j][1]) poly.addInteriorRing(mycurve) multipoly.addPart(poly) self.createFeature(multipoly) else: extRing = 0 for i in range(len(coordsPoint)): if int(coordsPoint[i][0]) > 0: extRing = i mycurve = QgsLineString(coordsPoint[extRing][1]) poly = QgsPolygon() poly.setExteriorRing(mycurve) polyGeometry = QgsGeometry(QgsPolygon(poly)) for i in range(len(coordsPoint)): if int(coordsPoint[i][0]) < 0: containsAllPoints = True for j in range(len(coordsPoint[i][1])): containsAllPoints = True curPoint = coordsPoint[i][1][j].clone() containsAllPoints = containsAllPoints \ and polyGeometry.contains(QgsPointXY(curPoint.x(), curPoint.y())) if containsAllPoints: mycurve = QgsLineString(coordsPoint[i][1]) poly.addInteriorRing(mycurve) else: QMessageBox.question(self.iface.mainWindow(), self.translate_str("Ring not in exterior contour"), self.translate_str("The new geometry of the feature" " isn't valid. Do you want to use it anyway?"), QMessageBox.Yes, QMessageBox.No) self.createFeature(QgsGeometry(poly))
def setSelectFeatures(canvas, selectGeometry, doContains, doDifference, singleSelect=None): """ QgsMapCanvas* canvas, QgsGeometry* selectGeometry, bool doContains, bool doDifference, bool singleSelect """ if selectGeometry.type() != QGis.Polygon: return vlayer = getCurrentVectorLayer(canvas) if vlayer == None: return #toLayerCoordinates will throw an exception for any 'invalid' points in #the rubber band. #For example, if you project a world map onto a globe using EPSG 2163 #and then click somewhere off the globe, an exception will be thrown. selectGeomTrans = QgsGeometry(selectGeometry) if canvas.mapSettings().hasCrsTransformEnabled(): try: ct = QgsCoordinateTransform(canvas.mapSettings().destinationCrs(), vlayer.crs()) selectGeomTrans.transform( ct ) except QgsCsException as cse: Q_UNUSED(cse) #catch exception for 'invalid' point and leave existing selection unchanged """ QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); QgisApp::instance()->messageBar()->pushMessage( QObject::tr( "CRS Exception" ), QObject::tr( "Selection extends beyond layer's coordinate system" ), QgsMessageBar::WARNING, QgisApp::instance()->messageTimeout() ); """ return QApplication.setOverrideCursor(Qt.WaitCursor) """ QgsDebugMsg( "Selection layer: " + vlayer->name() ); QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() ); QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) ); QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) ); """ context = QgsRenderContext().fromMapSettings(canvas.mapSettings()) r = vlayer.rendererV2() if r: r.startRender(context, vlayer.pendingFields()) request = QgsFeatureRequest() request.setFilterRect(selectGeomTrans.boundingBox()) request.setFlags(QgsFeatureRequest.ExactIntersect) if r: request.setSubsetOfAttributes(r.usedAttributes(), vlayer.pendingFields()) else: request.setSubsetOfAttributes(QgsAttributeList) fit = vlayer.getFeatures(request) newSelectedFeatures = [] #QgsFeatureIds f = QgsFeature() closestFeatureId = 0 #QgsFeatureId foundSingleFeature = False #double closestFeatureDist = std::numeric_limits<double>::max(); closestFeatureDist = sys.float_info.max while fit.nextFeature(f): # make sure to only use features that are visible if r and not r.willRenderFeature( f ): continue; g = QgsGeometry(f.geometry()) if doContains: if not selectGeomTrans.contains(g): continue else: if not selectGeomTrans.intersects(g): continue if singleSelect: foundSingleFeature = True distance = float(g.distance(selectGeomTrans)) if ( distance <= closestFeatureDist ): closestFeatureDist = distance closestFeatureId = f.id() else: newSelectedFeatures.insert(0, f.id()) if singleSelect and foundSingleFeature: newSelectedFeatures.insert(0, closestFeatureId) if r: r.stopRender(context) #QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) if doDifference: layerSelectedFeatures = vlayer.selectedFeaturesIds() selectedFeatures = [] #QgsFeatureIds deselectedFeatures = []# QgsFeatureIds # i = QgsFeatureIds.const_iterator(newSelectedFeatures.constEnd()) # while i != newSelectedFeatures.constBegin(): # i = i - 1 # if layerSelectedFeatures.contains(i): # deselectedFeatures.insert(0, i) # else: # selectedFeatures.insert(0, i) for item in newSelectedFeatures: if item in layerSelectedFeatures: deselectedFeatures.insert(0, item) else: selectedFeatures.insert(0, item) vlayer.modifySelection(selectedFeatures, deselectedFeatures) else: vlayer.setSelectedFeatures(newSelectedFeatures) QApplication.restoreOverrideCursor() """
def setSelectFeaturesOrRubberband_Tas(canvas, selectGeometry, doContains=True, doDifference=False, singleSelect=False): if (selectGeometry.type() != QGis.Polygon): return vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer(canvas) if (vlayer == None): return #// toLayerCoordinates will throw an exception for any 'invalid' points in #// the rubber band. #// For example, if you project a world map onto a globe using EPSG 2163 #// and then click somewhere off the globe, an exception will be thrown. selectGeomTrans = QgsGeometry(selectGeometry) if (canvas.mapSettings().hasCrsTransformEnabled()): try: ct = QgsCoordinateTransform( canvas.mapSettings().destinationCrs(), vlayer.crs()) # print selectGeomTrans.boundingBox().xMaximum () # polygonList = [] # for polygon in selectGeomTrans1.asPolygon(): # pointList = [] # for point in polygon: # transPoint = QgisHelper.CrsTransformPoint(point.x(), point.y(), define._mapCrs, vlayer.crs()) # pointList.append(transPoint) # polygonList.extend(pointList) # selectGeomTrans = QgsGeometry.fromPolygon (pointList) selectGeomTrans.transform(ct) except QgsCsException as cse: raise UserWarning, "Coordinate Transform Error in QgsMapToolSelectUtils\n" + cse.message QApplication.setOverrideCursor(Qt.WaitCursor) fit = vlayer.getFeatures(QgsFeatureRequest().setFilterRect( selectGeomTrans.boundingBox()).setFlags( QgsFeatureRequest.ExactIntersect).setSubsetOfAttributes([])) newSelectedFeatures = [] newSelectedFeatureList = [] f = QgsFeature() closestFeatureId = 0 foundSingleFeature = False closestFeatureDist = 9.0E+10 for f in fit: g = f.geometry() if (doContains): if (not selectGeomTrans.contains(g)): continue else: if (not selectGeomTrans.intersects(g)): continue if (singleSelect): foundSingleFeature = True distance = g.distance(selectGeomTrans) if (distance <= closestFeatureDist): closestFeatureDist = distance closestFeatureId = f.id() else: newSelectedFeatures.append(f.id()) newSelectedFeatureList.append(f) if (singleSelect and foundSingleFeature): newSelectedFeatures.append(closestFeatureId) featIter = vlayer.getFeatures(QgsFeatureRequest(closestFeatureId)) for feat in featIter: newSelectedFeatureList.append(feat) if (doDifference): layerSelectedFeatures = vlayer.selectedFeaturesIds() deselectedFeatures = [] selectedFeatures = [] for i in newSelectedFeatures.reverse(): if i in layerSelectedFeatures: deselectedFeatures.append(i) else: selectedFeatures.append(i) vlayer.modifySelection(selectedFeatures, deselectedFeatures) else: vlayer.setSelectedFeatures(newSelectedFeatures) QApplication.restoreOverrideCursor() return newSelectedFeatureList
def getMatchingFeatures(self, geometry, contains, singleSelect): newFeatures = [] if geometry.type() != QgsWkbTypes.PolygonGeometry: return newFeatures layer = self.canvas.currentLayer() if layer is None: return newFeatures selectGeomTrans = QgsGeometry(geometry) try: ct = QgsCoordinateTransform(self.canvas.mapSettings().destinationCrs(), layer.crs(), QgsProject.instance()) if not ct.isShortCircuited() and selectGeomTrans.type() == QgsWkbTypes.PolygonGeometry: poly = selectGeomTrans.asPolygon() if len(poly) == 1 and len(poly[0]) == 5: ringIn = poly[0] ringOut = [] ringOut.append(ringIn[0]) i = 1 for j in range(1, 5): v = QgsVector((ringIn[j] - ringIn[j - 1]) / 10.0) for k in range(9): ringOut.append(ringOut[i - 1] + v) i += 1 ringOut.append(ringIn[j]) i += 1 selectGeomTrans = QgsGeometry.fromPolygonXY([ringOut]) selectGeomTrans.transform(ct) except QgsCsException as e: QgsMessageLog.logMessage("Selection extends beyond layer's coordinate system") return newFeatures context = QgsRenderContext.fromMapSettings(self.canvas.mapSettings()) context.expressionContext().appendScope(QgsExpressionContextUtils.layerScope(layer)) r = None if layer.renderer(): r = layer.renderer().clone() r.startRender(context, layer.fields()) request = QgsFeatureRequest() request.setFilterRect(selectGeomTrans.boundingBox()) request.setFlags(QgsFeatureRequest.ExactIntersect) if r: request.setSubsetOfAttributes(r.usedAttributes(context), layer.fields()) else: request.setSubsetOfAttributes([]) closestFeatureId = 0 foundSingleFeature = False closestFeatureDist = sys.float_info.max for f in layer.getFeatures(request): context.expressionContext().setFeature(f) if r and not r.willRenderFeature(f, context): continue g = f.geometry() if contains: if not selectGeomTrans.contains(g): continue else: if not selectGeomTrans.intersects(g): continue if singleSelect: foundSingleFeature = True distance = g.distance(selectGeomTrans) if distance <= closestFeatureDist: closestFeatureDist = distance closestFeatureId = f.id() else: newFeatures.append(f.id()) if singleSelect and foundSingleFeature: newFeatures.append(closestFeatureId) if r: r.stopRender(context) return newFeatures
def setSelectFeatures(canvas, selectGeometry, doContains, doDifference, singleSelect=None): """ QgsMapCanvas* canvas, QgsGeometry* selectGeometry, bool doContains, bool doDifference, bool singleSelect """ if selectGeometry.type() != QGis.Polygon: return vlayer = getCurrentVectorLayer(canvas) if vlayer == None: return #toLayerCoordinates will throw an exception for any 'invalid' points in #the rubber band. #For example, if you project a world map onto a globe using EPSG 2163 #and then click somewhere off the globe, an exception will be thrown. selectGeomTrans = QgsGeometry(selectGeometry) if canvas.mapSettings().hasCrsTransformEnabled(): try: ct = QgsCoordinateTransform(canvas.mapSettings().destinationCrs(), vlayer.crs()) selectGeomTrans.transform(ct) except QgsCsException as cse: Q_UNUSED(cse) #catch exception for 'invalid' point and leave existing selection unchanged """ QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); QgisApp::instance()->messageBar()->pushMessage( QObject::tr( "CRS Exception" ), QObject::tr( "Selection extends beyond layer's coordinate system" ), QgsMessageBar::WARNING, QgisApp::instance()->messageTimeout() ); """ return QApplication.setOverrideCursor(Qt.WaitCursor) """ QgsDebugMsg( "Selection layer: " + vlayer->name() ); QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() ); QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) ); QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) ); """ context = QgsRenderContext().fromMapSettings(canvas.mapSettings()) r = vlayer.rendererV2() if r: r.startRender(context, vlayer.pendingFields()) request = QgsFeatureRequest() request.setFilterRect(selectGeomTrans.boundingBox()) request.setFlags(QgsFeatureRequest.ExactIntersect) if r: request.setSubsetOfAttributes(r.usedAttributes(), vlayer.pendingFields()) else: request.setSubsetOfAttributes(QgsAttributeList) fit = vlayer.getFeatures(request) newSelectedFeatures = [] #QgsFeatureIds f = QgsFeature() closestFeatureId = 0 #QgsFeatureId foundSingleFeature = False #double closestFeatureDist = std::numeric_limits<double>::max(); closestFeatureDist = sys.float_info.max while fit.nextFeature(f): # make sure to only use features that are visible if r and not r.willRenderFeature(f): continue g = QgsGeometry(f.geometry()) if doContains: if not selectGeomTrans.contains(g): continue else: if not selectGeomTrans.intersects(g): continue if singleSelect: foundSingleFeature = True distance = float(g.distance(selectGeomTrans)) if (distance <= closestFeatureDist): closestFeatureDist = distance closestFeatureId = f.id() else: newSelectedFeatures.insert(0, f.id()) if singleSelect and foundSingleFeature: newSelectedFeatures.insert(0, closestFeatureId) if r: r.stopRender(context) #QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) if doDifference: layerSelectedFeatures = vlayer.selectedFeaturesIds() selectedFeatures = [] #QgsFeatureIds deselectedFeatures = [] # QgsFeatureIds # i = QgsFeatureIds.const_iterator(newSelectedFeatures.constEnd()) # while i != newSelectedFeatures.constBegin(): # i = i - 1 # if layerSelectedFeatures.contains(i): # deselectedFeatures.insert(0, i) # else: # selectedFeatures.insert(0, i) for item in newSelectedFeatures: if item in layerSelectedFeatures: deselectedFeatures.insert(0, item) else: selectedFeatures.insert(0, item) vlayer.modifySelection(selectedFeatures, deselectedFeatures) else: vlayer.setSelectedFeatures(newSelectedFeatures) QApplication.restoreOverrideCursor() """