def canvasReleaseEvent(self, e): super(MapToolInteractive, self).canvasReleaseEvent(e) e.ignore() if (e.button() == Qt.LeftButton): if self._dragging: # Pan map mode self.canvas().panActionEnd(e.pos()) self.setCursor(CapturePointCursor) self._dragging = False e.accept() elif (e.button() == Qt.RightButton): if self._dragging: # Zoom mode self._zoomRect.setBottomRight(e.pos()) if (self._zoomRect.topLeft() != self._zoomRect.bottomRight()): coordinateTransform = self.canvas().getCoordinateTransform( ) ll = coordinateTransform.toMapCoordinates( self._zoomRect.left(), self._zoomRect.bottom()) ur = coordinateTransform.toMapCoordinates( self._zoomRect.right(), self._zoomRect.top()) r = QgsRectangle() r.setXMinimum(ll.x()) r.setYMinimum(ll.y()) r.setXMaximum(ur.x()) r.setYMaximum(ur.y()) r.normalize() if (r.width() != 0 and r.height() != 0): self.canvas().setExtent(r) self.canvas().refresh() self._dragging = False if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None e.accept()
def _getFeatures(self): """Identify objects under the mouse, having actions""" searchRadius = self.searchRadiusMU(self.canvas) point = self.toMapCoordinates(self.__pos) features = [] rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) for layer in self.canvas.layers(): # treat only vector layers having actions if (layer.type() == QgsMapLayer.VectorLayer and len(layer.actions().actions()) > 0): layerRect = self.toLayerCoordinates(layer, rect) self.request.setFilterRect(layerRect) for feature in layer.getFeatures(layerRect if ( layer.dataProvider().name() == "WFS" ) else self.request): features.append({"layer": layer, "feature": feature}) return features
def getClickBbox(self, thePoint): """ Get a tiny bbox around a mouse click. Args: Point object. Returns: Tiny QgsRectangle bbox around point. Raises: CoordinateProcessingException if bbox creation encounters error. """ # get the xy coords #QMessageBox.information(None, 'VF', str(thePoint)) myX = thePoint.x() myY = thePoint.y() myUnitsPerPixel = self.canvas.mapUnitsPerPixel() # create a little bbox from clicked coords try: myBbox = QgsRectangle() myBbox.setXMinimum(myX - myUnitsPerPixel) myBbox.setYMinimum(myY - myUnitsPerPixel) myBbox.setXMaximum(myX + myUnitsPerPixel) myBbox.setYMaximum(myY + myUnitsPerPixel) #QMessageBox.information(None, 'VF', myBbox.toString()) return myBbox except: msg = 'Click coordinates could not be processed.' raise ex.CoordinateProcessingException(msg)
def withinBoundary(layer, point, featureId, closestFeature): # find the furthest bounding box borders closestFeature = layer.getFeatures(QgsFeatureRequest(featureId)).next() rect = closestFeature.geometry().boundingBox() dist_pX_rXmax = abs(point.x() - rect.xMaximum()) dist_pX_rXmin = abs(point.x() - rect.xMinimum()) if dist_pX_rXmax > dist_pX_rXmin: width = dist_pX_rXmax else: width = dist_pX_rXmin dist_pY_rYmax = abs(point.y() - rect.yMaximum()) dist_pY_rYmin = abs(point.y() - rect.yMinimum()) if dist_pY_rYmax > dist_pY_rYmin: height = dist_pY_rYmax else: height = dist_pY_rYmin # create the search rectangle rect = QgsRectangle() rect.setXMinimum(point.x() - width) rect.setXMaximum(point.x() + width) rect.setYMinimum(point.y() - height) rect.setYMaximum(point.y() + height) # retrieve all geometries into the search rectangle iter2 = layer.getFeatures(QgsFeatureRequest(rect)) # find the nearest feature minDist = -1 featureId = None point = QgsGeometry.fromPointXY(point) f = QgsFeature() while iter2.nextFeature(f): geom = f.geometry() distance = geom.distance(point) if minDist < 0 or distance < minDist: minDist = distance featureId = f.id() # get the closest feature try: closestFeature = layer.getFeatures(QgsFeatureRequest(featureId)).next() if featureId is None or layer.getFeatures( QgsFeatureRequest(featureId)).next(f) is False: closestFeature = None except: f = QgsFeature() closestFeature = layer.getFeatures( QgsFeatureRequest(featureId)).nextFeature(f) closestFeature = f if featureId is None or layer.getFeatures( QgsFeatureRequest(featureId)).nextFeature(f) is False: closestFeature = None return closestFeature
def toSearchRect(self, point): searchRadius = self.canvas.extent().width() * ( self.radius / 100.0 ) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) return rect
def toSearchRect(self, point): searchRadius = self.canvas.extent().width() * (self.radius / 100.0) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) return rect
def testRasterBlock(self): """Test raster block with extent""" path = os.path.join(unitTestDataPath(), 'landsat_4326.tif') raster_layer = QgsRasterLayer(path, 'test') self.assertTrue(raster_layer.isValid()) extent = QgsRectangle(17.94284482577178252, 30.23021770271909503, 17.94407867909909626, 30.23154272264058307) block = raster_layer.dataProvider().block(1, extent, 2, 3) self.checkBlockContents(block, [ 125.0, 125.0, 125.0, 125.0, 125.0, 124.0, ]) full_content = [ 125.0, 125.0, 125.0, 125.0, 125.0, 125.0, 125.0, 124.0, 125.0, 126.0, 127.0, 127.0, ] extent = raster_layer.extent() block = raster_layer.dataProvider().block(1, extent, 3, 4) self.checkBlockContents(block, full_content) extent = raster_layer.extent() extent.grow(-0.0001) block = raster_layer.dataProvider().block(1, extent, 3, 4) self.checkBlockContents(block, full_content) row_height = raster_layer.extent().height() / raster_layer.height() for row in range(raster_layer.height()): extent = raster_layer.extent() extent.setYMaximum(extent.yMaximum() - row_height * row) extent.setYMinimum(extent.yMaximum() - row_height) block = raster_layer.dataProvider().block(1, extent, 3, 1) self.checkBlockContents(block, full_content[row * 3:row * 3 + 3])
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) if self.layerto.geometryType() == QGis.Point: newfeature.setGeometry(QgsGeometry.fromPoint(point)) else: newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] passed, message = self.validation_method(feature=newfeature, layerto=self.layerto) if passed: self.finished.emit(self.layerto, newfeature) else: self.band.reset() self.error.emit(message) except StopIteration: pass
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) # Look for an existing feature first. If there is one # then we emit that back to qmap. try: feature = self.layerto.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerto) self.finished.emit(self.layerto, feature) return except StopIteration: pass try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] self.finished.emit(self.layerto, newfeature) except StopIteration: pass
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) # Look for an existing feature first. If there is one # then we emit that back to qmap. try: feature = self.layerto.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerto) self.finished.emit(self.layerto, feature) return except StopIteration: pass try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx ) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] self.finished.emit(self.layerto, newfeature) except StopIteration: pass
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) if self.layerto.geometryType() == QGis.Point: newfeature.setGeometry(QgsGeometry.fromPoint(point)) else: newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx ) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] passed, message = self.validation_method(feature=newfeature, layerto=self.layerto) if passed: self.finished.emit(self.layerto, newfeature) else: self.band.reset() self.error.emit(message) except StopIteration: pass
def canvasPressEvent(self, e): layer = config.iface.activeLayer() if layer is None or not isinstance(layer, QgsVectorLayer): config.iface.messageBar().pushMessage("No layer selected or the current active layer is not a valid vector layer", level = QgsMessageBar.WARNING, duration = 5) return if not layertracking.isRepoLayer(layer): config.iface.messageBar().pushMessage("The current active layer is not being tracked as part of a GeoGig repo", level = QgsMessageBar.WARNING, duration = 5) return trackedlayer = layertracking.getTrackingInfo(layer) point = self.toMapCoordinates(e.pos()) searchRadius = self.canvas().extent().width() * .01; r = QgsRectangle() r.setXMinimum(point.x() - searchRadius); r.setXMaximum(point.x() + searchRadius); r.setYMinimum(point.y() - searchRadius); r.setYMaximum(point.y() + searchRadius); r = self.toLayerCoordinates(layer, r); fit = layer.getFeatures(QgsFeatureRequest().setFilterRect(r).setFlags(QgsFeatureRequest.ExactIntersect)); fid = None try: feature = next(fit) fid = feature.id() fid = geogigFidFromGpkgFid(trackedlayer, fid) if fid is None: return except StopIteration as e: return repo = Repository(trackedlayer.repoUrl) menu = QMenu() versionsAction = QAction("Show all versions of this feature...", None) versionsAction.triggered.connect(lambda: self.versions(repo, trackedlayer.layername, fid)) menu.addAction(versionsAction) blameAction = QAction("Show authorship...", None) blameAction.triggered.connect(lambda: self.blame(repo, trackedlayer.layername, fid)) menu.addAction(blameAction) point = config.iface.mapCanvas().mapToGlobal(e.pos()) menu.exec_(point)
def getFeatures(self, point): searchRadius = (QgsTolerance.toleranceInMapUnits( self.radius, self.layers[0], self.canvas.mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) self.band.reset() for layer in self.layers: rq = QgsFeatureRequest().setFilterRect(rect) for feature in layer.getFeatures(rq): if feature.isValid(): yield feature, layer
def canvasPressEvent(self, event): """ Override of QgsMapTool mouse press event """ if event.button() == Qt.LeftButton and not self.mCtrl: if self.band: self.band.hide() self.band = None self.feature = None logger.info("layer feature count {}".format(self.layer.featureCount())) if not self.layer: return logger.info("Trying to find feature in layer") point = self.toLayerCoordinates(self.layer, event.pos()) search_radius = (QgsTolerance.toleranceInMapUnits(10, self.layer, self.canvas().mapSettings(), QgsTolerance.Pixels)) rect = QgsRectangle() rect.setXMinimum(point.x() - search_radius) rect.setXMaximum(point.x() + search_radius) rect.setYMinimum(point.y() - search_radius) rect.setYMaximum(point.y() + search_radius) rq = QgsFeatureRequest().setFilterRect(rect) f = QgsFeature() self.layer.getFeatures(rq).nextFeature(f) if f.geometry(): self.band = self.create_rubber_band() self.band.setToGeometry(f.geometry(), self.layer) self.band.show() self.startcoord = self.toMapCoordinates(event.pos()) self.feature = f self.clicked_outside_layer = False return else: self.clicked_outside_layer = True
def _getFeatures(self): """Identify objects under the mouse, having actions """ searchRadius = self.searchRadiusMU(self.canvas) point = self.toMapCoordinates(self.__pos) features = [] rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) for layer in self.canvas.layers(): # treat only vector layers having actions if layer.type() == QgsMapLayer.VectorLayer and len(layer.actions().actions()) > 0: self.request.setFilterRect(self.toLayerCoordinates(layer, rect)) for feature in layer.getFeatures(self.request): features.append({"layer":layer, "feature":feature}) return features
def canvasPressEvent(self, e): layer = iface.activeLayer() if layer is None or not isinstance(layer, QgsVectorLayer): iface.messageBar().pushMessage( "No layer selected or the current active layer is not a valid vector layer", level=Qgis.Warning, duration=5) return geogiglayer = getWrappingGeogigLayer(layer) if geogiglayer is None: iface.messageBar().pushMessage( "The current active layer is not being tracked as part of a GeoGig repo", level=Qgis.Warning, duration=5) return point = self.toMapCoordinates(e.pos()) searchRadius = self.canvas().extent().width() * .01 r = QgsRectangle() r.setXMinimum(point.x() - searchRadius) r.setXMaximum(point.x() + searchRadius) r.setYMinimum(point.y() - searchRadius) r.setYMaximum(point.y() + searchRadius) r = self.toLayerCoordinates(layer, r) fit = layer.getFeatures(QgsFeatureRequest().setFilterRect(r).setFlags( QgsFeatureRequest.ExactIntersect)) fid = None try: feature = next(fit) fid = feature[GEOGIGID_FIELD] if fid is None: return except StopIteration as e: return self.versions(geogiglayer, fid)
def show_tip(self, point): rectangle = QgsRectangle() radius = self.canvas.extent().width() / 100 * 5 # 5% of the map width rectangle.setXMinimum(point.x() - radius) rectangle.setYMinimum(point.y() - radius) rectangle.setXMaximum(point.x() + radius) rectangle.setYMaximum(point.y() + radius) layer_rectangle = self.canvas.mapRenderer().mapToLayerCoordinates( self.catalogue_layer, rectangle) features = self.catalogue_layer.getFeatures( QgsFeatureRequest().setFilterRect(layer_rectangle)) # assume the first one is the closest try: feat = features.next() msg_lines = ["Event Found"] for k in self.catalogue_model.catalogue_keys(): msg_lines.append("%s=%s" % (k, feat[k])) except StopIteration: msg_lines = ["No Event found"] if self.raster_layer is not None: src = self.basemap_layer.crs() dst = QgsCoordinateReferenceSystem(4326) trans = QgsCoordinateTransform(src, dst) point = trans.transform(point) raster_data = self.raster_layer.dataProvider().identify( point, QgsRaster.IdentifyFormatValue) for k, v in raster_data.results().items(): msg_lines.append("Smoothed=%s" % str(v)) utils.alert('\n'.join(msg_lines))
def run(bar, layer1_path, layer2_path, obstacles_path, research_ray): output = {} #layer1 receiver layer1 = QgsVectorLayer(layer1_path, "layer1", "ogr") #layer 2 source layer2 = QgsVectorLayer(layer2_path, "layer2", "ogr") layer2_feat_all_dict = {} layer2_feat_all = layer2.dataProvider().getFeatures() layer2_spIndex = QgsSpatialIndex() for layer2_feat in layer2_feat_all: layer2_spIndex.insertFeature(layer2_feat) layer2_feat_all_dict[layer2_feat.id()] = layer2_feat if obstacles_path is not None: obstacles_layer = QgsVectorLayer(obstacles_path, "obstacles", "ogr") obstacles_feat_all = obstacles_layer.dataProvider().getFeatures() obstacles_spIndex = QgsSpatialIndex() obstacles_feat_all_dict = {} for obstacles_feat in obstacles_feat_all: obstacles_spIndex.insertFeature(obstacles_feat) obstacles_feat_all_dict[obstacles_feat.id()] = obstacles_feat layer1_feat_all = layer1.dataProvider().getFeatures() layer1_feat_total = layer1.dataProvider().featureCount() layer1_feat_number = 0 for layer1_feat in layer1_feat_all: layer1_feat_number = layer1_feat_number + 1 barValue = layer1_feat_number / float(layer1_feat_total) * 100 bar.setValue(barValue) # researches the layer2 points in a rectangle created by the research_ray # creates the search rectangle rect = QgsRectangle() rect.setXMinimum(layer1_feat.geometry().asPoint().x() - research_ray) rect.setXMaximum(layer1_feat.geometry().asPoint().x() + research_ray) rect.setYMinimum(layer1_feat.geometry().asPoint().y() - research_ray) rect.setYMaximum(layer1_feat.geometry().asPoint().y() + research_ray) layer2_request = layer2_spIndex.intersects(rect) layer2_points = [] for layer2_id in layer2_request: layer2_feat = layer2_feat_all_dict[layer2_id] ray_to_test_length = compute_distance( layer1_feat.geometry().asPoint(), layer2_feat.geometry().asPoint()) if ray_to_test_length <= research_ray: ray_to_test = QgsGeometry.fromPolylineXY([ layer1_feat.geometry().asPoint(), layer2_feat.geometry().asPoint() ]) intersect = 0 if obstacles_path is not None: obstacles_request = obstacles_spIndex.intersects( ray_to_test.boundingBox()) for obstacles_id in obstacles_request: if obstacles_feat_all_dict[obstacles_id].geometry( ).crosses(ray_to_test) == 1: intersect = 1 break if intersect == 0: layer2_points.append(layer2_feat.id()) output[layer1_feat.id()] = layer2_points return output
def run_selection_distance(bar, layer1_path, layer2_path, obstacles_path, research_ray, dict_selection_layer2TOlayer3, layer3_path): '''runs only in the selection dict and check the distance also with the selection dict rays''' output = {} layer1 = QgsVectorLayer(layer1_path, "layer1", "ogr") layer2 = QgsVectorLayer(layer2_path, "layer2", "ogr") layer2_feat_all_dict = {} layer2_feat_all = layer2.dataProvider().getFeatures() layer2_spIndex = QgsSpatialIndex() for layer2_feat in layer2_feat_all: layer2_spIndex.insertFeature(layer2_feat) layer2_feat_all_dict[layer2_feat.id()] = layer2_feat if obstacles_path is not None: obstacles_layer = QgsVectorLayer(obstacles_path, "obstacles", "ogr") obstacles_feat_all = obstacles_layer.dataProvider().getFeatures() obstacles_spIndex = QgsSpatialIndex() obstacles_feat_all_dict = {} for obstacles_feat in obstacles_feat_all: obstacles_spIndex.insertFeature(obstacles_feat) obstacles_feat_all_dict[obstacles_feat.id()] = obstacles_feat layer3 = QgsVectorLayer(layer3_path, "layer3", "ogr") layer3_feat_all = layer3.dataProvider().getFeatures() layer3_feat_all_dict = {} for layer3_feat in layer3_feat_all: layer3_feat_all_dict[layer3_feat.id()] = layer3_feat layer1_feat_all = layer1.dataProvider().getFeatures() layer1_feat_total = layer1.dataProvider().featureCount() layer1_feat_number = 0 for layer1_feat in layer1_feat_all: layer1_feat_number = layer1_feat_number + 1 barValue = layer1_feat_number / float(layer1_feat_total) * 100 bar.setValue(barValue) # researches the layer2 points in a rectangle created by the research_ray # creates the search rectangle rect = QgsRectangle() rect.setXMinimum(layer1_feat.geometry().asPoint().x() - research_ray) rect.setXMaximum(layer1_feat.geometry().asPoint().x() + research_ray) rect.setYMinimum(layer1_feat.geometry().asPoint().y() - research_ray) rect.setYMaximum(layer1_feat.geometry().asPoint().y() + research_ray) layer2_request = layer2_spIndex.intersects(rect) layer2_points = [] for layer2_id in layer2_request: if layer2_id in dict_selection_layer2TOlayer3: layer2_feat = layer2_feat_all_dict[layer2_id] ray_to_test_length = compute_distance( layer1_feat.geometry().asPoint(), layer2_feat.geometry().asPoint()) distance_layer2_layer3 = [] min_distance_layer2_layer3 = research_ray for layer3_id in dict_selection_layer2TOlayer3[layer2_id]: layer3_feat = layer3_feat_all_dict[layer3_id] ray_layer2_layer3 = compute_distance( layer2_feat.geometry().asPoint(), layer3_feat.geometry().asPoint()) if ray_layer2_layer3 < min_distance_layer2_layer3: min_distance_layer2_layer3 = ray_layer2_layer3 if min_distance_layer2_layer3 + ray_to_test_length <= research_ray: ray_to_test = QgsGeometry.fromPolyline([ layer1_feat.geometry().asPoint(), layer2_feat.geometry().asPoint() ]) intersect = 0 if obstacles_path is not None: obstacles_request = obstacles_spIndex.intersects( ray_to_test.boundingBox()) for obstacles_id in obstacles_request: if obstacles_feat_all_dict[obstacles_id].geometry( ).crosses(ray_to_test) == 1: intersect = 1 break if intersect == 0: layer2_points.append(layer2_feat.id()) output[layer1_feat.id()] = layer2_points return output
def middle(bar, buildings_layer_path, receiver_points_layer_path): buildings_layer_name = os.path.splitext( os.path.basename(buildings_layer_path))[0] buildings_layer = QgsVectorLayer(buildings_layer_path, buildings_layer_name, "ogr") # defines emission_points layer receiver_points_fields = QgsFields() receiver_points_fields.append(QgsField("id_pt", QVariant.Int)) receiver_points_fields.append(QgsField("id_bui", QVariant.Int)) receiver_points_writer = QgsVectorFileWriter(receiver_points_layer_path, "System", receiver_points_fields, QgsWkbTypes.Point, buildings_layer.crs(), "ESRI Shapefile") # gets features from layer buildings_feat_all = buildings_layer.dataProvider().getFeatures() # creates SpatialIndex buildings_spIndex = QgsSpatialIndex() buildings_feat_all_dict = {} for buildings_feat in buildings_feat_all: buildings_spIndex.insertFeature(buildings_feat) buildings_feat_all_dict[buildings_feat.id()] = buildings_feat # defines distanze_point distance_point = 0.1 # re-gets features from layer buildings_feat_all = buildings_layer.dataProvider().getFeatures() buildings_feat_total = buildings_layer.dataProvider().featureCount() pt_id = 0 buildings_feat_number = 0 for buildings_feat in buildings_feat_all: buildings_feat_number = buildings_feat_number + 1 barValue = buildings_feat_number / float(buildings_feat_total) * 100 bar.setValue(barValue) building_geom = buildings_feat.geometry() if building_geom.isMultipart(): buildings_pt = building_geom.asMultiPolygon()[0] #building_geom.convertToSingleType() else: buildings_pt = buildings_feat.geometry().asPolygon() # creates the search rectangle to match the receiver point in the building and del them rect = QgsRectangle() rect.setXMinimum(buildings_feat.geometry().boundingBox().xMinimum() - distance_point) rect.setXMaximum(buildings_feat.geometry().boundingBox().xMaximum() + distance_point) rect.setYMinimum(buildings_feat.geometry().boundingBox().yMinimum() - distance_point) rect.setYMaximum(buildings_feat.geometry().boundingBox().yMaximum() + distance_point) buildings_selection = buildings_spIndex.intersects(rect) if len(buildings_pt) > 0: for i in range(0, len(buildings_pt)): buildings_pts = buildings_pt[i] #### # start part to delete pseudo vertex # this part it's different from the diffraction delete pseudo vertex part pts_index_to_delete_list = [] m_delta = 0.01 for ii in range(0, len(buildings_pts) - 1): x1 = buildings_pts[ii - 1][0] x2 = buildings_pts[ii][0] x3 = buildings_pts[ii + 1][0] y1 = buildings_pts[ii - 1][1] y2 = buildings_pts[ii][1] y3 = buildings_pts[ii + 1][1] # particular cases: first point to delete! (remember that the first and the last have the same coordinates) if ii == 0 and (x2 == x1 and y2 == y1): x1 = buildings_pts[ii - 2][0] y1 = buildings_pts[ii - 2][1] # angular coefficient to find pseudo vertex if x2 - x1 != 0 and x3 - x1 != 0: m1 = (y2 - y1) / (x2 - x1) m2 = (y3 - y1) / (x3 - x1) #if round(m1,2) <= round(m2,2) + m_delta and round(m1,2) >= round(m2,2) - m_delta: if m1 <= m2 + m_delta and m1 >= m2 - m_delta: pts_index_to_delete_list.append(ii) # particular cases: first point to delete! (remember that the first and the last have the same coordinates) # here we delete the last and add x3,y3 (buildings_pts[ii+1] - the new last point) if ii == 0: pts_index_to_delete_list.append( len(buildings_pts) - 1) buildings_pts.append(buildings_pts[ii + 1]) # del pseudo vertex pts_index_to_delete_list = sorted(pts_index_to_delete_list, reverse=True) for pt_index_to_del in pts_index_to_delete_list: del buildings_pts[pt_index_to_del] # end part to delete pseudo vertex # for to generate receiver points for ii in range(0, len(buildings_pts) - 1): x1 = buildings_pts[ii][0] x2 = buildings_pts[ii + 1][0] y1 = buildings_pts[ii][1] y2 = buildings_pts[ii + 1][1] xm = (x1 + x2) / 2 ym = (y1 + y2) / 2 if y2 == y1: dx = 0 dy = distance_point elif x2 == x1: dx = distance_point dy = 0 else: m = (y2 - y1) / (x2 - x1) m_p = -1 / m dx = sqrt((distance_point**2) / (1 + m_p**2)) dy = sqrt( ((distance_point**2) * (m_p**2)) / (1 + m_p**2)) if (x2 >= x1 and y2 >= y1) or (x2 < x1 and y2 < y1): pt1 = QgsPointXY(xm + dx, ym - dy) pt2 = QgsPointXY(xm - dx, ym + dy) if (x2 >= x1 and y2 < y1) or (x2 < x1 and y2 >= y1): pt1 = QgsPointXY(xm + dx, ym + dy) pt2 = QgsPointXY(xm - dx, ym - dy) pt = QgsFeature() # pt1, check if is in a building and eventually add it pt.setGeometry(QgsGeometry.fromPointXY(pt1)) intersect = 0 for buildings_id in buildings_selection: if buildings_feat_all_dict[buildings_id].geometry( ).intersects(pt.geometry()) == 1: intersect = 1 break if intersect == 0: pt.setAttributes([pt_id, buildings_feat.id()]) receiver_points_writer.addFeature(pt) pt_id = pt_id + 1 # pt2, check if is in a building and eventually add it pt.setGeometry(QgsGeometry.fromPointXY(pt2)) intersect = 0 for buildings_id in buildings_selection: if buildings_feat_all_dict[buildings_id].geometry( ).intersects(pt.geometry()) == 1: intersect = 1 break if intersect == 0: pt.setAttributes([pt_id, buildings_feat.id()]) receiver_points_writer.addFeature(pt) pt_id = pt_id + 1 del receiver_points_writer #print receiver_points_layer_path receiver_points_layer_name = os.path.splitext( os.path.basename(receiver_points_layer_path))[0] #print receiver_points_layer_name receiver_points_layer = QgsVectorLayer(receiver_points_layer_path, str(receiver_points_layer_name), "ogr") QgsProject.instance().addMapLayers([receiver_points_layer])
def run_selection_distance(bar,layer1_path,layer2_path,obstacles_path,research_ray,dict_selection_layer2TOlayer3,layer3_path): '''runs only in the selection dict and check the distance also with the selection dict rays''' output = {} layer1 = QgsVectorLayer(layer1_path,"layer1","ogr") layer2 = QgsVectorLayer(layer2_path,"layer2","ogr") layer2_feat_all_dict = {} layer2_feat_all = layer2.dataProvider().getFeatures() layer2_spIndex = QgsSpatialIndex() for layer2_feat in layer2_feat_all: layer2_spIndex.insertFeature(layer2_feat) layer2_feat_all_dict[layer2_feat.id()] = layer2_feat if obstacles_path is not None: obstacles_layer = QgsVectorLayer(obstacles_path,"obstacles","ogr") obstacles_feat_all = obstacles_layer.dataProvider().getFeatures() obstacles_spIndex = QgsSpatialIndex() obstacles_feat_all_dict = {} for obstacles_feat in obstacles_feat_all: obstacles_spIndex.insertFeature(obstacles_feat) obstacles_feat_all_dict[obstacles_feat.id()] = obstacles_feat layer3 = QgsVectorLayer(layer3_path,"layer3","ogr") layer3_feat_all = layer3.dataProvider().getFeatures() layer3_feat_all_dict = {} for layer3_feat in layer3_feat_all: layer3_feat_all_dict[layer3_feat.id()] = layer3_feat layer1_feat_all = layer1.dataProvider().getFeatures() layer1_feat_total = layer1.dataProvider().featureCount() layer1_feat_number = 0 for layer1_feat in layer1_feat_all: layer1_feat_number = layer1_feat_number + 1 barValue = layer1_feat_number/float(layer1_feat_total)*100 bar.setValue(barValue) # researches the layer2 points in a rectangle created by the research_ray # creates the search rectangle rect = QgsRectangle() rect.setXMinimum( layer1_feat.geometry().asPoint().x() - research_ray ) rect.setXMaximum( layer1_feat.geometry().asPoint().x() + research_ray ) rect.setYMinimum( layer1_feat.geometry().asPoint().y() - research_ray ) rect.setYMaximum( layer1_feat.geometry().asPoint().y() + research_ray ) layer2_request = layer2_spIndex.intersects(rect) layer2_points = [] for layer2_id in layer2_request: if layer2_id in dict_selection_layer2TOlayer3: layer2_feat = layer2_feat_all_dict[layer2_id] ray_to_test_length = compute_distance(layer1_feat.geometry().asPoint(),layer2_feat.geometry().asPoint()) distance_layer2_layer3 = [] min_distance_layer2_layer3 = research_ray for layer3_id in dict_selection_layer2TOlayer3[layer2_id]: layer3_feat = layer3_feat_all_dict[layer3_id] ray_layer2_layer3 = compute_distance(layer2_feat.geometry().asPoint(),layer3_feat.geometry().asPoint()) if ray_layer2_layer3 < min_distance_layer2_layer3: min_distance_layer2_layer3 = ray_layer2_layer3 if min_distance_layer2_layer3 + ray_to_test_length <= research_ray: ray_to_test = QgsGeometry.fromPolyline( [ layer1_feat.geometry().asPoint() , layer2_feat.geometry().asPoint() ] ) intersect = 0 if obstacles_path is not None: obstacles_request = obstacles_spIndex.intersects(ray_to_test.boundingBox()) for obstacles_id in obstacles_request: if obstacles_feat_all_dict[obstacles_id].geometry().crosses(ray_to_test) == 1: intersect = 1 break if intersect == 0: layer2_points.append(layer2_feat.id()) output[layer1_feat.id()] = layer2_points return output
def spaced(bar, buildings_layer_path, receiver_points_layer_path, spaced_pts_distance): distance_from_facades = 0.1 buildings_layer_name = os.path.splitext( os.path.basename(buildings_layer_path))[0] buildings_layer = QgsVectorLayer(buildings_layer_path, buildings_layer_name, "ogr") # cp building layer to delete all fields buildings_memory_layer = QgsVectorLayer( "Polygon?crs=" + str(buildings_layer.crs().authid()), "polygon_memory_layer", "memory") buildings_memory_layer.dataProvider().addAttributes([]) buildings_feat_all = buildings_layer.dataProvider().getFeatures() buildings_feat_list = [] for buildings_feat in buildings_feat_all: buildings_feat_list.append(buildings_feat) buildings_memory_layer.dataProvider().addFeatures(buildings_feat_list) buildings_memory_layer.updateExtents() # this is crazy: I had to addd this line otherwise the first processing doesn't work... QgsProject.instance().addMapLayers([buildings_memory_layer]) bar.setValue(1) # this processing alg has as output['OUTPUT'] the layer output = processing.run( "native:buffer", { 'INPUT': buildings_memory_layer, 'DISTANCE': distance_from_facades, 'DISSOLVE': False, 'OUTPUT': 'memory:' }) # I can now remove the layer from map... QgsProject.instance().removeMapLayers([buildings_memory_layer.id()]) bar.setValue(25) # this processing alg has as output['OUTPUT'] the layer output = processing.run("qgis:polygonstolines", { 'INPUT': output['OUTPUT'], 'OUTPUT': 'memory:' }) bar.setValue(50) # this processing alg has as output['output'] the layer path... poly_to_lines = output['OUTPUT'] output = processing.run( "qgis:pointsalonglines", { 'INPUT': poly_to_lines, 'DISTANCE': spaced_pts_distance, 'START_OFFSET': 0, 'END_OFFSET': 0, 'OUTPUT': 'memory:' }) bar.setValue(75) receiver_points_memory_layer = output['OUTPUT'] del output ## Delete pts in buildings # creates SpatialIndex buildings_feat_all = buildings_layer.dataProvider().getFeatures() buildings_spIndex = QgsSpatialIndex() buildings_feat_all_dict = {} for buildings_feat in buildings_feat_all: buildings_spIndex.insertFeature(buildings_feat) buildings_feat_all_dict[buildings_feat.id()] = buildings_feat receiver_points_memory_layer_all = receiver_points_memory_layer.dataProvider( ).getFeatures() receiver_points_layer_fields = QgsFields() receiver_points_layer_fields.append(QgsField("id_pt", QVariant.Int)) receiver_points_layer_fields.append(QgsField("id_bui", QVariant.Int)) receiver_points_layer_writer = QgsVectorFileWriter( receiver_points_layer_path, "System", receiver_points_layer_fields, QgsWkbTypes.Point, buildings_layer.crs(), "ESRI Shapefile") receiver_points_feat_id = 0 receiver_memory_feat_total = receiver_points_memory_layer.dataProvider( ).featureCount() receiver_memory_feat_number = 0 for receiver_memory_feat in receiver_points_memory_layer_all: receiver_memory_feat_number = receiver_memory_feat_number + 1 barValue = receiver_memory_feat_number / float( receiver_memory_feat_total) * 25 + 75 bar.setValue(barValue) rect = QgsRectangle() rect.setXMinimum(receiver_memory_feat.geometry().asPoint().x() - distance_from_facades) rect.setXMaximum(receiver_memory_feat.geometry().asPoint().x() + distance_from_facades) rect.setYMinimum(receiver_memory_feat.geometry().asPoint().y() - distance_from_facades) rect.setYMaximum(receiver_memory_feat.geometry().asPoint().y() + distance_from_facades) buildings_selection = buildings_spIndex.intersects(rect) to_add = True receiver_geom = receiver_memory_feat.geometry() building_id_correct = None for buildings_id in buildings_selection: building_geom = buildings_feat_all_dict[buildings_id].geometry() intersectBuilding = QgsGeometry.intersects(receiver_geom, building_geom) building_id_correct = buildings_id if intersectBuilding: to_add = False building_id_correct = None break # picking the nearest building to the receiver point analysed nearestIds = buildings_spIndex.nearestNeighbor(receiver_geom.asPoint(), 1) building_fid = [] for featureId in nearestIds: request = QgsFeatureRequest().setFilterFid(featureId) for feature in buildings_layer.getFeatures(request): dist = receiver_geom.distance(feature.geometry()) building_fid.append((dist, feature.id())) building_fid_correct = min(building_fid, key=lambda x: x[0])[-1] if to_add: attributes = [receiver_points_feat_id, building_fid_correct] fet = QgsFeature() fet.setGeometry(receiver_memory_feat.geometry()) fet.setAttributes(attributes) receiver_points_layer_writer.addFeature(fet) receiver_points_feat_id = receiver_points_feat_id + 1 del receiver_points_layer_writer receiver_points_layer_name = os.path.splitext( os.path.basename(receiver_points_layer_path))[0] receiver_points_layer = QgsVectorLayer(receiver_points_layer_path, str(receiver_points_layer_name), "ogr") QgsProject.instance().addMapLayers([receiver_points_layer]) QgsProject.instance().reloadAllLayers()
class HeatmapPixelSizeWidget(BASE, WIDGET): def __init__(self): super(HeatmapPixelSizeWidget, self).__init__(None) self.setupUi(self) self.layer_bounds = QgsRectangle() self.layer = None self.raster_bounds = QgsRectangle() self.radius = 100 self.radius_field = None self.mCellXSpinBox.setShowClearButton(False) self.mCellYSpinBox.setShowClearButton(False) self.mRowsSpinBox.setShowClearButton(False) self.mColumnsSpinBox.setShowClearButton(False) self.mCellYSpinBox.valueChanged.connect(self.mCellXSpinBox.setValue) self.mCellXSpinBox.valueChanged.connect(self.pixelSizeChanged) self.mRowsSpinBox.valueChanged.connect(self.rowsChanged) self.mColumnsSpinBox.valueChanged.connect(self.columnsChanged) def setRadius(self, radius): self.radius = radius self.recalculate_bounds() def setRadiusField(self, radius_field): self.radius_field = radius_field self.recalculate_bounds() def setLayer(self, layer): if not layer: return bounds = layer.extent() if bounds.isNull(): return self.layer = layer self.layer_bounds = bounds self.recalculate_bounds() def recalculate_bounds(self): self.raster_bounds = QgsRectangle(self.layer_bounds) if not self.layer: return max_radius = self.radius if self.radius_field: idx = self.layer.fields().lookupField(self.radius_field) try: max_radius = float(self.layer.maximumValue(idx)) except: pass self.raster_bounds.setXMinimum(self.raster_bounds.xMinimum() - max_radius) self.raster_bounds.setYMinimum(self.raster_bounds.yMinimum() - max_radius) self.raster_bounds.setXMaximum(self.raster_bounds.xMaximum() + max_radius) self.raster_bounds.setYMaximum(self.raster_bounds.yMaximum() + max_radius) self.pixelSizeChanged() def pixelSizeChanged(self): cell_size = self.mCellXSpinBox.value() if cell_size <= 0: return self.mCellYSpinBox.blockSignals(True) self.mCellYSpinBox.setValue(cell_size) self.mCellYSpinBox.blockSignals(False) rows = max(round(self.raster_bounds.height() / cell_size) + 1, 1) cols = max(round(self.raster_bounds.width() / cell_size) + 1, 1) self.mRowsSpinBox.blockSignals(True) self.mRowsSpinBox.setValue(rows) self.mRowsSpinBox.blockSignals(False) self.mColumnsSpinBox.blockSignals(True) self.mColumnsSpinBox.setValue(cols) self.mColumnsSpinBox.blockSignals(False) def rowsChanged(self): rows = self.mRowsSpinBox.value() if rows <= 0: return cell_size = self.raster_bounds.height() / rows cols = max(round(self.raster_bounds.width() / cell_size) + 1, 1) self.mColumnsSpinBox.blockSignals(True) self.mColumnsSpinBox.setValue(cols) self.mColumnsSpinBox.blockSignals(False) for w in [self.mCellXSpinBox, self.mCellYSpinBox]: w.blockSignals(True) w.setValue(cell_size) w.blockSignals(False) def columnsChanged(self): cols = self.mColumnsSpinBox.value() if cols < 2: return cell_size = self.raster_bounds.width() / (cols - 1) rows = max(round(self.raster_bounds.height() / cell_size), 1) self.mRowsSpinBox.blockSignals(True) self.mRowsSpinBox.setValue(rows) self.mRowsSpinBox.blockSignals(False) for w in [self.mCellXSpinBox, self.mCellYSpinBox]: w.blockSignals(True) w.setValue(cell_size) w.blockSignals(False) def setValue(self, value): try: numeric_value = float(value) except: return False self.mCellXSpinBox.setValue(numeric_value) self.mCellYSpinBox.setValue(numeric_value) return True def value(self): return self.mCellXSpinBox.value()
def run(bar,layer1_path,layer2_path,obstacles_path,research_ray): output = {} #layer1 receiver layer1 = QgsVectorLayer(layer1_path,"layer1","ogr") #layer 2 source layer2 = QgsVectorLayer(layer2_path,"layer2","ogr") layer2_feat_all_dict = {} layer2_feat_all = layer2.dataProvider().getFeatures() layer2_spIndex = QgsSpatialIndex() for layer2_feat in layer2_feat_all: layer2_spIndex.insertFeature(layer2_feat) layer2_feat_all_dict[layer2_feat.id()] = layer2_feat if obstacles_path is not None: obstacles_layer = QgsVectorLayer(obstacles_path,"obstacles","ogr") obstacles_feat_all = obstacles_layer.dataProvider().getFeatures() obstacles_spIndex = QgsSpatialIndex() obstacles_feat_all_dict = {} for obstacles_feat in obstacles_feat_all: obstacles_spIndex.insertFeature(obstacles_feat) obstacles_feat_all_dict[obstacles_feat.id()] = obstacles_feat layer1_feat_all = layer1.dataProvider().getFeatures() layer1_feat_total = layer1.dataProvider().featureCount() layer1_feat_number = 0 for layer1_feat in layer1_feat_all: layer1_feat_number = layer1_feat_number + 1 barValue = layer1_feat_number/float(layer1_feat_total)*100 bar.setValue(barValue) # researches the layer2 points in a rectangle created by the research_ray # creates the search rectangle rect = QgsRectangle() rect.setXMinimum( layer1_feat.geometry().asPoint().x() - research_ray ) rect.setXMaximum( layer1_feat.geometry().asPoint().x() + research_ray ) rect.setYMinimum( layer1_feat.geometry().asPoint().y() - research_ray ) rect.setYMaximum( layer1_feat.geometry().asPoint().y() + research_ray ) layer2_request = layer2_spIndex.intersects(rect) layer2_points = [] for layer2_id in layer2_request: layer2_feat = layer2_feat_all_dict[layer2_id] ray_to_test_length = compute_distance(layer1_feat.geometry().asPoint(),layer2_feat.geometry().asPoint()) if ray_to_test_length <= research_ray: ray_to_test = QgsGeometry.fromPolylineXY( [ layer1_feat.geometry().asPoint() , layer2_feat.geometry().asPoint() ] ) intersect = 0 if obstacles_path is not None: obstacles_request = obstacles_spIndex.intersects(ray_to_test.boundingBox()) for obstacles_id in obstacles_request: if obstacles_feat_all_dict[obstacles_id].geometry().crosses(ray_to_test) == 1: intersect = 1 break if intersect == 0: layer2_points.append(layer2_feat.id()) output[layer1_feat.id()] = layer2_points return output
def middle(bar,buildings_layer_path,receiver_points_layer_path): buildings_layer_name = os.path.splitext(os.path.basename(buildings_layer_path))[0] buildings_layer = QgsVectorLayer(buildings_layer_path,buildings_layer_name,"ogr") # defines emission_points layer receiver_points_fields = QgsFields() receiver_points_fields.append(QgsField("id_pt", QVariant.Int)) receiver_points_fields.append(QgsField("id_bui", QVariant.Int)) receiver_points_writer = QgsVectorFileWriter(receiver_points_layer_path, "System", receiver_points_fields, QgsWkbTypes.Point, buildings_layer.crs(),"ESRI Shapefile") # gets features from layer buildings_feat_all = buildings_layer.dataProvider().getFeatures() # creates SpatialIndex buildings_spIndex = QgsSpatialIndex() buildings_feat_all_dict = {} for buildings_feat in buildings_feat_all: buildings_spIndex.insertFeature(buildings_feat) buildings_feat_all_dict[buildings_feat.id()] = buildings_feat # defines distanze_point distance_point = 0.1 # re-gets features from layer buildings_feat_all = buildings_layer.dataProvider().getFeatures() buildings_feat_total = buildings_layer.dataProvider().featureCount() pt_id = 0 buildings_feat_number = 0 for buildings_feat in buildings_feat_all: buildings_feat_number = buildings_feat_number + 1 barValue = buildings_feat_number/float(buildings_feat_total)*100 bar.setValue(barValue) building_geom = buildings_feat.geometry() if building_geom.isMultipart(): buildings_pt = building_geom.asMultiPolygon()[0] #building_geom.convertToSingleType() else: buildings_pt = buildings_feat.geometry().asPolygon() # creates the search rectangle to match the receiver point in the building and del them rect = QgsRectangle() rect.setXMinimum( buildings_feat.geometry().boundingBox().xMinimum() - distance_point ) rect.setXMaximum( buildings_feat.geometry().boundingBox().xMaximum() + distance_point ) rect.setYMinimum( buildings_feat.geometry().boundingBox().yMinimum() - distance_point ) rect.setYMaximum( buildings_feat.geometry().boundingBox().yMaximum() + distance_point ) buildings_selection = buildings_spIndex.intersects(rect) if len(buildings_pt) > 0: for i in range(0,len(buildings_pt)): buildings_pts = buildings_pt[i] #### # start part to delete pseudo vertex # this part it's different from the diffraction delete pseudo vertex part pts_index_to_delete_list = [] m_delta = 0.01 for ii in range(0,len(buildings_pts)-1): x1 = buildings_pts[ii-1][0] x2 = buildings_pts[ii][0] x3 = buildings_pts[ii+1][0] y1 = buildings_pts[ii-1][1] y2 = buildings_pts[ii][1] y3 = buildings_pts[ii+1][1] # particular cases: first point to delete! (remember that the first and the last have the same coordinates) if ii == 0 and (x2 == x1 and y2 == y1): x1 = buildings_pts[ii-2][0] y1 = buildings_pts[ii-2][1] # angular coefficient to find pseudo vertex if x2 - x1 != 0 and x3 - x1 != 0: m1 = ( y2 - y1 ) / ( x2 - x1 ) m2 = ( y3 - y1 ) / ( x3 - x1 ) #if round(m1,2) <= round(m2,2) + m_delta and round(m1,2) >= round(m2,2) - m_delta: if m1 <= m2 + m_delta and m1 >= m2 - m_delta: pts_index_to_delete_list.append(ii) # particular cases: first point to delete! (remember that the first and the last have the same coordinates) # here we delete the last and add x3,y3 (buildings_pts[ii+1] - the new last point) if ii == 0: pts_index_to_delete_list.append(len(buildings_pts)-1) buildings_pts.append(buildings_pts[ii+1]) # del pseudo vertex pts_index_to_delete_list = sorted(pts_index_to_delete_list, reverse=True) for pt_index_to_del in pts_index_to_delete_list: del buildings_pts[pt_index_to_del] # end part to delete pseudo vertex # for to generate receiver points for ii in range(0,len(buildings_pts)-1): x1 = buildings_pts[ii][0] x2 = buildings_pts[ii+1][0] y1 = buildings_pts[ii][1] y2 = buildings_pts[ii+1][1] xm = ( x1 + x2 )/2 ym = ( y1 + y2 )/2 if y2 == y1: dx = 0 dy = distance_point elif x2 == x1: dx = distance_point dy = 0 else: m = ( y2 - y1 )/ ( x2 - x1 ) m_p = -1/m dx = sqrt((distance_point**2)/(1 + m_p**2)) dy = sqrt(((distance_point**2)*(m_p**2))/(1 + m_p**2)) if (x2 >= x1 and y2 >= y1) or (x2 < x1 and y2 < y1): pt1 = QgsPointXY(xm + dx, ym - dy) pt2 = QgsPointXY(xm - dx, ym + dy) if (x2 >= x1 and y2 < y1) or (x2 < x1 and y2 >= y1): pt1 = QgsPointXY(xm + dx, ym + dy) pt2 = QgsPointXY(xm - dx, ym - dy) pt = QgsFeature() # pt1, check if is in a building and eventually add it pt.setGeometry(QgsGeometry.fromPointXY(pt1)) intersect = 0 for buildings_id in buildings_selection: if buildings_feat_all_dict[buildings_id].geometry().intersects(pt.geometry()) == 1: intersect = 1 break if intersect == 0: pt.setAttributes([pt_id, buildings_feat.id()]) receiver_points_writer.addFeature(pt) pt_id = pt_id + 1 # pt2, check if is in a building and eventually add it pt.setGeometry(QgsGeometry.fromPointXY(pt2)) intersect = 0 for buildings_id in buildings_selection: if buildings_feat_all_dict[buildings_id].geometry().intersects(pt.geometry()) == 1: intersect = 1 break if intersect == 0: pt.setAttributes([pt_id, buildings_feat.id()]) receiver_points_writer.addFeature(pt) pt_id = pt_id + 1 del receiver_points_writer #print receiver_points_layer_path receiver_points_layer_name = os.path.splitext(os.path.basename(receiver_points_layer_path))[0] #print receiver_points_layer_name receiver_points_layer = QgsVectorLayer(receiver_points_layer_path, str(receiver_points_layer_name), "ogr") QgsProject.instance().addMapLayers([receiver_points_layer])
def spaced(bar,buildings_layer_path,receiver_points_layer_path,spaced_pts_distance): distance_from_facades = 0.1 buildings_layer_name = os.path.splitext(os.path.basename(buildings_layer_path))[0] buildings_layer = QgsVectorLayer(buildings_layer_path,buildings_layer_name,"ogr") # cp building layer to delete all fields buildings_memory_layer = QgsVectorLayer("Polygon?crs=" + str(buildings_layer.crs().authid()), "polygon_memory_layer", "memory") buildings_memory_layer.dataProvider().addAttributes([]) buildings_feat_all = buildings_layer.dataProvider().getFeatures() buildings_feat_list = [] for buildings_feat in buildings_feat_all: buildings_feat_list.append(buildings_feat) buildings_memory_layer.dataProvider().addFeatures(buildings_feat_list) buildings_memory_layer.updateExtents() # this is crazy: I had to addd this line otherwise the first processing doesn't work... QgsProject.instance().addMapLayers([buildings_memory_layer]) bar.setValue(1) # this processing alg has as output['OUTPUT'] the layer output = processing.run("native:buffer", {'INPUT': buildings_memory_layer, 'DISTANCE': distance_from_facades, 'DISSOLVE': False, 'OUTPUT': 'memory:'}) # I can now remove the layer from map... QgsProject.instance().removeMapLayers( [buildings_memory_layer.id()] ) bar.setValue(25) # this processing alg has as output['OUTPUT'] the layer output = processing.run("qgis:polygonstolines", {'INPUT': output['OUTPUT'], 'OUTPUT': 'memory:'}) bar.setValue(50) # this processing alg has as output['output'] the layer path... poly_to_lines = output['OUTPUT'] output = processing.run("qgis:pointsalonglines", {'INPUT': poly_to_lines, 'DISTANCE': spaced_pts_distance, 'START_OFFSET': 0, 'END_OFFSET': 0, 'OUTPUT': 'memory:'}) bar.setValue(75) receiver_points_memory_layer = output['OUTPUT'] del output ## Delete pts in buildings # creates SpatialIndex buildings_feat_all = buildings_layer.dataProvider().getFeatures() buildings_spIndex = QgsSpatialIndex() buildings_feat_all_dict = {} for buildings_feat in buildings_feat_all: buildings_spIndex.insertFeature(buildings_feat) buildings_feat_all_dict[buildings_feat.id()] = buildings_feat receiver_points_memory_layer_all = receiver_points_memory_layer.dataProvider().getFeatures() receiver_points_layer_fields = QgsFields() receiver_points_layer_fields.append(QgsField("id_pt", QVariant.Int)) receiver_points_layer_fields.append(QgsField("id_bui", QVariant.Int)) receiver_points_layer_writer = QgsVectorFileWriter(receiver_points_layer_path, "System", receiver_points_layer_fields, QgsWkbTypes.Point, buildings_layer.crs(), "ESRI Shapefile") receiver_points_feat_id = 0 receiver_memory_feat_total = receiver_points_memory_layer.dataProvider().featureCount() receiver_memory_feat_number = 0 for receiver_memory_feat in receiver_points_memory_layer_all: receiver_memory_feat_number = receiver_memory_feat_number + 1 barValue = receiver_memory_feat_number/float(receiver_memory_feat_total)*25 + 75 bar.setValue(barValue) rect = QgsRectangle() rect.setXMinimum(receiver_memory_feat.geometry().asPoint().x() - distance_from_facades) rect.setXMaximum(receiver_memory_feat.geometry().asPoint().x() + distance_from_facades) rect.setYMinimum(receiver_memory_feat.geometry().asPoint().y() - distance_from_facades) rect.setYMaximum(receiver_memory_feat.geometry().asPoint().y() + distance_from_facades) buildings_selection = buildings_spIndex.intersects(rect) to_add = True receiver_geom = receiver_memory_feat.geometry() building_id_correct = None for buildings_id in buildings_selection: building_geom = buildings_feat_all_dict[buildings_id].geometry() intersectBuilding = QgsGeometry.intersects(receiver_geom, building_geom) building_id_correct = buildings_id if intersectBuilding: to_add = False building_id_correct = None break # picking the nearest building to the receiver point analysed nearestIds = buildings_spIndex.nearestNeighbor(receiver_geom.asPoint(), 1) building_fid = [] for featureId in nearestIds: request = QgsFeatureRequest().setFilterFid(featureId) for feature in buildings_layer.getFeatures(request): dist = receiver_geom.distance(feature.geometry()) building_fid.append((dist, feature.id())) building_fid_correct = min(building_fid, key=lambda x: x[0])[-1] if to_add: attributes = [receiver_points_feat_id, building_fid_correct] fet = QgsFeature() fet.setGeometry(receiver_memory_feat.geometry()) fet.setAttributes(attributes) receiver_points_layer_writer.addFeature(fet) receiver_points_feat_id = receiver_points_feat_id + 1 del receiver_points_layer_writer receiver_points_layer_name = os.path.splitext(os.path.basename(receiver_points_layer_path))[0] receiver_points_layer = QgsVectorLayer(receiver_points_layer_path, str(receiver_points_layer_name), "ogr") QgsProject.instance().addMapLayers([receiver_points_layer]) QgsProject.instance().reloadAllLayers()
def run(sources_layer_path, receivers_layer_path, emission_pts_layer_path, research_ray): sources_layer = QgsVectorLayer(sources_layer_path, "input layer", "ogr") receivers_layer = QgsVectorLayer(receivers_layer_path, "output layer", "ogr") sources_feat_all = sources_layer.dataProvider().getFeatures() receivers_feat_all_dict = {} receivers_feat_all = receivers_layer.dataProvider().getFeatures() receivers_spIndex = QgsSpatialIndex() for receivers_feat in receivers_feat_all: receivers_spIndex.insertFeature(receivers_feat) receivers_feat_all_dict[receivers_feat.id()] = receivers_feat emission_pts_fields = QgsFields() emission_pts_fields.append(QgsField("id_emi", QVariant.Int)) emission_pts_fields.append(QgsField("id_emi_source", QVariant.Int)) emission_pts_fields.append(QgsField("id_source", QVariant.Int)) emission_pts_fields.append( QgsField("d_rTOe", QVariant.Double, len=10, prec=2)) # update for QGIS 3 converting VectorWriter to QgsVectorFileWriter # emission_pts_writer = VectorWriter(emission_pts_layer_path, None, emission_pts_fields, 0, sources_layer.crs()) emission_pts_writer = QgsVectorFileWriter(emission_pts_layer_path, "System", emission_pts_fields, QgsWkbTypes.Point, sources_layer.crs(), "ESRI Shapefile") # initializes ray and emission point id emission_pt_id = 0 for sources_feat in sources_feat_all: # researches the receiver points in a rectangle created by the research_ray # creates the search rectangle rect = QgsRectangle() rect.setXMinimum(sources_feat.geometry().boundingBox().xMinimum() - research_ray) rect.setXMaximum(sources_feat.geometry().boundingBox().xMaximum() + research_ray) rect.setYMinimum(sources_feat.geometry().boundingBox().yMinimum() - research_ray) rect.setYMaximum(sources_feat.geometry().boundingBox().yMaximum() + research_ray) receiver_pts_request = receivers_spIndex.intersects(rect) distance_min = [] for receiver_pts_id in receiver_pts_request: receiver_pts_feat = receivers_feat_all_dict[receiver_pts_id] result = sources_feat.geometry().closestSegmentWithContext( receiver_pts_feat.geometry().asPoint()) distance_min_tmp = sqrt(result[0]) if distance_min_tmp <= research_ray: distance_min.append(distance_min_tmp) # defines segment max length if len(distance_min) >= 1: segment_max = min(distance_min) / 2 if segment_max < 2: segment_max = 2 else: continue # splits the sources line in emission points at a fix distance (minimum distance/2) and create the emission point layer # gets vertex sources_geom = sources_feat.geometry() if sources_geom.isMultipart(): sources_geom.convertToSingleType() sources_feat_vertex_pt_all = sources_geom.asPolyline() emission_pt_id_road = 0 for i in range(0, len(sources_feat_vertex_pt_all)): pt1 = QgsPointXY(sources_feat_vertex_pt_all[i]) add_point_to_layer(emission_pts_writer, pt1, [ emission_pt_id, emission_pt_id_road, sources_feat.id(), segment_max ]) emission_pt_id = emission_pt_id + 1 emission_pt_id_road = emission_pt_id_road + 1 if i < len(sources_feat_vertex_pt_all) - 1: pt2 = QgsPoint(sources_feat_vertex_pt_all[i + 1]) x1 = pt1.x() y1 = pt1.y() x2 = pt2.x() y2 = pt2.y() if y2 == y1: dx = segment_max dy = 0 m = 0 elif x2 == x1: dx = 0 dy = segment_max else: m = (y2 - y1) / (x2 - x1) dx = sqrt((segment_max**2) / (1 + m**2)) dy = sqrt(((segment_max**2) * (m**2)) / (1 + m**2)) pt = pt1 while compute_distance(pt, pt2) > segment_max: x_temp = pt.x() y_temp = pt.y() if x_temp < x2: if m > 0: pt = QgsPointXY(x_temp + dx, y_temp + dy) elif m < 0: pt = QgsPointXY(x_temp + dx, y_temp - dy) elif m == 0: pt = QgsPointXY(x_temp + dx, y_temp) elif x_temp > x2: if m > 0: pt = QgsPointXY(x_temp - dx, y_temp - dy) elif m < 0: pt = QgsPointXY(x_temp - dx, y_temp + dy) elif m == 0: pt = QgsPointXY(x_temp - dx, y_temp) elif x_temp == x2: if y2 > y_temp: pt = QgsPointXY(x_temp, y_temp + dy) else: pt = QgsPointXY(x_temp, y_temp - dy) add_point_to_layer(emission_pts_writer, pt, [ emission_pt_id, emission_pt_id_road, sources_feat.id(), segment_max ]) emission_pt_id = emission_pt_id + 1 emission_pt_id_road = emission_pt_id_road + 1 del emission_pts_writer
def response_geotiff_mode(self, request): """ Export raster as geotiff i.e: 192.168.1.137:8006/raster/api/geotiff/qdjango/190/sfondo_clip_c60533a4_743e_4734_9b95_514ac765ec4e/ 192.168.1.137:8006/raster/api/geotiff/qdjango/190/europa_dem_8f0a9c30_5b96_4661_b747_8ce4f2679d6b/?map_extent=10.515901325263899%2C43.875701513907146%2C10.55669628723769%2C43.92294901234999 :param request: Http Django request object :return: http response with attached file """ #if not self.layer.download: # return HttpResponseForbidden() tmp_dir = tempfile.TemporaryDirectory() filename = f"{self.metadata_layer.qgis_layer.name()}.tif" file_path = os.path.join(tmp_dir.name, filename) writer = QgsRasterFileWriter(file_path) provider = self.metadata_layer.qgis_layer.dataProvider() renderer = self.metadata_layer.qgis_layer.renderer() # Check for Url Params if request.query_params.get('map_extent'): me = request.query_params.get('map_extent').split(',') orig_extent =provider.extent() extent = QgsRectangle(float(me[0]), float(me[1]), float(me[2]), float(me[3])) # If crs layer is not equal to project crs if self.reproject: ct = QgsCoordinateTransform( QgsCoordinateReferenceSystem(f'EPSG:{self.layer.project.group.srid.srid}'), self.metadata_layer.qgis_layer.crs(), QgsCoordinateTransformContext() ) extent = ct.transform(extent) # Calc columns and rows cols = int((extent.xMaximum() - extent.xMinimum()) / (orig_extent.xMaximum() - orig_extent.xMinimum()) * provider.xSize()) rows = int((extent.yMaximum() - extent.yMinimum()) / (orig_extent.yMaximum() - orig_extent.yMinimum()) * provider.ySize()) # For cols or rows lower than 0, we have to recalculate extent to guarantee minimal raster cell if cols < 1: cols = 1 new_wide_x_extent = (orig_extent.xMaximum() - orig_extent.xMinimum()) / provider.xSize() off = (new_wide_x_extent - (extent.xMaximum() - extent.xMinimum())) / 2 extent.setXMinimum(extent.xMinimum() - off) extent.setXMaximum(extent.xMaximum() + off) if rows < 1: rows = 1 new_wide_y_extent = (orig_extent.yMaximum() - orig_extent.yMinimum()) / provider.ySize() off = (new_wide_y_extent - (extent.yMaximum() - extent.yMinimum())) / 2 extent.setYMinimum(extent.yMinimum() - off) extent.setYMaximum(extent.yMaximum() + off) else: extent = provider.extent() cols = provider.xSize() rows = provider.ySize() pipe = QgsRasterPipe() pipe.set(provider.clone()) pipe.set(renderer.clone()) error_code = writer.writeRaster( pipe, cols, rows, extent, self.metadata_layer.qgis_layer.crs(), self.metadata_layer.qgis_layer.transformContext() ) if error_code != QgsRasterFileWriter.NoError: tmp_dir.cleanup() raise APIException(f"An error occoured on create raster file for export") # Grab ZIP file from in-memory, make response with correct MIME-type response = HttpResponse( open(file_path, 'rb').read(), content_type='image/tif') response['Content-Disposition'] = f'attachment; filename={filename}' response.set_cookie('fileDownload', 'true') return response
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 identifyLayer(self, point): self.results[:] = [] if not self.layer.hasGeometryType(): return False if (self.layer.hasScaleBasedVisibility() and (self.layer.minimumScale() > self.canvas.mapSettings().scale() or self.layer.maximumScale() <= self.canvas.mapSettings().scale())): print 'Out of scale limits' return False QApplication.setOverrideCursor(Qt.WaitCursor) featureCount = 0 featureList = [] try: searchRadius = self.searchRadiusMU(self.canvas) r = QgsRectangle() r.setXMinimum(point.x() - searchRadius) r.setXMaximum(point.x() + searchRadius) r.setYMinimum(point.y() - searchRadius) r.setYMaximum(point.y() + searchRadius) r = self.toLayerCoordinates(self.layer, r) req = QgsFeatureRequest() req.setFilterRect(r) req.setFlags(QgsFeatureRequest.ExactIntersect) for f in self.layer.getFeatures(req): featureList.append(QgsFeature(f)) except QgsCsException as cse: print 'Caught CRS exception', cse.what() myFilter = False context = QgsRenderContext( QgsRenderContext.fromMapSettings(self.canvas.mapSettings())) renderer = self.layer.rendererV2() if (renderer is not None and (renderer.capabilities() | QgsFeatureRendererV2.ScaleDependent)): renderer.startRender(context, self.layer.pendingFields()) myFilter = renderer.capabilities() and QgsFeatureRendererV2.Filter for f in featureList: if myFilter and not renderer.willRenderFeature(f): continue featureCount += 1 self.results.append((self.layer, f)) if (renderer is not None and (renderer.capabilities() | QgsFeatureRendererV2.ScaleDependent)): renderer.stopRender(context) print 'Feature count on identify:', featureCount QApplication.restoreOverrideCursor() return featureCount > 0
def ReadAndMergeVectorLayers(vectorLayers): # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements category = "" feats = [] for i in vectorLayers: if shared.vectorFileType[i] == "ogr": thisLayer = QgsVectorLayer(shared.vectorFileName[i], shared.vectorFileTitle[i], "ogr") elif shared.vectorFileType[i] == "spatialite": uri = QgsDataSourceUri() uri.setDatabase(shared.vectorFileName[i]) schema = '' geom_column = 'Geometry' uri.setDataSource(schema, shared.vectorFileTable[i], geom_column) thisLayer = QgsVectorLayer(uri.uri(), shared.vectorFileTitle[i], shared.vectorFileType[i]) elif shared.vectorFileType[i] == "xyz": uri = shared.vectorFileName[ i] + "?type=csv&useHeader=No&xField=field_1&yField=field_2&spatialIndex=no&subsetIndex=no&watchFile=no" thisLayer = QgsVectorLayer(uri, shared.vectorFileTitle[i], "delimitedtext") else: shared.fpOut.write("Cannot load vector file of type '" + shared.vectorFileType[i] + "'") return -1, -1 if not thisLayer.isValid(): shared.fpOut.write("Vector layer '" + shared.vectorFileTitle[i] + "' failed to load") return -1, -1 shared.fpOut.write("Vector layer '" + shared.vectorFileTitle[i] + "' loaded\n") # Copy the features from this layer that are within the displayed extent, to a new list extentRectWithBorder = QgsRectangle() borderSize = 100 extentRectWithBorder.setXMinimum(shared.extentRect.xMinimum() - borderSize) extentRectWithBorder.setYMinimum(shared.extentRect.yMinimum() - borderSize) extentRectWithBorder.setXMaximum(shared.extentRect.xMaximum() + borderSize) extentRectWithBorder.setYMaximum(shared.extentRect.yMaximum() + borderSize) request = QgsFeatureRequest(extentRectWithBorder) features = thisLayer.getFeatures(request) #features = thisLayer.getFeatures() print("Copying features from vector layer '" + shared.vectorFileTitle[i] + "'") feats += features #print("N features =", len(feats)) #for feat in features: #newFeature = QgsFeature() #newFeature.setGeometry(feat.geometry()) #fields = feat.fields() #newFeature.setFields(fields) #attrs = feat.attributes() #newFeature.setAttributes(attrs) #feats.append(newFeature) ##print(feat) ##feats.append(feat) flds = thisLayer.fields() #print(shared.vectorFileTitle[i] + " FIELD NAMES " + str(flds.names())) #print(shared.vectorFileTitle[i] + " number of attribute fields = " + str(len(flds.names()))) category = shared.vectorFileCategory[i] # Get the Coordinate Reference System and the list of fields from the last input file thisLayerCRS = thisLayer.crs().toWkt() thisLayerFieldList = thisLayer.dataProvider().fields().toList() # Create the merged layer by checking the geometry type of the input files layerGeom = thisLayer.geometryType() layerWkb = thisLayer.wkbType() isMulti = QgsWkbTypes.isMultiType(layerWkb) if layerGeom == QgsWkbTypes.PointGeometry: if isMulti: mergedLayer = QgsVectorLayer('MultiPoint?crs=' + thisLayerCRS, 'merged', "memory") else: mergedLayer = QgsVectorLayer('Point?crs=' + thisLayerCRS, 'merged', "memory") elif layerGeom == QgsWkbTypes.LineGeometry: if isMulti: mergedLayer = QgsVectorLayer('MultiLineString?crs=' + thisLayerCRS, 'merged', "memory") else: mergedLayer = QgsVectorLayer('LineString?crs=' + thisLayerCRS, 'merged', "memory") elif layerGeom == QgsWkbTypes.PolygonGeometry: if isMulti: mergedLayer = QgsVectorLayer('MultiPolygon?crs=' + thisLayerCRS, 'merged', "memory") else: mergedLayer = QgsVectorLayer('Polygon?crs=' + thisLayerCRS, 'merged', "memory") else: geomTypeString = QgsWkbTypes.displayString(int(layerWkb)) errStr = "ERROR: layer type " + geomTypeString + " could not be merged" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 # Is the new (but still empty) merged layer OK? if not mergedLayer.isValid(): titleStr = "" for i in vectorLayers: titleStr += shared.vectorFileTitle[i] if i < len(vectorLayers): titleStr += "' '" errStr = "ERROR: could not create new vector layer for merge of '" + titleStr + "'" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 # Sort the list of features by identifier feats.sort(key=lambda feat: feat.attributes()[1]) #for i in range(10): #print("BEFORE MERGE " + str(feats[i].attributes())) #print("=================") ##BODGE This is needed because QGIS 3 handles Boolean layers incorrectly #print("*********************") #print("*** ORIGINAL: " + str(thisLayerFieldList)) #for fld in thisLayerFieldList: #print(fld.type()) #print("*********************") #for fld in thisLayerFieldList: #fldName = fld.typeName() #if fldName == "Boolean": #fld.setTypeName("Integer64") #fld.setType(4) #print("**** CHANGED : " + str(thisLayerFieldList)) #for fld in thisLayerFieldList: #print(fld.type()) #print("*********************") # Add the field attributes to the merged layer provider = mergedLayer.dataProvider() #print("PROVIDER: " + str(provider)) #print("PROVIDER Number of attribute fields = " + str(len(thisLayerFieldList))) if not provider.addAttributes(thisLayerFieldList): errStr = "ERROR: could not add attributes to merged layer" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 mergedLayer.updateFields() flds = mergedLayer.fields() #print("MERGED FIELD NAMES " + str(flds.names())) #print("MERGED number of attribute fields = " + str(len(flds.names()))) if not mergedLayer.startEditing(): errStr = "ERROR: could not edit merged layer" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 if not mergedLayer.addFeatures(feats): errStr = "ERROR: could not add features to merged layer" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 #testFeats = mergedLayer.getFeatures() #print("BEFORE testFeats = " + str(testFeats)) #nMergedFeat = 0 #for feat in features: #nMergedFeat += 1 #print("BEFORE N features in testFeats =", nMergedFeat) mergedLayer.commitChanges() #testFeats = mergedLayer.getFeatures() #print("AFTER testFeats = " + str(testFeats)) #nMergedFeat = 0 #for feat in features: #nMergedFeat += 1 #print("AFTER N features in testFeats =", nMergedFeat) #features = mergedLayer.getFeatures() #for feat in features: #shared.fpOut.write(str(feat.attributes())) #for field in mergedLayer.fields().toList(): #shared.fpOut.write(str(field.name())) # Sort out style i = vectorLayers[-1] if not shared.vectorFileStyle[i]: shared.vectorFileStyle[i] = mergedLayer.styleURI() #shared.fpOut.write(shared.vectorFileStyle[i]) if not mergedLayer.loadDefaultStyle(): errStr = "ERROR: could not load default style '" + shared.vectorFileStyle[ i] + "' for vector layer '" + shared.vectorFileTitle[i] + "'" print(errStr) shared.fpOut.write(errStr + "\n") else: if not mergedLayer.loadNamedStyle(shared.vectorFileStyle[i]): errStr = "ERROR: could not load style '" + shared.vectorFileStyle[ i] + "' for vector layer '" + shared.vectorFileTitle[i] + "'" print(errStr) shared.fpOut.write(errStr + "\n") # Set transparency mergedLayer.setOpacity(shared.vectorFileOpacity[i]) # Add this layer to the app's registry QgsProject.instance().addMapLayer(mergedLayer) mergedNames = "" for i in vectorLayers: mergedNames += "'" mergedNames += shared.vectorFileTitle[i] mergedNames += "' " shared.fpOut.write("\tMerged layers " + mergedNames + "\n") print("Merged layers " + mergedNames) return mergedLayer, category
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(sources_layer_path, receivers_layer_path, emission_pts_layer_path, research_ray): sources_layer = QgsVectorLayer(sources_layer_path, "input layer", "ogr") receivers_layer = QgsVectorLayer(receivers_layer_path, "output layer", "ogr") sources_feat_all = sources_layer.dataProvider().getFeatures() receivers_feat_all_dict = {} receivers_feat_all = receivers_layer.dataProvider().getFeatures() receivers_spIndex = QgsSpatialIndex() for receivers_feat in receivers_feat_all: receivers_spIndex.insertFeature(receivers_feat) receivers_feat_all_dict[receivers_feat.id()] = receivers_feat emission_pts_fields = QgsFields() emission_pts_fields.append(QgsField("id_emi", QVariant.Int)) emission_pts_fields.append(QgsField("id_emi_source", QVariant.Int)) emission_pts_fields.append(QgsField("id_source", QVariant.Int)) emission_pts_fields.append(QgsField("d_rTOe", QVariant.Double, len=10, prec=2)) # update for QGIS 3 converting VectorWriter to QgsVectorFileWriter # emission_pts_writer = VectorWriter(emission_pts_layer_path, None, emission_pts_fields, 0, sources_layer.crs()) emission_pts_writer = QgsVectorFileWriter(emission_pts_layer_path, "System", emission_pts_fields, QgsWkbTypes.Point, sources_layer.crs(), "ESRI Shapefile") # initializes ray and emission point id emission_pt_id = 0 for sources_feat in sources_feat_all: # researches the receiver points in a rectangle created by the research_ray # creates the search rectangle rect = QgsRectangle() rect.setXMinimum(sources_feat.geometry().boundingBox().xMinimum() - research_ray) rect.setXMaximum(sources_feat.geometry().boundingBox().xMaximum() + research_ray) rect.setYMinimum(sources_feat.geometry().boundingBox().yMinimum() - research_ray) rect.setYMaximum(sources_feat.geometry().boundingBox().yMaximum() + research_ray) receiver_pts_request = receivers_spIndex.intersects(rect) distance_min = [] for receiver_pts_id in receiver_pts_request: receiver_pts_feat = receivers_feat_all_dict[receiver_pts_id] result = sources_feat.geometry().closestSegmentWithContext(receiver_pts_feat.geometry().asPoint()) distance_min_tmp = sqrt(result[0]) if distance_min_tmp <= research_ray: distance_min.append(distance_min_tmp) # defines segment max length if len(distance_min) >= 1: segment_max = min(distance_min) / 2 if segment_max < 2: segment_max = 2 else: continue # splits the sources line in emission points at a fix distance (minimum distance/2) and create the emission point layer # gets vertex sources_geom = sources_feat.geometry() if sources_geom.isMultipart(): sources_geom.convertToSingleType() sources_feat_vertex_pt_all = sources_geom.asPolyline() emission_pt_id_road = 0 for i in range(0, len(sources_feat_vertex_pt_all)): pt1 = QgsPointXY(sources_feat_vertex_pt_all[i]) add_point_to_layer(emission_pts_writer, pt1, [emission_pt_id, emission_pt_id_road, sources_feat.id(), segment_max]) emission_pt_id = emission_pt_id + 1 emission_pt_id_road = emission_pt_id_road + 1 if i < len(sources_feat_vertex_pt_all) - 1: pt2 = QgsPoint(sources_feat_vertex_pt_all[i + 1]) x1 = pt1.x() y1 = pt1.y() x2 = pt2.x() y2 = pt2.y() if y2 == y1: dx = segment_max dy = 0 m = 0 elif x2 == x1: dx = 0 dy = segment_max else: m = (y2 - y1) / (x2 - x1) dx = sqrt((segment_max ** 2) / (1 + m ** 2)) dy = sqrt(((segment_max ** 2) * (m ** 2)) / (1 + m ** 2)) pt = pt1 while compute_distance(pt, pt2) > segment_max: x_temp = pt.x() y_temp = pt.y() if x_temp < x2: if m > 0: pt = QgsPointXY(x_temp + dx, y_temp + dy) elif m < 0: pt = QgsPointXY(x_temp + dx, y_temp - dy) elif m == 0: pt = QgsPointXY(x_temp + dx, y_temp) elif x_temp > x2: if m > 0: pt = QgsPointXY(x_temp - dx, y_temp - dy) elif m < 0: pt = QgsPointXY(x_temp - dx, y_temp + dy) elif m == 0: pt = QgsPointXY(x_temp - dx, y_temp) elif x_temp == x2: if y2 > y_temp: pt = QgsPointXY(x_temp, y_temp + dy) else: pt = QgsPointXY(x_temp, y_temp - dy) add_point_to_layer(emission_pts_writer, pt, [emission_pt_id, emission_pt_id_road, sources_feat.id(), segment_max]) emission_pt_id = emission_pt_id + 1 emission_pt_id_road = emission_pt_id_road + 1 del emission_pts_writer