2006-01-08 01:18:20 +00:00
|
|
|
/***************************************************************************
|
|
|
|
QgsCoordinateTransform.h - Coordinate Transforms
|
|
|
|
-------------------
|
|
|
|
begin : Dec 2004
|
|
|
|
copyright : (C) 2004 Tim Sutton
|
|
|
|
email : tim at linfiniti.com
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
/* $Id$ */
|
|
|
|
#ifndef QGSCOORDINATETRANSFORM_H
|
|
|
|
#define QGSCOORDINATETRANSFORM_H
|
|
|
|
|
|
|
|
//qt includes
|
2006-03-10 03:11:06 +00:00
|
|
|
#include <QObject>
|
2006-01-08 01:18:20 +00:00
|
|
|
|
|
|
|
//qgis includes
|
|
|
|
#include "qgspoint.h"
|
|
|
|
#include "qgsrect.h"
|
|
|
|
#include "qgscsexception.h"
|
|
|
|
#include "qgsspatialrefsys.h"
|
|
|
|
class QDomNode;
|
|
|
|
class QDomDocument;
|
|
|
|
|
|
|
|
//non qt includes
|
|
|
|
#include <iostream>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
extern "C"{
|
|
|
|
#include <proj_api.h>
|
|
|
|
}
|
|
|
|
class QString;
|
|
|
|
|
|
|
|
/*! \class QgsCoordinateTransform
|
|
|
|
* \brief Class for doing transforms between two map coordinate systems.
|
|
|
|
*
|
|
|
|
* This class can convert map coordinates to a different spatial reference system.
|
|
|
|
* It is normally associated with a map layer and is used to transform between the
|
|
|
|
* layer's coordinate system and the coordinate system of the map canvas, although
|
|
|
|
* it can be used in a more general sense to transform coordinates.
|
|
|
|
*
|
|
|
|
* All references to source and destination coordinate systems refer to
|
|
|
|
* layer and map canvas respectively. All operations are from the perspective
|
|
|
|
* of the layer. For example, a forward transformation transforms coordinates from the
|
|
|
|
* layers coordinate system to the map canvas.
|
|
|
|
*/
|
|
|
|
class QgsCoordinateTransform: public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
/*! Default constructor. Make sure you use initialised() manually if you use this one! */
|
|
|
|
QgsCoordinateTransform() ;
|
|
|
|
|
2006-03-04 14:30:15 +00:00
|
|
|
/** Constructs a QgsCoordinateTransform using QgsSpatialRefSys objects.
|
|
|
|
* @param theSource SRS, typically of the layer's coordinate system
|
|
|
|
* @param theDest SRS, typically of the map canvas coordinate system
|
2006-01-08 01:18:20 +00:00
|
|
|
*/
|
|
|
|
QgsCoordinateTransform(const QgsSpatialRefSys& theSource,
|
|
|
|
const QgsSpatialRefSys& theDest);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Constructs a QgsCoordinateTransform using the Well Known Text representation
|
|
|
|
* of the layer and map canvas coordinate systems
|
2006-03-04 14:30:15 +00:00
|
|
|
* @param theSourceWKT WKT, typically of the layer's coordinate system
|
|
|
|
* @param theDestWKT WKT, typically of the map canvas coordinate system
|
2006-01-08 01:18:20 +00:00
|
|
|
*/
|
|
|
|
QgsCoordinateTransform(QString theSourceWKT, QString theDestWKT );
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* Constructs a QgsCoordinateTransform using a Spatial Reference Id
|
|
|
|
* of the layer and map canvas coordinate system as Wkt
|
|
|
|
* @param theSourceSrid Spatial Ref Id of the layer's coordinate system
|
|
|
|
* @param theSourceWKT WKT of the map canvas coordinate system
|
|
|
|
* @param theSourceSRSType On of the enum members defined in QgsSpatialRefSys::SRS_TYPE
|
|
|
|
*/
|
|
|
|
QgsCoordinateTransform(long theSourceSrid,
|
|
|
|
QString theDestWKT,
|
|
|
|
QgsSpatialRefSys::SRS_TYPE theSourceSRSType = QgsSpatialRefSys::POSTGIS_SRID );
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
//! destructor
|
|
|
|
~QgsCoordinateTransform();
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
//! Enum used to indicate the direction (forward or inverse) of the transform
|
|
|
|
enum TransformDirection{
|
2006-03-04 14:30:15 +00:00
|
|
|
FORWARD, /*!< Transform from source to destination SRS. */
|
|
|
|
INVERSE /*!< Transform from destination to source SRS. */
|
2006-01-08 01:18:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Set the source (layer) QgsSpatialRefSys
|
|
|
|
* @param theSRS QgsSpatialRefSys representation of the layer's coordinate system
|
|
|
|
*/
|
|
|
|
void setSourceSRS(const QgsSpatialRefSys& theSRS);
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* Mutator for dest QgsSpatialRefSys
|
|
|
|
* @param theSRS of the destination coordinate system
|
|
|
|
*/
|
2006-03-04 14:30:15 +00:00
|
|
|
void setDestSRS(const QgsSpatialRefSys& theSRS);
|
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* Get the QgsSpatialRefSys representation of the layer's coordinate system
|
|
|
|
* @return QgsSpatialRefSys of the layer's coordinate system
|
|
|
|
*/
|
|
|
|
QgsSpatialRefSys& sourceSRS() { return mSourceSRS; }
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* Get the QgsSpatialRefSys representation of the map canvas coordinate system
|
|
|
|
* @return QgsSpatialRefSys of the map canvas coordinate system
|
|
|
|
*/
|
|
|
|
QgsSpatialRefSys& destSRS() { return mDestSRS; }
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*! Transform the point from Source Coordinate System to Destination Coordinate System
|
|
|
|
* If the direction is FORWARD then coordinates are transformed from layer CS --> map canvas CS,
|
|
|
|
* otherwise points are transformed from map canvas CS to layerCS.
|
|
|
|
* @param p Point to transform
|
|
|
|
* @param direction TransformDirection (defaults to FORWARD)
|
|
|
|
* @return QgsPoint in Destination Coordinate System
|
|
|
|
*/
|
|
|
|
QgsPoint transform(const QgsPoint p,TransformDirection direction=FORWARD);
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*! Transform the point specified by x,y from Source Coordinate System to Destination Coordinate System
|
|
|
|
* If the direction is FORWARD then coordinates are transformed from layer CS --> map canvas CS,
|
|
|
|
* otherwise points are transformed from map canvas CS to layerCS.
|
|
|
|
* @param x x cordinate of point to transform
|
|
|
|
* @param y y coordinate of point to transform
|
|
|
|
* @param direction TransformDirection (defaults to FORWARD)
|
|
|
|
* @return QgsPoint in Destination Coordinate System
|
|
|
|
*/
|
|
|
|
QgsPoint transform(const double x, const double y,TransformDirection direction=FORWARD);
|
|
|
|
|
|
|
|
/*! Transform a QgsRect to the dest Coordinate system
|
|
|
|
* If the direction is FORWARD then coordinates are transformed from layer CS --> map canvas CS,
|
|
|
|
* otherwise points are transformed from map canvas CS to layerCS.
|
|
|
|
* It assumes that rect is a bounding box, and creates a bounding box
|
|
|
|
* in the proejcted CS, so that all points in source rectangle is within
|
|
|
|
* returned rectangle.
|
|
|
|
* @param QgsRect rect to transform
|
|
|
|
* @param direction TransformDirection (defaults to FORWARD)
|
|
|
|
* @return QgsRect in Destination Coordinate System
|
|
|
|
*/
|
|
|
|
QgsRect transformBoundingBox(const QgsRect theRect,TransformDirection direction=FORWARD);
|
|
|
|
|
|
|
|
// Same as for the other transform() functions, but alters the x
|
|
|
|
// and y variables in place. The second one works with good old-fashioned
|
|
|
|
// C style arrays.
|
|
|
|
void transformInPlace(double& x, double& y, double &z, TransformDirection direction = FORWARD);
|
|
|
|
|
|
|
|
void transformInPlace(std::vector<double>& x, std::vector<double>& y, std::vector<double>& z,
|
|
|
|
TransformDirection direction = FORWARD);
|
|
|
|
|
|
|
|
/*! Transform a QgsRect to the dest Coordinate system
|
|
|
|
* If the direction is FORWARD then coordinates are transformed from layer CS --> map canvas CS,
|
|
|
|
* otherwise points are transformed from map canvas CS to layerCS.
|
|
|
|
* @param QgsRect rect to transform
|
|
|
|
* @param direction TransformDirection (defaults to FORWARD)
|
|
|
|
* @return QgsRect in Destination Coordinate System
|
|
|
|
*/
|
|
|
|
QgsRect transform(const QgsRect theRect,TransformDirection direction=FORWARD);
|
|
|
|
|
|
|
|
/*! Transform an array of coordinates to a different Coordinate System
|
|
|
|
* If the direction is FORWARD then coordinates are transformed from layer CS --> map canvas CS,
|
|
|
|
* otherwise points are transformed from map canvas CS to layerCS.
|
|
|
|
* @param x x cordinate of point to transform
|
|
|
|
* @param y y coordinate of point to transform
|
|
|
|
* @param direction TransformDirection (defaults to FORWARD)
|
|
|
|
* @return QgsRect in Destination Coordinate System
|
|
|
|
*/
|
|
|
|
void transformCoords( const int &numPoint, double *x, double *y, double *z,TransformDirection direction=FORWARD);
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* Flag to indicate whether the coordinate systems have been initialised
|
|
|
|
* @return true if initialised, otherwise false
|
|
|
|
*/
|
|
|
|
bool isInitialised() {return mInitialisedFlag;};
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*! See if the transform short circuits because src and dest are equivalent
|
|
|
|
* @return bool True if it short circuits
|
|
|
|
*/
|
|
|
|
bool isShortCircuited() {return mShortCircuit;};
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
public slots:
|
|
|
|
/*! Change the destination coordinate system by passing it a qgis srsid
|
|
|
|
* A QGIS srsid is a unique key value to an entry on the tbl_srs in the
|
|
|
|
* srs.db sqlite database.
|
|
|
|
* @note This slot will usually be called if the
|
|
|
|
* project properties change and a different coordinate system is
|
|
|
|
* selected.
|
|
|
|
* @note This coord transform will be reinitialised when this slot is called
|
|
|
|
* to check if short circuiting is needed or not etc.
|
|
|
|
* @param theSRSID - A long representing the srsid of the srs to be used */
|
|
|
|
void setDestSRSID (long theSRSID);
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
//!initialise is used to actually create the Transformer instance
|
|
|
|
void initialise();
|
|
|
|
|
|
|
|
/*! Restores state from the given DOM node.
|
|
|
|
* @param theNode The node from which state will be restored
|
|
|
|
* @return bool True on success, False on failure
|
|
|
|
*/
|
|
|
|
bool readXML( QDomNode & theNode );
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*! Stores state to the given DOM node in the given document
|
|
|
|
* @param theNode The node in which state will be restored
|
|
|
|
* @param theDom The document in which state will be stored
|
|
|
|
* @return bool True on success, False on failure
|
|
|
|
*/
|
|
|
|
bool writeXML( QDomNode & theNode, QDomDocument & theDoc );
|
|
|
|
|
|
|
|
signals:
|
|
|
|
/** Signal when an invalid pj_transform() has occured */
|
|
|
|
void invalidTransformInput();
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Flag to indicate that the source and destination coordinate systems are
|
|
|
|
* equal and not transformation needs to be done
|
|
|
|
*/
|
|
|
|
bool mShortCircuit;
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* flag to show whether the transform is properly initialised or not
|
|
|
|
*/
|
|
|
|
bool mInitialisedFlag;
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* QgsSpatialRefSys of the source (layer) coordinate system
|
|
|
|
*/
|
|
|
|
QgsSpatialRefSys mSourceSRS;
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* QgsSpatialRefSys of the destination (map canvas) coordinate system
|
|
|
|
*/
|
|
|
|
QgsSpatialRefSys mDestSRS;
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* Proj4 data structure of the source projection (layer coordinate system)
|
|
|
|
*/
|
|
|
|
projPJ mSourceProjection;
|
2006-03-04 14:30:15 +00:00
|
|
|
|
2006-01-08 01:18:20 +00:00
|
|
|
/*!
|
|
|
|
* Proj4 data structure of the destination projection (map canvas coordinate system)
|
|
|
|
*/
|
|
|
|
projPJ mDestinationProjection;
|
|
|
|
};
|
|
|
|
|
|
|
|
//! Output stream operator
|
|
|
|
inline std::ostream& operator << (std::ostream& os, const QgsCoordinateTransform &r)
|
|
|
|
{
|
|
|
|
QString mySummary ("\n%%%%%%%%%%%%%%%%%%%%%%%%\nCoordinate Transform def begins:");
|
|
|
|
mySummary += "\n\tInitialised? : ";
|
|
|
|
/*
|
|
|
|
if (r.isInitialised())
|
|
|
|
{
|
|
|
|
mySummary += "Yes";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mySummary += "No" ;
|
|
|
|
}
|
|
|
|
mySummary += "\n\tShort Circuit? : " ;
|
|
|
|
if (r.isShortCircuited())
|
|
|
|
{
|
|
|
|
mySummary += "Yes";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mySummary += "No" ;
|
|
|
|
}
|
|
|
|
|
|
|
|
mySummary += "\n\tSource Spatial Ref Sys : ";
|
|
|
|
if (r.sourceSRS())
|
|
|
|
{
|
|
|
|
mySummary << r.sourceSRS();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mySummary += "Undefined" ;
|
|
|
|
}
|
|
|
|
|
|
|
|
mySummary += "\n\tDest Spatial Ref Sys : " ;
|
|
|
|
if (r.destSRS())
|
|
|
|
{
|
|
|
|
mySummary << r.destSRS();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mySummary += "Undefined" ;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
mySummary+=("\nCoordinate Transform def ends \n%%%%%%%%%%%%%%%%%%%%%%%%\n");
|
|
|
|
return os << mySummary.toLocal8Bit().data() << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif // QGSCOORDINATETRANSFORM_H
|