def __init__(self, xmin, ymin, xmax, ymax, x_segments, y_segments): self.vbands = [] self.hbands = [] self.vidx = QgsSpatialIndex() self.hidx = QgsSpatialIndex() xres = (xmax - xmin) / x_segments yres = (ymax - ymin) / y_segments self.xmin, self.ymax, self.xres, self.yres = xmin, ymax, xres, yres def addVBand(idx, geom): f = QgsFeature(idx) f.setGeometry(geom) self.vbands.append(f) self.vidx.insertFeature(f) def addHBand(idx, geom): f = QgsFeature(idx) f.setGeometry(geom) self.hbands.append(f) self.hidx.insertFeature(f) for x in range(x_segments): pt0 = QgsPoint(xmin + x * xres, ymax) pt1 = QgsPoint(xmin + x * xres, ymin) pt2 = QgsPoint(xmin + (x + 1) * xres, ymin) pt3 = QgsPoint(xmin + (x + 1) * xres, ymax) addVBand(x, QgsGeometry.fromPolygon([[pt0, pt1, pt2, pt3, pt0]])) for y in range(y_segments): pt0 = QgsPoint(xmin, ymax - y * yres) pt1 = QgsPoint(xmin, ymax - (y + 1) * yres) pt2 = QgsPoint(xmax, ymax - (y + 1) * yres) pt3 = QgsPoint(xmax, ymax - y * yres) addHBand(y, QgsGeometry.fromPolygon([[pt0, pt1, pt2, pt3, pt0]]))
def testOverlaps(self): myPolyA = QgsGeometry.fromPolygon([[QgsPoint(0, 0),QgsPoint(1, 3),QgsPoint(2, 0),QgsPoint(0, 0)]]) myPolyB = QgsGeometry.fromPolygon([[QgsPoint(0, 0),QgsPoint(2, 0),QgsPoint(2, 2),QgsPoint(0, 2), QgsPoint(0, 0)]]) overlapsGeom = QgsGeometry.overlaps(myPolyA, myPolyB) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", overlapsGeom)) assert overlapsGeom == True, myMessage
def fillHoles(self, layer, minWidth, minHeight, layerName): provider = layer.dataProvider() fields = provider.fields() writer = QgsVectorLayer("Polygon?crs=EPSG:2180", layerName, "memory") writer.startEditing() layer.startEditing() for feat in layer.getFeatures(): geometry = feat.geometry() if geometry.isMultipart(): multi_polygon = geometry.asMultiPolygon() for polygon in multi_polygon: for ring in polygon[1:]: geometry, area, perim, angle, width, height = self.OMBBox(QgsGeometry.fromPolygon([ring])) if width <= minWidth or height <= minHeight or area <=minWidth*minHeight: polygon.remove(ring) geometry = QgsGeometry.fromMultiPolygon(multi_polygon) else: polygon = geometry.asPolygon() for ring in polygon[1:]: geometry, area, perim, angle, width, height = self.OMBBox(QgsGeometry.fromPolygon([ring])) if width <= minWidth or height <= minHeight or area <= minWidth * minHeight: polygon.remove(ring) geometry = QgsGeometry.fromPolygon(polygon) outFeat = QgsFeature() outFeat.setGeometry(geometry) writer.addFeature(feat) writer.commitChanges() layer.commitChanges() return writer
def qgsgeom_from_mpl_collec(collections): polygons = [] for i, polygon in enumerate(collections): mpoly = [] for path in polygon.get_paths(): path.should_simplify = False poly = path.to_polygons() if len(poly) > 0 and len(poly[0]) > 3: exterior = [QgsPoint(*p.tolist()) for p in poly[0]] holes = [[QgsPoint(*p.tolist()) for p in h] for h in poly[1:] if len(h) > 3] if len(holes) == 1: mpoly.append([exterior, holes[0]]) elif len(holes) > 1: mpoly.append([exterior] + [h for h in holes]) else: mpoly.append([exterior]) if len(mpoly) == 1: polygons.append(QgsGeometry.fromPolygon(mpoly[0])) elif len(mpoly) > 1: polygons.append(QgsGeometry.fromMultiPolygon(mpoly)) else: polygons.append(QgsGeometry.fromPolygon([])) return polygons
def ovals(self, writer, features, width, height, rotation, segments): ft = QgsFeature() xOffset = width / 2.0 yOffset = height / 2.0 if rotation is not None: phi = rotation * math.pi / 180 for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft) else: for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft)
def diamonds(self, writer, features, width, height, rotation): ft = QgsFeature() xOffset = width / 2.0 yOffset = height / 2.0 if rotation is not None: phi = rotation * math.pi / 180 for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft) else: for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft)
def diamonds(self, writer, features, width, height, rotation): ft = QgsFeature() if rotation is not None: for current, feat in enumerate(features): w = feat[width] h = feat[height] angle = feat[rotation] if not w or not h or not angle: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr("Feature {} has empty " "width, height or angle. " "Skipping...".format(feat.id())), ) continue xOffset = w / 2.0 yOffset = h / 2.0 phi = angle * math.pi / 180 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [ [ QgsPoint( i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y, ) for i in points ] ] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft) else: for current, feat in enumerate(features): w = feat[width] h = feat[height] if not w or not h: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr("Feature {} has empty " "width or height. " "Skipping...".format(feat.id())), ) continue xOffset = w / 2.0 yOffset = h / 2.0 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft)
def ovals(self, writer, features, width, height, rotation, segments): ft = QgsFeature() if rotation is not None: for current, feat in enumerate(features): w = feat[width] h = feat[height] angle = feat[rotation] if not w or not h or not angle: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('Feature {} has empty ' 'width, height or angle. ' 'Skipping...'.format(feat.id()))) continue xOffset = w / 2.0 yOffset = h / 2.0 phi = angle * math.pi / 180 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft) else: for current, feat in enumerate(features): w = feat[width] h = feat[height] if not w or not h: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('Feature {} has empty ' 'width or height. ' 'Skipping...'.format(feat.id()))) continue xOffset = w / 2.0 yOffset = h / 2.0 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft)
def completePolygon(self,geom, p4): if (len(geom)>=2) and (len(geom) % 2 == 0): p1 = geom[1] p2 = geom[0] p3 = geom[-1] pf = self.lineIntersection(p1, p2, p3, p4) new_geom = QgsGeometry.fromPolygon([self.geometry+[p4, pf]]) else: new_geom = QgsGeometry.fromPolygon([self.geometry+[QgsPoint(p4.x(), p4.y())]]) pf = p4 return new_geom, pf
def diamonds(self, writer, features, width, height, rotation): ft = QgsFeature() if rotation is not None: for current, feat in enumerate(features): w = feat[width] h = feat[height] angle = feat[rotation] if not w or not h or not angle: QgsMessageLog.logMessage(self.tr('Feature {} has empty ' 'width, height or angle. ' 'Skipping...'.format(feat.id())), self.tr('Processing'), QgsMessageLog.WARNING) continue xOffset = w / 2.0 yOffset = h / 2.0 phi = angle * math.pi / 180 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPointXY(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft, QgsFeatureSink.FastInsert) else: for current, feat in enumerate(features): w = feat[width] h = feat[height] if not w or not h: QgsMessageLog.logMessage(self.tr('Feature {} has empty ' 'width or height. ' 'Skipping...'.format(feat.id())), self.tr('Processing'), QgsMessageLog.WARNING) continue xOffset = w / 2.0 yOffset = h / 2.0 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPointXY(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft, QgsFeatureSink.FastInsert)
def ovals(self, sink, source, width, height, rotation, segments, feedback): features = source.getFeatures() ft = QgsFeature() xOffset = width / 2.0 yOffset = height / 2.0 total = 100.0 / source.featureCount() if source.featureCount() else 0 if rotation is not None: phi = rotation * math.pi / 180 for current, feat in enumerate(features): if feedback.isCanceled(): break if not feat.hasGeometry(): continue point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPointXY(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) sink.addFeature(ft, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) else: for current, feat in enumerate(features): if feedback.isCanceled(): break if not feat.hasGeometry(): continue point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPointXY(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) sink.addFeature(ft, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total))
def drawLimits2 (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("Polygon", "Limites", "memory") v_layer.setLayerTransparency(70) symbols =v_layer.rendererV2().symbols() symbol=symbols[0] symbol.setColor(QColor('green')) #create the provider and add the layer pr = v_layer.dataProvider() poly = QgsFeature() #draw the lines between the buttons in order points = self.tool.polygon #print points[0].x() poly.setGeometry(QgsGeometry.fromPolygon([self.tool.polygon])) #add the lines to the provider and update the layer pr.addFeatures([poly]) v_layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayers([v_layer]) #add the points to the QlistWidget for i in range (len(self.tool.polygon)): self.addItem(i)
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 geom(elem, mesh): ring = [] for ni in elem.node_indexes(): ring.append(n2pt(ni, mesh)) ring.append(n2pt(elem.node_index(0), mesh)) geometry = QgsGeometry.fromPolygon([ring]) return geometry
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), QgsWkbTypes.Polygon, layer.crs(), context) outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): outGeomList = [] if f.geometry().isMultipart(): outGeomList = f.geometry().asMultiPolyline() else: outGeomList.append(f.geometry().asPolyline()) polyGeom = self.removeBadLines(outGeomList) if len(polyGeom) != 0: outFeat.setGeometry(QgsGeometry.fromPolygon(polyGeom)) attrs = f.attributes() outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields().toList(), QgsWkbTypes.Polygon, layer.crs() ) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): outGeomList = [] if f.geometry().isMultipart(): outGeomList = f.geometry().asMultiPolyline() else: outGeomList.append(f.geometry().asPolyline()) polyGeom = self.removeBadLines(outGeomList) if len(polyGeom) != 0: outFeat.setGeometry(QgsGeometry.fromPolygon(polyGeom)) attrs = f.attributes() outFeat.setAttributes(attrs) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def test_ExpressionFieldEllipsoidAreaCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("Polygon?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.fromPolygon([[QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853), QgsPoint(2520109, 2397715), QgsPoint(2520792, 2425494), QgsPoint(2484588, 2425722)]])) 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", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMeters)) idx = temp_layer.addExpressionField('$area', QgsField('area', QVariant.Double)) # NOQA # check value f = temp_layer.getFeatures().next() expected = 1009089817.0 self.assertAlmostEqual(f['area'], expected, delta=1.0) # change project area unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMiles)) f = temp_layer.getFeatures().next() expected = 389.6117565069 self.assertAlmostEqual(f['area'], expected, 3)
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 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 testContains(self): myPoly = QgsGeometry.fromPolygon([[QgsPoint(0, 0),QgsPoint(2, 0),QgsPoint(2, 2),QgsPoint(0, 2), QgsPoint(0, 0)]]) myPoint = QgsGeometry.fromPoint(QgsPoint(1, 1)) containsGeom = QgsGeometry.contains(myPoly, myPoint) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", containsGeom)) assert containsGeom == True, myMessage
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields(), layer.wkbType(), layer.crs() ) features = vector.features(layer) total = 100.0 / len(features) feat = QgsFeature() for current, f in enumerate(features): geometry = f.geometry() if geometry: if geometry.isMultipart(): multi_polygon = geometry.asMultiPolygon() for polygon in multi_polygon: for ring in polygon[1:]: polygon.remove(ring) geometry = QgsGeometry.fromMultiPolygon(multi_polygon) else: polygon = geometry.asPolygon() for ring in polygon[1:]: polygon.remove(ring) geometry = QgsGeometry.fromPolygon(polygon) else: geometry = QgsGeometry(None) feat.setGeometry(geometry) feat.setAttributes(f.attributes()) writer.addFeature(feat) progress.setPercentage(int(current * total)) del writer
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 _rectangleGridPoly(self, writer, width, height, originX, originY, hSpacing, vSpacing): ft = QgsFeature() columns = int(math.floor(float(width) / hSpacing)) rows = int(math.floor(float(height) / vSpacing)) for col in xrange(0, columns): # (column + 1) and (row + 1) calculation is used to maintain # topology between adjacent shapes and avoid overlaps/holes # due to rounding errors x1 = originX + (col * hSpacing) x2 = originX + ((col + 1) * hSpacing) for row in xrange(0, rows): y1 = originY + (row * vSpacing) y2 = originY + ((row + 1) * vSpacing) polyline = [] polyline.append(QgsPoint(x1, y1)) polyline.append(QgsPoint(x2, y1)) polyline.append(QgsPoint(x2, y2)) polyline.append(QgsPoint(x1, y2)) polyline.append(QgsPoint(x1, y1)) ft.setGeometry(QgsGeometry.fromPolygon([polyline])) ft.setAttributes([x1, y1, x2, y2]) writer.addFeature(ft)
def CalculateSheet(sheetTypeID,s_lats,s_longs,Xg,Yg): laty=s_lats lcount=0 id=0 for i in range(0,Yg): longx=s_longs bx1=0 s=" " for j in range(0,Xg): Blt_deg,Blt_min,Blt_sec=sectodeg(laty) # Bottom latitude Lln_deg,Lln_min,Lln_sec=sectodeg(longx) # Left longitude tlaty=laty+sheeth Tlt_deg,Tlt_min,Tlt_sec=sectodeg(tlaty) # Top latitude rlongx=longx+sheetw Rln_deg,Rln_min,Rln_sec=sectodeg(rlongx) # Right longitude xmin=DMS2DD(Lln_deg,Lln_min,Lln_sec) ymin=DMS2DD(Blt_deg,Blt_min,Blt_sec) xmax=DMS2DD(Rln_deg,Rln_min,Rln_sec) ymax=DMS2DD(Tlt_deg,Tlt_min,Tlt_sec) if sheetTypeID==1: Sheetnum=CalculateOldSheetNum(Blt_deg,Blt_min,Blt_sec,Lln_deg,Lln_min,Lln_sec) else: Sheetnum=CalcWGS84_Sheetno(Blt_deg,Blt_min,Blt_sec,Lln_deg,Lln_min,Lln_sec) points = [QgsPoint(xmin,ymin),QgsPoint(xmin,ymax),QgsPoint(xmax,ymax),QgsPoint(xmax,ymin),QgsPoint(xmin,ymin)] poly.setGeometry(QgsGeometry.fromPolygon([points])) poly.setAttributes([id,Sheetnum,0]) id=id+1 pr.addFeatures([poly]) longx=longx+sheetw laty=laty+sheeth
def splitPolygons(self, geom): xmin, ymax, xres, yres = self.xmin, self.ymax, self.xres, self.yres for x, vi in self.vSplit(geom): for y in self.hIntersects(vi): pt0 = QgsPoint(xmin + x * xres, ymax - y * yres) pt1 = QgsPoint(xmin + x * xres, ymax - (y + 1) * yres) pt2 = QgsPoint(xmin + (x + 1) * xres, ymax - (y + 1) * yres) pt3 = QgsPoint(xmin + (x + 1) * xres, ymax - y * yres) quad = QgsGeometry.fromPolygon([[pt0, pt1, pt2, pt3, pt0]]) tris = [[[pt0, pt1, pt3, pt0]], [[pt3, pt1, pt2, pt3]]] if geom.contains(quad): yield tris[0] yield tris[1] else: for i, tri in enumerate(map(QgsGeometry.fromPolygon, tris)): if geom.contains(tri): yield tris[i] elif geom.intersects(tri): poly = geom.intersection(tri) if poly.isMultipart(): for sp in poly.asMultiPolygon(): yield sp else: yield poly.asPolygon()
def _diamondGrid(self, writer, width, height, originX, originY, hSpacing, vSpacing): ft = QgsFeature() halfHSpacing = hSpacing / 2 halfVSpacing = vSpacing / 2 columns = int(math.floor(float(width) / halfHSpacing)) rows = int(math.floor(float(height) / vSpacing)) for col in xrange(0, columns): x1 = originX + ((col + 0) * halfHSpacing) x2 = originX + ((col + 1) * halfHSpacing) x3 = originX + ((col + 2) * halfHSpacing) for row in xrange(0, rows): if (col % 2) == 0: y1 = originY + (((row * 2) + 0) * halfVSpacing) y2 = originY + (((row * 2) + 1) * halfVSpacing) y3 = originY + (((row * 2) + 2) * halfVSpacing) else: y1 = originY + (((row * 2) + 1) * halfVSpacing) y2 = originY + (((row * 2) + 2) * halfVSpacing) y3 = originY + (((row * 2) + 3) * halfVSpacing) polyline = [] polyline.append(QgsPoint(x1, y2)) polyline.append(QgsPoint(x2, y1)) polyline.append(QgsPoint(x3, y2)) polyline.append(QgsPoint(x2, y3)) polyline.append(QgsPoint(x1, y2)) ft.setGeometry(QgsGeometry.fromPolygon([polyline])) ft.setAttributes([x1, y1, x3, y3]) writer.addFeature(ft)
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 lines_to_polygons( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPolygon, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() 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 ): outGeomList = [] nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) if inFeat.geometry().isMultipart(): outGeomList = inFeat.geometry().asMultiPolyline() else: outGeomList.append( inFeat.geometry().asPolyline() ) polyGeom = self.remove_bad_lines( outGeomList ) if len( polyGeom ) != 0: outFeat.setGeometry( QgsGeometry.fromPolygon( polyGeom ) ) atMap = inFeat.attributes() outFeat.setAttributes( atMap ) writer.addFeature( outFeat ) del writer return True
def testMeasurePolygon(self): # +-+-+ # | | # + +-+ # | | # +-+ polygon = QgsGeometry.fromPolygon( [ [ QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(0, 2), QgsPoint(0, 0), ] ] ) da = QgsDistanceArea() area = da.measure(polygon) assert area == 3, "Expected:\n%f\nGot:\n%f\n" % (3, area) perimeter = da.measurePerimeter(polygon) assert perimeter == 8, "Expected:\n%f\nGot:\n%f\n" % (8, perimeter)
def test_union_geometry(self): """Test union_geometry work""" # Create big polygons from the point layer, # then the union is one BIG polygon dx = dy = 10 points = self._create_points() polygons = points_to_rectangles(points, dx, dy) geom = union_geometry(polygons) # The union is the rectangle # noinspection PyCallByClass,PyTypeChecker expected_area = QgsGeometry.fromPolygon([[ QgsPoint(10, 30), QgsPoint(40, 30), QgsPoint(40, 0), QgsPoint(10, 0)]]) self.assertTrue(geom.isGeosValid()) self.assertFalse(geom.isMultipart()) self.assertAlmostEquals(geom.area(), 3 * dx * 3 * dy) self.assertTrue((geom.isGeosEqual(expected_area))) polygons = points_to_rectangles(points, 0.5 * dx, 0.5 * dy) geom = union_geometry(polygons) # The union is 9 squares self.assertAlmostEquals(geom.area(), 1.5 * dx * 1.5 * dy) self.assertTrue(geom.isMultipart())
def _diamondGrid(self, writer, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback): ft = QgsFeature() halfHSpacing = hSpacing / 2 halfVSpacing = vSpacing / 2 halfHOverlay = hOverlay / 2 halfVOverlay = vOverlay / 2 columns = int(math.ceil(float(width) / (halfHSpacing - halfHOverlay))) rows = int(math.ceil(float(height) / (vSpacing - halfVOverlay))) cells = rows * columns count_update = cells * 0.05 id = 1 count = 0 for col in range(columns): x = originX - (col * halfHOverlay) x1 = x + ((col + 0) * halfHSpacing) x2 = x + ((col + 1) * halfHSpacing) x3 = x + ((col + 2) * halfHSpacing) for row in range(rows): y = originY + (row * halfVOverlay) if (col % 2) == 0: y1 = y - (((row * 2) + 0) * halfVSpacing) y2 = y - (((row * 2) + 1) * halfVSpacing) y3 = y - (((row * 2) + 2) * halfVSpacing) else: y1 = y - (((row * 2) + 1) * halfVSpacing) y2 = y - (((row * 2) + 2) * halfVSpacing) y3 = y - (((row * 2) + 3) * halfVSpacing) polyline = [] polyline.append(QgsPoint(x1, y2)) polyline.append(QgsPoint(x2, y1)) polyline.append(QgsPoint(x3, y2)) polyline.append(QgsPoint(x2, y3)) polyline.append(QgsPoint(x1, y2)) ft.setGeometry(QgsGeometry.fromPolygon([polyline])) ft.setAttributes([x1, y1, x3, y3, id]) writer.addFeature(ft) id += 1 count += 1 if int(math.fmod(count, count_update)) == 0: feedback.setProgress(int(count / cells * 100))
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 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 fromQgsGeometry(geometry, z_func, transform_func, calcCentroid=False): useCentroidHeight = True centroidPerPolygon = True polygons = geometry.asMultiPolygon() if geometry.isMultipart() else [ geometry.asPolygon() ] geom = PolygonGeometry() if calcCentroid and not centroidPerPolygon: pt = geometry.centroid().asPoint() centroidHeight = z_func(pt.x(), pt.y()) geom.centroids.append( transform_func(pt.x(), pt.y(), centroidHeight)) for polygon in polygons: if useCentroidHeight or calcCentroid: pt = QgsGeometry.fromPolygon(polygon).centroid().asPoint() centroidHeight = z_func(pt.x(), pt.y()) if calcCentroid and centroidPerPolygon: geom.centroids.append( transform_func(pt.x(), pt.y(), centroidHeight)) if useCentroidHeight: z_func = lambda x, y: centroidHeight boundaries = [] # outer boundary points = [] for pt in polygon[0]: points.append( transform_func(pt.x(), pt.y(), z_func(pt.x(), pt.y()))) if not GeometryUtils.isClockwise(points): points.reverse() # to clockwise boundaries.append(points) # inner boundaries for boundary in polygon[1:]: points = [ transform_func(pt.x(), pt.y(), z_func(pt.x(), pt.y())) for pt in boundary ] if GeometryUtils.isClockwise(points): points.reverse() # to counter-clockwise boundaries.append(points) geom.polygons.append(boundaries) return geom
def getPointsOutsidePolygon(self, polygon, indexpoints, points): """ return a new triangulation based on triangles visbles in the canvas. return index of selafin points correspondind to the new triangulation """ #first get triangles in linebounding box ************************************************************ mesh = np.array(self.selafinlayer.hydrauparser.getIkle()) recttemp = self.qgspolygone.boundingBox() rect = [ float(recttemp.xMinimum()), float(recttemp.xMaximum()), float(recttemp.yMinimum()), float(recttemp.yMaximum()) ] xMesh, yMesh = self.selafinlayer.hydrauparser.getMesh() trianx = np.array( [xMesh[mesh[:, 0]], xMesh[mesh[:, 1]], xMesh[mesh[:, 2]]]) trianx = np.transpose(trianx) triany = [yMesh[mesh[:, 0]], yMesh[mesh[:, 1]], yMesh[mesh[:, 2]]] triany = np.transpose(triany) valtabx = np.where(np.logical_and(trianx > rect[0], trianx < rect[1])) valtaby = np.where(np.logical_and(triany > rect[2], triany < rect[3])) #index of triangles in canvas goodnums = np.intersect1d(valtabx[0], valtaby[0]) #goodikle = mesh[goodnums] #goodpointindex = np.unique(goodikle) #second get triangles intersecting contour of polygon ************************************************************ goodnums2 = [] qgspolygontoline = self.qgspolygone.convertToType(1) for goodnum in goodnums: if QgsGeometry.fromPolygon([[ QgsPoint(xMesh[i], yMesh[i]) for i in mesh[goodnum] ]]).intersects(qgspolygontoline): goodnums2.append(goodnum) pointstemp = points.tolist() for goodnum in goodnums2: for indexpoint in mesh[goodnum]: if not indexpoint in indexpoints: indexpoints.append(indexpoint) pointstemp.append([xMesh[indexpoint], yMesh[indexpoint]]) return indexpoints, np.array(pointstemp)
def diamonds(self, writer, features, width, height, rotation): ft = QgsFeature() xOffset = width / 2.0 yOffset = height / 2.0 if rotation is not None: phi = rotation * math.pi / 180 for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[ QgsPointXY( i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points ]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft, QgsFeatureSink.FastInsert) else: for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPointXY(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft, QgsFeatureSink.FastInsert)
def transform(self, meta_features, force_reduction_factor, geometry): """Transform the geometry based on the force reduction factor.""" if geometry.isMultipart(): geometries = [] for polygon in geometry.asMultiPolygon(): new_polygon = self.transform_polygon(polygon, meta_features, force_reduction_factor) geometries.append(new_polygon) return QgsGeometry.fromMultiPolygonXY(geometries) else: polygon = geometry.asPolygon() new_polygon = self.transform_polygon(polygon, meta_features, force_reduction_factor) return QgsGeometry.fromPolygon(new_polygon)
def smethod_3(polylineArea_0, altitude_0, altitude_1): # DBObjectCollection dBObjectCollection; polylineAreaList = HoldingTemplateBase.smethod_0( polylineArea_0, Unit.ConvertNMToMeter(1), 5) # DBObjectCollection dBObjectCollection2 = new DBObjectCollection(); num = 0.5 metres = altitude_0.Metres - altitude_1.Metres resultGeometryList = [] for i in range(5): if (i > 0): metres = altitude_0.Metres - num * altitude_1.Metres num = num - 0.1 # (dBObjectCollection1.get_Item(i) as Polyline).set_Elevation(metres); # DBObjectCollection dBObjectCollection3 = new DBObjectCollection(); # dBObjectCollection3.Add(dBObjectCollection1.get_Item(i)); item = polylineAreaList[i].method_14_closed(4) itemGeometry = QgsGeometry.fromPolygon([item]) # item.SetDatabaseDefaults(); if (i > 0): # (dBObjectCollection1.get_Item(i - 1) as Polyline).set_Elevation(metres); # DBObjectCollection dBObjectCollection4 = new DBObjectCollection(); # dBObjectCollection4.Add(dBObjectCollection1.get_Item(i - 1)); regionGeometry = QgsGeometry.fromPolygon( [polylineAreaList[i - 1].method_14_closed(4)]) polygonNew = itemGeometry.difference(regionGeometry) resultGeometryList.append(polygonNew) else: resultGeometryList.append(itemGeometry) # region.SetDatabaseDefaults(); # item.BooleanOperation(2, region); # region.Dispose(); # } # dBObjectCollection2.Add(item); # } # dBObjectCollection = dBObjectCollection2; return resultGeometryList
def insertTempFeatures(layer, geometry, attributes): provider = layer.dataProvider() geometry_type = provider.geometryType() for i, geom in enumerate(geometry): fet = QgsFeature() if geometry_type in (1, 4): fet.setGeometry(QgsGeometry.fromPoint(geom)) elif geometry_type in (2, 5): fet.setGeometry(QgsGeometry.fromPolyline(geom)) elif geometry_type in (3, 6): fet.setGeometry(QgsGeometry.fromPolygon(geom)) if attributes: fet.setAttributes(attributes[i]) provider.addFeatures([fet]) provider.updateExtents()
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 test_ExpressionFieldEllipsoidAreaCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("Polygon?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.fromPolygon([[ QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853), QgsPoint(2520109, 2397715), QgsPoint(2520792, 2425494), QgsPoint(2484588, 2425722) ]])) 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", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMeters)) idx = temp_layer.addExpressionField('$area', QgsField('area', QVariant.Double)) # NOQA # check value f = next(temp_layer.getFeatures()) expected = 1009089817.0 self.assertAlmostEqual(f['area'], expected, delta=1.0) # change project area unit, check calculation respects unit QgsProject.instance().writeEntry( "Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMiles)) f = next(temp_layer.getFeatures()) expected = 389.6117565069 self.assertAlmostEqual(f['area'], expected, 3)
def canvasReleaseEvent(self, event): """ Canvas is released. This means: * start digitizing * stop digitizing (create a rectangle * if the Ctrl-modifier is pressed, ask for the rectangle width :param event: coordinates etc. """ if event.button() == Qt.RightButton: self.deactivate() else: mousepos = self.canvas.getCoordinateTransform()\ .toMapCoordinates(event.pos().x(), event.pos().y()) self.rubberband.addPoint(mousepos) if self.firstPoint: # If the first point was set before, we are doing the second one lp1 = self.rubberband.asGeometry().asPolyline()[0] lp2 = self.rubberband.asGeometry().asPolyline()[1] width = 0.2 if QApplication.keyboardModifiers() & Qt.ControlModifier: dlg = QDialog() dlg.setLayout(QGridLayout()) dlg.layout().addWidget(QLabel(self.tr('Enter width'))) txt = QLineEdit('0.2') dlg.layout().addWidget(txt) bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) dlg.layout().addWidget(bb) bb.accepted.connect(dlg.accept) bb.rejected.connect(dlg.reject) if dlg.exec_(): try: width = float(txt.text()) except ValueError: width = 0.2 length = math.sqrt(math.pow(lp1.x() - lp2.x(), 2) + math.pow(lp1.y() - lp2.y(), 2)) xd = lp2.x() - lp1.x() yd = lp2.y() - lp1.y() pt1 = QgsPoint(lp1.x() + width * (yd / length), lp1.y() - width * (xd / length)) pt2 = QgsPoint(lp1.x() - width * (yd / length), lp1.y() + width * (xd / length)) pt3 = QgsPoint(lp2.x() - width * (yd / length), lp2.y() + width * (xd / length)) pt4 = QgsPoint(lp2.x() + width * (yd / length), lp2.y() - width * (xd / length)) self.geometry = QgsGeometry.fromPolygon([[pt1, pt2, pt3, pt4, pt1]]) self.geometryDigitized.emit() self.firstPoint = mousepos
def create_polygon(self): """ :return: """ self.point_to_list() line_array = [] for point in self._local_list: if point != '': var = point.replace('0.0 0.0', '').strip().split(' ') line_array.append( QgsPoint(self.set_point(var[1]), self.set_point(var[0]))) geom_poly = QgsGeometry.fromPolygon([line_array]) return geom_poly
def createLayerWithOnePolygon(): layer = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory") assert layer.isValid() f1 = QgsFeature(layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry( QgsGeometry.fromPolygon([[ QgsPointXY(2484588, 2425722), QgsPointXY(2482767, 2398853), QgsPointXY(2520109, 2397715), QgsPointXY(2520792, 2425494), QgsPointXY(2484588, 2425722) ]])) assert layer.dataProvider().addFeatures([f1]) return layer
def points_to_rectangles(points, dx, dy): """Create polygon layer around points. The polygons are dx to dy. Attributes of the points are copied. A point position is upper-left corner of the created rectangle. :param points: Point layer. :type points: QgsVectorLayer :param dx: Length of the horizontal sides :type dx: float :param dy: Length of the vertical sides :type dy: float :returns: Polygon layer :rtype: QgsVectorLayer """ crs = points.crs().toWkt() point_provider = points.dataProvider() fields = point_provider.fields() # Create layer for store the lines from E and extent polygons = QgsVectorLayer( 'Polygon?crs=' + crs, 'polygons', 'memory') polygon_provider = polygons.dataProvider() polygon_provider.addAttributes(fields.toList()) polygons.startEditing() for feature in points.getFeatures(): attrs = feature.attributes() point = feature.geometry().asPoint() x, y = point.x(), point.y() # noinspection PyCallByClass,PyTypeChecker g = QgsGeometry.fromPolygon([ [QgsPoint(x, y), QgsPoint(x + dx, y), QgsPoint(x + dx, y - dy), QgsPoint(x, y - dy)] ]) polygon_feat = QgsFeature() polygon_feat.setGeometry(g) polygon_feat.setAttributes(attrs) _ = polygon_provider.addFeatures([polygon_feat]) polygons.commitChanges() return polygons
def getTrianglesWithinPolygon(self, polygon): """ return a new triangulation based on triangles visbles in the canvas. return index of selafin points correspondind to the new triangulation """ # first get triangles in linebounding box ************************************************************ mesh = np.array(self.selafinlayer.hydrauparser.getIkle()) recttemp = self.qgspolygone.boundingBox() rect = [ float(recttemp.xMinimum()), float(recttemp.xMaximum()), float(recttemp.yMinimum()), float(recttemp.yMaximum()), ] xMesh, yMesh = self.selafinlayer.hydrauparser.getMesh() trianx = np.array( [xMesh[mesh[:, 0]], xMesh[mesh[:, 1]], xMesh[mesh[:, 2]]]) trianx = np.transpose(trianx) triany = [yMesh[mesh[:, 0]], yMesh[mesh[:, 1]], yMesh[mesh[:, 2]]] triany = np.transpose(triany) valtabx = np.where(np.logical_and(trianx > rect[0], trianx < rect[1])) valtaby = np.where(np.logical_and(triany > rect[2], triany < rect[3])) # index of triangles in canvas goodnums = np.intersect1d(valtabx[0], valtaby[0]) # goodikle = mesh[goodnums] # goodpointindex = np.unique(goodikle) # second get triangles inside line ************************************************************ goodnums2 = [] for goodnum in goodnums: if QgsGeometry.fromPolygon([[ QgsPoint(xMesh[i], yMesh[i]) for i in mesh[goodnum] ]]).within(self.qgspolygone): goodnums2.append(goodnum) for goodnum in goodnums2: xtoprint = [xMesh[i] for i in mesh[goodnum]] ytoprint = [yMesh[i] for i in mesh[goodnum]] # self.status.emit(str(xtoprint)+' ' +str(ytoprint)) self.emitpoint.emit(xtoprint, ytoprint) return goodnums2
def draw_circle(self, circle): polygon = [QgsPoint(*point) for point in circle.to_polygon()] geometry = QgsGeometry.fromPolygon([polygon]) feature = QgsFeature() feature.setGeometry(geometry) destination = self.layer.crs() source = self.layer.crs() xform = self.crs_transform(source, destination) line = [ QgsPoint(circle.center.x, circle.center.y), QgsPoint(circle.center.x + circle.radius, circle.center.y), ] transformed = [ self.transform_point(xform, line[0]), self.transform_point(xform, line[1]), ] new_line_geometry = QgsGeometry.fromPolyline(transformed) distance_area = self.get_distance_area(self.layer) actual_line_distance = distance_area.measureArea(new_line_geometry) # Translate circle center to units of degrees center_in_degrees = xform.transform(circle.center.x, circle.center.y) # circle_feature.id() is NULL right now # order is id, diameter, lon, lat feature.setAttributes([ feature.id(), actual_line_distance * 2, center_in_degrees[0], center_in_degrees[1], ]) self.layer.startEditing() # self.layer.dataProvider().addFeatures([feature]) self.layer.addFeature(feature, True) self.layer.commitChanges() # update layer's extent when new features have been added # because change of extent in provider is not propagated to the layer self.layer.updateExtents()
def _diamondGrid(self, writer, width, height, originX, originY, hSpacing, vSpacing, progress): ft = QgsFeature() halfHSpacing = hSpacing / 2 halfVSpacing = vSpacing / 2 columns = int(math.ceil(float(width) / halfHSpacing)) rows = int(math.ceil(float(height) / vSpacing)) cells = rows * columns count_update = cells * 0.05 id = 1 count = 0 for col in range(columns): x1 = originX + ((col + 0) * halfHSpacing) x2 = originX + ((col + 1) * halfHSpacing) x3 = originX + ((col + 2) * halfHSpacing) for row in range(rows): if (col % 2) == 0: y1 = originY - (((row * 2) + 0) * halfVSpacing) y2 = originY - (((row * 2) + 1) * halfVSpacing) y3 = originY - (((row * 2) + 2) * halfVSpacing) else: y1 = originY - (((row * 2) + 1) * halfVSpacing) y2 = originY - (((row * 2) + 2) * halfVSpacing) y3 = originY - (((row * 2) + 3) * halfVSpacing) polyline = [] polyline.append(QgsPoint(x1, y2)) polyline.append(QgsPoint(x2, y1)) polyline.append(QgsPoint(x3, y2)) polyline.append(QgsPoint(x2, y3)) polyline.append(QgsPoint(x1, y2)) ft.setGeometry(QgsGeometry.fromPolygon([polyline])) ft.setAttributes([x1, y1, x3, y3, id]) writer.addFeature(ft) id += 1 count += 1 if int(math.fmod(count, count_update)) == 0: progress.setPercentage(int(count / cells * 100))
def _hexagonGrid(self, writer, width, height, originX, originY, hSpacing, vSpacing): ft = QgsFeature() # To preserve symmetry, hspacing is fixed relative to vspacing xVertexLo = 0.288675134594813 * vSpacing xVertexHi = 0.577350269189626 * vSpacing hSpacing = xVertexLo + xVertexHi halfVSpacing = vSpacing / 2 columns = int(math.ceil(float(width) / hSpacing)) rows = int(math.ceil(float(height) / vSpacing)) for col in xrange(columns): # (column + 1) and (row + 1) calculation is used to maintain # topology between adjacent shapes and avoid overlaps/holes # due to rounding errors x1 = originX + (col * hSpacing) # far left x2 = x1 + (xVertexHi - xVertexLo) # left x3 = originX + ((col + 1) * hSpacing) # right x4 = x3 + (xVertexHi - xVertexLo) # far right for row in xrange(rows): if (col % 2) == 0: y1 = originY - (((row * 2) + 0) * halfVSpacing) # hi y2 = originY - (((row * 2) + 1) * halfVSpacing) # mid y3 = originY - (((row * 2) + 2) * halfVSpacing) # lo else: y1 = originY - (((row * 2) + 1) * halfVSpacing) # hi y2 = originY - (((row * 2) + 2) * halfVSpacing) # mid y3 = originY - (((row * 2) + 3) * halfVSpacing) # lo polyline = [] polyline.append(QgsPoint(x1, y2)) polyline.append(QgsPoint(x2, y1)) polyline.append(QgsPoint(x3, y1)) polyline.append(QgsPoint(x4, y2)) polyline.append(QgsPoint(x3, y3)) polyline.append(QgsPoint(x2, y3)) polyline.append(QgsPoint(x1, y2)) ft.setGeometry(QgsGeometry.fromPolygon([polyline])) ft.setAttributes([x1, y1, x4, y3]) writer.addFeature(ft)
def add_rubberband_borehole(self, boreholeno): """ Warning - this method fails silently on error """ self.remove_canvas_vertexmarkers() # Add new rubberband points = [[ QgsPoint(6640629.039, 6087146.608), QgsPoint(640629.039, 6087146.608), QgsPoint(640629.039, 6087146.608), QgsPoint(6640629.039, 6087146.608) ]] # lower left, upper right r = QgsRubberBand(iface.mapCanvas, True) # True = a polygon r.setColor(QColor(0, 255, 0, 255)) r.setWidth(3) r.setToGeometry(QgsGeometry.fromPolygon(points), None) JupiterAux.log_info( u'rubberband added for borehole {}'.format(boreholeno))
def testMeasurePolygon(self): # +-+-+ # | | # + +-+ # | | # +-+ polygon = QgsGeometry.fromPolygon( [[ QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(0, 2), QgsPoint(0, 0), ]] ) da = QgsDistanceArea() area = da.measureArea(polygon) assert area == 3, 'Expected:\n%f\nGot:\n%f\n' % (3, area) perimeter = da.measurePerimeter(polygon) assert perimeter == 8, 'Expected:\n%f\nGot:\n%f\n' % (8, perimeter)
def geometry(self): seg = 50 coords = [] r_x = self.selection_rect().width() r_y = self.selection_rect().height() for i in range(seg): angle = i * 2 * math.pi / seg x = r_x * math.cos(angle) y = r_y * math.sin(angle) coords.append(QgsPointXY(x, y)) # move to correct position if version_info[0] >= 3: geom = QgsGeometry.fromPolygonXY([coords]) else: geom = QgsGeometry.fromPolygon([coords]) geom.translate(self.startPoint.x(), self.startPoint.y()) return geom
def spatialValue(self): try: if self._spatialValue == None: raise ValueError if self.spatialOperand == "gml:Point": return QgsGeometry.fromPoint(self._spatialValue).exportToWkt() elif self.spatialOperand == "gml:Envelope": return QgsGeometry.fromRect(self._spatialValue).exportToWkt() elif self.spatialOperand == "gml:Polygon": return QgsGeometry.fromPolygon( self._spatialValue).exportToWkt() elif self.spatialOperand == "gml:LineString": return QgsGeometry.fromPolyline( self._spatialValue).exportToWkt() else: raise ValueError except: return ""
def processStar(self, layer, outname, numPoints, startAngle, innerRadius, outerRadius, unitOfDist): measureFactor = self.conversionToMeters(unitOfDist) innerRadius *= measureFactor outerRadius *= measureFactor fields = layer.pendingFields() polygonLayer = QgsVectorLayer("Polygon?crs=epsg:4326", outname, "memory") ppolygon = polygonLayer.dataProvider() ppolygon.addAttributes(fields) polygonLayer.updateFields() iter = layer.getFeatures() half = (360.0 / numPoints) / 2.0 for feature in iter: pts = [] pt = feature.geometry().asPoint() # make sure the coordinates are in EPSG:4326 pt = self.transform.transform(pt.x(), pt.y()) i = numPoints - 1 while i >= 0: i -= 1 angle = (i * 360.0 / numPoints) + startAngle g = self.geod.Direct(pt.y(), pt.x(), angle, outerRadius, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPoint(g['lon2'], g['lat2'])) #lat2, lon2 = LatLon.destinationPointVincenty(pt.y(), pt.x(), angle, outerRadius) #pts.append(QgsPoint(lon2, lat2)) g = self.geod.Direct(pt.y(), pt.x(), angle - half, innerRadius, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPoint(g['lon2'], g['lat2'])) #lat2, lon2 = LatLon.destinationPointVincenty(pt.y(), pt.x(), angle-half, innerRadius) #pts.append(QgsPoint(lon2, lat2)) featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromPolygon([pts])) featureout.setAttributes(feature.attributes()) ppolygon.addFeatures([featureout]) polygonLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(polygonLayer)
def processHeart(self, layer, outname, startAngle, size, unitOfDist): measureFactor = self.conversionToMeters(unitOfDist) # The algorithm creates the heart on its side so this rotates # it so that it is upright. startAngle -= 90.0 size *= measureFactor fields = layer.pendingFields() polygonLayer = QgsVectorLayer("Polygon?crs=epsg:4326", outname, "memory") ppolygon = polygonLayer.dataProvider() ppolygon.addAttributes(fields) polygonLayer.updateFields() iter = layer.getFeatures() for feature in iter: pts = [] pt = feature.geometry().asPoint() # make sure the coordinates are in EPSG:4326 pt = self.transform.transform(pt.x(), pt.y()) angle = 0.0 while angle <= 360.0: a = math.radians(angle) sina = math.sin(a) x = 16 * sina * sina * sina y = 13 * math.cos(a) - 5 * math.cos(2 * a) - 2 * math.cos( 3 * a) - math.cos(4 * a) dist = math.sqrt(x * x + y * y) * size / 17.0 a2 = math.degrees(math.atan2(y, x)) + startAngle g = self.geod.Direct(pt.y(), pt.x(), a2, dist, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPoint(g['lon2'], g['lat2'])) angle += 0.5 featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromPolygon([pts])) featureout.setAttributes(feature.attributes()) ppolygon.addFeatures([featureout]) polygonLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(polygonLayer)
def build_qgis_feature(self, vector_item): """ Constructs a QGIS feature for rendering :param vector_item: The item returned :return a VectorFeature that can be rendered by QGIS """ feature = VectorFeature() geometry = vector_item[KEY_JSON_GEOMETRY] coordinates = geometry[KEY_JSON_GEOMETRY_COORDINATES] geometry_type = geometry[KEY_JSON_GEOMETRY_TYPE] if geometry_type == u'Point': feature.setGeometry(QgsGeometry.fromPoint(self.get_point_from_json(coordinates))) elif geometry_type == u'LineString': feature.setGeometry(QgsGeometry.fromPolyline(self.get_linestring_from_json(coordinates))) elif geometry_type == u'MultiPoint': feature.setGeometry(QgsGeometry.fromMultiPoint(self.get_linestring_from_json(coordinates))) elif geometry_type == u'Polygon': feature.setGeometry(QgsGeometry.fromPolygon(self.get_polygon_from_json(coordinates))) elif geometry_type == u'MultiLineString': feature.setGeometry(QgsGeometry.fromMultiPolyline(self.get_polygon_from_json(coordinates))) elif geometry_type == u'MultiPolygon': feature.setGeometry(QgsGeometry.fromMultiPolygon(self.get_multipolygon_from_json(coordinates))) else: QgsMessageLog.instance().logMessage(u"Encountered odd geometry type: " + geometry_type, TAG_NAME, level=QgsMessageLog.CRITICAL) feature.geometry_type = geometry_type attributes = self.get_attributes_from_json(vector_item[KEY_JSON_PROPERTIES]) fields = QgsFields() values = [] for key, value in attributes.iteritems(): type_value = None if key.endswith(u'int'): type_value = QVariant.Int elif key.endswith(u'dbl'): type_value = QVariant.Double else: type_value = QVariant.String fields.append(QgsField(key, type_value)) values.append(value) feature.setFields(fields) feature.setAttributes(values) return feature
def record_clicked(self): """record clicked signal""" # disable only service buttons self.reset_buttons(True, False, False) if not self.treeRecords.selectedItems(): return item = self.treeRecords.currentItem() if not item: return identifier = get_item_data(item, 'identifier') try: record = self.catalog.records[identifier] except KeyError as err: QMessageBox.warning(self, self.tr('Record parsing error'), 'Unable to locate record identifier') return # if the record has a bbox, show a footprint on the map if record.bbox is not None: points = bbox_to_polygon(record.bbox) if points is not None: src = QgsCoordinateReferenceSystem(4326) dst = self.map.mapSettings().destinationCrs() geom = QgsGeometry.fromPolygon(points) if src.postgisSrid() != dst.postgisSrid(): ctr = QgsCoordinateTransform(src, dst) try: geom.transform(ctr) except Exception as err: QMessageBox.warning( self, self.tr('Coordinate Transformation Error'), unicode(err)) self.rubber_band.setToGeometry(geom, None) # figure out if the data is interactive and can be operated on self.find_services(record, item)
def find_geometry(self, g): if self.output_type == 'Poly': stat = g.area() if g.isMultipart(): geometry = QgsGeometry.fromMultiPolygon(g.asMultiPolygon()) else: geometry = QgsGeometry.fromPolygon(g.asPolygon()) elif self.output_type == 'Line': stat = g.length() if g.isMultipart(): geometry = QgsGeometry.fromMultiLineString(g.asMultiPolyLine()) else: geometry = QgsGeometry.fromLineString(g.asPoly()) else: stat = 1 if g.isMultipart(): geometry = QgsGeometry.fromMultiPoint(g.asMultiPoint()) else: geometry = QgsGeometry.fromPoint(g.asPoint()) return geometry, stat
def processEpicycloid(self, layer, outname, startAngle, lobes, radius, unitOfDist): measureFactor = self.conversionToMeters(unitOfDist) radius *= measureFactor r = radius / (lobes + 2.0) fields = layer.pendingFields() polygonLayer = QgsVectorLayer("Polygon?crs=epsg:4326", outname, "memory") ppolygon = polygonLayer.dataProvider() ppolygon.addAttributes(fields) polygonLayer.updateFields() iter = layer.getFeatures() for feature in iter: pts = [] pt = feature.geometry().asPoint() # make sure the coordinates are in EPSG:4326 pt = self.transform.transform(pt.x(), pt.y()) angle = 0.0 while angle <= 360.0: a = math.radians(angle) x = r * (lobes + 1.0) * math.cos(a) - r * math.cos( (lobes + 1.0) * a) y = r * (lobes + 1.0) * math.sin(a) - r * math.sin( (lobes + 1.0) * a) a2 = math.degrees(math.atan2(y, x)) + startAngle dist = math.sqrt(x * x + y * y) g = self.geod.Direct(pt.y(), pt.x(), a2, dist, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPoint(g['lon2'], g['lat2'])) angle += 0.5 featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromPolygon([pts])) featureout.setAttributes(feature.attributes()) ppolygon.addFeatures([featureout]) polygonLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(polygonLayer)
def testMeasurePolygonWithHole(self): # +-+-+-+ # | | # + +-+ + # | | | | # + +-+ + # | | # +-+-+-+ polygon = QgsGeometry.fromPolygon( [ [QgsPoint(0, 0), QgsPoint(3, 0), QgsPoint(3, 3), QgsPoint(0, 3), QgsPoint(0, 0)], [QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(1, 2), QgsPoint(1, 1)], ] ) da = QgsDistanceArea() area = da.measureArea(polygon) assert area == 8, "Expected:\n%f\nGot:\n%f\n" % (8, area) # MH150729: Changed behavior to consider inner rings for perimeter calculation. Therefore, expected result is 16. perimeter = da.measurePerimeter(polygon) assert perimeter == 16, "Expected:\n%f\nGot:\n%f\n" % (16, perimeter)