def densify(geometry, maxsegmentlength): """Densifies geometry vertices, so no segment is longer than maxsegmentlength Only implemented for linestring at the time being""" g = togeometry(geometry) type = QGis.flatType((g.wkbType())) if not type == QGis.WKBLineString: raise NotImplementedError("Densify is only implemented for LineStrings at the moment") input_coords = tocoordinates(g) output_coords = [] maxsegmentlength = float(maxsegmentlength) for ix in xrange(len(input_coords) - 1): p0 = input_coords[ix] p1 = input_coords[ix + 1] output_coords.append(QgsPoint(p0)) # Avoid calculating these values at the cost of performace. in_segment = QgsGeometry.fromPolyline([p0, p1]) in_segment_length = in_segment.length() segcount = int(ceil(in_segment_length / maxsegmentlength)) if segcount > 1: new_seg_length = float(in_segment_length) / segcount for i in xrange(1,segcount): new_p = in_segment.interpolate(new_seg_length * i).asPoint() output_coords.append(new_p) # Add last coord output_coords.append(input_coords[-1]) return QgsGeometry.fromPolyline(output_coords)
def drawLimits (self): self.dlg.listWidget.clear() #comprobate if the layer already exists and delete it for lyr in QgsMapLayerRegistry.instance().mapLayers().values(): if lyr.name() == "Limites": QgsMapLayerRegistry.instance().removeMapLayer( lyr.id() ) break #crete a vector layer with a expecific name and color v_layer = QgsVectorLayer("LineString", "Limites", "memory") symbols =v_layer.rendererV2().symbols() symbol=symbols[0] symbol.setColor(QColor('magenta')) #create the provider and add the layer pr = v_layer.dataProvider() QgsMapLayerRegistry.instance().addMapLayers([v_layer]) seg = QgsFeature() iterations=len(self.tool.polygon) #draw the lines between the buttons in order for i in range (iterations): if i== iterations-1: seg.setGeometry(QgsGeometry.fromPolyline([self.tool.polygon[i], self.tool.polygon[0]])) else: seg.setGeometry(QgsGeometry.fromPolyline([self.tool.polygon[i], self.tool.polygon[i+1]])) #add the lines to the provider and update the layer pr.addFeatures( [ seg ] ) v_layer.updateExtents() v_layer.triggerRepaint() #add the points to the QlistWidget for i in range (len(self.tool.polygon)): self.addItem(i)
def _rectangleGridLine(self, writer, width, height, originX, originY, hSpacing, vSpacing): ft = QgsFeature() columns = int(math.floor(float(width) / hSpacing)) rows = int(math.floor(float(height) / vSpacing)) # Longitude lines for col in xrange(0, columns + 1): polyline = [] x = originX + (col * hSpacing) for row in xrange(0, rows + 1): y = originY + (row * vSpacing) polyline.append(QgsPoint(x, y)) ft.setGeometry(QgsGeometry.fromPolyline(polyline)) ft.setAttributes([x, originY, x, originY + (rows * vSpacing)]) writer.addFeature(ft) # Latitude lines for row in xrange(0, rows + 1): polyline = [] y = originY + (row * vSpacing) for col in xrange(0, columns + 1): x = originX + (col * hSpacing) polyline.append(QgsPoint(x, y)) ft.setGeometry(QgsGeometry.fromPolyline(polyline)) ft.setAttributes([originX, y, originX + (col * hSpacing), y]) writer.addFeature(ft)
def finishGeom (self, numPoints): if self.maxPoints == 1: geom = QgsGeometry.fromPoint(self.captureList[0]) elif self.isPolygon and numPoints == 2: geom = QgsGeometry.fromPolyline(self.captureList) #geom = QgsGeometry.fromRect(geom.boundingBox()) elif self.isPolygon: geom = QgsGeometry.fromPolygon([self.captureList]) else: geom = QgsGeometry.fromPolyline(self.captureList) geom.simplify(0.00001) geom.transform(QgsCoordinateTransform( self.canvas.mapSettings().destinationCrs(), self.crs)) if self.yx: i = 0 vertex = geom.vertexAt(i) while (vertex != QgsPoint(0,0)): x = vertex.x() y = vertex.y() geom.moveVertex(y, x, i) i+=1 vertex = geom.vertexAt(i) self.selectionFinished.emit(geom.exportToWkt()) self.clearMapCanvas()
def test_identify_segment_center(self): """Test for identify_segment_center.""" points = [ (QgsPoint(0, 0)), (QgsPoint(1, 0)), (QgsPoint(2, 0)), ] geom = QgsGeometry.fromPolyline(points) line = QgsFeature() line.setGeometry(geom) center = identify_segment_center(line) expected_center = QgsPoint(1, 0) message = 'Expected %s but I got %s' % (expected_center, center) self.assertEqual(expected_center, center, message) points.append(QgsPoint(5, 0)) geom = QgsGeometry.fromPolyline(points) line = QgsFeature() line.setGeometry(geom) center = identify_segment_center(line) expected_center = QgsPoint(2.5, 0) message = 'Expected %s but I got %s' % (expected_center, center) self.assertEqual(expected_center, center, message)
def canvasReleaseEvent(self,event): if event.button() == Qt.RightButton: self.points.append(QgsPoint( self.toMapCoordinates( event.pos()) ) ) if len(self.points) <= 1 :return self.rubberBand.setToGeometry( QgsGeometry.fromPolyline(self.points), None ) self.callback( self.rubberBand ) QgsMapTool.deactivate(self) else: self.points.append(QgsPoint( self.toMapCoordinates(event.pos()) ) ) if len(self.points) <= 1 : return self.rubberBand.setToGeometry( QgsGeometry.fromPolyline(self.points), None )
def test_ExpressionFieldEllipsoidLengthCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("LineString?crs=epsg:3111&field=pk:int", "vl", "memory") self.assertTrue(temp_layer.isValid()) f1 = QgsFeature(temp_layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry(QgsGeometry.fromPolyline([QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853)])) temp_layer.dataProvider().addFeatures([f1]) # set project CRS and ellipsoid srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid()) QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84") QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Meters)) idx = temp_layer.addExpressionField('$length', QgsField('length', QVariant.Double)) # NOQA # check value f = temp_layer.getFeatures().next() expected = 26932.156 self.assertAlmostEqual(f['length'], expected, 3) # change project length unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Feet)) f = temp_layer.getFeatures().next() expected = 88360.0918635 self.assertAlmostEqual(f['length'], expected, 3)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields().toList(), QGis.WKBLineString, layer.crs()) outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() current = 0 features = vector.features(layer) total = 100.0 / float(len(features)) for f in features: inGeom = f.geometry() attrs = f.attributes() lineList = self.extractAsLine(inGeom) outFeat.setAttributes(attrs) for h in lineList: outFeat.setGeometry(outGeom.fromPolyline(h)) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def reprojectRubberBand(self, geom): """ Reprojects the geometry geom: QgsGeometry """ # Defining the crs from src and destiny epsg = self.canvas.mapSettings().destinationCrs().authid() crsSrc = QgsCoordinateReferenceSystem(epsg) #getting srid from something like 'EPSG:31983' layer = self.canvas.currentLayer() srid = layer.crs().authid() crsDest = QgsCoordinateReferenceSystem(srid) #here we have to put authid, not srid # Creating a transformer coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest) lyrType = self.iface.activeLayer().geometryType() # Transforming the points if lyrType == QGis.Line: geomList = geom.asPolyline() elif lyrType == QGis.Polygon: geomList = geom.asPolygon() newGeom = [] for j in xrange(len(geomList)): if lyrType == QGis.Line: newGeom.append(coordinateTransformer.transform(geomList[j])) elif lyrType == QGis.Polygon: line = geomList[j] for i in xrange(len(line)): point = line[i] newGeom.append(coordinateTransformer.transform(point)) if lyrType == QGis.Line: return QgsGeometry.fromPolyline(newGeom + [newGeom[0]]) elif lyrType == QGis.Polygon: return QgsGeometry.fromPolygon([newGeom])
def densifyGeometry(self, geometry, pointsNumber, isPolygon): output = [] if isPolygon: if geometry.isMultipart(): polygons = geometry.asMultiPolygon() for poly in polygons: p = [] for ring in poly: p.append(self.densify(ring, pointsNumber)) output.append(p) return QgsGeometry.fromMultiPolygon(output) else: rings = geometry.asPolygon() for ring in rings: output.append(self.densify(ring, pointsNumber)) return QgsGeometry.fromPolygon(output) else: if geometry.isMultipart(): lines = geometry.asMultiPolyline() for points in lines: output.append(self.densify(points, pointsNumber)) return QgsGeometry.fromMultiPolyline(output) else: points = geometry.asPolyline() output = self.densify(points, pointsNumber) return QgsGeometry.fromPolyline(output)
def testTouches(self): myLine = QgsGeometry.fromPolyline([QgsPoint(0, 0),QgsPoint(1, 1),QgsPoint(2, 2)]) myPoly = QgsGeometry.fromPolygon([[QgsPoint(0, 0),QgsPoint(1, 1),QgsPoint(2, 0),QgsPoint(0, 0)]]) touchesGeom = QgsGeometry.touches(myLine, myPoly) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", touchesGeom)) assert touchesGeom == True, myMessage
def _validateGeometry(self): geometryType = self.geometryType() if (geometryType == QGis.Point or geometryType == QGis.UnknownGeometry or geometryType == QGis.NoGeometry or len(self._mapPointList) < 2): return settings = QSettings() if (settings.value('/qgis/digitizing/validate_geometries', 1) == 0): return self._deleteGeometryValidation() geometry = None # QgsGeometry() if (geometryType == QGis.Line): geometry = QgsGeometry.fromPolyline(self._mapPointList) elif (geometryType == QGis.Polygon): if (len(self._mapPointList) < 3): return closed = list(self._mapPointList) closed.append(self._mapPointList[0]) geometry = QgsGeometry.fromPolygon([closed]) if (geometry is None): return self._validator = QgsGeometryValidator(geometry) self._validator.errorFound.connect(self._addGeometryError) self._validator.finished.connect(self.validationFinished) self._validator.start() self._iface.mainWindow().statusBar().showMessage(self.tr('Geometry validation started.'))
def canvasDoubleClickEvent(self,event): self.points.append(QgsPoint( self.toMapCoordinates( event.pos()) )) if len(self.points) <= 1 : return self.rubberBand.setToGeometry( QgsGeometry.fromPolyline(self.points), None ) self.callback( self.rubberBand ) QgsMapTool.deactivate(self)
def testWithin(self): myLine = QgsGeometry.fromPolyline([QgsPoint(0.5, 0.5),QgsPoint(1, 1),QgsPoint(1.5, 1.5)]) myPoly = QgsGeometry.fromPolygon([[QgsPoint(0, 0),QgsPoint(2, 0),QgsPoint(2, 2),QgsPoint(0, 2), QgsPoint(0, 0)]]) withinGeom = QgsGeometry.within(myLine, myPoly) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", withinGeom)) assert withinGeom == True, myMessage
def create_edge(self): # If edge already exists, delete it.. if self.edge: self.l_edge.deleteFeature(self.edge.id()) # Two vertices are needed.. if not self.vtx_start or not self.vtx_end: return self.canvas.refresh() # Two DIFFERENT vertices.. if self.vtx_start == self.vtx_end: return self.canvas.refresh() # Create line geometry.. line = QgsGeometry.fromPolyline([self.vtx_start.geometry().asPoint(), self.vtx_end.geometry().asPoint()]) # Create the feature.. self.edge = QgsFeature() self.edge.setGeometry(line) self.edge.setFields(self.l_edge.pendingFields()) self.edge.setAttributes( [QPyNullVariant(int), QPyNullVariant(int), QPyNullVariant(int)]) # Add feature to layer.. self.l_edge.addFeature(self.edge) self.canvas.refresh()
def canvasMoveEvent(self, event): if self.snapCursorRubberBand: self.snapCursorRubberBand.hide() self.snapCursorRubberBand.reset(geometryType=QGis.Point) self.snapCursorRubberBand = None oldPoint = QgsPoint(event.mapPoint()) event.snapPoint(QgsMapMouseEvent.SnapProjectConfig) point = QgsPoint(event.mapPoint()) if oldPoint != point: self.createSnapCursor(point) point = QgsPoint(event.mapPoint()) if self.qntPoint == 1: self.distanceToolTip.canvasMoveEvent(self.geometry[0], point) geom = QgsGeometry.fromPolyline([self.geometry[0], point]) self.rubberBand.setToGeometry(geom, None) elif self.qntPoint >= 2: self.distanceToolTip.canvasMoveEvent(self.geometry[-1], point) if self.free: geom = QgsGeometry.fromPolygon([self.geometry+[QgsPoint(point.x(), point.y())]]) self.rubberBand.setToGeometry(geom, None) else: if (self.qntPoint % 2 == 1): self.setAvoidStyleSnapRubberBand() else: self.setAllowedStyleSnapRubberBand() projectedMousePoint = self.projectPoint(self.geometry[-2], self.geometry[-1], point) if projectedMousePoint: geom, pf = self.completePolygon(self.geometry, projectedMousePoint) self.rubberBand.setToGeometry(geom, None)
def clipLine(lineGeometry, pt1, pt2): """Returns a line cliipped to the extent of two given points""" # Assumes pt1, pt2 lie on line if lineGeometry is None or lineGeometry.isEmpty() or pt1 is None or pt2 is None: return QgsGeometry() line = LineString(lineGeometry.geometry()) d1 = line.project(Point(pt1)) d2 = line.project(Point(pt2)) if d1 < d2: start = pt1 ds = d1 end = pt2 de = d2 else: start = pt2 ds = d2 end = pt1 de = d1 clip = [] clip.append(start) for coord in line.coords: pt = Point(coord) dp = line.project(pt) if dp > ds and dp < de: clip.append(QgsPointV2(pt.x, pt.y)) clip.append(end) return QgsGeometry.fromPolyline(clip)
def loadLines(self, lines, points, markers, suffix): no = self.project.readEntry("TUVIEW", "lines{0}no".format(suffix))[0] if no: no = int(no) for i in range(no): a = self.project.readEntry("TUVIEW", 'lines{0}x{1}'.format(suffix, i))[0] a = a.split('~~') b = self.project.readEntry("TUVIEW", 'lines{0}y{1}'.format(suffix, i))[0] b = b.split('~~') points.clear() for j in range(len(a)): x = float(a[j]) y = float(b[j]) point = QgsPoint(x, y) points.append(point) if i + 1 == no: marker = QgsVertexMarker(self.tuView.canvas) if suffix == 'cs': marker.setColor(Qt.red) marker.setIconSize(10) marker.setIconType(QgsVertexMarker.ICON_BOX) else: # 'q' marker.setColor(Qt.blue) marker.setIconSize(12) marker.setIconType(QgsVertexMarker.ICON_DOUBLE_TRIANGLE) marker.setCenter(QgsPointXY(point)) markers.append(marker) line = QgsRubberBand(self.tuView.canvas, False) line.setWidth(2) if suffix == 'cs': line.setColor(QColor(Qt.red)) else: # 'q' line.setColor(QColor(Qt.blue)) line.setToGeometry(QgsGeometry.fromPolyline(points), None) lines.append(line)
def test_multi_intersect(self): def zipline(p1, p2, increment): middle = p1.x() start = p1.y() + increment end = p2.y() - increment while start < end: yield QgsPoint(middle - increment, start) start += increment yield QgsPoint(middle + increment, start) # Define the two captured points p1, p2 = QgsPoint(20.0, 10.0), QgsPoint(20.0, 10.2) # Define a "zig-zag" LineString geometry along the line between these # two points ls_points = list(zipline(p1, p2, 0.01)) ls = QgsGeometry.fromPolyline(ls_points) # Get the points generated by ElevationReader points = self.extract_elevation_helper(p1, p2, [FeatureDescr(ls, 20)]) # Evaluate the results self.assertEqual(len(points), len(ls_points) - 1) p_x = [p.x() for p in points] self.assertListEqual(p_x, sorted(p_x)) for point in points: self.assertEqual(point.y(), 20)
def polygons_to_lines( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBLineString, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() lineList = self.extractAsLine( inGeom ) outFeat.setAttributes( atMap ) for h in lineList: outFeat.setGeometry( outGeom.fromPolyline( h ) ) writer.addFeature( outFeat ) del writer return True
def testCrosses(self): myLine = QgsGeometry.fromPolyline([QgsPoint(0, 0),QgsPoint(1, 1),QgsPoint(3, 3)]) myPoly = QgsGeometry.fromPolygon([[QgsPoint(1, 0),QgsPoint(2, 0),QgsPoint(2, 2),QgsPoint(1, 2), QgsPoint(1, 0)]]) crossesGeom = QgsGeometry.crosses(myLine, myPoly) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", crossesGeom)) assert crossesGeom == True, myMessage
def _segmentAzimuth(self, line1Azimuth, line2Azimuth): nearLineGeom = self._nearLine.geometry() if nearLineGeom.isMultipart(): dct = {} minDists = [] for line in nearLineGeom.asMultiPolyline(): l = QgsGeometry.fromPolyline(line) closestSegmContext = l.closestSegmentWithContext( self._nearestVertex ) minDists.append(closestSegmContext[0]) dct[closestSegmContext[0]] = [line, closestSegmContext[-1]] minDistance = min(minDists) closestSegment = dct[minDistance][0] indexSegmEnd = dct[minDistance][1] segmEnd = closestSegment[indexSegmEnd] segmStart = closestSegment[indexSegmEnd - 1] else: closestSegmContext = nearLineGeom.closestSegmentWithContext( self._nearestVertex ) indexSegmEnd = closestSegmContext[-1] segmEnd = nearLineGeom.asPolyline()[indexSegmEnd] segmStart = nearLineGeom.asPolyline()[indexSegmEnd - 1] segmentAzimuth = segmStart.azimuth(segmEnd) self._dltAz1 = self._getDeltaAzimuth(segmentAzimuth, line1Azimuth) self._dltAz2 = self._getDeltaAzimuth(segmentAzimuth, line2Azimuth) self._azimuth()
def execute(self, beforerepo, afterrepo, errorreporter, progressreporter): if not isinstance(beforerepo, Repository): raise TypeError() if not isinstance(afterrepo, Repository): raise TypeError() beforefeats = beforerepo.read(self.featuretype, attributes=[self.direction_attribute], feature_filter=self.beforefilter) afterfeats = afterrepo.read(self.featuretype, attributes=[self.direction_attribute], feature_filter=self.afterfilter) # Features that appear to be changed changed_before_features = list(beforefeats) changed_after_features = [] progressreporter.begintask(self.name, len(afterfeats)) exact_matcher = ExactGeometryMatcher() # Find exact geometry matches finder = MatchFinder(beforefeats) for f in afterfeats: matches = finder.findmatching(f, exact_matcher) match_found = False for match in matches: match_found = True self._check(errorreporter, match.feature2, f, f, True, False) # Remove from changed if exists (Duplicate geometries forces us to use this check) if match.feature2 in changed_before_features: changed_before_features.remove(match.feature2) if match_found: continue # check on reversed geom reversed_geom = QgsGeometry.fromPolyline(list(reversed(f.geometry().asPolyline()))) matches = finder.findmatching(reversed_geom, exact_matcher) for match in matches: match_found = True self._check(errorreporter, match.feature2, f, f, False, False) # Remove from changed if exists (Duplicate geometries forces us to use this check) if match.feature2 in changed_before_features: changed_before_features.remove(match.feature2) if not match_found: changed_after_features.append(f) progressreporter.completed_one() # Compare nonexact geometry matches progressreporter.begintask(self.name, len(changed_after_features)) segmentmatchfinder = SegmentMatchFinder(changed_before_features, segmentize=self.segmentize) segmentmatchfinder2 = SegmentMatchFinder(afterfeats, segmentize=self.segmentize) for f in changed_after_features: for sm in segmentmatchfinder.findmatching(f, maxdistance=self.maxdist): f2 = sm.nearestfeature # check so that the projection of sm at least once matches the same nearest feature when segment matched against afterfeats projgeom = sm.toprojgeometry() projmatches = False for sm2 in segmentmatchfinder2.findmatching(projgeom, maxdistance=self.maxdist, ignore=f): projmatches = True if f2 == sm2.nearestfeature: self._check(errorreporter, f2, f, sm.togeometry(), sm.samedirection(), True) break if not projmatches: self._check(errorreporter, f2, f, sm.togeometry(), sm.samedirection(), True) progressreporter.completed_one()
def clipLine(lineGeometry, pt1, pt2): if lineGeometry is None or lineGeometry.isGeosEmpty() or pt1 is None or pt2 is None: return QgsGeometry() line = LineString(lineGeometry.asPolyline()) d1 = line.project(Point(pt1)) d2 = line.project(Point(pt2)) if d1 < d2: start = pt1 ds = d1 end = pt2 de = d2 else: start = pt2 ds = d2 end = pt1 de = d1 clip = [] clip.append(start) for coord in line.coords: pt = Point(coord) dp = line.project(pt) if dp > ds and dp < de: clip.append(QgsPoint(pt.x, pt.y)) clip.append(end) return QgsGeometry.fromPolyline(clip)
def createlinemarker(f0, f1): g0 = togeometry(f0) g1 = togeometry(f1) p0 = linemarkerpoint(g0, g1) p1 = linemarkerpoint(g1, g0) geom = QgsGeometry.fromPolyline([p0.asPoint(), p1.asPoint()]) return geom
def processAlgorithm(self, parameters, context, feedback): if parameters[self.SPOKES] == parameters[self.HUBS]: raise QgsProcessingException( self.tr('Same layer given for both hubs and spokes')) hub_source = self.parameterAsSource(parameters, self.HUBS, context) spoke_source = self.parameterAsSource(parameters, self.SPOKES, context) field_hub = self.parameterAsString(parameters, self.HUB_FIELD, context) field_hub_index = hub_source.fields().lookupField(field_hub) field_spoke = self.parameterAsString(parameters, self.SPOKE_FIELD, context) field_spoke_index = hub_source.fields().lookupField(field_spoke) fields = vector.combineFields(hub_source.fields(), spoke_source.fields()) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, hub_source.sourceCrs()) hubs = hub_source.getFeatures() total = 100.0 / hub_source.featureCount() if hub_source.featureCount() else 0 matching_field_types = hub_source.fields().at(field_hub_index).type() == spoke_source.fields().at(field_spoke_index).type() for current, hub_point in enumerate(hubs): if feedback.isCanceled(): break if not hub_point.hasGeometry(): continue p = hub_point.geometry().boundingBox().center() hub_x = p.x() hub_y = p.y() hub_id = str(hub_point[field_hub]) hub_attributes = hub_point.attributes() request = QgsFeatureRequest().setDestinationCrs(hub_source.sourceCrs()) if matching_field_types: request.setFilterExpression(QgsExpression.createFieldEqualityExpression(field_spoke, hub_attributes[field_hub_index])) spokes = spoke_source.getFeatures() for spoke_point in spokes: if feedback.isCanceled(): break spoke_id = str(spoke_point[field_spoke]) if hub_id == spoke_id: p = spoke_point.geometry().boundingBox().center() spoke_x = p.x() spoke_y = p.y() f = QgsFeature() f.setAttributes(hub_attributes + spoke_point.attributes()) f.setGeometry(QgsGeometry.fromPolyline( [QgsPointXY(hub_x, hub_y), QgsPointXY(spoke_x, spoke_y)])) sink.addFeature(f, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): if parameters[self.INPUT] == parameters[self.HUBS]: raise QgsProcessingException( self.tr('Same layer given for both hubs and spokes')) point_source = self.parameterAsSource(parameters, self.INPUT, context) hub_source = self.parameterAsSource(parameters, self.HUBS, context) fieldName = self.parameterAsString(parameters, self.FIELD, context) units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT, context)] fields = point_source.fields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, point_source.sourceCrs()) index = QgsSpatialIndex(hub_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(point_source.sourceCrs()))) distance = QgsDistanceArea() distance.setSourceCrs(point_source.sourceCrs()) distance.setEllipsoid(context.project().ellipsoid()) # Scan source points, find nearest hub, and write to output file features = point_source.getFeatures() total = 100.0 / point_source.featureCount() if point_source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break if not f.hasGeometry(): sink.addFeature(f, QgsFeatureSink.FastInsert) continue src = f.geometry().boundingBox().center() neighbors = index.nearestNeighbor(src, 1) ft = next(hub_source.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0]).setSubsetOfAttributes([fieldName], hub_source.fields()).setDestinationCrs(point_source.sourceCrs()))) closest = ft.geometry().boundingBox().center() hubDist = distance.measureLine(src, closest) if units != self.LAYER_UNITS: hub_dist_in_desired_units = distance.convertLengthMeasurement(hubDist, units) else: hub_dist_in_desired_units = hubDist attributes = f.attributes() attributes.append(ft[fieldName]) attributes.append(hub_dist_in_desired_units) feat = QgsFeature() feat.setAttributes(attributes) feat.setGeometry(QgsGeometry.fromPolyline([src, closest])) sink.addFeature(feat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): layerPoints = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.POINTS), context) layerHubs = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.HUBS), context) fieldName = self.getParameterValue(self.FIELD) units = self.UNITS[self.getParameterValue(self.UNIT)] if layerPoints.source() == layerHubs.source(): raise GeoAlgorithmExecutionException( self.tr('Same layer given for both hubs and spokes')) fields = layerPoints.fields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.LineString, layerPoints.crs(), context) index = QgsProcessingUtils.createSpatialIndex(layerHubs, context) distance = QgsDistanceArea() distance.setSourceCrs(layerPoints.crs()) distance.setEllipsoid(QgsProject.instance().ellipsoid()) # Scan source points, find nearest hub, and write to output file features = QgsProcessingUtils.getFeatures(layerPoints, context) total = 100.0 / layerPoints.featureCount() if layerPoints.featureCount() else 0 for current, f in enumerate(features): src = f.geometry().boundingBox().center() neighbors = index.nearestNeighbor(src, 1) ft = next(layerHubs.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0]).setSubsetOfAttributes([fieldName], layerHubs.fields()))) closest = ft.geometry().boundingBox().center() hubDist = distance.measureLine(src, closest) attributes = f.attributes() attributes.append(ft[fieldName]) if units == 'Feet': attributes.append(hubDist * 3.2808399) elif units == 'Miles': attributes.append(hubDist * 0.000621371192) elif units == 'Kilometers': attributes.append(hubDist / 1000.0) elif units != 'Meters': attributes.append(sqrt( pow(src.x() - closest.x(), 2.0) + pow(src.y() - closest.y(), 2.0))) else: attributes.append(hubDist) feat = QgsFeature() feat.setAttributes(attributes) feat.setGeometry(QgsGeometry.fromPolyline([src, closest])) writer.addFeature(feat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) del writer
def getPolylineAsSingleSegments(self, polyline): segments = [] for i in range(len(polyline) - 1): ptA = polyline[i] ptB = polyline[i + 1] segment = QgsGeometry.fromPolyline([ptA, ptB]) segments.append(segment) return segments
def segmentFromPoints(self, start, end): """ Makes a QgsGeometry from start and end points :param start: QgsPoint :param end: QgsPoint :return: """ return QgsGeometry.fromPolyline([start, end])
def circleArc2(layer, data, index, layer2, i): fcount = featureCount(layer) if fcount > 0: fant = [f for f in layer.getFeatures()][fcount - 1] l1 = fant.geometry() l2 = QgsGeometry(l1) dd = diff( qgsGeometryToPolyline(fant.geometry())[-1], qgsGeometryToPolyline(fant.geometry())[0]) l2.translate(dd.x(), dd.y()) PI = qgsGeometryToPolyline(fant.geometry())[-1] d = float(data["D"]) if not index == "S" else 90.0 l2.rotate(d, QgsPointXY(PI)) else: data["Disable"].append("C") data["Disable"].append("D") data["Disable"].append("R") data["Disable"].append("L") data["Disable"].append("T") return data data["Disable"].append("C") startAngle = azi(qgsGeometryToPolyline(l1)) angle = 90 - (data["D"] + startAngle) angle = angle if angle > 0 else 360 + angle angle = angle if angle < 360 else angle - 360 angleInternal = 180 - abs(d) p1 = p2QgsPoint(PI) corda = 2 * data["R"] * np.sin(np.deg2rad(angleInternal / 2)) p2 = p2QgsPoint(corda * np.cos(np.deg2rad(angle)) + p1.x(), corda * np.sin(np.deg2rad(angle)) + p1.y()) T = None E = None p = None arc = None if index == "R": pass elif index == "L": data["R"] = data["L"] / (np.deg2rad(abs(data["D"]))) corda = 2 * data["R"] * np.sin(np.deg2rad(abs(data["D"]) / 2)) T = abs(corda / (2 * np.tan(np.deg2rad(abs(data["D"]) / 2)))) p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) l2 = QgsGeometry(l1) dd = diff(p1, qgsGeometryToPolyline(l2)[0]) l2.translate(dd.x(), dd.y()) dd = diff(l2.interpolate(T).asPoint(), qgsGeometryToPolyline(l2)[0]) l2.translate(dd.x(), dd.y()) l2.rotate(data["D"], QgsPointXY(qgsGeometryToPolyline(l2)[0])) p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) p2 = p2QgsPoint(l2.interpolate(data["T"]).asPoint()) PI = p2QgsPoint(qgsGeometryToPolyline(l2)[0]) elif index == "T": corda = 2 * data["R"] * np.sin(np.deg2rad(abs(data["D"]) / 2)) T = abs(corda / (2 * np.tan(np.deg2rad((abs(data["D"])) / 2)))) p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) l2 = QgsGeometry(l1) dd = diff(p1, qgsGeometryToPolyline(l2)[0]) l2.translate(dd.x(), dd.y()) dd = diff(l2.interpolate(T).asPoint(), qgsGeometryToPolyline(l2)[0]) l2.translate(dd.x(), dd.y()) l2.rotate(data["D"], QgsPointXY(qgsGeometryToPolyline(l2)[0])) p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) p2 = p2QgsPoint(l2.interpolate(data["T"]).asPoint()) PI = p2QgsPoint(qgsGeometryToPolyline(l2)[0]) elif index == "D": data["L"] = np.deg2rad(abs(data["D"])) * data["R"] corda = 2 * data["R"] * np.sin(np.deg2rad(abs(data["D"]) / 2)) T = abs(corda / (2 * np.tan(np.deg2rad((abs(data["D"])) / 2)))) p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) l2 = QgsGeometry(l1) dd = diff(p1, qgsGeometryToPolyline(l2)[0]) l2.translate(dd.x(), dd.y()) PI = p2QgsPoint(l2.interpolate(T).asPoint()) dd = diff(PI, qgsGeometryToPolyline(l2)[0]) l2.translate(dd.x(), dd.y()) l2.rotate(data["D"], qgsGeometryToPolyline(l2)[0]) p2 = p2QgsPoint(l2.interpolate(T).asPoint()) elif index == "C": pass elif index == "S": data["C"] = True data["D"] = 90 data["L"] = np.deg2rad(abs(data["D"])) * data["R"] data["T"] = 0 if (data["T"] > l1.length() or data["T"] > l2.length()) and data["C"]: data["L"] = np.deg2rad(abs(d)) * data["R"] * abs(data["D"] / d) corda = 2 * data["R"] * np.sin(np.deg2rad(abs(data["D"]) / 2)) data["T"] = abs(corda / (2 * np.tan(np.deg2rad((d) / 2)))) p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) PI = p2QgsPoint(PI) corda = 2 * data["R"] * np.sin(np.deg2rad(angleInternal / 2)) p2 = p2QgsPoint(corda * np.cos(np.deg2rad(angle)) + p1.x(), corda * np.sin(np.deg2rad(angle)) + p1.y()) T = float(data["T"]) if T is None else T E = abs(T * np.tan(np.deg2rad(data["D"] / 4))) if E is None else E p = p2QgsPoint((p1.x() + p2.x()) / 2, (p2.y() + p1.y()) / 2) tmp_line = QgsGeometry.fromPolyline([p2QgsPoint(PI), p]) p = p2QgsPoint(tmp_line.interpolate(E).asPoint()) feat = QgsFeature(layer.fields()) feat.setAttribute('Tipo', 'C') # Create a QgsCircularStringV2 circularRing = QgsCircularString() # Set first point, intermediate point for curvature and end point circularRing.setPoints([p1, p, p2]) # data["R"]=QgsGeometryUtils.circleCenterRadius(p1,p,p2)[0] circularRing = arc if arc else circularRing feat.setGeometry(circularRing) f2 = QgsFeature(layer.fields()) f2.setGeometry(l2) layer.dataProvider().addFeatures([feat]) data["Disable"].append("C") return data
def tangent2(layer, data, index, layer2, i): fcount = featureCount(layer) if fcount > 0: fant = [f for f in layer.getFeatures()][fcount - 1] length = fant.geometry().length() lpt = qgsGeometryToPolyline(fant.geometry())[-1] angle = 90 - lastAzimuth(fant.geometry()) lpt = p2QgsPoint(lpt.x() - length * np.cos(np.deg2rad(angle)), lpt.y() - length * np.sin(np.deg2rad(angle))) l1 = QgsGeometry.fromPolyline([ p2QgsPoint(lpt), p2QgsPoint(qgsGeometryToPolyline(fant.geometry())[-1]) ]) l2 = QgsGeometry(l1) dd = diff( qgsGeometryToPolyline(fant.geometry())[-1], qgsGeometryToPolyline(fant.geometry())[0]) l2.translate(dd.x(), dd.y()) PI = qgsGeometryToPolyline(fant.geometry())[-1] d = 0 data["Disable"].append("C") else: l1, l2 = getTangentesGeometry(layer2, i) d = deflection(layer2, i) PI = qgsGeometryToPolyline(l1)[-1] if l1 is None: l1 = QgsGeometry(l2) dd = diff( qgsGeometryToPolyline(l2)[0], qgsGeometryToPolyline(l2)[-1]) l2.translate(dd.x(), dd.y()) elif l2 is None: l2 = QgsGeometry(l1) dd = diff( qgsGeometryToPolyline(l1)[-1], qgsGeometryToPolyline(l2)[0]) l2.translate(dd.x(), dd.y()) startAngle = azi(qgsGeometryToPolyline(l1)) angle = 90 - (data["D"] + startAngle) angle = angle if angle > 0 else 360 + angle angle = angle if angle < 360 else angle - 360 p1 = p2QgsPoint(PI) p2 = p2QgsPoint(data["L"] * np.cos(np.deg2rad(angle)) + p1.x(), data["L"] * np.sin(np.deg2rad(angle)) + p1.y()) line = QgsGeometry.fromPolyline([p1, p2]) if data["T"] > l1.length(): data["T"] = l1.length if index == "R": pass elif index == "L": if data["C"]: Lmax = np.sqrt(l1.length()**2 + l2.length()**2 - 2 * l1.length() * l2.length() * np.cos(np.deg2rad(360 - d))) if data["L"] > Lmax: data["L"] = Lmax data["T"] = abs(data["L"] / (2 * np.tan(np.deg2rad((d) / 2)))) data["D"] = d - 90 p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) p2 = p2QgsPoint(l2.interpolate(data["T"]).asPoint()) else: p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) dd = diff(p1, PI) line.translate(dd.x(), dd.y()) p2 = qgsGeometryToPolyline(line)[-1] elif index == "T": if data["C"]: data["L"] = abs(data["T"] * 2 * np.tan(np.deg2rad((d) / 2))) p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) p2 = p2QgsPoint(l2.interpolate(data["T"]).asPoint()) else: p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) dd = diff(p1, PI) line.translate(dd.x(), dd.y()) p2 = qgsGeometryToPolyline(line)[-1] elif index == "D": if data["C"]: data["D"] = 0 data["T"] = 0 data["C"] = False p2 = qgsGeometryToPolyline(line)[-1] else: p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) dd = diff(p1, PI) line.translate(dd.x(), dd.y()) p2 = qgsGeometryToPolyline(line)[-1] elif index == "C": if data["C"]: Lmax = np.sqrt(l1.length()**2 + l2.length()**2 - 2 * l1.length() * l2.length() * np.cos(np.deg2rad(360 - d))) if data["L"] > Lmax: data["L"] = Lmax data["T"] = abs(data["L"] / (2 * np.tan(np.deg2rad((d) / 2)))) data["D"] = d - 90 p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) p2 = p2QgsPoint(l2.interpolate(data["T"]).asPoint()) else: data["D"] = d if data["L"] < data["T"]: data["L"] = data["T"] data["T"] = 0 p1 = p2QgsPoint(l1.interpolate(l1.length() - data["T"]).asPoint()) p2 = p2QgsPoint(l2.interpolate(data["L"] - data["T"]).asPoint()) elif index == "S": data["D"] = 0 data["T"] = 0 p2 = qgsGeometryToPolyline(line)[-1] feat = QgsFeature(layer.fields()) feat.setAttribute('Tipo', 'T') feat.setGeometry(QgsGeometry.fromPolyline([p2QgsPoint(p1), p2QgsPoint(p2)])) layer.dataProvider().addFeatures([feat]) data["Disable"].append("R") data["Disable"].append("C") return data
def compute_compatibilty_matrix(self): """ Compatibility is stored in a matrix (rows = edges, columns = edges). Every coordinate in the matrix tells whether the two edges (r,c)/(c,r) are compatible, or not. The diagonal is always zero, and the other fields are filled with either -1 (not compatible) or 1 (compatible). The matrix is symmetric. """ edges_as_geom = [] edges_as_vect = [] for e_idx, edge in enumerate(self.edges): geom = edge.geometry() edges_as_geom.append(geom) edges_as_vect.append(QgsVector(geom.vertexAt(1).x() - geom.vertexAt(0).x(), geom.vertexAt(1).y() - geom.vertexAt(0).y())) self.edge_lengths.append(edges_as_vect[e_idx].length()) progress = 0 for i in range(self.E-1): for j in range(i+1, self.E): # Parameters lavg = (self.edge_lengths[i] + self.edge_lengths[j]) / 2.0 dot = edges_as_vect[i].normalized() * edges_as_vect[j].normalized() # Angle compatibility angle_comp = abs(dot) # Scale compatibility scale_comp = 2.0 / (lavg / min(self.edge_lengths[i], self.edge_lengths[j]) + max(self.edge_lengths[i], self.edge_lengths[j]) / lavg) # Position compatibility i0 = edges_as_geom[i].vertexAt(0) i1 = edges_as_geom[i].vertexAt(1) j0 = edges_as_geom[j].vertexAt(0) j1 = edges_as_geom[j].vertexAt(1) e1_mid = QgsPoint((i0.x() + i1.x()) / 2.0, (i0.y() + i1.y()) / 2.0) e2_mid = QgsPoint((j0.x() + j1.x()) / 2.0, (j0.y() + j1.y()) / 2.0) diff = QgsVector(e2_mid.x() - e1_mid.x(), e2_mid.y() - e1_mid.y()) pos_comp = lavg / (lavg + diff.length()) # Visibility compatibility mid_E1 = edges_as_geom[i].centroid() mid_E2 = edges_as_geom[j].centroid() #dist = mid_E1.distance(mid_E2) I0 = MiscUtils.project_point_on_line(j0, edges_as_geom[i]) I1 = MiscUtils.project_point_on_line(j1, edges_as_geom[i]) mid_I = QgsGeometry.fromPolyline([I0, I1]).centroid() dist_I = I0.distance(I1) if dist_I == 0.0: pass # previously: visibility = 0.0 else: visibility1 = max(0, 1 - ((2 * mid_E1.distance(mid_I)) / dist_I)) J0 = MiscUtils.project_point_on_line(i0, edges_as_geom[j]) J1 = MiscUtils.project_point_on_line(i1, edges_as_geom[j]) mid_J = QgsGeometry.fromPolyline([J0, J1]).centroid() dist_J = J0.distance(J1) if dist_J == 0.0: visibility2 = 0.0 else: visibility2 = max(0, 1 - ((2 * mid_E2.distance(mid_J)) / dist_J)) visibility_comp = min(visibility1, visibility2) # Compatibility score comp_score = angle_comp * scale_comp * pos_comp * visibility_comp # Fill values into the matrix (1 = yes, -1 = no) and use matrix symmetry (i/j = j/i) if comp_score >= compatibility: self.compatibility_matrix[i, j] = 1 self.compatibility_matrix[j, i] = 1 else: self.compatibility_matrix[i, j] = -1 self.compatibility_matrix[j, i] = -1 # Store direction distStart1 = j0.distance(i0) distStart2 = j1.distance(i0) if distStart1 > distStart2: self.direction_matrix[i, j] = -1 self.direction_matrix[j, i] = -1 else: self.direction_matrix[i, j] = 1 self.direction_matrix[j, i] = 1
def processAlgorithm(self, parameters, context, feedback): network = self.parameterAsSource(parameters, self.INPUT, context) startPoint = self.parameterAsPoint(parameters, self.START_POINT, context) endPoints = self.parameterAsSource(parameters, self.END_POINTS, context) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context) bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context) defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context) speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) feat = QgsFeature() feat.setFields(fields) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, network.sourceCrs()) directionField = -1 if directionFieldName: directionField = network.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName: speedField = network.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(network, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = context.project().crs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder(context.project().crs(), True, tolerance) feedback.pushInfo(self.tr('Loading end points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) request.setDestinationCrs(network.sourceCrs()) features = endPoints.getFeatures(request) total = 100.0 / endPoints.featureCount() if endPoints.featureCount( ) else 0 points = [startPoint] for current, f in enumerate(features): if feedback.isCanceled(): break points.append(f.geometry().asPoint()) feedback.setProgress(int(current * total)) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points, feedback) feedback.pushInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() idxStart = graph.findVertex(snappedPoints[0]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) route = [] nPoints = len(snappedPoints) total = 100.0 / nPoints if nPoints else 1 for i in range(1, count + 1): if feedback.isCanceled(): break idxEnd = graph.findVertex(snappedPoints[i]) if tree[idxEnd] == -1: msg = self.tr( 'There is no route from start point ({}) to end point ({}).' .format(startPoint.toString(), points[i].toString())) feedback.setProgressText(msg) QgsMessageLog.logMessage(msg, self.tr('Processing'), QgsMessageLog.WARNING) continue cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[0]) route.reverse() geom = QgsGeometry.fromPolyline(route) feat.setGeometry(geom) feat['start'] = startPoint.toString() feat['end'] = points[i].toString() feat['cost'] = cost / multiplier sink.addFeature(feat, QgsFeatureSink.FastInsert) route[:] = [] feedback.setProgress(int(i * total)) return {self.OUTPUT: dest_id}
def reverse_edge(edge): geom = list(edge.get()) pts = [pt for pt in geom[::-1]] return QgsGeometry.fromPolyline(pts)
""" import csv from qgis.core import QgsGeometry, QgsPoint import crayfish.plot from . import load_example_mesh # Load mesh and a results file mesh = load_example_mesh() # Get data for the plot output_bed = mesh.dataset(0).output(0) # bed elevation output_dep = mesh.dataset(1).output(0) # first output of second dataset line_geometry = QgsGeometry.fromPolyline([QgsPoint(1000,1005), QgsPoint(1028,1005)]) x, y_bed = crayfish.plot.cross_section_plot_data(output_bed, line_geometry) x, y_dep = crayfish.plot.cross_section_plot_data(output_dep, line_geometry) # make derived array: y = bed elevation + depth # so we can draw them together in a plot y_bed_dep = [ yi_bed + yi_dep for yi_bed, yi_dep in zip(y_bed, y_dep) ] # Export to CSV file with open('/tmp/plot_data.csv', 'w') as csvfile: writer = csv.writer(csvfile) writer.writerow(['x', 'bed', 'bed+depth']) for xi, yi_bed, yi_bed_dep in zip(x, y_bed, y_bed_dep): writer.writerow([xi, yi_bed, yi_bed_dep]) # Show plot plt = crayfish.plot.show_plot(x, y_bed, pen=(0,0,0))
def processAlgorithm(self, parameters, context, feedback): network = self.parameterAsSource(parameters, self.INPUT, context) startPoint = self.parameterAsPoint(parameters, self.START_POINT, context, network.sourceCrs()) endPoint = self.parameterAsPoint(parameters, self.END_POINT, context, network.sourceCrs()) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context) bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context) defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context) speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, network.sourceCrs()) directionField = -1 if directionField: directionField = network.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName: speedField = network.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(network, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = context.project().crs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder(network.sourceCrs(), True, tolerance) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, [startPoint, endPoint], feedback) feedback.pushInfo(self.tr('Calculating shortest path...')) graph = builder.graph() idxStart = graph.findVertex(snappedPoints[0]) idxEnd = graph.findVertex(snappedPoints[1]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) if tree[idxEnd] == -1: raise QgsProcessingException( self.tr('There is no route from start point to end point.')) route = [] cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[0]) route.reverse() feedback.pushInfo(self.tr('Writing results...')) geom = QgsGeometry.fromPolyline(route) feat = QgsFeature() feat.setFields(fields) feat['start'] = startPoint.toString() feat['end'] = endPoint.toString() feat['cost'] = cost / multiplier feat.setGeometry(geom) sink.addFeature(feat, QgsFeatureSink.FastInsert) results = {} results[self.TRAVEL_COST] = cost / multiplier results[self.OUTPUT] = dest_id return results
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) startPoint = self.getParameterValue(self.START_POINT) endPoint = self.getParameterValue(self.END_POINT) strategy = self.getParameterValue(self.STRATEGY) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), QgsWkbTypes.LineString, layer.crs()) tmp = startPoint.split(',') startPoint = QgsPoint(float(tmp[0]), float(tmp[1])) tmp = endPoint.split(',') endPoint = QgsPoint(float(tmp[0]), float(tmp[1])) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), True, tolerance) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, [startPoint, endPoint]) feedback.pushInfo(self.tr('Calculating shortest path...')) graph = builder.graph() idxStart = graph.findVertex(snappedPoints[0]) idxEnd = graph.findVertex(snappedPoints[1]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) if tree[idxEnd] == -1: raise GeoAlgorithmExecutionException( self.tr('There is no route from start point to end point.')) route = [] cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[0]) route.reverse() self.setOutputValue(self.TRAVEL_COST, cost / multiplier) feedback.pushInfo(self.tr('Writing results...')) geom = QgsGeometry.fromPolyline(route) feat = QgsFeature() feat.setFields(fields) feat['start'] = startPoint.toString() feat['end'] = endPoint.toString() feat['cost'] = cost / multiplier feat.setGeometry(geom) writer.addFeature(feat) del writer
def assess_accuracy(self): self.dlg.txtResults.clear() refObjLyr = self.dlg.cboRefObjLyr.currentLayer() claObjLyr = self.dlg.cboClaObjLyr.currentLayer() refObjFld = self.dlg.cboRefObjFld.currentField() claObjFld = self.dlg.cboClaObjFld.currentField() if refObjLyr == None and claObjLyr == None: QMessageBox.critical(None, "Error", "There are not layers in QGIS!. Please add Layers.") elif refObjLyr == claObjLyr: QMessageBox.critical(None, "Error", "Reference objects and classified objects are the same!") elif refObjFld == '' or claObjFld == '': QMessageBox.critical(None, "Error", "Please select category fields.") elif self.dlg.txtDirName.text() == '': QMessageBox.critical(None, "Error", "Please select results output directory.") else: #Start accuracy assessment epsilon = float(self.dlg.txtEpsilon.text()) #Objects' number nRef = refObjLyr.featureCount() nCla = claObjLyr.featureCount() #calculation of intersection matrix mint = [] for i in range(nRef): mint.append([]) for j in range(nCla): mint[i].append(None) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): mint[i.id()][j.id()] = i.geometry().intersects(j.geometry()) #calculation of intersected area matrix amint = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: geom = i.geometry().intersection(j.geometry()) amint[i.id()][j.id()] = geom.area() else: amint[i.id()][j.id()] = 0 #Categories' labels lblRef = [r[refObjFld] for r in refObjLyr.getFeatures()] valRef = list(set(lblRef)) valRef.sort() lblCla = [c[claObjFld] for c in claObjLyr.getFeatures()] valCla = list(set(lblCla)) valCla.sort() rdim = len(valRef) cdim = len(mint) aref = [r.geometry().area() for r in refObjLyr.getFeatures()] asum = sum(aref) ppref = [p/asum for p in aref] wref = [1/w for w in ppref] wsum = sum(wref) weight = [w/wsum for w in wref] # Weights' vertical aggregation vrtWeights = [] for i, v in enumerate(valRef): tmp = 0 for j, l in enumerate(lblRef): if v == l: tmp = tmp + weight[j] vrtWeights.append(tmp) """Calculation of Theme similarity""" #Objects' theme matrix theme = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()]==True and i[refObjFld]==j[claObjFld]: geom = i.geometry().intersection(j.geometry()) theme[i.id()][j.id()] = geom.area() / i.geometry().area() else: theme[i.id()][j.id()] = 0 #Horizontal aggregation wtheme = [range(rdim) for i in range(cdim)] for r in range(cdim): for c, v in enumerate(valCla): tmp = 0 for j, l in enumerate(lblCla): if v == l: tmp = tmp + amint[r][j] / aref[r] wtheme[r][c] = tmp #Vertical aggregation ttheme = deepcopy(wtheme) for i in range(cdim): for j in range(rdim): ttheme[i][j] = wtheme[i][j] * weight[i] wntheme = [range(rdim) for i in range(rdim)] for col, lblC in enumerate(valCla): pattern = [] for row, lblR in enumerate(lblRef): pattern.append(lblR + lblC) patternVal = list(set(pattern)) patternVal.sort() for i,val in enumerate(patternVal): tmp = 0 for c, lblc in enumerate(valCla): for r, lblr in enumerate(lblRef): if val == (lblr + lblc): tmp = tmp + ttheme[r][c] wntheme[i][col] = tmp #Theme similarity matrix step_theme = deepcopy(wntheme) for i in range(rdim): for j in range(rdim): step_theme[i][j] = wntheme[i][j] / vrtWeights[i] self.dlg.progressBar.setValue(25) """Calculation of Position similarity""" #Calculation of centroids distance matrix distCent = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: ptoRef = i.geometry().centroid().asPoint() ptoCla = j.geometry().centroid().asPoint() dist = QgsGeometry().fromPoint(ptoRef). \ distance(QgsGeometry().fromPoint(ptoCla)) distCent[i.id()][j.id()] = dist else: distCent[i.id()][j.id()] = 0 #Calculation of equivalent circle diameter reference matrix deqref = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: deqref[i.id()][j.id()] = 2 \ * sqrt((amint[i.id()][j.id()] + aref[i.id()]) / pi) else: deqref[i.id()][j.id()] = 0 #Calculation of position matrix position = deepcopy(deqref) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: position[i.id()][j.id()] = 1 - \ distCent[i.id()][j.id()] / deqref[i.id()][j.id()] else: position[i.id()][j.id()] = 0 #Horizontal aggregation wposition = [range(rdim) for i in range(cdim)] for r in range(cdim): for c, v in enumerate(valCla): tmp = 0 for j, l in enumerate(lblCla): if v == l: tmp = tmp + position[r][j] * amint[r][j] / aref[r] wposition[r][c] = tmp #Vertical aggregation tposition = deepcopy(wtheme) for i in range(cdim): for j in range(rdim): tposition[i][j] = wposition[i][j] * weight[i] wnposition = [range(rdim) for i in range(rdim)] for col, lblC in enumerate(valCla): pattern = [] for row, lblR in enumerate(lblRef): pattern.append(lblR + lblC) patternVal = list(set(pattern)) patternVal.sort() for i,val in enumerate(patternVal): tmp = 0 for c, lblc in enumerate(valCla): for r, lblr in enumerate(lblRef): if val == (lblr + lblc): tmp = tmp + tposition[r][c] wnposition[i][col] = tmp #Position similarity matrix step_position = deepcopy(wnposition) for i in range(rdim): for j in range(rdim): step_position[i][j] = wnposition[i][j] / vrtWeights[i] self.dlg.progressBar.setValue(50) """Calculation of Edge similarity""" #Calculaton of edge tolerance lmtRef = [QgsGeometry.fromPolyline(r.geometry().asPolygon()[0]) \ for r in refObjLyr.getFeatures()] bffRef = [r.buffer(0.1,0) for r in lmtRef] lmtCla = [QgsGeometry.fromPolyline(c.geometry().asPolygon()[0]) \ for c in claObjLyr.getFeatures()] bffCla = [c.buffer(epsilon,0) for c in lmtCla] #Horizontal aggregation tedge = deepcopy(mint) for i, r in enumerate(bffRef): for j, c in enumerate(bffCla): if mint[i][j] == True: geom = r.intersection(c) tedge[i][j] = geom.length() else: tedge[i][j] = 0 #Retrieving boundary of reference objects boundRef = [r.geometry().length() for r in refObjLyr.getFeatures()] #Objects' edge matrix edge = deepcopy(tedge) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: tmp = tedge[i.id()][j.id()] / boundRef[i.id()] if tmp > 1: edge[i.id()][j.id()]= 1 / tmp else: edge[i.id()][j.id()] = tmp else: edge[i.id()][j.id()] = 0 #Horizontal aggregation wedge = [range(rdim) for i in range(cdim)] for r in range(cdim): for c, v in enumerate(valCla): tmp = 0 for j, l in enumerate(lblCla): if v == l: tmp = tmp + edge[r][j] * amint[r][j] / aref[r] wedge[r][c] = tmp #Vertical aggregation tedge= deepcopy(wtheme) for i in range(cdim): for j in range(rdim): tedge[i][j] = wedge[i][j] * weight[i] wnedge = [range(rdim) for i in range(rdim)] for col, lblC in enumerate(valCla): pattern = [] for row, lblR in enumerate(lblRef): pattern.append(lblR + lblC) patternVal = list(set(pattern)) patternVal.sort() for i,val in enumerate(patternVal): tmp = 0 for c, lblc in enumerate(valCla): for r, lblr in enumerate(lblRef): if val == (lblr + lblc): tmp = tmp + tedge[r][c] wnedge[i][col] = tmp #Edge similarity matrix step_edge = deepcopy(wnedge) for i in range(rdim): for j in range(rdim): step_edge[i][j] = wnedge[i][j] / vrtWeights[i] self.dlg.progressBar.setValue(75) """Calculation of shape similarity""" #Retrieving boundary of classified objects boundCla = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: boundCla[i.id()][j.id()] = j.geometry().length() else: boundCla[i.id()][j.id()] = 0 #Calculation of the equal area circle (eac) eacRef = [sqrt(a / pi) for a in aref] eacCla = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: eacCla[i.id()][j.id()] = sqrt(j.geometry().area() / pi) else: eacCla[i.id()][j.id()] = 0 #Calculation of the normlized perimeter index (npi) npiRef = [eacRef[i]/boundRef[i] for i, a in enumerate(eacRef)] npiCla = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: npiCla[i.id()][j.id()] = eacCla[i.id()][j.id()] \ / boundCla[i.id()][j.id()] else: npiCla[i.id()][j.id()] = 0 #Objects' shape matrix shape = deepcopy(mint) for i in refObjLyr.getFeatures(): for j in claObjLyr.getFeatures(): if mint[i.id()][j.id()] == True: tmp = npiCla[i.id()][j.id()]/npiRef[i.id()] if tmp > 1: shape[i.id()][j.id()]= 1 / tmp else: shape[i.id()][j.id()] = tmp else: shape[i.id()][j.id()] = 0 #Horizontal aggregation wshape = [range(rdim) for i in range(cdim)] for r in range(cdim): for c, v in enumerate(valCla): tmp = 0 for j, l in enumerate(lblCla): if v == l: tmp = tmp + shape[r][j] * amint[r][j]/aref[r] wshape[r][c] = tmp #Vertical aggregation tshape = deepcopy(wtheme) for i in range(cdim): for j in range(rdim): tshape[i][j] = wshape[i][j] * weight[i] wnshape = [range(rdim) for i in range(rdim)] for col, lblC in enumerate(valCla): pattern = [] for row, lblR in enumerate(lblRef): pattern.append(lblR + lblC) patternVal = list(set(pattern)) patternVal.sort() for i,val in enumerate(patternVal): tmp = 0 for c, lblc in enumerate(valCla): for r, lblr in enumerate(lblRef): if val == (lblr + lblc): tmp = tmp + tshape[r][c] wnshape[i][col] = tmp #Shape similarity matrix step_shape = deepcopy(wnshape) for i in range(rdim): for j in range(rdim): step_shape[i][j] = wnshape[i][j] / vrtWeights[i] self.dlg.progressBar.setValue(100) #show an save similarity metrics fileSTEPname = self.dlg.txtDirName.text() + \ "\STEP_Similarity_Metrics.csv" outputFileSTEP = open(fileSTEPname, 'w') outputFileSTEP.write("Category;Shape;Theme;Edge;Position\n") for i in range(rdim): for j in range(rdim): if i == j: step = '%s; %s; %s; %s; %s' % \ (valRef[i], round(step_shape[i][j],4), round(step_theme[i][j],4), round(step_edge[i][j],4), round(step_position[i][j],4)) self.dlg.txtResults.appendPlainText(step) outputFileSTEP.write(step) outputFileSTEP.write("\n") outputFileSTEP.close() #Save similarity matrix to files fileShapeName = self.dlg.txtDirName.text() + \ "\Shape_Similarity_Matrix.csv" fileThemeName = self.dlg.txtDirName.text() + \ "\Theme_Similarity_Matrix.csv" fileEdgeName = self.dlg.txtDirName.text() + \ "\Edge_Similarity_Matrix.csv" filePositionName = self.dlg.txtDirName.text() + \ "\Position_Similarity_Matrix.csv" outputFileShape = open(fileShapeName, 'w') outputFileTheme = open(fileThemeName, 'w') outputFileEdge = open(fileEdgeName, 'w') outputFilePosition = open(filePositionName, 'w') outputFileShape.write("Shape") outputFileShape.write(";") outputFileTheme.write("Theme") outputFileTheme.write(";") outputFileEdge.write("Edge") outputFileEdge.write(";") outputFilePosition.write("Position") outputFilePosition.write(";") for i in range(rdim): outputFileShape.write(valRef[i]) outputFileShape.write(";") outputFileTheme.write(valRef[i]) outputFileTheme.write(";") outputFileEdge.write(valRef[i]) outputFileEdge.write(";") outputFilePosition.write(valRef[i]) outputFilePosition.write(";") outputFileShape.write("\n") outputFileTheme.write("\n") outputFileEdge.write("\n") outputFilePosition.write("\n") for i in range(rdim): outputFileShape.write(valRef[i]) outputFileTheme.write(valRef[i]) outputFileEdge.write(valRef[i]) outputFilePosition.write(valRef[i]) outputFileShape.write(";") outputFileTheme.write(";") outputFileEdge.write(";") outputFilePosition.write(";") for j in range(rdim): outputFileShape.write(str(round(step_shape[i][j],4))) outputFileTheme.write(str(round(step_theme[i][j],4))) outputFileEdge.write(str(round(step_edge[i][j],4))) outputFilePosition.write(str(round(step_position[i][j],4))) outputFileShape.write(";") outputFileTheme.write(";") outputFileEdge.write(";") outputFilePosition.write(";") outputFileShape.write("\n") outputFileTheme.write("\n") outputFileEdge.write("\n") outputFilePosition.write("\n") outputFileShape.close() outputFileTheme.close() outputFileEdge.close() outputFilePosition.close()
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT)) hSpacing = self.getParameterValue(self.HSPACING) vSpacing = self.getParameterValue(self.VSPACING) if hSpacing <= 0 or vSpacing <= 0: raise GeoAlgorithmExecutionException( self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() geomType = geom.wkbType() if geomType == QgsWkbTypes.Point: points = self._gridify([geom.asPoint()], hSpacing, vSpacing) newGeom = QgsGeometry.fromPoint(points[0]) elif geomType == QgsWkbTypes.MultiPoint: points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing) newGeom = QgsGeometry.fromMultiPoint(points) elif geomType == QgsWkbTypes.LineString: points = self._gridify(geom.asPolyline(), hSpacing, vSpacing) if len(points) < 2: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID {0}').format(f.id())) newGeom = None else: newGeom = QgsGeometry.fromPolyline(points) elif geomType == QgsWkbTypes.MultiLineString: polyline = [] for line in geom.asMultiPolyline(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polyline.append(points) if len(polyline) <= 0: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID {0}').format(f.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolyline(polyline) elif geomType == QgsWkbTypes.Polygon: polygon = [] for line in geom.asPolygon(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polygon.append(points) if len(polygon) <= 0: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID {0}').format(f.id())) newGeom = None else: newGeom = QgsGeometry.fromPolygon(polygon) elif geomType == QgsWkbTypes.MultiPolygon: multipolygon = [] for polygon in geom.asMultiPolygon(): newPolygon = [] for line in polygon: points = self._gridify(line, hSpacing, vSpacing) if len(points) > 2: newPolygon.append(points) if len(newPolygon) > 0: multipolygon.append(newPolygon) if len(multipolygon) <= 0: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID {0}').format(f.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolygon(multipolygon) if newGeom is not None: feat = QgsFeature() feat.setGeometry(newGeom) feat.setAttributes(f.attributes()) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_VECTOR), context) startPoints = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.START_POINTS), context) endPoint = self.getParameterValue(self.END_POINT) strategy = self.getParameterValue(self.STRATEGY) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) feat = QgsFeature() feat.setFields(fields) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields, QgsWkbTypes.LineString, layer.crs(), context) tmp = endPoint.split(',') endPoint = QgsPoint(float(tmp[0]), float(tmp[1])) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), True, tolerance) feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) features = QgsProcessingUtils.getFeatures(startPoints, context, request) count = QgsProcessingUtils.featureCount(startPoints, context) points = [endPoint] for f in features: points.append(f.geometry().asPoint()) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points) feedback.pushInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() idxEnd = graph.findVertex(snappedPoints[0]) route = [] total = 100.0 / count for i in range(1, count + 1): idxStart = graph.findVertex(snappedPoints[i]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) if tree[idxEnd] == -1: msg = self.tr( 'There is no route from start point ({}) to end point ({}).' .format(points[i].toString(), endPoint.toString())) feedback.setProgressText(msg) QgsMessageLog.logMessage(msg, self.tr('Processing'), QgsMessageLog.WARNING) continue cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[i]) route.reverse() geom = QgsGeometry.fromPolyline(route) feat.setGeometry(geom) feat['start'] = points[i].toString() feat['end'] = endPoint.toString() feat['cost'] = cost / multiplier writer.addFeature(feat) route[:] = [] feedback.setProgress(int(i * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.VECTOR)) groupField = self.getParameterValue(self.GROUP_FIELD) orderField = self.getParameterValue(self.ORDER_FIELD) dateFormat = str(self.getParameterValue(self.DATE_FORMAT)) #gap = int(self.getParameterValue(self.GAP_PERIOD)) dirName = self.getOutputValue(self.OUTPUT_TEXT) fields = QgsFields() fields.append(QgsField('group', QVariant.String, '', 254, 0)) fields.append(QgsField('begin', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) writer = self.getOutputFromName(self.OUTPUT_LINES).getVectorWriter( fields, QgsWkbTypes.LineString, layer.crs()) points = dict() features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): point = f.geometry().asPoint() group = f[groupField] order = f[orderField] if dateFormat != '': order = datetime.strptime(str(order), dateFormat) if group in points: points[group].append((order, point)) else: points[group] = [(order, point)] feedback.setProgress(int(current * total)) feedback.setProgress(0) da = QgsDistanceArea() current = 0 total = 100.0 / len(points) for group, vertices in list(points.items()): vertices.sort() f = QgsFeature() f.initAttributes(len(fields)) f.setFields(fields) f['group'] = group f['begin'] = vertices[0][0] f['end'] = vertices[-1][0] fileName = os.path.join(dirName, '%s.txt' % group) with open(fileName, 'w') as fl: fl.write('angle=Azimuth\n') fl.write('heading=Coordinate_System\n') fl.write('dist_units=Default\n') line = [] i = 0 for node in vertices: line.append(node[1]) if i == 0: fl.write('startAt=%f;%f;90\n' % (node[1].x(), node[1].y())) fl.write('survey=Polygonal\n') fl.write('[data]\n') else: angle = line[i - 1].azimuth(line[i]) distance = da.measureLine(line[i - 1], line[i]) fl.write('%f;%f;90\n' % (angle, distance)) i += 1 f.setGeometry(QgsGeometry.fromPolyline(line)) writer.addFeature(f) current += 1 feedback.setProgress(int(current * total)) del writer
def compute( self, bound, xOffset, yOffset, polygon ): crs = None layer = ftools_utils.getMapLayerByName(unicode(self.inShape.currentText())) if layer is None: crs = self.iface.mapCanvas().mapRenderer().destinationCrs() else: crs = layer.crs() if not crs.isValid(): crs = None fields = QgsFields() fields.append( QgsField("ID", QVariant.Int) ) fieldCount = 1 if polygon: fields.append( QgsField("X_MIN", QVariant.Double) ) fields.append( QgsField("X_MAX", QVariant.Double) ) fields.append( QgsField("Y_MIN", QVariant.Double) ) fields.append( QgsField("Y_MAX", QVariant.Double) ) fieldCount = 5 check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBPolygon, crs) else: fields.append( QgsField("COORD", QVariant.Double) ) fieldCount = 2 check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBLineString, crs) outFeat = QgsFeature() outFeat.initAttributes(fieldCount) outFeat.setFields(fields) outGeom = QgsGeometry() idVar = 0 self.progressBar.setValue( 0 ) if not polygon: # counters for progressbar - update every 5% count = 0 count_max = (bound.yMaximum() - bound.yMinimum()) / yOffset count_update = count_max * 0.10 y = bound.yMaximum() while y >= bound.yMinimum(): pt1 = QgsPoint(bound.xMinimum(), y) pt2 = QgsPoint(bound.xMaximum(), y) line = [pt1, pt2] outFeat.setGeometry(outGeom.fromPolyline(line)) outFeat.setAttribute(0, idVar) outFeat.setAttribute(1, y) writer.addFeature(outFeat) y = y - yOffset idVar = idVar + 1 count += 1 if int( math.fmod( count, count_update ) ) == 0: prog = int( count / count_max * 50 ) self.progressBar.setValue( prog ) self.progressBar.setValue( 50 ) # counters for progressbar - update every 5% count = 0 count_max = (bound.xMaximum() - bound.xMinimum()) / xOffset count_update = count_max * 0.10 x = bound.xMinimum() while x <= bound.xMaximum(): pt1 = QgsPoint(x, bound.yMaximum()) pt2 = QgsPoint(x, bound.yMinimum()) line = [pt1, pt2] outFeat.setGeometry(outGeom.fromPolyline(line)) outFeat.setAttribute(0, idVar) outFeat.setAttribute(1, x) writer.addFeature(outFeat) x = x + xOffset idVar = idVar + 1 count += 1 if int( math.fmod( count, count_update ) ) == 0: prog = 50 + int( count / count_max * 50 ) self.progressBar.setValue( prog ) else: # counters for progressbar - update every 5% count = 0 count_max = (bound.yMaximum() - bound.yMinimum()) / yOffset count_update = count_max * 0.05 y = bound.yMaximum() while y >= bound.yMinimum(): x = bound.xMinimum() while x <= bound.xMaximum(): pt1 = QgsPoint(x, y) pt2 = QgsPoint(x + xOffset, y) pt3 = QgsPoint(x + xOffset, y - yOffset) pt4 = QgsPoint(x, y - yOffset) pt5 = QgsPoint(x, y) polygon = [[pt1, pt2, pt3, pt4, pt5]] outFeat.setGeometry(outGeom.fromPolygon(polygon)) outFeat.setAttribute(0, idVar) outFeat.setAttribute(1, x) outFeat.setAttribute(2, x + xOffset) outFeat.setAttribute(3, y - yOffset) outFeat.setAttribute(4, y) writer.addFeature(outFeat) idVar = idVar + 1 x = x + xOffset y = y - yOffset count += 1 if int( math.fmod( count, count_update ) ) == 0: prog = int( count / count_max * 100 ) self.progressBar.setValue( 100 ) del writer
def processAlgorithm(self, parameters, context, feedback): if parameters[self.SPOKES] == parameters[self.HUBS]: raise QgsProcessingException( self.tr('Same layer given for both hubs and spokes')) hub_source = self.parameterAsSource(parameters, self.HUBS, context) spoke_source = self.parameterAsSource(parameters, self.SPOKES, context) field_hub = self.parameterAsString(parameters, self.HUB_FIELD, context) field_hub_index = hub_source.fields().lookupField(field_hub) field_spoke = self.parameterAsString(parameters, self.SPOKE_FIELD, context) field_spoke_index = hub_source.fields().lookupField(field_spoke) fields = QgsProcessingUtils.combineFields(hub_source.fields(), spoke_source.fields()) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, hub_source.sourceCrs()) hubs = hub_source.getFeatures() total = 100.0 / hub_source.featureCount() if hub_source.featureCount( ) else 0 matching_field_types = hub_source.fields().at(field_hub_index).type( ) == spoke_source.fields().at(field_spoke_index).type() for current, hub_point in enumerate(hubs): if feedback.isCanceled(): break if not hub_point.hasGeometry(): continue p = hub_point.geometry().boundingBox().center() hub_x = p.x() hub_y = p.y() hub_id = str(hub_point[field_hub]) hub_attributes = hub_point.attributes() request = QgsFeatureRequest().setDestinationCrs( hub_source.sourceCrs()) if matching_field_types: request.setFilterExpression( QgsExpression.createFieldEqualityExpression( field_spoke, hub_attributes[field_hub_index])) spokes = spoke_source.getFeatures() for spoke_point in spokes: if feedback.isCanceled(): break spoke_id = str(spoke_point[field_spoke]) if hub_id == spoke_id: p = spoke_point.geometry().boundingBox().center() spoke_x = p.x() spoke_y = p.y() f = QgsFeature() f.setAttributes(hub_attributes + spoke_point.attributes()) f.setGeometry( QgsGeometry.fromPolyline([ QgsPointXY(hub_x, hub_y), QgsPointXY(spoke_x, spoke_y) ])) sink.addFeature(f, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started #Limpa o caminho pra salvar o arquivo self.dlg.caminho.clear() # Carrega os Layer que corresponde somente a Shp de polylines layers = QgsProject.instance().mapLayers().values() self.dlg.select_layer.clear() for layer in layers: if layer.type() == QgsMapLayer.VectorLayer and layer.geometryType() == QgsWkbTypes.LineGeometry: self.dlg.select_layer.addItem( layer.name(), layer ) self.set_select_attributes() # Carrega as colunas dos shape sempre que seleciona os shape self.dlg.select_layer.currentIndexChanged.connect(self.set_select_attributes) self.set_select_attributes() # 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. listcom = [] # Seleciona Somente o Shape que foi escolhido for selectlayer in QgsProject.instance().mapLayers().values(): if selectlayer.name() == self.dlg.select_layer.currentText(): coluna = self.dlg.coluna.currentText() lay = selectlayer sRs = lay.crs() provider = lay.dataProvider() n_new_feats = 0 for i in lay.getFeatures(): geomVerif = i.geometry() print(i.geometry()) print(i.attributes()) geomSingleType = QgsWkbTypes.isSingleType(geomVerif.wkbType()) if not geomSingleType: geomFeature = geomVerif.asGeometryCollection() if not geomSingleType: a_list = [] vlayer = QgsVectorLayer("LineString?", "vlayer", "memory" ) pr = vlayer.dataProvider() for feature in lay.getFeatures(): geomMult = feature.geometry() a_list.append(feature[coluna]) if geomMult.isMultipart(): geom_list = geomMult.asMultiPolyline() listTeste = [] for single_geom_list in geom_list: corrdsList = [] for coords in single_geom_list: corrdsList.append(QgsPoint(coords)) single_feature = QgsFeature() single_geom = QgsGeometry.fromPolyline(corrdsList) single_feature.setGeometry(single_geom) pr.addFeature(single_feature) vlayer.updateExtents() if geomSingleType: for f in lay.getFeatures(): nome = f[coluna] geom = f.geometry() wkb = geom.asWkb() geom_ogr = ogr.CreateGeometryFromWkb(wkb) vertices = geom.asPolyline() n = len(vertices) - 1 xi = geom_ogr.GetX(0) yi = geom_ogr.GetY(0) zi = geom_ogr.GetZ(0) xf = geom_ogr.GetX(n) yf = geom_ogr.GetY(n) zf = geom_ogr.GetZ(n) if geom_ogr.GetZ(0) == geom_ogr.GetZ(n): list = [xi,yi,zi,nome,'Inicio'] listcom.append(list) list2 = [xf,yf,zf,nome,'Fim'] listcom.append(list2) elif geom_ogr.GetZ(0) < geom_ogr.GetZ(n): list3 = [xi,yi,zi,nome,'Fim'] listcom.append(list3) list4 = [xf,yf,zf,nome,'Inicio'] listcom.append(list4) elif geom_ogr.GetZ(0) > geom_ogr.GetZ(n): list5 = [xi,yi,zi,nome,'Inicio'] listcom.append(list5) list6 = [xf,yf,zf,nome,'Fim'] listcom.append(list6) else : for f in vlayer.getFeatures(): nome = a_list[n_new_feats] geom = f.geometry() wkb = geom.asWkb() geom_ogr = ogr.CreateGeometryFromWkb(wkb) vertices = geom.asPolyline() n = len(vertices) - 1 xi = geom_ogr.GetX(0) yi = geom_ogr.GetY(0) zi = geom_ogr.GetZ(0) xf = geom_ogr.GetX(n) yf = geom_ogr.GetY(n) zf = geom_ogr.GetZ(n) if geom_ogr.GetZ(0) == geom_ogr.GetZ(n): list = [xi,yi,zi,nome,'Inicio'] listcom.append(list) list2 = [xf,yf,zf,nome,'Fim'] listcom.append(list2) elif geom_ogr.GetZ(0) < geom_ogr.GetZ(n): list3 = [xi,yi,zi,nome,'Fim'] listcom.append(list3) list4 = [xf,yf,zf,nome,'Inicio'] listcom.append(list4) elif geom_ogr.GetZ(0) > geom_ogr.GetZ(n): list5 = [xi,yi,zi,nome,'Inicio'] listcom.append(list5) list6 = [xf,yf,zf,nome,'Fim'] listcom.append(list6) n_new_feats += 1 listfinal = [] listverif = [] v = 0 for s in listcom: valorXY = [listcom[v][0],listcom[v][1]] listverif.append(valorXY) v += 1 for d in listverif: rX1 = d[0] rY1 = d[1] resultado = 0 for resp in listverif: rX2 = resp[0] rY2 = resp[1] if rX1 == rX2 and rY1 == rY2: resultado += 1 tfinal = 0 for j in listfinal: if j[0] == d[0] and j[1] == d[1]: tfinal = 1 if tfinal == 0 : if resultado == 1: for verifin in listcom: if verifin[0] == d[0] and verifin[1] == d[1]: listfinal.append(verifin) else : v2 = 0 Listrio = [] for verif in listcom: if verif[0] == d[0] and verif[1] == d[1]: altitude = verif[2] nome_rio = verif[3] Listrio.append(nome_rio) riofinal = verif[3] riot = 0 for rio in Listrio: riot = 0 for riofin in Listrio: if rio == riofin : riot += 1 if riot == 2: if rio != '' or rio != None: riofinal = rio valorfinal = [d[0],d[1],altitude,riofinal,'Confluencia'] del Listrio listfinal.append(valorfinal) self.Fields = QgsFields() self.Fields.append(QgsField('id',QVariant.Int)) self.Fields.append(QgsField('nome',QVariant.String)) self.Fields.append(QgsField('situacao',QVariant.String)) global SHPCaminho SHPCaminho = self.outFilePath self.outputPointsShape = QgsVectorFileWriter(SHPCaminho, self.encoding, self.Fields, QgsWkbTypes.Point, sRs, "ESRI Shapefile") idX = 1 for final in listfinal: self.fetf = QgsFeature() zPoint = QgsPoint(final[0], final[1], final[2]) zPoint.z() self.fetf.setGeometry( QgsGeometry( zPoint ) ) self.fetf.setAttributes([idX, final[3], final[4]] ) self.outputPointsShape.addFeature(self.fetf) idX += 1 pegarNome = self.outFilePath Nomes = pegarNome.split( '/' ) contNomes = len(Nomes) - 1 nomefinalshp = Nomes[contNomes] nomefinalshp = nomefinalshp.replace('.shp','') nomefinalshp = nomefinalshp.replace('.SHP','') #self.iface.addVectorLayer(self.outFilePath, nomefinalshp, 'ogr') self.layer = QgsVectorLayer(self.outFilePath, nomefinalshp, "ogr") if not self.layer.isValid(): raise ValueError("Failed to open the layer") self.canvas = QgsMapCanvas() QgsProject.instance().addMapLayer(self.layer) self.canvas.setExtent(self.layer.extent()) self.canvas.setLayers([self.layer]) del self.outputPointsShape QgsProject.instance().removeMapLayer(self.layer) self.layer = QgsVectorLayer(self.outFilePath, nomefinalshp, "ogr") QgsProject.instance().addMapLayer(self.layer)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue( self.INPUT)) index = self.getParameterValue(self.TYPE) splitNodes = False if index == 0: newType = QgsWkbTypes.Point elif index == 1: newType = QgsWkbTypes.Point splitNodes = True elif index == 2: newType = QgsWkbTypes.LineString elif index == 3: newType = QgsWkbTypes.MultiLineString elif index == 4: newType = QgsWkbTypes.Polygon else: newType = QgsWkbTypes.Point writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), newType, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() geomType = geom.wkbType() if geomType in [QgsWkbTypes.Point, QgsWkbTypes.Point25D]: if newType == QgsWkbTypes.Point: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.MultiPoint, QgsWkbTypes.MultiPoint25D ]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asMultiPoint() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.LineString, QgsWkbTypes.LineString25D ]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asPolyline() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiLineString25D ]: if newType == QgsWkbTypes.Point and splitNodes: lines = geom.asMultiPolyline() for line in lines: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: lines = geom.asMultiPolyline() for line in lines: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(line)) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [QgsWkbTypes.Polygon, QgsWkbTypes.Polygon25D]: if newType == QgsWkbTypes.Point and splitNodes: rings = geom.asPolygon() for ring in rings: for p in ring: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: rings = geom.asPolygon() feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromMultiPolyline(rings)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.MultiPolygon, QgsWkbTypes.MultiPolygon25D ]: if newType == QgsWkbTypes.Point and splitNodes: polygons = geom.asMultiPolygon() for polygon in polygons: for line in polygon: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: polygons = geom.asMultiPolygon() for polygons in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(polygon)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: polygons = geom.asMultiPolygon() for polygon in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolygon(polygon)) writer.addFeature(feat) elif newType in [ QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiPolygon ]: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) progress.setPercentage(int(current * total)) del writer
def load_complex_gml(self, xml_uri, is_remote, attributes = {}, geometry_mapping = None, logger = None, swap_xy = False): """ :param xml_uri: the XML URI :param is_remote: True if it has to be fetched by http :param attributes: { 'attr1' : ( '//xpath/expression', QVariant.Int ) } :param geometry_mapping: XPath expression to a gml geometry node :param swap_xy: True if X/Y coordinates must be swapped :returns: the created layer """ if is_remote: xml = remote_open_from_qgis(xml_uri) else: # Open the file in binary mode, this means returning bytes # instead of a string whose encoding would have to be interpreted # it is up to the XML parser to determine which encoding it is xml = open(xml_uri, 'rb') src = ComplexFeatureSource(xml, attributes, geometry_mapping, logger) attr_list = [ (k, v[1]) for k, v in attributes.items() ] # first feature id, fid, g, xml, attrs = next(src.getFeatures()) qgsgeom = None if g is None: layer = self._create_layer('none', None, attr_list, src.title) else: wkb, srid = g qgsgeom = QgsGeometry() qgsgeom.fromWkb(wkb) if qgsgeom and qgsgeom.type() == QgsWkbTypes.PointGeometry: layer = self._create_layer('point', srid, attr_list, src.title + " (points)") elif qgsgeom and qgsgeom.type() == QgsWkbTypes.LineGeometry: layer = self._create_layer('linestring', srid, attr_list, src.title + " (lines)") elif qgsgeom and qgsgeom.type() == QgsWkbTypes.PolygonGeometry: layer = self._create_layer('polygon', srid, attr_list, src.title + " (polygons)") # add metadata self._add_properties_to_layer(layer, xml_uri, is_remote, attributes, geometry_mapping) # collect features features = [] for id, fid, g, xml, attrs in src.getFeatures(): qgsgeom = None wkb, srid = g qgsgeom = QgsGeometry() qgsgeom.fromWkb(wkb) if qgsgeom and qgsgeom.type() == QgsWkbTypes.PointGeometry: if swap_xy: p = qgsgeom.asPoint() qgsgeom = QgsGeometry.fromPoint(QgsPointXY(p[1], p[0])) elif qgsgeom and qgsgeom.type() == QgsWkbTypes.LineGeometry: if swap_xy: pl = qgsgeom.asPolyline() qgsgeom = QgsGeometry.fromPolyline([QgsPointXY(p[1],p[0]) for p in pl]) elif qgsgeom and qgsgeom.type() == QgsWkbTypes.PolygonGeometry: if swap_xy: pl = qgsgeom.asPolygon() qgsgeom = QgsGeometry.fromPolygon([[QgsPointXY(p[1],p[0]) for p in r] for r in pl]) f = QgsFeature(layer.dataProvider().fields(), id) if qgsgeom: f.setGeometry(qgsgeom) f.setAttribute("id", str(id)) f.setAttribute("fid", fid) f.setAttribute("_xml_", ET.tostring(xml).decode('utf8')) for k, v in attrs.items(): r = f.setAttribute(k, v) features.append(f) # write features if len(features) > 0: layer.dataProvider().addFeatures(features) return layer
def utm_symb_generator(self, grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, t, u, geo_bound_bb, bound_UTM_bb, utmcheck): xmin_source = float(geo_bound_bb.split()[1]) ymin_source = float(geo_bound_bb.split()[2]) xmax_source = float(geo_bound_bb.split()[3]) ymax_source = float(geo_bound_bb.split()[4]) xmin_UTM = float(bound_UTM_bb.split()[1]) ymin_UTM = float(bound_UTM_bb.split()[2]) xmax_UTM = float(bound_UTM_bb.split()[3]) ymax_UTM = float(bound_UTM_bb.split()[4]) test_line = [None] * 2 properties = {'color': 'black'} line_temp = QgsLineSymbol.createSimple(properties) line_temp.setWidth(0.05) symb = QgsGeometryGeneratorSymbolLayer.create(properties) symb.setSymbolType(1) symb.setSubSymbol(line_temp) #Test First And Last Grid Lines #Vertical if (t == 1 and u == 0) or (t == UTM_num_x and u == 0): #Symbol vertices auxPointlist = self.gridLinesymbolMaker( ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), ymin_UTM, ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), ymax_UTM, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, True) #0: left bound; 1: right bound test_line[0] = QgsGeometry.fromWkt('LINESTRING (' + str(xmin_source) + ' ' + str(ymin_source) + ',' + str(xmin_source) + ' ' + str(ymax_source) + ')') test_line[1] = QgsGeometry.fromWkt('LINESTRING (' + str(xmax_source) + ' ' + str(ymin_source) + ',' + str(xmax_source) + ' ' + str(ymax_source) + ')') test_grid = QgsGeometry.fromPolyline( [auxPointlist[0], auxPointlist[1]]) if test_line[0].intersects(test_grid): mid_point = test_line[0].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].x() > auxPointlist[1].x(): symb.setGeometryExpression('make_line(make_point(' + str(auxPointlist[2].x()) + ',' + str(auxPointlist[2].y()) + '), make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '))') else: symb.setGeometryExpression('make_line(make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '), make_point(' + str(auxPointlist[3].x()) + ',' + str(auxPointlist[3].y()) + '))') elif test_line[1].intersects(test_grid): mid_point = test_line[1].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].x() < auxPointlist[1].x(): symb.setGeometryExpression('make_line(make_point(' + str(auxPointlist[2].x()) + ',' + str(auxPointlist[2].y()) + '), make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '))') else: symb.setGeometryExpression('make_line(make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '), make_point(' + str(auxPointlist[3].x()) + ',' + str(auxPointlist[3].y()) + '))') else: symb.setGeometryExpression('make_line(make_point(' + str(auxPointlist[2].x()) + ',' + str(auxPointlist[2].y()) + '), make_point(' + str(auxPointlist[3].x()) + ',' + str(auxPointlist[3].y()) + '))') #Horizontal elif (u == 1 and t == 0) or (u == UTM_num_y and t == 0): #Symbol vertices auxPointlist = self.gridLinesymbolMaker( xmin_UTM, ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), xmax_UTM, ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, False) #0: bottom bound; 1: upper bound test_line[0] = QgsGeometry.fromWkt('LINESTRING (' + str(xmin_source) + ' ' + str(ymin_source) + ',' + str(xmax_source) + ' ' + str(ymin_source) + ')') test_line[1] = QgsGeometry.fromWkt('LINESTRING (' + str(xmin_source) + ' ' + str(ymax_source) + ',' + str(xmax_source) + ' ' + str(ymax_source) + ')') test_grid = QgsGeometry.fromPolyline( [auxPointlist[0], auxPointlist[1]]) if test_line[0].intersects(test_grid): mid_point = test_line[0].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].y() > auxPointlist[1].y(): symb.setGeometryExpression('make_line(make_point(' + str(auxPointlist[2].x()) + ',' + str(auxPointlist[2].y()) + '), make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '))') else: symb.setGeometryExpression('make_line(make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '), make_point(' + str(auxPointlist[3].x()) + ',' + str(auxPointlist[3].y()) + '))') elif test_line[1].intersects(test_grid): mid_point = test_line[1].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].y() < auxPointlist[1].y(): symb.setGeometryExpression('make_line(make_point(' + str(auxPointlist[2].x()) + ',' + str(auxPointlist[2].y()) + '), make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '))') else: symb.setGeometryExpression('make_line(make_point(' + str(mid_point.x()) + ',' + str(mid_point.y()) + '), make_point(' + str(auxPointlist[3].x()) + ',' + str(auxPointlist[3].y()) + '))') else: symb.setGeometryExpression("make_line(make_point(" + str(auxPointlist[2].x()) + "," + str(auxPointlist[2].y()) + "), make_point(" + str(auxPointlist[3].x()) + "," + str(auxPointlist[3].y()) + "))") #Inner Grid Lines #Vertical elif (not (t == 1)) and (not (t == UTM_num_x)) and u == 0: auxPointlist = self.gridLinesymbolMaker( ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), ymin_UTM, ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), ymax_UTM, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, True) symb.setGeometryExpression('make_line(make_point(' + str(auxPointlist[2].x()) + ',' + str(auxPointlist[2].y()) + '), make_point(' + str(auxPointlist[3].x()) + ',' + str(auxPointlist[3].y()) + '))') #Horizontal elif (not (u == 1)) and (not (u == UTM_num_y)) and t == 0: auxPointlist = self.gridLinesymbolMaker( xmin_UTM, ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), xmax_UTM, ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, False) symb.setGeometryExpression("make_line(make_point(" + str(auxPointlist[2].x()) + "," + str(auxPointlist[2].y()) + "), make_point(" + str(auxPointlist[3].x()) + "," + str(auxPointlist[3].y()) + "))") grid_symb.appendSymbolLayer(symb) return grid_symb
def run_open_pli(self): file = QFileDialog.getOpenFileName( self.dlg, "Select pli-file ", self.directory, '*') # .ldb,*.pol,*.pli,*.xyn,*.xyz') # file = r'd:\projecten\11200569_Maas_G6\20171114 Deltashell2\files\dflowfm\invoer\j17_5-v1_landboundaries.ldb' self.directory, filename = os.path.split(file) layername, extension = os.path.splitext(filename) print(layername) if extension == '.xyz' or extension == '.xyn': vl = QgsVectorLayer("Point", layername, "memory") QgsMapLayerRegistry.instance().addMapLayer(vl) pr = vl.dataProvider() # add fields if extension == 'xyz': attribute = 'z' else: attribute = 'name' pr.addAttributes([QgsField(attribute, QVariant.String)]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider with open(file) as f: for line in f: ls = line.strip().split('\t') X = float(ls[0]) Y = float(ls[1]) Z = ls[2] fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(X, Y))) fet.setAttributes([Z]) pr.addFeatures([fet]) # update layer's extent when new features have been added # because change of extent in provider is not propagated to the layer vl.updateExtents() else: D = tek.tekal(file) # initialize D.info(file) # get file meta-data: all blocks vl = QgsVectorLayer("LineString", layername, "memory") QgsMapLayerRegistry.instance().addMapLayer(vl) pr = vl.dataProvider() attribute = "name" # add fields pr.addAttributes([QgsField(attribute, QVariant.String)]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider for ii in range(len(D.blocks)): Name = D.blocks[ii].name M = D.read(ii) P = [] for ix in range(len(M[0])): P.append(QgsPoint(M[0][ix], M[1][ix])) # If line of just one points: duplicate if ix == 0: P.append(QgsPoint(M[0][ix] + 0.01, M[1][ix] + 0.01)) # add a feature fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPolyline(P)) fet.setAttributes([Name]) pr.addFeatures([fet]) # update layer's extent when new features have been added # because change of extent in provider is not propagated to the layer vl.updateExtents() # Enable labels if attribute == 'name': label = QgsPalLayerSettings() label.readFromLayer(vl) label.enabled = True label.fieldName = attribute label.writeToLayer(vl)
def processAlgorithm(self, context, feedback): layerPoints = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.POINTS), context) layerHubs = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.HUBS), context) fieldName = self.getParameterValue(self.FIELD) units = self.UNITS[self.getParameterValue(self.UNIT)] if layerPoints.source() == layerHubs.source(): raise GeoAlgorithmExecutionException( self.tr('Same layer given for both hubs and spokes')) fields = layerPoints.fields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.LineString, layerPoints.crs(), context) index = QgsProcessingUtils.createSpatialIndex(layerHubs, context) distance = QgsDistanceArea() distance.setSourceCrs(layerPoints.crs()) distance.setEllipsoid(QgsProject.instance().ellipsoid()) # Scan source points, find nearest hub, and write to output file features = QgsProcessingUtils.getFeatures(layerPoints, context) total = 100.0 / QgsProcessingUtils.featureCount(layerPoints, context) for current, f in enumerate(features): src = f.geometry().boundingBox().center() neighbors = index.nearestNeighbor(src, 1) ft = next( layerHubs.getFeatures(QgsFeatureRequest().setFilterFid( neighbors[0]).setSubsetOfAttributes([fieldName], layerHubs.fields()))) closest = ft.geometry().boundingBox().center() hubDist = distance.measureLine(src, closest) attributes = f.attributes() attributes.append(ft[fieldName]) if units == 'Feet': attributes.append(hubDist * 3.2808399) elif units == 'Miles': attributes.append(hubDist * 0.000621371192) elif units == 'Kilometers': attributes.append(hubDist / 1000.0) elif units != 'Meters': attributes.append( sqrt( pow(src.x() - closest.x(), 2.0) + pow(src.y() - closest.y(), 2.0))) else: attributes.append(hubDist) feat = QgsFeature() feat.setAttributes(attributes) feat.setGeometry(QgsGeometry.fromPolyline([src, closest])) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
# Fetch OSM layer & features inputLayer = iface.activeLayer() feats = inputLayer.getFeatures() # Build graph for feat in feats: # Retrieve LineString geometry geom = feat.geometry() string = geom.get() # Split into segments n = len(string) - 1 segments = [] for i in range(n): start, end = string[i], string[i + 1] segment = QgsGeometry.fromPolyline([start, end]) segments.append(segment) # Process segments for segment in segments: processed[segment] = False # Mark edge as not processed for vex in segment.get(): coords = (vex.x(), vex.y()) if coords not in graph.keys(): graph[coords] = [segment] else: graph[coords].append(segment) # Check if graph vertex is intersection def is_intersection(vex, edges):
def _connect_shapes(self): path_to_shapes = self.gpkg_path + "|layername=" + 'shapes_point' layer = QgsVectorLayer(path_to_shapes, 'shapes', "ogr") # Index used to decide id field shape_dist_traveled exist idx = (layer.fields().indexFromName('shape_dist_traveled')) # load attribute table of shapes into variable features features = layer.getFeatures() # selecting unique id of shapes from features IDList = [] for feat in features: id = feat['shape_id'] IDList.append(id) uniqueId = list(set(IDList)) # create polyline layer shapes_layer = QgsVectorLayer("LineString?crs=epsg:4326", "shapes_line", "memory") pr = shapes_layer.dataProvider() layer_provider = shapes_layer.dataProvider() # add new fields to polyline layer layer_provider.addAttributes([ QgsField("shape_id", QVariant.String), QgsField("shape_dist_traveled", QVariant.Double), QgsField("shape_id_short", QVariant.String) ]) shapes_layer.updateFields() for Id in uniqueId: # select rows from attribute table, where shape_id agree with current Id in for-cycle expression = ('"shape_id" = \'%s%s\'' % (Id, '')) request = QgsFeatureRequest().setFilterExpression(expression) features_shape = layer.getFeatures(request) # sorting attribute table of features_shape by field shape_pt_sequence sorted_f_shapes = sorted(features_shape, key=lambda por: por['shape_pt_sequence']) PointList = [] DistList = [] # add coordinates of shape points and traveled distance to the list for f in sorted_f_shapes: point = QgsPoint(f['shape_pt_lon'], f['shape_pt_lat']) PointList.append(point) if idx != -1: dist = (f['shape_dist_traveled']) DistList.append(dist) # create polyline from PointList polyline = QgsFeature() polyline.setGeometry(QgsGeometry.fromPolyline(PointList)) if type(Id) == str and Id.find('V') != -1: # Create shape id short, used for joining routes shape_id_s = Id[0:Id.index('V')] # find last distance of each shape for j in range(0, len(sorted_f_shapes)): if j == (len(sorted_f_shapes) - 1): Dist = DistList[j] # adding features to attribute table of polyline polyline.setAttributes([Id, Dist, shape_id_s]) pr.addFeatures([polyline]) else: polyline.setAttributes([Id]) pr.addFeatures([polyline]) shapes_layer.updateExtents() self.gtfs.setProgress(85) return shapes_layer
def getQgsPolyline(self): pointList = self.getQgsPointList() return QgsGeometry.fromPolyline(pointList)
def processAlgorithm(self, feedback): extent = self.getParameterValue(self.EXTENT).split(',') xSpace = self.getParameterValue(self.STEP_X) ySpace = self.getParameterValue(self.STEP_Y) bbox = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3])) mapCRS = iface.mapCanvas().mapSettings().destinationCrs() fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) fields.append(QgsField('coord', QVariant.Double, '', 24, 15)) fieldCount = 2 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.LineString, mapCRS) feat = QgsFeature() feat.initAttributes(fieldCount) feat.setFields(fields) geom = QgsGeometry() idVar = 0 count = 0 count_max = (bbox.yMaximum() - bbox.yMinimum()) / ySpace count_update = count_max * 0.10 y = bbox.yMaximum() while y >= bbox.yMinimum(): pt1 = QgsPoint(bbox.xMinimum(), y) pt2 = QgsPoint(bbox.xMaximum(), y) line = [pt1, pt2] feat.setGeometry(geom.fromPolyline(line)) feat.setAttribute(0, idVar) feat.setAttribute(1, y) writer.addFeature(feat) y = y - ySpace idVar += 1 count += 1 if int(math.fmod(count, count_update)) == 0: feedback.setProgress(int(count / count_max * 50)) feedback.setProgress(50) # counters for progressbar - update every 5% count = 0 count_max = (bbox.xMaximum() - bbox.xMinimum()) / xSpace count_update = count_max * 0.10 x = bbox.xMinimum() while x <= bbox.xMaximum(): pt1 = QgsPoint(x, bbox.yMaximum()) pt2 = QgsPoint(x, bbox.yMinimum()) line = [pt1, pt2] feat.setGeometry(geom.fromPolyline(line)) feat.setAttribute(0, idVar) feat.setAttribute(1, x) writer.addFeature(feat) x = x + xSpace idVar += 1 count += 1 if int(math.fmod(count, count_update)) == 0: feedback.setProgress(50 + int(count / count_max * 50)) del writer
def force_directed_eb(self): """ Force-directed edge bundling """ # Create compatibility matrix self.compute_compatibilty_matrix() for e_idx, edge in enumerate(self.edges): vertices = edge.geometry().asPolyline() self.epm_x[e_idx, 0] = vertices[0].x() self.epm_y[e_idx, 0] = vertices[0].y() self.epm_x[e_idx, self.N-1] = vertices[1].x() self.epm_y[e_idx, self.N-1] = vertices[1].y() # For each cycle for c in range(cycles): print 'Cycle {0}'.format(c) # New number of subdivision points current_num = self.EP currentindeces = [] for i in range(current_num): idx = int((float(i) / float(current_num - 1)) * float(self.N - 1)) currentindeces.append(idx) self.SP += 2 ** c self.EP = self.SP + 2 edgeindeces = [] newindeces = [] for i in range(self.EP): idx = int((float(i) / float(self.EP - 1)) * float(self.N - 1)) edgeindeces.append(idx) if idx not in currentindeces: newindeces.append(idx) pointindeces = edgeindeces[1:self.EP-1] # Calculate position of new points for idx in newindeces: i = int((float(idx) / float(self.N - 1)) * float(self.EP - 1)) left = i - 1 leftidx = int((float(left) / float(self.EP - 1)) * float(self.N - 1)) right = i + 1 rightidx = int((float(right) / float(self.EP - 1)) * float(self.N - 1)) self.epm_x[:, idx] = ( self.epm_x[:, leftidx] + self.epm_x[:, rightidx] ) / 2.0 self.epm_y[:, idx] = ( self.epm_y[:, leftidx] + self.epm_y[:, rightidx] ) / 2.0 # Needed for spring forces KP0 = np.zeros(shape=(self.E,1)) KP0[:,0] = np.asarray(self.edge_lengths) KP = K / (KP0 * (self.EP - 1)) # For all iterations (number decreased in every cycle) for iteration in range(self.I): # Spring forces middlepoints_x = self.epm_x[:, pointindeces] middlepoints_y = self.epm_y[:, pointindeces] neighbours_left_x = self.epm_x[:, edgeindeces[0:self.EP-2]] neighbours_left_y = self.epm_y[:, edgeindeces[0:self.EP-2]] neighbours_right_x = self.epm_x[:, edgeindeces[2:self.EP]] neighbours_right_y = self.epm_y[:, edgeindeces[2:self.EP]] springforces_x = (neighbours_left_x - middlepoints_x + neighbours_right_x - middlepoints_x) * KP springforces_y = (neighbours_left_y - middlepoints_y + neighbours_right_y - middlepoints_y) * KP # Electrostatic forces electrostaticforces_x = np.zeros(shape=(self.E, self.SP)) electrostaticforces_y = np.zeros(shape=(self.E, self.SP)) # Loop through all edges for e_idx, edge in enumerate(self.edges): # Loop through compatible edges comp_list = np.where(self.compatibility_matrix[:,e_idx] > 0) for other_idx in np.nditer(comp_list, ['zerosize_ok']): otherindeces = pointindeces[:] if self.direction_matrix[e_idx,other_idx] < 0: otherindeces.reverse() # Distance between points subtr_x = self.epm_x[other_idx, otherindeces] - self.epm_x[e_idx, pointindeces] subtr_y = self.epm_y[other_idx, otherindeces] - self.epm_y[e_idx, pointindeces] distance = np.sqrt( np.add( np.multiply(subtr_x, subtr_x), np.multiply(subtr_y, subtr_y))) flocal_x = map(forcecalcx, subtr_x, subtr_y, distance) flocal_y = map(forcecalcy, subtr_x, subtr_y, distance) # Sum of forces electrostaticforces_x[e_idx, :] += flocal_x electrostaticforces_y[e_idx, :] += flocal_y # Compute total forces force_x = (springforces_x + electrostaticforces_x) * self.S force_y = (springforces_y + electrostaticforces_y) * self.S # Compute new point positions self.epm_x[:, pointindeces] += force_x self.epm_y[:, pointindeces] += force_y # Adjustments for next cycle self.S = self.S * sdc # Decrease weighting factor self.I = int(round(self.I * idc)) # Decrease iterations for e_idx in range(self.E): # Create a new polyline out of the line array line = map(lambda p,q: QgsPoint(p,q), self.epm_x[e_idx], self.epm_y[e_idx]) self.edges[e_idx].setGeometry(QgsGeometry.fromPolyline(line))
def processAlgorithm(self, progress): layerPoints = dataobjects.getObjectFromUri( self.getParameterValue(self.POINTS)) layerHubs = dataobjects.getObjectFromUri( self.getParameterValue(self.HUBS)) fieldName = self.getParameterValue(self.FIELD) addLines = self.getParameterValue(self.GEOMETRY) units = self.UNITS[self.getParameterValue(self.UNIT)] if layerPoints.source() == layerHubs.source(): raise GeoAlgorithmExecutionException( self.tr('Same layer given for both hubs and spokes')) geomType = QGis.WKBPoint if addLines: geomType = QGis.WKBLineString fields = layerPoints.pendingFields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, geomType, layerPoints.crs()) # Create array of hubs in memory hubs = [] features = vector.features(layerHubs) for f in features: hubs.append(Hub(f.geometry().boundingBox().center(), unicode(f[fieldName]))) distance = QgsDistanceArea() distance.setSourceCrs(layerPoints.crs().srsid()) distance.setEllipsoidalMode(True) # Scan source points, find nearest hub, and write to output file features = vector.features(layerPoints) total = 100.0 / len(features) for current, f in enumerate(features): src = f.geometry().boundingBox().center() closest = hubs[0] hubDist = distance.measureLine(src, closest.point) for hub in hubs: dist = distance.measureLine(src, hub.point) if dist < hubDist: closest = hub hubDist = dist attributes = f.attributes() attributes.append(closest.name) if units == 'Feet': attributes.append(hubDist * 3.2808399) elif units == 'Miles': attributes.append(hubDist * 0.000621371192) elif units == 'Kilometers': attributes.append(hubDist / 1000.0) elif units != 'Meters': attributes.append(sqrt( pow(src.x() - closest.point.x(), 2.0) + pow(src.y() - closest.point.y(), 2.0))) else: attributes.append(hubDist) feat = QgsFeature() feat.setAttributes(attributes) if geomType == QGis.WKBPoint: feat.setGeometry(QgsGeometry.fromPoint(src)) else: feat.setGeometry(QgsGeometry.fromPolyline([src, closest.point])) writer.addFeature(feat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT), context) index = self.getParameterValue(self.TYPE) splitNodes = False if index == 0: newType = QgsWkbTypes.Point elif index == 1: newType = QgsWkbTypes.Point splitNodes = True elif index == 2: newType = QgsWkbTypes.LineString elif index == 3: newType = QgsWkbTypes.MultiLineString elif index == 4: newType = QgsWkbTypes.Polygon else: newType = QgsWkbTypes.Point writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), newType, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): geom = f.geometry() geomType = geom.wkbType() if geomType in [QgsWkbTypes.Point, QgsWkbTypes.Point25D]: if newType == QgsWkbTypes.Point: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format( geomType, newType)) elif geomType in [ QgsWkbTypes.MultiPoint, QgsWkbTypes.MultiPoint25D ]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asMultiPoint() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format( geomType, newType)) elif geomType in [ QgsWkbTypes.LineString, QgsWkbTypes.LineString25D ]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asPolyline() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format( geomType, newType)) elif geomType in [ QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiLineString25D ]: if newType == QgsWkbTypes.Point and splitNodes: lines = geom.asMultiPolyline() for line in lines: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: lines = geom.asMultiPolyline() for line in lines: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(line)) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format( geomType, newType)) elif geomType in [QgsWkbTypes.Polygon, QgsWkbTypes.Polygon25D]: if newType == QgsWkbTypes.Point and splitNodes: rings = geom.asPolygon() for ring in rings: for p in ring: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: rings = geom.asPolygon() feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromMultiPolyline(rings)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format( geomType, newType)) elif geomType in [ QgsWkbTypes.MultiPolygon, QgsWkbTypes.MultiPolygon25D ]: if newType == QgsWkbTypes.Point and splitNodes: polygons = geom.asMultiPolygon() for polygon in polygons: for line in polygon: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: polygons = geom.asMultiPolygon() for polygons in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(polygon)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: polygons = geom.asMultiPolygon() for polygon in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolygon(polygon)) writer.addFeature(feat) elif newType in [ QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiPolygon ]: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format( geomType, newType)) feedback.setProgress(int(current * total)) del writer
def processFeature(self, feature, feedback): if feature.hasGeometry(): geom = feature.geometry() geomType = QgsWkbTypes.flatType(geom.wkbType()) newGeom = None if geomType == QgsWkbTypes.Point: points = self._gridify([geom.asPoint()], self.h_spacing, self.v_spacing) newGeom = QgsGeometry.fromPoint(points[0]) elif geomType == QgsWkbTypes.MultiPoint: points = self._gridify(geom.asMultiPoint(), self.h_spacing, self.v_spacing) newGeom = QgsGeometry.fromMultiPoint(points) elif geomType == QgsWkbTypes.LineString: points = self._gridify(geom.asPolyline(), self.h_spacing, self.v_spacing) if len(points) < 2: feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id())) newGeom = None else: newGeom = QgsGeometry.fromPolyline(points) elif geomType == QgsWkbTypes.MultiLineString: polyline = [] for line in geom.asMultiPolyline(): points = self._gridify(line, self.h_spacing, self.v_spacing) if len(points) > 1: polyline.append(points) if len(polyline) <= 0: feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolyline(polyline) elif geomType == QgsWkbTypes.Polygon: polygon = [] for line in geom.asPolygon(): points = self._gridify(line, self.h_spacing, self.v_spacing) if len(points) > 1: polygon.append(points) if len(polygon) <= 0: feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id())) newGeom = None else: newGeom = QgsGeometry.fromPolygon(polygon) elif geomType == QgsWkbTypes.MultiPolygon: multipolygon = [] for polygon in geom.asMultiPolygon(): newPolygon = [] for line in polygon: points = self._gridify(line, self.h_spacing, self.v_spacing) if len(points) > 2: newPolygon.append(points) if len(newPolygon) > 0: multipolygon.append(newPolygon) if len(multipolygon) <= 0: feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolygon(multipolygon) if newGeom is not None: feature.setGeometry(newGeom) else: feature.clearGeometry() return feature
def processAlgorithm(self, progress): extent = self.getParameterValue(self.EXTENT).split(',') xSpace = self.getParameterValue(self.STEP_X) ySpace = self.getParameterValue(self.STEP_Y) polygon = self.getParameterValue(self.TYPE) == 0 bbox = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3])) mapCRS = iface.mapCanvas().mapSettings().destinationCrs() fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) if polygon: fields.append(QgsField('xmin', QVariant.Double, '', 24, 15)) fields.append(QgsField('xmax', QVariant.Double, '', 24, 15)) fields.append(QgsField('ymin', QVariant.Double, '', 24, 15)) fields.append(QgsField('ymax', QVariant.Double, '', 24, 15)) fieldCount = 5 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QGis.WKBPolygon, mapCRS) else: fields.append(QgsField('coord', QVariant.Double, '', 24, 15)) fieldCount = 2 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QGis.WKBLineString, mapCRS) feat = QgsFeature() feat.initAttributes(fieldCount) feat.setFields(fields) geom = QgsGeometry() idVar = 0 if not polygon: count = 0 count_max = (bbox.yMaximum() - bbox.yMinimum()) / ySpace count_update = count_max * 0.10 y = bbox.yMaximum() while y >= bbox.yMinimum(): pt1 = QgsPoint(bbox.xMinimum(), y) pt2 = QgsPoint(bbox.xMaximum(), y) line = [pt1, pt2] feat.setGeometry(geom.fromPolyline(line)) feat.setAttribute(0, idVar) feat.setAttribute(1, y) writer.addFeature(feat) y = y - ySpace idVar += 1 count += 1 if int(math.fmod(count, count_update)) == 0: progress.setPercentage(int(count / count_max * 50)) progress.setPercentage(50) # counters for progressbar - update every 5% count = 0 count_max = (bbox.xMaximum() - bbox.xMinimum()) / xSpace count_update = count_max * 0.10 x = bbox.xMinimum() while x <= bbox.xMaximum(): pt1 = QgsPoint(x, bbox.yMaximum()) pt2 = QgsPoint(x, bbox.yMinimum()) line = [pt1, pt2] feat.setGeometry(geom.fromPolyline(line)) feat.setAttribute(0, idVar) feat.setAttribute(1, x) writer.addFeature(feat) x = x + xSpace idVar += 1 count += 1 if int(math.fmod(count, count_update)) == 0: progress.setPercentage(50 + int(count / count_max * 50)) else: # counters for progressbar - update every 5% count = 0 count_max = (bbox.yMaximum() - bbox.yMinimum()) / ySpace count_update = count_max * 0.05 y = bbox.yMaximum() while y >= bbox.yMinimum(): x = bbox.xMinimum() while x <= bbox.xMaximum(): pt1 = QgsPoint(x, y) pt2 = QgsPoint(x + xSpace, y) pt3 = QgsPoint(x + xSpace, y - ySpace) pt4 = QgsPoint(x, y - ySpace) pt5 = QgsPoint(x, y) polygon = [[pt1, pt2, pt3, pt4, pt5]] feat.setGeometry(geom.fromPolygon(polygon)) feat.setAttribute(0, idVar) feat.setAttribute(1, x) feat.setAttribute(2, x + xSpace) feat.setAttribute(3, y - ySpace) feat.setAttribute(4, y) writer.addFeature(feat) idVar += 1 x = x + xSpace y = y - ySpace count += 1 if int(math.fmod(count, count_update)) == 0: progress.setPercentage(int(count / count_max * 100)) del writer
def testFromLine(self): myLine = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)]) myMessage = ('Expected:\n%s\nGot:\n%s\n' % (QGis.WKBLineString, myLine.type())) assert myLine.wkbType() == QGis.WKBLineString, myMessage