def densify(geometry, maxsegmentlength): """Densifies geometry vertices, so no segment is longer than maxsegmentlength Only implemented for linestring at the time being""" g = togeometry(geometry) type = QGis.flatType((g.wkbType())) if not type == QGis.WKBLineString: raise NotImplementedError("Densify is only implemented for LineStrings at the moment") input_coords = tocoordinates(g) output_coords = [] maxsegmentlength = float(maxsegmentlength) for ix in xrange(len(input_coords) - 1): p0 = input_coords[ix] p1 = input_coords[ix + 1] output_coords.append(QgsPoint(p0)) # Avoid calculating these values at the cost of performace. in_segment = QgsGeometry.fromPolyline([p0, p1]) in_segment_length = in_segment.length() segcount = int(ceil(in_segment_length / maxsegmentlength)) if segcount > 1: new_seg_length = float(in_segment_length) / segcount for i in xrange(1,segcount): new_p = in_segment.interpolate(new_seg_length * i).asPoint() output_coords.append(new_p) # Add last coord output_coords.append(input_coords[-1]) return QgsGeometry.fromPolyline(output_coords)
def unitDistance(self, distance): units = self.unitsComboBox.currentIndex() if units == 0: # meters return distance elif units == 1: # kilometers return distance / 1000.0 elif units == 2: # feet return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.Feet) elif units == 3: # yards return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.Feet) / 3.0 elif units == 4: # miles return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.Miles) else: # nautical miles return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.NauticalMiles)
def conversionToMeters(self, units): if units == 2: # Nautical Miles measureFactor = QGis.fromUnitToUnitFactor(QGis.NauticalMiles, QGis.Meters) elif units == 0: # Kilometers measureFactor = 1000.0 elif units == 1: # Meters measureFactor = 1.0 elif units == 3: # Miles measureFactor = QGis.fromUnitToUnitFactor(QGis.Feet, QGis.Meters) * 5280.0 elif units == 4: # Feet measureFactor = QGis.fromUnitToUnitFactor(QGis.Feet, QGis.Meters) return measureFactor
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) tolerance = self.getParameterValue(self.TOLERANCE) pointsBefore = 0 pointsAfter = 0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields().toList(), QGis.flatType(layer.wkbType()), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) if len(features) > 0 else 1 for current, f in enumerate(features): featGeometry = f.geometry() if featGeometry is not None: attrs = f.attributes() pointsBefore += self.geomVertexCount(featGeometry) newGeometry = featGeometry.simplify(tolerance) pointsAfter += self.geomVertexCount(newGeometry) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrs) writer.addFeature(feature) progress.setPercentage(int(current * total)) del writer ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Simplify: Input geometries have been simplified from %s to %s points' % (pointsBefore, pointsAfter)))
def canvasReleaseEvent(self, event): """ When the mouse is clicked :param event: mouse event """ types = [QgsWKBTypes.PointZ, QgsWKBTypes.LineStringZ, QgsWKBTypes.CircularStringZ, QgsWKBTypes.CompoundCurveZ, QgsWKBTypes.CurvePolygonZ, QgsWKBTypes.PolygonZ] display = "" for layer in self.canvas().layers(): if layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType(layer.wkbType()) in types: layerConfig = QgsSnappingUtils.LayerConfig(layer, QgsPointLocator.Vertex, 10, QgsTolerance.Pixels) features = Finder.findFeaturesAt(event.mapPoint(), layerConfig, self) if len(features) > 0: display += layer.name() + " : \n" for f in features: if f.geometry().type() == QGis.Point: alt = f.geometry().geometry().z() elif f.geometry().type() == QGis.Line: closest = f.geometry().closestVertex(event.mapPoint()) alt = f.geometry().geometry().zAt(closest[1]) elif f.geometry().type() == QGis.Polygon: self.__iface.messageBar().pushMessage( QCoreApplication.translate("VDLTools", "Polygon not yet implemented"), level=QgsMessageBar.WARNING) continue else: continue display += " " + str(f.id()) + " | " + str(alt) + " m.\n" if display != "": QMessageBox.information(None, QCoreApplication.translate("VDLTools", "Id | Elevation"), display)
def get_wkb_type(cls, wkb_type): if COMPAT_QGIS_VERSION == 2: return QGis.fromOldWkbType(wkb_type) # get new (not deprecated) WKB type for e.g. QgsVectorLayer::wkbType(), QgsGeometry::wkbType(), etc elif COMPAT_QGIS_VERSION == 3: return wkb_type else: raise NotImplementedError(COMPAT_QGIS_UNSUPPORTED_MSG)
def create_memory_layer(self, layer): """Create an in-memory copy of an existing vector layer.""" data_provider = layer.dataProvider() # create the layer path defining geometry type and reference system geometry_type = QGis.vectorGeometryType(layer.geometryType()) crs_id = layer.crs().authid() path = geometry_type + '?crs=' + crs_id + '&index=yes' # create the memory layer and get a reference to the data provider memory_layer = QgsVectorLayer(path, 'Cartogram', 'memory') memory_layer_data_provider = memory_layer.dataProvider() # copy all attributes from the source layer to the memory layer memory_layer.startEditing() memory_layer_data_provider.addAttributes( data_provider.fields().toList()) memory_layer.commitChanges() # copy all features from the source layer to the memory layer for feature in data_provider.getFeatures(): memory_layer_data_provider.addFeatures([feature]) return memory_layer
def action_triggered(self, *args): action = self.actiongroup.checkedAction() layer = self.activelayercombo.currentLayer() self.clear_line() if not action: return if not action == self.measureaction and (not layer or not layer.type() == QgsMapLayer.VectorLayer): return color = self.current_action_color actiondata = {} if action == self.measureaction: self.measuredialog.show() actiondata['mode'] = self.mode geomtype = None layerid = None else: self.measuredialog.hide() geomtype = QGis.vectorGeometryType(layer.geometryType()) layerid = layer.id() data = dict(action=action.objectName(), layer=layerid, geom=geomtype, actiondata=actiondata, color=color) self.earthmine.updateAction(data)
def load_layer_features(self, point=None, layers=None): # TODO Move this logic into the viewer and let it track it's position if point is None and self.marker.map_pos is None: return if point is None: point = self.marker.map_pos area, units = self.distancearea() rect = search_area(units, area, point) if layers is None: layers = self.visible_layers() for layer in layers: transform = self.coordinatetransform(layer) # Transform the rect source = self.canvas.mapRenderer().destinationCrs() dest = layer.crs() recttransform = QgsCoordinateTransform(source, dest) rect = recttransform.transformBoundingBox(rect) features = list(get_features_in_area(layer, rect, transform, self.canvas.mapSettings())) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, features)
def setEnable(self, layer): """ To check if we can enable the action for the selected layer :param layer: selected layer """ if layer is not None\ and isinstance(layer, QgsVectorLayer)\ and QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ: if layer == self.__layer: return if self.__layer is not None: if self.__layer.isEditable(): self.__layer.editingStopped.disconnect(self.stopEditing) else: self.__layer.editingStarted.disconnect(self.startEditing) self.__layer = layer if self.__layer.isEditable(): self.action().setEnabled(True) self.__updateList() self.__layer.editingStopped.connect(self.stopEditing) else: self.action().setEnabled(False) self.__layer.editingStarted.connect(self.startEditing) if self.__canvas.mapTool == self: self.__iface.actionPan().trigger() # self.__canvas.setMapTool(self.__oldTool) return self.action().setEnabled(False) self.removeLayer()
def densify(geometry, maxsegmentlength): """Densifies geometry vertices, so no segment is longer than maxsegmentlength Only implemented for linestring at the time being""" g = togeometry(geometry) type = QGis.flatType((g.wkbType())) if not type == QGis.WKBLineString: raise NotImplementedError( "Densify is only implemented for LineStrings at the moment") input_coords = tocoordinates(g) output_coords = [] maxsegmentlength = float(maxsegmentlength) for ix in xrange(len(input_coords) - 1): p0 = input_coords[ix] p1 = input_coords[ix + 1] output_coords.append(QgsPoint(p0)) # Avoid calculating these values at the cost of performace. in_segment = QgsGeometry.fromPolyline([p0, p1]) in_segment_length = in_segment.length() segcount = int(ceil(in_segment_length / maxsegmentlength)) if segcount > 1: new_seg_length = float(in_segment_length) / segcount for i in xrange(1, segcount): new_p = in_segment.interpolate(new_seg_length * i).asPoint() output_coords.append(new_p) # Add last coord output_coords.append(input_coords[-1]) return QgsGeometry.fromPolyline(output_coords)
def line_locate_point(geometry, point): coords = tocoordinates(geometry) assert QGis.flatType( (geometry.wkbType())) == QGis.WKBLineString, 'Expected a LineString' assert len(point) == 2, 'Expected a point' sqrddist, closestsegmentpoint, indexofclosestvertexafter = geometry.closestSegmentWithContext( point) sum_length = 0 # Length of segments before the segment, where the point is located for ix in range(1, indexofclosestvertexafter): p0 = coords[ix - 1] p1 = coords[ix] segment = QgsGeometry.fromPolyline([p0, p1]) sum_length += segment.length() # Part of segment where the points is located p0 = coords[indexofclosestvertexafter - 1] segment = QgsGeometry.fromPolyline([p0, closestsegmentpoint]) sum_length += segment.length() return sum_length
def __init__(self, table, parent=None): TableDataModel.__init__(self, table, parent) self.layer = None if isinstance(table, LVectorTable): self.layer = VLayerRegistry.instance().getLayer(table.name) else: self.layer = VLayerRegistry.instance().getLayer(table) if not self.layer: return # populate self.resdata self.resdata = [] for f in self.layer.getFeatures(): a = f.attributes() # add the geometry type if f.geometry(): a.append(QgsWKBTypes.displayString(QGis.fromOldWkbType(f.geometry().wkbType()))) else: a.append('None') self.resdata.append(a) self.fetchedFrom = 0 self.fetchedCount = len(self.resdata)
def action_triggered(self, *args): action = self.actiongroup.checkedAction() layer = self.activelayercombo.currentLayer() self.clear_line() if not action: return if not action == self.measureaction and ( not layer or not layer.type() == QgsMapLayer.VectorLayer): return color = self.current_action_color actiondata = {} if action == self.measureaction: self.measuredialog.show() actiondata['mode'] = self.mode geomtype = None layerid = None else: self.measuredialog.hide() geomtype = QGis.vectorGeometryType(layer.geometryType()) layerid = layer.id() data = dict(action=action.objectName(), layer=layerid, geom=geomtype, actiondata=actiondata, color=color) self.earthmine.updateAction(data)
def setEnable(self, layer): """ To check if we can enable the action for the selected layer :param layer: selected layer """ if layer is not None and layer.type() == QgsMapLayer.VectorLayer\ and QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ: if layer == self.__layer: return if self.__layer is not None: if self.__layer.isEditable(): Signal.safelyDisconnect(self.__layer.editingStopped, self.stopEditing) else: Signal.safelyDisconnect(self.__layer.editingStarted, self.startEditing) self.__layer = layer if self.__layer.isEditable(): self.action().setEnabled(True) self.__layer.editingStopped.connect(self.stopEditing) else: self.action().setEnabled(False) self.__layer.editingStarted.connect(self.startEditing) if self.canvas().mapTool() == self: self.__iface.actionPan().trigger() return self.action().setEnabled(False) self.__removeLayer()
def load_layer_features(self, point=None, layers=None): # TODO Move this logic into the viewer and let it track it's position if point is None and self.marker.map_pos is None: return if point is None: point = self.marker.map_pos area, units = self.distancearea() rect = search_area(units, area, point) if layers is None: layers = self.visible_layers() for layer in layers: transform = self.coordinatetransform(layer) # Transform the rect source = self.canvas.mapRenderer().destinationCrs() dest = layer.crs() recttransform = QgsCoordinateTransform(source, dest) rect = recttransform.transformBoundingBox(rect) features = list( get_features_in_area(layer, rect, transform, self.canvas.mapSettings())) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, features)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue( self.INPUT)) tolerance = self.getParameterValue(self.TOLERANCE) pointsBefore = 0 pointsAfter = 0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields().toList(), QGis.flatType(layer.wkbType()), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) if len(features) > 0 else 1 for current, f in enumerate(features): featGeometry = f.geometry() if featGeometry is not None: attrs = f.attributes() pointsBefore += self.geomVertexCount(featGeometry) newGeometry = featGeometry.simplify(tolerance) pointsAfter += self.geomVertexCount(newGeometry) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrs) writer.addFeature(feature) progress.setPercentage(int(current * total)) del writer ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Simplify: Input geometries have been simplified from %s to %s points' % (pointsBefore, pointsAfter)))
def report(self, rulename, typeinfo, message, geometry, level): if geometry: try: geometry = togeometry(geometry) except TypeError: geometry = None fields = [ ('rulename', unicode(rulename).encode('utf-8')), ('objecttype', unicode(typeinfo).encode('utf-8')), ('message', unicode(message).encode('utf-8')), ('level', unicode(level).encode('utf-8')) ] # QGis.flatType if we don't care about 25D and whatnot if geometry is None: print 'XXXXX text output xxxxx', message self.db.add_feature_to_layer( self.text_table, fields, None ) elif QGis.flatType(geometry.wkbType()) == QGis.WKBLineString: if geometry.length() < 0.001: # Lines with length 0 tends to crash spatialite. Report as point instead self.report(rulename, typeinfo, message, geometry.centroid(), level) else: self.db.add_feature_to_layer( self.linestring_table, fields, geometry ) elif QGis.flatType((geometry.wkbType())) == QGis.WKBPoint: self.db.add_feature_to_layer( self.point_table, fields, geometry ) elif QGis.flatType((geometry.wkbType())) == QGis.WKBPolygon: self.db.add_feature_to_layer( self.polygon_table, fields, geometry )
def tocoordinates(feature): g = togeometry(feature) type = QGis.flatType((g.wkbType())) if type == QGis.WKBPoint: return g.asPoint() if type == QGis.WKBLineString: return g.asPolyline() if type == QGis.WKBPolygon: return g.asPolygon() raise TypeError("Unknown geometry type: " + str(type))
def layer_feature_added(self, layer, featureid): if not self.viewer: return feature = layer.getFeatures(QgsFeatureRequest(featureid)).next() renderer = layer.rendererV2() transform = self.coordinatetransform(layer) featuredata = to_feature_data(layer.id(), feature, renderer, transform) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, featuredata)
def __getPointLayers(self): """ To get all points layers that can be used :return: layers list """ layerList = [] for layer in self.__iface.mapCanvas().layers(): if layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType( layer.wkbType()) == QgsWKBTypes.PointZ: layerList.append(layer) return layerList
def toflatcoordinates(feature): """Returns a flat list of all coordinates in the geometry""" g = togeometry(feature) type = QGis.flatType((g.wkbType())) if type == QGis.WKBPoint: return [g.asPoint()] if type == QGis.WKBLineString: return g.asPolyline() if type == QGis.WKBPolygon: return [coord for ring in g.asPolygon() for coord in ring] raise TypeError("Unknown geometry type: " + str(type))
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(Difference.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(Difference.OVERLAY)) ignoreInvalid = self.getParameterValue(Difference.IGNORE_INVALID) geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(layerA.wkbType())) writer = self.getOutputFromName( Difference.OUTPUT).getVectorWriter(layerA.pendingFields(), geomType, layerA.crs()) outFeat = QgsFeature() index = vector.spatialindex(layerB) selectionA = vector.features(layerA) total = 100.0 / len(selectionA) if len(selectionA) > 0 else 1 for current, inFeatA in enumerate(selectionA): add = True geom = QgsGeometry(inFeatA.geometry()) diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) for i in intersections: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) if diff_geom.isGeosEmpty(): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Feature with NULL geometry found.')) if not diff_geom.isGeosValid(): if ignoreInvalid: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.')) add = False else: raise GeoAlgorithmExecutionException(self.tr('Features with invalid geometries found. Please fix these errors or specify the "Ignore invalid input features" flag')) break if add: try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.')) continue progress.setPercentage(int(current * total)) del writer
def __getOtherLayers(self): """ To get all points layers that can be used :return: layers list """ layerList = [] types = [QgsWKBTypes.PointZ, QgsWKBTypes.LineStringZ, QgsWKBTypes.CircularStringZ, QgsWKBTypes.CompoundCurveZ, QgsWKBTypes.CurvePolygonZ, QgsWKBTypes.PolygonZ] for layer in self.canvas().layers(): if layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType(layer.wkbType()) in types: layerList.append(layer) return layerList
def _calc_size(self): realSize = self.realsize canvaswidth = self.canvas.width() mapunitsperpixel = abs(self.canvas.mapUnitsPerPixel()) mapunits = self.canvas.mapUnits() prefered_units = roam.config.settings.get("prefer_units", "meters") newunits = QGis.fromLiteral(prefered_units, QGis.Meters) mapunitsperpixel *= QGis.fromUnitToUnitFactor(mapunits, newunits) mapunits = newunits # Convert the real distance into pixels barwidth = realSize / mapunitsperpixel if barwidth < 30: barwidth = canvaswidth / 4 while barwidth > canvaswidth / 3: barwidth /= 3 realSize = barwidth * mapunitsperpixel # Round powerof10 = math.floor(math.log10(realSize)) scaler = math.pow(10.0, powerof10) realSize = round(realSize / scaler) * scaler barwidth = realSize / mapunitsperpixel label, realSize = self._label_size(mapunits, realSize) metrics = QFontMetrics(self.font) fontwidth = metrics.width(label) fontheight = metrics.height() sizelabel = QLocale.system().toString(realSize) sizelabel = "{} {}".format(sizelabel, label) barwidth = self._adjust_bar_size(barwidth, mapunits) barwidth = barwidth + fontwidth return barwidth, realSize, sizelabel, (fontwidth, fontheight)
def to_feature_data(layerid, feature, renderer, transform): """ Transform the feature into the data for the viewer to use. :param feature: QgsFeature :param renderer: :param transform: :return: """ def polylinenodes(polyline): nodes = [] for point in polyline: point = transform.transform( point, QgsCoordinateTransform.ReverseTransform) location = dict(lat=point.y(), lng=point.x()) nodes.append(location) return nodes geom = feature.geometry() geomtype = geom.type() featuredata = [] data = dict(id=feature.id(), layerid=layerid, color=get_color(renderer, feature), geomtype=QGis.vectorGeometryType(geomtype)) if geomtype == QGis.Point: geom = geom.asPoint() point = transform.transform(geom, QgsCoordinateTransform.ReverseTransform) try: z = feature['Z'] if not z: z = 0 except KeyError: z = 0 location = dict(lat=point.y(), lng=point.x(), z=z) data['nodes'] = [location] featuredata.append(data) elif geomtype == QGis.Line: if geom.isMultipart(): # Copy the data for each polyline for polyline in geom.asMultiPolyline(): newdata = copy.copy(data) newdata['nodes'] = polylinenodes(polyline) featuredata.append(newdata) else: data['nodes'] = polylinenodes(geom.asPolyline()) featuredata.append(data) return featuredata
def setEnable(self, layer): """ To check if we can enable the action for the selected layer :param layer: selected layer """ if layer is not None and layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType(layer.wkbType()) == \ QgsWKBTypes.LineStringZ: self.__lineLayer = layer self.action().setEnabled(True) return self.action().setEnabled(False) if self.canvas().mapTool() == self: self.__iface.actionPan().trigger() if self.__dockWdg is not None: self.__dockWdg.close() self.__lineLayer = None
def setEnable(self, layer): """ To check if we can enable the action for the selected layer :param layer: selected layer """ if layer is not None and layer.type() == QgsMapLayer.VectorLayer and \ QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ: self.__lineLayer = layer self.action().setEnabled(True) return self.action().setEnabled(False) if self.__canvas.mapTool == self: self.__iface.actionPan().trigger() # self.__canvas.setMapTool(self.__oldTool) if self.__dockWdg is not None: self.__dockWdg.close() self.__lineLayer = None
def get_layer_geometry(layer): """Get layer geometry for vector layers. From layer object extract which geometry type it has. Is it point, line or polygon. """ if layer.type() == QgsMapLayer.RasterLayer: return ['raster', 999] if ISQGIS3: wkb_type = QgsWkbTypes.flatType(layer.wkbType()) point_type = QgsWkbTypes.Point line_string_type = QgsWkbTypes.LineString polygon_type = QgsWkbTypes.Polygon multi_point_type = QgsWkbTypes.MultiPoint multi_line_string_type = QgsWkbTypes.MultiLineString multi_polygon_type = QgsWkbTypes.MultiPolygon else: wkb_type = QGis.flatType(layer.wkbType()) point_type = QGis.WKBPoint line_string_type = QGis.WKBLineString polygon_type = QGis.WKBPolygon multi_point_type = QGis.WKBMultiPoint multi_line_string_type = QGis.WKBMultiLineString multi_polygon_type = QGis.WKBMultiPolygon LOGGER.info('type {}', layer.wkbType()) geometry = [None, 100] if wkb_type == point_type: geometry = ['point', 1] if wkb_type == line_string_type: geometry = ['line', 2] if wkb_type == polygon_type: geometry = ['polygon', 3] if wkb_type == multi_point_type: geometry = ['point', 4] if wkb_type == multi_line_string_type: geometry = ['line', 5] if wkb_type == multi_polygon_type: geometry = ['polygon', 6] if wkb_type == 100: LOGGER.info('Layer is a data-only layer') return geometry
def line_locate_point(geometry, point): coords = tocoordinates(geometry) assert QGis.flatType((geometry.wkbType())) == QGis.WKBLineString, 'Expected a LineString' assert len(point) == 2, 'Expected a point' sqrddist, closestsegmentpoint, indexofclosestvertexafter = geometry.closestSegmentWithContext(point) sum_length = 0 # Length of segments before the segment, where the point is located for ix in range(1, indexofclosestvertexafter): p0 = coords[ix - 1] p1 = coords[ix] segment = QgsGeometry.fromPolyline([p0, p1]) sum_length += segment.length() # Part of segment where the points is located p0 = coords[indexofclosestvertexafter - 1] segment = QgsGeometry.fromPolyline([p0, closestsegmentpoint]) sum_length += segment.length() return sum_length
def __init__(self, iface, memoryPointsLayer, memoryLinesLayer, importConfigTable, importUriDb, importSchemaDb, controlConfigTable, controlUriDb, controlSchemaDb, mntUrl, refLayers, adjLayers, levelAtt, levelVal, drawdowmLayer, pipeDiam, moreTools): """ Constructor :param iface: interface :param memoryPointsLayer: working memory points layer :param memoryLinesLayer: working memory lines layer :param importConfigTable: config table selected for import :param importUriDb: database for import :param importSchemaDb: db schema for import :param controlConfigTable: config table selected for control :param controlUriDb: database for control :param controlSchemaDb: db schema for control :param mntUrl: url to get mnt :param refLayers: reference layers for drawdown :param adjLayers: adjustement layers for drawdown :param levelAtt: level attribute for drawdown :param levelVal: level value for drawdown :param drawdowmLayer: line layer for drawdown :param pipeDiam: pipe diameter for drawdown :param moreTools: if more tools or not """ QDialog.__init__(self) self.__iface = iface self.__memoryPointsLayer = memoryPointsLayer self.__memoryLinesLayer = memoryLinesLayer self.__importConfigTable = importConfigTable self.__importUriDb = importUriDb self.__importSchemaDb = importSchemaDb self.__controlConfigTable = controlConfigTable self.__controlUriDb = controlUriDb self.__controlSchemaDb = controlSchemaDb self.__mntUrl = mntUrl self.__refLayers = refLayers self.__adjLayers = adjLayers self.__levelAtt = levelAtt self.__levelVal = levelVal self.__drawdowmLayer = drawdowmLayer self.__pipeDiam = pipeDiam self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings")) self.__pointsLayers = [] self.__linesLayers = [] self.__refAvailableLayers = [] self.__drawdownLayers = [] self.__tables = [] self.__schemas = [] self.__pipeDiamFields = [] self.__levelAttFields = [] self.__dbs = DBConnector.getUsedDatabases() self.__refLabels = [] self.__refChecks = [] self.__adjChecks = [] for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()): if layer is not None and layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() == "memory": if layer.geometryType() == QGis.Point: self.__pointsLayers.append(layer) if layer.geometryType() == QGis.Line: self.__linesLayers.append(layer) if QGis.fromOldWkbType( layer.wkbType()) == QgsWKBTypes.LineStringZ: self.__drawdownLayers.append(layer) if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ: self.__refAvailableLayers.append(layer) self.resize(600, 500) self.__layout = QGridLayout() self.__scrollLayout = QGridLayout() line = 0 intersectLabel = QLabel( QCoreApplication.translate("VDLTools", "Intersect ")) self.__scrollLayout.addWidget(intersectLabel, line, 0) line += 1 pointLabel = QLabel( QCoreApplication.translate("VDLTools", "Working points layer : ")) self.__scrollLayout.addWidget(pointLabel, line, 1) self.__pointCombo = QComboBox() self.__pointCombo.setMinimumHeight(20) self.__pointCombo.setMinimumWidth(50) self.__pointCombo.addItem("") for layer in self.__pointsLayers: self.__pointCombo.addItem(layer.name()) self.__scrollLayout.addWidget(self.__pointCombo, line, 2) self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged) if self.__memoryPointsLayer is not None: if self.__memoryPointsLayer in self.__pointsLayers: self.__pointCombo.setCurrentIndex( self.__pointsLayers.index(self.__memoryPointsLayer) + 1) line += 1 lineLabel = QLabel( QCoreApplication.translate("VDLTools", "Working lines layer : ")) self.__scrollLayout.addWidget(lineLabel, line, 1) self.__lineCombo = QComboBox() self.__lineCombo.setMinimumHeight(20) self.__lineCombo.setMinimumWidth(50) self.__lineCombo.addItem("") for layer in self.__linesLayers: self.__lineCombo.addItem(layer.name()) self.__scrollLayout.addWidget(self.__lineCombo, line, 2) self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged) if self.__memoryLinesLayer is not None: if self.__memoryLinesLayer in self.__linesLayers: self.__lineCombo.setCurrentIndex( self.__linesLayers.index(self.__memoryLinesLayer) + 1) line += 1 profilesLabel = QLabel( QCoreApplication.translate("VDLTools", "Profiles ")) self.__scrollLayout.addWidget(profilesLabel, line, 0) line += 1 mntLabel = QLabel( QCoreApplication.translate("VDLTools", "Url for MNT : ")) self.__scrollLayout.addWidget(mntLabel, line, 1) self.__mntText = QLineEdit() if self.__mntUrl is None or self.__mntUrl == "None": self.__mntText.insert( 'https://map.lausanne.ch/prod/wsgi/profile.json') else: self.__mntText.insert(self.__mntUrl) self.__mntText.setMinimumHeight(20) self.__mntText.setMinimumWidth(100) self.__scrollLayout.addWidget(self.__mntText, line, 2) line += 1 ddLabel = QLabel(QCoreApplication.translate("VDLTools", "Drawdown ")) self.__scrollLayout.addWidget(ddLabel, line, 0) line += 1 self.__scrollLayout.addWidget( QLabel(QCoreApplication.translate("VDLTools", "Layer")), line, 1) namesLayout = QHBoxLayout() namesWidget = QWidget() namesLayout.addWidget( QLabel(QCoreApplication.translate("VDLTools", "Reference"))) namesLayout.addWidget( QLabel(QCoreApplication.translate("VDLTools", "Adjustable"))) namesLayout.setContentsMargins(0, 0, 0, 0) namesWidget.setLayout(namesLayout) self.__scrollLayout.addWidget(namesWidget, line, 2) line += 1 for layer in self.__refAvailableLayers: refLabel = QLabel(" - " + layer.name()) self.__refLabels.append(refLabel) self.__scrollLayout.addWidget(refLabel, line, 1) checksLayout = QHBoxLayout() checksLayout.setContentsMargins(0, 0, 0, 0) checksWidget = QWidget() refCheck = QCheckBox() self.__refChecks.append(refCheck) refCheck.stateChanged.connect(self.__refBoxesChanged) checksLayout.addWidget(refCheck) adjCheck = QCheckBox() self.__adjChecks.append(adjCheck) checksLayout.addWidget(adjCheck) checksWidget.setLayout(checksLayout) self.__scrollLayout.addWidget(checksWidget, line, 2) line += 1 levelAttLabel = QLabel( QCoreApplication.translate("VDLTools", "Code(s) on pipe : ")) self.__scrollLayout.addWidget(levelAttLabel, line, 1) self.__levelAttCombo = QComboBox() self.__levelAttCombo.setMinimumHeight(20) self.__levelAttCombo.setMinimumWidth(50) self.__levelAttCombo.addItem("") self.__scrollLayout.addWidget(self.__levelAttCombo, line, 2) self.__levelAttCombo.currentIndexChanged.connect( self.__levelAttComboChanged) i = 0 for layer in self.__refAvailableLayers: if layer in self.__refLayers: self.__refChecks[i].setChecked(True) if layer in self.__adjLayers: self.__adjChecks[i].setChecked(True) i += 1 line += 1 levelValLabel = QLabel( QCoreApplication.translate("VDLTools", "Point code attribute : ")) self.__scrollLayout.addWidget(levelValLabel, line, 1) self.__levelValText = QLineEdit() if self.__levelVal is not None and self.__levelVal != "None": self.__levelValText.insert(self.__levelVal) self.__levelValText.setMinimumHeight(20) self.__levelValText.setMinimumWidth(100) self.__scrollLayout.addWidget(self.__levelValText, line, 2) line += 1 drawdownLabel = QLabel( QCoreApplication.translate("VDLTools", "drawdown layer : ")) self.__scrollLayout.addWidget(drawdownLabel, line, 1) self.__drawdownCombo = QComboBox() self.__drawdownCombo.setMinimumHeight(20) self.__drawdownCombo.setMinimumWidth(50) self.__drawdownCombo.addItem("") for layer in self.__drawdownLayers: self.__drawdownCombo.addItem(layer.name()) self.__scrollLayout.addWidget(self.__drawdownCombo, line, 2) line += 1 pipeDiamLabel = QLabel( QCoreApplication.translate("VDLTools", "Pipe diameter attribute [cm] : ")) self.__scrollLayout.addWidget(pipeDiamLabel, line, 1) self.__pipeDiamCombo = QComboBox() self.__pipeDiamCombo.setMinimumHeight(20) self.__pipeDiamCombo.setMinimumWidth(50) self.__pipeDiamCombo.addItem("") self.__scrollLayout.addWidget(self.__pipeDiamCombo, line, 2) self.__drawdownCombo.currentIndexChanged.connect( self.__drawdownComboChanged) self.__pipeDiamCombo.currentIndexChanged.connect( self.__pipeDiamComboChanged) if self.__drawdowmLayer is not None: if self.__drawdowmLayer in self.__drawdownLayers: self.__drawdownCombo.setCurrentIndex( self.__drawdownLayers.index(self.__drawdowmLayer) + 1) line += 1 controlLabel = QLabel( QCoreApplication.translate("VDLTools", "Control ")) self.__scrollLayout.addWidget(controlLabel, line, 0) line += 1 controlDbLabel = QLabel( QCoreApplication.translate("VDLTools", "Control database : ")) self.__scrollLayout.addWidget(controlDbLabel, line, 1) self.__controlDbCombo = QComboBox() self.__controlDbCombo.setMinimumHeight(20) self.__controlDbCombo.setMinimumWidth(50) self.__controlDbCombo.addItem("") for db in list(self.__dbs.keys()): self.__controlDbCombo.addItem(db) self.__scrollLayout.addWidget(self.__controlDbCombo, line, 2) line += 1 controlSchemaLabel = QLabel( QCoreApplication.translate("VDLTools", "Control database schema : ")) self.__scrollLayout.addWidget(controlSchemaLabel, line, 1) self.__controlSchemaCombo = QComboBox() self.__controlSchemaCombo.setMinimumHeight(20) self.__controlSchemaCombo.setMinimumWidth(50) self.__controlSchemaCombo.addItem("") self.__scrollLayout.addWidget(self.__controlSchemaCombo, line, 2) line += 1 controlTableLabel = QLabel( QCoreApplication.translate("VDLTools", "Control config table : ")) self.__scrollLayout.addWidget(controlTableLabel, line, 1) self.__controlTableCombo = QComboBox() self.__controlTableCombo.setMinimumHeight(20) self.__controlTableCombo.setMinimumWidth(50) self.__controlTableCombo.addItem("") self.__scrollLayout.addWidget(self.__controlTableCombo, line, 2) self.__controlDbCombo.currentIndexChanged.connect( self.__controlDbComboChanged) self.__controlSchemaCombo.currentIndexChanged.connect( self.__controlSchemaComboChanged) self.__controlTableCombo.currentIndexChanged.connect( self.__controlTableComboChanged) if self.__controlUriDb is not None: if self.__controlUriDb.database() in list(self.__dbs.keys()): self.__controlDbCombo.setCurrentIndex( list(self.__dbs.keys()).index( self.__controlUriDb.database()) + 1) if moreTools: line += 1 importLabel = QLabel( QCoreApplication.translate("VDLTools", "Import ")) self.__scrollLayout.addWidget(importLabel, line, 0) line += 1 importDbLabel = QLabel( QCoreApplication.translate("VDLTools", "Import database : ")) self.__scrollLayout.addWidget(importDbLabel, line, 1) self.__importDbCombo = QComboBox() self.__importDbCombo.setMinimumHeight(20) self.__importDbCombo.setMinimumWidth(50) self.__importDbCombo.addItem("") for db in list(self.__dbs.keys()): self.__importDbCombo.addItem(db) self.__scrollLayout.addWidget(self.__importDbCombo, line, 2) line += 1 importSchemaLabel = QLabel( QCoreApplication.translate("VDLTools", "Import database schema : ")) self.__scrollLayout.addWidget(importSchemaLabel, line, 1) self.__importSchemaCombo = QComboBox() self.__importSchemaCombo.setMinimumHeight(20) self.__importSchemaCombo.setMinimumWidth(50) self.__importSchemaCombo.addItem("") self.__scrollLayout.addWidget(self.__importSchemaCombo, line, 2) line += 1 importTableLabel = QLabel( QCoreApplication.translate("VDLTools", "Import config table : ")) self.__scrollLayout.addWidget(importTableLabel, line, 1) self.__importTableCombo = QComboBox() self.__importTableCombo.setMinimumHeight(20) self.__importTableCombo.setMinimumWidth(50) self.__importTableCombo.addItem("") self.__scrollLayout.addWidget(self.__importTableCombo, line, 2) self.__importDbCombo.currentIndexChanged.connect( self.__importDbComboChanged) self.__importSchemaCombo.currentIndexChanged.connect( self.__importSchemaComboChanged) self.__importTableCombo.currentIndexChanged.connect( self.__importTableComboChanged) if self.__importUriDb is not None: if self.__importUriDb.database() in list(self.__dbs.keys()): self.__importDbCombo.setCurrentIndex( list(self.__dbs.keys()).index( self.__importUriDb.database()) + 1) else: self.__importDbCombo = None self.__importSchemaCombo = None self.__importTableCombo = None widget = QWidget() widget.setLayout(self.__scrollLayout) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(widget) self.__layout.addWidget(scroll, 1, 0, 1, 2) self.__okButton = QPushButton( QCoreApplication.translate("VDLTools", "OK")) self.__okButton.setMinimumHeight(20) self.__okButton.setMinimumWidth(100) self.__cancelButton = QPushButton( QCoreApplication.translate("VDLTools", "Cancel")) self.__cancelButton.setMinimumHeight(20) self.__cancelButton.setMinimumWidth(100) self.__layout.addWidget(self.__okButton, 100, 0) self.__layout.addWidget(self.__cancelButton, 100, 1) self.setLayout(self.__layout)
def processAlgorithm(self, progress): source_layer = dataobjects.getObjectFromUri( self.getParameterValue(Clip.INPUT)) mask_layer = dataobjects.getObjectFromUri( self.getParameterValue(Clip.OVERLAY)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( source_layer.fields(), QgsWKBTypes.multiType(QGis.fromOldWkbType(source_layer.wkbType())), source_layer.crs()) # first build up a list of clip geometries clip_geoms = [] for maskFeat in vector.features(mask_layer, QgsFeatureRequest().setSubsetOfAttributes([])): clip_geoms.append(QgsGeometry(maskFeat.constGeometry())) # are we clipping against a single feature? if so, we can show finer progress reports if len(clip_geoms) > 1: combined_clip_geom = QgsGeometry.unaryUnion(clip_geoms) single_clip_feature = False else: combined_clip_geom = clip_geoms[0] single_clip_feature = True # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(combined_clip_geom.geometry()) engine.prepareGeometry() tested_feature_ids = set() for i, clip_geom in enumerate(clip_geoms): input_features = [f for f in vector.features(source_layer, QgsFeatureRequest().setFilterRect(clip_geom.boundingBox()))] if not input_features: continue if single_clip_feature: total = 100.0 / len(input_features) if len(input_features) > 0 else 1 else: total = 0 for current, in_feat in enumerate(input_features): if not in_feat.constGeometry(): continue if in_feat.id() in tested_feature_ids: # don't retest a feature we have already checked continue tested_feature_ids.add(in_feat.id()) if not engine.intersects(in_feat.constGeometry().geometry()): continue if not engine.contains(in_feat.constGeometry().geometry()): cur_geom = QgsGeometry(in_feat.constGeometry()) new_geom = combined_clip_geom.intersection(cur_geom) if new_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(new_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection: int_com = in_feat.constGeometry().combine(new_geom) int_sym = in_feat.constGeometry().symDifference(new_geom) if not int_com or not int_sym: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or more ' 'input features have invalid geometry.')) else: new_geom = int_com.difference(int_sym) if new_geom.isGeosEmpty() or not new_geom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or more ' 'input features have invalid geometry.')) else: # clip geometry totally contains feature geometry, so no need to perform intersection new_geom = QgsGeometry(in_feat.constGeometry()) try: out_feat = QgsFeature() out_feat.setGeometry(new_geom) out_feat.setAttributes(in_feat.attributes()) writer.addFeature(out_feat) except: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Feature geometry error: One or more ' 'output features ignored due to ' 'invalid geometry.')) continue if single_clip_feature: progress.setPercentage(int(current * total)) if not single_clip_feature: # coarse progress report for multiple clip geometries progress.setPercentage(100.0 * i / len(clip_geoms)) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.OVERLAY)) geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(layerA.wkbType())) fields = vector.combineVectorFields(layerA, layerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, geomType, layerA.crs()) featB = QgsFeature() outFeat = QgsFeature() indexA = vector.spatialindex(layerB) indexB = vector.spatialindex(layerA) featuresA = vector.features(layerA) featuresB = vector.features(layerB) total = 100.0 / (len(featuresA) * len(featuresB)) count = 0 for featA in featuresA: add = True geom = QgsGeometry(featA.geometry()) diffGeom = QgsGeometry(geom) attrs = featA.attributes() intersects = indexA.intersects(geom.boundingBox()) for i in intersects: layerB.getFeatures( QgsFeatureRequest().setFilterFid(i)).nextFeature(featB) tmpGeom = QgsGeometry(featB.geometry()) if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) if not diffGeom.isGeosValid(): ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) add = False break if add: try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) continue count += 1 progress.setPercentage(int(count * total)) length = len(layerA.fields()) for featA in featuresB: add = True geom = QgsGeometry(featA.geometry()) diffGeom = QgsGeometry(geom) attrs = featA.attributes() attrs = [NULL] * length + attrs intersects = indexB.intersects(geom.boundingBox()) for i in intersects: layerA.getFeatures( QgsFeatureRequest().setFilterFid(i)).nextFeature(featB) tmpGeom = QgsGeometry(featB.geometry()) if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) if not diffGeom.isGeosValid(): ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) add = False break if add: try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) continue count += 1 progress.setPercentage(int(count * total)) del writer
def __project_loaded(self): """ Get saved settings on load """ """ Reference point layers for drawdown tool """ str_ids = QgsProject.instance().readEntry("VDLTools", "ref_layers", "None")[0] ref_ids = str_ids.split(',') """ Adjustable point layers for drawdown tool """ str_ids = QgsProject.instance().readEntry("VDLTools", "adj_layers", "None")[0] adj_ids = str_ids.split(',') """ Level attribute for drawdown tool """ self.__levelAtt = QgsProject.instance().readEntry("VDLTools", "level_att", "None")[0] """ Level value for drawdown tool """ value = QgsProject.instance().readEntry("VDLTools", "level_val", "None")[0] self.__levelVals = value.split(",") """ Drawdown line layer """ dd_id = QgsProject.instance().readEntry("VDLTools", "drawdown_layer", "None")[0] """ Pipe diameter attribute for drawdown line layer """ self.__pipeDiam = QgsProject.instance().readEntry("VDLTools", "pipe_diam", "None")[0] """ Url used to get mnt values on a line """ self.__mntUrl = QgsProject.instance().readEntry("VDLTools", "mnt_url", "None")[0] """ Config table in Database for importing new Lausanne data """ self.__configTable = QgsProject.instance().readEntry("VDLTools", "config_table", None)[0] """ Database used for importing new Lausanne data """ dbName = QgsProject.instance().readEntry("VDLTools", "db_name", None)[0] """ Table in Database containing control values for importing new Lausanne data """ ctlDbName = QgsProject.instance().readEntry("VDLTools", "ctl_db_name", None)[0] """ Schema of the Database used for importing new Lausanne data """ self.__schemaDb = QgsProject.instance().readEntry("VDLTools", "schema_db", None)[0] """ Temporarly points layer for the project """ mpl_id = QgsProject.instance().readEntry("VDLTools", "memory_points_layer", None)[0] """ Temporarly lines layer for the project """ mll_id = QgsProject.instance().readEntry("VDLTools", "memory_lines_layer", None)[0] for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()): if layer and layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() == "memory": if layer.geometryType() == QGis.Point: if layer.id() == mpl_id: self.__memoryPointsLayer = layer if layer.geometryType() == QGis.Line: if layer.id() == mll_id: self.__memoryLinesLayer = layer if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ: if layer.id() == dd_id: self.__drawdownLayer = layer if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ: if layer.id() in ref_ids: self.__refLayers.append(layer) if layer.id() in adj_ids: self.__adjLayers.append(layer) if dbName != "": usedDbs = DBConnector.getUsedDatabases() if dbName in list(usedDbs.keys()): self.__uriDb = usedDbs[dbName] if ctlDbName != "": usedDbs = DBConnector.getUsedDatabases() if ctlDbName in list(usedDbs.keys()): self.__ctlDb = usedDbs[ctlDbName] self.changedSignal.emit()
def __init__(self, iface, memoryPointsLayer, memoryLinesLayer, ctllDb, configTable, uriDb, schemaDb, mntUrl, refLayers, adjLayers, levelAtt, levelVal, drawdowmLayer, pipeDiam, moreTools): """ Constructor :param iface: interface :param memoryPointsLayer: working memory points layer :param memoryLinesLayer: working memory lines layer :param configTable: config table selected for import """ QDialog.__init__(self) self.__iface = iface self.__memoryPointsLayer = memoryPointsLayer self.__memoryLinesLayer = memoryLinesLayer self.__ctlDb = ctllDb self.__configTable = configTable self.__uriDb = uriDb self.__schemaDb = schemaDb self.__mntUrl = mntUrl self.__refLayers = refLayers self.__adjLayers = adjLayers self.__levelAtt = levelAtt self.__levelVal = levelVal self.__drawdowmLayer = drawdowmLayer self.__pipeDiam = pipeDiam self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings")) self.__pointsLayers = [] self.__linesLayers = [] self.__refAvailableLayers = [] self.__drawdownLayers = [] self.__tables = [] self.__schemas = [] self.__pipeDiamFields = [] self.__levelAttFields = [] self.__dbs = DBConnector.getUsedDatabases() self.__refLabels = [] self.__refChecks = [] self.__adjChecks = [] for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()): if layer is not None and layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() == "memory": if layer.geometryType() == QGis.Point: self.__pointsLayers.append(layer) if layer.geometryType() == QGis.Line: self.__linesLayers.append(layer) if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ: self.__drawdownLayers.append(layer) if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ: self.__refAvailableLayers.append(layer) # self.resize(450, 400) self.__layout = QGridLayout() line = 0 intersectLabel = QLabel(QCoreApplication.translate("VDLTools", "Intersect ")) self.__layout.addWidget(intersectLabel, line, 0) line += 1 pointLabel = QLabel(QCoreApplication.translate("VDLTools", "Working points layer : ")) self.__layout.addWidget(pointLabel, line, 1) self.__pointCombo = QComboBox() self.__pointCombo.setMinimumHeight(20) self.__pointCombo.setMinimumWidth(50) self.__pointCombo.addItem("") for layer in self.__pointsLayers: self.__pointCombo.addItem(layer.name()) self.__layout.addWidget(self.__pointCombo, line, 2) self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged) if self.__memoryPointsLayer is not None: if self.__memoryPointsLayer in self.__pointsLayers: self.__pointCombo.setCurrentIndex(self.__pointsLayers.index(self.__memoryPointsLayer)+1) line += 1 lineLabel = QLabel(QCoreApplication.translate("VDLTools", "Working lines layer : ")) self.__layout.addWidget(lineLabel, line, 1) self.__lineCombo = QComboBox() self.__lineCombo.setMinimumHeight(20) self.__lineCombo.setMinimumWidth(50) self.__lineCombo.addItem("") for layer in self.__linesLayers: self.__lineCombo.addItem(layer.name()) self.__layout.addWidget(self.__lineCombo, line, 2) self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged) if self.__memoryLinesLayer is not None: if self.__memoryLinesLayer in self.__linesLayers: self.__lineCombo.setCurrentIndex(self.__linesLayers.index(self.__memoryLinesLayer)+1) line += 1 profilesLabel = QLabel(QCoreApplication.translate("VDLTools", "Profiles ")) self.__layout.addWidget(profilesLabel, line, 0) line += 1 mntLabel = QLabel(QCoreApplication.translate("VDLTools", "Url for MNT : ")) self.__layout.addWidget(mntLabel, line, 1) self.__mntText = QLineEdit() if self.__mntUrl is None or self.__mntUrl == "None": self.__mntText.insert('https://map.lausanne.ch/prod/wsgi/profile.json') else: self.__mntText.insert(self.__mntUrl) self.__mntText.setMinimumHeight(20) self.__mntText.setMinimumWidth(100) self.__layout.addWidget(self.__mntText, line, 2) line += 1 ddLabel = QLabel(QCoreApplication.translate("VDLTools", "Drawdown ")) self.__layout.addWidget(ddLabel, line, 0) line += 1 self.__layout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Layer")), line, 1) namesLayout = QHBoxLayout() namesWidget = QWidget() namesLayout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Reference"))) namesLayout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Adjustable"))) namesLayout.setContentsMargins(0,0,0,0) namesWidget.setLayout(namesLayout) self.__layout.addWidget(namesWidget, line, 2) line += 1 for layer in self.__refAvailableLayers: refLabel = QLabel(" - " + layer.name()) self.__refLabels.append(refLabel) self.__layout.addWidget(refLabel, line, 1) checksLayout = QHBoxLayout() checksLayout.setContentsMargins(0,0,0,0) checksWidget = QWidget() refCheck = QCheckBox() self.__refChecks.append(refCheck) refCheck.stateChanged.connect(self.__refBoxesChanged) checksLayout.addWidget(refCheck) adjCheck = QCheckBox() self.__adjChecks.append(adjCheck) checksLayout.addWidget(adjCheck) checksWidget.setLayout(checksLayout) self.__layout.addWidget(checksWidget, line, 2) line += 1 levelAttLabel = QLabel(QCoreApplication.translate("VDLTools", "Code(s) on pipe : ")) self.__layout.addWidget(levelAttLabel, line, 1) self.__levelAttCombo = QComboBox() self.__levelAttCombo.setMinimumHeight(20) self.__levelAttCombo.setMinimumWidth(50) self.__levelAttCombo.addItem("") self.__layout.addWidget(self.__levelAttCombo, line, 2) self.__levelAttCombo.currentIndexChanged.connect(self.__levelAttComboChanged) i = 0 for layer in self.__refAvailableLayers: if layer in self.__refLayers: self.__refChecks[i].setChecked(True) if layer in self.__adjLayers: self.__adjChecks[i].setChecked(True) i += 1 line += 1 levelValLabel = QLabel(QCoreApplication.translate("VDLTools", "Point code attribute : ")) self.__layout.addWidget(levelValLabel, line, 1) self.__levelValText = QLineEdit() if self.__levelVal is not None and self.__levelVal != "None": self.__levelValText.insert(self.__levelVal) self.__levelValText.setMinimumHeight(20) self.__levelValText.setMinimumWidth(100) self.__layout.addWidget(self.__levelValText, line, 2) line += 1 drawdownLabel = QLabel(QCoreApplication.translate("VDLTools", "drawdown layer : ")) self.__layout.addWidget(drawdownLabel, line, 1) self.__drawdownCombo = QComboBox() self.__drawdownCombo.setMinimumHeight(20) self.__drawdownCombo.setMinimumWidth(50) self.__drawdownCombo.addItem("") for layer in self.__drawdownLayers: self.__drawdownCombo.addItem(layer.name()) self.__layout.addWidget(self.__drawdownCombo, line, 2) line += 1 pipeDiamLabel = QLabel(QCoreApplication.translate("VDLTools", "Pipe diameter attribute [cm] : ")) self.__layout.addWidget(pipeDiamLabel, line, 1) self.__pipeDiamCombo = QComboBox() self.__pipeDiamCombo.setMinimumHeight(20) self.__pipeDiamCombo.setMinimumWidth(50) self.__pipeDiamCombo.addItem("") self.__layout.addWidget(self.__pipeDiamCombo, line, 2) self.__drawdownCombo.currentIndexChanged.connect(self.__drawdownComboChanged) self.__pipeDiamCombo.currentIndexChanged.connect(self.__pipeDiamComboChanged) if self.__drawdowmLayer is not None: if self.__drawdowmLayer in self.__drawdownLayers: self.__drawdownCombo.setCurrentIndex(self.__drawdownLayers.index(self.__drawdowmLayer)+1) if moreTools: line += 1 importLabel = QLabel(QCoreApplication.translate("VDLTools", "Import ")) self.__layout.addWidget(importLabel, line, 0) line += 1 dbLabel = QLabel(QCoreApplication.translate("VDLTools", "Import database : ")) self.__layout.addWidget(dbLabel, line, 1) self.__dbCombo = QComboBox() self.__dbCombo.setMinimumHeight(20) self.__dbCombo.setMinimumWidth(50) self.__dbCombo.addItem("") for db in list(self.__dbs.keys()): self.__dbCombo.addItem(db) self.__layout.addWidget(self.__dbCombo, line, 2) line += 1 schemaLabel = QLabel(QCoreApplication.translate("VDLTools", "Database schema : ")) self.__layout.addWidget(schemaLabel, line, 1) self.__schemaCombo = QComboBox() self.__schemaCombo.setMinimumHeight(20) self.__schemaCombo.setMinimumWidth(50) self.__schemaCombo.addItem("") self.__layout.addWidget(self.__schemaCombo, line, 2) line += 1 tableLabel = QLabel(QCoreApplication.translate("VDLTools", "Config table : ")) self.__layout.addWidget(tableLabel, line, 1) self.__tableCombo = QComboBox() self.__tableCombo.setMinimumHeight(20) self.__tableCombo.setMinimumWidth(50) self.__tableCombo.addItem("") self.__layout.addWidget(self.__tableCombo, line, 2) line += 1 controlLabel = QLabel(QCoreApplication.translate("VDLTools", "Control ")) self.__layout.addWidget(controlLabel, line, 0) line += 1 ctlLabel = QLabel(QCoreApplication.translate("VDLTools", "Control database : ")) self.__layout.addWidget(ctlLabel, line, 1) self.__ctlCombo = QComboBox() self.__ctlCombo.setMinimumHeight(20) self.__ctlCombo.setMinimumWidth(50) self.__ctlCombo.addItem("") for db in list(self.__dbs.keys()): self.__ctlCombo.addItem(db) self.__layout.addWidget(self.__ctlCombo, line, 2) self.__dbCombo.currentIndexChanged.connect(self.__dbComboChanged) self.__schemaCombo.currentIndexChanged.connect(self.__schemaComboChanged) self.__tableCombo.currentIndexChanged.connect(self.__tableComboChanged) self.__ctlCombo.currentIndexChanged.connect(self.__ctlComboChanged) if self.__uriDb is not None: if self.__uriDb.database() in list(self.__dbs.keys()): self.__dbCombo.setCurrentIndex(list(self.__dbs.keys()).index(self.__uriDb.database()) + 1) if self.__ctlDb is not None: if self.__ctlDb.database() in list(self.__dbs.keys()): self.__ctlCombo.setCurrentIndex(list(self.__dbs.keys()).index(self.__ctlDb.database()) + 1) else: self.__dbCombo = None self.__schemaCombo = None self.__tableCombo = None self.__ctlCombo = None self.__okButton = QPushButton(QCoreApplication.translate("VDLTools", "OK")) self.__okButton.setMinimumHeight(20) self.__okButton.setMinimumWidth(100) self.__cancelButton = QPushButton(QCoreApplication.translate("VDLTools", "Cancel")) self.__cancelButton.setMinimumHeight(20) self.__cancelButton.setMinimumWidth(100) self.__layout.addWidget(self.__okButton, 100, 1) self.__layout.addWidget(self.__cancelButton, 100, 2) self.setLayout(self.__layout)
def processAlgorithm(self, progress): vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT2)) ignoreNull = self.getParameterValue(Intersection.IGNORE_NULL) geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(vlayerA.wkbType())) fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, geomType, vlayerA.crs()) outFeat = QgsFeature() index = vector.spatialindex(vlayerB) selectionA = vector.features(vlayerA) total = 100.0 / len(selectionA) if len(selectionA) > 0 else 1 for current, inFeatA in enumerate(selectionA): progress.setPercentage(int(current * total)) geom = inFeatA.geometry() if not geom: if ignoreNull: continue else: raise GeoAlgorithmExecutionException( self.tr('Input layer A contains NULL geometries. ' 'Please check "Ignore NULL geometries" ' 'if you want to run this algorithm anyway.')) if not geom.isGeosValid(): raise GeoAlgorithmExecutionException( self.tr('Input layer A contains invalid geometries ' '(feature {}). Unable to complete intersection ' 'algorithm.'.format(inFeatA.id()))) atMapA = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) for inFeatB in vlayerB.getFeatures(QgsFeatureRequest().setFilterFids(intersects)): tmpGeom = QgsGeometry(inFeatB.geometry()) if not geom: if ignoreNull: continue else: raise GeoAlgorithmExecutionException( self.tr('Input layer B contains NULL geometries. ' 'Please check "Ignore NULL geometries" ' 'if you want to run this algorithm anyway.')) if not geom.isGeosValid(): raise GeoAlgorithmExecutionException( self.tr('Input layer B contains invalid geometries ' '(feature {}). Unable to complete intersection ' 'algorithm.'.format(inFeatB.id()))) if geom.intersects(tmpGeom): atMapB = inFeatB.attributes() int_geom = QgsGeometry(geom.intersection(tmpGeom)) if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection: int_com = geom.combine(tmpGeom) int_geom = QgsGeometry() if int_com is not None: int_sym = geom.symDifference(tmpGeom) if int_sym: diff_geom = int_com.difference(int_sym) int_geom = QgsGeometry(diff_geom) if int_geom.isGeosEmpty() or not int_geom.isGeosValid(): raise GeoAlgorithmExecutionException( self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) try: if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]: outFeat.setGeometry(int_geom) attrs = [] attrs.extend(atMapA) attrs.extend(atMapB) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: raise GeoAlgorithmExecutionException( self.tr('Feature geometry error: one or ' 'more output features ignored due ' 'to invalid geometry.')) del writer
def spatial_unit(self): u = self.rgis.crs.mapUnits() su = QGis.toLiteral(u).upper() return su
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 __project_loaded(self): """ Get saved settings on load """ """ Reference point layers for drawdown tool """ str_ids = QgsProject.instance().readEntry("VDLTools", "ref_layers", "None")[0] ref_ids = str_ids.split(',') """ Adjustable point layers for drawdown tool """ str_ids = QgsProject.instance().readEntry("VDLTools", "adj_layers", "None")[0] adj_ids = str_ids.split(',') """ Level attribute for drawdown tool """ self.__levelAtt = QgsProject.instance().readEntry( "VDLTools", "level_att", "None")[0] """ Level value for drawdown tool """ value = QgsProject.instance().readEntry("VDLTools", "level_val", "None")[0] self.__levelVals = value.split(",") """ Drawdown line layer """ dd_id = QgsProject.instance().readEntry("VDLTools", "drawdown_layer", "None")[0] """ Pipe diameter attribute for drawdown line layer """ self.__pipeDiam = QgsProject.instance().readEntry( "VDLTools", "pipe_diam", "None")[0] """ Url used to get mnt values on a line """ self.__mntUrl = QgsProject.instance().readEntry( "VDLTools", "mnt_url", "None")[0] """ Config table in Database for importing new Lausanne data """ self.__importConfigTable = QgsProject.instance().readEntry( "VDLTools", "import_config_table", None)[0] """ Config table in Database for controling """ self.__controlConfigTable = QgsProject.instance().readEntry( "VDLTools", "control_config_table", None)[0] """ Database used for importing new Lausanne data """ importDbName = QgsProject.instance().readEntry("VDLTools", "import_db_name", None)[0] """ Database used for controling """ controlDbName = QgsProject.instance().readEntry( "VDLTools", "control_db_name", None)[0] """ Schema of the Database used for importing new Lausanne data """ self.__importSchemaDb = QgsProject.instance().readEntry( "VDLTools", "import_schema_db", None)[0] """ Schema of the Database used for controling """ self.__controlSchemaDb = QgsProject.instance().readEntry( "VDLTools", "control_schema_db", None)[0] """ Temporarly points layer for the project """ mpl_id = QgsProject.instance().readEntry("VDLTools", "memory_points_layer", None)[0] """ Temporarly lines layer for the project """ mll_id = QgsProject.instance().readEntry("VDLTools", "memory_lines_layer", None)[0] for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()): if layer and layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() == "memory": if layer.geometryType() == QGis.Point: if layer.id() == mpl_id: self.__memoryPointsLayer = layer if layer.geometryType() == QGis.Line: if layer.id() == mll_id: self.__memoryLinesLayer = layer if QGis.fromOldWkbType( layer.wkbType()) == QgsWKBTypes.LineStringZ: if layer.id() == dd_id: self.__drawdownLayer = layer if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ: if layer.id() in ref_ids: self.__refLayers.append(layer) if layer.id() in adj_ids: self.__adjLayers.append(layer) if importDbName != "" or controlDbName != "": usedDbs = DBConnector.getUsedDatabases() if importDbName != "" and importDbName in list(usedDbs.keys()): self.__importUriDb = usedDbs[importDbName] if controlDbName != "" and controlDbName in list(usedDbs.keys()): self.__controlUriDb = usedDbs[controlDbName] self.changedSignal.emit()
def processAlgorithm(self, progress): vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT2)) ignoreNull = self.getParameterValue(Intersection.IGNORE_NULL) geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType( vlayerA.wkbType())) fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, geomType, vlayerA.crs()) outFeat = QgsFeature() index = vector.spatialindex(vlayerB) selectionA = vector.features(vlayerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): progress.setPercentage(int(current * total)) geom = inFeatA.geometry() if not geom: if ignoreNull: continue else: raise GeoAlgorithmExecutionException( self.tr('Input layer A contains NULL geometries. ' 'Please check "Ignore NULL geometries" ' 'if you want to run this algorithm anyway.')) if not geom.isGeosValid(): raise GeoAlgorithmExecutionException( self.tr('Input layer A contains invalid geometries ' '(feature {}). Unable to complete intersection ' 'algorithm.'.format(inFeatA.id()))) atMapA = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) for inFeatB in vlayerB.getFeatures( QgsFeatureRequest().setFilterFids(intersects)): tmpGeom = QgsGeometry(inFeatB.geometry()) if not geom: if ignoreNull: continue else: raise GeoAlgorithmExecutionException( self.tr( 'Input layer B contains NULL geometries. ' 'Please check "Ignore NULL geometries" ' 'if you want to run this algorithm anyway.')) if not geom.isGeosValid(): raise GeoAlgorithmExecutionException( self.tr( 'Input layer B contains invalid geometries ' '(feature {}). Unable to complete intersection ' 'algorithm.'.format(inFeatB.id()))) if geom.intersects(tmpGeom): atMapB = inFeatB.attributes() int_geom = QgsGeometry(geom.intersection(tmpGeom)) if int_geom.wkbType( ) == QGis.WKBUnknown or QgsWKBTypes.flatType( int_geom.geometry().wkbType( )) == QgsWKBTypes.GeometryCollection: int_com = geom.combine(tmpGeom) int_geom = QgsGeometry() if int_com is not None: int_sym = geom.symDifference(tmpGeom) if int_sym: diff_geom = int_com.difference(int_sym) int_geom = QgsGeometry(diff_geom) if int_geom.isGeosEmpty() or not int_geom.isGeosValid(): raise GeoAlgorithmExecutionException( self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) try: if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[ int_geom.wkbType()]]: outFeat.setGeometry(int_geom) attrs = [] attrs.extend(atMapA) attrs.extend(atMapB) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: raise GeoAlgorithmExecutionException( self.tr('Feature geometry error: one or ' 'more output features ignored due ' 'to invalid geometry.')) del writer
def spatialInfo(self): ret = [] if not self.table.geomType: return ret tbl = [ (QApplication.translate("DBManagerPlugin", "Column:"), self.table.geomColumn), (QApplication.translate("DBManagerPlugin", "Geometry:"), self.table.geomType), (QApplication.translate("DBManagerPlugin", "QGis Geometry type:"), QGis.featureType(self.table.wkbType)) ] # only if we have info from geometry_columns if self.table.geomDim: tbl.append( (QApplication.translate( "DBManagerPlugin", "Dimension:"), self.table.geomDim)) srid = self.table.srid if self.table.srid else -1 if srid != -1: sr_info = ( self.table.database().connector.getSpatialRefInfo(srid)) else: sr_info = QApplication.translate("DBManagerPlugin", "Undefined") if sr_info: tbl.append( (QApplication.translate( "DBManagerPlugin", "Spatial ref:"), u"{0} ({1})".format(sr_info, srid))) # estimated extent if not self.table.estimatedExtent: # estimated extent information is not displayed yet, so just block # table signals to avoid double refreshing # (infoViewer->refreshEstimatedExtent->tableChanged->infoViewer) self.table.blockSignals(True) self.table.refreshTableEstimatedExtent() self.table.blockSignals(False) if self.table.estimatedExtent: estimated_extent_str = (u"{:.9f}, {:.9f} - {:.9f}, " u"{:.9f}".format( *self.table.estimatedExtent)) tbl.append( (QApplication.translate( "DBManagerPlugin", "Estimated extent:"), estimated_extent_str)) # extent extent_str = None if self.table.extent and len(self.table.extent) == 4: extent_str = (u"{:.9f}, {:.9f} - {:.9f}, " u"{:.9f}".format(*self.table.extent)) elif self.table.rowCount > 0 or self.table.estimatedRowCount > 0: # Can't calculate an extent on empty layer extent_str = QApplication.translate( "DBManagerPlugin", '(unknown) (<a href="action:extent/get">find out</a>)') if extent_str: tbl.append( (QApplication.translate( "DBManagerPlugin", "Extent:"), extent_str)) ret.append(HtmlTable(tbl)) # Handle extent update metadata if (self.table.extent and self.table.extent != self.table.estimatedExtent and self.table.canUpdateMetadata()): ret.append( HtmlParagraph( QApplication.translate( "DBManagerPlugin", (u'<warning> Metadata extent is different from' u'real extent. You should <a href="action:extent' u'/update">update it</a>!')))) # is there an entry in geometry_columns? if self.table.geomType.lower() == 'geometry': ret.append( HtmlParagraph( QApplication.translate( "DBManagerPlugin", "<warning> There is no entry in geometry_columns!"))) # find out whether the geometry column has spatial index on it if not self.table.isView: if not self.table.hasSpatialIndex(): ret.append( HtmlParagraph( QApplication.translate( "DBManagerPlugin", (u'<warning> No spatial index defined (<a href=' u'"action:spatialindex/create">' u'create it</a>).')))) return ret
def to_feature_data(layerid, feature, renderer, transform): """ Transform the feature into the data for the viewer to use. :param feature: QgsFeature :param renderer: :param transform: :return: """ def polylinenodes(polyline): nodes = [] for point in polyline: point = transform.transform(point, QgsCoordinateTransform.ReverseTransform) location = dict(lat=point.y(), lng=point.x()) nodes.append(location) return nodes geom = feature.geometry() geomtype = geom.type() featuredata = [] data = dict( id=feature.id(), layerid=layerid, color=get_color(renderer, feature), geomtype=QGis.vectorGeometryType(geomtype) ) if geomtype == QGis.Point: geom = geom.asPoint() point = transform.transform(geom, QgsCoordinateTransform.ReverseTransform) try: z = feature["Z"] if not z: z = 0 except KeyError: z = 0 location = dict(lat=point.y(), lng=point.x(), z=z) data["nodes"] = [location] featuredata.append(data) elif geomtype == QGis.Line: if geom.isMultipart(): # Copy the data for each polyline for polyline in geom.asMultiPolyline(): newdata = copy.copy(data) newdata["nodes"] = polylinenodes(polyline) featuredata.append(newdata) else: data["nodes"] = polylinenodes(geom.asPolyline()) featuredata.append(data) return featuredata
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(Difference.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(Difference.OVERLAY)) ignoreInvalid = self.getParameterValue(Difference.IGNORE_INVALID) geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(layerA.wkbType())) writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter( layerA.pendingFields(), geomType, layerA.crs()) outFeat = QgsFeature() index = vector.spatialindex(layerB) selectionA = vector.features(layerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): add = True geom = QgsGeometry(inFeatA.geometry()) diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) for i in intersections: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) if diff_geom.isGeosEmpty(): ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Feature with NULL geometry found.')) if not diff_geom.isGeosValid(): if ignoreInvalid: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self. tr('GEOS geoprocessing error: One or more input features have invalid geometry.' )) add = False else: raise GeoAlgorithmExecutionException( self. tr('Features with invalid geometries found. Please fix these errors or specify the "Ignore invalid input features" flag' )) break if add: try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) continue progress.setPercentage(int(current * total)) del writer
def processEllipse(self, layer, outname, semimajorcol, semiminorcol, orientcol, unitOfMeasure, defSemiMajor, defSemiMinor, defOrientation): measureFactor = 1.0 # The ellipse calculation is done in Nautical Miles. This converts # the semi-major and minor axis to nautical miles if unitOfMeasure == 2: # Nautical Miles measureFactor = 1.0 elif unitOfMeasure == 0: # Kilometers measureFactor = QGis.fromUnitToUnitFactor( QGis.Meters, QGis.NauticalMiles) * 1000.0 elif unitOfMeasure == 1: # Meters measureFactor = QGis.fromUnitToUnitFactor(QGis.Meters, QGis.NauticalMiles) elif unitOfMeasure == 3: # Miles measureFactor = QGis.fromUnitToUnitFactor( QGis.Feet, QGis.NauticalMiles) * 5280.0 elif unitOfMeasure == 4: # Feet measureFactor = QGis.fromUnitToUnitFactor(QGis.Feet, QGis.NauticalMiles) fields = layer.pendingFields() self.polygonLayer = QgsVectorLayer("Polygon?crs=epsg:4326", outname, "memory") ppolygon = self.polygonLayer.dataProvider() ppolygon.addAttributes(fields) self.polygonLayer.updateFields() iter = layer.getFeatures() num_features = 0 num_good = 0 for feature in iter: num_features += 1 try: if semimajorcol != -1: semi_major = float(feature[semimajorcol]) else: semi_major = defSemiMajor if semiminorcol != -1: semi_minor = float(feature[semiminorcol]) else: semi_minor = defSemiMinor if orientcol != -1: orient = float(feature[orientcol]) else: orient = defOrientation pt = feature.geometry().asPoint() # make sure the coordinates are in EPSG:4326 pt = self.transform.transform(pt.x(), pt.y()) geom = LatLon.getEllipseCoords(pt.y(), pt.x(), semi_major * measureFactor, semi_minor * measureFactor, orient) featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromPolygon([geom])) featureout.setAttributes(feature.attributes()) ppolygon.addFeatures([featureout]) num_good += 1 except: # Just skip any lines that are badly formed pass self.polygonLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(self.polygonLayer) self.iface.messageBar().pushMessage( "", "{} Ellipses created from {} records".format( num_good, num_features), level=QgsMessageBar.INFO, duration=3)