diff --git a/src/plugins/grass/qgsgrassnewmapset.cpp b/src/plugins/grass/qgsgrassnewmapset.cpp index ff5b01bca9db..df3896cc666d 100644 --- a/src/plugins/grass/qgsgrassnewmapset.cpp +++ b/src/plugins/grass/qgsgrassnewmapset.cpp @@ -32,9 +32,6 @@ #include "qgsgui.h" #include "qgsextentwidget.h" -#include "cpl_conv.h" -#include "ogr_srs_api.h" - #include #include #include @@ -402,19 +399,9 @@ void QgsGrassNewMapset::setGrassProjection() const QString wkt = crs.toWkt( QgsCoordinateReferenceSystem::WktVariant::WKT_PREFERRED ); QgsDebugMsgLevel( QStringLiteral( "wkt = %1" ).arg( crs.toWkt( Qgis::CrsWktVariant::Preferred ) ), 3 ); - // Note: GPJ_osr_to_grass() defaults in PROJECTION_XY if projection - // cannot be set - G_TRY { - // There was a bug in GRASS, it is present in 6.0.x line - int ret = GPJ_wkt_to_grass( &mCellHead, &mProjInfo, &mProjUnits, wkt.toUtf8().constData(), 0 ); - // Note: It seems that GPJ_osr_to_grass()returns always 1, - // -> test if mProjInfo was set - - Q_UNUSED( ret ) - QgsDebugMsgLevel( QString( "ret = %1" ).arg( ret ), 2 ); - QgsDebugMsgLevel( QString( "mProjInfo = %1" ).arg( QString::number( static_cast( mProjInfo ), 16 ).toLocal8Bit().constData() ), 2 ); + GPJ_wkt_to_grass( &mCellHead, &mProjInfo, &mProjUnits, wkt.toUtf8().constData(), 0 ); } G_CATCH( QgsGrass::Exception & e ) { @@ -426,6 +413,11 @@ void QgsGrassNewMapset::setGrassProjection() { setError( mProjErrorLabel, tr( "Selected projection is not supported by GRASS!" ) ); } + else + { + mProjSrid = crs.authid().toUpper(); + mProjWkt = wkt; + } } else // Nothing selected { @@ -433,6 +425,8 @@ void QgsGrassNewMapset::setGrassProjection() mCellHead.zone = 0; mProjInfo = nullptr; mProjUnits = nullptr; + mProjSrid.clear(); + mProjWkt.clear(); } button( QWizard::NextButton )->setEnabled( mProjInfo && mProjUnits ); } @@ -1110,7 +1104,10 @@ void QgsGrassNewMapset::createMapset() QString error; G_TRY { - ret = G_make_location( location.toUtf8().constData(), &mCellHead, mProjInfo, mProjUnits ); + ret = G_make_location_crs( location.toUtf8().constData(), + &mCellHead, mProjInfo, mProjUnits, + mProjSrid.toUtf8().constData(), + mProjWkt.toUtf8().constData() ); } G_CATCH( QgsGrass::Exception & e ) { diff --git a/src/plugins/grass/qgsgrassnewmapset.h b/src/plugins/grass/qgsgrassnewmapset.h index 4c34e01a34be..0d423290ef6e 100644 --- a/src/plugins/grass/qgsgrassnewmapset.h +++ b/src/plugins/grass/qgsgrassnewmapset.h @@ -195,6 +195,8 @@ class QgsGrassNewMapset : public QWizard, private Ui::QgsGrassNewMapsetBase struct Cell_head mCellHead; struct Key_Value *mProjInfo = nullptr; struct Key_Value *mProjUnits = nullptr; + QString mProjSrid; + QString mProjWkt; //! Previous page int mPreviousPage = -1; diff --git a/src/providers/grass/qgis.g.info.c b/src/providers/grass/qgis.g.info.c index 462bed9067ad..a73570a393b4 100644 --- a/src/providers/grass/qgis.g.info.c +++ b/src/providers/grass/qgis.g.info.c @@ -53,7 +53,7 @@ int main( int argc, char **argv ) info_opt->key = "info"; info_opt->type = TYPE_STRING; info_opt->description = "info key"; - info_opt->options = "proj,window,size,query,info,colors,stats"; + info_opt->options = "proj,wkt,srid,window,size,query,info,colors,stats"; rast_opt = G_define_standard_option( G_OPT_R_INPUT ); rast_opt->key = "rast"; @@ -107,7 +107,6 @@ int main( int argc, char **argv ) if ( strcmp( "proj", info_opt->answer ) == 0 ) { G_get_window( &window ); - /* code from g.proj */ if ( window.proj != PROJECTION_XY ) { struct Key_Value *projinfo, *projunits; @@ -118,6 +117,30 @@ int main( int argc, char **argv ) fprintf( stdout, "%s", wkt ); } } + else if ( strcmp( "wkt", info_opt->answer ) == 0 ) + { + G_get_window( &window ); + if ( window.proj != PROJECTION_XY ) + { + char *wkt = G_get_projwkt(); + if ( wkt ) + { + fprintf( stdout, "%s", wkt ); + } + } + } + else if ( strcmp( "srid", info_opt->answer ) == 0 ) + { + G_get_window( &window ); + if ( window.proj != PROJECTION_XY ) + { + char *srid = G_get_projsrid(); + if ( srid ) + { + fprintf( stdout, "%s", srid ); + } + } + } else if ( strcmp( "window", info_opt->answer ) == 0 ) { if ( rast_opt->answer ) diff --git a/src/providers/grass/qgsgrass.cpp b/src/providers/grass/qgsgrass.cpp index 0f3ef32e9fbe..5c32bab06725 100644 --- a/src/providers/grass/qgsgrass.cpp +++ b/src/providers/grass/qgsgrass.cpp @@ -2082,13 +2082,48 @@ QgsCoordinateReferenceSystem QgsGrass::crs( const QString &gisdbase, const QStri QString &error ) { QgsDebugMsgLevel( QStringLiteral( "gisdbase = %1 location = %2" ).arg( gisdbase, location ), 2 ); - QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem(); + QgsCoordinateReferenceSystem crs; + + // try getting SRID directly first + try + { + const QString srid = getInfo( QStringLiteral( "srid" ), gisdbase, location ); + QgsDebugMsgLevel( QStringLiteral( "srid: %1" ).arg( srid ), 2 ); + crs = QgsCoordinateReferenceSystem( srid ); + if ( crs.isValid() ) + return crs; + } + catch ( QgsGrass::Exception &e ) + { + error = tr( "Cannot get SRID" ) + "\n" + e.what(); + QgsDebugError( error ); + } + + // else try WKT try { - QString wkt = getInfo( QStringLiteral( "proj" ), gisdbase, location ); - QgsDebugMsgLevel( "wkt: " + wkt, 2 ); + const QString wkt = getInfo( QStringLiteral( "wkt" ), gisdbase, location ); + QgsDebugMsgLevel( QStringLiteral( "wkt: %1" ).arg( wkt ), 2 ); crs = QgsCoordinateReferenceSystem::fromWkt( wkt ); QgsDebugMsgLevel( "crs.toWkt: " + crs.toWkt(), 2 ); + if ( crs.isValid() ) + return crs; + } + catch ( QgsGrass::Exception &e ) + { + error = tr( "Cannot get projection" ) + "\n" + e.what(); + QgsDebugError( error ); + } + + //else try lossy old proj properties approach + try + { + const QString wktFromProjString = getInfo( QStringLiteral( "proj" ), gisdbase, location ); + QgsDebugMsgLevel( QStringLiteral( "WKT from proj string: %1" ).arg( wktFromProjString ), 2 ); + crs = QgsCoordinateReferenceSystem::fromWkt( wktFromProjString ); + QgsDebugMsgLevel( "crs.toWkt: " + crs.toWkt(), 2 ); + if ( crs.isValid() ) + return crs; } catch ( QgsGrass::Exception &e ) { diff --git a/tests/src/providers/grass/testqgsgrassprovider.cpp b/tests/src/providers/grass/testqgsgrassprovider.cpp index c12b205a2eb3..e9f87441eb2d 100644 --- a/tests/src/providers/grass/testqgsgrassprovider.cpp +++ b/tests/src/providers/grass/testqgsgrassprovider.cpp @@ -204,6 +204,7 @@ class TestQgsGrassProvider: public QgsTest void invalidLayer(); void region(); void info(); + void crsEpsg3857(); void rasterImport(); void vectorImport(); void edit(); @@ -352,15 +353,8 @@ void TestQgsGrassProvider::fatalError() void TestQgsGrassProvider::locations() { - reportHeader( QStringLiteral( "TestQgsGrassProvider::locations" ) ); - bool ok = true; - QStringList expectedLocations; - expectedLocations << QStringLiteral( "wgs84" ); - QStringList locations = QgsGrass::locations( mGisdbase ); - reportRow( "expectedLocations: " + expectedLocations.join( QLatin1String( ", " ) ) ); - reportRow( "locations: " + locations.join( QLatin1String( ", " ) ) ); - compare( expectedLocations, locations, ok ); - GVERIFY( ok ); + const QStringList locations = QgsGrass::locations( mGisdbase ); + QCOMPARE( locations, QStringList() << QStringLiteral( "webmerc" ) << QStringLiteral( "wgs84" ) ); } void TestQgsGrassProvider::mapsets() @@ -622,6 +616,14 @@ void TestQgsGrassProvider::info() GVERIFY( ok ); } +void TestQgsGrassProvider::crsEpsg3857() +{ + QString error; + const QgsCoordinateReferenceSystem crs = QgsGrass::crs( mGisdbase, QStringLiteral( "webmerc" ), error ); + QCOMPARE( error, QString() ); + QCOMPARE( crs.authid(), QStringLiteral( "EPSG:3857" ) ); +} + // From Qt creator bool TestQgsGrassProvider::copyRecursively( const QString &srcFilePath, const QString &tgtFilePath, QString *error ) diff --git a/tests/testdata/grass/webmerc/PERMANENT/DEFAULT_WIND b/tests/testdata/grass/webmerc/PERMANENT/DEFAULT_WIND new file mode 100644 index 000000000000..88faf91ab3f1 --- /dev/null +++ b/tests/testdata/grass/webmerc/PERMANENT/DEFAULT_WIND @@ -0,0 +1,18 @@ +proj: 99 +zone: 0 +north: 20048966.104 +south: -20048966.104 +east: 20037508.3428 +west: -20037508.3428 +cols: 1000 +rows: 1000 +e-w resol: 40075.0166856 +n-s resol: 40075.0166856 +top: 1.000000000000000 +bottom: 0.000000000000000 +cols3: 10000 +rows3: 10005 +depths: 1 +e-w resol3: 4007.50166856 +n-s resol3: 4007.50166856 +t-b resol: 1 diff --git a/tests/testdata/grass/webmerc/PERMANENT/PROJ_INFO b/tests/testdata/grass/webmerc/PERMANENT/PROJ_INFO new file mode 100644 index 000000000000..5ab7ea71fa47 --- /dev/null +++ b/tests/testdata/grass/webmerc/PERMANENT/PROJ_INFO @@ -0,0 +1,12 @@ +name: WGS 84 / Pseudo-Mercator +a: 6378137 +es: 0 +proj: merc +lat_ts: 0 +lon_0: 0 +x_0: 0 +y_0: 0 +k: 1 +nadgrids: @null +wktext: defined +no_defs: defined diff --git a/tests/testdata/grass/webmerc/PERMANENT/PROJ_SRID b/tests/testdata/grass/webmerc/PERMANENT/PROJ_SRID new file mode 100644 index 000000000000..f44fca47398a --- /dev/null +++ b/tests/testdata/grass/webmerc/PERMANENT/PROJ_SRID @@ -0,0 +1 @@ +EPSG:3857 diff --git a/tests/testdata/grass/webmerc/PERMANENT/PROJ_UNITS b/tests/testdata/grass/webmerc/PERMANENT/PROJ_UNITS new file mode 100644 index 000000000000..28243d2cf275 --- /dev/null +++ b/tests/testdata/grass/webmerc/PERMANENT/PROJ_UNITS @@ -0,0 +1,3 @@ +unit: meter +units: meters +meters: 1 diff --git a/tests/testdata/grass/webmerc/PERMANENT/PROJ_WKT b/tests/testdata/grass/webmerc/PERMANENT/PROJ_WKT new file mode 100644 index 000000000000..56bed5ca76b0 --- /dev/null +++ b/tests/testdata/grass/webmerc/PERMANENT/PROJ_WKT @@ -0,0 +1 @@ +PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] diff --git a/tests/testdata/grass/webmerc/PERMANENT/WIND b/tests/testdata/grass/webmerc/PERMANENT/WIND new file mode 100644 index 000000000000..88faf91ab3f1 --- /dev/null +++ b/tests/testdata/grass/webmerc/PERMANENT/WIND @@ -0,0 +1,18 @@ +proj: 99 +zone: 0 +north: 20048966.104 +south: -20048966.104 +east: 20037508.3428 +west: -20037508.3428 +cols: 1000 +rows: 1000 +e-w resol: 40075.0166856 +n-s resol: 40075.0166856 +top: 1.000000000000000 +bottom: 0.000000000000000 +cols3: 10000 +rows3: 10005 +depths: 1 +e-w resol3: 4007.50166856 +n-s resol3: 4007.50166856 +t-b resol: 1 diff --git a/tests/testdata/grass/webmerc/webmerc/WIND b/tests/testdata/grass/webmerc/webmerc/WIND new file mode 100644 index 000000000000..88faf91ab3f1 --- /dev/null +++ b/tests/testdata/grass/webmerc/webmerc/WIND @@ -0,0 +1,18 @@ +proj: 99 +zone: 0 +north: 20048966.104 +south: -20048966.104 +east: 20037508.3428 +west: -20037508.3428 +cols: 1000 +rows: 1000 +e-w resol: 40075.0166856 +n-s resol: 40075.0166856 +top: 1.000000000000000 +bottom: 0.000000000000000 +cols3: 10000 +rows3: 10005 +depths: 1 +e-w resol3: 4007.50166856 +n-s resol3: 4007.50166856 +t-b resol: 1 diff --git a/tests/testdata/grass/webmerc/webmerc/vector/ff/coor b/tests/testdata/grass/webmerc/webmerc/vector/ff/coor new file mode 100644 index 000000000000..0f70f6411830 Binary files /dev/null and b/tests/testdata/grass/webmerc/webmerc/vector/ff/coor differ diff --git a/tests/testdata/grass/webmerc/webmerc/vector/ff/dbln b/tests/testdata/grass/webmerc/webmerc/vector/ff/dbln new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/testdata/grass/webmerc/webmerc/vector/ff/head b/tests/testdata/grass/webmerc/webmerc/vector/ff/head new file mode 100644 index 000000000000..bb255d6ee696 --- /dev/null +++ b/tests/testdata/grass/webmerc/webmerc/vector/ff/head @@ -0,0 +1,10 @@ +ORGANIZATION: +DIGIT DATE: +DIGIT NAME: nyall +MAP NAME: +MAP DATE: Thu Jul 11 11:54:19 2024 +MAP SCALE: 1 +OTHER INFO: +PROJ: 99 +ZONE: 0 +MAP THRESH: 0.000000 diff --git a/tests/testdata/grass/webmerc/webmerc/vector/ff/hist b/tests/testdata/grass/webmerc/webmerc/vector/ff/hist new file mode 100644 index 000000000000..6af280dcd049 --- /dev/null +++ b/tests/testdata/grass/webmerc/webmerc/vector/ff/hist @@ -0,0 +1,4 @@ +--------------------------------------------------------------------------------- +COMMAND: QGIS --quiet +GISDBASE: /home/nyall/grassdata +LOCATION: webmerc MAPSET: webmerc USER: nyall DATE: Thu Jul 11 11:54:19 2024