def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) fields = source.fields() x_field_index = fields.lookupField(self.parameterAsString(parameters, self.XFIELD, context)) y_field_index = fields.lookupField(self.parameterAsString(parameters, self.YFIELD, context)) z_field_index = -1 if self.parameterAsString(parameters, self.ZFIELD, context): z_field_index = fields.lookupField(self.parameterAsString(parameters, self.ZFIELD, context)) m_field_index = -1 if self.parameterAsString(parameters, self.MFIELD, context): m_field_index = fields.lookupField(self.parameterAsString(parameters, self.MFIELD, context)) wkb_type = QgsWkbTypes.Point if z_field_index >= 0: wkb_type = QgsWkbTypes.addZ(wkb_type) if m_field_index >= 0: wkb_type = QgsWkbTypes.addM(wkb_type) target_crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, wkb_type, target_crs) request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry) features = source.getFeatures() total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, feature in enumerate(features): if feedback.isCanceled(): break feedback.setProgress(int(current * total)) attrs = feature.attributes() try: x = float(attrs[x_field_index]) y = float(attrs[y_field_index]) point = QgsPoint(x, y) if z_field_index >= 0: try: point.addZValue(float(attrs[z_field_index])) except: point.addZValue(0.0) if m_field_index >= 0: try: point.addMValue(float(attrs[m_field_index])) except: point.addMValue(0.0) feature.setGeometry(QgsGeometry(point)) except: pass # no geometry sink.addFeature(feature) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.getParameterValue(self.INPUT) vlayer = QgsProcessingUtils.mapLayerFromString(source, context) output = self.getOutputFromName(self.OUTPUT) fields = vlayer.fields() x_field_index = fields.lookupField(self.getParameterValue(self.XFIELD)) y_field_index = fields.lookupField(self.getParameterValue(self.YFIELD)) z_field_index = None if self.getParameterValue(self.ZFIELD): z_field_index = fields.lookupField(self.getParameterValue(self.ZFIELD)) m_field_index = None if self.getParameterValue(self.MFIELD): m_field_index = fields.lookupField(self.getParameterValue(self.MFIELD)) wkb_type = QgsWkbTypes.Point if z_field_index is not None: wkb_type = QgsWkbTypes.addZ(wkb_type) if m_field_index is not None: wkb_type = QgsWkbTypes.addM(wkb_type) crsId = self.getParameterValue(self.TARGET_CRS) target_crs = QgsCoordinateReferenceSystem() target_crs.createFromUserInput(crsId) writer = output.getVectorWriter(fields, wkb_type, target_crs, context) features = QgsProcessingUtils.getFeatures(vlayer, context) total = 100.0 / QgsProcessingUtils.featureCount(vlayer, context) for current, feature in enumerate(features): feedback.setProgress(int(current * total)) attrs = feature.attributes() try: x = float(attrs[x_field_index]) y = float(attrs[y_field_index]) point = QgsPoint(x, y) if z_field_index is not None: try: point.addZValue(float(attrs[z_field_index])) except: point.addZValue(0.0) if m_field_index is not None: try: point.addMValue(float(attrs[m_field_index])) except: point.addMValue(0.0) feature.setGeometry(QgsGeometry(point)) except: pass # no geometry writer.addFeature(feature) del writer
def calcIsoPoints(self, analysis_point_list, max_dist, entry_cost_start=0): iso_pointcloud = dict() for counter, point in enumerate(analysis_point_list): self.feedback.pushInfo( "[QNEAT3Network][calcIsoPoints] Processing Point {}".format( counter)) dijkstra_query = self.calcDijkstra(point.network_vertex_id, 0) tree = dijkstra_query[0] cost = dijkstra_query[1] current_start_point_id = point.point_id #id of the input point current_vertex_id = point.network_vertex_id entry_cost = point.entry_cost field_type = getFieldDatatypeFromPythontype(current_start_point_id) #startpoints are not part of the Query so they have to be added manually before #dikstra is called. start_vertex_feat = QgsFeature() start_vertex_fields = QgsFields() start_vertex_fields.append( QgsField('vertex_id', QVariant.Int, '', 254, 0)) start_vertex_fields.append( QgsField('cost', QVariant.Double, '', 254, 7)) start_vertex_fields.append( QgsField('origin_point_id', field_type, '', 254, 7)) start_vertex_feat.setFields(start_vertex_fields) start_vertex_feat['vertex_id'] = current_vertex_id start_vertex_feat['cost'] = entry_cost start_vertex_feat['origin_point_id'] = current_start_point_id pt_m = QgsPoint( self.network.vertex(current_vertex_id).point().x(), self.network.vertex(current_vertex_id).point().y()) pt_m.addMValue(entry_cost) geom = QgsGeometry(pt_m) start_vertex_feat.setGeometry(geom) iso_pointcloud.update({current_vertex_id: start_vertex_feat}) i = 0 real_cost = entry_cost_start while i < len(cost): #as long as costs at vertex i is greater than iso_distance and there exists an incoming edge (tree[i]!=-1) #consider it as a possible catchment polygon element if tree[i] != -1: fromVertexId = self.network.edge(tree[i]).toVertex() real_cost += cost[fromVertexId] + entry_cost #if the costs of the current vertex are lower than the radius, append the vertex id to results. if real_cost <= max_dist: #build feature feat = QgsFeature() fields = QgsFields() fields.append( QgsField('vertex_id', QVariant.Int, '', 254, 0)) fields.append( QgsField('cost', QVariant.Double, '', 254, 7)) fields.append( QgsField('origin_point_id', field_type, '', 254, 7)) feat.setFields(fields) feat['vertex_id'] = fromVertexId feat['cost'] = real_cost feat['origin_point_id'] = current_start_point_id pt_xy = self.network.vertex( fromVertexId).point() #QGIS API BUG: remove line) pt_m = QgsPoint( pt_xy.x(), pt_xy.y() ) #QGIS API BUG: Change back to QgsPoint(self.network.vertex(fromVertexId).point()) pt_m.addMValue((500 - cost[fromVertexId]) * 2) geom = QgsGeometry(pt_m) feat.setGeometry(geom) if fromVertexId not in iso_pointcloud: #ERROR: FIRST POINT IN POINTCLOUD WILL NEVER BE ADDED iso_pointcloud.update({fromVertexId: feat}) if fromVertexId in iso_pointcloud.keys( ) and iso_pointcloud.get( fromVertexId)['cost'] > real_cost: #if the vertex already exists in the iso_pointcloud and the cost is greater than the existing cost del iso_pointcloud[fromVertexId] #iso_pointcloud.pop(toVertexId) iso_pointcloud.update({fromVertexId: feat}) #count up to next vertex i = i + 1 if (i % 10000) == 0: self.feedback.pushInfo( "[QNEAT3Network][calcIsoPoints] Added {} Nodes to iso pointcloud..." .format(i)) return iso_pointcloud.values() #list of QgsFeature (=QgsFeatureList)