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 testMeasureMultiPolygon(self): # +-+-+ +-+-+ # | | | | # + +-+ +-+ + # | | | | # +-+ +-+ polygon = QgsGeometry.fromMultiPolygon([[[ QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(0, 2), QgsPoint(0, 0), ]], [[ QgsPoint(4, 0), QgsPoint(5, 0), QgsPoint(5, 2), QgsPoint(3, 2), QgsPoint(3, 1), QgsPoint(4, 1), QgsPoint(4, 0), ]]]) da = QgsDistanceArea() area = da.measure(polygon) assert area == 6, 'Expected:\n%f\nGot:\n%f\n' % (6, area) perimeter = da.measurePerimeter(polygon) assert perimeter == 16, "Expected:\n%f\nGot:\n%f\n" % (16, perimeter)
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) if len(features) > 0 else 1 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 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 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 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 reprojectGridZone(self, multipoly): crsSrc = QgsCoordinateReferenceSystem(self.crs.geographicCRSAuthId()) coordinateTransformer = QgsCoordinateTransform(crsSrc, self.crs) polyline = multipoly.asMultiPolygon()[0][0] newPolyline = [] for point in polyline: newPolyline.append(coordinateTransformer.transform(point)) qgsMultiPolygon = QgsGeometry.fromMultiPolygon([[newPolyline]]) return qgsMultiPolygon
def toQgsGeometry(self): count = len(self.polygons) if count > 1: polys = map(polygonToQgsPolygon, self.polygons) return QgsGeometry.fromMultiPolygon(polys) if count == 1: return QgsGeometry.fromPolygon(polygonToQgsPolygon(self.polygons[0])) return QgsGeometry()
def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False): """ Inverts the flow from a given feature. THE GIVEN FEATURE IS ALTERED. Standard behaviour is to not refresh canvas map. :param layer: layer containing the target feature for flipping. :param feature: feature to be flipped. :param geomType: if layer geometry type is not given, it'll calculate it (0,1 or 2) :param refreshCanvas: indicates whether the canvas should be refreshed after flipping feature. :returns: flipped feature as of [layer, feature, geometry_type]. """ if not geomType: geomType = layer.geometryType() # getting whether geometry is multipart or not isMulti = QgsWKBTypes.isMultiType(int(layer.wkbType())) geom = feature.geometry() if geomType == 0: if isMulti: nodes = geom.asMultiPoint() # inverting the point list by parts for idx, part in enumerate(nodes): nodes[idx] = part[::-1] # setting flipped geometry flippedFeatureGeom = QgsGeometry.fromMultiPoint(nodes) else: # inverting the point list nodes = geom.asPoint() nodes = nodes[::-1] flippedFeatureGeom = QgsGeometry.fromPoint(nodes) elif geomType == 1: if isMulti: nodes = geom.asMultiPolyline() for idx, part in enumerate(nodes): nodes[idx] = part[::-1] flippedFeatureGeom = QgsGeometry.fromMultiPolyline(nodes) else: nodes = geom.asPolyline() nodes = nodes[::-1] flippedFeatureGeom = QgsGeometry.fromPolyline(nodes) elif geomType == 2: if isMulti: nodes = geom.asMultiPolygon() for idx, part in enumerate(nodes): nodes[idx] = part[::-1] flippedFeatureGeom = QgsGeometry.fromMultiPolygon(nodes) else: nodes = geom.asPolygon() nodes = nodes[::-1] flippedFeatureGeom = QgsGeometry.fromPolygon(nodes) # setting feature geometry to the flipped one # feature.setGeometry(flippedFeatureGeom) # layer.updateFeature(feature) layer.changeGeometry(feature.id(), flippedFeatureGeom) if refreshCanvas: self.iface.mapCanvas().refresh() return [layer, feature, geomType]
def toQgsGeometry(self): count = len(self.polygons) if count > 1: polys = [polygonToQgsPolygon(poly) for poly in self.polygons] return QgsGeometry.fromMultiPolygon(polys) if count == 1: return QgsGeometry.fromPolygon( polygonToQgsPolygon(self.polygons[0])) return QgsGeometry()
def testFromMultiPolygon(self): myMultiPolygon = QgsGeometry.fromMultiPolygon( [[[QgsPoint(1, 1), QgsPoint(2, 2), QgsPoint(1, 2), QgsPoint(1, 1)]], [[QgsPoint(2, 2), QgsPoint(3, 3), QgsPoint(3, 1), QgsPoint(2, 2)]]]) myMessage = ('Expected:\n%s\nGot:\n%s\n' % (QGis.WKBMultiPolygon, myMultiPolygon.type())) assert myMultiPolygon.wkbType() == QGis.WKBMultiPolygon, myMessage
def testFromMultiPolygon(self): myMultiPolygon = QgsGeometry.fromMultiPolygon([ [[QgsPoint(1, 1), QgsPoint(2, 2), QgsPoint(1, 2), QgsPoint(1, 1)]], [[QgsPoint(2, 2), QgsPoint(3, 3), QgsPoint(3, 1), QgsPoint(2, 2)]] ]) myMessage = ('Expected:\n%s\nGot:\n%s\n' % (QGis.WKBMultiPolygon, myMultiPolygon.type())) assert myMultiPolygon.wkbType() == QGis.WKBMultiPolygon, myMessage
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.fromMultiPolygon(geometries) else: polygon = geometry.asPolygon() new_polygon = self.transform_polygon(polygon, meta_features, force_reduction_factor) return QgsGeometry.fromPolygon(new_polygon)
def parse_geometry(gr): """node s ISLH grafikou""" g = gr[0] #obraz ma jen jeden prvek geom = ( QgsGeometry.fromPoint(islh_parser.parse_point(g)) if g.tag == 'B' else QgsGeometry.fromPolyline(islh_parser.parse_line(g)) if g.tag == 'L' else QgsGeometry.fromMultiPoint(islh_parser.parse_multipoint(g)) if g.tag == 'MB' else QgsGeometry.fromMultiPolyline(islh_parser.parse_multiline(g)) if g.tag == 'ML' else QgsGeometry.fromPolygon(islh_parser.parse_polygon(g)) if g.tag == 'P' else QgsGeometry.fromMultiPolygon(islh_parser.parse_multipolygon(g)) if g.tag == 'MP' else None) return(geom)
def spGeometry(geom, type): def split(L): n = len(L)/2 return [L[:n], L[n:]] if type == "Polygon": coords = [map(lambda p: QgsPoint(*p), zip(*split(list(po.do_slot('coords'))))) for po in geom.do_slot('Polygons')] coords = QgsGeometry.fromMultiPolygon([coords]) elif type == "LineString": coords = [map(lambda p: QgsPoint(*p), zip(*split(list(line.do_slot('coords'))))) for line in geom.do_slot('Lines')] coords = QgsGeometry.fromMultiPolyline(coords) elif type == "Point": coords = [QgsPoint(*geom)] coords = QgsGeometry.fromMultiPoint(coords) else: raise Exception("unable to convert geometries") return coords
def testMeasureMultiPolygon(self): # +-+-+ +-+-+ # | | | | # + +-+ +-+ + # | | | | # +-+ +-+ polygon = QgsGeometry.fromMultiPolygon( [ [[QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(0, 2), QgsPoint(0, 0), ]], [[QgsPoint(4, 0), QgsPoint(5, 0), QgsPoint(5, 2), QgsPoint(3, 2), QgsPoint(3, 1), QgsPoint(4, 1), QgsPoint(4, 0), ]] ] ) da = QgsDistanceArea() area = da.measureArea(polygon) assert area == 6, 'Expected:\n%f\nGot:\n%f\n' % (6, area) perimeter = da.measurePerimeter(polygon) assert perimeter == 16, "Expected:\n%f\nGot:\n%f\n" % (16, perimeter)
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 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 __polygon_grid(self, feature, wkb_type): if feature.geometry().isMultipart(): polygons = feature.geometry().asMultiPolygon() cleaned_polygons = list() for polygon in polygons: cleaned_polylines = list() for polyline in polygon: snapped_points = self.__points_to_grid(polyline) cleaned_polyline = snapped_points cleaned_polylines.append(cleaned_polyline) cleaned_polygons.append(cleaned_polylines) geom = QgsGeometry.fromMultiPolygon([x for x in cleaned_polygons]) else: polygon = feature.geometry().asPolygon() cleaned_polylines = list() for polyline in polygon: snapped_points = self.__points_to_grid(polyline) cleaned_polyline = snapped_points cleaned_polylines.append(cleaned_polyline) geom = QgsGeometry.fromPolyline(x for x in cleaned_polylines) return geom
def makeQgsPolygon(self, xmin, ymin, xmax, ymax): """Creating a polygon for the given coordinates """ dx = (xmax - xmin)/3 dy = (ymax - ymin)/3 polyline = [] point = QgsPoint(xmin, ymin) polyline.append(point) point = QgsPoint(xmin+dx, ymin) polyline.append(point) point = QgsPoint(xmax-dx, ymin) polyline.append(point) point = QgsPoint(xmax, ymin) polyline.append(point) point = QgsPoint(xmax, ymin+dy) polyline.append(point) point = QgsPoint(xmax, ymax-dy) polyline.append(point) point = QgsPoint(xmax, ymax) polyline.append(point) point = QgsPoint(xmax-dx, ymax) polyline.append(point) point = QgsPoint(xmin+dx, ymax) polyline.append(point) point = QgsPoint(xmin, ymax) polyline.append(point) point = QgsPoint(xmin, ymax-dy) polyline.append(point) point = QgsPoint(xmin, ymin+dy) polyline.append(point) point = QgsPoint(xmin, ymin) polyline.append(point) qgsPolygon = QgsGeometry.fromMultiPolygon([[polyline]]) return qgsPolygon
def makeQgsPolygon(self, xmin, ymin, xmax, ymax): """Creating a polygon for the given coordinates """ dx = (xmax - xmin) / 3 dy = (ymax - ymin) / 3 polyline = [] point = QgsPoint(xmin, ymin) polyline.append(point) point = QgsPoint(xmin + dx, ymin) polyline.append(point) point = QgsPoint(xmax - dx, ymin) polyline.append(point) point = QgsPoint(xmax, ymin) polyline.append(point) point = QgsPoint(xmax, ymin + dy) polyline.append(point) point = QgsPoint(xmax, ymax - dy) polyline.append(point) point = QgsPoint(xmax, ymax) polyline.append(point) point = QgsPoint(xmax - dx, ymax) polyline.append(point) point = QgsPoint(xmin + dx, ymax) polyline.append(point) point = QgsPoint(xmin, ymax) polyline.append(point) point = QgsPoint(xmin, ymax - dy) polyline.append(point) point = QgsPoint(xmin, ymin + dy) polyline.append(point) point = QgsPoint(xmin, ymin) polyline.append(point) qgsPolygon = QgsGeometry.fromMultiPolygon([[polyline]]) return qgsPolygon
polyLayer = processing.getObject(Polygons) polyPrder = polyLayer.dataProvider() count = polyLayer.featureCount() writer = processing.VectorWriter(Results, None, polyPrder.fields(), QGis.WKBMultiPolygon, polyPrder.crs()) for n, feat in enumerate(processing.features(polyLayer)): progress.setPercentage(int(100*n/count)) geom = feat.geometry() if geom.isMultipart(): featres = feat geoms = geom.asGeometryCollection() geomarea = [(i, geoms[i].area()) for i in range(len(geoms))] geomarea.sort(key=itemgetter(1)) if To_keep == 1: featres.setGeometry(geoms[geomarea[-1][0]]) elif To_keep > len(geoms): featres.setGeometry(geom) else: featres.setGeometry(geom) geomres = [geoms[i].asPolygon() for i,a in geomarea[-1 * To_keep :]] featres.setGeometry(QgsGeometry.fromMultiPolygon(geomres)) writer.addFeature(featres) else: writer.addFeature(feat) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(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: %s/%s' % (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 %s' % 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 %s' % 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 %s' % 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 %s' % 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) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) 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(), 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 == 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) 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 fromMultiPolygonXY(mp): try: return QgsGeometry.fromMultiPolygonXY([[[QgsPointXY(p) for p in r] for r in t] for t in mp]) except AttributeError: return QgsGeometry.fromMultiPolygon(mp)
def addAnyFeature(self, featureType, mapPointList, attributes, layer): geometryType = FeatureType.toGeometryType(featureType) # points: bail out if there is not exactly one vertex if (geometryType == QGis.Point and len(mapPointList) != 1): return False # segments: bail out if there are not exactly two vertices if (featureType == FeatureType.Segment and len(mapPointList) != 2): return False # lines: bail out if there are not at least two vertices if (featureType == FeatureType.Line and len(mapPointList) < 2): return False # polygons: bail out if there are not at least three vertices if (geometryType == QGis.Polygon and len(mapPointList) < 3): return False if (geometryType != layer.geometryType()): self.messageEmitted.emit( self.tr('Cannot add feature: Layer and Feature geometry type mismatch'), QgsMessageBar.CRITICAL) return False if (layer.type() != QgsMapLayer.VectorLayer): self.messageEmitted.emit( self.tr('Cannot add feature: Current layer not a vector layer'), QgsMessageBar.CRITICAL) return False if (not layer.isEditable()): self.messageEmitted.emit(self.tr('Cannot add feature: Current layer not editable'), QgsMessageBar.CRITICAL) return False provider = layer.dataProvider() if (not (provider.capabilities() & QgsVectorDataProvider.AddFeatures)): self.messageEmitted.emit( self.tr('Cannot add feature: Data provider does not support the addition of features.'), QgsMessageBar.CRITICAL) return False multiType = QGis.isMultiType(layer.wkbType()) layerPoints = self._layerPoints(mapPointList, layer) feature = QgsFeature(layer.pendingFields(), 0) geometry = None if (geometryType == QGis.Point): if multiType: geometry = QgsGeometry.fromMultiPoint([layerPoints[0]]) else: geometry = QgsGeometry(layerPoints[0]) elif (geometryType == QGis.Line): if multiType: geometry = QgsGeometry.fromMultiPolyline([layerPoints]) else: geometry = QgsGeometry.fromPolyline(layerPoints) elif (geometryType == QGis.Polygon): if multiType: geometry = QgsGeometry.fromMultiPolygon([layerPoints]) else: geometry = QgsGeometry.fromPolygon([layerPoints]) else: self.messageEmitted.emit(self.tr('Cannot add feature. Unknown geometry type'), QgsMessageBar.CRITICAL) return False if (geometry is None): self.messageEmitted.emit(self.tr('Cannot add feature. Invalid geometry'), QgsMessageBar.CRITICAL) return False feature.setGeometry(geometry) if (geometryType == QGis.Polygon): avoidIntersectionsReturn = feature.geometry().avoidIntersections() if (avoidIntersectionsReturn == 1): # not a polygon type. Impossible to get there pass elif (avoidIntersectionsReturn == 3): self.messageEmitted.emit( self.tr('An error was reported during intersection removal'), QgsMessageBar.CRITICAL) if (not feature.geometry().asWkb()): # avoid intersection might have removed the whole geometry reason = '' if (avoidIntersectionsReturn != 2): reason = self.tr('The feature cannot be added because it\'s geometry is empty') else: reason = self.tr( 'The feature cannot be added because it\'s geometry collapsed due to intersection avoidance') self.messageEmitted.emit(reason, QgsMessageBar.CRITICAL) return False featureSaved = self._addFeatureAction(feature, attributes, layer, False) if (featureSaved and geometryType != QGis.Point): # add points to other features to keep topology up-to-date topologicalEditing = Snapping.topologicalEditing() # use always topological editing for avoidIntersection. # Otherwise, no way to guarantee the geometries don't have a small gap in between. intersectionLayers = Snapping.intersectionLayers() avoidIntersection = len(intersectionLayers) if (avoidIntersection): # try to add topological points also to background layers for intersectionLayer in intersectionLayers: vl = QgsMapLayerRegistry.instance().mapLayer(str(intersectionLayer)) # can only add topological points if background layer is editable... if (vl is not None and vl.geometryType() == QGis.Polygon and vl.isEditable()): vl.addTopologicalPoints(feature.geometry()) elif (topologicalEditing): self._layer.addTopologicalPoints(feature.geometry()) self.canvas().refresh() return True
def testBoundingBox(self): # 2-+-+-+-+-3 # | | # + 6-+-+-7 + # | | | | # + + 9-+-8 + # | | | # ! 5-+-+-+-4 ! # | # 1-+-+-+-+-0 ! points = [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ] polyline = QgsGeometry.fromPolyline(points) expbb = QgsRectangle(0,0,5,4) bb = polyline.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 2-3 6-+-7 # | | | | # 0-1 4 5 8-9 points = [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ], [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ] ] polyline = QgsGeometry.fromMultiPolyline(points) expbb = QgsRectangle(0,0,6,1) bb = polyline.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 5---4 # | | # | 2-3 # | | # 0-1 points = [[ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ]] polygon = QgsGeometry.fromPolygon(points) expbb = QgsRectangle(0,0,2,2) bb = polygon.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 3-+-+-2 # | | # + 8-7 + # | | | | # + 5-6 + # | | # 0-+-+-1 points = [ [ 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) ], ] polygon = QgsGeometry.fromPolygon(points) expbb = QgsRectangle(0,0,3,3) bb = polygon.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 5-+-4 0-+-9 # | | | | # | 2-3 1-2 | # | | | | # 0-1 7-8 points = [ [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ], [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ] ] polygon = QgsGeometry.fromMultiPolygon(points) expbb = QgsRectangle(0,0,5,2) bb = polygon.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString())
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri(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 on_click_load(self): # default value of the progress bar is set to 0 self.counter = 0 self.ui.progressBar.setValue(self.counter) # check if the user wants to limit the selection by distinct value if self.ui.checkBox.isChecked(): load_key = self.ui.load_field.currentText() # if the data type is not a string if self.data_type != str: load_key = ast.literal_eval(load_key) self.ourList = self.collection.find({self.key: load_key}) else: query_text = self.ui.query_field.currentText().strip() if query_text == '': query = {} else: query = ast.literal_eval(query_text) if type(query) is not dict: QMessageBox.about(self, "Warning!", "Query must be a dict!") return self.ourList = self.collection.find(query) self.percent = 100 / float(self.ourList.count()) # get the first level of attributes, we can modify which fields we want to use self.single_return = self.collection.find_one({}, {'geom': 0, 'fibres': 0, 'date': 0}) # {} , {"geom": 1} self.attr_list = self.single_return.keys() # list defined for the attributes table self.attr_list_new = [] # list defined for structural access to tables self.attr_list_structure = [] # locate the sub attributes and store them in sub_attr_list for attr in self.attr_list: # append keys from the first layer self.attr_list_new.append(str(attr)) self.attr_list_structure.append([attr]) # if the key is a dictionary if type(self.single_return[attr]) is dict: # find all of the sub keys in the dictionary sub_keys_list = self.single_return[attr].keys() # search through the list of sub keys for sub_key in sub_keys_list: # structural code for ease of access later struct_sub = [attr], [sub_key] # append the sub keys to our main list, define differences self.attr_list_new.append(str(attr) + "." + str(sub_key)) # create a structure for ease of access self.attr_list_structure.append(struct_sub) else: pass QMessageBox.about(self, "Info", "Fields are"+ (', '.join(self.attr_list_new))) # define the dataLayer type as either Point, LineString or Polygon self.dataLayer = QgsVectorLayer(self.geometry_name, self.collection_name, "memory") # prepare the layer for the data we will be inputing self.dataLayer.startEditing() self.layerData = self.dataLayer.dataProvider() # create the shapefile attributes based on existing mongoDB field for attribute in (self.attr_list_new): self.layerData.addAttributes([QgsField(attribute, QVariant.String)]) # our attribute container self.feature = QgsFeature() self.feature.initAttributes(len(self.attr_list_new)) for value in self.ourList: # print value[self.geom_name]["type"] # if the user has selected a collection with point geometry if value[self.geom_name]["type"] == "Point": x_coord = value[self.geom_name]["coordinates"][0] y_coord = value[self.geom_name]["coordinates"][1] self.populate_attributes(value) try: self.feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x_coord, y_coord))) except: self.feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(x_coord, y_coord))) (res, outFeats) = self.dataLayer.dataProvider().addFeatures([self.feature]) # update the progress bar self.event_progress() self.ui.load_collection.setEnabled(False) self.ui.listCol.setEnabled(False) elif value[self.geom_name]["type"] == "LineString": # used to store a list of poly lines line_string = [] # checks the geometry and only imports valid geometry if self.check_valid_geom(value): for y in range(len(value[self.geom_name]["coordinates"])): # do not use unless needed, in case there is a multiLineString Object in the DB try: line_string.append(QgsPoint(value[self.geom_name]["coordinates"][y][0], value[self.geom_name]["coordinates"][y][1])) except: qgis.utils.iface.messageBar().pushMessage("Error", "Error loading Linestring on {}: {}".format(str(value["_id"]), str(sys.exc_info()[0])), level=Qgis.critical) self.populate_attributes(value) self.feature.setGeometry(QgsGeometry.fromPolyline(line_string)) (res, outFeats) = self.dataLayer.dataProvider().addFeatures([self.feature]) del line_string[:] # update the progress bar self.event_progress() self.ui.load_collection.setEnabled(False) self.ui.listCol.setEnabled(False) # this deals with Polygon geometry elif value[self.geom_name]["type"] == "Polygon": # store the polygon points poly_shape = [] # store the line (a poly has multiple lines) line_string = [] # checks the geometry and only imports valid geometry if self.check_valid_geom(value): for y in range(len(value[self.geom_name]["coordinates"][0])): try: line_string.append(QgsPoint(value[self.geom_name]["coordinates"][0][y][0], value[self.geom_name]["coordinates"][0][y][1])) except: qgis.utils.iface.messageBar().pushMessage("Error", "Error loading Polygon {}: {}".format(str(value["_id"]), str(sys.exc_info()[0])), level=QgsMessageBar.CRITICAL) poly_shape.append(line_string); self.populate_attributes(value) try: ps = QgsGeometry.fromPolygonXY(poly_shape) self.feature.setGeometry(ps) except AttributeError: ps = QgsGeometry.fromPolygon(poly_shape) self.feature.setGeometry(ps) except: qgis.utils.iface.messageBar().pushMessage("Error", "Error on {}: {}".format(str(value["_id"]), str(sys.exc_info()[0])), level=QgsMessageBar.CRITICAL) (res, outFeats) = self.dataLayer.dataProvider().addFeatures([self.feature]) del line_string[:] del poly_shape[:] # update the progress bar self.event_progress() self.ui.load_collection.setEnabled(False) self.ui.listCol.setEnabled(False) # this deals with Polygon geometry elif value[self.geom_name]["type"] == "MultiPolygon": # store the polygon points poly_shape = [] # checks the geometry and only imports valid geometry if self.check_valid_geom(value): multi_poly_shape = [] for multi_shape in value[self.geom_name]["coordinates"]: for shape in multi_shape: each_shape = [] for xy in shape: try: each_shape.append(QgsPoint(xy[0], xy[1])) except: qgis.utils.iface.messageBar().pushMessage("Error", "Error loading Multipolygon {}: {}".format(str(value["_id"]), str(sys.exc_info()[0])), level=QgsMessageBar.CRITICAL) multi_poly_shape.append(each_shape) # final append at highest level poly_shape.append(multi_poly_shape) self.populate_attributes(value) try: ps = QgsGeometry.fromMultiPolygonXY(poly_shape) self.feature.setGeometry(ps) except AttributeError: ps = QgsGeometry.fromMultiPolygon(poly_shape) self.feature.setGeometry(ps) except: qgis.utils.iface.messageBar().pushMessage("Error", "Error on {}: {}".format(str(value["_id"]), str(sys.exc_info()[0])), level=QgsMessageBar.CRITICAL) (res, outFeats) = self.dataLayer.dataProvider().addFeatures([self.feature]) del poly_shape[:] # update the progress bar self.event_progress() self.ui.load_collection.setEnabled(False) self.ui.listCol.setEnabled(False) else: qgis.utils.iface.messageBar().pushMessage("Error", "Failed to load geometry due to {} being unsupported".format(value[self.geom_name]["type"]), level=QgsMessageBar.CRITICAL) self.ui.listCol.setEnabled(True) # commits the changes made to the layer and adds the layer to the map self.dataLayer.commitChanges() # the path we will be writing to is the plugin folder dependant on the layer name write_to = str(os.path.abspath(__file__ + "/../../")) + "/" + str(self.collection_name) + ".shp" write_error = QgsVectorFileWriter.writeAsVectorFormat(self.dataLayer, write_to, "system", self.dataLayer.crs(), "ESRI Shapefile") self.dataLayer = QgsVectorLayer(write_to, self.collection_name, "ogr") try: QgsProject.instance().addMapLayer(self.dataLayer) except: QgsMapLayerRegistry.instance().addMapLayer(self.dataLayer)
def onFinishSketch(self): ''' Slot raised upon selecting to finish drawing the sketch spatial unit. ''' stdmLayer = self.currentVectorLayer() layerWKBType = stdmLayer.wkbType() feature = QgsFeature(stdmLayer.fields()) if self._mode == CAPTURE_POINT: feature.setGeometry(self._geometry) elif self._mode == CAPTURE_LINE or self._mode == CAPTURE_POLYGON: # Delete temporary rubber band if self._tempRubberBand != None: self.canvas.scene().removeItem(self._tempRubberBand) del self._tempRubberBand self._tempRubberBand = None # Validate geometries using number of points if self._mode == CAPTURE_LINE and len(self._captureList) < 2: self.stopCapturing() return if self._mode == CAPTURE_POLYGON and len(self._captureList) < 3: self.stopCapturing() return if self._mode == CAPTURE_LINE: if layerWKBType == QgsWkbTypes.LineString or layerWKBType == QgsWkbTypes.LineString25D: self._geometry = QgsGeometry.fromPolyline( self._captureList) elif layerWKBType == QgsWkbTypes.MultiLineString or layerWKBType == QgsWkbTypes.MultiLineString25D: self._geometry = QgsGeometry.fromMultiPolyline( self._captureList) else: QMessageBox.critical(self.iface.mainWindow(), \ QApplication.translate("StdmMapToolCreateFeature", "WKB Type Error"), \ QApplication.translate("StdmMapToolCreateFeature", "Cannot add feature. Unknown WKB type")) return feature.setGeometry(self._geometry) # Polygon else: if layerWKBType == QgsWkbTypes.Polygon or layerWKBType == QgsWkbTypes.Polygon25D: self._geometry = QgsGeometry.fromPolygon( [self._captureList]) elif layerWKBType == QgsWkbTypes.MultiPolygon or layerWKBType == QgsWkbTypes.MultiPolygon25D: self._geometry = QgsGeometry.fromMultiPolygon( [self._captureList]) else: QMessageBox.critical(self.iface.mainWindow(), \ QApplication.translate("StdmMapToolCreateFeature", "WKB Type Error"), \ QApplication.translate("StdmMapToolCreateFeature", "Cannot add feature. Unknown WKB type")) return feature.setGeometry(self._geometry) avoidIntersectionsReturn = feature.geometry( ).avoidIntersections() if avoidIntersectionsReturn == 3: QMessageBox.critical(self.iface.mainWindow(), \ QApplication.translate("StdmMapToolCreateFeature", "Error"), \ QApplication.translate("StdmMapToolCreateFeature", "An error was reported during intersection removal")) polyWkb = feature.geometry().asWkb() if polyWkb == None: reason = "" if avoidIntersectionsReturn != 2: reason = QApplication.translate( "StdmMapToolCreateFeature", "The feature cannot be added because it's geometry is empty" ) else: reason = QApplication.translate( "StdmMapToolCreateFeature", "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ) QMessageBox.critical(self.iface.mainWindow(), \ QApplication.translate("StdmMapToolCreateFeature", "Error"), \ reason) self.stopCapturing() del feature self._resetGeometry() return stdmLayer.beginEditCommand( QApplication.translate("StdmMapToolCreateFeature", "Feature Added")) if self.addFeature(stdmLayer, feature): stdmLayer.endEditCommand() else: del feature self._resetGeometry() stdmLayer.destroyEditCommand() self.stopCapturing() self.canvas.refresh()
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) 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(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / layer.featureCount() if layer.featureCount() else 0 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) 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: QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO) newGeom = None else: newGeom = QgsGeometry.fromMultiPolygon(multipolygon) if newGeom is not None: feat = QgsFeature() feat.setGeometry(newGeom) feat.setAttributes(f.attributes()) writer.addFeature(feat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) del writer
def testAdjacentVertex(self): # 2-+-+-+-+-3 # | | # + 6-+-+-7 + # | | | | # + + 9-+-8 + # | | | # ! 5-+-+-+-4 ! # | # 1-+-+-+-+-0 ! polyline = QgsGeometry.fromPolyline( [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ] ) # don't crash (before,after) = polyline.adjacentVertices(-100) if TestQgsGeometry.wkbPtr: # CHANGE previous implementation returned (-101,-99) here assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) for i in range(0, 10): (before,after) = polyline.adjacentVertices(i) if i==0: assert before==-1 and after==1, "Expected (0,1), Got:(%d,%d)" % (before,after) elif i==9: assert before==i-1 and after==-1, "Expected (0,1), Got:(%d,%d)" % (before,after) else: assert before==i-1 and after==i+1, "Expected (0,1), Got:(%d,%d)" % (before,after) (before,after) = polyline.adjacentVertices(100) if TestQgsGeometry.wkbPtr: # CHANGE previous implementation returned (99,101) here assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) # 2-3 6-+-7 # | | | | # 0-1 4 5 8-9 polyline = QgsGeometry.fromMultiPolyline( [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ], [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ] ] ) (before,after) = polyline.adjacentVertices(-100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) for i in range(0,10): (before,after) = polyline.adjacentVertices(i) if i==0 or i==5: assert before==-1 and after==i+1, "Expected (-1,%d), Got:(%d,%d)" % (i+1,before,after) elif i==4 or i==9: assert before==i-1 and after==-1, "Expected (%d,-1), Got:(%d,%d)" % (i-1,before,after) else: assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after) (before,after) = polyline.adjacentVertices(100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) # 5---4 # | | # | 2-3 # | | # 0-1 polygon = QgsGeometry.fromPolygon( [[ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ]] ) (before,after) = polygon.adjacentVertices(-100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) for i in range(0,7): (before,after) = polygon.adjacentVertices(i) if i==0 or i==6: assert before==5 and after==1, "Expected (5,1), Got:(%d,%d)" % (before,after) else: assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after) (before,after) = polygon.adjacentVertices(100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) # 3-+-+-2 # | | # + 8-7 + # | | | | # + 5-6 + # | | # 0-+-+-1 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) ], ] ) (before,after) = polygon.adjacentVertices(-100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) for i in range(0,8): (before,after) = polygon.adjacentVertices(i) if i==0 or i==4: assert before==3 and after==1, "Expected (3,1), Got:(%d,%d)" % (before,after) elif i==5: assert before==8 and after==6, "Expected (2,0), Got:(%d,%d)" % (before,after) else: assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after) (before,after) = polygon.adjacentVertices(100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) # 5-+-4 0-+-9 # | | | | # | 2-3 1-2 | # | | | | # 0-1 7-8 polygon = QgsGeometry.fromMultiPolygon( [ [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ], [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ] ] ) (before,after) = polygon.adjacentVertices(-100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after) for i in range(0,14): (before,after) = polygon.adjacentVertices(i) if i==0 or i==6: assert before==5 and after==1, "Expected (5,1), Got:(%d,%d)" % (before,after) elif i==7 or i==13: assert before==12 and after==8, "Expected (12,8), Got:(%d,%d)" % (before,after) else: assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after) (before,after) = polygon.adjacentVertices(100) assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)
def testVertexAt(self): # 2-+-+-+-+-3 # | | # + 6-+-+-7 + # | | | | # + + 9-+-8 + # | | | # ! 5-+-+-+-4 ! # | # 1-+-+-+-+-0 ! points = [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ] polyline = QgsGeometry.fromPolyline(points) for i in range(0, len(points)): assert points[i] == polyline.vertexAt(i), "Mismatch at %d" % i # 2-3 6-+-7 # | | | | # 0-1 4 5 8-9 points = [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ], [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ] ] polyline = QgsGeometry.fromMultiPolyline(points) p = polyline.vertexAt(-100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() p = polyline.vertexAt(100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() i = 0 for j in range(0, len(points)): for k in range(0, len(points[j])): assert points[j][k] == polyline.vertexAt(i), "Mismatch at %d / %d,%d" % (i,j,k) i+=1 # 5---4 # | | # | 2-3 # | | # 0-1 points = [[ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ]] polygon = QgsGeometry.fromPolygon(points) p = polygon.vertexAt(-100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() p = polygon.vertexAt(100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() i = 0 for j in range(0, len(points)): for k in range(0, len(points[j])): assert points[j][k] == polygon.vertexAt(i), "Mismatch at %d / %d,%d" % (i,j,k) i+=1 # 3-+-+-2 # | | # + 8-7 + # | | | | # + 5-6 + # | | # 0-+-+-1 points = [ [ 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) ], ] polygon = QgsGeometry.fromPolygon(points) p = polygon.vertexAt(-100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() p = polygon.vertexAt(100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() i = 0 for j in range(0, len(points)): for k in range(0, len(points[j])): assert points[j][k] == polygon.vertexAt(i), "Mismatch at %d / %d,%d" % (i,j,k) i+=1 # 5-+-4 0-+-9 # | | | | # | 2-3 1-2 | # | | | | # 0-1 7-8 points = [ [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ], [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ] ] polygon = QgsGeometry.fromMultiPolygon(points) p = polygon.vertexAt(-100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() p = polygon.vertexAt(100) assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString() i = 0 for j in range(0, len(points)): for k in range(0, len(points[j])): for l in range(0, len(points[j][k])): p = polygon.vertexAt(i) assert points[j][k][l] == p, "Got %s, Expected %s at %d / %d,%d,%d" % (p.toString(),points[j][k][l].toString(),i,j,k,l) i+=1
def processPoly(layer, writerLines, isProcessing): layercrs = layer.crs() if layercrs != epsg4326: transto4326 = QgsCoordinateTransform(layercrs, epsg4326) transfrom4326 = QgsCoordinateTransform(epsg4326, layercrs) wkbtype = layer.wkbType() iterator = layer.getFeatures() num_features = 0 num_bad = 0 maxseglen = settings.maxSegLength*1000.0 maxSegments = settings.maxSegments for feature in iterator: num_features += 1 try: if wkbtype == QGis.WKBPolygon: poly = feature.geometry().asPolygon() numpolygons = len(poly) if numpolygons < 1: continue ptset = [] for points in poly: numpoints = len(points) if numpoints < 2: continue # If the input is not 4326 we need to convert it to that and then back to the output CRS ptStart = QgsPoint(points[0][0], points[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1,numpoints): ptEnd = QgsPoint(points[x][0], points[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) l = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) n = int(math.ceil(l.s13 / maxseglen)) if n > maxSegments: n = maxSegments seglen = l.s13 / n for i in range(1,n): s = seglen * i g = l.Position(s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append( QgsPoint(g['lon2'], g['lat2']) ) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) ptset.append(pts) if len(ptset) > 0: featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromPolygon(ptset)) featureout.setAttributes(feature.attributes()) if isProcessing: writerLines.addFeature(featureout) else: writerLines.addFeatures([featureout]) else: multipoly = feature.geometry().asMultiPolygon() multiset = [] for poly in multipoly: ptset = [] for points in poly: numpoints = len(points) if numpoints < 2: continue # If the input is not 4326 we need to convert it to that and then back to the output CRS ptStart = QgsPoint(points[0][0], points[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1,numpoints): ptEnd = QgsPoint(points[x][0], points[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) l = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) n = int(math.ceil(l.s13 / maxseglen)) if n > maxSegments: n = maxSegments seglen = l.s13 / n for i in range(1,n): s = seglen * i g = l.Position(s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append( QgsPoint(g['lon2'], g['lat2']) ) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) ptset.append(pts) multiset.append(ptset) if len(multiset) > 0: featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromMultiPolygon(multiset)) featureout.setAttributes(feature.attributes()) if isProcessing: writerLines.addFeature(featureout) else: writerLines.addFeatures([featureout]) except: num_bad += 1 pass return num_bad
def testClosestVertex(self): # 2-+-+-+-+-3 # | | # + 6-+-+-7 + # | | | | # + + 9-+-8 + # | | | # ! 5-+-+-+-4 ! # | # 1-+-+-+-+-0 ! polyline = QgsGeometry.fromPolyline( [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ] ) (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(6,1) ) self.assertEqual( point, QgsPoint(5,1) ) self.assertEqual( beforeVertex, 3 ) self.assertEqual( atVertex, 4 ) self.assertEqual( afterVertex, 5 ) self.assertEqual( dist, 1 ) (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(6,2) ) self.assertEqual( dist, 1 ) self.assertEqual( minDistPoint, QgsPoint(5,2) ) self.assertEqual( afterVertex, 4) (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(6,0) ) self.assertEqual( point, QgsPoint(5,0) ) self.assertEqual( beforeVertex, -1 ) self.assertEqual( atVertex, 0 ) self.assertEqual( afterVertex, 1 ) self.assertEqual( dist, 1 ) (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(6,0) ) self.assertEqual( dist, 1 ) self.assertEqual( minDistPoint, QgsPoint(5,0) ) self.assertEqual( afterVertex, 1) (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(0,1) ) self.assertEqual( point, QgsPoint(0,0) ) self.assertEqual( beforeVertex, 0 ) self.assertEqual( atVertex, 1 ) self.assertEqual( afterVertex, 2 ) self.assertEqual( dist, 1 ) (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(0,1) ) self.assertEqual( dist, 0 ) self.assertEqual( minDistPoint, QgsPoint(0,1) ) self.assertEqual( afterVertex, 2) # 2-3 6-+-7 ! # | | | | # 0-1 4 5 8-9 polyline = QgsGeometry.fromMultiPolyline( [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ], [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ] ] ) (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(6,1) ) self.assertEqual( point, QgsPoint(5,1) ) self.assertEqual( beforeVertex, 6 ) self.assertEqual( atVertex, 7 ) self.assertEqual( afterVertex, 8 ) self.assertEqual( dist, 1 ) (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(7,0) ) self.assertEqual( dist, 1 ) self.assertEqual( minDistPoint, QgsPoint(6,0) ) self.assertEqual( afterVertex, 9) # 5---4 # |! | # | 2-3 # | | # 0-1 polygon = QgsGeometry.fromPolygon( [[ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ]] ) (point, atVertex, beforeVertex, afterVertex, dist ) = polygon.closestVertex( QgsPoint(0.7,1.1) ) self.assertEqual( point, QgsPoint(1,1) ) self.assertEqual( beforeVertex, 1 ) self.assertEqual( atVertex, 2 ) self.assertEqual( afterVertex, 3 ) assert abs( dist - 0.1 ) < 0.00001, "Expected: %f; Got:%f" % (dist,0.1) (dist,minDistPoint,afterVertex) = polygon.closestSegmentWithContext( QgsPoint(0.7,1.1) ) self.assertEqual( afterVertex, 2) self.assertEqual( minDistPoint, QgsPoint(1,1) ) exp = 0.3**2 + 0.1**2 assert abs( dist - exp ) < 0.00001, "Expected: %f; Got:%f" % (exp,dist) # 3-+-+-2 # | | # + 8-7 + # | |!| | # + 5-6 + # | | # 0-+-+-1 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) ], ] ) (point, atVertex, beforeVertex, afterVertex, dist ) = polygon.closestVertex( QgsPoint(1.1,1.9) ) self.assertEqual( point, QgsPoint(1,2) ) self.assertEqual( beforeVertex, 7 ) self.assertEqual( atVertex, 8 ) self.assertEqual( afterVertex, 9 ) assert abs( dist - 0.02 ) < 0.00001, "Expected: %f; Got:%f" % (dist,0.02) (dist,minDistPoint,afterVertex) = polygon.closestSegmentWithContext( QgsPoint(1.2,1.9) ) self.assertEqual( afterVertex, 8) self.assertEqual( minDistPoint, QgsPoint(1.2,2) ) exp = 0.01 assert abs( dist - exp ) < 0.00001, "Expected: %f; Got:%f" % (exp,dist) # 5-+-4 0-+-9 # | | | | # 6 2-3 1-2!+ # | | | | # 0-1 7-8 polygon = QgsGeometry.fromMultiPolygon( [ [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ], [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ] ] ) (point, atVertex, beforeVertex, afterVertex, dist ) = polygon.closestVertex( QgsPoint(4.1,1.1) ) self.assertEqual( point, QgsPoint(4,1) ) self.assertEqual( beforeVertex, 11 ) self.assertEqual( atVertex, 12 ) self.assertEqual( afterVertex, 13 ) assert abs( dist - 0.02 ) < 0.00001, "Expected: %f; Got:%f" % (dist,0.02) (dist,minDistPoint,afterVertex) = polygon.closestSegmentWithContext( QgsPoint(4.1,1.1) ) self.assertEqual( afterVertex, 12) self.assertEqual( minDistPoint, QgsPoint(4,1) ) exp = 0.02 assert abs( dist - exp ) < 0.00001, "Expected: %f; Got:%f" % (exp,dist)
def accept(self): layer = self.inputPolyComboBox.currentLayer() if not layer: self.iface.messageBar().pushMessage("", "No Valid Layer", level=QgsMessageBar.WARNING, duration=4) layercrs = layer.crs() wkbtype = layer.wkbType() polyname = self.geodesicPolyNameLineEdit.text() # Get the field names for the input layer. The will be copied to the output layers fields = layer.pendingFields() # Create the points and polygon output layers if wkbtype == QGis.WKBPolygon: polyLayer = QgsVectorLayer( "Polygon?crs={}".format(layercrs.authid()), polyname, "memory") else: polyLayer = QgsVectorLayer( "MultiPolygon?crs={}".format(layercrs.authid()), polyname, "memory") ppoly = polyLayer.dataProvider() ppoly.addAttributes(fields) polyLayer.updateFields() if layercrs != epsg4326: transto4326 = QgsCoordinateTransform(layercrs, epsg4326) transfrom4326 = QgsCoordinateTransform(epsg4326, layercrs) iter = layer.getFeatures() num_features = 0 num_bad = 0 maxseglen = settings.maxSegLength * 1000.0 maxSegments = settings.maxSegments for feature in iter: num_features += 1 try: if wkbtype == QGis.WKBPolygon: poly = feature.geometry().asPolygon() numpolygons = len(poly) if numpolygons < 1: continue ptset = [] for points in poly: numpoints = len(points) if numpoints < 2: continue # If the input is not 4326 we need to convert it to that and then back to the output CRS ptStart = QgsPoint(points[0][0], points[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1, numpoints): ptEnd = QgsPoint(points[x][0], points[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) l = self.geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) n = int(math.ceil(l.s13 / maxseglen)) if n > maxSegments: n = maxSegments seglen = l.s13 / n for i in range(1, n): s = seglen * i g = l.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPoint(g['lon2'], g['lat2'])) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) ptset.append(pts) if len(ptset) > 0: featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromPolygon(ptset)) featureout.setAttributes(feature.attributes()) ppoly.addFeatures([featureout]) else: multipoly = feature.geometry().asMultiPolygon() multiset = [] for poly in multipoly: ptset = [] for points in poly: numpoints = len(points) if numpoints < 2: continue # If the input is not 4326 we need to convert it to that and then back to the output CRS ptStart = QgsPoint(points[0][0], points[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1, numpoints): ptEnd = QgsPoint(points[x][0], points[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) l = self.geod.InverseLine( ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) n = int(math.ceil(l.s13 / maxseglen)) if n > maxSegments: n = maxSegments seglen = l.s13 / n for i in range(1, n): s = seglen * i g = l.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPoint(g['lon2'], g['lat2'])) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) ptset.append(pts) multiset.append(ptset) if len(multiset) > 0: featureout = QgsFeature() featureout.setGeometry( QgsGeometry.fromMultiPolygon(multiset)) featureout.setAttributes(feature.attributes()) ppoly.addFeatures([featureout]) except: num_bad += 1 pass polyLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(polyLayer) if num_bad != 0: self.iface.messageBar().pushMessage( "", "{} out of {} features failed".format(num_bad, num_features), level=QgsMessageBar.WARNING, duration=3) self.close()
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