def test_projection(self): """Test that QGIS properly parses a wkt string. """ crs = QgsCoordinateReferenceSystem() wkt = ( 'GEOGCS["WGS 84",DATUM["WGS_1984",' 'SPHEROID["WGS 84",6378137,298.257223563,' 'AUTHORITY["EPSG","7030"]],' 'AUTHORITY["EPSG","6326"]],' 'PRIMEM["Greenwich",0,' 'AUTHORITY["EPSG","8901"]],' 'UNIT["degree",0.0174532925199433,' 'AUTHORITY["EPSG","9122"]],' 'AUTHORITY["EPSG","4326"]]' ) crs.createFromWkt(wkt) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id) # now test for a loaded layer path = os.path.join(os.path.dirname(__file__), 'tenbytenraster.asc') title = 'TestRaster' layer = QgsRasterLayer(path, title) auth_id = layer.crs().authid() self.assertEqual(auth_id, expected_auth_id)
def test_projection(self): """Test that QGIS properly parses a wkt string. """ crs = QgsCoordinateReferenceSystem() wkt = ('GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(wkt) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id)
def test_projection(self): """Test that QGIS properly parses a wkt string. """ crs = QgsCoordinateReferenceSystem() wkt = ( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(wkt) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id)
def coordinatetransform(self, layer=None): """ Return the transform for WGS84 -> QGIS projection. """ source = QgsCoordinateReferenceSystem() source.createFromWkt( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]' ) if not layer: dest = self.canvas.mapRenderer().destinationCrs() else: dest = layer.crs() transform = QgsCoordinateTransform(source, dest) return transform
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 coordinatetransform(self, layer=None): """ Return the transform for WGS84 -> QGIS projection. """ source = QgsCoordinateReferenceSystem() source.createFromWkt( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]' ) if not layer: dest = self.canvas.mapRenderer().destinationCrs() else: dest = layer.crs() transform = QgsCoordinateTransform(source, dest) return transform
def test_projection(self): """Test that QGIS properly parses a wkt string. """ crs = QgsCoordinateReferenceSystem() wkt = ('GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(wkt) auth_id = crs.authid() self.assertIn(auth_id, ('EPSG:4326', 'OGC:CRS84')) # now test for a loaded layer path = os.path.join(os.path.dirname(__file__), 'tenbytenraster.asc') title = 'TestRaster' layer = QgsRasterLayer(path, title) auth_id = layer.crs().authid() self.assertIn(auth_id, ('EPSG:4326', 'OGC:CRS84'))
def _extractCrsFromPrj(self): crs = None if self._fileContainer.hasPrj(): with open(self._fileContainer.pathToPrj) as prjfile: crsWkt = prjfile.readline() _crs = QgsCoordinateReferenceSystem() if _crs.createFromWkt(crsWkt): crs = _crs return crs
def _extractCrsFromPrj(self): crs = None if self._fileContainer.hasPrj(): with open(self._fileContainer.pathToPrj) as prjfile: crsWkt = prjfile.readline() _crs = QgsCoordinateReferenceSystem() if _crs.createFromWkt(crsWkt): crs = _crs return crs
def test_projection(self): """QGIS properly parses a wkt string""" crs = QgsCoordinateReferenceSystem() wkt = ( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(wkt) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id) # now test for a loaded layer path = os.path.join(os.path.dirname(__file__), 'tenbytenraster.asc') title = 'TestRaster' layer = QgsRasterLayer(path, title) auth_id = layer.crs().authid() self.assertEqual(auth_id, expected_auth_id)
def testProjInterpretation(self): """Test that QGIS properly parses a proj4 string. see https://github.com/AIFDR/inasafe/issues/349 """ myCrs = QgsCoordinateReferenceSystem() myProj4 = ('GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') myCrs.createFromWkt(myProj4) myAuthId = myCrs.authid() myExpectedAuthId = 'EPSG:4326' self.assertEqual(myAuthId, myExpectedAuthId) # now test for a loaded layer myPath = os.path.join(EXPDATA, 'glp10ag.asc') myTitle = 'people' myLayer = QgsRasterLayer(myPath, myTitle) myAuthId = myLayer.crs().authid() self.assertEqual(myAuthId, myExpectedAuthId)
def test_projection(self): """Tests that QGIS properly parses a WKT string.""" crs = QgsCoordinateReferenceSystem() wkt = ('GEOGCS["GCS_WGS_1984",' 'DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],' 'UNIT["Degree",0.0174532925199433]]') crs.createFromWkt(wkt) auth_id = crs.authid() exp_auth_id = 'EPSG:4326' self.assertEqual(auth_id, exp_auth_id) # test for a loaded layer path = os.path.join(os.path.dirname(__file__), 'tenbytenraster.asc') lyr = QgsRasterLayer(path, 'TestRaster') auth_id = lyr.crs().authid() self.assertEqual(auth_id, exp_auth_id)
def test_proj_interpretation(self): """Test that QGIS properly parses a proj4 string. see https://github.com/AIFDR/inasafe/issues/349 """ # noinspection PyCallingNonCallable crs = QgsCoordinateReferenceSystem() proj4 = ('GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(proj4) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id) # now test for a loaded layer path = standard_data_path('hazard', 'jakarta_flood_design.tif') title = 'Jakarta Flood' # noinspection PyCallingNonCallable layer = QgsRasterLayer(path, title) auth_id = layer.crs().authid() self.assertEqual(auth_id, expected_auth_id)
def computeBoxAndAttributes(self, layer, line, extension, insertIntoMemory=True): """ Computes bounding box and inventory attributes """ # get the bounding box and wkt projection (ogrPoly, prjWkt) = self.getExtent(line) if ogrPoly == None or prjWkt == None: return # making a QGIS projection crsSrc = QgsCoordinateReferenceSystem() crsSrc.createFromWkt(prjWkt) # reprojecting the bounding box qgsPolygon = self.reprojectBoundingBox(crsSrc, ogrPoly) # making the attributes attributes = self.makeAttributes(line, extension) # inserting into memory layer if not insertIntoMemory: return qgsPolygon, attributes self.insertIntoMemoryLayer(layer, qgsPolygon, attributes)
def test_proj_interpretation(self): """Test that QGIS properly parses a proj4 string. see https://github.com/AIFDR/inasafe/issues/349 """ # noinspection PyCallingNonCallable crs = QgsCoordinateReferenceSystem() proj4 = ( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(proj4) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id) # now test for a loaded layer path = standard_data_path('hazard', 'jakarta_flood_design.tif') title = 'Jakarta Flood' # noinspection PyCallingNonCallable layer = QgsRasterLayer(path, title) auth_id = layer.crs().authid() self.assertEqual(auth_id, expected_auth_id)
class GSIElevTileProvider: def __init__(self, dest_wkt): self.dest_wkt = dest_wkt # crs transformer, which aims to calculate bbox in EPSG:3857 self.crs3857 = QgsCoordinateReferenceSystem(3857) self.dest_crs = QgsCoordinateReferenceSystem() if not self.dest_crs.createFromWkt(dest_wkt): logMessage("Failed to create CRS from WKT: {0}".format(dest_wkt)) self.transform = QgsCoordinateTransform(self.dest_crs, self.crs3857) # approximate bbox of this data self.boundingbox = QgsRectangle(13667807, 2320477, 17230031, 5713298) self.downloader = Downloader() self.downloader.userAgent = "QGIS/{0} Qgis2threejs GSIElevTileProvider".format(QGis.QGIS_VERSION) # not written since QGIS 2.2 self.downloader.DEFAULT_CACHE_EXPIRATION = QSettings().value("/qgis/defaultTileExpiry", 24, type=int) self.driver = gdal.GetDriverByName("MEM") self.last_dataset = None def name(self): return "GSI Elevation Tile" def read(self, width, height, extent): # calculate bounding box in EPSG:3857 geometry = extent.geometry() geometry.transform(self.transform) merc_rect = geometry.boundingBox() # if the bounding box doesn't intersect with the bounding box of this data, return a list filled with nodata value if not self.boundingbox.intersects(merc_rect): return [NODATA_VALUE] * width * height # get tiles over_smpl = 1 segments_x = 1 if width == 1 else width - 1 res = extent.width() / segments_x / over_smpl ds = self.getDataset(merc_rect.xMinimum(), merc_rect.yMinimum(), merc_rect.xMaximum(), merc_rect.yMaximum(), res) geotransform = extent.geotransform(width, height) return self._read(ds, width, height, geotransform) def readValue(self, x, y): """Get value at the position using 1px * 1px memory raster. The value is calculated using a tile of max zoom level""" # coordinate transformation into EPSG:3857 pt = self.transform.transform(QgsPoint(x, y)) # if the point is not within the bounding box of this data, return nodata value if not self.boundingbox.contains(pt): return NODATA_VALUE res = 0.1 hres = res / 2 ds = self.getDataset(pt.x() - hres, pt.y() - hres, pt.x() + hres, pt.y() + hres, res) geotransform = [x - hres, res, 0, y + hres, 0, -res] return self._read(ds, 1, 1, geotransform)[0] def _read(self, ds, width, height, geotransform): # create a memory dataset warped_ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32) warped_ds.SetProjection(self.dest_wkt) warped_ds.SetGeoTransform(geotransform) # reproject image gdal.ReprojectImage(ds, warped_ds, None, None, gdal.GRA_Bilinear) # load values into an array band = warped_ds.GetRasterBand(1) fs = "f" * width * height return struct.unpack(fs, band.ReadRaster(0, 0, width, height, buf_type=gdal.GDT_Float32)) def getDataset(self, xmin, ymin, xmax, ymax, mapUnitsPerPixel): # calculate zoom level mpp1 = TSIZE1 / TILE_SIZE zoom = int(math.ceil(math.log(mpp1 / mapUnitsPerPixel, 2) + 1)) zoom = max(0, min(zoom, ZMAX)) # calculate tile range (yOrigin is top) size = TSIZE1 / 2 ** (zoom - 1) matrixSize = 2 ** zoom ulx = max(0, int((xmin + TSIZE1) / size)) uly = max(0, int((TSIZE1 - ymax) / size)) lrx = min(int((xmax + TSIZE1) / size), matrixSize - 1) lry = min(int((TSIZE1 - ymin) / size), matrixSize - 1) cols = lrx - ulx + 1 rows = lry - uly + 1 # download count limit if cols * rows > 128: logMessage("Number of tiles to fetch is too large!") width = height = 1 return self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) if self.last_dataset and self.last_dataset[0] == [zoom, ulx, uly, lrx, lry]: # if same as last tile set, return cached dataset return self.last_dataset[1] urltmpl = "http://cyberjapandata.gsi.go.jp/xyz/dem/{z}/{x}/{y}.txt" #urltmpl = "http://localhost/xyz/dem/{z}/{x}/{y}.txt" tiles = self.fetchFiles(urltmpl, zoom, ulx, uly, lrx, lry) # create a memory dataset width = cols * TILE_SIZE height = rows * TILE_SIZE res = size / TILE_SIZE geotransform = [ulx * size - TSIZE1, res, 0, TSIZE1 - uly * size, 0, -res] #mem_driver = gdal.GetDriverByName("GTiff") #ds = mem_driver.Create("D:/fetched_tile.tif", width, height, 1, gdal.GDT_Float32, []) ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) ds.SetProjection(str(self.crs3857.toWkt())) ds.SetGeoTransform(geotransform) band = ds.GetRasterBand(1) for i, tile in enumerate(tiles): if tile: col = i % cols row = i / cols band.WriteRaster(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile) ds.FlushCache() self.last_dataset = [[zoom, ulx, uly, lrx, lry], ds] # cache dataset return ds def fetchFiles(self, urltmpl, zoom, xmin, ymin, xmax, ymax): downloadTimeout = 60 urls = [] for y in range(ymin, ymax + 1): for x in range(xmin, xmax + 1): urls.append(urltmpl.replace("{x}", str(x)).replace("{y}", str(y)).replace("{z}", str(zoom))) files = self.downloader.fetchFiles(urls, downloadTimeout) for url in urls: data = files[url] if data: yield numpy.fromstring(data.replace("e", str(NODATA_VALUE)).replace("\n", ","), dtype=numpy.float32, sep=",").tostring() # to byte array else: array = numpy.empty(TILE_SIZE * TILE_SIZE, dtype=numpy.float32) array.fill(NODATA_VALUE) yield array.tostring()
class GSIElevTileProvider: def __init__(self, dest_wkt): self.dest_wkt = dest_wkt # crs transformer, which aims to calculate bbox in EPSG:3857 self.crs3857 = QgsCoordinateReferenceSystem(3857) self.dest_crs = QgsCoordinateReferenceSystem() if not self.dest_crs.createFromWkt(dest_wkt): logMessage("Failed to create CRS from WKT: {0}".format(dest_wkt)) self.transform = QgsCoordinateTransform(self.dest_crs, self.crs3857, QgsProject.instance()) # approximate bbox of this data self.boundingbox = QgsRectangle(13667807, 2320477, 17230031, 5713298) self.downloader = Downloader() self.downloader.userAgent = "QGIS/{0} Qgis2threejs GSIElevTileProvider".format( Qgis.QGIS_VERSION_INT ) # will be overwritten in QgsNetworkAccessManager::createRequest() since 2.2 self.downloader.DEFAULT_CACHE_EXPIRATION = QSettings().value( "/qgis/defaultTileExpiry", 24, type=int) self.driver = gdal.GetDriverByName("MEM") self.last_dataset = None def name(self): return "GSI Elevation Tile" def read(self, width, height, extent): # calculate bounding box in EPSG:3857 geometry = extent.geometry() geometry.transform(self.transform) merc_rect = geometry.boundingBox() # if the bounding box doesn't intersect with the bounding box of this data, return a list filled with nodata value if not self.boundingbox.intersects(merc_rect): return [NODATA_VALUE] * width * height # get tiles over_smpl = 1 segments_x = 1 if width == 1 else width - 1 res = extent.width() / segments_x / over_smpl ds = self.getDataset(merc_rect.xMinimum(), merc_rect.yMinimum(), merc_rect.xMaximum(), merc_rect.yMaximum(), res) geotransform = extent.geotransform(width, height) return self._read(ds, width, height, geotransform) def readValue(self, x, y): """Get value at the position using 1px * 1px memory raster. The value is calculated using a tile of max zoom level""" # coordinate transformation into EPSG:3857 pt = self.transform.transform(QgsPoint(x, y)) # if the point is not within the bounding box of this data, return nodata value if not self.boundingbox.contains(pt): return NODATA_VALUE res = 0.1 hres = res / 2 ds = self.getDataset(pt.x() - hres, pt.y() - hres, pt.x() + hres, pt.y() + hres, res) geotransform = [x - hres, res, 0, y + hres, 0, -res] return self._read(ds, 1, 1, geotransform)[0] def _read(self, ds, width, height, geotransform): # create a memory dataset warped_ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32) warped_ds.SetProjection(self.dest_wkt) warped_ds.SetGeoTransform(geotransform) # reproject image gdal.ReprojectImage(ds, warped_ds, None, None, gdal.GRA_Bilinear) # load values into an array band = warped_ds.GetRasterBand(1) fs = "f" * width * height return struct.unpack( fs, band.ReadRaster(0, 0, width, height, buf_type=gdal.GDT_Float32)) def getDataset(self, xmin, ymin, xmax, ymax, mapUnitsPerPixel): # calculate zoom level mpp1 = TSIZE1 / TILE_SIZE zoom = int(math.ceil(math.log(mpp1 / mapUnitsPerPixel, 2) + 1)) zoom = max(0, min(zoom, ZMAX)) # calculate tile range (yOrigin is top) size = TSIZE1 / 2**(zoom - 1) matrixSize = 2**zoom ulx = max(0, int((xmin + TSIZE1) / size)) uly = max(0, int((TSIZE1 - ymax) / size)) lrx = min(int((xmax + TSIZE1) / size), matrixSize - 1) lry = min(int((TSIZE1 - ymin) / size), matrixSize - 1) cols = lrx - ulx + 1 rows = lry - uly + 1 # download count limit if cols * rows > 128: logMessage("Number of tiles to fetch is too large!") width = height = 1 return self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) if self.last_dataset and self.last_dataset[0] == [ zoom, ulx, uly, lrx, lry ]: # if same as last tile set, return cached dataset return self.last_dataset[1] urltmpl = "http://cyberjapandata.gsi.go.jp/xyz/dem/{z}/{x}/{y}.txt" #urltmpl = "http://localhost/xyz/dem/{z}/{x}/{y}.txt" tiles = self.fetchFiles(urltmpl, zoom, ulx, uly, lrx, lry) # create a memory dataset width = cols * TILE_SIZE height = rows * TILE_SIZE res = size / TILE_SIZE geotransform = [ ulx * size - TSIZE1, res, 0, TSIZE1 - uly * size, 0, -res ] #mem_driver = gdal.GetDriverByName("GTiff") #ds = mem_driver.Create("D:/fetched_tile.tif", width, height, 1, gdal.GDT_Float32, []) ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) ds.SetProjection(str(self.crs3857.toWkt())) ds.SetGeoTransform(geotransform) band = ds.GetRasterBand(1) for i, tile in enumerate(tiles): if tile: col = i % cols row = i // cols band.WriteRaster(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile) ds.FlushCache() self.last_dataset = [[zoom, ulx, uly, lrx, lry], ds] # cache dataset return ds def fetchFiles(self, urltmpl, zoom, xmin, ymin, xmax, ymax): downloadTimeout = 60 urls = [] for y in range(ymin, ymax + 1): for x in range(xmin, xmax + 1): urls.append( urltmpl.replace("{x}", str(x)).replace("{y}", str(y)).replace( "{z}", str(zoom))) files = self.downloader.fetchFiles(urls, downloadTimeout) for url in urls: data = files[url] if data: yield numpy.fromstring(data.replace( b"e", NODATA_VALUE_BYTES).replace(b"\n", b","), dtype=numpy.float32, sep=",").tostring() # to byte array else: array = numpy.empty(TILE_SIZE * TILE_SIZE, dtype=numpy.float32) array.fill(NODATA_VALUE) yield array.tostring()
def getCRS_3857(): wkt = 'PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],EXTENSION["PROJ4","+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"],AUTHORITY["EPSG","3857"]]' crs = QgsCoordinateReferenceSystem() crs.createFromWkt(wkt) return crs