def writeMeshShapefile(mesh, fileName, crs=None): try: os.remove(fileName) except OSError: pass fields = { 0: qgis.QgsField("ID", pyqt.QVariant.Int), 1: qgis.QgsField("Marker", pyqt.QVariant.Int), 2: qgis.QgsField("Node1", pyqt.QVariant.Int), 3: qgis.QgsField("Node2", pyqt.QVariant.Int), 4: qgis.QgsField("Node3", pyqt.QVariant.Int) } writer = qgis.QgsVectorFileWriter(fileName, "utf-8", fields, qgis.QGis.WKBPolygon, crs, "ESRI Shapefile") if writer.hasError() != qgis.QgsVectorFileWriter.NoError: print "Error when creating shapefile: ", writer.hasError() for index, triangle in enumerate(mesh.elements): nodeIDs = triangle[1] coordinates = mesh.nodes.coordinates[nodeIDs] fet = qgis.QgsFeature() fet.setGeometry( qgis.QgsGeometry.fromPolygon([[ qgis.QgsPoint(*coordinates[0]), qgis.QgsPoint(*coordinates[1]), qgis.QgsPoint(*coordinates[2]) ]])) fet.addAttribute(0, pyqt.QVariant(index)) fet.addAttribute(1, pyqt.QVariant(1)) fet.addAttribute(2, pyqt.QVariant(1)) writer.addFeature(fet)
def writeFractureShapefile(fractures, fileName, crs=None): try: os.remove(fileName) except OSError: pass fields = { 0: qgis.QgsField("ID", pyqt.QVariant.Int), 1: qgis.QgsField("Aperture", pyqt.QVariant.Double) } writer = qgis.QgsVectorFileWriter(fileName, "utf-8", fields, qgis.QGis.WKBLineString, crs, "ESRI Shapefile") if writer.hasError() != qgis.QgsVectorFileWriter.NoError: print "Error when creating shapefile: ", writer.hasError() for index, fracture in enumerate(fractures): feat = qgis.QgsFeature() feat.setGeometry( qgis.QgsGeometry.fromPolyline([ qgis.QgsPoint(fracture[0], fracture[1]), qgis.QgsPoint(fracture[2], fracture[3]) ])) # feat.addAttribute(0, pyqt.QVariant(index)) # feat.addAttribute(1, pyqt.QVariant(1)) # feat.addAttribute(2, pyqt.QVariant(1)) writer.addFeature(feat) # delete the writer to flush features to disk (optional) del writer
def selectGeometry(self, geometry, mode=0, label="", toggleRendering=True): """Add the given geometry to the selection. Parameters ---------- geometry : QGisCore.QgsGeometry Geometry to add to the selection. mode : int, optional Mode to use for the selected geometry. Defaults to 0. label : str, optional Label to use for the selected geometry. Defaults to an empty label. toggleRendering : boolean, optional Redraw the map after changing the tempLayer. Defaults to True. When making multiple changes to the selection set only the last change to toggleRendering=`True` for improved performance. """ if not self.__getLayer(): return f = QGisCore.QgsFeature() f.fields().append(QGisCore.QgsField( 'mode', QtCore.QVariant.Int, 'int', 1, 0)) f.fields().append(QGisCore.QgsField( 'label', QtCore.QVariant.String, 'string', 1, 0)) f.setGeometry(geometry) f.setAttributes([mode, label]) self.main.iface.mapCanvas().setRenderFlag(False) self.layer.addFeature(f) if toggleRendering: self.main.iface.mapCanvas().setRenderFlag(True)
def pointBuffer(self,p): infoLayer = self.infoBoxManager.getInfolayer() toInfoLayerProjection = core.QgsCoordinateTransform(self.iface.mapCanvas().mapSettings().destinationCrs(),infoLayer.crs(), core.QgsProject.instance()) toWGS84 = core.QgsCoordinateTransform(infoLayer.crs(),core.QgsCoordinateReferenceSystem(4326), core.QgsProject.instance()) # create layer and replicate fields bufferLayer = core.QgsVectorLayer("Point?crs="+infoLayer.crs().toWkt(), "temporary_points", "memory") #bufferLayer.setCrs(infoLayer.crs()) #This generates alert message bufferLayer.startEditing() bufferLayer.addAttribute(core.QgsField("id",QtCore.QVariant.String)) bufferLayer.addAttribute(core.QgsField("html",QtCore.QVariant.String)) bufferLayer.addAttribute(core.QgsField("icon",QtCore.QVariant.String)) bufferLayer.addAttribute(core.QgsField("fid",QtCore.QVariant.Int)) self.enableControlShape(toInfoLayerProjection.transform(core.QgsPointXY(p))) fetched = 0 self.featsId = self.infoBoxManager.getContextFeatures(toInfoLayerProjection.transform(p)) for featId in self.featsId: feat = infoLayer.getFeatures(core.QgsFeatureRequest(featId)).__next__() if fetched < 200: if infoLayer.geometryType() == core.QgsWkbTypes.PolygonGeometry: fGeom = feat.geometry().pointOnSurface() elif infoLayer.geometryType() == core.QgsWkbTypes.PointGeometry: fGeom = feat.geometry() if fGeom.isMultipart(): multipoint = fGeom.asMultiPoint() point = multipoint[0] else: point = fGeom.asPoint() fetched += 1 newGeom = core.QgsGeometry.fromPointXY(core.QgsPointXY(point)) newFeat = core.QgsFeature() newFeat.setGeometry(newGeom) newFeat.setAttributes([self.infoBoxManager.getInfoField(feat),self.infoBoxManager.getHtml(feat),self.infoBoxManager.getIconPath(feat),self.infoBoxManager.getFeatId(feat)]) bufferLayer.addFeature(newFeat) else: core.QgsMessageLog.logMessage("fetched too much features..... 200 max", tag="go2streetview", level=core.Qgis.Warning) break bufferLayer.commitChanges() core.QgsMessageLog.logMessage("markers context rebuilt", tag="go2streetview", level=core.Qgis.Info) #StreetView markers tmpfile = os.path.join(self.dirPath,"tmp","tmp_markers.geojson") core.QgsVectorFileWriter.writeAsVectorFormat (bufferLayer, tmpfile,"UTF8",toWGS84,"GeoJSON") with open(tmpfile) as f: geojson = f.read().replace('\n','') os.remove(tmpfile) #js = geojson.replace("'",'') #js = js.replace("\n",'\n') js = """this.markersJson = %s""" % json.dumps(geojson) self.view.SV.page().mainFrame().evaluateJavaScript(js) self.view.BE.page().mainFrame().evaluateJavaScript(js) js = """this.readJson() """ self.view.SV.page().mainFrame().evaluateJavaScript(js) self.view.BE.page().mainFrame().evaluateJavaScript(js) core.QgsMessageLog.logMessage("webview markers refreshed", tag="go2streetview", level=core.Qgis.Info)
def gerarMapaDeValores(self, lyrModelo, lyrDestino): camposIndex = lyrModelo.attributeList() for index in camposIndex: if lyrModelo.editorWidgetV2(index) in [u'ValueMap']: lyrDestino.setEditorWidgetV2(index, lyrModelo.editorWidgetV2(index)) lyrDestino.setEditorWidgetV2Config(index, lyrModelo.valueMap(index)) if lyrDestino.geometryType() == 1: lyrDestino.addExpressionField( '$length', core.QgsField(u'Comprimento', QtCore.QVariant.Double)) elif lyrDestino.geometryType() == 2: lyrDestino.addExpressionField( '$area', core.QgsField(u'Área', QtCore.QVariant.Double))
def __getLayer(self): """Find the QgsVectorLayer based on its name and add two attributes. Adds two attributes 'mode' (int) and 'label' (str). Mode is to differentiate between various selection modes (f. ex. using a different style). Label is to be able to show a label for selected features. """ if not self.layer: self.layer = self.utils.getLayerByName(self.layerName) if self.layer: self.layer.startEditing() self.layer.addAttribute(QGisCore.QgsField( 'mode', QtCore.QVariant.Int, 'int', 1, 0)) self.layer.addAttribute(QGisCore.QgsField( 'label', QtCore.QVariant.String, 'string', 1, 0)) self.layer.commitChanges() self.layer.endEditCommand() return self.layer
def processAlgorithm(self, parameters, context, feedback): inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) attributeName = self.parameterAsFile(parameters, self.ATTRIBUTE_NAME, context) spellchecker = SpellCheckerCtrl('pt-BR') errors = [] output_dest_id = '' listSize = len(inputLyrList) progressStep = 100 / listSize if listSize else 0 errorFieldName = '{}_erro'.format(attributeName) #field = core.QgsField('{}_erro'.format(attributeName)) fieldRelation = core.QgsField('id', QVariant.Double) for step, layer in enumerate(inputLyrList): if not layer.isEditable(): raise Exception( 'Todas as camadas de entrada devem está com a edição ativa!' ) attributeIndex = self.getAttributeIndex(attributeName, layer) if attributeIndex < 0: continue auxlayer = core.QgsAuxiliaryStorage().createAuxiliaryLayer( fieldRelation, layer) layer.setAuxiliaryLayer(auxlayer) auxLayer = layer.auxiliaryLayer() vdef = core.QgsPropertyDefinition( errorFieldName, core.QgsPropertyDefinition.DataType.DataTypeString, "", "", "") auxLayer.addAuxiliaryField(vdef) idx = layer.fields().indexOf( 'auxiliary_storage__{}'.format(errorFieldName)) layer.setFieldAlias(idx, errorFieldName) auxFields = auxLayer.fields() for feature in layer.getFeatures(): if feedback.isCanceled(): return {self.OUTPUT: output_dest_id} attributeValue = feature[attributeIndex] if not attributeValue: continue attributeValue = ''.join( e for e in attributeValue if not (e in [',', ';', '&', '.'] or e.isdigit())) wordlist = re.split(' |/', attributeValue) wordlist = [w for w in wordlist if not w in ['-']] wrongWords = [ word for word in wordlist if not spellchecker.hasWord(word.lower()) ] if len(wrongWords) == 0: continue auxFeature = QgsFeature(auxFields) auxFeature['ASPK'] = feature['id'] auxFeature['_{}'.format(errorFieldName)] = ';'.join(wrongWords) auxLayer.addFeature(auxFeature) feedback.setProgress(step * progressStep) return {self.OUTPUT: ''}
def createShapefile(self, path): fields = core.QgsFields() fields.append(core.QgsField("date", QtCore.QVariant.String)) fields.append(core.QgsField("lon", QtCore.QVariant.String)) fields.append(core.QgsField("lat", QtCore.QVariant.String)) fields.append(core.QgsField("heading", QtCore.QVariant.String)) fields.append(core.QgsField("pitch", QtCore.QVariant.String)) fields.append(core.QgsField("address", QtCore.QVariant.String)) fields.append(core.QgsField("notes", QtCore.QVariant.String)) fields.append(core.QgsField("url", QtCore.QVariant.String, len=250)) srs = core.QgsCoordinateReferenceSystem() srs.createFromProj4("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs") writer = core.QgsVectorFileWriter(path, "ISO 8859-1", fields, core.QgsWkbTypes.Point, srs, "ESRI Shapefile") del writer
10001: [125, 315, 500], 35001: [200, 500, 800], 150001: [315, 800, 1250], 500001: [500, 1250, 2000] } xmin, ymin, xmax, ymax = lyrInput.extent().toRectF().getCoords() gridWidth = Tamanho_da_celula_da_grade gridHeight = Tamanho_da_celula_da_grade rows = ceil((ymax - ymin) / gridHeight) cols = ceil((xmax - xmin) / gridWidth) ringXleftOrigin = xmin ringXrightOrigin = xmin + gridWidth ringYtopOrigin = ymax ringYbottomOrigin = ymax - gridHeight fields = [QgsCore.QgsField("id", QtCore.QVariant.Int)] lyrOutput = VectorWriter(Areas_de_Inspecao, None, fields, QgsCore.QGis.WKBPolygon, lyrInput.crs()) lyrIntermediate = QgsCore.QgsVectorLayer("Polygon", "temporary_polygons", "memory") lyrIntermediate.setCrs(lyrInput.crs()) id = 1 progress.setInfo("Gerando grade de cobertura da camada...") progress.setInfo("Numero de linhas: " + str(rows)) progress.setInfo("Numero de colunas: " + str(cols)) for i in range(int(cols)): ringYtop = ringYtopOrigin ringYbottom = ringYbottomOrigin
def lineBuffer(self,p,polygons = None): dBuffer = self.infoBoxManager.getDistanceBuffer() infoLayer = self.infoBoxManager.getInfolayer() toInfoLayerProjection = core.QgsCoordinateTransform(self.iface.mapCanvas().mapSettings().destinationCrs(),infoLayer.crs(), core.QgsProject.instance()) toWGS84 = core.QgsCoordinateTransform(infoLayer.crs(),core.QgsCoordinateReferenceSystem(4326), core.QgsProject.instance()) # create layer and replicate fields bufferLayer = core.QgsVectorLayer("LineString?crs="+infoLayer.crs().toWkt(), "temporary_lines", "memory") #bufferLayer.setCrs(infoLayer.crs()) #This generates alert message bufferLayer.startEditing() bufferLayer.addAttribute(core.QgsField("id",QtCore.QVariant.String)) bufferLayer.addAttribute(core.QgsField("html",QtCore.QVariant.String)) bufferLayer.addAttribute(core.QgsField("icon",QtCore.QVariant.String)) bufferLayer.addAttribute(core.QgsField("fid",QtCore.QVariant.Int)) fetched = 0 cutBuffer = core.QgsGeometry.fromPointXY(toInfoLayerProjection.transform(core.QgsPointXY(p))).buffer(dBuffer*2,10) self.enableControlShape(toInfoLayerProjection.transform(core.QgsPointXY(p))) if not polygons: self.featsId = self.infoBoxManager.getContextFeatures(toInfoLayerProjection.transform(p)) for featId in self.featsId: feat = infoLayer.getFeatures(core.QgsFeatureRequest(featId)).__next__() if fetched < 1500: if infoLayer.geometryType() == core.QgsWkbTypes.PolygonGeometry: fGeom = feat.geometry().convertToType(core.QgsWkbTypes.LineGeometry) elif infoLayer.geometryType() == core.QgsWkbTypes.LineGeometry: fGeom = feat.geometry() if fGeom: #break on closest point on segment to pov to improve visibility closestResult = fGeom.closestSegmentWithContext(toInfoLayerProjection.transform(p)); fGeom.insertVertex(closestResult[1][0],closestResult[1][1],closestResult[2]) cGeom = fGeom.intersection(cutBuffer) if cGeom.isMultipart(): multigeom = cGeom.asMultiPolyline() for geom in multigeom: newGeom = core.QgsGeometry.fromPolylineXY(geom) newFeat = core.QgsFeature() newFeat.setGeometry(newGeom) newFeat.setAttributes([self.infoBoxManager.getInfoField(feat),self.infoBoxManager.getHtml(feat),self.infoBoxManager.getIconPath(feat),self.infoBoxManager.getFeatId(feat)]) bufferLayer.addFeature(newFeat) else: geom = cGeom.asPolyline() newGeom = core.QgsGeometry.fromPolylineXY(geom) newFeat = core.QgsFeature() newFeat.setGeometry(newGeom) newFeat.setAttributes([self.infoBoxManager.getInfoField(feat),self.infoBoxManager.getHtml(feat),self.infoBoxManager.getIconPath(feat),self.infoBoxManager.getFeatId(feat)]) bufferLayer.addFeature(newFeat) fetched = fetched + len(newGeom.asPolyline()) else: core.QgsMessageLog.logMessage("Null geometry!", tag="go2streetview", level=core.Qgis.Warning) else: core.QgsMessageLog.logMessage("fetched too much features..... 200 max", tag="go2streetview", level=core.Qgis.Warning) break bufferLayer.commitChanges() core.QgsMessageLog.logMessage("line context rebuilt: %s features" % bufferLayer.featureCount(), tag="go2streetview", level=core.Qgis.Info) #StreetView lines tmpfile = os.path.join(self.dirPath, "tmp", "tmp_lines.geojson") core.QgsVectorFileWriter.writeAsVectorFormat(bufferLayer, tmpfile,"UTF8", toWGS84, "GeoJSON") with open(tmpfile) as f: geojson = f.read().replace('\n', '') os.remove(tmpfile) js = """this.linesJson = %s""" % json.dumps(geojson) self.view.SV.page().mainFrame().evaluateJavaScript(js) self.view.BE.page().mainFrame().evaluateJavaScript(js) js = """this.readLinesJson() """ self.view.SV.page().mainFrame().evaluateJavaScript(js) self.view.BE.page().mainFrame().evaluateJavaScript(js) core.QgsMessageLog.logMessage("webview lines refreshed", tag="go2streetview", level=core.Qgis.Info)
def __init__(self, iface): QtGui.QDialog.__init__(self) self.iface = iface # Set up the user interface from Designer. self.ui = Ui_MeshToolsPlugin() self.ui.setupUi(self) self.ui.cbAlgorithm.addItems(['EasyMesh', 'Triangle', 'Netgen']) self.ui.cbAlgorithm.setCurrentIndex(1) if (platform.system() == 'Windows'): self.ui.cbAlgorithm.setEnabled(False) #self.ui.cbPolygons.currentIndexChanged.connect( # lambda: mtp.setAttributeComboBox(self, self.ui.cbLength)) # Trigger repopulation of attribute comboboxes with changes layer comboboxes self.ui.cbBoundaryPolygons.currentIndexChanged.connect( self.populateAttributeComboBoxes) self.ui.cbPolygons.currentIndexChanged.connect( self.populateAttributeComboBoxes) self.ui.cbLines.currentIndexChanged.connect( self.populateAttributeComboBoxes) self.ui.cbPoints.currentIndexChanged.connect( self.populateAttributeComboBoxes) self.ui.cbTriangleRefinementPoints.currentIndexChanged.connect( self.populateTriangleComboBox) self.ui.cbPolygons.currentIndexChanged.emit(0) self.ui.pbGenerate.clicked.connect(self.generateMesh) self.ui.pbTriangleNewPoints.clicked.connect( lambda: self.createNewLayer( qgis.QGis.WKBPoint, self.ui.cbTriangleBoundaryPoints, {0: qgis.QgsField("Element Area", QtCore.QVariant.Double)})) self.ui.pbTriangleNewPolygons.clicked.connect( lambda: self.createNewLayer( qgis.QGis.WKBPolygon, self.ui.cbTriangleBoundaryPolygons, {0: qgis.QgsField("Element Area", QtCore.QVariant.Double)})) self.ui.pbTriangleNewLines.clicked.connect(lambda: self.createNewLayer( qgis.QGis.WKBLineString, self.ui.cbTriangleBoundaryLines, {0: qgis.QgsField("Element Area", QtCore.QVariant.Double)})) self.ui.pbTriangleRefinementNewPoints.clicked.connect( lambda: self.createNewLayer( qgis.QGis.WKBPoint, self.ui.cbTriangleRefinementPoints, {0: qgis.QgsField("Element Area", QtCore.QVariant.Double)})) self.ui.pbNewPolygons.clicked.connect(lambda: self.createNewLayer( qgis.QGis.WKBPolygon, self.ui.cbPolygons, { 0: qgis.QgsField("Edge Length", QtCore.QVariant.Double), 1: qgis.QgsField("Edge Type", QtCore.QVariant.Double) })) self.ui.pbNewLines.clicked.connect(lambda: self.createNewLayer( qgis.QGis.WKBLineString, self.ui.cbLines, { 0: qgis.QgsField("Edge Length", QtCore.QVariant.Double), 1: qgis.QgsField("Edge Type", QtCore.QVariant.Double) })) self.ui.pbNewPoints.clicked.connect(lambda: self.createNewLayer( qgis.QGis.WKBPoint, self.ui.cbPoints, { 0: qgis.QgsField("Edge Length", QtCore.QVariant.Double), 1: qgis.QgsField("Edge Type", QtCore.QVariant.Double) })) self.ui.pbNewBoundaryPolygons.clicked.connect( lambda: self.createNewLayer( qgis.QGis.WKBPolygon, self.ui.cbBoundaryPolygons, { 0: qgis.QgsField("Edge Length", QtCore.QVariant.Double), 1: qgis.QgsField("Edge Type", QtCore.QVariant.Double) }))
funcExist = existNodeCheckFid populateListFidNode(fid, line, l_fid_node, funcExist) # Remove Exists nodes for id in reversed(xrange(len(l_fid_node))): if l_fid_node[id]['exists']: l_fid_node.pop(id) # Remove nodes with same FID line ids_remove = [] for id in xrange(len(l_fid_node) - 1): fid1, fid2 = l_fid_node[id]['fid'], l_fid_node[id + 1]['fid'] if fid1 == fid2: ids_remove.append(id) ids_remove.append(id + 1) ids_remove.reverse() for id in ids_remove: l_fid_node.pop(id) # Output fields = [QgsCore.QgsField("fid_line", QtCore.QVariant.Int)] lyrSource = VectorWriter(Nascentes, None, fields, QgsCore.QGis.WKBPoint, lyrRiver.crs()) for fn in l_fid_node: feat = QgsCore.QgsFeature() feat.setAttributes([fn['fid']]) feat.setGeometry(QgsCore.QgsGeometry.fromPoint(fn['node'])) lyrSource.addFeature(feat) del feat del lyrSource
class LatLonGridLayer (core.QgsPluginLayer): LAYER_TYPE = 'LatLonGrid' _featuremap = { 0: core.QgsField('angle', QtCore.QVariant.Double, 'double', 8, 4), 1: core.QgsField('ordinate', QtCore.QVariant.String, 'string', 32), 2: core.QgsField('alignment', QtCore.QVariant.String, 'string', 8), 3: core.QgsField('offset_x', QtCore.QVariant.Double, 'double', 8, 4), 4: core.QgsField('offset_y', QtCore.QVariant.Double, 'double', 8, 4) } def __init__(self): core.QgsPluginLayer.__init__(self, LatLonGridLayer.LAYER_TYPE, 'Lat/Lon grid overlay') self.setValid(True) self.parent_layer_name = "" self.parent_layer_id = "" #dialog self.dlg = LatLonGridDialog(self) # connect slot for parent removal QgsMapLayerRegistry.instance().layerRemoved.connect(self.RemovingParentSlot) # use dialog boxes or status self.use_dialogs = False # grid itlesf self.ll_grid = [] # step size in decimal degrees self.step = 0.01 #labels positions self.labels_S = [] self.labels_N = [] self.labels_W = [] self.labels_E = [] # label to draw #fields = QgsFields() #self.label = core.QgsLabel(fields) #self.label = core.QgsLabel(LatLonGridLayer._featuremap) #eature.setAttribute(core.QgsLabel.Text, "sasasas") self.fields = QgsFields() self.label = QgsLabel(self.fields) #self.label.labelAttributes().setText('test label') self.label_features = [] #self.label.labelAttributes().setOffset(-8.66774, 37.08391, 0) #self.feat.setAttribute(0,'Test Text') #self.feat.setAttribute('8', -8.66774) #self.feat.setAttribute('9', 37.08391) def showDialog(self): # test if layers are available nLayers = 0 for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems(): if layer.type() == QgsMapLayer.PluginLayer : continue nLayers += 1 if nLayers == 0 : text = "No layers avalaible to create Lat/Lon grid.\nOnly vector and raster layers can be used.\n\n Please add layers to QGIS project!" if self.use_dialogs : QtGui.QMessageBox.information(None,'Warning', text, QMessageBox.Ok) else : qgis.utils.iface.messageBar().pushMessage("Warning", text, QgsMessageBar.WARNING, 5) self.setValid(False) return # see if on the fly projection is enabled is_defined = QgsProject.instance().readEntry("SpatialRefSys", "/ProjectionsEnabled")[1] if not is_defined or int(QgsProject.instance().readEntry("SpatialRefSys", "/ProjectionsEnabled")[0]) == 0: if self.use_dialogs : QtGui.QMessageBox.information(None,'Cannot add lat/lon grid', """Lat/Lon grid alsways uses geograhical coordinates.\n\nPlease enable projection 'on the fly' CRS transformation in project settings!""", QMessageBox.Ok) else : qgis.utils.iface.messageBar().pushMessage("Cannot add lat/lon grid", """Lat/Lon grid alsways uses geograhical coordinates.\n\nPlease enable projection 'on the fly' CRS transformation in project settings!""", QgsMessageBar.WARNING, 5) self.setValid(False) return self.get_layer_name_by_id() self.dlg.show() result = self.dlg.exec_() if result == 1: self.get_layer_id_by_name() #self.generateGrid() self.setValid(True) self.setLatLonGridCrsAndExtent() self.generateLatLonGrid() self.setCacheImage(None) self.emit(QtCore.SIGNAL('repaintRequested()')) else: self.setValid(False) def draw(self, renderContext): if self.CheckLayerExtent() == False : self.setLatLonGridCrsAndExtent() self.generateLatLonGrid() mapToPixel = renderContext.mapToPixel() proj = core.QgsProject.instance() # Default CRS: 3452 == EPSG:4326 srid = proj.readNumEntry('SpatialRefSys', '/ProjectCRSID', 3452)[0] crs = core.QgsCoordinateReferenceSystem(srid, core.QgsCoordinateReferenceSystem.InternalCrsId) xform = core.QgsCoordinateTransform(self.crs(), crs) self.dlg.symbol.startRender(renderContext) for line in self.ll_grid: polyline = QtGui.QPolygonF() for vertex in line: end = mapToPixel.transform(xform.transform(vertex)) polyline.append(QtCore.QPointF(end.x(), end.y())) if QGis.QGIS_VERSION_INT < 10800: self.dlg.symbol.renderPolyline(polyline, renderContext) else: self.dlg.symbol.renderPolyline(polyline, None, renderContext) if QGis.QGIS_VERSION_INT > 20200 : self.drawLabels(renderContext) self.dlg.symbol.stopRender(renderContext) return True def drawLabels(self, renderContext): self.label.setLabelField(QgsLabel.Text,QgsLabel.Text) self.label.setLabelField(QgsLabel.Angle,QgsLabel.Angle) self.label.setLabelField(QgsLabel.Alignment,QgsLabel.Alignment) self.label.setLabelField(QgsLabel.XOffset,QgsLabel.XOffset) self.label.setLabelField(QgsLabel.YOffset,QgsLabel.YOffset) for feat in self.label_features : self.label.renderLabel(renderContext, feat, False) return def writeXml(self, node, doc): element = node.toElement() element.setAttribute('type', 'plugin') element.setAttribute('name', LatLonGridLayer.LAYER_TYPE); # custom properties gridElement = doc.createElement('latlongrid') gridElement.setAttribute('parent_layer', str(self.parent_layer_id)) gridElement.setAttribute('label_format', str(self.dlg.ui.labels_format.currentIndex())) gridElement.setAttribute('long_spacing', str(self.dlg.ui.long_spacing.value())) gridElement.setAttribute('lat_spacing', str(self.dlg.ui.lat_spacing.value())) gridElement.setAttribute('label_north', str(self.dlg.ui.label_north.isChecked())) gridElement.setAttribute('label_south', str(self.dlg.ui.label_south.isChecked())) gridElement.setAttribute('label_west', str(self.dlg.ui.label_west.isChecked())) gridElement.setAttribute('label_east', str(self.dlg.ui.label_east.isChecked())) gridElement.setAttribute('label_orientation', str(self.dlg.ui.label_orientation.currentIndex())) node.appendChild(gridElement) # write font gridElement = doc.createElement('latlongrid_font') gridElement.setAttribute('farmily', str(self.dlg.label_attributes.family())) gridElement.setAttribute('bold', str(self.dlg.label_attributes.bold())) gridElement.setAttribute('italic', str(self.dlg.label_attributes.italic())) gridElement.setAttribute('underline', str(self.dlg.label_attributes.underline())) gridElement.setAttribute('strikeOut', str(self.dlg.label_attributes.strikeOut())) gridElement.setAttribute('size', str(self.dlg.label_attributes.size())) gridElement.setAttribute('color', str(self.dlg.label_attributes.color().rgba())) node.appendChild(gridElement) self.writeSymbology(node, doc) # write extend gridElement = doc.createElement('latlongrid_extend') gridElement.setAttribute('xmin', str(core.QgsPluginLayer.extent(self).xMinimum())) gridElement.setAttribute('xmax', str(core.QgsPluginLayer.extent(self).xMaximum())) gridElement.setAttribute('ymin', str(core.QgsPluginLayer.extent(self).yMinimum())) gridElement.setAttribute('ymax', str(core.QgsPluginLayer.extent(self).yMaximum())) node.appendChild(gridElement) return True def writeSymbology(self, node, doc): symbolElement = core.QgsSymbolLayerV2Utils.saveSymbol('grid_lines', self.dlg.symbol, doc) node.appendChild(symbolElement) return True def readXml(self, node): element = node.toElement() gridElement = node.firstChildElement('latlongrid') if gridElement is not None: self.parent_layer_id = str(gridElement.attribute('parent_layer')) self.dlg.ui.labels_format.setCurrentIndex(int(gridElement.attribute('label_format'))) self.dlg.ui.long_spacing.setValue(float(gridElement.attribute('long_spacing'))) self.dlg.ui.lat_spacing.setValue(float(gridElement.attribute('lat_spacing'))) self.dlg.ui.label_north.setChecked('True'== gridElement.attribute('label_north', 'False')) self.dlg.ui.label_south.setChecked('True'== gridElement.attribute('label_south', 'False')) self.dlg.ui.label_west.setChecked('True'== gridElement.attribute('label_west', 'False')) self.dlg.ui.label_east.setChecked('True'== gridElement.attribute('label_east', 'False')) self.dlg.ui.label_orientation.setCurrentIndex(int(gridElement.attribute('label_orientation'))) gridElement = node.firstChildElement('latlongrid_font') if gridElement is not None: self.dlg.label_attributes.setFamily(str(gridElement.attribute('farmily'))) self.dlg.label_attributes.setBold('True'== gridElement.attribute('bold', 'False')) self.dlg.label_attributes.setItalic('True'== gridElement.attribute('italic', 'False')) self.dlg.label_attributes.setUnderline('True'== gridElement.attribute('underline', 'False')) self.dlg.label_attributes.setStrikeOut('True'== gridElement.attribute('strikeOut', 'False')) self.dlg.label_attributes.setSize(float(gridElement.attribute('size')), core.QgsLabelAttributes.PointUnits) self.dlg.label_attributes.setColor(QtGui.QColor.fromRgba(int(gridElement.attribute('color')))) self.readSymbology(node) gridElement = node.firstChildElement('latlongrid_extend') if gridElement is not None: rect = QgsRectangle(); rect.setXMinimum(float(gridElement.attribute('xmin'))) rect.setXMaximum(float(gridElement.attribute('xmax'))) rect.setYMinimum(float(gridElement.attribute('ymin'))) rect.setYMaximum(float(gridElement.attribute('ymax'))) self.setExtent(rect); self.generateLatLonGrid() return True def readSymbology(self, node): symbolElement = node.firstChildElement('symbol') if symbolElement is not None and symbolElement.attribute('name') == 'grid_lines': self.dlg.symbol = core.QgsSymbolLayerV2Utils.loadSymbol(symbolElement) self.setCacheImage(None) self.emit(QtCore.SIGNAL('repaintRequested()')) return True else: return False def get_layer_id_by_name(self) : for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems(): if layer.type() == QgsMapLayer.PluginLayer and layer.pluginLayerType() == LatLonGridLayer.LAYER_TYPE : continue if layer.name() == self.parent_layer_name : self.parent_layer_id = layer.id() break def get_layer_name_by_id(self) : for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems(): if layer.type() == QgsMapLayer.PluginLayer and layer.pluginLayerType() == LatLonGridLayer.LAYER_TYPE : continue if layer.id() == self.parent_layer_id : self.parent_layer_name = layer.name() break def RemovingParentSlot(self, parent_id) : try: if parent_id == self.parent_layer_id: text = "Lat/Lon grid layer '" + self.name() + "'\nwas removed because its parent has been removed!" if self.use_dialogs : QtGui.QMessageBox.information(None,'Warning', text, QMessageBox.Ok) else : qgis.utils.iface.messageBar().pushMessage("Warning", text, QgsMessageBar.WARNING, 5) QgsMapLayerRegistry.instance().removeMapLayer(self.id()) except: print "No layer exists..." def get_parent_layer(self, parent_layer): for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems(): if layer.type() == QgsMapLayer.PluginLayer and layer.pluginLayerType() == LatLonGridLayer.LAYER_TYPE : continue if layer.id() == self.parent_layer_id : parent_layer = layer return True return False def setLatLonGridCrsAndExtent(self) : layer = QgsMapLayerRegistry.instance().mapLayer(self.parent_layer_id) # for vector layers if layer.type() == QgsMapLayer.VectorLayer : layer.updateExtents() if layer == None : text = "Cannot get parent layer for Lat/Lon grid !\nLat/Lon CRS not set!" QtGui.QMessageBox.information(None,'Warning', text, QMessageBox.Ok) return if layer.crs().geographicFlag() == False: # deal with projected CRS geo_system = QgsCoordinateReferenceSystem(layer.crs().geographicCRSAuthId()) core.QgsPluginLayer.setCrs(self, geo_system) transform = QgsCoordinateTransform(layer.crs(), geo_system) core.QgsPluginLayer.setExtent(self, transform.transform(layer.extent())) return # if parent layer is lat/lon CRS, use it core.QgsPluginLayer.setCrs(self, layer.crs()) core.QgsPluginLayer.setExtent(self, layer.extent()) def CheckLayerExtent(self) : layer = QgsMapLayerRegistry.instance().mapLayer(self.parent_layer_id) # for vector layers if layer.type() == QgsMapLayer.VectorLayer : layer.updateExtents() if layer.extent().xMinimum() == core.QgsPluginLayer.extent(self).xMinimum() and \ layer.extent().xMaximum() == core.QgsPluginLayer.extent(self).xMaximum() and \ layer.extent().yMinimum() == core.QgsPluginLayer.extent(self).yMinimum() and \ layer.extent().yMaximum() == core.QgsPluginLayer.extent(self).yMaximum() : return True return False def generateLatLonGrid(self) : self.ll_grid = [] dx = self.dlg.ui.long_spacing.value() dy = self.dlg.ui.lat_spacing.value() x1 = core.QgsPluginLayer.extent(self).xMinimum()/dx y1 = core.QgsPluginLayer.extent(self).yMinimum()/dy x2 = core.QgsPluginLayer.extent(self).xMaximum()/dx y2 = core.QgsPluginLayer.extent(self).yMaximum()/dy #progressMessageBar = self.iface.messageBar().createMessage("Generating Lat/Lon grid...") #progress = QProgressBar() #progress.setMaximum(100) #progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) #progressMessageBar.layout().addWidget(progress) #self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) #i_progress = 0; scale = 1. # x1, y1 x2, y2 in lat / lon, transate in selected units if self.dlg.ui.labels_format.currentIndex() == 1 : # minutes x1 *= 60. y1 *= 60. x2 *= 60. y2 *= 60. scale = 60. elif self.dlg.ui.labels_format.currentIndex() == 2: # seconds x1 *= 3600. y1 *= 3600. x2 *= 3600. y2 *= 3600. scale = 3600. x1 = round(x1) y1 = round(y1) x2 = round(x2) y2 = round(y2) if x2 - x1 > 1000 or y2 - y1 > 1000 : text = "Too many Lat/Lon lines! Cannot update view!" if self.use_dialogs : QtGui.QMessageBox.information(None,'Warning', text, QMessageBox.Ok) else : qgis.utils.iface.messageBar().pushMessage("Warning", text, QgsMessageBar.WARNING, 10) return self.labels_S = [] self.labels_N = [] self.labels_W = [] self.labels_E = [] # horizontal lines if y1 < scale*core.QgsPluginLayer.extent(self).yMinimum()/dy : y1 += 1 if y2 > scale*core.QgsPluginLayer.extent(self).yMaximum()/dy : y2 -= 1 yt = y1 while yt <= y2 : line = [] xt1 = core.QgsPluginLayer.extent(self).xMinimum() i = 1 bContinue = True line.append(core.QgsPoint(xt1, dy*yt/scale)); self.labels_W.append([xt1, (dy*yt/scale)]) while bContinue: xt2 = xt1 + self.step * i if xt2 > core.QgsPluginLayer.extent(self).xMaximum() : xt2 = core.QgsPluginLayer.extent(self).xMaximum() bContinue = False self.labels_E.append([xt2, (dy*yt/scale)]) line.append(core.QgsPoint(xt2, dy*yt/scale)); i += 1 self.ll_grid.append(line) yt += 1 #i_progress += 1 #progress.setValue(i_progress) # vertical lines if x1 < scale*core.QgsPluginLayer.extent(self).xMinimum()/dx : x1 += 1 if x2 > scale*core.QgsPluginLayer.extent(self).xMaximum()/dx : x2 -= 1 xt = x1 while xt <= x2: line = [] yt1 = core.QgsPluginLayer.extent(self).yMinimum() i = 1 bContinue = True line.append(core.QgsPoint(dx*xt/scale, yt1)); self.labels_S.append([(dx*xt/scale), yt1]) while bContinue: yt2 = yt1 + self.step * i if yt2 > core.QgsPluginLayer.extent(self).yMaximum() : yt2 = core.QgsPluginLayer.extent(self).yMaximum() bContinue = False self.labels_N.append([(dx*xt/scale), yt2]) line.append(core.QgsPoint(dx*xt/scale, yt2)); i += 1 self.ll_grid.append(line) xt += 1 #self.iface.messageBar().clearWidgets() self.generateLabels() def generateLabels(self) : self.label.labelAttributes().setFamily(self.dlg.label_attributes.family()) self.label.labelAttributes().setBold(self.dlg.label_attributes.bold()) self.label.labelAttributes().setItalic(self.dlg.label_attributes.italic()) self.label.labelAttributes().setUnderline(self.dlg.label_attributes.underline()) self.label.labelAttributes().setStrikeOut(self.dlg.label_attributes.strikeOut()) self.label.labelAttributes().setSize(self.dlg.label_attributes.size(), core.QgsLabelAttributes.PointUnits) self.label.labelAttributes().setColor(QtGui.QColor.fromRgba(self.dlg.label_attributes.color().rgba())) self.label_features = [] x_digits = 0; a = math.log(float(self.dlg.ui.long_spacing.value()))/math.log(10.) if a < 0 : x_digits = int(round(math.fabs(a))) y_digits = 0; a = math.log(float(self.dlg.ui.lat_spacing.value()))/math.log(10.) if a < 0 : y_digits = int(round(math.fabs(a))) if self.dlg.ui.label_south.isChecked() : for pos in self.labels_S : fields = QgsFields() feat = QgsFeature(fields) feat.initAttributes(QgsLabel.LabelFieldCount) feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(pos[0], pos[1]))) if self.dlg.ui.label_orientation.currentIndex() == 0 : feat.setAttribute(QgsLabel.Angle,90.) feat.setAttribute(QgsLabel.Alignment, 'right') feat.setAttribute(QgsLabel.XOffset, -2) else : feat.setAttribute(QgsLabel.Angle,0.) feat.setAttribute(QgsLabel.Alignment, 'center|top') feat.setAttribute(QgsLabel.Text, convertDMS(pos[0], "EW", self.dlg.ui.labels_format.currentIndex(), x_digits)) self.label_features.append(feat) if self.dlg.ui.label_north.isChecked() : for pos in self.labels_N : fields = QgsFields() feat = QgsFeature(fields) feat.initAttributes(QgsLabel.LabelFieldCount) feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(pos[0], pos[1]))) if self.dlg.ui.label_orientation.currentIndex() == 0 : feat.setAttribute(QgsLabel.Angle,90.) feat.setAttribute(QgsLabel.Alignment, 'left') feat.setAttribute(QgsLabel.XOffset, 2) else : feat.setAttribute(QgsLabel.Angle,0.) feat.setAttribute(QgsLabel.Alignment, 'center|bottom') feat.setAttribute(QgsLabel.YOffset, 2) feat.setAttribute(QgsLabel.Text, convertDMS(pos[0], "EW", self.dlg.ui.labels_format.currentIndex(), x_digits)) self.label_features.append(feat) if self.dlg.ui.label_west.isChecked() : for pos in self.labels_W : fields = QgsFields() feat = QgsFeature(fields) feat.initAttributes(QgsLabel.LabelFieldCount) feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(pos[0], pos[1]))) if self.dlg.ui.label_orientation.currentIndex() == 0 : feat.setAttribute(QgsLabel.Angle,0.) feat.setAttribute(QgsLabel.Alignment, 'right') feat.setAttribute(QgsLabel.XOffset, -2) else : feat.setAttribute(QgsLabel.Angle,90.) feat.setAttribute(QgsLabel.Alignment, 'center|bottom') feat.setAttribute(QgsLabel.YOffset, 2) feat.setAttribute(QgsLabel.Text, convertDMS(pos[1], "NS", self.dlg.ui.labels_format.currentIndex(), y_digits)) self.label_features.append(feat) if self.dlg.ui.label_east.isChecked() : for pos in self.labels_E : fields = QgsFields() feat = QgsFeature(fields) feat.initAttributes(QgsLabel.LabelFieldCount) feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(pos[0], pos[1]))) if self.dlg.ui.label_orientation.currentIndex() == 0 : feat.setAttribute(QgsLabel.Angle,0.) feat.setAttribute(QgsLabel.Alignment, 'left') feat.setAttribute(QgsLabel.XOffset, 2) else : feat.setAttribute(QgsLabel.Angle,90.) feat.setAttribute(QgsLabel.Alignment, 'center|top') feat.setAttribute(QgsLabel.Text, convertDMS(pos[1], "NS", self.dlg.ui.labels_format.currentIndex(),y_digits)) self.label_features.append(feat)