25 #include <QDomElement>
26 #include <QApplication>
28 #include <QStringList>
42 , mInitialisedFlag( false )
43 , mSourceProjection( 0 )
44 , mDestinationProjection( 0 )
45 , mSourceDatumTransform( -1 )
46 , mDestinationDatumTransform( -1 )
53 , mInitialisedFlag( false )
54 , mSourceProjection( 0 )
55 , mDestinationProjection( 0 )
56 , mSourceDatumTransform( -1 )
57 , mDestinationDatumTransform( -1 )
67 , mInitialisedFlag( false )
70 , mSourceProjection( 0 )
71 , mDestinationProjection( 0 )
72 , mSourceDatumTransform( -1 )
73 , mDestinationDatumTransform( -1 )
80 , mInitialisedFlag( false )
81 , mSourceProjection( 0 )
82 , mDestinationProjection( 0 )
83 , mSourceDatumTransform( -1 )
84 , mDestinationDatumTransform( -1 )
100 , mInitialisedFlag( false )
101 , mSourceProjection( 0 )
102 , mDestinationProjection( 0 )
103 , mSourceDatumTransform( -1 )
104 , mDestinationDatumTransform( -1 )
185 if ( !useDefaultDatumTransform )
196 if ( !useDefaultDatumTransform )
205 if ( !useDefaultDatumTransform )
213 #ifdef COORDINATE_TRANSFORM_VERBOSE
219 if ( !mDestinationProjection )
221 mInitialisedFlag =
false;
225 mInitialisedFlag =
false;
227 #ifdef COORDINATE_TRANSFORM_VERBOSE
228 if ( mInitialisedFlag )
230 QgsDebugMsg(
"------------------------------------------------------------" );
231 QgsDebugMsg(
"The OGR Coordinate transformation for this layer was set to" );
232 QgsLogger::debug<QgsCoordinateReferenceSystem>(
"Input",
mSourceCRS, __FILE__, __FUNCTION__, __LINE__ );
233 QgsLogger::debug<QgsCoordinateReferenceSystem>(
"Output",
mDestCRS, __FILE__, __FUNCTION__, __LINE__ );
234 QgsDebugMsg(
"------------------------------------------------------------" );
238 QgsDebugMsg(
"------------------------------------------------------------" );
239 QgsDebugMsg(
"The OGR Coordinate transformation FAILED TO INITIALISE!" );
240 QgsDebugMsg(
"------------------------------------------------------------" );
243 if ( !mInitialisedFlag )
245 QgsDebugMsg(
"Coordinate transformation failed to initialize!" );
281 double x = thePoint.
x();
282 double y = thePoint.
y();
339 #ifdef COORDINATE_TRANSFORM_VERBOSE
378 int nVertices = poly.size();
380 QVector<double> x( nVertices );
381 QVector<double> y( nVertices );
382 QVector<double> z( nVertices );
384 for (
int i = 0; i < nVertices; ++i )
386 const QPointF& pt = poly.at( i );
403 for (
int i = 0; i < nVertices; ++i )
405 QPointF& pt = poly[i];
412 QVector<double>& x, QVector<double>& y, QVector<double>& z,
418 Q_ASSERT( x.size() == y.size() );
439 TransformDirection direction )
const
441 double xd = ( double ) x, yd = (
double ) y;
450 TransformDirection direction )
const
477 QVector<float>& x, QVector<float>& y, QVector<float>& z,
478 TransformDirection direction )
const
483 Q_ASSERT( x.size() == y.size() );
493 int vectorSize = x.size();
494 QVector<double> xd( x.size() );
495 QVector<double> yd( y.size() );
496 QVector<double> zd( z.size() );
497 for (
int i = 0; i < vectorSize; ++i )
506 for (
int i = 0; i < vectorSize; ++i )
539 static const int numP = 8;
547 double x[numP * numP];
548 double y[numP * numP];
549 double z[numP * numP];
555 double dx = rect.
width() / ( double )( numP - 1 );
556 double dy = rect.
height() / ( double )( numP - 1 );
560 for (
int i = 0; i < numP ; i++ )
566 for (
int j = 0; j < numP; j++ )
568 x[( i*numP ) + j] = pointX;
569 y[( i*numP ) + j] = pointY;
571 z[( i*numP ) + j] = 0.0;
593 for (
int i = 0; i < numP * numP; i++ )
595 if ( qIsFinite( x[i] ) && qIsFinite( y[i] ) )
615 "The coordinates can not be reprojected. The CRS is: %1" )
622 "The coordinates can not be reprojected. The CRS is: %1" ).arg(
mDestCRS.
toProj4() ),
tr(
"CRS" ) );
626 #ifdef COORDINATE_TRANSFORM_VERBOSE
629 QgsDebugMsg( QString(
"[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) );
639 for (
int i = 0; i < numPoints; ++i )
659 if ( projResult != 0 )
664 for (
int i = 0; i < numPoints; ++i )
668 points += QString(
"(%1, %2)\n" ).arg( x[i], 0,
'f' ).arg( y[i], 0,
'f' );
672 points += QString(
"(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0,
'f' ).arg( y[i] * RAD_TO_DEG, 0,
'f' );
676 dir = ( direction ==
ForwardTransform ) ?
tr(
"forward transform" ) :
tr(
"inverse transform" );
678 QString msg =
tr(
"%1 of\n"
680 "PROJ.4: %3 +to %4\n"
685 .arg( QString::fromUtf8( pj_strerrno( projResult ) ) );
687 QgsDebugMsg(
"Projection failed emitting invalid transform signal: " + msg );
701 for (
int i = 0; i < numPoints; ++i )
708 #ifdef COORDINATE_TRANSFORM_VERBOSE
709 QgsDebugMsg( QString(
"[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" )
710 .arg( xorg, 0,
'g', 15 ).arg( yorg, 0,
'g', 15 )
711 .arg( *x, 0,
'g', 15 ).arg( *y, 0,
'g', 15 ) );
718 QgsDebugMsg(
"Reading Coordinate Transform from xml ------------------------!" );
720 QDomNode mySrcNode = theNode.namedItem(
"sourcesrs" );
723 QDomNode myDestNode = theNode.namedItem(
"destinationsrs" );
736 QDomElement myNodeElement = theNode.toElement();
737 QDomElement myTransformElement = theDoc.createElement(
"coordinatetransform" );
741 QDomElement mySourceElement = theDoc.createElement(
"sourcesrs" );
743 myTransformElement.appendChild( mySourceElement );
745 QDomElement myDestElement = theDoc.createElement(
"destinationsrs" );
747 myTransformElement.appendChild( myDestElement );
749 myNodeElement.appendChild( myTransformElement );
758 proj = QApplication::applicationDirPath()
759 +
"/share/proj/" + QString( name );
763 return proj.toUtf8();
784 QList< QList< int > > transformations;
789 if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
791 return transformations;
794 QStringList srcSplit = srcGeoId.split(
":" );
795 QStringList destSplit = destGeoId.split(
":" );
797 if ( srcSplit.size() < 2 || destSplit.size() < 2 )
799 return transformations;
802 int srcAuthCode = srcSplit.at( 1 ).toInt();
803 int destAuthCode = destSplit.at( 1 ).toInt();
805 if ( srcAuthCode == destAuthCode )
807 return transformations;
810 QList<int> directTransforms;
811 searchDatumTransform( QString(
"SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code=%1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( destAuthCode ),
813 QList<int> reverseDirectTransforms;
814 searchDatumTransform( QString(
"SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( srcAuthCode ),
815 reverseDirectTransforms );
816 QList<int> srcToWgs84;
817 searchDatumTransform( QString(
"SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( 4326 ),
819 QList<int> destToWgs84;
820 searchDatumTransform( QString(
"SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( 4326 ),
824 QList<int>::const_iterator directIt = directTransforms.constBegin();
825 for ( ; directIt != directTransforms.constEnd(); ++directIt )
827 transformations.push_back( QList<int>() << *directIt << -1 );
831 directIt = reverseDirectTransforms.constBegin();
832 for ( ; directIt != reverseDirectTransforms.constEnd(); ++directIt )
834 transformations.push_back( QList<int>() << -1 << *directIt );
837 QList<int>::const_iterator srcWgsIt = srcToWgs84.constBegin();
838 for ( ; srcWgsIt != srcToWgs84.constEnd(); ++srcWgsIt )
840 QList<int>::const_iterator dstWgsIt = destToWgs84.constBegin();
841 for ( ; dstWgsIt != destToWgs84.constEnd(); ++dstWgsIt )
843 transformations.push_back( QList<int>() << *srcWgsIt << *dstWgsIt );
847 return transformations;
852 QStringList parameterSplit = proj4.split(
"+", QString::SkipEmptyParts );
853 QString currentParameter;
854 QString newProjString;
856 for (
int i = 0; i < parameterSplit.size(); ++i )
858 currentParameter = parameterSplit.at( i );
859 if ( !currentParameter.startsWith(
"towgs84", Qt::CaseInsensitive )
860 && !currentParameter.startsWith(
"nadgrids", Qt::CaseInsensitive ) )
862 newProjString.append(
"+" );
863 newProjString.append( currentParameter );
864 newProjString.append(
" " );
867 return newProjString;
874 if ( openResult != SQLITE_OK )
881 int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
882 if ( prepareRes != SQLITE_OK )
884 sqlite3_finalize( stmt ); sqlite3_close( db );
889 while ( sqlite3_step( stmt ) == SQLITE_ROW )
891 cOpCode = (
const char * ) sqlite3_column_text( stmt, 0 );
892 transforms.push_back( cOpCode.toInt() );
894 sqlite3_finalize( stmt ); sqlite3_close( db );
899 QString transformString;
903 if ( openResult != SQLITE_OK )
906 return transformString;
910 QString sql = QString(
"SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7 FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
911 int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
912 if ( prepareRes != SQLITE_OK )
914 sqlite3_finalize( stmt ); sqlite3_close( db );
915 return transformString;
918 if ( sqlite3_step( stmt ) == SQLITE_ROW )
921 int methodCode = sqlite3_column_int( stmt, 0 );
922 if ( methodCode == 9615 )
924 transformString =
"+nadgrids=" + QString((
const char * )sqlite3_column_text( stmt, 1 ) );
926 else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
928 transformString +=
"+towgs84=";
929 double p1 = sqlite3_column_double( stmt, 1 );
930 double p2 = sqlite3_column_double( stmt, 2 );
931 double p3 = sqlite3_column_double( stmt, 3 );
932 double p4 = sqlite3_column_double( stmt, 4 );
933 double p5 = sqlite3_column_double( stmt, 5 );
934 double p6 = sqlite3_column_double( stmt, 6 );
935 double p7 = sqlite3_column_double( stmt, 7 );
936 if ( methodCode == 9603 )
938 transformString += QString(
"%1,%2,%3" ).arg( p1 ).arg( p2 ).arg( p3 );
942 transformString += QString(
"%1,%2,%3,%4,%5,%6,%7" ).arg( p1 ).arg( p2 ).arg( p3 ).arg( p4 ).arg( p5 ).arg( p6 ).arg( p7 );
947 sqlite3_finalize( stmt ); sqlite3_close( db );
948 return transformString;
955 if ( openResult != SQLITE_OK )
962 QString sql = QString(
"SELECT epsg_nr,source_crs_code,target_crs_code,remarks,scope,preferred,deprecated FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
963 int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
964 if ( prepareRes != SQLITE_OK )
966 sqlite3_finalize( stmt ); sqlite3_close( db );
970 int srcCrsId, destCrsId;
971 if ( sqlite3_step( stmt ) != SQLITE_ROW )
973 sqlite3_finalize( stmt );
978 epsgNr = sqlite3_column_int( stmt, 0 );
979 srcCrsId = sqlite3_column_int( stmt, 1 );
980 destCrsId = sqlite3_column_int( stmt, 2 );
981 remarks = QString::fromUtf8((
const char * ) sqlite3_column_text( stmt, 3 ) );
982 scope = QString::fromUtf8((
const char * ) sqlite3_column_text( stmt, 4 ) );
983 preferred = sqlite3_column_int( stmt, 5 ) != 0;
984 deprecated = sqlite3_column_int( stmt, 6 ) != 0;
993 sqlite3_finalize( stmt );
1003 destProjString +=
" +nadgrids=@null";
1008 srcProjString +=
" +nadgrids=@null";
1016 srcProjString +=
" +nadgrids=@null";
1020 destProjString +=
" +nadgrids=@null";
A rectangle specified with double values.
const QgsCoordinateReferenceSystem & crsByAuthId(const QString &authid)
Returns the CRS for authid, e.g.
bool isEmpty() const
test if rectangle is empty.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
bool createFromWkt(const QString &theWkt)
double yMaximum() const
Get the y maximum value (top side of rectangle)
QString geographicCRSAuthId() const
Returns auth id of related geographic CRS.
bool createFromId(const long theId, CrsType theType=PostgisCrsId)
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
bool createFromOgcWmsCrs(QString theCrs)
Set up this CRS from the given OGC CRS.
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
bool createFromSrsId(const long theSrsId)
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
#define QgsDebugMsgLevel(str, level)
A class to represent a point geometry.
bool writeXML(QDomNode &theNode, QDomDocument &theDoc) const
Class for storing a coordinate reference system (CRS)
static const QString srsDbFilePath()
Returns the path to the srs.db file.
bool readXML(QDomNode &theNode)
QString description() const
Custom exception class for Coordinate Reference System related exceptions.
double width() const
Width of the rectangle.
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
double xMinimum() const
Get the x minimum value (left side of rectangle)
static QgsCRSCache * instance()
double height() const
Height of the rectangle.
QString toProj4() const
Get the Proj Proj4 string representation of this srs.