Skip to content

Commit

Permalink
Fix loading 2.x projects with custom CRS
Browse files Browse the repository at this point in the history
Fixes #17257
  • Loading branch information
nyalldawson committed Nov 13, 2017
1 parent e967881 commit f2b5a59
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 10 deletions.
35 changes: 29 additions & 6 deletions src/core/qgsproject.cpp
Expand Up @@ -451,9 +451,6 @@ QgsCoordinateReferenceSystem QgsProject::crs() const
void QgsProject::setCrs( const QgsCoordinateReferenceSystem &crs )
{
mCrs = crs;
writeEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectCRSProj4String" ), crs.toProj4() );
writeEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectCRSID" ), static_cast< int >( crs.srsid() ) );
writeEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectCrs" ), crs.authid() );
writeEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectionsEnabled" ), crs.isValid() ? 1 : 0 );
setDirty( true );
emit crsChanged();
Expand Down Expand Up @@ -884,10 +881,31 @@ bool QgsProject::readProjectFile( const QString &filename )
QgsCoordinateReferenceSystem projectCrs;
if ( readNumEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectionsEnabled" ), 0 ) )
{
long currentCRS = readNumEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectCRSID" ), -1 );
if ( currentCRS != -1 )
// first preference - dedicated projectCrs node
QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral( "projectCrs" ) );
if ( !srsNode.isNull() )
{
projectCrs = QgsCoordinateReferenceSystem::fromSrsId( currentCRS );
projectCrs.readXml( srsNode );
}

if ( !projectCrs.isValid() )
{
// else we try using the stored proj4 string - it's consistent across different QGIS installs,
// whereas the srsid can vary (e.g. for custom projections)
QString projCrsString = readEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectCRSProj4String" ) );
if ( !projCrsString.isEmpty() )
{
projectCrs = QgsCoordinateReferenceSystem::fromProj4( projCrsString );
}
// last try using crs id - most fragile
if ( !projectCrs.isValid() )
{
long currentCRS = readNumEntry( QStringLiteral( "SpatialRefSys" ), QStringLiteral( "/ProjectCRSID" ), -1 );
if ( currentCRS != -1 && currentCRS < USER_CRS_START_ID )
{
projectCrs = QgsCoordinateReferenceSystem::fromSrsId( currentCRS );
}
}
}
}
mCrs = projectCrs;
Expand Down Expand Up @@ -1340,6 +1358,11 @@ bool QgsProject::writeProjectFile( const QString &filename )
QDomText titleText = doc->createTextNode( title() ); // XXX why have title TWICE?
titleNode.appendChild( titleText );

// write project CRS
QDomElement srsNode = doc->createElement( QStringLiteral( "projectCrs" ) );
mCrs.writeXml( srsNode, *doc );
qgisNode.appendChild( srsNode );

// write layer tree - make sure it is without embedded subgroups
QgsLayerTreeNode *clonedRoot = mRootGroup->clone();
QgsLayerTreeUtils::replaceChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
Expand Down
19 changes: 15 additions & 4 deletions tests/src/core/testqgscoordinatereferencesystem.cpp
Expand Up @@ -15,13 +15,14 @@ Email : sherman at mrcc dot com
#include "qgstest.h"
#include <QPixmap>

#include <qgsapplication.h>
#include "qgsapplication.h"
#include "qgslogger.h"

//header for class being tested
#include <qgscoordinatereferencesystem.h>
#include <qgis.h>
#include <qgsvectorlayer.h>
#include "qgscoordinatereferencesystem.h"
#include "qgis.h"
#include "qgsvectorlayer.h"
#include "qgsproject.h"

#include <proj_api.h>
#include <gdal.h>
Expand Down Expand Up @@ -77,6 +78,7 @@ class TestQgsCoordinateReferenceSystem: public QObject
void asVariant();
void bounds();
void saveAsUserCrs();
void projectWithCustomCrs();

private:
void debugPrint( QgsCoordinateReferenceSystem &crs );
Expand Down Expand Up @@ -834,5 +836,14 @@ void TestQgsCoordinateReferenceSystem::saveAsUserCrs()
QCOMPARE( userCrs2.description(), QStringLiteral( "babies first projection" ) );
}

void TestQgsCoordinateReferenceSystem::projectWithCustomCrs()
{
// tests loading a 2.x project with a custom CRS defined
QgsProject p;
QVERIFY( p.read( TEST_DATA_DIR + QStringLiteral( "/projects/custom_crs.qgs" ) ) );
QVERIFY( p.crs().isValid() );
QCOMPARE( p.crs().toProj4(), QStringLiteral( "+proj=ortho +lat_0=42.1 +lon_0=12.8 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs" ) );
}

QGSTEST_MAIN( TestQgsCoordinateReferenceSystem )
#include "testqgscoordinatereferencesystem.moc"
129 changes: 129 additions & 0 deletions tests/testdata/projects/custom_crs.qgs
@@ -0,0 +1,129 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis projectname="" version="2.18.9">
<title></title>
<autotransaction active="0"/>
<evaluateDefaultValues active="0"/>
<layer-tree-group expanded="1" checked="Qt::Checked" name="">
<customproperties/>
</layer-tree-group>
<relations/>
<mapcanvas>
<units>meters</units>
<extent>
<xmin>-1579730.21282207453623414</xmin>
<ymin>-4271174.32985332515090704</ymin>
<xmax>-1242009.40286419028416276</xmax>
<ymax>-4054770.71263487357646227</ymax>
</extent>
<rotation>0</rotation>
<projections>1</projections>
<destinationsrs>
<spatialrefsys>
<proj4>+proj=ortho +lat_0=42.1 +lon_0=12.8 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs</proj4>
<srsid>100001</srsid>
<srid>0</srid>
<authid>USER:100001</authid>
<description>new CRS</description>
<projectionacronym>ortho</projectionacronym>
<ellipsoidacronym></ellipsoidacronym>
<geographicflag>false</geographicflag>
</spatialrefsys>
</destinationsrs>
<rendermaptile>0</rendermaptile>
<layer_coordinate_transform_info/>
</mapcanvas>
<layer-tree-canvas>
<custom-order enabled="0"/>
</layer-tree-canvas>
<legend updateDrawingOrder="true"/>
<projectlayers/>
<properties>
<WMSContactPerson type="QString"></WMSContactPerson>
<Variables>
<variableNames type="QStringList"/>
<variableValues type="QStringList"/>
</Variables>
<WMSOnlineResource type="QString"></WMSOnlineResource>
<WMSUseLayerIDs type="bool">false</WMSUseLayerIDs>
<WMSContactOrganization type="QString"></WMSContactOrganization>
<WMSKeywordList type="QStringList">
<value></value>
</WMSKeywordList>
<WFSUrl type="QString"></WFSUrl>
<Paths>
<Absolute type="bool">false</Absolute>
</Paths>
<WMSServiceTitle type="QString"></WMSServiceTitle>
<WFSLayers type="QStringList"/>
<WMSContactMail type="QString"></WMSContactMail>
<PositionPrecision>
<DecimalPlaces type="int">2</DecimalPlaces>
<Automatic type="bool">true</Automatic>
<DegreeFormat type="QString">MU</DegreeFormat>
</PositionPrecision>
<WCSUrl type="QString"></WCSUrl>
<WMSContactPhone type="QString"></WMSContactPhone>
<WMSServiceCapabilities type="bool">false</WMSServiceCapabilities>
<WMSServiceAbstract type="QString"></WMSServiceAbstract>
<WMSContactPosition type="QString"></WMSContactPosition>
<WMSAddWktGeometry type="bool">false</WMSAddWktGeometry>
<Measure>
<Ellipsoid type="QString">NONE</Ellipsoid>
</Measure>
<WMSPrecision type="QString">8</WMSPrecision>
<WMSSegmentizeFeatureInfoGeometry type="bool">false</WMSSegmentizeFeatureInfoGeometry>
<WFSTLayers>
<Insert type="QStringList"/>
<Update type="QStringList"/>
<Delete type="QStringList"/>
</WFSTLayers>
<Gui>
<SelectionColorBluePart type="int">0</SelectionColorBluePart>
<CanvasColorGreenPart type="int">255</CanvasColorGreenPart>
<CanvasColorRedPart type="int">255</CanvasColorRedPart>
<SelectionColorRedPart type="int">255</SelectionColorRedPart>
<SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
<SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
<CanvasColorBluePart type="int">255</CanvasColorBluePart>
</Gui>
<Digitizing>
<DefaultSnapToleranceUnit type="int">2</DefaultSnapToleranceUnit>
<SnappingMode type="QString">current_layer</SnappingMode>
<DefaultSnapType type="QString">off</DefaultSnapType>
<DefaultSnapTolerance type="double">0</DefaultSnapTolerance>
</Digitizing>
<Identify>
<disabledLayers type="QStringList"/>
</Identify>
<Macros>
<pythonCode type="QString"></pythonCode>
</Macros>
<WMSAccessConstraints type="QString">None</WMSAccessConstraints>
<WCSLayers type="QStringList"/>
<Legend>
<filterByMap type="bool">false</filterByMap>
</Legend>
<SpatialRefSys>
<ProjectCRSProj4String type="QString">+proj=ortho +lat_0=42.1 +lon_0=12.8 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs</ProjectCRSProj4String>
<ProjectCrs type="QString">USER:100001</ProjectCrs>
<ProjectCRSID type="int">100001</ProjectCRSID>
<ProjectionsEnabled type="int">1</ProjectionsEnabled>
</SpatialRefSys>
<DefaultStyles>
<Fill type="QString"></Fill>
<Line type="QString"></Line>
<Marker type="QString"></Marker>
<RandomColors type="bool">true</RandomColors>
<AlphaInt type="int">255</AlphaInt>
<ColorRamp type="QString"></ColorRamp>
</DefaultStyles>
<WMSFees type="QString">conditions unknown</WMSFees>
<WMSImageQuality type="int">90</WMSImageQuality>
<Measurement>
<DistanceUnits type="QString">meters</DistanceUnits>
<AreaUnits type="QString">m2</AreaUnits>
</Measurement>
<WMSUrl type="QString"></WMSUrl>
</properties>
<visibility-presets/>
</qgis>

0 comments on commit f2b5a59

Please sign in to comment.