def calculateSquare(self, point): ''' point in layer coordinates(QgsPoint) ''' mapCrs = self.canvas.mapSettings().destinationCrs() utmCrs = QgsCoordinateReferenceSystem() utmCrs.createFromProj4(self.proj4Utm(point)) ctFwd = QgsCoordinateTransform(mapCrs, utmCrs) ctBwd = QgsCoordinateTransform(utmCrs, mapCrs) pointGeom = QgsGeometry.fromPoint(point) pointGeom.transform(ctFwd) pointUtm = QgsPoint(pointGeom.asPoint()) # calculate d d = self.diagonal/(2*(2**0.5)) l = pointUtm.x() - d b = pointUtm.y() - d r = pointUtm.x() + d t = pointUtm.y() + d p1 = QgsGeometry.fromPoint(QgsPoint(l, b)) p2 = QgsGeometry.fromPoint(QgsPoint(r, b)) p3 = QgsGeometry.fromPoint(QgsPoint(r, t)) p4 = QgsGeometry.fromPoint(QgsPoint(l, t)) p1.transform(ctBwd) p2.transform(ctBwd) p3.transform(ctBwd) p4.transform(ctBwd) mapPol = [p1.asPoint(), p2.asPoint(), p3.asPoint(), p4.asPoint(), p1.asPoint()] return mapPol
def testCrsConversion(self): self.assertFalse( GdalUtils.gdal_crs_string(QgsCoordinateReferenceSystem())) self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem('EPSG:3111')), 'EPSG:3111') self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem('POSTGIS:3111')), 'EPSG:3111') self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem( 'proj4: +proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' )), 'EPSG:20936') crs = QgsCoordinateReferenceSystem() crs.createFromProj4( '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' ) self.assertTrue(crs.isValid()) self.assertEqual( GdalUtils.gdal_crs_string(crs), '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' ) # check that newlines are stripped crs = QgsCoordinateReferenceSystem() crs.createFromProj4( '+proj=utm +zone=36 +south\n +a=600000 +b=70000 \r\n +towgs84=-143,-90,-294,0,0,0,0 +units=m\n+no_defs' ) self.assertTrue(crs.isValid()) self.assertEqual( GdalUtils.gdal_crs_string(crs), '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' )
def _create_QGSRasterLayer_with_projection(self, proj_radolan): """ Change QGIS-Settings to avoid the assign CRS dialog to the ascii layer (appear at the point "QgsRasterLayer(..."). asc_layer.setCrs(crs_radolan) is not sufficient! == Part 1 of 2 == see https://gis.stackexchange.com/questions/27745/how-can-i-specify-the-crs-of-a-raster-layer-in-pyqgis/27765#27765 """ settings = QSettings() oldValidation = settings.value( "/Projections/defaultBehavior" ) settings.setValue( "/Projections/defaultBehavior", "useGlobal" ) asc_layer = QgsRasterLayer(self._full_asc_filename, path.basename(self._full_asc_filename) ) crs_radolan = QgsCoordinateReferenceSystem() crs_radolan.createFromProj4(proj_radolan) #asc_layer.setCrs( QgsCoordinateReferenceSystem(PROJ_RADOLAN_NATIVE, QgsCoordinateReferenceSystem.EpsgCrsId) ) # -> funktioniert nicht :-/ asc_layer.setCrs(crs_radolan) """ Change QGIS-Settings to avoid the assign CRS dialog to the ascii layer. asc_layer.setCrs(crs_radolan) is not sufficient! == Part 2 of 2 == """ settings.setValue( "/Projections/defaultBehavior", oldValidation ) return asc_layer
def get_layer_wgs84(self): """ Return layer in WGS84 (WPGS:4326) """ # Setup settings for AOI provided to GEE: wgs84_crs = QgsCoordinateReferenceSystem() wgs84_crs.createFromProj4('+proj=longlat +datum=WGS84 +no_defs') return transform_layer(self.l, wgs84_crs, datatype=self.datatype, wrap=False)
def __init__(self, plugin, layerDef, creditVisibility=1): QgsPluginLayer.__init__(self, TileLayer.LAYER_TYPE, layerDef.title) self.plugin = plugin self.iface = plugin.iface self.layerDef = layerDef self.creditVisibility = 1 if creditVisibility else 0 # set custom properties self.setCustomProperty("title", layerDef.title) self.setCustomProperty("credit", layerDef.credit) # TODO: need to remove self.setCustomProperty("serviceUrl", layerDef.serviceUrl) self.setCustomProperty("yOriginTop", layerDef.yOriginTop) self.setCustomProperty("zmin", layerDef.zmin) self.setCustomProperty("zmax", layerDef.zmax) if layerDef.bbox: self.setCustomProperty("bbox", layerDef.bbox.toString()) self.setCustomProperty("creditVisibility", self.creditVisibility) # create a QgsCoordinateReferenceSystem instance if plugin has no instance yet if layerDef.proj is not None: customcrs = QgsCoordinateReferenceSystem() customcrs.createFromProj4(layerDef.proj) else: customcrs = QgsCoordinateReferenceSystem(layerDef.crs) self.setCrs(customcrs) if layerDef.bbox: self.setExtent(BoundingBox.degreesToMercatorMeters(layerDef.bbox).toQgsRectangle()) else: self.setExtent(QgsRectangle(-layerDef.TSIZE1, -layerDef.TSIZE1, layerDef.TSIZE1, layerDef.TSIZE1)) self.setValid(True) self.tiles = None self.useLastZoomForPrint = False self.canvasLastZoom = 0 self.setTransparency(LayerDefaultSettings.TRANSPARENCY) self.setBlendModeByName(LayerDefaultSettings.BLEND_MODE) self.setSmoothRender(LayerDefaultSettings.SMOOTH_RENDER) # downloader self.downloader = Downloader(self) self.downloader.userAgent = QGISSettings.get_default_user_agent() self.downloader.default_cache_expiration = QGISSettings.get_default_tile_expiry() self.downloader.max_connection = PluginSettings.default_tile_layer_conn_count() #TODO: Move to INI files QObject.connect(self.downloader, SIGNAL("replyFinished(QString, int, int)"), self.networkReplyFinished) #network self.downloadTimeout = QGISSettings.get_default_network_timeout() # multi-thread rendering self.eventLoop = None QObject.connect(self, SIGNAL("fetchRequest(QStringList)"), self.fetchRequest) if self.iface: QObject.connect(self, SIGNAL("showMessage(QString, int)"), self.showStatusMessageSlot) QObject.connect(self, SIGNAL("showBarMessage(QString, QString, int, int)"), self.showBarMessageSlot)
def testCrsConversion(self): self.assertFalse(GdalUtils.gdal_crs_string(QgsCoordinateReferenceSystem())) self.assertEqual(GdalUtils.gdal_crs_string(QgsCoordinateReferenceSystem('EPSG:3111')), 'EPSG:3111') self.assertEqual(GdalUtils.gdal_crs_string(QgsCoordinateReferenceSystem('POSTGIS:3111')), 'EPSG:3111') self.assertEqual(GdalUtils.gdal_crs_string(QgsCoordinateReferenceSystem( 'proj4: +proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs')), 'EPSG:20936') crs = QgsCoordinateReferenceSystem() crs.createFromProj4( '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs') self.assertTrue(crs.isValid()) self.assertEqual(GdalUtils.gdal_crs_string(crs), '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs')
def convertCoordinateProj(crsProj, fromX, fromY, outputProjected): regex = r"^[ ]*PROJCS" isProjected = re.match(regex, crsProj) if (isProjected and outputProjected) or ( not isProjected and not outputProjected): return (fromX, fromY) else: fProj = QgsCoordinateReferenceSystem() fProj.createFromWkt(crsProj) tProj = QgsCoordinateReferenceSystem() tProj.createFromProj4("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" if outputProjected else "+proj=longlat +datum=WGS84 +no_defs ") newCoord = QgsCoordinateTransform(fProj, tProj, QgsProject.instance()).transform(QgsPointXY(fromX, fromY), True) return (newCoord.x, newCoord.y)
def get_qgis_prj_default_projection(db): tig_projections = TigProjections(db=db) proj = tig_projections.get_projection( tig_projections.default_projection_id) if proj is not None: proj4String = 'PROJ4:' + proj.qgis_string QgsCoordinateReferenceSystem('EPSG:..') proj4String = 'PROJ4:' + proj.qgis_string destSrc = QgsCoordinateReferenceSystem() destSrc.createFromProj4(proj.qgis_string) pass
def _getOutputCrs(self): crs = QgsCoordinateReferenceSystem(self.outCrs) if not crs.isValid(): if not crs.createFromProj4(self.outCrs): qWarning(u"unable to create the output CRS from '%s'" % self.outCrs) return crs
def transform_layer(l, crs_dst, datatype='polygon', wrap=False): log('Transforming layer from "{}" to "{}". Wrap is {}. Datatype is {}.'. format(l.crs().toProj4(), crs_dst.toProj4(), wrap, datatype)) crs_src_string = l.crs().toProj4() if wrap: if not l.crs().isGeographic(): QtWidgets.QMessageBox.critical( None, tr("Error"), tr("Error - layer is not in a geographic coordinate system. Cannot wrap layer across 180th meridian." )) log('Can\'t wrap layer in non-geographic coordinate system: "{}"'. format(crs_src_string)) return None crs_src_string = crs_src_string + ' +lon_wrap=180' crs_src = QgsCoordinateReferenceSystem() crs_src.createFromProj4(crs_src_string) t = QgsCoordinateTransform(crs_src, crs_dst) l_w = QgsVectorLayer( "{datatype}?crs=proj4:{crs}".format(datatype=datatype, crs=crs_dst.toProj4()), "calculation boundary (transformed)", "memory") feats = [] for f in l.getFeatures(): geom = f.geometry() if wrap: n = 0 p = geom.vertexAt(n) # Note vertexAt returns QgsPoint(0, 0) on error while p != QgsPoint(0, 0): if p.x() < 0: geom.moveVertex(p.x() + 360, p.y(), n) n += 1 p = geom.vertexAt(n) geom.transform(t) f.setGeometry(geom) feats.append(f) l_w.dataProvider().addFeatures(feats) l_w.commitChanges() if not l_w.isValid(): log('Error transforming layer from "{}" to "{}" (wrap is {})'.format( crs_src_string, crs_dst.toProj4(), wrap)) return None else: return l_w
def sameBaseCrs(self, crs1, crs2): if crs1 == crs2: # it's the same! return True # remove towgs84, nadgrids and wktext from both and try again proj4str1 = self.__removeFromProj4( crs1.toProj4(), ['+towgs84', '+nadgrids', '+wktext']) proj4str2 = self.__removeFromProj4( crs2.toProj4(), ['+towgs84', '+nadgrids', '+wktext']) newcrs1 = QgsCoordinateReferenceSystem() newcrs2 = QgsCoordinateReferenceSystem() if newcrs1.createFromProj4( proj4str1 ) and newcrs1.isValid() and \ newcrs2.createFromProj4( proj4str2 ) and newcrs2.isValid(): if newcrs1 == newcrs2: return True return False
def define_crs_if_not_exist(): __logger.debug('Check if CQFS CRS is defined...') config = __config['global'] name = config['crs_name'] proj4 = config['crs_proj4'] crs = QgsCoordinateReferenceSystem() crs.createFromProj4(proj4) description = str(crs.description()) if description == '': success = crs.saveAsUserCRS(name) if success: __logger.debug('CRS defined successfully.') else: __logger.warning('Fail to save CRS "{}".'.format(name)) else: __logger.debug('CRS "{}" already exists.'.format(description))
def getFeatureWithMultiGeomFromOgrShp(self, filmNumber, shpExtension, geomType, source, targetCrs, sortBy=None): flightPathDirectory = self.settings.value( "APIS/flightpath_dir") + "\\" + self.yearFromFilm(filmNumber) shpFile = flightPathDirectory + "\\" + filmNumber + shpExtension dataSource = self.shpDriver.Open(shpFile, 0) if dataSource: sourceCrs = QgsCoordinateReferenceSystem() spatialRef = dataSource.GetLayer().GetSpatialRef() if spatialRef: sourceCrs.createFromProj4( dataSource.GetLayer().GetSpatialRef().ExportToProj4()) else: sourceCrs.createFromId( 4326, type=QgsCoordinateReferenceSystem.EpsgCrsId) # Create QgsMultiPointGeometry; iterate over all Points and add to MultiGeometry if sortBy: layer = sorted(dataSource.GetLayer(), key=lambda f: f[sortBy]) else: layer = dataSource.GetLayer() sourceMultiGeom = ogr.Geometry(geomType) for feature in layer: sourceMultiGeom.AddGeometry(feature.GetGeometryRef()) targetMultiGeom = QgsGeometry( QgsGeometry.fromWkt(sourceMultiGeom.ExportToWkt())) targetMultiGeom.convertToMultiType() feature = QgsFeature() feature.setGeometry( TransformGeometry(targetMultiGeom, sourceCrs, targetCrs)) feature.setAttributes([filmNumber, source] + self.getAttributesForFilm(filmNumber)) return feature else: return None
def calculateSquare(self, point): ''' point in layer coordinates(QgsPoint) ''' mapCrs = self.canvas.mapSettings().destinationCrs() utmCrs = QgsCoordinateReferenceSystem() utmCrs.createFromProj4(self.proj4Utm(point)) ctFwd = QgsCoordinateTransform(mapCrs, utmCrs, QgsProject.instance()) ctBwd = QgsCoordinateTransform(utmCrs, mapCrs, QgsProject.instance()) pointGeom = QgsGeometry.fromPointXY(point) pointGeom.transform(ctFwd) pointUtm = QgsPointXY(pointGeom.asPoint()) # calculate d d = self.diagonal / (2 * (2**0.5)) left = pointUtm.x() - d bottom = pointUtm.y() - d right = pointUtm.x() + d top = pointUtm.y() + d p1 = QgsGeometry.fromPointXY(QgsPointXY(left, bottom)) p2 = QgsGeometry.fromPointXY(QgsPointXY(right, bottom)) p3 = QgsGeometry.fromPointXY(QgsPointXY(right, top)) p4 = QgsGeometry.fromPointXY(QgsPointXY(left, top)) p1.transform(ctBwd) p2.transform(ctBwd) p3.transform(ctBwd) p4.transform(ctBwd) mapPol = [ p1.asPoint(), p2.asPoint(), p3.asPoint(), p4.asPoint(), p1.asPoint() ] return mapPol
def set_tile_layer_proj(cls, layer, epsg_crs_id, postgis_crs_id, custom_proj): # set standard crs for tiled layer layer.setCrs(cls.CRS_3857) # set standard/custom crs try: crs = None if epsg_crs_id is not None: crs = QgsCoordinateReferenceSystem( epsg_crs_id, QgsCoordinateReferenceSystem.EpsgCrsId) if postgis_crs_id is not None: crs = QgsCoordinateReferenceSystem( postgis_crs_id, QgsCoordinateReferenceSystem.PostgisCrsId) if custom_proj is not None: # create form proj4 str custom_crs = QgsCoordinateReferenceSystem() custom_crs.createFromProj4(custom_proj) # try to search in db searched = custom_crs.findMatchingProj() if searched: crs = QgsCoordinateReferenceSystem( searched, QgsCoordinateReferenceSystem.InternalCrsId) else: # create custom and use it custom_crs.saveAsUserCRS(u'quickmapservices ' + layer.name()) searched = custom_crs.findMatchingProj() if searched: crs = QgsCoordinateReferenceSystem( searched, QgsCoordinateReferenceSystem.InternalCrsId) else: crs = custom_crs if crs: layer.setCrs(crs) except: msg = "Custom crs can't be set for layer {0}!".format(layer.name()) self.show_bar_message(msg, QgsMessageBar.WARNING, 4)
def coordRefSys(self, mapCoordSys): epsg = self.epsgList[0] coordRefSys = QgsCoordinateReferenceSystem() if QGis.QGIS_VERSION_INT >= 10900: idEpsgRSGoogle = "EPSG:%d" % epsg createCrs = coordRefSys.createFromOgcWmsCrs(idEpsgRSGoogle) else: idEpsgRSGoogle = epsg createCrs = coordRefSys.createFromEpsg(idEpsgRSGoogle) if not createCrs: google_proj_def = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 " google_proj_def += "+units=m +nadgrids=@null +wktext +no_defs" isOk = coordRefSys.createFromProj4(google_proj_def) if not isOk: return None return coordRefSys
def coordRefSys(self, mapCoordSys): epsg = self.epsgList[0] coordRefSys = QgsCoordinateReferenceSystem() if QGis.QGIS_VERSION_INT >= 10900: idEpsgRSGoogle = "EPSG:%d" % epsg createCrs = coordRefSys.createFromOgcWmsCrs(idEpsgRSGoogle) else: idEpsgRSGoogle = epsg createCrs = coordRefSys.createFromEpsg(idEpsgRSGoogle) if not createCrs: proj_def = "+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=GRS80 " proj_def += "+towgs84=0,0,0,0,0,0,0 +units=m +no_defs" isOk = coordRefSys.createFromProj4(proj_def) if not isOk: return None return coordRefSys
def coordRefSys(self, mapCoordSys): epsg = self.epsgList[0] coordRefSys = QgsCoordinateReferenceSystem() if QGis.QGIS_VERSION_INT >= 10900: idEpsgRSGoogle = "EPSG:%d" % epsg createCrs = coordRefSys.createFromOgcWmsCrs(idEpsgRSGoogle) else: idEpsgRSGoogle = epsg createCrs = coordRefSys.createFromEpsg(idEpsgRSGoogle) if not createCrs: google_proj_def = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 " google_proj_def += "+units=m +nadgrids=@null +wktext +no_defs" isOk = coordRefSys.createFromProj4(google_proj_def) if not isOk: return None return coordRefSys
def spQgsVectorLayer(name): spatial = robjects.r.get(name) type = spType(spatial) layer = QgsVectorLayer(type, unicode(name), "memory") crs = QgsCoordinateReferenceSystem() proj = spatial.do_slot('proj4string').do_slot('projargs')[0] if crs.createFromProj4(proj): layer.setCrs(crs) else: print "Error: unable to parse proj4string: using QGIS default" provider = layer.dataProvider() fields = spFields(spatial) provider.addAttributes(fields) feats = spData(spatial) features = [spFeature(*feat) for feat in feats] provider.addFeatures(features) layer.updateExtents() return layer
def makeCoordinateReferenceSystem(latitude, utmZone): """ Creates a coordinate reference system, for instance for converting to this system. Args: param1: The WGS84 latitude. param2: The UTM zone number. Returns: A valid QgsCoordinateReferenceSystem or None >>> makeCoordinateReferenceSystem(13.41250188, 48) #doctest: +ELLIPSIS <qgis._core.QgsCoordinateReferenceSystem object at 0x...> >>> makeCoordinateReferenceSystem(13.41250188, 21442) is None True """ crs = QgsCoordinateReferenceSystem() proj4String = "+proj=utm +ellps=WGS84 +datum=WGS84 +units=m +zone=%s" % utmZone if latitude < 0: proj4String += " +south" result = crs.createFromProj4(proj4String) return crs if result and crs.isValid() else None
def import_params(self): setting_file = QFileDialog.getOpenFileName( self, self.tr("Open settings file"), self.lastSavingPath, "*.txt") if setting_file[0] != '': with open(setting_file[0]) as json_file: try: parameters = json.load(json_file) param_crs = QgsCoordinateReferenceSystem() param_crs.createFromProj4(parameters["crs_map"]) if (self.map_crs != param_crs): # do traslation transform = QgsCoordinateTransform( param_crs, self.map_crs, QgsProject.instance()) pointMin = transform.transform(parameters["roi_x_min"], parameters["roi_y_min"]) pointMax = transform.transform(parameters["roi_x_max"], parameters["roi_y_max"]) self.roi_x_max = pointMax.x() self.roi_y_min = pointMin.y() self.roi_x_min = pointMin.x() self.roi_y_max = pointMax.y() else: self.roi_x_max = parameters["roi_x_max"] self.roi_y_min = parameters["roi_y_min"] self.roi_x_min = parameters["roi_x_min"] self.roi_y_max = parameters["roi_y_max"] self.ui.XMaxLineEdit.setText(str(round(self.roi_x_max, 3))) self.ui.YMinLineEdit.setText(str(round(self.roi_y_min, 3))) self.ui.XMinLineEdit.setText(str(round(self.roi_x_min, 3))) self.ui.YMaxLineEdit.setText(str(round(self.roi_y_max, 3))) if "roi_rect_Param" in parameters: self.rect_Params = parameters["roi_rect_Param"] else: rec = QgsRectangle(self.roi_x_min, self.roi_y_min, self.roi_x_max, self.roi_y_max) self.rect_Params = { 'center': [rec.center().x(), rec.center().y()], 'width': rec.width(), 'height': rec.height(), 'rotation': 0 } self.ui.WidthGeoLineEdit.setText( str(round(self.rect_Params["width"], 3))) self.ui.HeightGeoLineEdit.setText( str(round(self.rect_Params["height"], 3))) self.ui.SpacingLineEdit.setText( str(round(parameters["spacing_mm"], 2))) self.scale = parameters['scale'] self.scale_h = parameters['scale_h'] self.scale_w = parameters['scale_w'] self.ui.ScaleLineEdit.setScale(int(parameters["scale"])) self.upload_size_from_scale() self.ui.ZScaleDoubleSpinBox.setValue(parameters["z_scale"]) self.get_z_max_z_min() self.ui.BaseHeightLineEdit.setText( str(round(parameters["z_base"], 3))) self.ui.RevereseZCheckBox.setChecked(parameters["z_inv"]) self.get_height_model() if "divideRow" in parameters: self.ui.RowPartsSpinBox.setValue( int(parameters["divideRow"])) if "divideCols" in parameters: self.ui.ColPartsSpinBox.setValue( int(parameters["divideCols"])) self.paint_extent(self.rect_Params) except: QMessageBox.warning(self, self.tr("Attention"), self.tr("Wrong file"))
def moveVertex(self, result): marker = result[1] snappingResult = result[0] QMessageBox.critical(self.iface.mainWindow(), "Move vertex error", "Move vertex error", QMessageBox.Ok) # The vertex that is found by the tool: vertexCoords = snappingResult.point( ) # vertexCoord are given in crs of the project vertexNr = snappingResult.vertexIndex() featureId = snappingResult.featureId() layer = snappingResult.layer() try: layerSrs = layer.srs() # find out the srs of the layer except AttributeError: # API version >1.8 layerSrs = layer.crs() # find out the srs of the layer # Give a dialog with the current coords and ask for the new ones (input, ok) = QInputDialog.getText( self.iface.mainWindow(), "Move Vertex Feature", "Enter New Coordinates as 'xcoord, ycoord'", QLineEdit.Normal, str(vertexCoords.x()) + "," + str(vertexCoords.y())) if not ok: # If we are aborting, we have to delete the marker self.canvas.scene().removeItem(marker) del marker return 0 # Find out which is the current crs of the project projectSrsEntry = QgsProject.instance().readEntry( "SpatialRefSys", "/ProjectCRSProj4String") projectSrs = QgsCoordinateReferenceSystem() projectSrs.createFromProj4(projectSrsEntry[0]) # Set up a coordinate transformation to transform the vertex coord into the srs of his layer transformer = QgsCoordinateTransform(projectSrs, layerSrs, QgsProject.instance()) # transformedPoint = transformer.transform(input.split(",")[0].toDouble()[0], # input.split(",")[1].toDouble()[0]) transformedPoint = transformer.transform(float(input.split(",")[0]), float(input.split(",")[1])) # If the transformation is successful, we move the vertex to his new place # else we inform the user that there is something wrong if (type(transformedPoint.x()).__name__ == 'double' and type(transformedPoint.y()).__name__ == 'double') or\ (type(transformedPoint.x()).__name__ == 'float' and type(transformedPoint.y()).__name__ == 'float'): # If the undo/redo stack is available, we use it if self.undoAvailable: layer.beginEditCommand("Moved Vertex") # Now we move the vertex to the given coordinates layer.moveVertex(transformedPoint.x(), transformedPoint.y(), featureId, vertexNr) # end of undo/redo stack (if available) if self.undoAvailable: layer.endEditCommand() else: QMessageBox.critical( self.iface.mainWindow(), "Error while transforming the vertex", "It's not possible to transform the coordinates you gave into the srs of this layer." ) # Now refresh the map canvas self.canvas.refresh() # At last we have to delete the marker self.canvas.scene().removeItem(marker) del marker
def crsCreateFromProj4(proj4String): crs = QgsCoordinateReferenceSystem() result = crs.createFromProj4(proj4String) return crs if result and crs.isValid() else None
class SurvexImport: """QGIS Plugin Implementation.""" # The following are some dictionaries for flags in the .3d file station_attr = { 0x01: 'SURFACE', 0x02: 'UNDERGROUND', 0x04: 'ENTRANCE', 0x08: 'EXPORTED', 0x10: 'FIXED', 0x20: 'ANON' } leg_attr = {0x01: 'SURFACE', 0x02: 'DUPLICATE', 0x04: 'SPLAY'} style_type = { 0x00: 'NORMAL', 0x01: 'DIVING', 0x02: 'CARTESIAN', 0x03: 'CYLPOLAR', 0x04: 'NOSURVEY', 0xff: 'NOSTYLE' } # lists of keys of above, sorted to restore ordering station_flags = sorted(station_attr.keys()) leg_flags = sorted(leg_attr.keys()) # field names if there is error data error_fields = ('ERROR_VERT', 'ERROR_HORIZ', 'ERROR', 'LENGTH') # main data structures leg_list = [] # accumulates legs + metadata station_list = [] # ditto stations xsect_list = [] # ditto for cross sections for walls station_xyz = {} # map station names to xyz coordinates crs = None # used to set layer CRS in memory provider crs_source = None # records the origin of the CRS title = '' # used to set layer title in memory provider path_3d = '' # to remember the path to the survex .3d file path_gpkg = '' # ditto for path to save GeoPackage (.gpkg) def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'SurvexImport_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Import .3d file') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('SurvexImport', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToVectorMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/survex_import/icon.png' self.add_action(icon_path, text=self.tr(u'.3d import'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginVectorMenu(self.tr(u'&Import .3d file'), action) self.iface.removeToolBarIcon(action) def crs_from_file(self): """Enforce consistent CRS selector state""" if self.dlg.CRSFromFile.isChecked(): self.dlg.CRSFromProject.setChecked(False) def crs_from_project(self): """Enforce consistent CRS selector state""" if self.dlg.CRSFromProject.isChecked(): self.dlg.CRSFromFile.setChecked(False) def select_3d_file(self): """Select 3d file""" file_3d, _filter_3d = QFileDialog.getOpenFileName( self.dlg, "Select .3d file ", self.path_3d, '*.3d') self.dlg.selectedFile.setText(file_3d) self.path_3d = QFileInfo(file_3d).path() # memorise path selection def select_gpkg(self): """Select GeoPackage (.gpkg)""" file_gpkg, _filter_gpkg = QFileDialog.getSaveFileName( self.dlg, "Enter or select existing .gpkg file ", self.path_gpkg, '*.gpkg') self.dlg.selectedGPKG.setText(file_gpkg) self.path_gpkg = QFileInfo(file_gpkg).path() # memorise path selection def set_crs(self, s): """Figure out the CRS for layer creation, from the selected options and/or string""" if self.dlg.CRSFromProject.isChecked(): self.crs_source = 'from project' self.crs = QgsProject.instance().crs() elif self.dlg.CRSFromFile.isChecked() and s: self.crs_source = 'from .3d file' self.crs = QgsCoordinateReferenceSystem() match = search('epsg:([0-9]*)', s) # check for epsg in proj string if match: # if found, use the EPSG number explicitly self.crs.createFromString('EPSG:{}'.format(int( match.group(1)))) else: # fall back to proj4 self.crs.createFromProj4(s) else: # fall back to raising a CRS selection dialog self.crs_source = 'from dialog' dialog = QgsProjectionSelectionDialog() dialog.setMessage('define the CRS for the imported layers') dialog.exec() # run the dialog .. self.crs = dialog.crs() # .. and recover the user input if self.crs.isValid(): msg = 'CRS {} : {}'.format(self.crs_source, self.crs.authid()) QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) QgsMessageLog.logMessage(self.crs.description(), tag='Import .3d', level=Qgis.Info) else: # hopefully never happens msg = "CRS invalid!" QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) self.crs = None def all_checked(self): """ ensures the import all check box is consistent""" check = self.dlg.Legs.isChecked() check = check and self.dlg.Stations.isChecked() check = check and self.dlg.Polygons.isChecked() check = check and self.dlg.Walls.isChecked() check = check and self.dlg.XSections.isChecked() check = check and self.dlg.Traverses.isChecked() check = check and self.dlg.LegsSurface.isChecked() check = check and self.dlg.LegsSplay.isChecked() check = check and self.dlg.LegsDuplicate.isChecked() check = check and self.dlg.StationsSurface.isChecked() self.dlg.ImportAll.setChecked(check) def toggle_import_all(self): """toggle import all possible data""" checked = self.dlg.ImportAll.isChecked() self.dlg.Legs.setChecked(checked) self.dlg.Stations.setChecked(checked) self.dlg.Polygons.setChecked(checked) self.dlg.Walls.setChecked(checked) self.dlg.XSections.setChecked(checked) self.dlg.Traverses.setChecked(checked) self.dlg.LegsSurface.setChecked(checked) self.dlg.LegsSplay.setChecked(checked) self.dlg.LegsDuplicate.setChecked(checked) self.dlg.StationsSurface.setChecked(checked) def add_layer(self, subtitle, geom): """Add a memory layer with title(subtitle) and geom""" name = '%s(%s)' % (self.title, subtitle) if self.title else subtitle layer = QgsVectorLayer(geom, name, 'memory') if self.crs: # this should have been set by now layer.setCrs(self.crs) if not layer.isValid(): raise Exception("Invalid layer with %s" % geom) msg = "Memory layer '%s' called '%s' added" % (geom, name) QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) return layer # The next three routines are to do with reading .3d binary file format def read_xyz(self, fp): """Read xyz as integers, according to .3d spec""" return unpack('<iii', fp.read(12)) def read_len(self, fp): """Read a number as a length according to .3d spec""" byte = ord(fp.read(1)) if byte != 0xff: return byte else: return unpack('<I', fp.read(4))[0] def read_label(self, fp, current_label): """Read a string as a label, or part thereof, according to .3d spec""" byte = ord(fp.read(1)) if byte != 0x00: ndel = byte >> 4 nadd = byte & 0x0f else: ndel = self.read_len(fp) nadd = self.read_len(fp) oldlen = len(current_label) return current_label[:oldlen - ndel] + fp.read(nadd).decode('ascii') def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = SurvexImportDialog() self.dlg.selectedFile.clear() self.dlg.fileSelector.clicked.connect(self.select_3d_file) self.dlg.selectedGPKG.clear() self.dlg.GPKGSelector.clicked.connect(self.select_gpkg) self.dlg.CRSFromProject.setChecked(False) self.dlg.CRSFromFile.clicked.connect(self.crs_from_file) self.dlg.CRSFromFile.setChecked(False) self.dlg.CRSFromProject.clicked.connect(self.crs_from_project) self.dlg.ImportAll.clicked.connect(self.toggle_import_all) self.dlg.Legs.clicked.connect(self.all_checked) self.dlg.Stations.clicked.connect(self.all_checked) self.dlg.Polygons.clicked.connect(self.all_checked) self.dlg.Walls.clicked.connect(self.all_checked) self.dlg.XSections.clicked.connect(self.all_checked) self.dlg.Traverses.clicked.connect(self.all_checked) self.dlg.LegsSurface.clicked.connect(self.all_checked) self.dlg.LegsSplay.clicked.connect(self.all_checked) self.dlg.LegsDuplicate.clicked.connect(self.all_checked) self.dlg.StationsSurface.clicked.connect(self.all_checked) self.dlg.show() # show the dialog result = self.dlg.exec_() # Run the dialog event loop if result: # The user pressed OK, and this is what happened next! survex_3d = self.dlg.selectedFile.text() gpkg_file = self.dlg.selectedGPKG.text() include_legs = self.dlg.Legs.isChecked() include_stations = self.dlg.Stations.isChecked() include_polygons = self.dlg.Polygons.isChecked() include_walls = self.dlg.Walls.isChecked() include_xsections = self.dlg.XSections.isChecked() include_traverses = self.dlg.Traverses.isChecked() exclude_surface_legs = not self.dlg.LegsSurface.isChecked() exclude_splay_legs = not self.dlg.LegsSplay.isChecked() exclude_duplicate_legs = not self.dlg.LegsDuplicate.isChecked() exclude_surface_stations = not self.dlg.StationsSurface.isChecked() use_clino_wgt = self.dlg.UseClinoWeights.isChecked() include_up_down = self.dlg.IncludeUpDown.isChecked() discard_features = not self.dlg.KeepFeatures.isChecked() if not os.path.exists(survex_3d): raise Exception("File '%s' doesn't exist" % survex_3d) if discard_features: self.leg_list = [] self.station_list = [] self.station_xyz = {} self.xsect_list = [] # Read .3d file as binary, parse, and save data structures with open(survex_3d, 'rb') as fp: line = fp.readline().rstrip() # File ID check if not line.startswith(b'Survex 3D Image File'): raise IOError('Not a survex .3d file: ' + survex_3d) line = fp.readline().rstrip() # File format version if not line.startswith(b'v'): raise IOError('Unrecognised survex .3d version in ' + survex_3d) version = int(line[1:]) if version < 8: raise IOError('Survex .3d version >= 8 required in ' + survex_3d) line = fp.readline().rstrip( ) # Metadata (title and coordinate system) fields = line.split(b'\x00') previous_title = '' if discard_features else self.title if previous_title: self.title = previous_title + ' + ' + fields[0].decode( 'ascii') else: self.title = fields[0].decode('ascii') self.set_crs( fields[1].decode('ascii') if len(fields) > 1 else None) line = fp.readline().rstrip( ) # Timestamp, unused in present application if not line.startswith(b'@'): raise IOError('Unrecognised timestamp in ' + survex_3d) # timestamp = int(line[1:]) flag = ord(fp.read(1)) # file-wide flag if flag & 0x80: # abort if extended elevation raise IOError("Can't deal with extended elevation in " + survex_3d) # All file-wide header data read in, now read byte-wise # according to .3d spec. Note that all elements must # be processed, in order, otherwise we get out of sync. # We first define some baseline dates date0 = QDate(1900, 1, 1) date1 = QDate(1900, 1, 1) date2 = QDate(1900, 1, 1) label, style = '', 0xff # initialise label and style legs = [] # will be used to capture leg data between MOVEs xsect = [] # will be used to capture XSECT data nlehv = None # .. remains None if there isn't any error data... while True: # start of byte-gobbling while loop char = fp.read(1) if not char: # End of file (reached prematurely?) raise IOError('Premature end of file in ' + survex_3d) byte = ord(char) if byte <= 0x05: # STYLE if byte == 0x00 and style == 0x00: # this signals end of data if legs: # there may be a pending list of legs to save self.leg_list.append((legs, nlehv)) break # escape from byte-gobbling while loop else: style = byte elif byte <= 0x0e: # Reserved continue elif byte == 0x0f: # MOVE xyz = self.read_xyz(fp) if legs: self.leg_list.append((legs, nlehv)) legs = [] elif byte == 0x10: # DATE (none) date1 = date2 = date0 elif byte == 0x11: # DATE (single date) days = unpack('<H', fp.read(2))[0] date1 = date2 = date0.addDays(days) elif byte == 0x12: # DATE (date range, short format) days, extra = unpack('<HB', fp.read(3)) date1 = date0.addDays(days) date2 = date0.addDays(days + extra + 1) elif byte == 0x13: # DATE (date range, long format) days1, days2 = unpack('<HH', fp.read(4)) date1 = date0.addDays(days1) date2 = date0.addDays(days2) elif byte <= 0x1e: # Reserved continue elif byte == 0x1f: # Error info nlehv = unpack('<iiiii', fp.read(20)) elif byte <= 0x2f: # Reserved continue elif byte <= 0x33: # XSECT label = self.read_label(fp, label) if byte & 0x02: lrud = unpack('<iiii', fp.read(16)) else: lrud = unpack('<hhhh', fp.read(8)) xsect.append((label, lrud)) if byte & 0x01: # XSECT_END self.xsect_list.append(xsect) xsect = [] elif byte <= 0x3f: # Reserved continue elif byte <= 0x7f: # LINE flag = byte & 0x3f if not (flag & 0x20): label = self.read_label(fp, label) xyz_prev = xyz xyz = self.read_xyz(fp) while (True): # code pattern to implement logic if exclude_surface_legs and flag & 0x01: break if exclude_duplicate_legs and flag & 0x02: break if exclude_splay_legs and flag & 0x04: break legs.append(((xyz_prev, xyz), label, style, date1, date2, flag)) break elif byte <= 0xff: # LABEL (or NODE) flag = byte & 0x7f label = self.read_label(fp, label) xyz = self.read_xyz(fp) while (True): # code pattern to implement logic if exclude_surface_stations and flag & 0x01 and not flag & 0x02: break self.station_list.append((xyz, label, flag)) break self.station_xyz[label] = xyz # End of byte-gobbling while loop # file closes automatically, with open(survex_3d, 'rb') as fp: layers = [] # used to keep a list of the created layers if include_stations and self.station_list: # station layer station_layer = self.add_layer('stations', 'PointZ') attrs = [ QgsField(self.station_attr[k], QVariant.Int) for k in self.station_flags ] attrs.insert(0, QgsField('ELEVATION', QVariant.Double)) attrs.insert(0, QgsField('NAME', QVariant.String)) station_layer.dataProvider().addAttributes(attrs) station_layer.updateFields() features = [] for (xyz, label, flag) in self.station_list: xyz = [0.01 * v for v in xyz] attrs = [1 if flag & k else 0 for k in self.station_flags] attrs.insert(0, round(xyz[2], 2)) # elevation attrs.insert(0, label) feat = QgsFeature() geom = QgsGeometry(QgsPoint(*xyz)) feat.setGeometry(geom) feat.setAttributes(attrs) features.append(feat) station_layer.dataProvider().addFeatures(features) layers.append(station_layer) if include_legs and self.leg_list: # leg layer leg_layer = self.add_layer('legs', 'LineStringZ') attrs = [ QgsField(self.leg_attr[k], QVariant.Int) for k in self.leg_flags ] if nlehv: [ attrs.insert(0, QgsField(s, QVariant.Double)) for s in self.error_fields ] attrs.insert(0, QgsField('NLEGS', QVariant.Int)) attrs.insert(0, QgsField('DATE2', QVariant.Date)) attrs.insert(0, QgsField('DATE1', QVariant.Date)) attrs.insert(0, QgsField('STYLE', QVariant.String)) attrs.insert(0, QgsField('ELEVATION', QVariant.Double)) attrs.insert(0, QgsField('NAME', QVariant.String)) leg_layer.dataProvider().addAttributes(attrs) leg_layer.updateFields() features = [] for legs, nlehv in self.leg_list: for (xyz_pair, label, style, from_date, to_date, flag) in legs: elev = 0.5 * sum([0.01 * xyz[2] for xyz in xyz_pair]) points = [] for xyz in xyz_pair: xyz = [0.01 * v for v in xyz] points.append(QgsPoint(*xyz)) attrs = [1 if flag & k else 0 for k in self.leg_flags] if nlehv: [ attrs.insert(0, 0.01 * v) for v in reversed(nlehv[1:5]) ] attrs.insert(0, nlehv[0]) attrs.insert(0, to_date) attrs.insert(0, from_date) attrs.insert(0, self.style_type[style]) attrs.insert(0, round(elev, 2)) attrs.insert(0, label) linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) features.append(feat) leg_layer.dataProvider().addFeatures(features) layers.append(leg_layer) # Now do wall features if asked if (include_traverses or include_xsections or include_walls or include_polygons) and self.xsect_list: trav_features = [] wall_features = [] xsect_features = [] quad_features = [] for xsect in self.xsect_list: if len(xsect) < 2: # if there's only one station .. continue # .. give up as we don't know which way to face centerline = [ ] # will contain the station position and LRUD data for label, lrud in xsect: xyz = self.station_xyz[ label] # look up coordinates from label lrud_or_zero = tuple([max(0, v) for v in lrud ]) # deal with missing data centerline.append( xyz + lrud_or_zero) # and collect as 7-uple direction = [ ] # will contain the corresponding direction vectors # The calculations below use integers for xyz and lrud, and # conversion to metres is left to the end. Then dh2 is an # integer and the test for a plumb is safely dh2 = 0. # The directions are unit vectors optionally weighted by # cos(inclination) = dh/dl where dh^2 = dx^2 + dy^2 (note, no dz^2), # and dl^2 = dh^2 + dz^2. The normalisation is correspondingly # either 1/dh, or 1/dh * dh/dl = 1/dl. for i, xyzlrud in enumerate(centerline): x, y, z = xyzlrud[0:3] if i > 0: dx, dy, dz = x - xp, y - yp, z - zp dh2 = dx * dx + dy * dy # integer horizontal displacement (mm^2) norm = sqrt(dh2 + dz * dz) if use_clino_wgt else sqrt(dh2) dx, dy = (dx / norm, dy / norm) if dh2 > 0 and norm > 0 else (0, 0) direction.append((dx, dy)) xp, yp, zp = x, y, z left_wall = [] right_wall = [] up_down = [] # We build the walls by walking through the list # of stations and directions, with simple defaults # for the start and end stations for i, (x, y, z, l, r, u, d) in enumerate(centerline): d1x, d1y = direction[i - 1] if i > 0 else (0, 0) d2x, d2y = direction[i] if i + 1 < len( centerline) else (0, 0) dx, dy = d1x + d2x, d1y + d2y # mean (sum of) direction vectors norm = sqrt(dx * dx + dy * dy) # normalise to unit vector ex, ey = (dx / norm, dy / norm) if norm > 0 else (0, 0) # Convert to metres when saving the points left_wall.append((0.01 * (x - l * ey), 0.01 * (y + l * ex), 0.01 * z)) right_wall.append((0.01 * (x + r * ey), 0.01 * (y - r * ex), 0.01 * z)) up_down.append((0.01 * u, 0.01 * d)) # Mean elevation of centerline, used for elevation attribute elev = 0.01 * sum([xyzlrud[2] for xyzlrud in centerline ]) / len(centerline) attrs = [round(elev, 2)] # Now create the feature sets - first the centerline traverse points = [] for xyzlrud in centerline: xyz = [0.01 * v for v in xyzlrud[0:3] ] # These were mm, convert to metres points.append(QgsPoint(*xyz)) linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) trav_features.append(feat) # The walls as line strings for wall in (left_wall, right_wall): points = [QgsPoint(*xyz) for xyz in wall] linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) wall_features.append(feat) # Slightly more elaborate, pair up points on left # and right walls, and build a cross section as a # 2-point line string, and a quadrilateral polygon # with a closed 5-point line string for the # exterior ring. Note that QGIS polygons are # supposed to have their points ordered clockwise. for i, xyz_pair in enumerate(zip(left_wall, right_wall)): elev = 0.01 * centerline[i][ 2] # elevation of station in centerline attrs = [round(elev, 2)] points = [QgsPoint(*xyz) for xyz in xyz_pair] linestring = QgsLineString() linestring.setPoints(points) feat = QgsFeature() geom = QgsGeometry(linestring) feat.setGeometry(geom) feat.setAttributes(attrs) xsect_features.append(feat) if i > 0: elev = 0.5 * (prev_xyz_pair[0][2] + xyz_pair[0][2] ) # average elevation attrs = [round(elev, 2)] if include_up_down: # average up / down attrs += [ 0.5 * (v1 + v2) for (v1, v2) in zip(up_down[i - 1], up_down[i]) ] points = [ ] # will contain the exterior 5-point ring, as follows... for xyz in tuple( reversed(prev_xyz_pair)) + xyz_pair + ( prev_xyz_pair[1], ): points.append(QgsPoint(*xyz)) linestring = QgsLineString() linestring.setPoints(points) polygon = QgsPolygon() polygon.setExteriorRing(linestring) feat = QgsFeature() geom = QgsGeometry(polygon) feat.setGeometry(geom) feat.setAttributes(attrs) quad_features.append(feat) prev_xyz_pair = xyz_pair # End of processing xsect_list - now add features to requested layers attrs = [QgsField('ELEVATION', QVariant.Double)] # common to all if include_traverses and trav_features: # traverse layer travs_layer = self.add_layer('traverses', 'LineStringZ') travs_layer.dataProvider().addAttributes(attrs) travs_layer.updateFields() travs_layer.dataProvider().addFeatures(trav_features) layers.append(travs_layer) if include_xsections and xsect_features: # xsection layer xsects_layer = self.add_layer('xsections', 'LineStringZ') xsects_layer.dataProvider().addAttributes(attrs) xsects_layer.updateFields() xsects_layer.dataProvider().addFeatures(xsect_features) layers.append(xsects_layer) if include_walls and wall_features: # wall layer walls_layer = self.add_layer('walls', 'LineStringZ') walls_layer.dataProvider().addAttributes(attrs) walls_layer.updateFields() walls_layer.dataProvider().addFeatures(wall_features) layers.append(walls_layer) if include_up_down: # add fields if requested for polygons attrs += [ QgsField(s, QVariant.Double) for s in ('MEAN_UP', 'MEAN_DOWN') ] if include_polygons and quad_features: # polygon layer quads_layer = self.add_layer('polygons', 'PolygonZ') quads_layer.dataProvider().addAttributes(attrs) quads_layer.updateFields() quads_layer.dataProvider().addFeatures(quad_features) layers.append(quads_layer) # All layers have been created, now update extents and add to QGIS registry if layers: [layer.updateExtents() for layer in layers] QgsProject.instance().addMapLayers(layers) # Write to GeoPackage if requested if gpkg_file: opts = [ QgsVectorFileWriter.CreateOrOverwriteFile, QgsVectorFileWriter.CreateOrOverwriteLayer ] for i, layer in enumerate(layers): options = QgsVectorFileWriter.SaveVectorOptions() options.actionOnExistingFile = opts[int( i > 0)] # create file or layer layer_name = layer.name() match = search( ' - ([a-z]*)', layer_name) # ie, extract 'legs', 'stations', etc options.layerName = str( match.group(1)) if match else layer_name writer = QgsVectorFileWriter.writeAsVectorFormat( layer, gpkg_file, options) if writer: msg = "'{}' -> {} in {}".format( layer_name, options.layerName, gpkg_file) QgsMessageLog.logMessage(msg, tag='Import .3d', level=Qgis.Info) options, writer = None, None
def set_orto_crs(self): # if self.dlg.defProjButton.clicked: temp = QgsCoordinateReferenceSystem() temp.createFromProj4("+proj=ortho +lat_0=0.0 +lon_0=0.0 +x_0=0 +y_0=0") self.dlg.crsSel.setCrs(temp)
def __init__(self, plugin, layerDef, creditVisibility=1): QgsPluginLayer.__init__(self, TileLayer.LAYER_TYPE, layerDef.title) self.plugin = plugin self.iface = plugin.iface self.layerDef = layerDef self.creditVisibility = 1 if creditVisibility else 0 # set custom properties self.setCustomProperty("title", layerDef.title) self.setCustomProperty("credit", layerDef.credit) # TODO: need to remove self.setCustomProperty("serviceUrl", layerDef.serviceUrl) self.setCustomProperty("yOriginTop", layerDef.yOriginTop) self.setCustomProperty("zmin", layerDef.zmin) self.setCustomProperty("zmax", layerDef.zmax) if layerDef.bbox: self.setCustomProperty("bbox", layerDef.bbox.toString()) self.setCustomProperty("creditVisibility", self.creditVisibility) # set standard/custom crs self.setCrs(self.CRS_3857) try: crs = None if layerDef.epsg_crs_id is not None: crs = QgsCoordinateReferenceSystem( layerDef.epsg_crs_id, QgsCoordinateReferenceSystem.EpsgCrsId) if layerDef.postgis_crs_id is not None: crs = QgsCoordinateReferenceSystem( layerDef.postgis_crs_id, QgsCoordinateReferenceSystem.PostgisCrsId) if layerDef.custom_proj is not None: # create form proj4 str custom_crs = QgsCoordinateReferenceSystem() custom_crs.createFromProj4(layerDef.custom_proj) # try to search in db searched = custom_crs.findMatchingProj() if searched: crs = QgsCoordinateReferenceSystem( searched, QgsCoordinateReferenceSystem.InternalCrsId) else: # create custom and use it custom_crs.saveAsUserCRS('quickmapservices %s' % layerDef.title) searched = custom_crs.findMatchingProj() if searched: crs = QgsCoordinateReferenceSystem( searched, QgsCoordinateReferenceSystem.InternalCrsId) else: crs = custom_crs if crs: self.setCrs(crs) except: msg = self.tr("Custom crs can't be set for layer {0}!").format( layerDef.title) self.showBarMessage(msg, QgsMessageBar.WARNING, 4) if layerDef.bbox: self.setExtent( BoundingBox.degreesToMercatorMeters( layerDef.bbox).toQgsRectangle()) else: self.setExtent( QgsRectangle(-layerDef.TSIZE1, -layerDef.TSIZE1, layerDef.TSIZE1, layerDef.TSIZE1)) self.setValid(True) self.tiles = None self.useLastZoomForPrint = False self.canvasLastZoom = 0 self.setTransparency(LayerDefaultSettings.TRANSPARENCY) self.setBlendModeByName(LayerDefaultSettings.BLEND_MODE) self.setSmoothRender(LayerDefaultSettings.SMOOTH_RENDER) # downloader self.downloader = Downloader(self) self.downloader.userAgent = QGISSettings.get_default_user_agent() self.downloader.default_cache_expiration = QGISSettings.get_default_tile_expiry( ) self.downloader.max_connection = PluginSettings.default_tile_layer_conn_count( ) #TODO: Move to INI files QObject.connect(self.downloader, SIGNAL("replyFinished(QString, int, int)"), self.networkReplyFinished) #network self.downloadTimeout = QGISSettings.get_default_network_timeout() # multi-thread rendering self.eventLoop = None QObject.connect(self, SIGNAL("fetchRequest(QStringList)"), self.fetchRequest) if self.iface: QObject.connect(self, SIGNAL("showMessage(QString, int)"), self.showStatusMessageSlot) QObject.connect( self, SIGNAL("showBarMessage(QString, QString, int, int)"), self.showBarMessageSlot)
def __init__(self, plugin, layerDef, creditVisibility=1): QgsPluginLayer.__init__(self, TileLayer.LAYER_TYPE, layerDef.title) self.plugin = plugin self.iface = plugin.iface self.layerDef = layerDef self.creditVisibility = 1 if creditVisibility else 0 # set custom properties self.setCustomProperty("title", layerDef.title) self.setCustomProperty("credit", layerDef.credit) # TODO: need to remove self.setCustomProperty("serviceUrl", layerDef.serviceUrl) self.setCustomProperty("yOriginTop", layerDef.yOriginTop) self.setCustomProperty("zmin", layerDef.zmin) self.setCustomProperty("zmax", layerDef.zmax) if layerDef.bbox: self.setCustomProperty("bbox", layerDef.bbox.toString()) self.setCustomProperty("creditVisibility", self.creditVisibility) # set standard/custom crs self.setCrs(self.CRS_3857) try: crs = None if layerDef.epsg_crs_id is not None: crs = QgsCoordinateReferenceSystem(layerDef.epsg_crs_id, QgsCoordinateReferenceSystem.EpsgCrsId) if layerDef.postgis_crs_id is not None: crs = QgsCoordinateReferenceSystem(layerDef.postgis_crs_id, QgsCoordinateReferenceSystem.PostgisCrsId) if layerDef.custom_proj is not None: # create form proj4 str custom_crs = QgsCoordinateReferenceSystem() custom_crs.createFromProj4(layerDef.custom_proj) # try to search in db searched = custom_crs.findMatchingProj() if searched: crs = QgsCoordinateReferenceSystem(searched, QgsCoordinateReferenceSystem.InternalCrsId) else: # create custom and use it custom_crs.saveAsUserCRS('quickmapservices %s' % layerDef.title) searched = custom_crs.findMatchingProj() if searched: crs = QgsCoordinateReferenceSystem(searched, QgsCoordinateReferenceSystem.InternalCrsId) else: crs = custom_crs if crs: self.setCrs(crs) except: msg = self.tr("Custom crs can't be set for layer {0}!").format(layerDef.title) self.showBarMessage(msg, QgsMessageBar.WARNING, 4) if layerDef.bbox: self.setExtent(BoundingBox.degreesToMercatorMeters(layerDef.bbox).toQgsRectangle()) else: self.setExtent(QgsRectangle(-layerDef.TSIZE1, -layerDef.TSIZE1, layerDef.TSIZE1, layerDef.TSIZE1)) self.setValid(True) self.tiles = None self.useLastZoomForPrint = False self.canvasLastZoom = 0 self.setTransparency(LayerDefaultSettings.TRANSPARENCY) self.setBlendModeByName(LayerDefaultSettings.BLEND_MODE) self.setSmoothRender(LayerDefaultSettings.SMOOTH_RENDER) self.setGrayscaleRender(LayerDefaultSettings.GRAYSCALE_RENDER) self.setBrigthness(LayerDefaultSettings.BRIGTNESS) self.setContrast(LayerDefaultSettings.CONTRAST) # downloader self.downloader = Downloader(self) self.downloader.userAgent = QGISSettings.get_default_user_agent() self.downloader.default_cache_expiration = QGISSettings.get_default_tile_expiry() self.downloader.max_connection = PluginSettings.default_tile_layer_conn_count() #TODO: Move to INI files QObject.connect(self.downloader, SIGNAL("replyFinished(QString, int, int)"), self.networkReplyFinished) #network self.downloadTimeout = QGISSettings.get_default_network_timeout() # multi-thread rendering self.eventLoop = None QObject.connect(self, SIGNAL("fetchRequest(QStringList)"), self.fetchRequest) if self.iface: QObject.connect(self, SIGNAL("showMessage(QString, int)"), self.showStatusMessageSlot) QObject.connect(self, SIGNAL("showBarMessage(QString, QString, int, int)"), self.showBarMessageSlot)
crs = QgsCoordinateReferenceSystem(wkt) print("Valid: ", crs.isValid()) print("QGIS CRS ID:", crs.srsid()) print("EPSG ID:", crs.authid()) print("Description:", crs.description()) print("Projection Acronym:", crs.projectionAcronym()) print("Ellipsoid Acronym:", crs.ellipsoidAcronym()) print("Proj4 String:", crs.toProj4()) # check whether it's geographic or projected coordinate system print("Is geographic:", crs.geographicFlag()) # check type of map units in this CRS (values defined in QGis::units enum) print("Map units:", crs.mapUnits()) print("-----------------------------------------------\n\n") crs = QgsCoordinateReferenceSystem() crs.createFromProj4("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs") print("Valid: ", crs.isValid()) print("QGIS CRS ID:", crs.srsid()) print("EPSG ID:", crs.authid()) print("Description:", crs.description()) print("Projection Acronym:", crs.projectionAcronym()) print("Ellipsoid Acronym:", crs.ellipsoidAcronym()) print("Proj4 String:", crs.toProj4()) # check whether it's geographic or projected coordinate system print("Is geographic:", crs.geographicFlag()) # check type of map units in this CRS (values defined in QGis::units enum) print("Map units:", crs.mapUnits()) print("-----------------------------------------------\n\n") wkt = '''PROJCS["Albers_like_IBGE",GEOGCS["GCS_SIRGAS_2000",DATUM["D_SIRGAS_2000",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-54.0],PARAMETER["Standard_Parallel_1",-2.0],PARAMETER["Standard_Parallel_2",-22.0],PARAMETER["Latitude_Of_Origin",-12.0],UNIT["Meter",1.0]]'''
def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ earthRadius = 6370997 # Retrieve the feature source and sink. The 'dest_id' variable is used # to uniquely identify the feature sink, and must be included in the # dictionary returned by the processAlgorithm function. source = self.parameterAsVectorLayer( parameters, self.INPUT, context ) #lat centerLatitude = self.parameterAsDouble( parameters, self.CENTER_LATITUDE, context ) #lon centerLongitude = self.parameterAsDouble( parameters, self.CENTER_LONGITUDE, context ) #segment segments = self.parameterAsInt( parameters, self.SEGMENTS, context ) # If source was not found, throw an exception to indicate that the algorithm # encountered a fatal error. The exception text can be any string, but in this # case we use the pre-built invalidSourceError method to return a standard # helper text for when a source cannot be evaluated if source is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) if centerLatitude is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.CENTER_LATITUDE)) if centerLongitude is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.CENTER_LATITUDE)) if segments is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.SEGMENTS)) output = self.parameterAsOutputLayer( parameters, self.OUTPUT, context ) # Send some information to the user if source.sourceCrs().authid() != 'EPSG:4326': feedback.pushDebugInfo('Input layer for "Clip to Hemisphere" does not use the WGS84 (EPSG:4326) CRS. This can cause unexpected results.') else: feedback.pushInfo('CRS is {}'.format(source.sourceCrs().authid())) sourceCrs = source.sourceCrs() targetProjString = "+proj=ortho +lat_0=" + str(centerLatitude) + \ " +lon_0=" + str(centerLongitude) + \ " +x_0=0 +y_0=0 +a=" + str(earthRadius) + \ " +b=" + str(earthRadius) + \ " +units=m +no_defs" targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromProj4(targetProjString) transformTargetToSrc = QgsCoordinateTransform(targetCrs,sourceCrs,QgsProject.instance()) transformSrcToTarget = QgsCoordinateTransform(sourceCrs,targetCrs,QgsProject.instance()) clipLayer = QgsVectorLayer("MultiPolygon?crs=epsg:4326", "clipLayer", "memory") pr = clipLayer.dataProvider() """ This part was adapted from (C) 2016 by Juernjakob Dugge Source: https://plugins.qgis.org/plugins/ClipToHemisphere/ """ # Handle edge cases: # Hemisphere centered on the equator if centerLatitude == 0: # Hemisphere centered on the equator and including the antimeridian if abs(centerLongitude) >= 90: edgeEast = -180 - np.sign(centerLongitude) * \ (180 - abs(centerLongitude)) + 90 edgeWest = 180 - np.sign(centerLongitude) * \ (180 - abs(centerLongitude)) - 90 circlePoints = [[ [QgsPointXY(-180.01, latitude) for latitude in np.linspace(90, -90, segments / 8)] + [QgsPointXY(longitude, -90) for longitude in np.linspace(-180, edgeEast, segments / 8)] + [QgsPointXY(edgeEast, latitude) for latitude in np.linspace(-90, 90, segments / 8)] + [QgsPointXY(longitude, 90) for longitude in np.linspace(edgeEast, -180, segments / 8)] ], [ [QgsPointXY(edgeWest, latitude) for latitude in np.linspace(90, -90, segments / 8)] + [QgsPointXY(longitude, -90) for longitude in np.linspace(edgeWest, 180, segments / 8)] + [QgsPointXY(180.01, latitude) for latitude in np.linspace(-90, 90, segments / 8)] + [QgsPointXY(longitude, 90) for longitude in np.linspace(180, edgeWest, segments / 8)] ]] # Hemisphere centered on the equator not including the antimeridian else: edgeWest = centerLongitude - 90 edgeEast = centerLongitude + 90 circlePoints = [[ [QgsPointXY(edgeWest, latitude) for latitude in np.linspace(90, -90, segments / 4)] + [QgsPointXY(longitude, -90) for longitude in np.linspace(edgeWest, edgeEast, segments / 4)] + [QgsPointXY(edgeEast, latitude) for latitude in np.linspace(-90, 90, segments / 4)] + [QgsPointXY(longitude, 90) for longitude in np.linspace(edgeEast, edgeWest, segments / 4)] ]] # Hemisphere centered on one of the poles elif abs(centerLatitude) == 90: circlePoints = [[ [QgsPointXY(-180.01, latitude) for latitude in np.linspace(45 + 0.5 * centerLatitude, -45 + 0.5 * centerLatitude, segments / 4)] + [QgsPointXY(longitude, -45 + 0.5 * centerLatitude) for longitude in np.linspace(-180, 180, segments / 4)] + [QgsPointXY(180.01, latitude) for latitude in np.linspace(-45 + 0.5 * centerLatitude, 45 + 0.5 * centerLatitude, segments / 4)] + [QgsPointXY(longitude, 45 + 0.5 * centerLatitude) for longitude in np.linspace(180, -180, segments / 4)] ]] # All other hemispheres else: # Create a circle in the orthographic projection, convert the # circle coordinates to the source CRS angles = np.linspace(0, 2 * np.pi, segments, endpoint=False) circlePoints = np.array([ transformTargetToSrc.transform( QgsPointXY(np.cos(angle) * earthRadius * 0.9999, np.sin(angle) * earthRadius * 0.9999) ) for angle in angles ]) # Sort the projected circle coordinates from west to east sortIdx = np.argsort(circlePoints[:, 0]) circlePoints = circlePoints[sortIdx, :] circlePoints = [[[QgsPointXY(point[0], point[1]) for point in circlePoints]]] # Find the circle point in the orthographic projection that lies # on the antimeridian by linearly interpolating the angles of the # first and last coordinates startGap = 180 + circlePoints[0][0][0][0] endGap = 180 - circlePoints[0][0][-1][0] totalGap = startGap + endGap startCoordinates = transformSrcToTarget.transform(circlePoints[0][0][0]) endCoordinates = transformSrcToTarget.transform(circlePoints[0][0][-1]) startAngle = np.arctan2(startCoordinates[0], startCoordinates[1]) endAngle = np.arctan2(endCoordinates[0], endCoordinates[1]) antimeridianAngle = cmath.phase( endGap / totalGap * cmath.rect(1, startAngle) + startGap / totalGap * cmath.rect(1, endAngle)) antimeridianPoint = transformTargetToSrc.transform(QgsPointXY( np.sin(antimeridianAngle) * earthRadius * 0.9999, np.cos(antimeridianAngle) * earthRadius * 0.9999 )) # Close the polygon circlePoints[0][0].extend( [QgsPointXY(180.01, latitude) for latitude in np.linspace(antimeridianPoint[1], np.sign(centerLatitude) * 90, segments / 4)] + [QgsPointXY(-180.01, latitude) for latitude in np.linspace(np.sign(centerLatitude) * 90, antimeridianPoint[1], segments / 4)] ) # Create the feature and add it to the layer circle = QgsFeature() circle.setGeometry(QgsGeometry.fromMultiPolygonXY(circlePoints)) pr.addFeatures([circle]) pr.updateExtents() # We need to add the clipping layer to the layer list in order to be # able to use them with processing.runalg() clipLayerReg = QgsProject.instance().addMapLayer(clipLayer) # If sink was not created, throw an exception to indicate that the algorithm # encountered a fatal error. The exception text can be any string, but in this # case we use the pre-built invalidSinkError method to return a standard # helper text for when a sink cannot be evaluated if output is None: raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) #clip the layer processing.run("qgis:clip", {'INPUT': source, 'OVERLAY': clipLayerReg, 'OUTPUT':output}, feedback = feedback, context = context) return {self.OUTPUT: output}
g = math.floor(abs(gdec)) m = math.floor((abs(gdec)-g)*60) s = (((abs(gdec)-g)*60)-m)*60 if gdec < 0.0: g = -g m = -m s = -s return (g,m,s) def deleteIfExists(path): if os.path.isfile(path): os.remove(path) crsOrt = QgsCoordinateReferenceSystem() crsOrt.createFromProj4("+proj=ortho +lat_0=0.0 +lon_0=0.0 +x_0=0 +y_0=0") def azimuth2points(A,B): dif = (B[0]-A[0],B[1]-A[1]) a = math.atan2(dif[1],dif[0]) *toDeg az = 90 - a if az < 0: az+=360 return az def dotProduct(p1,p2): return p1[0]*p2[0]+p1[1]*p2[1] def crossProduct(p1,p2):
def processAlgorithm(self, parameters, context, feedback): # 実行される処理を記述する # self.parameterAsFoo でパラメータを参照できる # 詳しくは QgsProcessingAlgorithm クラスのドキュメント参照 crs4326 = QgsCoordinateReferenceSystem('EPSG:4326') # パラメータの値を参照する point1 = self.parameterAsPoint(parameters, self.POINT1, context, crs4326) if point1 is None: raise QgsProcessingException( 'Error: failed to get coordnates of POINT1') # 実行時のログ欄に出力 feedback.pushInfo('point1 ({}, {})'.format(point1.x(), point1.y())) point2 = self.parameterAsPoint(parameters, self.POINT2, context, crs4326) if point2 is None: raise QgsProcessingException( 'Error: failed to get coordnates of POINT2') feedback.pushInfo('point2 ({}, {})'.format(point2.x(), point2.y())) # QgsProcessingParameterDistance の場合は、デフォルトの単位に # 変換された数値が得られる? segment_dist = self.parameterAsDouble(parameters, self.SEGMENT_DIST, context) # メートルになおす # addParameter 時の minValue は単位に関わらず適用されるので # 最低値等をここで設定する segment_dist = max((10, segment_dist)) * 1000.0 feedback.pushInfo('segment dist: {}'.format(segment_dist)) # 出力レイヤの属性の定義を行う fields = QgsFields() fields.append(QgsField('lat_1', QVariant.Double)) fields.append(QgsField('lng_1', QVariant.Double)) fields.append(QgsField('lat_2', QVariant.Double)) fields.append(QgsField('lng_2', QVariant.Double)) fields.append(QgsField('dist', QVariant.Double)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, crs4326) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) # 点1を中心とした正距方位図法の投影法を定義する crs_aeqd = QgsCoordinateReferenceSystem() crs_aeqd.createFromProj4( '+proj=aeqd +lat_0={} +lon_0={} +datum=WGS84'.format( point1.y(), point1.x())) if not crs_aeqd.isValid(): raise QgsProcessingException('Invalid CRS') trans = QgsCoordinateTransform(crs4326, crs_aeqd, QgsProject.instance()) if not trans.isValid(): raise QgsProcessingException('Invalid coordinate transformer') # 点2を、点1中心正距方位図法への座標変換を行う p2_aeqd = trans.transform(point2) # 正距方位図法における中心点との距離は測地線長 dist = p2_aeqd.distance(0.0, 0.0) # 測地線の折れ線を作るための点群 points = [point1] # セグメントに分割することで曲線のような折れ線を作る num_segments = math.floor(dist / segment_dist) + 1 for i in range(1, num_segments): # 点1中心正距方位図法における、点1-点2を結ぶ線上の点を # EPSG:4326 に逆変換を行う x = i * segment_dist / dist * p2_aeqd.x() y = i * segment_dist / dist * p2_aeqd.y() p_4326 = trans.transform(QgsPointXY(x, y), QgsCoordinateTransform.ReverseTransform) points.append(p_4326) points.append(point2) # 折れ線の測地線のジオメトリを作る geom = QgsGeometry().fromPolylineXY(points) # 折れ線の測地線のジオメトリを持つ地物を作る feat = QgsFeature(fields) feat.setGeometry(geom) feat.setAttribute('lat_1', point1.y()) feat.setAttribute('lng_1', point1.x()) feat.setAttribute('lat_2', point2.y()) feat.setAttribute('lng_2', point2.x()) feat.setAttribute('dist', dist) # 地物を出力レイヤ (sink) に追加する sink.addFeature(feat, QgsFeatureSink.FastInsert) # アルゴリズムの結果を返す # このアルゴリズムでは出力 sink のひとつのみ return {self.OUTPUT: dest_id}
def transform_vector(self, out_file): log("Transforming file to: {}".format(out_file)) layer = self.in_dataset source_crs = QgsCoordinateReferenceSystem() if self.SELECTED_TRANSFORM.source_proj: log("Source from proj") log(self.SELECTED_TRANSFORM.source_proj) source_crs.createFromProj4(self.SELECTED_TRANSFORM.source_proj) else: log("Source from id") source_crs.createFromId(self.SELECTED_TRANSFORM.source_code) log("Setting Source CRS") layer.setCrs(source_crs) if self.SELECTED_TRANSFORM.target_proj: log("Setting intermediate CRS from proj") log(self.SELECTED_TRANSFORM.target_proj) temp_crs = QgsCoordinateReferenceSystem() temp_crs.createFromProj4(self.SELECTED_TRANSFORM.target_proj) # We do an intermediate transform, so that the target gets a proper SRID temp_dir = tempfile.mkdtemp() temp_outfilename = os.path.join(temp_dir, 'temp_file.shp') log("Tempfile is: {}".format(temp_outfilename)) error, message = QgsVectorFileWriter.writeAsVectorFormat( layer, temp_outfilename, 'utf-8', temp_crs, 'ESRI Shapefile') if error == QgsVectorFileWriter.NoError: log("Success on intermediate transform") # These overwrite the original target layer destination file. layer = QgsVectorLayer(temp_outfilename, 'in layer', 'ogr') # The next transform is from and to the destination transform, which is needed to define the CRS properly. intermediary_crs = QgsCoordinateReferenceSystem() intermediary_crs.createFromId( self.SELECTED_TRANSFORM.target_code) layer.setCrs(intermediary_crs) else: log("Error writing temporary vector, code: {} and message: {}". format(str(error), message)) self.iface.messageBar().pushMessage( "Error", "Transformation failed, please check your configuration.", level=Qgis.Critical, duration=3) return log("Setting final target CRS from id") dest_crs = QgsCoordinateReferenceSystem() dest_crs.createFromId(self.SELECTED_TRANSFORM.target_code) error, message = QgsVectorFileWriter.writeAsVectorFormat( layer, out_file, 'utf-8', dest_crs, 'ESRI Shapefile') if error == QgsVectorFileWriter.NoError: log("Success") self.iface.messageBar().pushMessage("Success", "Transformation complete.", level=Qgis.Info, duration=3) if self.dlg.TOCcheckBox.isChecked(): log("Opening file {}".format(out_file)) basename = QFileInfo(out_file).baseName() vlayer = QgsVectorLayer(out_file, str(basename), "ogr") if vlayer.isValid(): QgsProject.instance().addMapLayers([vlayer]) else: log("vlayer invalid") else: log("Error writing vector, code: {} and message: {}".format( str(error), message)) self.iface.messageBar().pushMessage( "Error", "Transformation failed, please check your configuration.", level=Qgis.Critical, duration=3)
def getCustom(self, htd_output, f): # Coordinate UTM, WGS84 crs_4326 = QgsCoordinateReferenceSystem( 4326, QgsCoordinateReferenceSystem.EpsgCrsId) htd_utm_48 = QgsCoordinateReferenceSystem( 32648, QgsCoordinateReferenceSystem.EpsgCrsId) htd_utm_49 = QgsCoordinateReferenceSystem( 32649, QgsCoordinateReferenceSystem.EpsgCrsId) # VN2000 Hoi nhap mui 3 htd_102_hn = "+proj=tmerc +lat_0=0 +lon_0=102 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_103_hn = "+proj=tmerc +lat_0=0 +lon_0=103 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_104_hn = "+proj=tmerc +lat_0=0 +lon_0=104 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_104_5_hn = "+proj=tmerc +lat_0=0 +lon_0=104.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_104_75_hn = "+proj=tmerc +lat_0=0 +lon_0=104.75 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_105_hn = "+proj=tmerc +lat_0=0 +lon_0=105 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_105_5_hn = "+proj=tmerc +lat_0=0 +lon_0=105.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_105_75_hn = "+proj=tmerc +lat_0=0 +lon_0=105.75 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_106_hn = "+proj=tmerc +lat_0=0 +lon_0=106 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_106_25_hn = "+proj=tmerc +lat_0=0 +lon_0=106.25 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_106_5_hn = "+proj=tmerc +lat_0=0 +lon_0=106.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_107_hn = "+proj=tmerc +lat_0=0 +lon_0=107 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_107_25_hn = "+proj=tmerc +lat_0=0 +lon_0=107.25 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_107_5_hn = "+proj=tmerc +lat_0=0 +lon_0=107.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_107_75_hn = "+proj=tmerc +lat_0=0 +lon_0=107.75 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_108_hn = "+proj=tmerc +lat_0=0 +lon_0=108 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_108_25_hn = "+proj=tmerc +lat_0=0 +lon_0=108.25 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" htd_108_5_hn = "+proj=tmerc +lat_0=0 +lon_0=108.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +units=m +no_defs" if htd_output == "System": return f.crs() elif htd_output == "UTM Zone 48N - EPGS: 32648": return htd_utm_48 elif htd_output == "UTM Zone 49N - EPGS: 32649": return htd_utm_49 elif htd_output == "WGS84 Lat/long - EPGS: 4326": return crs_4326 elif htd_output == "VN2000 mui 3 KTT 102" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 102": custom = htd_102_hn elif htd_output == "VN2000 mui 3 KTT 103" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 103": custom = htd_103_hn elif htd_output == "VN2000 mui 3 KTT 104" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 104": custom = htd_104_hn elif htd_output == "VN2000 mui 3 KTT 104.5" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 104.5": custom = htd_104_5_hn elif htd_output == "VN2000 mui 3 KTT 104.75" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 104.75": custom = htd_104_75_hn elif htd_output == "VN2000 mui 3 KTT 105" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 105": custom = htd_105_hn elif htd_output == "VN2000 mui 3 KTT 105.5" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 105.5": custom = htd_105_5_hn elif htd_output == "VN2000 mui 3 KTT 105.75" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 105.75": custom = htd_105_75_hn elif htd_output == "VN2000 mui 3 KTT 106" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 106": custom = htd_106_hn elif htd_output == "VN2000 mui 3 KTT 106.25" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 106.25": custom = htd_106_25_hn elif htd_output == "VN2000 mui 3 KTT 106.5" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 106.5": custom = htd_106_5_hn elif htd_output == "VN2000 mui 3 KTT 107" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 107": custom = htd_107_hn elif htd_output == "VN2000 mui 3 KTT 107.25" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 107.25": custom = htd_107_25_hn elif htd_output == "VN2000 mui 3 KTT 107.5" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 107.5": custom = htd_107_5_hn elif htd_output == "VN2000 mui 3 KTT 107.75" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 107.75": custom = htd_107_75_hn elif htd_output == "VN2000 mui 3 KTT 108" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 108": custom = htd_108_hn elif htd_output == "VN2000 mui 3 KTT 108" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 108": custom = htd_108_25_hn elif htd_output == "VN2000 mui 3 KTT 108.25" or htd_output == "VN-2000 Hoi nhap mui 3 KTT 108.25": custom = htd_108_5_hn res = QgsCoordinateReferenceSystem() res.createFromProj4(custom) return res
def importuj(self): #ponizsze troche z lenistwa - pozostalosc po starym kodzie, nie chce mi sie szukac zmiennych i dopisywac #self przed kazda swde_file = self.swde_file tableListString = self.tableListString srid = self.srid pyproj4strFrom = self.pyproj4strFrom pyproj4strTo = self.pyproj4strTo rodz_importu = self.rodz_importu pgserver = self.pgserver pgbase = self.pgbase pguser = self.pguser pguserpswd = self.pguserpswd txtcodec = self.txtcodec id_zd = self.id_zd crs_source = QgsCoordinateReferenceSystem() crs_source.createFromProj4(str(pyproj4strFrom)) crs_dest = QgsCoordinateReferenceSystem() crs_dest.createFromProj4(str(pyproj4strTo)) xform = QgsCoordinateTransform(crs_source, crs_dest) tableList = [] #tabela nazw tabel w bazie tableList = tableListString.split(',') import_testowy = False if rodz_importu == 'testowyJEW' or rodz_importu == 'testowyOBR' or rodz_importu == 'testowyDZE': import_testowy = True for tabName in tableList: if tabName <> 'NONE': print tabName print srid print pyproj4strFrom print pyproj4strTo print "identyfikator jednostki rejestrowej:", self.id_jed_rej print "ilość linii", self.ilosc_linii print "rodzaj importu", rodz_importu print pgserver, pgbase, pguser, pguserpswd uni = lambda s: s if type(s) == unicode else unicode(s,'utf-8','replace') try: f = open(swde_file, "r") if f == 0 or f.closed: print u"Przed rozpoczęciem importu musisz wczytać plik" else: if id_zd == 'NONE': #parametr wybierany przez uzytkownika, jesli jest inny niz NONE self.id_jed_rej = str(self.id_jed_rej).rstrip() #zostanie uzyty jako wymuszenie nazwy zbioru danych else: #w innym przypadku uzyta zostanie nazwa jednostki rej wyłuskana przez program self.id_jed_rej = id_zd #lista column tablicowych - do innej obróbki niż pozostałe arrayCols = ['G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RSKD', 'G5RDOK', 'G5RDZE', 'G5ROBJ'] #słownik kolumn do zmiany nazwy - zmieniamy polskie znaki w nazwie kolumn bo trochę to broi przy pytaniach SQL plcharCols = {u'G5RŻONA':'G5RZONA', u'G5RMĄŻ':'G5RMAZ', u'G5RPWŁ':'G5RPWL', u'G5RWŁ':'G5RWL', u'G5RWŁS':'G5RWLS', u'G5RWŁD':'G5RWLD'} g5Cols = {} #słownik zbudowany: {'nazwa_tabeli':Tablica_Column[]} - posluzy do inicjacji tabel - obiektow robdbtable #inicjalizacja bazy danych rdbase = RobDBBase(pgserver, pgbase, pguser, pguserpswd,1) rdg5Table = {} #słownik zawiera następującą strukturę: {'nazwa_tabeli': Obiekt_rdbtable} #okreslenie rodzaju importu if rodz_importu == 'zwykly' or rodz_importu == 'aktualizacja': Cols = ['G5IDJ', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU','G5RKRG']#g5jew g5Cols['G5JEW'] = Cols Cols = [ 'G5IDD', 'GEOM', 'NR', 'G5IDR', 'G5NOS', 'G5WRT', 'G5DWR', 'G5PEW', 'G5RZN', 'G5DWW', 'G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RJDR', 'G5DTW', 'G5DTU'] #g5dze g5Cols['G5DZE'] = Cols Cols = [ 'G5NRO', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU', 'G5RKRG', 'G5RJEW', 'IDJEW'] #g5obr g5Cols['G5OBR'] = Cols Cols = ['G5PLC', 'G5PSL', 'G5NIP', 'G5NZW', 'G5PIM', 'G5DIM', 'G5OIM', 'G5MIM', 'G5OBL', 'G5DOS', 'G5RADR', 'G5STI', 'G5DTW', 'G5DTU'] #g5osf g5Cols['G5OSF'] = Cols Cols = [ 'G5STI', 'G5NPE', 'G5NSK', 'G5RGN', 'G5NIP', 'G5NZR', 'G5NRR', 'G5NSR', 'G5RADR', 'G5DTW', 'G5DTU'] #g5ins g5Cols['G5INS'] = Cols Cols = ['G5RZONA', 'G5RMAZ', 'G5DTW', 'G5DTU'] #g5mlz g5Cols['G5MLZ'] = Cols Cols = [ 'G5STI', 'G5NPE', 'G5NSK', 'G5RGN', 'G5NIP', 'G5RSKD', 'G5RADR', 'G5DTW', 'G5DTU'] #g5osz g5Cols['G5OSZ'] = Cols Cols = ['G5TJR', 'G5IJR', 'G5RGN', 'G5RWL', 'G5RWLS', 'G5RWLD', 'G5ROBR', 'G5DTW', 'G5DTU' ] #g5jdr g5Cols['G5JDR'] = Cols Cols = [ 'G5UD', 'G5RWLS', 'G5RPOD', 'G5DTW', 'G5DTU'] #g5udz g5Cols['G5UDZ'] = Cols Cols = [ 'G5RWD', 'G5UD', 'G5RWLD', 'G5RPOD', 'G5DTW', 'G5DTU'] #g5udw g5Cols['G5UDW'] = Cols Cols = [ 'G5OFU', 'G5OZU', 'G5OZK', 'G5PEW', 'G5RDZE', 'G5DTW', 'G5DTU'] #g5klu g5Cols['G5KLU'] = Cols Cols = [ 'G5IDT', 'G5OZU','G5OFU', 'G5PEW', 'G5RKRG', 'G5ROBR', 'G5DTW', 'G5DTU'] #g5uzg g5Cols['G5UZG'] = Cols Cols = ['G5KDK', 'G5DTD', 'G5DTP', 'G5SYG', 'G5NSR', 'G5OPD', 'G5RDOK', 'G5DTW', 'G5DTU'] #g5dok g5Cols['G5DOK'] = Cols Cols = ['G5TAR', 'G5NAZ', 'G5KRJ', 'G5WJD', 'G5PWJ', 'G5GMN', 'G5ULC', 'G5NRA', 'G5NRL', 'G5MSC', 'G5KOD', 'G5PCZ', 'G5DTW', 'G5DTU']#g5adr g5Cols['G5ADR'] = Cols Cols = ['G5IDB', 'G5FUZ', 'G5WRT', 'G5DWR', 'G5RBB', 'G5PEW', 'G5PEU', 'G5RZN', 'G5SCN', 'G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RJDR','G5RDZE', 'G5DTU', 'G5DTW']#g5bud g5Cols['G5BUD'] = Cols Cols = ['G5IDK', 'G5OZU', 'G5OZK', 'G5PEW', 'G5RKRG', 'G5ROBR', 'G5DTW', 'G5DTU'] g5Cols['G5KKL'] = Cols Cols = ['G5IDL', 'G5TLOK', 'G5PEW', 'G5PPP', 'G5LIZ', 'G5WRT', 'G5DWR', 'G5RJDR', 'G5RADR', 'G5RDOK', 'G5RBUD', 'G5DTW', 'G5DTU'] g5Cols['G5LKL'] = Cols Cols = ['G5NRZ', 'G5STZ', 'G5DZZ', 'G5DTA', 'G5DTZ', 'G5NAZ', 'G5ROBJ', 'G5RDOK', 'G5DTW', 'G5DTU'] g5Cols['G5ZMN'] = Cols elif rodz_importu == 'testowyJEW' or rodz_importu == 'testowyOBR' or rodz_importu == 'testowyDZE': #teoretycznie powinno wystarczyć zwykle elif bez parametrow, ale na wszelki dorzuce te ory #w przypadku importu testowego importować będziemy tylko jedną z trzech tabel (dze, obr, lub jew) # przy okazji opróżnimy zawartość dotychczasowych tabel testowych delSQLstr = "delete from " if rodz_importu == 'testowyJEW': tableList.append('G5JEW') g5Cols['G5JEW'] = ['G5IDJ', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU','G5RKRG']#g5jew delSQLstr += "g5jew_test;" elif rodz_importu == 'testowyOBR': tableList.append('G5OBR') g5Cols['G5OBR'] = [ 'G5NRO', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU', 'G5RKRG', 'G5RJEW', 'IDJEW'] delSQLstr += "g5obr_test;" elif rodz_importu == 'testowyDZE': tableList.append('G5DZE') g5Cols['G5DZE'] = [ 'G5IDD', 'GEOM', 'NR', 'G5IDR', 'G5NOS', 'G5WRT', 'G5DWR', 'G5PEW', 'G5RZN', 'G5DWW', 'G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RJDR', 'G5DTW', 'G5DTU'] delSQLstr += "g5dze_test;" rdbase.executeSQL(delSQLstr) #nazwy kolumn muszą zostać podane dokładnie jak w bazie - czyli małymi literami #na przyszłość można to rozwiązać w samej RobDBTable #za zamianę liter na małe w tablicy odpowiada ta fikuśna konstrukcja: [x.lower() ....] for tableName in tableList: if import_testowy: appendix = '_TEST' else: appendix = '' rdg5Table[tableName] = RobDBTable(rdbase, tableName + appendix, [x.lower() for x in g5Cols[tableName]], 1, 1) G5Table = "" collist = [] valuelist = [] insertdic = {} # forma [nazwa_tabeli:ilosc_insertow] arraylist = [] #wykorzystywana do przechowywania kolumn typu tablicaowego w formie [[col2, wart..], [col1, wart..], [col2, wart..]] arrayvalue = [] # wykorzystywane do przechowywania danych 1+ takich jak g5rkrg arrayname = '' # nazwa tablicy tożsama z nazwą kolumny w bazie pointslist = [] point = [] Kznak = "" #znacznik + albo -, oznaczajacy czy okreslane sa punkty tworzace polygon czy #wycinajace w nim dziure oldKznak = "0" #posluzy do sprawdzenia czy nastapila zmiana Kznak newPoly = 0 polycount = 0 linianr = 0 #przyda sie w momencie gdy sie program wywali - okresli ktora linia pliku swde nabroiła obieg = 0 #bedzie wykorzystywane przy commit do bazy, ktore bedzie realizowane co np 100 pytań SQL transform = False if import_testowy == False: #tylko jesli nie jest to import testowy if pyproj4strFrom != pyproj4strTo: transform = True print "transform:", transform print "Krok 2. Start programu: ", strftime("%Y-%m-%d %H:%M:%S") if rodz_importu == 'aktualizacja': #usuniecie wszystkich rekordow o id_zd print u"Usuwanie rekordów ze zbioru danych o id = ", self.id_jed_rej #naprawde dziwna sprawa, ale bez tego dwukrotnie powtorzonego slepp-applicationevent print u"Rozpoczęcie usuwania aktualizowanych rekordów: ", strftime("%Y-%m-%d %H:%M:%S") rdbase.executeSQL("SELECT g5sp_delfromtables('" + self.id_jed_rej + "');") print u"Zakończono usuwanie aktualizowanych rekordów: ", strftime("%Y-%m-%d %H:%M:%S") #import_file = str(self.swde_file.toUtf8()).decode('utf-8') try: #self.f = open(self.swde_file "r") f.seek(0.0) tekstline = "" try: print u"Krok 3. Rozpoczynam import pliku: ", f.name, " ",strftime("%Y-%m-%d %H:%M:%S") i = 0; procent_wykonania = 0; #do monitorowania postepu linianr = 0 step = self.ilosc_linii/100 print u'ilość linii:',self.ilosc_linii, "step", step for line in f.readlines(): tekstline = line #zmienna tekstline bedzie wykorzystywana poza petla w celu lokalizacji bledu - w exception if i == step: i = 0 procent_wykonania += 1 sys.stdout.write("\r wykonano: %d%s" % (procent_wykonania, "%")) sys.stdout.flush() sleep(0.01) #print u"postęp:", procent_wykonania, u"%" line = unicode(line, txtcodec) #print "unikod zadzialal" i= i + 1 linianr+=1 #przyda sie jak sie program wypierniczy pocz = StringBetweenChar(line, ',',0) if pocz == "RO" or pocz == "RD" or pocz == "RC": #line = unicode(line, txtcodec) G5Table = StringBetweenChar(line, ',',2) g5id1_value = StringBetweenChar(line,',',3) g5id2_value = StringBetweenChar(line,',',4) if line[0:3] == "P,P": #self.dlg.peditOutput.appendPlainText(u"znaleziono ciąg line 0:3 = P,P") str1 = StringBetweenChar(line, ',', 2) #self.dlg.peditOutput.appendPlainText(u"str1 = " + str1 + u" o długości " + str(len(str1)) ) if str1 == u"G5PZG": #self.dlg.peditOutput.appendPlainText(u"wlazło") nr = StringBetweenChar(line, ',', 3) #self.dlg.peditOutput.appendPlainText(u"nr = " + nr) #strnr = nr.rstrip(';\r')# trzeba usuwac pojedynczo czyli tak jak poniżej strnr = nr.rstrip()# czyli jakiekolwiek białe znaki niezaleznie czy \n \r itp strnr = strnr.rstrip(';') #self.dlg.peditOutput.appendPlainText(u"strnr = " + strnr) #oldline = line #self.dlg.peditOutput.appendPlainText(u"oldline = " + oldline) line = "P,G," + self.pzgdic[strnr] + ",;\n" #self.dlg.peditOutput.appendPlainText(u"line = " + line) #self.dlg.peditOutput.appendPlainText(u"Zastąpiono ciąg P,P >>" + oldline + "<< na >>" + line + "<< " + strftime("%Y-%m-%d %H:%M:%S")) if G5Table in tableList: colname = "" colvalue = "" znacznik = StringBetweenChar(line, ',',0) if znacznik == "D" or znacznik == "WG": line = line.rstrip() line = line.rstrip(';') # szczególnie linie ze znacznikami WG zakończone są średnikiem line = line.strip("'") line = line.strip('"') line = line.replace("'", '') line = line.replace('"', "") colname = StringBetweenChar(line,',',1) #zamiana nazw kolumn z polskimi znakami if colname in plcharCols: colname = plcharCols[colname] colvalue = StringBetweenChar(line,',',3) #dzialania wspolne dla wszystkich tablic if colname in g5Cols[G5Table]: #G5RDZE w G5KLU nie jest typu tablicowego, natomiast w g5BUD #jest. Na szczescie w g5klu nie ma żadnego pola tablicowego #to samo dotyczy g5radr - w g5osf i g5ins - nie jest array w przeciwienstwie do g5bud if colname in arrayCols and G5Table != 'G5KLU' and G5Table != 'G5INS' and G5Table != 'G5OSF': arraylist.append([colname,colvalue]) else: collist.append(colname) valuelist.append(colvalue) #dzialania nietypowe #TODO przewidziec dla g5obr wyluskanie numeru obrebu do osobnego pola if colname == 'G5IDD' and G5Table == "G5DZE": #trzeba wyluskac numer dzialki i zapisac do oddzielnej kolumny #nr_dzialki = StringBetweenChar(colvalue, '.', 2) collist.append(u'nr') valuelist.append(StringBetweenChar(colvalue, '.', 2)) #nr obrębu też się przyda collist.append(u'nrobr') valuelist.append(StringBetweenChar(colvalue, '.', 1)) if colname == 'G5RPOD': #dla tabel g5udz i g5udw - wyglada to nastepujaco: "WG,G5RPOD,G5OSF,5465;" #a więc najpierw mamy określenie do jakiej tabeli jest dowiązanie (osf, ins, mlz czy osz) #a potem wartość wiązania w danej tabeli. Należy więc jeszcze wyciągnąć wartość po drugim ',' collist.append(u'rpod_rodzaj') pod_rodzaj = StringBetweenChar(line, ',', 2) valuelist.append(pod_rodzaj) #kolumna zawierajaca polaczone ze soba wartosci collist.append(u'id_podmiot') valuelist.append(colvalue + pod_rodzaj) elif znacznik == "K": Kznak = StringBetweenChar(line, ',',1)#czyli albo '+;' albo '-;' Kznak = Kznak[0]#pozostawienie tylko + albo - newPoly = 1 polycount+=1 elif znacznik == "P": yvalue = StringBetweenChar(line, ',',2) xvalue = StringBetweenChar(line, ',',3) #print "xv:", xvalue, "yv:", yvalue if transform: #======================================= # p1 = pyproj.Proj(str(pyproj4strFrom)) # p2 = pyproj.Proj(str(pyproj4strTo)) # x92, y92 = pyproj.transform(p1,p2,xvalue,yvalue) # value = str(x92) + " " + str(y92) #======================================= pt1 = xform.transform(QgsPoint(float(xvalue), float(yvalue))) value = str(pt1[0]) + " " + str(pt1[1]) else: value = xvalue + " " + yvalue point.append( polycount) point.append(newPoly) point.append(Kznak) point.append(value) pointslist.append(point) #print point point = [] newPoly = 0 elif znacznik[0] == "X": #czyli koniec definicji recordu #print "2 line", line #print "2 znacznik = ", znacznik, collist, valuelist p = "" p1 = "" if len(pointslist)>0: for points in pointslist: if points[1] == 1:#newPoly #p1 = points[3] if points[0] == 1:#czyli pierwszy i byc moze jedyny polygon if srid == -1: #niezdefiniowany układ p = "POLYGON((" else: p = "@ST_GeomFromText(\'POLYGON((" else: #czyli ewentualne kolejne polygony p = p + p1 + "),(" p1 = points[3] p = p + points[3] + ',' if srid == -1: p = p + p1 + "))" else: p = p + p1 + "))\'," + srid + ")" collist.append("geom") valuelist.append(p) #dodanie kolumn tablicowych if len(arraylist) > 0: old_col = '' arraystr = "ARRAY[" arraylist.sort() for col, val in arraylist: if old_col == '': #startujemy old_col = col if col == old_col: arraystr += "\'"+ val + "\'," else: #nastąpiła zmiana columny arraystr = arraystr.rstrip(",") arraystr += "]" collist.append(old_col) valuelist.append(arraystr) old_col = col arraystr = "ARRAY[\'" + val + "\'," collist.append(old_col) arraystr = arraystr.rstrip(",") arraystr += ']' valuelist.append(arraystr) arraylist = [] #dodatnie self.id_jed_rej do kazdej tabeli collist.append("id_zd") valuelist.append(self.id_jed_rej) #dodanie id1 i id2 do kazdej z tabel collist.append("g5id1") valuelist.append(g5id1_value) collist.append("g5id2") valuelist.append(g5id2_value) #dodanie unikatowej kolumny - będzie stanowiła klucz główny w całej bazie collist.append('tab_uid') valuelist.append(self.id_jed_rej+g5id1_value) #sprawdzenie czy jest jeszcze jakas tablica, ktora nie zostala dodana do valuelist if len(arrayvalue)>0: collist.append(arrayname) values = "" for value in arrayvalue: values += "\'" + value.strip('[]') + "\'," values = values.rstrip(",")#usuniecie ostatniego przecinka valuelist.append(u"ARRAY[" + values + "]") arrayname = '' arrayvalue = [] rdg5Table[G5Table].insert(0, collist, valuelist) if G5Table in insertdic: insertdic[G5Table] += 1 else: insertdic[G5Table] = 1 #obieg+=1 #if obieg == 1000: # rdbase.commit() # obieg = 0 obieg+=1 collist = [] valuelist = [] pointslist = [] Kznak = "" polycount = 0 G5Table = "" if rodz_importu == 'testowyJEW': #w tym przypadku nie ma co dalej ciągnąć pętli break #i = i+1 except Exception, ex: cols = "[" values = "[" for col in collist: cols += col + ", " for value in valuelist: values += value + ", " cols += "]" values += "]" print u"błąd: ", uni(G5Table), uni(cols), uni(values), "rekord nr: ", uni(str(obieg)), "line = ", uni(tekstline), "error: ",uni(str(ex)) #przerwanie = 1 finally: rdbase.commit() print "wykonano commita" insstr = "" for tab, ilosc in insertdic.items(): insstr += tab + ':' + str(ilosc) + '; ' print "tab:", tab print "zapisano do bazy: ",str(obieg), u" rekordów: ", insstr f.close() except IOError: print "IOError: ", strftime("%Y-%m-%d %H:%M:%S") print "przerobiono lini: ", str(linianr) print "Koniec programu: ", strftime("%Y-%m-%d %H:%M:%S")
def generateFootprintsForFilmVertical(self): self.reloadFpLayer() self.reloadCpLayer() # Error wenn nur ein punkt vorhanden if self.cpLayer.featureCount() > 1: caps = self.fpLayer.dataProvider().capabilities() if caps & QgsVectorDataProvider.AddFeatures: #Get FORM1 from FilmInfoDict f1 = self.currentFilmInfoDict["form1"] # Image height f2 = self.currentFilmInfoDict["form2"] # Image width iterFeatures = self.cpLayer.getFeatures() iterNext = self.cpLayer.getFeatures() existingFootpints = QgsVectorLayerUtils.getValues( self.fpLayer, "bildnummer")[0] ft = QgsFeature() ftNext = QgsFeature() iterNext.nextFeature(ftNext) fpFeats = [] kappasToUpdate = {} # iterate over points from CP Layer > LON, LAT i = 0 while iterFeatures.nextFeature(ft): i += 1 iterNext.nextFeature(ftNext) p = QgsPointXY(ft.geometry().asPoint()) if ft['bildnummer'] in existingFootpints: pPrevGeom = QgsGeometry(ft.geometry()) #QMessageBox.warning(None, u"Bild Nummern", u"Footprint für das Bild mit der Nummer {0} wurde bereits erstellt.".format(ft['BILD'])) continue if i == 1: pPrevGeom = QgsGeometry(ftNext.geometry()) #if iterNext.isClosed(): # #use pPrev as pNext # pNext = QgsPoint(pPrev) #else: # pNext = QgsPoint(ftNext.geometry().asPoint()) #kappa = p.azimuth(pPrev) #kappa = p.azimuth(pNext) # d = math.sqrt(2*((f1/2 * ft['MASS']/1000)**2)) d1 = f1 / 2 * ft['massstab'] / 1000 d2 = f2 / 2 * ft['massstab'] / 1000 #QMessageBox.warning(None, u"Bild Nummern", "{0}".format(d)) calcCrs = QgsCoordinateReferenceSystem() calcCrs.createFromProj4(self.Proj4Utm(p)) ctF = QgsCoordinateTransform(self.cpLayer.crs(), calcCrs, QgsProject.instance()) cpMetric = QgsGeometry(ft.geometry()) cpMetric.transform(ctF) pPrevGeom.transform(ctF) pMetric = QgsPointXY(cpMetric.asPoint()) pPrevMetric = QgsPointXY(pPrevGeom.asPoint()) kappaMetric = pMetric.azimuth(pPrevMetric) pPrevGeom = QgsGeometry(ft.geometry()) left = pMetric.x() - d2 bottom = pMetric.y() - d1 right = pMetric.x() + d2 top = pMetric.y() + d1 #R = 6371 #D = (d/1000) #cpLat = math.radians(p.y()) #cpLon = math.radians(p.x()) #urLat = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R)*math.cos(urBrng) ) #urLon = cpLon + math.atan2(math.sin(urBrng)*math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(urLat)) #top = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R) ) #bottom = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R)*-1 ) #lat = math.asin( math.sin(cpLat)*math.cos(D/R) ) #right = cpLon + math.atan2(math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(lat)) #left = cpLon + math.atan2(-1*math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(lat)) #QMessageBox.warning(None, u"Bild Nummern", "{0}, {1}, {2}, {3}".format(math.degrees(top), math.degrees(bottom), math.degrees(left), math.degrees(right))) #rect = QgsRectangle(math.degrees(left), math.degrees(bottom), math.degrees(right), math.degrees(top)) #l = math.degrees(left) #b = math.degrees(bottom) #r = math.degrees(right) #t = math.degrees(top) p1 = QgsGeometry.fromPointXY(QgsPointXY(left, bottom)) p2 = QgsGeometry.fromPointXY(QgsPointXY(right, bottom)) p3 = QgsGeometry.fromPointXY(QgsPointXY(right, top)) p4 = QgsGeometry.fromPointXY(QgsPointXY(left, top)) #p1.rotate(kappa+90, p) #p2.rotate(kappa+90, p) #p3.rotate(kappa+90, p) #p4.rotate(kappa+90, p) pol = [[ p1.asPoint(), p2.asPoint(), p3.asPoint(), p4.asPoint() ]] geom = QgsGeometry.fromPolygonXY(pol) geom.rotate(kappaMetric, pMetric) #Transform to DestinationCRS ctB = QgsCoordinateTransform(calcCrs, self.fpLayer.crs(), QgsProject.instance()) geom.transform(ctB) feat = QgsFeature(self.fpLayer.fields()) feat.setGeometry(geom) feat.setAttribute('filmnummer', self.currentFilmNumber) feat.setAttribute('bildnummer', ft['bildnummer']) da = QgsDistanceArea() da.setEllipsoid(self.fpLayer.crs().ellipsoidAcronym()) feat.setAttribute('shape_length', da.measurePerimeter(geom)) feat.setAttribute('shape_area', da.measureArea(geom)) fpFeats.append(feat) # update Kappa in cpLayer kappasToUpdate[ft.id()] = { ft.fieldNameIndex('kappa'): kappaMetric } iterFeatures.close() iterNext.close() resCAVs = self.cpLayer.dataProvider().changeAttributeValues( kappasToUpdate) QgsMessageLog.logMessage( f"Kappa Update for {kappasToUpdate}, Success: {resCAVs}", tag="APIS", level=Qgis.Success if resCAVs else Qgis.Critical) (res, outFeats) = self.fpLayer.dataProvider().addFeatures(fpFeats) self.fpLayer.updateExtents() if self.canvas.isCachingEnabled(): self.fpLayer.triggerRepaint() else: self.canvas.refresh() else: #Caps QMessageBox.warning(None, "Layer Capabilities!", "Layer Capabilities!") else: #small feature count QMessageBox.warning( None, "Footprints", "Zum Berechnen der senkrecht Footprint müssen mindestens zwei Bilder kartiert werden!" )
def importuj(self): #ponizsze troche z lenistwa - pozostalosc po starym kodzie, nie chce mi sie szukac zmiennych i dopisywac #self przed kazda swde_file = self.swde_file tableListString = self.tableListString srid = self.srid pyproj4strFrom = self.pyproj4strFrom pyproj4strTo = self.pyproj4strTo rodz_importu = self.rodz_importu pgserver = self.pgserver pgbase = self.pgbase pguser = self.pguser pguserpswd = self.pguserpswd txtcodec = self.txtcodec id_zd = self.id_zd crs_source = QgsCoordinateReferenceSystem() crs_source.createFromProj4(str(pyproj4strFrom)) crs_dest = QgsCoordinateReferenceSystem() crs_dest.createFromProj4(str(pyproj4strTo)) xform = QgsCoordinateTransform(crs_source, crs_dest) tableList = [] #tabela nazw tabel w bazie tableList = tableListString.split(',') import_testowy = False if rodz_importu == 'testowyJEW' or rodz_importu == 'testowyOBR' or rodz_importu == 'testowyDZE': import_testowy = True for tabName in tableList: if tabName <> 'NONE': print tabName print srid print pyproj4strFrom print pyproj4strTo print "identyfikator jednostki rejestrowej:", self.id_jed_rej print "ilość linii", self.ilosc_linii print "rodzaj importu", rodz_importu print pgserver, pgbase, pguser, pguserpswd uni = lambda s: s if type(s) == unicode else unicode( s, 'utf-8', 'replace') try: f = open(swde_file, "r") if f == 0 or f.closed: print u"Przed rozpoczęciem importu musisz wczytać plik" else: if id_zd == 'NONE': #parametr wybierany przez uzytkownika, jesli jest inny niz NONE self.id_jed_rej = str(self.id_jed_rej).rstrip( ) #zostanie uzyty jako wymuszenie nazwy zbioru danych else: #w innym przypadku uzyta zostanie nazwa jednostki rej wyłuskana przez program self.id_jed_rej = id_zd #lista column tablicowych - do innej obróbki niż pozostałe arrayCols = [ 'G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RSKD', 'G5RDOK', 'G5RDZE', 'G5ROBJ' ] #słownik kolumn do zmiany nazwy - zmieniamy polskie znaki w nazwie kolumn bo trochę to broi przy pytaniach SQL plcharCols = { u'G5RŻONA': 'G5RZONA', u'G5RMĄŻ': 'G5RMAZ', u'G5RPWŁ': 'G5RPWL', u'G5RWŁ': 'G5RWL', u'G5RWŁS': 'G5RWLS', u'G5RWŁD': 'G5RWLD' } g5Cols = { } #słownik zbudowany: {'nazwa_tabeli':Tablica_Column[]} - posluzy do inicjacji tabel - obiektow robdbtable #inicjalizacja bazy danych rdbase = RobDBBase(pgserver, pgbase, pguser, pguserpswd, 1) rdg5Table = { } #słownik zawiera następującą strukturę: {'nazwa_tabeli': Obiekt_rdbtable} #okreslenie rodzaju importu if rodz_importu == 'zwykly' or rodz_importu == 'aktualizacja': Cols = [ 'G5IDJ', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU', 'G5RKRG' ] #g5jew g5Cols['G5JEW'] = Cols Cols = [ 'G5IDD', 'GEOM', 'NR', 'G5IDR', 'G5NOS', 'G5WRT', 'G5DWR', 'G5PEW', 'G5RZN', 'G5DWW', 'G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RJDR', 'G5DTW', 'G5DTU' ] #g5dze g5Cols['G5DZE'] = Cols Cols = [ 'G5NRO', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU', 'G5RKRG', 'G5RJEW', 'IDJEW' ] #g5obr g5Cols['G5OBR'] = Cols Cols = [ 'G5PLC', 'G5PSL', 'G5NIP', 'G5NZW', 'G5PIM', 'G5DIM', 'G5OIM', 'G5MIM', 'G5OBL', 'G5DOS', 'G5RADR', 'G5STI', 'G5DTW', 'G5DTU' ] #g5osf g5Cols['G5OSF'] = Cols Cols = [ 'G5STI', 'G5NPE', 'G5NSK', 'G5RGN', 'G5NIP', 'G5NZR', 'G5NRR', 'G5NSR', 'G5RADR', 'G5DTW', 'G5DTU' ] #g5ins g5Cols['G5INS'] = Cols Cols = ['G5RZONA', 'G5RMAZ', 'G5DTW', 'G5DTU'] #g5mlz g5Cols['G5MLZ'] = Cols Cols = [ 'G5STI', 'G5NPE', 'G5NSK', 'G5RGN', 'G5NIP', 'G5RSKD', 'G5RADR', 'G5DTW', 'G5DTU' ] #g5osz g5Cols['G5OSZ'] = Cols Cols = [ 'G5TJR', 'G5IJR', 'G5RGN', 'G5RWL', 'G5RWLS', 'G5RWLD', 'G5ROBR', 'G5DTW', 'G5DTU' ] #g5jdr g5Cols['G5JDR'] = Cols Cols = ['G5UD', 'G5RWLS', 'G5RPOD', 'G5DTW', 'G5DTU'] #g5udz g5Cols['G5UDZ'] = Cols Cols = [ 'G5RWD', 'G5UD', 'G5RWLD', 'G5RPOD', 'G5DTW', 'G5DTU' ] #g5udw g5Cols['G5UDW'] = Cols Cols = [ 'G5OFU', 'G5OZU', 'G5OZK', 'G5PEW', 'G5RDZE', 'G5DTW', 'G5DTU' ] #g5klu g5Cols['G5KLU'] = Cols Cols = [ 'G5IDT', 'G5OZU', 'G5OFU', 'G5PEW', 'G5RKRG', 'G5ROBR', 'G5DTW', 'G5DTU' ] #g5uzg g5Cols['G5UZG'] = Cols Cols = [ 'G5KDK', 'G5DTD', 'G5DTP', 'G5SYG', 'G5NSR', 'G5OPD', 'G5RDOK', 'G5DTW', 'G5DTU' ] #g5dok g5Cols['G5DOK'] = Cols Cols = [ 'G5TAR', 'G5NAZ', 'G5KRJ', 'G5WJD', 'G5PWJ', 'G5GMN', 'G5ULC', 'G5NRA', 'G5NRL', 'G5MSC', 'G5KOD', 'G5PCZ', 'G5DTW', 'G5DTU' ] #g5adr g5Cols['G5ADR'] = Cols Cols = [ 'G5IDB', 'G5FUZ', 'G5WRT', 'G5DWR', 'G5RBB', 'G5PEW', 'G5PEU', 'G5RZN', 'G5SCN', 'G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RJDR', 'G5RDZE', 'G5DTU', 'G5DTW' ] #g5bud g5Cols['G5BUD'] = Cols Cols = [ 'G5IDK', 'G5OZU', 'G5OZK', 'G5PEW', 'G5RKRG', 'G5ROBR', 'G5DTW', 'G5DTU' ] g5Cols['G5KKL'] = Cols Cols = [ 'G5IDL', 'G5TLOK', 'G5PEW', 'G5PPP', 'G5LIZ', 'G5WRT', 'G5DWR', 'G5RJDR', 'G5RADR', 'G5RDOK', 'G5RBUD', 'G5DTW', 'G5DTU' ] g5Cols['G5LKL'] = Cols Cols = [ 'G5NRZ', 'G5STZ', 'G5DZZ', 'G5DTA', 'G5DTZ', 'G5NAZ', 'G5ROBJ', 'G5RDOK', 'G5DTW', 'G5DTU' ] g5Cols['G5ZMN'] = Cols elif rodz_importu == 'testowyJEW' or rodz_importu == 'testowyOBR' or rodz_importu == 'testowyDZE': #teoretycznie powinno wystarczyć zwykle elif bez parametrow, ale na wszelki dorzuce te ory #w przypadku importu testowego importować będziemy tylko jedną z trzech tabel (dze, obr, lub jew) # przy okazji opróżnimy zawartość dotychczasowych tabel testowych delSQLstr = "delete from " if rodz_importu == 'testowyJEW': tableList.append('G5JEW') g5Cols['G5JEW'] = [ 'G5IDJ', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU', 'G5RKRG' ] #g5jew delSQLstr += "g5jew_test;" elif rodz_importu == 'testowyOBR': tableList.append('G5OBR') g5Cols['G5OBR'] = [ 'G5NRO', 'G5PEW', 'G5NAZ', 'G5DTW', 'G5DTU', 'G5RKRG', 'G5RJEW', 'IDJEW' ] delSQLstr += "g5obr_test;" elif rodz_importu == 'testowyDZE': tableList.append('G5DZE') g5Cols['G5DZE'] = [ 'G5IDD', 'GEOM', 'NR', 'G5IDR', 'G5NOS', 'G5WRT', 'G5DWR', 'G5PEW', 'G5RZN', 'G5DWW', 'G5RADR', 'G5RPWL', 'G5RPWD', 'G5RKRG', 'G5RJDR', 'G5DTW', 'G5DTU' ] delSQLstr += "g5dze_test;" rdbase.executeSQL(delSQLstr) #nazwy kolumn muszą zostać podane dokładnie jak w bazie - czyli małymi literami #na przyszłość można to rozwiązać w samej RobDBTable #za zamianę liter na małe w tablicy odpowiada ta fikuśna konstrukcja: [x.lower() ....] for tableName in tableList: if import_testowy: appendix = '_TEST' else: appendix = '' rdg5Table[tableName] = RobDBTable( rdbase, tableName + appendix, [x.lower() for x in g5Cols[tableName]], 1, 1) G5Table = "" collist = [] valuelist = [] insertdic = {} # forma [nazwa_tabeli:ilosc_insertow] arraylist = [ ] #wykorzystywana do przechowywania kolumn typu tablicaowego w formie [[col2, wart..], [col1, wart..], [col2, wart..]] arrayvalue = [ ] # wykorzystywane do przechowywania danych 1+ takich jak g5rkrg arrayname = '' # nazwa tablicy tożsama z nazwą kolumny w bazie pointslist = [] point = [] Kznak = "" #znacznik + albo -, oznaczajacy czy okreslane sa punkty tworzace polygon czy #wycinajace w nim dziure oldKznak = "0" #posluzy do sprawdzenia czy nastapila zmiana Kznak newPoly = 0 polycount = 0 linianr = 0 #przyda sie w momencie gdy sie program wywali - okresli ktora linia pliku swde nabroiła obieg = 0 #bedzie wykorzystywane przy commit do bazy, ktore bedzie realizowane co np 100 pytań SQL transform = False if import_testowy == False: #tylko jesli nie jest to import testowy if pyproj4strFrom != pyproj4strTo: transform = True print "transform:", transform print "Krok 2. Start programu: ", strftime("%Y-%m-%d %H:%M:%S") if rodz_importu == 'aktualizacja': #usuniecie wszystkich rekordow o id_zd print u"Usuwanie rekordów ze zbioru danych o id = ", self.id_jed_rej #naprawde dziwna sprawa, ale bez tego dwukrotnie powtorzonego slepp-applicationevent print u"Rozpoczęcie usuwania aktualizowanych rekordów: ", strftime( "%Y-%m-%d %H:%M:%S") rdbase.executeSQL("SELECT g5sp_delfromtables('" + self.id_jed_rej + "');") print u"Zakończono usuwanie aktualizowanych rekordów: ", strftime( "%Y-%m-%d %H:%M:%S") #import_file = str(self.swde_file.toUtf8()).decode('utf-8') try: #self.f = open(self.swde_file "r") f.seek(0.0) tekstline = "" try: print u"Krok 3. Rozpoczynam import pliku: ", f.name, " ", strftime( "%Y-%m-%d %H:%M:%S") i = 0 procent_wykonania = 0 #do monitorowania postepu linianr = 0 step = self.ilosc_linii / 100 print u'ilość linii:', self.ilosc_linii, "step", step for line in f.readlines(): tekstline = line #zmienna tekstline bedzie wykorzystywana poza petla w celu lokalizacji bledu - w exception if i == step: i = 0 procent_wykonania += 1 sys.stdout.write("\r wykonano: %d%s" % (procent_wykonania, "%")) sys.stdout.flush() sleep(0.01) #print u"postęp:", procent_wykonania, u"%" line = unicode(line, txtcodec) #print "unikod zadzialal" i = i + 1 linianr += 1 #przyda sie jak sie program wypierniczy pocz = StringBetweenChar(line, ',', 0) if pocz == "RO" or pocz == "RD" or pocz == "RC": #line = unicode(line, txtcodec) G5Table = StringBetweenChar(line, ',', 2) g5id1_value = StringBetweenChar(line, ',', 3) g5id2_value = StringBetweenChar(line, ',', 4) if line[0:3] == "P,P": #self.dlg.peditOutput.appendPlainText(u"znaleziono ciąg line 0:3 = P,P") str1 = StringBetweenChar(line, ',', 2) #self.dlg.peditOutput.appendPlainText(u"str1 = " + str1 + u" o długości " + str(len(str1)) ) if str1 == u"G5PZG": #self.dlg.peditOutput.appendPlainText(u"wlazło") nr = StringBetweenChar(line, ',', 3) #self.dlg.peditOutput.appendPlainText(u"nr = " + nr) #strnr = nr.rstrip(';\r')# trzeba usuwac pojedynczo czyli tak jak poniżej strnr = nr.rstrip( ) # czyli jakiekolwiek białe znaki niezaleznie czy \n \r itp strnr = strnr.rstrip(';') #self.dlg.peditOutput.appendPlainText(u"strnr = " + strnr) #oldline = line #self.dlg.peditOutput.appendPlainText(u"oldline = " + oldline) line = "P,G," + self.pzgdic[strnr] + ",;\n" #self.dlg.peditOutput.appendPlainText(u"line = " + line) #self.dlg.peditOutput.appendPlainText(u"Zastąpiono ciąg P,P >>" + oldline + "<< na >>" + line + "<< " + strftime("%Y-%m-%d %H:%M:%S")) if G5Table in tableList: colname = "" colvalue = "" znacznik = StringBetweenChar(line, ',', 0) if znacznik == "D" or znacznik == "WG": line = line.rstrip() line = line.rstrip( ';' ) # szczególnie linie ze znacznikami WG zakończone są średnikiem line = line.strip("'") line = line.strip('"') line = line.replace("'", '') line = line.replace('"', "") colname = StringBetweenChar(line, ',', 1) #zamiana nazw kolumn z polskimi znakami if colname in plcharCols: colname = plcharCols[colname] colvalue = StringBetweenChar(line, ',', 3) #dzialania wspolne dla wszystkich tablic if colname in g5Cols[G5Table]: #G5RDZE w G5KLU nie jest typu tablicowego, natomiast w g5BUD #jest. Na szczescie w g5klu nie ma żadnego pola tablicowego #to samo dotyczy g5radr - w g5osf i g5ins - nie jest array w przeciwienstwie do g5bud if colname in arrayCols and G5Table != 'G5KLU' and G5Table != 'G5INS' and G5Table != 'G5OSF': arraylist.append( [colname, colvalue]) else: collist.append(colname) valuelist.append(colvalue) #dzialania nietypowe #TODO przewidziec dla g5obr wyluskanie numeru obrebu do osobnego pola if colname == 'G5IDD' and G5Table == "G5DZE": #trzeba wyluskac numer dzialki i zapisac do oddzielnej kolumny #nr_dzialki = StringBetweenChar(colvalue, '.', 2) collist.append(u'nr') valuelist.append( StringBetweenChar( colvalue, '.', 2)) #nr obrębu też się przyda collist.append(u'nrobr') valuelist.append( StringBetweenChar( colvalue, '.', 1)) if colname == 'G5RPOD': #dla tabel g5udz i g5udw - wyglada to nastepujaco: "WG,G5RPOD,G5OSF,5465;" #a więc najpierw mamy określenie do jakiej tabeli jest dowiązanie (osf, ins, mlz czy osz) #a potem wartość wiązania w danej tabeli. Należy więc jeszcze wyciągnąć wartość po drugim ',' collist.append(u'rpod_rodzaj') pod_rodzaj = StringBetweenChar( line, ',', 2) valuelist.append(pod_rodzaj) #kolumna zawierajaca polaczone ze soba wartosci collist.append(u'id_podmiot') valuelist.append(colvalue + pod_rodzaj) elif znacznik == "K": Kznak = StringBetweenChar( line, ',', 1) #czyli albo '+;' albo '-;' Kznak = Kznak[ 0] #pozostawienie tylko + albo - newPoly = 1 polycount += 1 elif znacznik == "P": yvalue = StringBetweenChar(line, ',', 2) xvalue = StringBetweenChar(line, ',', 3) #print "xv:", xvalue, "yv:", yvalue if transform: #======================================= # p1 = pyproj.Proj(str(pyproj4strFrom)) # p2 = pyproj.Proj(str(pyproj4strTo)) # x92, y92 = pyproj.transform(p1,p2,xvalue,yvalue) # value = str(x92) + " " + str(y92) #======================================= pt1 = xform.transform( QgsPoint(float(xvalue), float(yvalue))) value = str(pt1[0]) + " " + str(pt1[1]) else: value = xvalue + " " + yvalue point.append(polycount) point.append(newPoly) point.append(Kznak) point.append(value) pointslist.append(point) #print point point = [] newPoly = 0 elif znacznik[ 0] == "X": #czyli koniec definicji recordu #print "2 line", line #print "2 znacznik = ", znacznik, collist, valuelist p = "" p1 = "" if len(pointslist) > 0: for points in pointslist: if points[1] == 1: #newPoly #p1 = points[3] if points[ 0] == 1: #czyli pierwszy i byc moze jedyny polygon if srid == -1: #niezdefiniowany układ p = "POLYGON((" else: p = "@ST_GeomFromText(\'POLYGON((" else: #czyli ewentualne kolejne polygony p = p + p1 + "),(" p1 = points[3] p = p + points[3] + ',' if srid == -1: p = p + p1 + "))" else: p = p + p1 + "))\'," + srid + ")" collist.append("geom") valuelist.append(p) #dodanie kolumn tablicowych if len(arraylist) > 0: old_col = '' arraystr = "ARRAY[" arraylist.sort() for col, val in arraylist: if old_col == '': #startujemy old_col = col if col == old_col: arraystr += "\'" + val + "\'," else: #nastąpiła zmiana columny arraystr = arraystr.rstrip(",") arraystr += "]" collist.append(old_col) valuelist.append(arraystr) old_col = col arraystr = "ARRAY[\'" + val + "\'," collist.append(old_col) arraystr = arraystr.rstrip(",") arraystr += ']' valuelist.append(arraystr) arraylist = [] #dodatnie self.id_jed_rej do kazdej tabeli collist.append("id_zd") valuelist.append(self.id_jed_rej) #dodanie id1 i id2 do kazdej z tabel collist.append("g5id1") valuelist.append(g5id1_value) collist.append("g5id2") valuelist.append(g5id2_value) #dodanie unikatowej kolumny - będzie stanowiła klucz główny w całej bazie collist.append('tab_uid') valuelist.append(self.id_jed_rej + g5id1_value) #sprawdzenie czy jest jeszcze jakas tablica, ktora nie zostala dodana do valuelist if len(arrayvalue) > 0: collist.append(arrayname) values = "" for value in arrayvalue: values += "\'" + value.strip( '[]') + "\'," values = values.rstrip( "," ) #usuniecie ostatniego przecinka valuelist.append(u"ARRAY[" + values + "]") arrayname = '' arrayvalue = [] rdg5Table[G5Table].insert( 0, collist, valuelist) if G5Table in insertdic: insertdic[G5Table] += 1 else: insertdic[G5Table] = 1 #obieg+=1 #if obieg == 1000: # rdbase.commit() # obieg = 0 obieg += 1 collist = [] valuelist = [] pointslist = [] Kznak = "" polycount = 0 G5Table = "" if rodz_importu == 'testowyJEW': #w tym przypadku nie ma co dalej ciągnąć pętli break #i = i+1 except Exception, ex: cols = "[" values = "[" for col in collist: cols += col + ", " for value in valuelist: values += value + ", " cols += "]" values += "]" print u"błąd: ", uni(G5Table), uni(cols), uni( values), "rekord nr: ", uni( str(obieg)), "line = ", uni( tekstline), "error: ", uni(str(ex)) #przerwanie = 1 finally: rdbase.commit() print "wykonano commita" insstr = "" for tab, ilosc in insertdic.items(): insstr += tab + ':' + str(ilosc) + '; ' print "tab:", tab print "zapisano do bazy: ", str( obieg), u" rekordów: ", insstr f.close() except IOError: print "IOError: ", strftime("%Y-%m-%d %H:%M:%S") print "przerobiono lini: ", str(linianr) print "Koniec programu: ", strftime("%Y-%m-%d %H:%M:%S")
def generateFootprintsForFilmOblique(self): self.reloadFpLayer() self.reloadCpLayer() caps = self.fpLayer.dataProvider().capabilities() if caps & QgsVectorDataProvider.AddFeatures: if self.cpLayer.dataProvider().featureCount() > 0: iter = self.cpLayer.getFeatures() existingFootpints = QgsVectorLayerUtils.getValues( self.fpLayer, "bildnummer")[0] cpFt = QgsFeature() fpFts = [] #iterate over points from CP Layer > LON, LAT while iter.nextFeature(cpFt): if cpFt['bildnummer'] in existingFootpints: #QMessageBox.warning(None, u"Bild Nummern", u"Footprint für das Bild mit der Nummer {0} wurde bereits erstellt.".format(ft['BILD'])) continue cp = cpFt.geometry() cpMetric = QgsGeometry(cp) destCrs = QgsCoordinateReferenceSystem() destCrs.createFromProj4(self.Proj4Utm(cp.asPoint())) coordTransformF = QgsCoordinateTransform( self.cpLayer.crs(), destCrs, QgsProject.instance()) coordTransformB = QgsCoordinateTransform( destCrs, self.cpLayer.crs(), QgsProject.instance()) cpMetric.transform(coordTransformF) if cpFt['radius'] == '': r = 175 else: r = float(cpFt['radius']) fpMetric = QgsGeometry(cpMetric.buffer(r, 18)) fp = QgsGeometry(fpMetric) fp.transform(coordTransformB) fpFt = QgsFeature(self.fpLayer.fields()) fpFt.setGeometry(fp) fpFt.setAttribute("bildnummer", cpFt["bildnummer"]) fpFt.setAttribute("filmnummer", cpFt["filmnummer"]) da = QgsDistanceArea() da.setEllipsoid(self.fpLayer.crs().ellipsoidAcronym()) fpFt.setAttribute('shape_length', da.measurePerimeter(fp)) fpFt.setAttribute('shape_area', da.measureArea(fp)) fpFts.append(fpFt) (res, outFeats) = self.fpLayer.dataProvider().addFeatures(fpFts) self.fpLayer.updateExtents() if self.canvas.isCachingEnabled(): self.fpLayer.triggerRepaint() else: self.canvas.refresh() else: QMessageBox.warning( None, "Keine Bildmittelpunkte", "Keine Bildmittelpunkte für den Film {0} vorhanden.". format(self.currentFilmNumber)) else: QMessageBox.warning( None, "Layer Capabilities", "AddFeature is not enabled ({0})".format( self.fpLayer.dataProvider().capabilitiesString()))