[Marble-commits] KDE/kdeedu/marble/src/lib/Projections
Bernhard Beschow
bbeschow at cs.tu-berlin.de
Sun Aug 29 21:40:22 CEST 2010
SVN commit 1169604 by beschow:
add another *Projection::geoCoordinates(), where given x and y are normalized absolute coordinates rather than offsets to a viewport
M +25 -4 AbstractProjection.h
M +32 -4 EquirectProjection.cpp
M +12 -4 EquirectProjection.h
M +45 -4 MercatorProjection.cpp
M +12 -4 MercatorProjection.h
M +46 -3 SphericalProjection.cpp
M +12 -4 SphericalProjection.h
--- trunk/KDE/kdeedu/marble/src/lib/Projections/AbstractProjection.h #1169603:1169604
@@ -177,10 +177,16 @@
const ViewportParams *viewport,
QVector<QPolygonF*> &polygons );
+ virtual QPointF projectionCoordinates( qreal lon, qreal lat ) const = 0;
+
/**
- * @brief Get the earth coordinates corresponding to a pixel in the map.
- * @param x the x coordinate of the pixel
- * @param y the y coordinate of the pixel
+ * @brief Get the earth coordinates corresponding to a position in the projection.
+ *
+ * The projected area has its origin (0.0, 0.0) at (-180, +90) and reaches to
+ * (1.0, 1.0) at (+180, -90).
+ *
+ * @param normalizedX the x coordinate of the pixel relative to the origin of the viewport
+ * @param normalizedY the y coordinate of the pixel relative to the origin of the viewport
* @param viewport the viewport parameters
* @param lon the longitude angle is returned through this parameter
* @param lat the latitude angle is returned through this parameter
@@ -188,7 +194,22 @@
* @return @c true if the pixel (x, y) is within the globe
* @c false if the pixel (x, y) is outside the globe, i.e. in space.
*/
- virtual bool geoCoordinates( const int x, const int y,
+ virtual bool geoCoordinates( qreal normalizedX, qreal normalizedY,
+ qreal& lon, qreal& lat,
+ GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree ) const = 0;
+
+ /**
+ * @brief Get the earth coordinates corresponding to a pixel on the screen.
+ * @param viewportX the x coordinate of the pixel relative to the origin of the viewport
+ * @param viewportY the y coordinate of the pixel relative to the origin of the viewport
+ * @param viewport the viewport parameters
+ * @param lon the longitude angle is returned through this parameter
+ * @param lat the latitude angle is returned through this parameter
+ * @param unit the unit of the angles for lon and lat.
+ * @return @c true if the pixel (x, y) is within the globe
+ * @c false if the pixel (x, y) is outside the globe, i.e. in space.
+ */
+ virtual bool geoCoordinates( const int viewportX, const int viewportY,
const ViewportParams *viewport,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree ) = 0;
--- trunk/KDE/kdeedu/marble/src/lib/Projections/EquirectProjection.cpp #1169603:1169604
@@ -198,7 +198,35 @@
}
-bool EquirectProjection::geoCoordinates( const int x, const int y,
+QPointF EquirectProjection::projectionCoordinates( qreal lon, qreal lat ) const
+{
+ const qreal x = ( 0.5 + 0.5 * lon / M_PI );
+ const qreal y = ( 0.5 - lat / M_PI );
+
+ return QPointF( x, y );
+}
+
+
+bool EquirectProjection::geoCoordinates( qreal normalizedX, qreal normalizedY,
+ qreal& lon, qreal& lat,
+ GeoDataCoordinates::Unit unit) const
+{
+ lat = ( 0.5 - normalizedY ) * M_PI;
+ lon = ( normalizedX - 0.5 ) * 2 * M_PI;
+
+ while ( lon > M_PI ) lon -= 2.0 * M_PI;
+ while ( lon < -M_PI ) lon += 2.0 * M_PI;
+
+ if ( unit == GeoDataCoordinates::Degree ) {
+ lon *= RAD2DEG;
+ lat *= RAD2DEG;
+ }
+
+ return true;
+}
+
+
+bool EquirectProjection::geoCoordinates( const int viewportX, const int viewportY,
const ViewportParams *viewport,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit )
@@ -218,11 +246,11 @@
int yBottom = yTop + 2 * radius;
// Return here if the y coordinate is outside the map
- if ( y < yTop || y >= yBottom )
+ if ( viewportY < yTop || viewportY >= yBottom )
return false;
- int const xPixels = x - halfImageWidth;
- int const yPixels = y - halfImageHeight;
+ int const xPixels = viewportX - halfImageWidth;
+ int const yPixels = viewportY - halfImageHeight;
qreal const pixel2Rad = M_PI / (2.0 * radius);
lat = - yPixels * pixel2Rad + centerLat;
--- trunk/KDE/kdeedu/marble/src/lib/Projections/EquirectProjection.h #1169603:1169604
@@ -84,16 +84,24 @@
const ViewportParams *viewport,
QVector<QPolygonF*> &polygons );
+ virtual QPointF projectionCoordinates( qreal lon, qreal lat ) const;
+
+ virtual bool geoCoordinates( qreal normalizedX, qreal normalizedY,
+ qreal& lon, qreal& lat,
+ GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree ) const;
+
/**
- * @brief Get the earth coordinates corresponding to a pixel in the map.
- * @param x the x coordinate of the pixel
- * @param y the y coordinate of the pixel
+ * @brief Get the earth coordinates corresponding to a pixel on the screen.
+ * @param viewportX the x coordinate of the pixel relative to the origin of the viewport
+ * @param viewportY the y coordinate of the pixel relative to the origin of the viewport
+ * @param viewport the viewport parameters
* @param lon the longitude angle is returned through this parameter
* @param lat the latitude angle is returned through this parameter
+ * @param unit the unit of the angles for lon and lat.
* @return @c true if the pixel (x, y) is within the globe
* @c false if the pixel (x, y) is outside the globe, i.e. in space.
*/
- bool geoCoordinates( const int x, const int y,
+ bool geoCoordinates( const int viewportX, const int viewportY,
const ViewportParams *params,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree );
--- trunk/KDE/kdeedu/marble/src/lib/Projections/MercatorProjection.cpp #1169603:1169604
@@ -244,7 +244,48 @@
}
-bool MercatorProjection::geoCoordinates( const int x, const int y,
+QPointF MercatorProjection::projectionCoordinates( qreal lon, qreal lat ) const
+{
+ if ( lat > maxLat() ) {
+ lat = maxLat();
+ }
+ if ( lat < minLat() ) {
+ lat = minLat();
+ }
+
+ const qreal x = ( 0.5 + 0.5 * lon / M_PI );
+ const qreal y = ( 0.5 - 0.5 * atanh( sin( lat ) ) / M_PI );
+
+ return QPointF( x, y );
+}
+
+
+bool MercatorProjection::geoCoordinates( qreal normalizedX, qreal normalizedY,
+ qreal& lon, qreal& lat,
+ GeoDataCoordinates::Unit unit) const
+{
+ bool noerr = false;
+
+ if ( 0 <= normalizedY && normalizedY < 1 ) {
+ lat = atan( sinh( ( 0.5 - normalizedY ) * 2 * M_PI ) );
+ lon = ( normalizedX - 0.5 ) * 2 * M_PI;
+
+ while ( lon > M_PI ) lon -= 2*M_PI;
+ while ( lon < -M_PI ) lon += 2*M_PI;
+
+ noerr = true;
+ }
+
+ if ( unit == GeoDataCoordinates::Degree ) {
+ lon *= RAD2DEG;
+ lat *= RAD2DEG;
+ }
+
+ return noerr;
+}
+
+
+bool MercatorProjection::geoCoordinates( const int viewportX, const int viewportY,
const ViewportParams *viewport,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit )
@@ -266,11 +307,11 @@
int yTop = halfImageHeight - 2 * radius + yCenterOffset;
int yBottom = yTop + 4 * radius;
- if ( y >= yTop && y < yBottom ) {
- int const xPixels = x - halfImageWidth;
+ if ( viewportY >= yTop && viewportY < yBottom ) {
+ int const xPixels = viewportX - halfImageWidth;
qreal const pixel2Rad = M_PI / (2 * radius);
- lat = atan( sinh( ( ( halfImageHeight + yCenterOffset ) - y)
+ lat = atan( sinh( ( ( halfImageHeight + yCenterOffset ) - viewportY)
* pixel2Rad ) );
lon = xPixels * pixel2Rad + centerLon;
--- trunk/KDE/kdeedu/marble/src/lib/Projections/MercatorProjection.h #1169603:1169604
@@ -83,16 +83,24 @@
const ViewportParams *viewport,
QVector<QPolygonF*> &polygons );
+ virtual QPointF projectionCoordinates( qreal lon, qreal lat ) const;
+
+ virtual bool geoCoordinates( qreal normalizedX, qreal normalizedY,
+ qreal& lon, qreal& lat,
+ GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree ) const;
+
/**
- * @brief Get the earth coordinates corresponding to a pixel in the map.
- * @param x the x coordinate of the pixel
- * @param y the y coordinate of the pixel
+ * @brief Get the earth coordinates corresponding to a pixel on the screen.
+ * @param viewportX the x coordinate of the pixel relative to the origin of the viewport
+ * @param viewportY the y coordinate of the pixel relative to the origin of the viewport
+ * @param viewport the viewport parameters
* @param lon the longitude angle is returned through this parameter
* @param lat the latitude angle is returned through this parameter
+ * @param unit the unit of the angles for lon and lat.
* @return @c true if the pixel (x, y) is within the globe
* @c false if the pixel (x, y) is outside the globe, i.e. in space.
*/
- bool geoCoordinates( const int x, const int y,
+ bool geoCoordinates( const int viewportX, const int viewportY,
const ViewportParams *params,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit = GeoDataCoordinates::Degree );
--- trunk/KDE/kdeedu/marble/src/lib/Projections/SphericalProjection.cpp #1169603:1169604
@@ -189,7 +189,50 @@
}
-bool SphericalProjection::geoCoordinates( const int x, const int y,
+QPointF SphericalProjection::projectionCoordinates( qreal lon, qreal lat ) const
+{
+ const Quaternion p( lon, lat );
+
+ const qreal x = ( 0.5 + 0.5 * p.v[Q_X] );
+ const qreal y = ( 0.5 - 0.5 * p.v[Q_Y] );
+
+ return QPointF( x, y );
+}
+
+
+bool SphericalProjection::geoCoordinates( qreal normalizedX, qreal normalizedY,
+ qreal& lon, qreal& lat,
+ GeoDataCoordinates::Unit unit ) const
+{
+ bool noerr = false;
+
+ qreal centerX = normalizedX - 0.5;
+ qreal centerY = normalizedY - 0.5;
+
+ if ( 1 > centerX * centerX + centerY * centerY ) {
+ qreal qx = 2 * +centerX;
+ qreal qy = 2 * -centerY;
+ qreal qr = 1.0 - qy * qy;
+
+ qreal qr2z = qr - qx * qx;
+ qreal qz = ( qr2z > 0.0 ) ? sqrt( qr2z ) : 0.0;
+
+ Quaternion qpos( 0.0, qx, qy, qz );
+ qpos.getSpherical( lon, lat );
+
+ noerr = true;
+ }
+
+ if ( unit == GeoDataCoordinates::Degree ) {
+ lon *= RAD2DEG;
+ lat *= RAD2DEG;
+ }
+
+ return noerr;
+}
+
+
+bool SphericalProjection::geoCoordinates( const int viewportX, const int viewportY,
const ViewportParams *viewport,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit )
@@ -198,8 +241,8 @@
bool noerr = false;
qreal radius = (qreal)( viewport->radius() );
- qreal centerX = (qreal)( x - viewport->width() / 2 );
- qreal centerY = (qreal)( y - viewport->height() / 2 );
+ qreal centerX = (qreal)( viewportX - viewport->width() / 2 );
+ qreal centerY = (qreal)( viewportY - viewport->height() / 2 );
if ( radius * radius > centerX * centerX + centerY * centerY ) {
qreal qx = inverseRadius * +centerX;
--- trunk/KDE/kdeedu/marble/src/lib/Projections/SphericalProjection.h #1169603:1169604
@@ -83,16 +83,24 @@
const ViewportParams *viewport,
QVector<QPolygonF*> &polygons );
+ virtual QPointF projectionCoordinates( qreal lon, qreal lat ) const;
+
+ virtual bool geoCoordinates( qreal normalizedX, qreal normalizedY,
+ qreal& lon, qreal& lat,
+ GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree ) const;
+
/**
- * @brief Get the earth coordinates corresponding to a pixel in the map.
- * @param x the x coordinate of the pixel
- * @param y the y coordinate of the pixel
+ * @brief Get the earth coordinates corresponding to a pixel on the screen.
+ * @param viewportX the x coordinate of the pixel relative to the origin of the viewport
+ * @param viewportY the y coordinate of the pixel relative to the origin of the viewport
+ * @param viewport the viewport parameters
* @param lon the longitude angle is returned through this parameter
* @param lat the latitude angle is returned through this parameter
+ * @param unit the unit of the angles for lon and lat.
* @return @c true if the pixel (x, y) is within the globe
* @c false if the pixel (x, y) is outside the globe, i.e. in space.
*/
- bool geoCoordinates( const int x, const int y,
+ bool geoCoordinates( const int viewportX, const int viewportY,
const ViewportParams *params,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree );
More information about the Marble-commits
mailing list