def calculate_shortest_road_distance(layer, road_layer): """Calculating the shortest distance to the nearest road""" debug('Calculate shortest road distance') road_distance_field = layer.fields().indexFromName('road_distance') all_roads = { feature.id(): feature for (feature) in road_layer.getFeatures() } # Create spatial index road_spatial_index = create_spatial_index(road_layer) nearest_distances = [] for building in layer.getFeatures(): nearest_road_id = road_spatial_index.nearestNeighbor( building.geometry())[0] road = all_roads[nearest_road_id] distance = QgsGeometry.distance(building.geometry(), road.geometry()) nearest_distances.append(distance) # Rescale min_nearest_distances = min(nearest_distances) max_nearest_distances = max(nearest_distances) range_nearest_distances = max_nearest_distances - min_nearest_distances # Update value layer.startEditing() i = 0 for feature in layer.getFeatures(): nearest_distance_index = (nearest_distances[i] - min_nearest_distances ) / range_nearest_distances layer.changeAttributeValue(feature.id(), road_distance_field, nearest_distance_index) i += 1 layer.commitChanges()
def removePointsNextToFrame(self, frameLinesLayer, pointsLayer, distance): toBeRemoved = [] for point in pointsLayer.getFeatures(): for frameLine in frameLinesLayer.getFeatures(): dist = QgsGeometry.distance(point.geometry(), frameLine.geometry()) if dist < distance: toBeRemoved.append(point.id()) pointsLayer.deleteFeatures(toBeRemoved)
def hdist(self, feata, lDist): geoma = QgsGeometry(feata.geometry()) feat = QgsFeature() provider = self.ml.dataProvider() feats = provider.getFeatures() self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0) self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, provider.featureCount())) ne = 0 neighbours = "" while feats.nextFeature(feat): ne += 1 self.emit(SIGNAL("runStatus(PyQt_PyObject)"), ne) geomb = QgsGeometry(feat.geometry()) if feata.id()!=feat.id(): if geoma.distance(geomb)<=lDist: neighbours = neighbours + '%s,' % (feat.id()+self.p) return neighbours[:-1]
def hdist(self, feata, lDist): geoma = QgsGeometry(feata.geometry()) feat = QgsFeature() provider = self.ml.dataProvider() feats = provider.getFeatures() #self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0) #self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, provider.featureCount())) ne = 0 neighbours = "" while feats.nextFeature(feat): ne += 1 #self.emit(SIGNAL("runStatus(PyQt_PyObject)"), ne) geomb = QgsGeometry(feat.geometry()) if feata.id() != feat.id(): if geoma.distance(geomb) <= lDist: neighbours = neighbours + '%s,' % (feat.id() + self.p) return neighbours[:-1]
def getDistance(self, layer1, feature1, layer2, feature2): distance = -1 transform = None if layer1.sourceCrs() != layer2.sourceCrs(): transform = QgsCoordinateTransform(layer1.sourceCrs(), layer2.sourceCrs(), QgsProject.instance()) geom1 = feature1.geometry() geom2 = feature2.geometry() if not geom1.isNull() and not geom2.isNull(): transformedSourceGeom1 = None if transform is not None: transformedGeom1 = QgsGeometry(geom1) transformedGeom1.transform(transform) else: transformedGeom1 = QgsGeometry(geom) distance = int(round(transformedGeom1.distance(geom2))) return distance
def run(self): #CARREGA A LISTA DOS NOMES DOS LAYER DA TOC layers = self.iface.legendInterface().layers() layer_list = [] i = 0 iObra = 0 iLote = 0 for layer in layers: nomeLayer = layer.name() layer_list.append(nomeLayer) if 'obra' in str(nomeLayer).lower(): iObra = i if 'lote' in str(nomeLayer).lower(): iLote = i i = i + 1 #SELECIONAR O SHP DA OBRA self.dlg.comboBox_obra.clear() self.dlg.comboBox_obra.addItems(layer_list) #SELECIONAR O SHP DOS LOTES self.dlg.comboBox_lote.clear() self.dlg.comboBox_lote.addItems(layer_list) #SELECIONAR OBRA E LOTE AUTOMATICAMENTE self.dlg.comboBox_obra.setCurrentIndex(iObra) self.dlg.comboBox_lote.setCurrentIndex(iLote) """Run method that performs all the real work""" # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. # pass selectedLayerIndex = self.dlg.comboBox_obra.currentIndex() selectedLayerObra = layers[selectedLayerIndex] selectedLayerIndex = self.dlg.comboBox_lote.currentIndex() selectedLayerLote = layers[selectedLayerIndex] #LISTA DOS CAMPOS OBTIDA PELO dataProvider lotes = selectedLayerLote.dataProvider() #CRIACAO DE NOVO CAMPOS EM LOTES field_dista1_index = lotes.fields().indexFromName("area") if field_dista1_index == -1: #CRIAR O CAMPO AREA, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("area", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() field_dista1_index = lotes.fields().indexFromName("distobra") if field_dista1_index == -1: #CRIAR O CAMPO DISTOBRA, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("distobra", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() field_valor_index = lotes.fields().indexFromName("valor") if field_valor_index == -1: #CRIAR O CAMPO VALOR, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("valor", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() field_valtot_index = lotes.fields().indexFromName("valtot") if field_valtot_index == -1: #CRIAR O CAMPO VALTOT, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("valtot", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() #DETECTA OS IDs DOS NOVOS CAMPOS CRIADOS id_field_area = lotes.fields().indexFromName('area') id_field_distObra = lotes.fields().indexFromName('distobra') id_field_valor = lotes.fields().indexFromName('valor') id_field_valtot = lotes.fields().indexFromName('valtot') #PARAMETRO PARA O CALCULO DE VALOR1 if self.dlg.radioButton_pav.isChecked(): #radioButton_pavimentacao_via localmin1 = 0.00 localmax1 = 100.00 valor1 = 10.00 localmin2 = 100.00 localmax2 = 200.00 valor2 = 5.00 localmin3 = 200.00 localmax3 = 300.00 valor3 = 2.50 #LE AS COORDENADA DA OBRA for fObra in selectedLayerObra.getFeatures(): geomObra = fObra.geometry() #INICIO DA EDICAO DOS DADOS selectedLayerLote.startEditing() #LE AS COORDENADA DOS LOTES val_tot_geral = 0.00 val_tot_area = 0.00 tot_lotes = 0 for fLote in selectedLayerLote.getFeatures(): id = fLote.id() geomLote = fLote.geometry() #CALCULO DA DISTANCIA ENTRE POLIGONOS E AREA DO LOTE distobra = QgsGeometry.distance(geomLote, geomObra) val_area = QgsGeometry.area(geomLote) valor = 0.0 if localmin1 <= distobra < localmax1: valor = valor1 elif localmin2 <= distobra < localmax2: valor = valor2 elif localmin3 <= distobra < localmax3: valor = valor3 #TOTALIZA VALOR POR LOTE val_tot_lot = val_area * valor #TOTALIZA POR LOTE AFETADO if valor > 0: val_tot_area = val_tot_area + val_area val_tot_geral = val_tot_geral + val_tot_lot tot_lotes = tot_lotes + 1 #GRAVA OS VALORES NA CAMADA DE LOTES selectedLayerLote.changeAttributeValue(id, id_field_area, geomLote.area()) selectedLayerLote.changeAttributeValue(id, id_field_distObra, distobra) selectedLayerLote.changeAttributeValue(id, id_field_valor, valor) selectedLayerLote.changeAttributeValue(id, id_field_valtot, val_tot_lot) #COMITA AS MUDANCAS selectedLayerLote.commitChanges() iface.messageBar().pushMessage("BID - VALORIZA SOLO URBANO", "Calculo realizado com sucesso!", level=QgsMessageBar.INFO, duration=5) #ABRE A TABELA DE ATRIBUTOS DOS LOTES iface.showAttributeTable(selectedLayerLote) #FORMATA A MENSAGEM tot_tributo_geral = val_tot_geral * 0.02 tot_valor = round(val_tot_geral, 2) tot_area = round(val_tot_area, 2) tot_tributo = round(tot_tributo_geral, 2) tot_valor_formatado = '{0:,}'.format(tot_valor).replace(',', '.') tot_tributo_formatado = '{0:,}'.format(tot_tributo).replace( ',', '.') tot_area_formatado = '{0:,}'.format(tot_area).replace(',', '.') tot_lotes_formatado = '{0:,}'.format(tot_lotes).replace(',', '.') txt1 = '%s' % ("VALORIZA SOLO URBANO\n\n\n") txt2 = 'Total Lotes......................= %s\n\n' % ( tot_lotes_formatado) txt3 = 'Total Area (m2)..............= %s\n\n' % ( tot_area_formatado) txt4 = 'Total Incremento ($).....= %s\n\n' % (tot_valor_formatado) txt5 = 'Total Aliquota a 2 ($).....= %s\n' % ( tot_tributo_formatado) txt6 = '%s%s%s%s%s' % (txt1, txt2, txt3, txt4, txt5) import ctypes MessageBox = ctypes.windll.user32.MessageBoxA MessageBox(None, txt6, ' B I D / A B R A S F', 0)
def refreshPreview(self): """refreshing canvas on preview""" if len(self.similarLayer) > 0: # set the layer self.layerCanvas = QgsVectorLayer("Polygon?crs=ESPG:4326", 'SimilarityLayer', 'memory') self.layer2Canvas = QgsVectorLayer("Polygon?crs=ESPG:4326", 'SimilarityLayer', 'memory') # set the feature previewLayerFeature = self.calcTask.getLayersDup()[0].getFeature( self.similarLayer[self.previewLayer][0]) previewLayerFeature2 = self.calcTask.getLayersDup()[1].getFeature( self.similarLayer[self.previewLayer][1]) # set the label score on preview scoreLabel = "Score : " + str( round(self.similarLayer[self.previewLayer][2], 3)) # set cumulative score on preview if (not self.calcTask.getTranslate()): scoreLabel += " - Cumulative score : " + str( self.calcTask.getCumulative( self.similarLayer[self.previewLayer])) # show distance if the layer merge centered (NN and WK only) if (self.dlg.methodComboBox.currentIndex() == 1 or self.dlg.methodComboBox.currentIndex() == 2): distance = QgsGeometry.distance( previewLayerFeature.geometry().centroid(), previewLayerFeature2.geometry().centroid()) if distance < 0.00001: distance = 0 self.dlg.labelScore.setText(scoreLabel + " - Distance : " + str(round(distance, 3))) else: self.dlg.labelScore.setText(scoreLabel) self.attrPrinter( self.calcTask.getLayersDup() [0].dataProvider().fields().toList(), previewLayerFeature, self.dlg.previewAttr) self.attrPrinter( self.calcTask.getLayersDup() [1].dataProvider().fields().toList(), previewLayerFeature2, self.dlg.previewAttr_2) self.layerCanvas.dataProvider().addFeature(previewLayerFeature) # translating preview if self.calcTask.getTranslate(): tGeom = self.calcTask.translateCenterGeom( previewLayerFeature2.geometry(), previewLayerFeature.geometry()) nFeat = QgsFeature(previewLayerFeature2) nFeat.setGeometry(tGeom) self.layer2Canvas.dataProvider().addFeature(nFeat) else: self.layer2Canvas.dataProvider().addFeature( previewLayerFeature2) # set canvas to preview feature layer self.dlg.widgetCanvas.setExtent( previewLayerFeature.geometry().boundingBox(), True) self.dlg.widgetCanvas.setDestinationCrs( self.layerCanvas.sourceCrs()) symbol = self.layerCanvas.renderer().symbol() symbol.setColor(QColor(0, 147, 221, 127)) symbol2 = self.layer2Canvas.renderer().symbol() symbol2.setColor(QColor(231, 120, 23, 127)) self.dlg.widgetCanvas.setLayers( [self.layer2Canvas, self.layerCanvas]) # redraw the canvas self.dlg.widgetCanvas.refresh()
def traf(self, geometry, trafic, spatial, lines, echelle, angle_max, dist_min, double_sens): lignes = lines conn = db.connect(':memory:') conn.enable_load_extension(True) conn.execute("select load_extension('mod_spatialite')") c = conn.cursor() proj = str(self.lines.crs().postgisSrid()) t = geometry[trafic] texte = "select astext(st_buffer(st_geomfromtext('" + geometry.geometry( ).asWkt() + "'," + proj + ")," + str(echelle * t) + "))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() texte_buf = resultat[0][0] texte_buf = texte_buf.replace("Polygon", "MultiLineString") buf = QgsGeometry.fromWkt(texte_buf) #buf=buf.convertToType(QgsWkbTypes.LineGeometry,False) texte = "select astext(st_union(st_exteriorring(st_geomfromtext('" + buf.asWkt( ) + "'," + proj + "))))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf = QgsGeometry.fromWkt(resultat[0][0]) #QgsMessageLog.logMessage(texte) #QgsMessageLog.logMessage(buf.asWkt()) buf_poly = buf geom = geometry.geometry() buf_sav = buf buf_l = buf.length() l2 = QgsLineString() #print(geom.asWkt()) geom.convertToSingleType() #print(geom.asWkt()) l2.fromWkt(geom.asWkt()) #print(l2.asWkt()) pt1 = QgsGeometry(l2.startPoint()) pt2 = QgsGeometry(l2.endPoint()) ###point debut debut = spatial.intersects( QgsGeometry.buffer(pt1, 10, 3).boundingBox()) fe = [f for f in debut] feats = [] for f in fe: ff = QgsLineString() #QgsMessageLog.logMessage(lignes[f].geometry().asWkt()) geom = lignes[f].geometry() geom.convertToSingleType() ff.fromWkt(geom.asWkt()) #QgsMessageLog.logMessage(ff.asWkt()) #print(pt1.distance(QgsGeometry(ff.startPoint()))) if pt1.distance(QgsGeometry(ff.startPoint())) < 10: if lignes[f] not in feats: feats.append(f) elif pt1.distance(QgsGeometry(ff.endPoint())) < 10: if lignes[f] not in feats: feats.append(f) #QgsMessageLog.logMessage(str(fe)) #QgsMessageLog.logMessage(str(feats)) distances = {} angles = {} for i in feats: longueur = lignes[i].geometry().length() if not (geometry.id() == i): distances[i] = lignes[i].geometry().lineLocatePoint(pt1) if distances[i] < dist_min: angles[i] = ((lignes[i].geometry().interpolateAngle( min(dist_min, longueur)) * 180 / math.pi) + 180) % 360 else: angles[i] = lignes[i].geometry().interpolateAngle( longueur - min(dist_min, longueur)) * 180 / math.pi else: angle1 = lignes[i].geometry().interpolateAngle( min(dist_min, longueur)) * 180 / math.pi angle_maxi = 1e38 voisin = None angle_voisin = None angle2 = None if len(distances) == 0: angle = (angle1) % 360 angle2 = angle1 angle_voisin = angle2 for i in distances: if distances[i] < dist_min: angle = (angles[i]) % 360 min_angle = min( abs((angle + 180) % 360 - (angle1 + 180) % 360), abs(angle - angle1)) if min_angle < angle_maxi: angle_maxi = min_angle angle_voisin = angle voisin = i else: angle = angles[i] min_angle = min( abs((angle + 180) % 360 - (angle1 + 180) % 360), abs(angle - angle1)) if min_angle < angle_maxi: angle_maxi = min_angle angle_voisin = angle voisin = i if min(abs((angle_voisin + 180) % 360 - (angle1 + 180) % 360), abs(angle_voisin - angle1)) < angle_max: if abs((angle_voisin + 180) % 360 - (angle1 + 180) % 360) < abs(angle_voisin - angle1): angle2 = (0.5 * (((angle_voisin + 180) % 360 + (angle1 + 180) % 360)) + 180) % 360 else: angle2 = 0.5 * (angle_voisin + angle1) else: angle2 = angle1 if angle2 == None: angle2 = (angle1) % 360 start_line = QgsGeometry.fromPolyline([ QgsPoint( pt1.asPoint().x() - 40 * echelle * t * math.cos( (180 - angle2) * math.pi / 180), pt1.asPoint().y() - 40 * echelle * t * math.sin( (180 - angle2) * math.pi / 180)), QgsPoint(pt1.asPoint().x(), pt1.asPoint().y()) ]) int1 = buf.intersection(start_line) start_line2 = QgsGeometry.fromPolyline([ QgsPoint( pt1.asPoint().x() + 40 * echelle * t * math.cos( (180 - angle2) * math.pi / 180), pt1.asPoint().y() + 40 * echelle * t * math.sin( (180 - angle2) * math.pi / 180)), QgsPoint(pt1.asPoint().x(), pt1.asPoint().y()) ]) int3 = buf.intersection(start_line2) if int1.isMultipart(): points = int1.asMultiPoint() dmax = 1e38 for p in points: d = pt1.distance(QgsGeometry.fromPointXY(p)) if d < dmax: dmax = d pmax = p int1 = QgsGeometry.fromPointXY(pmax) if int3.isMultipart(): points = int3.asMultiPoint() dmax = 1e38 for p in points: d = pt1.distance(QgsGeometry.fromPointXY(p)) if d < dmax: dmax = d pmax = p int3 = QgsGeometry.fromPointXY(pmax) ###point fin debut = spatial.intersects( QgsGeometry.buffer(pt2, 10, 3).boundingBox()) fe = [f for f in debut] for f in fe: ff = QgsLineString() geom = lignes[f].geometry() geom.convertToSingleType() ff.fromWkt(geom.asWkt()) if pt2.distance(QgsGeometry(ff.startPoint())) < 10: if lignes[f] not in feats: feats.append(f) elif pt2.distance(QgsGeometry(ff.endPoint())) < 10: if lignes[f] not in feats: feats.append(f) distances = {} angles = {} for i in feats: longueur = lignes[i].geometry().length() if not (geometry.id() == i): distances[i] = lignes[i].geometry().lineLocatePoint(pt2) if distances[i] < dist_min: angles[i] = (lignes[i].geometry().interpolateAngle( min(dist_min, longueur)) * 180 / math.pi) % 360 else: angles[i] = (((lignes[i].geometry().interpolateAngle( longueur - min(dist_min, longueur)) * 180) / math.pi) + 180) % 360 else: angle1 = ((lignes[i].geometry().interpolateAngle( longueur - min(dist_min, longueur)) * 180 / math.pi)) angle_maxi = 1e38 voisin = None angle_voisin = None angle2 = None if len(distances) == 0: angle = (angle1) % 360 angle2 = angle1 angle_voisin = angle2 for i in distances: if distances[i] < dist_min: angle = (angles[i]) min_angle = min( abs((angle + 180) % 360 - (angle1 + 180) % 360), abs(angle - angle1)) if min_angle < angle_maxi: angle_maxi = min_angle angle_voisin = angle voisin = i else: angle = (angles[i]) min_angle = min( abs((angle + 180) % 360 - (angle1 + 180) % 360), abs(angle - angle1)) if min_angle < angle_maxi: angle_maxi = min_angle angle_voisin = angle voisin = i if min(abs((angle_voisin + 180) % 360 - (angle1 + 180) % 360), abs(angle_voisin - angle1)) < angle_max: if abs((angle_voisin + 180) % 360 - (angle1 + 180) % 360) < abs(angle_voisin - angle1): angle2 = (0.5 * (((angle_voisin + 180) % 360 + (angle1 + 180) % 360)) + 180) % 360 else: angle2 = 0.5 * (angle_voisin + angle1) else: angle2 = angle1 if angle2 == None: angle2 = (angle1) % 360 end_line = QgsGeometry.fromPolyline([ QgsPoint( pt2.asPoint().x() - 40 * echelle * t * math.cos( (180 - angle2) * math.pi / 180), pt2.asPoint().y() - 40 * echelle * t * math.sin( (180 - angle2) * math.pi / 180)), QgsPoint(pt2.asPoint().x(), pt2.asPoint().y()) ]) int2 = buf.intersection(end_line) end_line2 = QgsGeometry.fromPolyline([ QgsPoint( pt2.asPoint().x() + 40 * echelle * t * math.cos( (180 - angle2) * math.pi / 180), pt2.asPoint().y() + 40 * echelle * t * math.sin( (180 - angle2) * math.pi / 180)), QgsPoint(pt2.asPoint().x(), pt2.asPoint().y()) ]) int4 = buf.intersection(end_line2) int5 = start_line.intersection(end_line) int6 = start_line2.intersection(end_line2) m5 = -1 m6 = -1 if int5.type() == 0: if int5.within(buf_poly): m5 = 1 if int6.type() == 0: if int6.within(buf_poly): m6 = 1 if int2.isMultipart(): points = int2.asMultiPoint() dmax = 1e38 for p in points: d = pt2.distance(QgsGeometry.fromPointXY(p)) if d < dmax: dmax = d pmax = p int2 = QgsGeometry.fromPointXY(pmax) if int4.isMultipart(): points = int4.asMultiPoint() dmax = 1e38 for p in points: d = pt2.distance(QgsGeometry.fromPointXY(p)) if d < dmax: dmax = d pmax = p int4 = QgsGeometry.fromPointXY(pmax) #print(int1.exportToWkt(),int2.exportToWkt(),int3.exportToWkt(),int4.exportToWkt()) #QgsMessageLog.logMessage(buf.asWkt()) texte = "select astext(st_union(st_snap(st_geomfromtext('" + buf.asWkt( ) + "'," + proj + "),st_geomfromtext('" + int1.asWkt( ) + "'," + proj + "),1)))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf = resultat[0][0] #QgsMessageLog.logMessage(texte) #QgsMessageLog.logMessage(buf) #QgsMessageLog.logMessage(proj) #QgsMessageLog.logMessage(int2.asWkt()) texte = "select astext(st_union(st_snap(st_geomfromtext('" + buf + "'," + proj + "),st_geomfromtext('" + int2.asWkt( ) + "'," + proj + "),1)))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf = resultat[0][0] texte = "select astext(st_union(st_snap(st_geomfromtext('" + buf + "'," + proj + "),st_geomfromtext('" + int3.asWkt( ) + "'," + proj + "),1)))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf = resultat[0][0] texte = "select astext(st_union(st_snap(st_geomfromtext('" + buf + "'," + proj + "),st_geomfromtext('" + int4.asWkt( ) + "'," + proj + "),1)))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf = QgsGeometry.fromWkt(resultat[0][0]) m1 = buf.lineLocatePoint(int1) m2 = buf.lineLocatePoint(int2) m3 = buf.lineLocatePoint(int3) m4 = buf.lineLocatePoint(int4) #creation epaisseur buf_l = buf.length() m1 = m1 / buf_l m2 = m2 / buf_l m3 = m3 / buf_l m4 = m4 / buf_l if m2 < m1: texte = "select asText(st_line_substring(st_geomfromtext('" + buf.asWkt( ) + "'," + proj + ")" + ',' + str(m2) + ',' + str(m1) + "))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf1 = QgsGeometry.fromWkt(resultat[0][0]) else: texte = "select astext(st_union(st_snap(st_line_substring(geomfromtext('" + buf.asWkt( ) + "'," + proj + "),0," + str( m1) + "),st_line_substring(geomfromtext('" + buf.asWkt( ) + "'," + proj + ")," + str( m3 ) + ",1),1),st_line_substring(geomfromtext('" + buf.asWkt( ) + "'," + proj + ")," + str(m2) + ",1)))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf1 = QgsGeometry.fromWkt(resultat[0][0]) if m3 < m4: texte = "select asText(st_line_substring(st_geomfromtext('" + buf.asWkt( ) + "'," + proj + ")" + ',' + str(m3) + ',' + str(m4) + "))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf2 = QgsGeometry.fromWkt(resultat[0][0]) else: texte = "select astext(st_union(g)) from (select st_line_substring(st_geomfromtext('" + buf.asWkt( ) + "'," + proj + "),0," + str( m4 ) + ") as \"g\" union all select st_line_substring(st_geomfromtext('" + buf.asWkt( ) + "'," + proj + ")," + str(m3) + ",1) as \"g\" )" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf2 = QgsGeometry.fromWkt(resultat[0][0]) texte = "select astext(st_union(st_snap(st_line_substring(geomfromtext('" + buf.asWkt( ) + "'," + proj + "),0," + str( m4) + "),st_line_substring(geomfromtext('" + buf.asWkt( ) + "'," + proj + ")," + str( m3 ) + ",1),1),st_line_substring(geomfromtext('" + buf.asWkt( ) + "'," + proj + ")," + str(m3) + ",1)))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf2 = QgsGeometry.fromWkt(resultat[0][0]) g1 = buf g2 = buf.shortestLine(int1) g2 = g2.combine(g1) g3 = buf.shortestLine(int2) g3 = g3.combine(g2) g3 = g3.combine(pt1.shortestLine(int1)) g3 = g3.combine(pt2.shortestLine(int2)) g3 = g3.combine(pt1.shortestLine(geometry.geometry())) g3 = g3.combine(pt2.shortestLine(geometry.geometry())) g3 = g3.combine(geometry.geometry()) buf3 = buf1.asWkt() buf4 = buf2.asWkt() if double_sens == False: if m5 > 0: texte = "select astext(st_union(st_snap(geomfromtext('" + geometry.geometry( ).asWkt( ) + "'," + proj + "),geomfromtext('" + pt1.shortestLine( int5).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt1.shortestLine( int5).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt2.shortestLine( int5).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt2.shortestLine( int5).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] else: texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + buf1.shortestLine( int1 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + buf1.shortestLine( int1).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + buf1.shortestLine( int2 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + buf1.shortestLine( int2).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt1.shortestLine( int1).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt1.shortestLine( int1).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt2.shortestLine( int2).asWkt() + "'),1),geomfromtext('" + pt2.shortestLine( int2).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt1.shortestLine( geometry.geometry()).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt1.shortestLine( geometry.geometry()).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt2.shortestLine( geometry.geometry()).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt2.shortestLine( geometry.geometry()).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + geometry.geometry( ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + geometry.geometry( ).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] else: if m5 > 0: texte = "select astext(st_union(st_snap(geomfromtext('" + buf4 + "'," + proj + "),geomfromtext('" + pt1.shortestLine( int3).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt1.shortestLine( int3).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt2.shortestLine( int4).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt2.shortestLine( int4).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt1.shortestLine( int5).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt1.shortestLine( int5).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt2.shortestLine( int5).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt2.shortestLine( int5).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] elif m6 > 0: texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt1.shortestLine( int1).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt1.shortestLine( int1).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt2.shortestLine( int2).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt2.shortestLine( int2).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt1.shortestLine( int6).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt1.shortestLine( int6).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + pt2.shortestLine( int6).asWkt( ) + "'," + proj + "),1),geomfromtext('" + pt2.shortestLine( int6).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] else: texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + buf1.shortestLine( int1 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + buf1.shortestLine( int1).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + buf1.shortestLine( int2 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + buf1.shortestLine( int2).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + int3.shortestLine( int1 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + int3.shortestLine( int1).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + int4.shortestLine( int2 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + int4.shortestLine( int2).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + buf2.shortestLine( int3 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + buf2.shortestLine( int3).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + buf2.shortestLine( int4 ).asWkt( ) + "'," + proj + "),1),geomfromtext('" + buf2.shortestLine( int4).asWkt() + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_union(st_snap(geomfromtext('" + buf3 + "'," + proj + "),geomfromtext('" + buf4 + "'," + proj + "),1),geomfromtext('" + buf4 + "'," + proj + ")))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf3 = resultat[0][0] texte = "select astext(st_buildarea(st_union(g))) from ((select geomfromtext('" + buf3 + "'," + proj + ") as \"g\"))" rs = c.execute(texte) resultat = c.fetchall() conn.commit() buf = QgsGeometry.fromWkt(resultat[0][0]) return (buf)
def traf(self,geometry,trafic,spatial,lines,echelle,angle_max,dist_min,double_sens): lignes=lines conn = db.connect(':memory:') conn.enable_load_extension(True) conn.execute("select load_extension('mod_spatialite')") c = conn.cursor() proj=str(self.lines.crs().postgisSrid()) t=geometry[trafic] texte="select astext(st_buffer(st_geomfromtext('"+geometry.geometry().asWkt()+"',"+proj+"),"+str(echelle*t)+"))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() texte_buf= resultat[0][0] texte_buf=texte_buf.replace("Polygon","MultiLineString") buf=QgsGeometry.fromWkt(texte_buf) #buf=buf.convertToType(QgsWkbTypes.LineGeometry,False) texte="select astext(st_union(st_exteriorring(st_geomfromtext('"+buf.asWkt()+"',"+proj+"))))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf= QgsGeometry.fromWkt(resultat[0][0]) #QgsMessageLog.logMessage(texte) #QgsMessageLog.logMessage(buf.asWkt()) buf_poly=buf geom=geometry.geometry() buf_sav=buf buf_l=buf.length() l2=QgsLineString() #print(geom.asWkt()) geom.convertToSingleType() #print(geom.asWkt()) l2.fromWkt(geom.asWkt()) #print(l2.asWkt()) pt1=QgsGeometry(l2.startPoint()) pt2=QgsGeometry(l2.endPoint()) ###point debut debut=spatial.intersects(QgsGeometry.buffer(pt1,10,3).boundingBox()) fe= [f for f in debut] feats=[] for f in fe: ff=QgsLineString() #QgsMessageLog.logMessage(lignes[f].geometry().asWkt()) geom=lignes[f].geometry() geom.convertToSingleType() ff.fromWkt(geom.asWkt()) #QgsMessageLog.logMessage(ff.asWkt()) #print(pt1.distance(QgsGeometry(ff.startPoint()))) if pt1.distance(QgsGeometry(ff.startPoint()))<10: if lignes[f] not in feats: feats.append(f) elif pt1.distance(QgsGeometry(ff.endPoint()))<10: if lignes[f] not in feats: feats.append(f) #QgsMessageLog.logMessage(str(fe)) #QgsMessageLog.logMessage(str(feats)) distances={} angles={} for i in feats: longueur=lignes[i].geometry().length() if not(geometry.id()==i): distances[i]=lignes[i].geometry().lineLocatePoint(pt1) if distances[i]<dist_min: angles[i]=((lignes[i].geometry().interpolateAngle(min(dist_min,longueur))*180/math.pi)+180)%360 else: angles[i]=lignes[i].geometry().interpolateAngle(longueur-min(dist_min,longueur))*180/math.pi else: angle1=lignes[i].geometry().interpolateAngle(min(dist_min,longueur))*180/math.pi angle_maxi=1e38 voisin=None angle_voisin=None angle2=None if len(distances)==0: angle=(angle1)%360 angle2=angle1 angle_voisin=angle2 for i in distances: if distances[i]<dist_min: angle=(angles[i])%360 min_angle=min(abs((angle+180)%360-(angle1+180)%360),abs(angle-angle1)) if min_angle<angle_maxi: angle_maxi=min_angle angle_voisin=angle voisin=i else: angle=angles[i] min_angle=min(abs((angle+180)%360-(angle1+180)%360),abs(angle-angle1)) if min_angle<angle_maxi: angle_maxi=min_angle angle_voisin=angle voisin=i if min(abs((angle_voisin+180)%360-(angle1+180)%360),abs(angle_voisin-angle1))<angle_max: if abs((angle_voisin+180)%360-(angle1+180)%360)<abs(angle_voisin-angle1): angle2=(0.5*(((angle_voisin+180)%360+(angle1+180)%360))+180)%360 else: angle2=0.5*(angle_voisin+angle1) else: angle2=angle1 if angle2==None: angle2=(angle1)%360 start_line=QgsGeometry.fromPolyline([QgsPoint(pt1.asPoint().x()-40*echelle*t*math.cos((180-angle2)*math.pi/180),pt1.asPoint().y()-40*echelle*t*math.sin((180-angle2)*math.pi/180)),QgsPoint(pt1.asPoint().x(),pt1.asPoint().y())]) int1=buf.intersection(start_line) start_line2=QgsGeometry.fromPolyline([QgsPoint(pt1.asPoint().x()+40*echelle*t*math.cos((180-angle2)*math.pi/180),pt1.asPoint().y()+40*echelle*t*math.sin((180-angle2)*math.pi/180)),QgsPoint(pt1.asPoint().x(),pt1.asPoint().y())]) int3=buf.intersection(start_line2) if int1.isMultipart(): points=int1.asMultiPoint() dmax=1e38 for p in points: d=pt1.distance(QgsGeometry.fromPointXY(p)) if d<dmax: dmax=d pmax=p int1=QgsGeometry.fromPointXY(pmax) if int3.isMultipart(): points=int3.asMultiPoint() dmax=1e38 for p in points: d=pt1.distance(QgsGeometry.fromPointXY(p)) if d<dmax: dmax=d pmax=p int3=QgsGeometry.fromPointXY(pmax) ###point fin debut=spatial.intersects(QgsGeometry.buffer(pt2,10,3).boundingBox()) fe= [f for f in debut] for f in fe: ff=QgsLineString() geom=lignes[f].geometry() geom.convertToSingleType() ff.fromWkt(geom.asWkt()) if pt2.distance(QgsGeometry(ff.startPoint()))<10: if lignes[f] not in feats: feats.append(f) elif pt2.distance(QgsGeometry(ff.endPoint()))<10: if lignes[f] not in feats: feats.append(f) distances={} angles={} for i in feats: longueur=lignes[i].geometry().length() if not(geometry.id()==i): distances[i]=lignes[i].geometry().lineLocatePoint(pt2) if distances[i]<dist_min: angles[i]=(lignes[i].geometry().interpolateAngle(min(dist_min,longueur))*180/math.pi)%360 else: angles[i]=(((lignes[i].geometry().interpolateAngle(longueur-min(dist_min,longueur))*180)/math.pi)+180)%360 else: angle1=((lignes[i].geometry().interpolateAngle(longueur-min(dist_min,longueur))*180/math.pi)) angle_maxi=1e38 voisin=None angle_voisin=None angle2=None if len(distances)==0: angle=(angle1)%360 angle2=angle1 angle_voisin=angle2 for i in distances: if distances[i]<dist_min: angle=(angles[i]) min_angle=min(abs((angle+180)%360-(angle1+180)%360),abs(angle-angle1)) if min_angle<angle_maxi: angle_maxi=min_angle angle_voisin=angle voisin=i else: angle=(angles[i]) min_angle=min(abs((angle+180)%360-(angle1+180)%360),abs(angle-angle1)) if min_angle<angle_maxi: angle_maxi=min_angle angle_voisin=angle voisin=i if min(abs((angle_voisin+180)%360-(angle1+180)%360),abs(angle_voisin-angle1))<angle_max: if abs((angle_voisin+180)%360-(angle1+180)%360)<abs(angle_voisin-angle1): angle2=(0.5*(((angle_voisin+180)%360+(angle1+180)%360))+180)%360 else: angle2=0.5*(angle_voisin+angle1) else: angle2=angle1 if angle2==None: angle2=(angle1)%360 end_line=QgsGeometry.fromPolyline([QgsPoint(pt2.asPoint().x()-40*echelle*t*math.cos((180-angle2)*math.pi/180),pt2.asPoint().y()-40*echelle*t*math.sin((180-angle2)*math.pi/180)),QgsPoint(pt2.asPoint().x(),pt2.asPoint().y())]) int2=buf.intersection(end_line) end_line2=QgsGeometry.fromPolyline([QgsPoint(pt2.asPoint().x()+40*echelle*t*math.cos((180-angle2)*math.pi/180),pt2.asPoint().y()+40*echelle*t*math.sin((180-angle2)*math.pi/180)),QgsPoint(pt2.asPoint().x(),pt2.asPoint().y())]) int4=buf.intersection(end_line2) int5=start_line.intersection(end_line) int6=start_line2.intersection(end_line2) m5=-1 m6=-1 if int5.type()==0: if int5.within(buf_poly): m5=1 if int6.type()==0: if int6.within(buf_poly): m6=1 if int2.isMultipart(): points=int2.asMultiPoint() dmax=1e38 for p in points: d=pt2.distance(QgsGeometry.fromPointXY(p)) if d<dmax: dmax=d pmax=p int2=QgsGeometry.fromPointXY(pmax) if int4.isMultipart(): points=int4.asMultiPoint() dmax=1e38 for p in points: d=pt2.distance(QgsGeometry.fromPointXY(p)) if d<dmax: dmax=d pmax=p int4=QgsGeometry.fromPointXY(pmax) #print(int1.exportToWkt(),int2.exportToWkt(),int3.exportToWkt(),int4.exportToWkt()) #QgsMessageLog.logMessage(buf.asWkt()) texte="select astext(st_union(st_snap(st_geomfromtext('"+buf.asWkt()+"',"+proj+"),st_geomfromtext('"+int1.asWkt()+"',"+proj+"),1)))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf= resultat[0][0] #QgsMessageLog.logMessage(texte) #QgsMessageLog.logMessage(buf) #QgsMessageLog.logMessage(proj) #QgsMessageLog.logMessage(int2.asWkt()) texte="select astext(st_union(st_snap(st_geomfromtext('"+buf+"',"+proj+"),st_geomfromtext('"+int2.asWkt()+"',"+proj+"),1)))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf= resultat[0][0] texte="select astext(st_union(st_snap(st_geomfromtext('"+buf+"',"+proj+"),st_geomfromtext('"+int3.asWkt()+"',"+proj+"),1)))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf= resultat[0][0] texte="select astext(st_union(st_snap(st_geomfromtext('"+buf+"',"+proj+"),st_geomfromtext('"+int4.asWkt()+"',"+proj+"),1)))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf= QgsGeometry.fromWkt(resultat[0][0]) m1=buf.lineLocatePoint(int1) m2=buf.lineLocatePoint(int2) m3=buf.lineLocatePoint(int3) m4=buf.lineLocatePoint(int4) #creation epaisseur buf_l=buf.length() m1=m1/buf_l m2=m2/buf_l m3=m3/buf_l m4=m4/buf_l if m2<m1: texte="select asText(st_line_substring(st_geomfromtext('"+buf.asWkt()+"',"+proj+")"+','+str(m2)+','+str(m1)+"))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf1= QgsGeometry.fromWkt(resultat[0][0]) else: texte="select astext(st_union(st_snap(st_line_substring(geomfromtext('"+buf.asWkt()+"',"+proj+"),0,"+str(m1)+"),st_line_substring(geomfromtext('"+buf.asWkt()+"',"+proj+"),"+str(m3)+",1),1),st_line_substring(geomfromtext('"+buf.asWkt()+"',"+proj+"),"+str(m2)+",1)))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf1= QgsGeometry.fromWkt(resultat[0][0]) if m3<m4: texte="select asText(st_line_substring(st_geomfromtext('"+buf.asWkt()+"',"+proj+")"+','+str(m3)+','+str(m4)+"))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf2= QgsGeometry.fromWkt(resultat[0][0]) else: texte="select astext(st_union(g)) from (select st_line_substring(st_geomfromtext('"+buf.asWkt()+"',"+proj+"),0,"+str(m4)+") as \"g\" union all select st_line_substring(st_geomfromtext('"+buf.asWkt()+"',"+proj+"),"+str(m3)+",1) as \"g\" )" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf2= QgsGeometry.fromWkt(resultat[0][0]) texte="select astext(st_union(st_snap(st_line_substring(geomfromtext('"+buf.asWkt()+"',"+proj+"),0,"+str(m4)+"),st_line_substring(geomfromtext('"+buf.asWkt()+"',"+proj+"),"+str(m3)+",1),1),st_line_substring(geomfromtext('"+buf.asWkt()+"',"+proj+"),"+str(m3)+",1)))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf2= QgsGeometry.fromWkt(resultat[0][0]) g1=buf g2=buf.shortestLine(int1) g2=g2.combine(g1) g3=buf.shortestLine(int2) g3=g3.combine(g2) g3=g3.combine(pt1.shortestLine(int1)) g3=g3.combine(pt2.shortestLine(int2)) g3=g3.combine(pt1.shortestLine(geometry.geometry())) g3=g3.combine(pt2.shortestLine(geometry.geometry())) g3=g3.combine(geometry.geometry()) buf3=buf1.asWkt() buf4=buf2.asWkt() if double_sens==False: if m5>0: texte="select astext(st_union(st_snap(geomfromtext('"+geometry.geometry().asWkt()+"',"+proj+"),geomfromtext('"+pt1.shortestLine(int5).asWkt()+"',"+proj+"),1),geomfromtext('"+pt1.shortestLine(int5).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt2.shortestLine(int5).asWkt()+"',"+proj+"),1),geomfromtext('"+pt2.shortestLine(int5).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] else: texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+buf1.shortestLine(int1).asWkt()+"',"+proj+"),1),geomfromtext('"+buf1.shortestLine(int1).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+buf1.shortestLine(int2).asWkt()+"',"+proj+"),1),geomfromtext('"+buf1.shortestLine(int2).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt1.shortestLine(int1).asWkt()+"',"+proj+"),1),geomfromtext('"+pt1.shortestLine(int1).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt2.shortestLine(int2).asWkt()+"'),1),geomfromtext('"+pt2.shortestLine(int2).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt1.shortestLine(geometry.geometry()).asWkt()+"',"+proj+"),1),geomfromtext('"+pt1.shortestLine(geometry.geometry()).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt2.shortestLine(geometry.geometry()).asWkt()+"',"+proj+"),1),geomfromtext('"+pt2.shortestLine(geometry.geometry()).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+geometry.geometry().asWkt()+"',"+proj+"),1),geomfromtext('"+geometry.geometry().asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] else: if m5>0: texte="select astext(st_union(st_snap(geomfromtext('"+buf4+"',"+proj+"),geomfromtext('"+pt1.shortestLine(int3).asWkt()+"',"+proj+"),1),geomfromtext('"+pt1.shortestLine(int3).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt2.shortestLine(int4).asWkt()+"',"+proj+"),1),geomfromtext('"+pt2.shortestLine(int4).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt1.shortestLine(int5).asWkt()+"',"+proj+"),1),geomfromtext('"+pt1.shortestLine(int5).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt2.shortestLine(int5).asWkt()+"',"+proj+"),1),geomfromtext('"+pt2.shortestLine(int5).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] elif m6>0: texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt1.shortestLine(int1).asWkt()+"',"+proj+"),1),geomfromtext('"+pt1.shortestLine(int1).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt2.shortestLine(int2).asWkt()+"',"+proj+"),1),geomfromtext('"+pt2.shortestLine(int2).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt1.shortestLine(int6).asWkt()+"',"+proj+"),1),geomfromtext('"+pt1.shortestLine(int6).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+pt2.shortestLine(int6).asWkt()+"',"+proj+"),1),geomfromtext('"+pt2.shortestLine(int6).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] else: texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+buf1.shortestLine(int1).asWkt()+"',"+proj+"),1),geomfromtext('"+buf1.shortestLine(int1).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+buf1.shortestLine(int2).asWkt()+"',"+proj+"),1),geomfromtext('"+buf1.shortestLine(int2).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+int3.shortestLine(int1).asWkt()+"',"+proj+"),1),geomfromtext('"+int3.shortestLine(int1).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+int4.shortestLine(int2).asWkt()+"',"+proj+"),1),geomfromtext('"+int4.shortestLine(int2).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+buf2.shortestLine(int3).asWkt()+"',"+proj+"),1),geomfromtext('"+buf2.shortestLine(int3).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+buf2.shortestLine(int4).asWkt()+"',"+proj+"),1),geomfromtext('"+buf2.shortestLine(int4).asWkt()+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_union(st_snap(geomfromtext('"+buf3+"',"+proj+"),geomfromtext('"+buf4+"',"+proj+"),1),geomfromtext('"+buf4+"',"+proj+")))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf3= resultat[0][0] texte="select astext(st_buildarea(st_union(g))) from ((select geomfromtext('"+buf3+"',"+proj+") as \"g\"))" rs = c.execute(texte) resultat=c.fetchall() conn.commit() buf=QgsGeometry.fromWkt(resultat[0][0]) return(buf)
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 do_indexjoin(self, feat): '''Find the nearest neigbour using an index, if possible Parameter: feat -- The feature for which a neighbour is sought ''' infeature = feat infeatureid = infeature.id() inputgeom = QgsGeometry(infeature.geometry()) # Shall approximate input geometries be used? if self.approximateinputgeom: # Use the centroid as the input geometry inputgeom = QgsGeometry(infeature.geometry()).centroid() # Check if the coordinate systems are equal, if not, # transform the input feature! if (self.inpvl.crs() != self.joinvl.crs()): try: inputgeom.transform(QgsCoordinateTransform( self.inpvl.crs(), self.joinvl.crs())) except: import traceback self.error.emit(self.tr('CRS Transformation error!') + ' - ' + traceback.format_exc()) self.abort = True return nnfeature = None mindist = float("inf") ## Find the closest feature! if (self.approximateinputgeom or self.inpvl.wkbType() == QGis.WKBPoint or self.inpvl.wkbType() == QGis.WKBPoint25D): # The input layer's geometry type is point, or shall be # approximated to point (centroid). # Then a join index will always be used. if (self.usejoinlayerapprox or self.joinvl.wkbType() == QGis.WKBPoint or self.joinvl.wkbType() == QGis.WKBPoint25D): # The join layer's geometry type is point, or the # user wants approximate join geometries to be used. # Then the join index nearest neighbour function can # be used without refinement. if self.selfjoin: # Self join! # Have to get the two nearest neighbours nearestids = self.joinlind.nearestNeighbor( inputgeom.asPoint(), 2) if nearestids[0] == infeatureid and len(nearestids) > 1: # The first feature is the same as the input # feature, so choose the second one nnfeature = self.joinvl.getFeatures( QgsFeatureRequest(nearestids[1])).next() else: # The first feature is not the same as the # input feature, so choose it nnfeature = self.joinvl.getFeatures( QgsFeatureRequest(nearestids[0])).next() ## Pick the second closest neighbour! ## (the first is supposed to be the point itself) ## Should we check for coinciding points? #nearestid = self.joinlind.nearestNeighbor( # inputgeom.asPoint(), 2)[1] #nnfeature = self.joinvl.getFeatures( # QgsFeatureRequest(nearestid)).next() else: # Not a self join, so we can search for only the # nearest neighbour (1) nearestid = self.joinlind.nearestNeighbor( inputgeom.asPoint(), 1)[0] nnfeature = self.joinvl.getFeatures( QgsFeatureRequest(nearestid)).next() mindist = inputgeom.distance(nnfeature.geometry()) elif (self.joinvl.wkbType() == QGis.WKBPolygon or self.joinvl.wkbType() == QGis.WKBPolygon25D or self.joinvl.wkbType() == QGis.WKBLineString or self.joinvl.wkbType() == QGis.WKBLineString25D): # Use the join layer index to speed up the join when # the join layer geometry type is polygon or line # and the input layer geometry type is point or an # approximation (point) nearestindexid = self.joinlind.nearestNeighbor( inputgeom.asPoint(), 1)[0] # Check for self join if self.selfjoin and nearestindexid == infeatureid: # Self join and same feature, so get the two # first two neighbours nearestindexes = self.joinlind.nearestNeighbor( inputgeom.asPoint(), 2) nearestindexid = nearestindexes[0] if (nearestindexid == infeatureid and len(nearestindexes) > 1): nearestindexid = nearestindexes[1] nnfeature = self.joinvl.getFeatures( QgsFeatureRequest(nearestindexid)).next() mindist = inputgeom.distance(nnfeature.geometry()) px = inputgeom.asPoint().x() py = inputgeom.asPoint().y() closefids = self.joinlind.intersects(QgsRectangle( px - mindist, py - mindist, px + mindist, py + mindist)) for closefid in closefids: if self.abort is True: break # Check for self join and same feature if self.selfjoin and closefid == infeatureid: continue closef = self.joinvl.getFeatures( QgsFeatureRequest(closefid)).next() thisdistance = inputgeom.distance(closef.geometry()) if thisdistance < mindist: mindist = thisdistance nnfeature = closef if mindist == 0: break else: # Join with no index use # Go through all the features from the join layer! for inFeatJoin in self.joinf: if self.abort is True: break joingeom = QgsGeometry(inFeatJoin.geometry()) thisdistance = inputgeom.distance(joingeom) # If the distance is 0, check for equality of the # features (in case it is a self join) if (thisdistance == 0 and self.selfjoin and infeatureid == inFeatJoin.id()): continue if thisdistance < mindist: mindist = thisdistance nnfeature = inFeatJoin # For 0 distance, settle with the first feature if mindist == 0: break else: # non-simple point input geometries (could be multipoint) if (self.nonpointexactindex): # Use the spatial index on the join layer (default). # First we do an approximate search # Get the input geometry centroid centroid = QgsGeometry(infeature.geometry()).centroid() centroidgeom = centroid.asPoint() # Find the nearest neighbour (index geometries only) nearestid = self.joinlind.nearestNeighbor(centroidgeom, 1)[0] # Check for self join if self.selfjoin and nearestid == infeatureid: # Self join and same feature, so get the two # first two neighbours nearestindexes = self.joinlind.nearestNeighbor( centroidgeom, 2) nearestid = nearestindexes[0] if nearestid == infeatureid and len(nearestindexes) > 1: nearestid = nearestindexes[1] nnfeature = self.joinvl.getFeatures( QgsFeatureRequest(nearestid)).next() mindist = inputgeom.distance(nnfeature.geometry()) # Calculate the search rectangle (inputgeom BBOX inpbbox = infeature.geometry().boundingBox() minx = inpbbox.xMinimum() - mindist maxx = inpbbox.xMaximum() + mindist miny = inpbbox.yMinimum() - mindist maxy = inpbbox.yMaximum() + mindist #minx = min(inpbbox.xMinimum(), centroidgeom.x() - mindist) #maxx = max(inpbbox.xMaximum(), centroidgeom.x() + mindist) #miny = min(inpbbox.yMinimum(), centroidgeom.y() - mindist) #maxy = max(inpbbox.yMaximum(), centroidgeom.y() + mindist) searchrectangle = QgsRectangle(minx, miny, maxx, maxy) # Fetch the candidate join geometries closefids = self.joinlind.intersects(searchrectangle) # Loop through the geometries and choose the closest # one for closefid in closefids: if self.abort is True: break # Check for self join and identical feature if self.selfjoin and closefid == infeatureid: continue closef = self.joinvl.getFeatures( QgsFeatureRequest(closefid)).next() thisdistance = inputgeom.distance(closef.geometry()) if thisdistance < mindist: mindist = thisdistance nnfeature = closef if mindist == 0: break else: # Join with no index use # Check all the features of the join layer! mindist = float("inf") # should not be necessary for inFeatJoin in self.joinf: if self.abort is True: break joingeom = QgsGeometry(inFeatJoin.geometry()) thisdistance = inputgeom.distance(joingeom) # If the distance is 0, check for equality of the # features (in case it is a self join) if (thisdistance == 0 and self.selfjoin and infeatureid == inFeatJoin.id()): continue if thisdistance < mindist: mindist = thisdistance nnfeature = inFeatJoin # For 0 distance, settle with the first feature if mindist == 0: break if not self.abort: atMapA = infeature.attributes() atMapB = nnfeature.attributes() attrs = [] attrs.extend(atMapA) attrs.extend(atMapB) attrs.append(mindist) outFeat = QgsFeature() # Use the original input layer geometry!: outFeat.setGeometry(QgsGeometry(infeature.geometry())) # Use the modified input layer geometry (could be # centroid) #outFeat.setGeometry(QgsGeometry(inputgeom)) outFeat.setAttributes(attrs) self.calculate_progress() self.features.append(outFeat)
def processAlgorithm(self, parameters, context, feedback): try: import math, random, string import pandas as pd import processing as st import networkx as nx import numpy as np except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) feedback.reportError(QCoreApplication.translate('Error',' ')) feedback.reportError(QCoreApplication.translate('Error','Error loading modules - please install the necessary dependencies')) return {} Network = self.parameterAsLayer(parameters, self.Centerline, context) Sources = self.parameterAsLayer(parameters, self.Sources, context) Targets = self.parameterAsLayer(parameters, self.Targets, context) Precision = 6 explode = st.run("native:explodelines",{'INPUT':Network,'OUTPUT':'memory:'},context=context,feedback=feedback) wF = parameters[self.Weight] fet = QgsFeature() fs = QgsFields() fs = QgsFields() fs.append(QgsField("ID", QVariant.Int)) field_names = ['Distance', 'SP_Dist'] for name in field_names: fs.append(QgsField(name, QVariant.Double)) (writer, dest_id) = self.parameterAsSink(parameters, self.Tortuosity, context, fs, QgsWkbTypes.LineString, Network.sourceCrs()) index = QgsSpatialIndex(explode['OUTPUT'].getFeatures()) orig_data = {feature.id():feature for feature in explode['OUTPUT'].getFeatures()} srcs,tgts = {},{} field_check = Sources.fields().indexFromName('ID') if field_check == -1: feedback.reportError(QCoreApplication.translate('Error','No ID attribute in Source layer')) return {} if Targets: field_check2 = Targets.fields().indexFromName('ID') if field_check2 == -1: feedback.reportError(QCoreApplication.translate('Error','No ID attribute in Targets layer')) return {} feedback.pushInfo(QCoreApplication.translate('Model','Defining Source Nodes')) total = 100.0/Sources.featureCount() c = 0 for enum,feature in enumerate(Sources.getFeatures()): #Find source node try: if total > 0: feedback.setProgress(int(enum*total)) pnt = feature.geometry().asPoint() startx,starty = (round(pnt.x(),Precision),round(pnt.y(),Precision)) featFIDs = index.nearestNeighbor(QgsPointXY(startx,starty), 2) d = 1e10 ID = None for FID in featFIDs: feature2 = orig_data[FID] testGeom = QgsGeometry.fromPointXY(QgsPointXY(startx,starty)) dist = QgsGeometry.distance(testGeom,feature2.geometry()) if dist < d: #Find closest vertex in graph to source point ID = feature['ID'] d = dist geom = feature2.geometry() start,end = geom.asPolyline() startx2,starty2 = (round(start.x(),Precision),round(start.y(),Precision)) endx2,endy2 = (round(end.x(),Precision),round(end.y(),Precision)) testGeom2 = QgsGeometry.fromPointXY(QgsPointXY(startx2,starty2)) testGeom3 = QgsGeometry.fromPointXY(QgsPointXY(endx2,endy2)) near = QgsGeometry.distance(testGeom2,testGeom) near2 = QgsGeometry.distance(testGeom3,testGeom) if near < near2: x,y = startx2,starty2 else: x,y = endx2,endy2 if ID: if ID in srcs: srcs[ID].append((x,y)) else: srcs[ID] = [(x,y)] c+=1 except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) if Targets: total = 100.0/Targets.featureCount() feedback.pushInfo(QCoreApplication.translate('Model','Defining Target Nodes')) for enum,feature in enumerate(Targets.getFeatures()): #Find source node try: if total > 0: feedback.setProgress(int(enum*total)) pnt = feature.geometry().asPoint() startx,starty = (round(pnt.x(),Precision),round(pnt.y(),Precision)) featFIDs = index.nearestNeighbor(QgsPointXY(startx,starty), 2) d = 1e10 ID = None for FID in featFIDs: feature2 = orig_data[FID] testGeom = QgsGeometry.fromPointXY(QgsPointXY(startx,starty)) dist = QgsGeometry.distance(testGeom,feature2.geometry()) if dist < d: #Find closest vertex in graph to source point ID = feature['ID'] d = dist geom = feature2.geometry() start,end = geom.asPolyline() startx2,starty2 = (round(start.x(),Precision),round(start.y(),Precision)) endx2,endy2 = (round(end.x(),Precision),round(end.y(),Precision)) testGeom2 = QgsGeometry.fromPointXY(QgsPointXY(startx2,starty2)) testGeom3 = QgsGeometry.fromPointXY(QgsPointXY(endx2,endy2)) near = QgsGeometry.distance(testGeom2,testGeom) near2 = QgsGeometry.distance(testGeom3,testGeom) if near < near2: x,y = startx2,starty2 else: x,y = endx2,endy2 if ID: if ID in tgts: tgts[ID].append((x,y)) else: tgts[ID] = [(x,y)] c+=1 except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) total = 100.0/Network.featureCount() G = nx.Graph() feedback.pushInfo(QCoreApplication.translate('Model','Building Graph')) for enum,feature in enumerate(explode['OUTPUT'].getFeatures()): #Build Graph try: if total > 0: feedback.setProgress(int(enum*total)) geom = feature.geometry() if geom.isMultipart(): start,end = geom.asMultiPolyline()[0] else: start,end = geom.asPolyline() startx,starty = (round(start.x(),Precision),round(start.y(),Precision)) endx,endy = (round(end.x(),Precision),round(end.y(),Precision)) if wF: w = feature[wF] if type(w) == int or type(w) == float: pass else: feedback.reportError(QCoreApplication.translate('Error','Weight field contains non numeric values - check for null values')) return {} w = float(W)*feature.geometry().length() else: w = feature.geometry().length() G.add_edge((startx,starty),(endx,endy),weight=w) #G.add_edge((endx,endy),(startx,starty),weight=w) except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) feedback.pushInfo(QCoreApplication.translate('Model','Creating Fracture Network')) try: for FID in srcs: sources = srcs[FID] for source in sources: if G.has_node(source): if FID in tgts: targets = tgts[FID] for target in targets: try: path = nx.single_source_dijkstra(G, source, target, weight='weight') except Exception: feedback.reportError(QCoreApplication.translate('Error','No connection found between source and target of ID %s'%(FID))) continue length = nx.single_source_dijkstra_path_length(G,source) sx = None Index = 1 for p in path[Index]: if sx == None: sx, sy = p[0], p[1] continue ex, ey = p[0], p[1] D = max([length[(sx, sy)], length[(ex, ey)]]) dx = path[Index][0][0] - ex dy = path[Index][0][1] - ey dx2 = path[Index][0][0] - sx dy2 = path[Index][0][1] - sy SP = max([math.sqrt((dx ** 2) + (dy ** 2)), math.sqrt((dx2 ** 2) + (dy2 ** 2))]) points = [QgsPointXY(sx, sy), QgsPointXY(ex, ey)] fet.setGeometry(QgsGeometry.fromPolylineXY(points)) fet.setAttributes([FID, D, SP]) writer.addFeature(fet) sx, sy = ex, ey else: length, path = nx.single_source_dijkstra(G, source, weight='weight') sx = None Index = max(length, key=length.get) source = path[Index][-1] for p in path[Index]: if sx == None: sx, sy = p[0], p[1] continue ex, ey = p[0], p[1] D = max([length[(sx, sy)], length[(ex, ey)]]) dx = path[Index][0][0] - ex dy = path[Index][0][1] - ey dx2 = path[Index][0][0] - sx dy2 = path[Index][0][1] - sy SP = max([math.sqrt((dx ** 2) + (dy ** 2)), math.sqrt((dx2 ** 2) + (dy2 ** 2))]) points = [QgsPointXY(sx, sy), QgsPointXY(ex, ey)] fet.setGeometry(QgsGeometry.fromPolylineXY(points)) fet.setAttributes([FID, D, SP]) writer.addFeature(fet) sx, sy = ex, ey except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) return {self.Tortuosity:dest_id}
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 processAlgorithm(self, parameters, context, feedback): try: import processing as st import networkx as nx except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) feedback.reportError(QCoreApplication.translate('Error',' ')) feedback.reportError(QCoreApplication.translate('Error','Error loading modules - please install the necessary dependencies')) return {} Network = self.parameterAsLayer(parameters, self.Network, context) Sources = self.parameterAsLayer(parameters, self.Sources, context) d = parameters[self.lineDen] Precision = 6 explode = st.run("native:explodelines",{'INPUT':Network,'OUTPUT':'memory:'},context=context,feedback=feedback) wF = parameters[self.Weight] fet = QgsFeature() fs = QgsFields() skip = ['Distance'] fields = Network.fields() for field in fields: if field.name() not in skip: fs.append( QgsField(field.name() ,field.type() )) fs.append(QgsField('Distance', QVariant.Double)) (writer, dest_id) = self.parameterAsSink(parameters, self.SP, context, fs, QgsWkbTypes.LineString, Network.sourceCrs()) index = QgsSpatialIndex(explode['OUTPUT'].getFeatures()) orig_data = {feature.id():feature for feature in explode['OUTPUT'].getFeatures()} srcs,data = [],{} if d > 0 and Sources.geometryType() == 1: params = {'INPUT':Sources,'INTERVAL':d,'OUTPUT':'memory:'} densify = st.run("native:densifygeometriesgivenaninterval",params,context=context,feedback=feedback) infc = densify['OUTPUT'] else: infc = Sources params = {'INPUT':infc,'OUTPUT':'memory:'} #Create nodes vertices = st.run('native:extractvertices',params,context=context,feedback=feedback) G = nx.Graph() feedback.pushInfo(QCoreApplication.translate('Model','Defining Source Nodes')) total = 100.0/vertices['OUTPUT'].featureCount() for enum,feature in enumerate(vertices['OUTPUT'].getFeatures()): #Find source node try: if total > 0: feedback.setProgress(int(enum*total)) pnt = feature.geometry().asPoint() startx,starty = (round(pnt.x(),Precision),round(pnt.y(),Precision)) featFIDs = index.nearestNeighbor(QgsPointXY(startx,starty), 2) d = 1e10 for FID in featFIDs: feature2 = orig_data[FID] testGeom = QgsGeometry.fromPointXY(QgsPointXY(startx,starty)) dist = QgsGeometry.distance(testGeom,feature2.geometry()) if dist < d: #Find closest vertex in graph to source point d = dist geom = feature2.geometry() start,end = geom.asPolyline() startx2,starty2 = (round(start.x(),Precision),round(start.y(),Precision)) endx2,endy2 = (round(end.x(),Precision),round(end.y(),Precision)) testGeom2 = QgsGeometry.fromPointXY(QgsPointXY(startx2,starty2)) testGeom3 = QgsGeometry.fromPointXY(QgsPointXY(endx2,endy2)) near = QgsGeometry.distance(testGeom2,testGeom) near2 = QgsGeometry.distance(testGeom3,testGeom) if near < near2: x,y = startx2,starty2 else: x,y = endx2,endy2 dx = startx - x dy = starty - y w = math.sqrt((dx**2)+(dy**2)) srcs.append((startx,starty)) #srcs.append((x,y)) G.add_edge((startx,starty),(x,y),weight=w) G.add_edge((x,y),(startx,starty),weight=w) except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) total = 100.0/explode['OUTPUT'].featureCount() feedback.pushInfo(QCoreApplication.translate('Model','Building Graph')) for enum,feature in enumerate(explode['OUTPUT'].getFeatures()): #Build Graph try: if total > 0: feedback.setProgress(int(enum*total)) geom = feature.geometry() if geom.isMultipart(): start,end = geom.asMultiPolyline()[0] else: start,end = geom.asPolyline() startx,starty = (round(start.x(),Precision),round(start.y(),Precision)) endx,endy = (round(end.x(),Precision),round(end.y(),Precision)) if wF: w = float(feature[wF])*feature.geometry().length() else: w = feature.geometry().length() G.add_edge((startx,starty),(endx,endy),weight=w) #G.add_edge((endx,endy),(startx,starty),weight=w) rows = [] for field in fields: if field.name() not in skip: rows.append(feature[field.name()]) data[((endx,endy),(startx,starty))] = rows except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) feedback.pushInfo(QCoreApplication.translate('Model','Creating Fracture Network')) try: if len(srcs) > 0: total = 100.0/len(srcs) lengths = None for enum,source in enumerate(srcs): feedback.setProgress(int(enum*total)) if G.has_node(source): if lengths != None: lengths2 = nx.single_source_dijkstra_path_length(G,source) for k in lengths2.keys(): if k in lengths: v = lengths2[k] v2 = lengths[k] if v < v2: lengths[k] = v else: lengths[k] = lengths2[k] del lengths2 else: lengths = nx.single_source_dijkstra_path_length(G,source) if lengths: #if connection exists for edge in G.edges(): L = -9999 for node in edge: if node in lengths: dist = lengths[node] if L == -9999: L = dist prev = node elif dist < L: L = dist midS = node midE = prev else: midS = prev midE = node if L != -9999: # Check if there is a connection if (edge[1],edge[0]) in data: rows = data[(edge[1],edge[0])] elif (edge[0],edge[1]) in data: rows = data[(edge[0],edge[1])] else: continue midEx,midEy = midE midSx,midSy = midS points = [QgsPointXY(midSx,midSy),QgsPointXY(midEx,midEy)] outGeom = QgsGeometry.fromPolylineXY(points) fet.setGeometry(outGeom) rows.extend([float(L)]) fet.setAttributes(rows) writer.addFeature(fet) except Exception as e: feedback.reportError(QCoreApplication.translate('Error','%s'%(e))) return {self.SP:dest_id}