def remove_lines_layer(self): """ Remove the municipi's boundary lines from the database's layer """ # Remove boundary lines delete_lines_list, edit_lines_dict = self.get_lines_to_manage() if delete_lines_list: with edit(self.input_lines_layer): for line_id in delete_lines_list: self.input_lines_layer.selectByExpression( f'"IdLinia"=\'{line_id}\'', QgsVectorLayer.SetSelection) for line in self.input_lines_layer.getSelectedFeatures(): self.input_lines_layer.deleteFeature(line.id()) # Edit boundary lines if edit_lines_dict: with edit(self.input_lines_layer): for line_id, dates in edit_lines_dict.items(): neighbor_valid_de, neighbor_data_alta, neighbor_ine = dates self.input_lines_layer.selectByExpression( f'"IdLinia"=\'{line_id}\'', QgsVectorLayer.SetSelection) for line in self.input_lines_layer.getSelectedFeatures(): if line['ValidDe'] < neighbor_valid_de: line['ValidDe'] = neighbor_valid_de self.input_lines_layer.updateFeature(line) if line['DataAlta'] < neighbor_data_alta: line['DataAlta'] = neighbor_data_alta self.input_lines_layer.updateFeature(line)
def splitNode(self): #Loop over the links """ try: nodesLayer = QgsProject.instance().mapLayersByName("Noeuds")[0] linksLayer = QgsProject.instance().mapLayersByName("Liens")[0] except IndexError: print("No link layer...") # Deleting the nodes with edit(nodesLayer): features = nodesLayer.selectedFeatures() if features: delIDs = [] for feature in features: delIDs.append(feature.id()) # delete the features nodesLayer.deleteFeatures(delIDs) # Adding the new nodes with edit(nodesLayer): data = [] for nodeID in delIDs: # Catch the links with that node in up_node expr = QgsExpression( "\"up_node\"='{}'".format( nodeID ) ) features = linksLayer.getFeatures( QgsFeatureRequest( expr ) ) for feature in features: point = feature.geometry().asMultiPolyline()[0][0] newFeat = QgsFeature(nodesLayer.fields()) newFeat.setGeometry(QgsGeometry.fromPointXY(point)) newFeat["type"] = 1 (res, outFeat) = nodesLayer.dataProvider().addFeatures([newFeat]) data.append([feature.id(), outFeat[0].id(), 1]) # Catch the links with that node in up_node expr = QgsExpression( "\"down_node\"='{}'".format( nodeID ) ) features = linksLayer.getFeatures( QgsFeatureRequest( expr ) ) for feature in features: point = feature.geometry().asMultiPolyline()[0][-1] newFeat = QgsFeature(nodesLayer.fields()) newFeat.setGeometry(QgsGeometry.fromPointXY(point)) newFeat["type"] = 2 (res, outFeat) = nodesLayer.dataProvider().addFeatures([newFeat]) data.append([feature.id(), outFeat[0].id(), 2]) # Assigning the new nodes to the corresponding links with edit(linksLayer): for line in data: if line[2] == 1: linksLayer.dataProvider().changeAttributeValues({line[0]:{4 : line[1]}}) else: linksLayer.dataProvider().changeAttributeValues({line[0]:{5 : line[1]}})
def mergeNodes(self): #Loop over the links """ try: nodesLayer = QgsProject.instance().mapLayersByName("Noeuds")[0] linksLayer = QgsProject.instance().mapLayersByName("Liens")[0] except IndexError: print("No link layer...") with edit(nodesLayer): features = nodesLayer.selectedFeatures() if features: n = 0 xData = [] yData = [] delIDs = [] for feature in features: n += 1 geom = feature.geometry().asPoint() delIDs.append(feature.id()) xData.append(geom[0]) yData.append(geom[1]) xBar = sum(xData)/n yBar = sum(yData)/n newGeom = QgsGeometry.fromPointXY(QgsPointXY(xBar,yBar)) newFeat = QgsFeature(nodesLayer.fields()) newFeat["type"] = 0 newFeat.setGeometry(newGeom) (res, outFeats) = nodesLayer.dataProvider().addFeatures([newFeat]) newID = outFeats[0].id() nodesLayer.deleteFeatures(delIDs) # Modification of the links layer with edit(linksLayer): # Loop over all the IDS of the deleted nodes for id in delIDs: # Catch the links that have this node in UpNode expr = QgsExpression( "\"up_node\"='{}'".format( id ) ) features = linksLayer.getFeatures( QgsFeatureRequest( expr ) ) # Loop over the links selected for feature in features: # modify the up_node to the newID linksLayer.dataProvider().changeAttributeValues({feature.id() : {4 : newID}}) # Catch the links that haver this node in DownNode expr = QgsExpression( "\"down_node\"='{}'".format( id ) ) features = linksLayer.getFeatures( QgsFeatureRequest( expr ) ) # Loop over the links selected for feature in features: # modify the down_node to the newID linksLayer.dataProvider().changeAttributeValues({feature.id() : {5 : newID}})
def remove_coast_lines_table(self): """ Remove the municipi's boundary coast line from the database's table """ with edit(self.input_coast_line_table): self.input_coast_line_table.selectByExpression( f'"IdLinia"={self.municipi_coast_line}') for feature in self.input_coast_line_table.getSelectedFeatures(): self.input_coast_line_table.deleteFeature(feature.id())
def remove_full_bt5m(self): """ Remove the municipi's BT5M full from the database's table """ self.input_full_bt5_table.selectByExpression( f'"IdLinia"={self.municipi_coast_line}', QgsVectorLayer.SetSelection) with edit(self.input_full_bt5_table): for line in self.input_full_bt5_table.getSelectedFeatures(): self.input_full_bt5_table.deleteFeature(line.id())
def remove_polygons(self): """ Remove the municipi's polygons from the database """ self.input_polygons_layer.selectByExpression( f'"CodiMuni"=\'{self.municipi_codi_ine}\'', QgsVectorLayer.SetSelection) with edit(self.input_polygons_layer): for polygon in self.input_polygons_layer.getSelectedFeatures(): self.input_polygons_layer.deleteFeature(polygon.id())
def add_lines_table(self): """ Add the input lines to the table of the Municipal Map of Catalonia """ line_id_list = self.get_lines_id_list('table') lines_features = self.lines_input_table.getFeatures() with edit(self.lines_work_table): for line in lines_features: if not line['IdLinia'] in line_id_list: self.lines_work_table.addFeature(line)
def remove_coast_line_layer(self): """ Remove the municipi's coast lines from the database's layer """ # 5065 self.input_coast_lines_layer.selectByExpression( f'"IdLinia"={self.municipi_coast_line}', QgsVectorLayer.SetSelection) with edit(self.input_coast_lines_layer): for line in self.input_coast_lines_layer.getSelectedFeatures(): self.input_coast_lines_layer.deleteFeature(line.id())
def add_lines_layer(self): """ Add the input lines to the Municipal Map of Catalonia """ line_id_list = self.get_lines_id_list('layer') lines_features = self.lines_input_layer.getFeatures() with edit(self.lines_work_layer): for line in lines_features: if not line['IdLinia'] in line_id_list: self.lines_work_layer.addFeature(line)
def add_points_table(self): """ Add the input points to the table of the Municipal Map of Catalonia """ points_features = self.points_input_layer.getFeatures() with edit(self.points_work_table): for point in points_features: fet = QgsFeature() fet.setAttributes([point['IdUFita'], point['IdFita'], point['NumTermes'], point['Monument'], point['ValidDe'], point['ValidA'], point['DataAlta'], point['DataBaixa'], point['IdLinia'], point['IdFitaR'], point['IdSector']]) self.points_work_table.addFeature(fet)
def remove_lines_table(self): """ Remove the municipi's boundary lines from the database's table """ with edit(self.input_line_table): for line in self.municipi_lines: line_txt = line_id_2_txt(line) self.input_line_table.selectByExpression( f'"IdLinia"={line_txt} and "CodiMuni" = \'{self.municipi_codi_ine}\'', QgsVectorLayer.SetSelection) for feature in self.input_line_table.getSelectedFeatures(): self.input_line_table.deleteFeature(feature.id())
def remove_points_table(self): """ Remove the municipi's points from the database's table """ for line_id in self.municipi_lines: with edit(self.input_points_table): line_id_txt = line_id_2_txt(line_id) self.input_points_table.selectByExpression( f'"IdLinia"=\'{line_id_txt}\'', QgsVectorLayer.SetSelection) for feature in self.input_points_table.getSelectedFeatures(): self.input_points_table.deleteFeature(feature.id())
def decimetritzar_lines(self): """ Edit the lines' geometry in order to round the endpoint's coordinates decimals """ with edit(self.line_layer): for line in self.line_layer.getFeatures(): tram = line.geometry().asMultiPolyline() verts = tram[0] # Comprovar si el primer i últim vertex del tram ja estan decimetritzats i per tant no s'han # de decimetritzar first_vert_decim, last_vert_decim = self.check_tram_decimals( verts) if first_vert_decim and last_vert_decim: continue first_vertex = verts[0] last_vertex = verts[-1] if len(verts) > 2: if first_vert_decim and not last_vert_decim: tram_vertex = verts[:-1] elif not first_vert_decim and last_vert_decim: tram_vertex = verts[1:] else: tram_vertex = verts[1:-1] # Round first and last vertex # First if not first_vert_decim: first_coord_x = first_vertex.x() first_coord_y = first_vertex.y() first_x, first_y = round_coordinates( first_coord_x, first_coord_y) rounded_first_vert = QgsPointXY(first_x, first_y) # Last if not last_vert_decim: last_coord_x = last_vertex.x() last_coord_y = last_vertex.y() last_x, last_y = round_coordinates(last_coord_x, last_coord_y) rounded_last_vert = QgsPointXY(last_x, last_y) # Create new geometry if len(verts) > 2: if not first_vert_decim: tram_vertex.insert(0, rounded_first_vert) if not last_vert_decim: tram_vertex.insert(len(tram_vertex), rounded_last_vert) rounded_geom = QgsGeometry.fromMultiPolylineXY( [tram_vertex]) else: pairs_vertex = [rounded_first_vert, rounded_last_vert] rounded_geom = QgsGeometry.fromMultiPolylineXY( [pairs_vertex]) # Set new geometry self.line_layer.changeGeometry(line.id(), rounded_geom)
def add_owner_type(self, ownership_csv): msg = f"adding owner type to output layer..." logger.debug(msg) QgsMessageLog.logMessage(msg, "fmsf2hms") start = datetime.now() owner_value_lookup = { 'CITY': "City", 'COUN': "County", 'STAT': "State", 'FEDE': "Federal", 'PULO': "Local government", 'PRIV': "Private-individual", 'CORP': "Private-corporate-for profit", 'CONP': "Private-corporate-nonprofit", 'FORE': "Foreign", 'NAAM': "Native American", 'MULT': "Multiple categories of ownership", 'UNSP': "Unspecified by Surveyor", 'PUUN': "Public-unspecified", 'PRUN': "Private-unspecified", 'OTHR': "Other", 'UNKN': "Unknown" } owner_info = {} with open(ownership_csv, "r") as opencsv: reader = csv.DictReader(opencsv) for row in reader: siteid, owner = row['SiteID'].rstrip(), row['OwnType'].rstrip() if owner in owner_value_lookup: owner_info[siteid] = owner_value_lookup[owner] elif owner in owner_value_lookup.values(): owner_info[siteid] = owner else: msg = f" - siteid: {siteid}; unexpected ownership: {owner}" logger.debug(msg) QgsMessageLog.logMessage(msg, "fmsf2hms") own_field_index = self.out_layer.fields().names().index("OWNERSHIP") with edit(self.out_layer): for feature in self.out_layer.getFeatures(): siteid = feature.attributes()[self.siteid_index] if siteid in owner_info: feature["OWNERSHIP"] = owner_info[siteid] self.out_layer.updateFeature(feature) msg = f" - done in {datetime.now() - start}." logger.debug(msg) QgsMessageLog.logMessage(msg, "fmsf2hms")
def add_points(self): """ Add the input points to the Municipal Map of Catalonia """ points_features = self.points_input_layer.getFeatures() with edit(self.points_work_layer): for point in points_features: # Get a list with all the points ID fita_id_list = self.get_points_id_list() # This is done in order to avoid adding duplicated features if not point['IdFita'] in fita_id_list: geom = point.geometry() fet = QgsFeature() fet.setGeometry(geom) fet.setAttributes([point['IdFita']]) self.points_work_layer.addFeature(fet)
def deleteAllLinks(self): # select the layer of nodes try: layer = QgsProject.instance().mapLayersByName("Liens")[0] except IndexError: print("No link layer...") return # check if the layer is in edit mode if layer.isEditable(): self.stopEdition() with edit(layer): listOfIds = [feat.id() for feat in layer.getFeatures()] layer.deleteFeatures( listOfIds )
def decimetritzar_points(self): """ Edit the points' geometry in order to round the coordinates decimals """ with edit(self.point_layer): for point in self.point_layer.getFeatures(): geom = point.geometry() coord_x = geom.get().x() coord_y = geom.get().y() z = geom.get().z() # Round coordinates x, y = round_coordinates(coord_x, coord_y) if z != 0.0: z = round(z, 1) # Create new geometry rounded_point = QgsPoint(x, y, z) rounded_geom = QgsGeometry(rounded_point) # Set new geometry self.point_layer.changeGeometry(point.id(), rounded_geom)
def addLinkReverse(self): offset = 5 #Loop over the links """ try: layer = QgsProject.instance().mapLayersByName("Liens")[0] except IndexError: print("No link layer...") with edit(layer): features = layer.selectedFeatures() for feature in features: print("Feature ID: ", feature.id()) geom = feature.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType()) if geom.type()==QgsWkbTypes.LineGeometry: if geomSingleType: print("Dev Notes : maybe useless here but if you see it in the console, this case has to be handled") else: x = geom.asMultiPolyline() newPoints = [] # first point X = x[0][0][0] + offset*(x[0][0][1]-x[0][1][1])/((x[0][1][0]-x[0][0][0])**2 + (x[0][1][1]-x[0][0][1])**2)**0.5 Y = x[0][0][1] + offset*(x[0][1][0]-x[0][0][0])/((x[0][1][0]-x[0][0][0])**2 + (x[0][1][1]-x[0][0][1])**2)**0.5 newPoints.append(QgsPointXY(X,Y)) #last point N = len(x[0]) - 1 for i in range(1,N): x1 = x[0][i][0] + offset*(x[0][i-1][1]-x[0][i][1])/((x[0][i][0]-x[0][i-1][0])**2 + (x[0][i][1]-x[0][i-1][1])**2)**0.5 y1 = x[0][i][1] + offset*(x[0][i][0]-x[0][i-1][0])/((x[0][i][0]-x[0][i-1][0])**2 + (x[0][i][1]-x[0][i-1][1])**2)**0.5 x2 = x[0][i][0] + offset*(x[0][i][1]-x[0][i+1][1])/((x[0][i+1][0]-x[0][i][0])**2 + (x[0][i+1][1]-x[0][i][1])**2)**0.5 y2 = x[0][i][1] + offset*(x[0][i+1][0]-x[0][i][0])/((x[0][i+1][0]-x[0][i][0])**2 + (x[0][i+1][1]-x[0][i][1])**2)**0.5 X = (x1 + x2)/2 Y = (y1 + y2)/2 # TODO !! Faire quand Etienne sera parti newPoints.append(QgsPointXY(X,Y)) #last point X = x[0][N][0] + offset*(x[0][N-1][1]-x[0][N][1])/((x[0][N][0]-x[0][N-1][0])**2 + (x[0][N][1]-x[0][N-1][1])**2)**0.5 Y = x[0][N][1] + offset*(x[0][N][0]-x[0][N-1][0])/((x[0][N][0]-x[0][N-1][0])**2 + (x[0][N][1]-x[0][N-1][1])**2)**0.5 newPoints.append(QgsPointXY(X,Y)) # reverse newPoints.reverse() newgeom = QgsGeometry.fromMultiPolylineXY([newPoints]) feat = QgsFeature(layer.fields()) feat.setGeometry(newgeom) (res, outFeats) = layer.dataProvider().addFeatures([feat])
def remove_points_layer(self): """ Remove the municipi's points from the database's layer Atenció: en alguns casos no esborra correctament les fites 3 termes. """ point_id_remove_list = self.get_points_to_remove() with edit(self.input_points_layer): for point_id in point_id_remove_list: self.input_points_layer.selectByExpression( f'"IdFita"=\'{point_id}\'', QgsVectorLayer.SetSelection) for feature in self.input_points_layer.getSelectedFeatures(): self.input_points_layer.deleteFeature(feature.id()) box = QMessageBox() box.setIcon(QMessageBox.Warning) box.setText( "Enrecorda't de revisar que s'han esborrat\ncorrectament totes les fites 3 termes." ) box.exec_()
def reverseSelectedLinks(self): try: layer = QgsProject.instance().mapLayersByName("Liens")[0] except IndexError: print("No link layer...") return with edit(layer): features = layer.selectedFeatures() for feature in features: geom = feature.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType()) if geom.type()==QgsWkbTypes.LineGeometry: if geomSingleType: #TODO print("Dev Notes : maybe useless here but if you see it in the console, this case has to be handled") else: x = geom.asMultiPolyline() x[0].reverse() newgeom = QgsGeometry.fromMultiPolylineXY(x) layer.changeGeometry(feature.id(),newgeom)
def importDemand(self): try: periodsLayer = QgsProject.instance().mapLayersByName("Periods")[0] demandLayer = QgsProject.instance().mapLayersByName("Demand")[0] vTypesLayer = QgsProject.instance().mapLayersByName("VehicleTypes")[0] nodesLayer = QgsProject.instance().mapLayersByName("Noeuds")[0] except IndexError: print("No Layers") """displays open file dialog to select bus track input file""" file, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select Demand ODS File", "", "GeoPackage (*.ods)") data = json.loads(json.dumps(get_data(file))) # delete everything in periods and Demand with edit(periodsLayer): # delete all periods features listOfIds = [feat.id() for feat in periodsLayer.getFeatures()] periodsLayer.deleteFeatures( listOfIds ) with edit(demandLayer): # delete all periods features listOfIds = [feat.id() for feat in demandLayer.getFeatures()] demandLayer.deleteFeatures( listOfIds ) # Sheets vehicleTypes = [] periodsString = [] for key in list(data.keys()): if not key.split(' ')[0] in vehicleTypes: vehicleTypes.append(key.split(' ')[0]) if not key.split(' ')[1] in periodsString: periodsString.append(key.split(' ')[1]) with edit(periodsLayer): for i in range(len(periodsString)): feat = QgsFeature(periodsLayer.fields()) feat['fid'] = i+1 feat['start'] = convertHHMMSStoSeconds(periodsString[i]) (res, outFeats) = periodsLayer.dataProvider().addFeatures([feat]) with edit(demandLayer): feat = QgsFeature() newFeats = [] for sheet in data: lines = data[sheet] # Get vehicle type id expr = QgsExpression( "\"name\"='{}'".format( sheet.split(' ')[0] ) ) vTypesLayer.getFeatures( QgsFeatureRequest( expr ) ).nextFeature(feat) vTypeID = feat.id() # Get period id expr = QgsExpression( "\"start\"='{}'".format(convertHHMMSStoSeconds(sheet.split(' ')[1] ) )) periodsLayer.getFeatures( QgsFeatureRequest( expr ) ).nextFeature(feat) periodID = feat.id() ##### ADVANCEMENT total = len(vehicleTypes)*len(periodsString)*(len(lines)-1)*(len(lines[0])-1) # for each cell for i in range(1,len(lines)): for j in range(1,len(lines[0])): # lines[i][j] is the value of flow from origin lines[i][0] # to destination lines[0][j] # Get origin feature id nodeNameCalc = lines[i][0] if nodesLayer.getFeatures(QgsFeatureRequest(QgsExpression("\"name\"='{}'".format(nodeNameCalc)))).nextFeature(feat): originID = feat.id() else: originID = int(nodeNameCalc.split('_')[1]) # Get destination feature id nodeNameCalc = lines[0][j] if nodesLayer.getFeatures(QgsFeatureRequest(QgsExpression("\"name\"='{}'".format(nodeNameCalc)))).nextFeature(feat): destinationID = feat.id() else: destinationID = int(nodeNameCalc.split('_')[1]) # Create new feature of demands newFeat = QgsFeature(demandLayer.fields()) newFeat['origin'] = originID newFeat['destination'] = destinationID newFeat['vehicle_type'] = vTypeID newFeat['period'] = periodID newFeat['flow'] = lines[i][j] newFeats.append(newFeat) (res, outFeats) = demandLayer.dataProvider().addFeatures(newFeats)
def generateEmptyDemand(self): # get layers try: nodeLayer = QgsProject.instance().mapLayersByName("Noeuds")[0] vTypeLayer = QgsProject.instance().mapLayersByName("VehicleTypes")[0] periodsLayer = QgsProject.instance().mapLayersByName("Periods")[0] generalLayer = QgsProject.instance().mapLayersByName("General")[0] except IndexError: print("No layers") return # edit the period layer to take into account the generalLayer # Delete all periods with edit(periodsLayer): listOfIds = [feat.id() for feat in periodsLayer.getFeatures()] periodsLayer.deleteFeatures( listOfIds ) with edit(periodsLayer): start = float(generalLayer.getFeature(1).attribute(2)) end = float(generalLayer.getFeature(2).attribute(2)) period = float(generalLayer.getFeature(3).attribute(2)) count = 1 newFeats = [] currTime = start while currTime < end + period: newFeat = QgsFeature(periodsLayer.fields()) newFeat["fid"] = count newFeat["start"] = start + period*(count-1) newFeats.append(newFeat) currTime += period count += 1 periodsLayer.dataProvider().addFeatures(newFeats) folder = os.path.dirname( unicode( nodeLayer.dataProvider().dataSourceUri() ) ) #TODO periodFeats = [feat for feat in periodsLayer.getFeatures()] if len(periodFeats)==0: #TODO 6h to 11h with 30min duration start = 0 period = 15*60 nb_periods = 4 elif len(periodFeats)==1: # TODO: start at start during 1h with 30 minutes start = periodFeats[0]['start'] period = 15*60 nb_periods = 4 else: start = periodFeats[0]['start'] period = periodFeats[1]['start'] - start nb_periods = len(periodFeats) template = [] data = {} # Destination firstLine = [''] N = 0 expr = QgsExpression( "\"type\"='{}'".format( 2 ) ) nodes = nodeLayer.getFeatures( QgsFeatureRequest( expr ) ) for node in nodes: N+=1 if node['name']: firstLine.append(node['name']) else: firstLine.append('fid_' + str(node.id())) template.append(firstLine) # Origins expr = QgsExpression( "\"type\"='{}'".format( 1 ) ) nodes = nodeLayer.getFeatures( QgsFeatureRequest( expr ) ) for node in nodes: if node['name']: line = [node['name']] else: line = ['fid_' + str(node.id())] line.extend(N*[0.0]) template.append(line) # Write vtypes = vTypeLayer.getFeatures() for vtype in vtypes: for j in range(nb_periods): data.update({vtype['name'] + ' ' + convertSecondsTohhmmss(start+j*period) : template}) save_data(os.path.join(folder,'OD_matrix.ods'),data)
def generateNodes(self): # commit all self.stopEdition() #Loop over the links """ try: linkLayer = QgsProject.instance().mapLayersByName("Liens")[0] nodeLayer = QgsProject.instance().mapLayersByName("Noeuds")[0] except IndexError: print("No link layer...") return # Delete all nodes with edit(nodeLayer): listOfIds = [feat.id() for feat in nodeLayer.getFeatures()] nodeLayer.deleteFeatures( listOfIds ) # Loop on all the feratures to store the first points features = linkLayer.getFeatures() coords = np.zeros([2*linkLayer.featureCount() , 4]) i = 0 for feature in features: coords[i,0] = feature.id() coords[i,1] = 0 geom = feature.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType()) if geom.type()==QgsWkbTypes.LineGeometry: if geomSingleType: x = geom.asPolyline() coords[i,2] = x[0][0] coords[i,3] = x[0][1] else: x = geom.asMultiPolyline() coords[i,2] = x[0][0][0] coords[i,3] = x[0][0][1] i+=1 # Loop on all the features tp store the last points features = linkLayer.getFeatures() for feature in features: coords[i,0] = feature.id() coords[i,1] = 2 geom = feature.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType()) if geom.type()==QgsWkbTypes.LineGeometry: if geomSingleType: x = geom.asPolyline() coords[i,2] = x[-1][0] coords[i,3] = x[-1][1] else: x = geom.asMultiPolyline() coords[i,2] = x[0][-1][0] coords[i,3] = x[0][-1][1] i+=1 # Get the uniques coords to ensure that the nodes are not duplicated uniques = np.unique(coords[:,2:4], axis=0) # Generate the nodes with edit(nodeLayer): for i in range(len(uniques)): feat = QgsFeature(nodeLayer.fields()) feat['fid'] = i+1 feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(uniques[i,0], uniques[i,1]))) (res, outFeats) = nodeLayer.dataProvider().addFeatures([feat]) # Assign the nodes to the links features = nodeLayer.getFeatures() with edit(linkLayer): # Loop over the nodes count = 0 for feature in features: X = feature.geometry().asPoint()[0] Y = feature.geometry().asPoint()[1] # get the lines in coords where the node appear lines = np.unique(np.where(coords[:,2:4]==[X,Y])[0]) # get fids fidsAndPlaces = coords[lines, 0:2] fidsAndPlaces = fidsAndPlaces[fidsAndPlaces[:,0].argsort()] fids = list(fidsAndPlaces[:,0]) # get places 0 = upstram / 2 = downstream places = list(fidsAndPlaces[:,1]) # get Features corresponding to the fids linkFeats = linkLayer.getFeatures(QgsFeatureRequest().setFilterFids(fids)) i = 0 # Loop over the features for feat in linkFeats: # if it is an upstream node if places[i] == 0.: linkLayer.dataProvider().changeAttributeValues({feat.id() : {4 : feature.id()}}) # if it is a downstream node elif places[i] == 2.: linkLayer.dataProvider().changeAttributeValues({feat.id() : {5 : feature.id()}}) else: print('ERROR HERE / Search for E-001') i += 1 # Assign types with edit(nodeLayer): nodes = nodeLayer.getFeatures() for node in nodes: # Test if links has this node as upstream node expr = QgsExpression( "\"up_node\"='{}'".format( node.id() ) ) features = linkLayer.getFeatures( QgsFeatureRequest( expr ) ) # if it is empty if not features.nextFeature(QgsFeature()): nodeLayer.dataProvider().changeAttributeValues({node.id() : {1 : 2}}) continue # Test if links has this node as downstream node expr = QgsExpression( "\"down_node\"='{}'".format( node.id() ) ) features = linkLayer.getFeatures( QgsFeatureRequest( expr ) ) # if it is empty if not features.nextFeature(QgsFeature()): nodeLayer.dataProvider().changeAttributeValues({node.id() : {1 : 1}}) continue nodeLayer.dataProvider().changeAttributeValues({node.id() : {1 : 0}})
def add_bt5_full_table(self): """ Add the input BT5M table of the Municipal Map of Catalonia """ fulls_features = self.bt5_full_input_table.getFeatures() with edit(self.bt5_full_work_table): for full in fulls_features: self.bt5_full_work_table.addFeature(full)
def add_coast_lines_table(self): """ Add the input coast lines to the table of the Municipal Map of Catalonia """ coast_lines_features = self.coast_lines_input_table.getFeatures() with edit(self.coast_lines_work_table): for coast_line in coast_lines_features: self.coast_lines_work_table.addFeature(coast_line)
def add_polygons(self): """ Add the input polygons to the Municipal Map of Catalonia """ polygons_features = self.polygons_input_layer.getFeatures() with edit(self.polygons_work_layer): for polygon in polygons_features: self.polygons_work_layer.addFeature(polygon)
def add_coast_lines_layer(self): """ Add the input coast lines to the Municipal Map of Catalonia """ coast_lines_features = self.coast_lines_input_layer.getFeatures() with edit(self.coast_lines_work_layer): for coast_line in coast_lines_features: self.coast_lines_work_layer.addFeature(coast_line)