Skip to content
Permalink
Browse files

Fixed measurements from identify tool:

* Added support for 25D (by ignoring Z value completely)
* Made the tool convert to the preferred units set for measurment tool

git-svn-id: http://svn.osgeo.org/qgis/trunk@11474 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
homann
homann committed Aug 21, 2009
1 parent f346a86 commit a6081baa828c5c8c18754ded4f10955d1423c6a7
Showing with 90 additions and 11 deletions.
  1. +52 −2 src/app/qgsmaptoolidentify.cpp
  2. +5 −0 src/app/qgsmaptoolidentify.h
  3. +31 −7 src/core/qgsdistancearea.cpp
  4. +2 −2 src/core/qgsdistancearea.h
@@ -346,7 +346,9 @@ void QgsMapToolIdentify::identifyVectorLayer( const QgsPoint& point )
if ( layer->geometryType() == QGis::Line )
{
double dist = calc.measure( f_it->geometry() );
QString str = calc.textUnit( dist, 3, mCanvas->mapUnits(), false );
QGis::UnitType myDisplayUnits;
convertMeasurement( calc, dist, myDisplayUnits, false );
QString str = calc.textUnit( dist, 3, myDisplayUnits, false ); // dist and myDisplayUnits are out params
mResults->addDerivedAttribute( featureNode, tr( "Length" ), str );
if ( f_it->geometry()->wkbType() == QGis::WKBLineString )
{
@@ -364,7 +366,9 @@ void QgsMapToolIdentify::identifyVectorLayer( const QgsPoint& point )
else if ( layer->geometryType() == QGis::Polygon )
{
double area = calc.measure( f_it->geometry() );
QString str = calc.textUnit( area, 3, mCanvas->mapUnits(), true );
QGis::UnitType myDisplayUnits;
convertMeasurement( calc, area, myDisplayUnits, true ); // area and myDisplayUnits are out params
QString str = calc.textUnit( area, 3, myDisplayUnits, true );
mResults->addDerivedAttribute( featureNode, tr( "Area" ), str );
}
else if ( layer->geometryType() == QGis::Point )
@@ -534,3 +538,49 @@ void QgsMapToolIdentify::removeLayer( QString layerID )
}
}
}

void QgsMapToolIdentify::convertMeasurement( QgsDistanceArea &calc, double &measure, QGis::UnitType &u, bool isArea )
{
// Helper for converting between meters and feet
// The parameter &u is out only...

QGis::UnitType myUnits = mCanvas->mapUnits();
if (( myUnits == QGis::Degrees || myUnits == QGis::Feet ) &&
calc.ellipsoid() != "NONE" &&
calc.hasCrsTransformEnabled() )
{
// Measuring on an ellipsoid returns meters, and so does using projections???
myUnits = QGis::Meters;
QgsDebugMsg( "We're measuring on an ellipsoid or using projections, the system is returning meters" );
}

// Get the units for display
QSettings settings;
QString myDisplayUnitsTxt = settings.value( "/qgis/measure/displayunits", "meters" ).toString();

// Only convert between meters and feet
if ( myUnits == QGis::Meters && myDisplayUnitsTxt == "feet" )
{
QgsDebugMsg( QString( "Converting %1 meters" ).arg( QString::number( measure ) ) );
measure /= 0.3048;
if ( isArea )
{
measure /= 0.3048;
}
QgsDebugMsg( QString( "to %1 feet" ).arg( QString::number( measure ) ) );
myUnits = QGis::Feet;
}
if ( myUnits == QGis::Feet && myDisplayUnitsTxt == "meters" )
{
QgsDebugMsg( QString( "Converting %1 feet" ).arg( QString::number( measure ) ) );
measure *= 0.3048;
if ( isArea )
{
measure *= 0.3048;
}
QgsDebugMsg( QString( "to %1 meters" ).arg( QString::number( measure ) ) );
myUnits = QGis::Meters;
}

u = myUnits;
}
@@ -17,9 +17,11 @@
#ifndef QGSMAPTOOLIDENTIFY_H
#define QGSMAPTOOLIDENTIFY_H

#include "qgis.h"
#include "qgsmaptool.h"
#include "qgspoint.h"
#include "qgsfeature.h"
#include "qgsdistancearea.h"

#include <QObject>

@@ -108,6 +110,9 @@ class QgsMapToolIdentify : public QgsMapTool
//! list of identified features
QgsFeatureList mFeatureList;

//! Private helper
void convertMeasurement( QgsDistanceArea &calc, double &measure, QGis::UnitType &u, bool isArea );

private slots:
// Let us know when the QgsIdentifyResults dialog box has been closed
void resultsDialogGone();
@@ -29,7 +29,6 @@
#include "qgsdistancearea.h"
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgslogger.h"

// MSVC compiler doesn't have defined M_PI in math.h
#ifndef M_PI
@@ -185,34 +184,48 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
memcpy( &wkbType, ( wkb + 1 ), sizeof( wkbType ) );

// measure distance or area based on what is the type of geometry
bool hasZptr = false;

switch ( wkbType )
{
case QGis::WKBLineString25D:
hasZptr = true;
case QGis::WKBLineString:
measureLine( wkb, &res );
measureLine( wkb, &res, hasZptr );
QgsDebugMsg( "returning " + QString::number( res ) );
return res;

case QGis::WKBMultiLineString25D:
hasZptr = true;
case QGis::WKBMultiLineString:
count = *(( int* )( wkb + 5 ) );
ptr = wkb + 9;
for ( i = 0; i < count; i++ )
{
ptr = measureLine( ptr, &res );
ptr = measureLine( ptr, &res, hasZptr );
resTotal += res;
}
QgsDebugMsg( "returning " + QString::number( resTotal ) );
return resTotal;

case QGis::WKBPolygon25D:
hasZptr = true;
case QGis::WKBPolygon:
measurePolygon( wkb, &res );
measurePolygon( wkb, &res, hasZptr );
QgsDebugMsg( "returning " + QString::number( res ) );
return res;

case QGis::WKBMultiPolygon25D:
hasZptr = true;
case QGis::WKBMultiPolygon:
count = *(( int* )( wkb + 5 ) );
ptr = wkb + 9;
for ( i = 0; i < count; i++ )
{
ptr = measurePolygon( ptr, &res );
ptr = measurePolygon( ptr, &res, hasZptr );
resTotal += res;
}
QgsDebugMsg( "returning " + QString::number( resTotal ) );
return resTotal;

default:
@@ -222,7 +235,7 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
}


unsigned char* QgsDistanceArea::measureLine( unsigned char* feature, double* area )
unsigned char* QgsDistanceArea::measureLine( unsigned char* feature, double* area, bool hasZptr )
{
unsigned char *ptr = feature + 5;
unsigned int nPoints = *(( int* )ptr );
@@ -239,6 +252,12 @@ unsigned char* QgsDistanceArea::measureLine( unsigned char* feature, double* are
ptr += sizeof( double );
y = *(( double * ) ptr );
ptr += sizeof( double );
if ( hasZptr )
{
// totally ignore Z value
ptr += sizeof( double );
}

points.append( QgsPoint( x, y ) );
}

@@ -313,7 +332,7 @@ double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2 )
}


unsigned char* QgsDistanceArea::measurePolygon( unsigned char* feature, double* area )
unsigned char* QgsDistanceArea::measurePolygon( unsigned char* feature, double* area, bool hasZptr )
{
// get number of rings in the polygon
unsigned int numRings = *(( int* )( feature + 1 + sizeof( int ) ) );
@@ -344,6 +363,11 @@ unsigned char* QgsDistanceArea::measurePolygon( unsigned char* feature, double*
ptr += sizeof( double );
y = *(( double * ) ptr );
ptr += sizeof( double );
if ( hasZptr )
{
// totally ignore Z value
ptr += sizeof( double );
}

pnt = QgsPoint( x, y );

@@ -90,9 +90,9 @@ class CORE_EXPORT QgsDistanceArea
protected:

//! measures line distance, line points are extracted from WKB
unsigned char* measureLine( unsigned char* feature, double* area );
unsigned char* measureLine( unsigned char* feature, double* area, bool hasZptr = false );
//! measures polygon area, vertices are extracted from WKB
unsigned char* measurePolygon( unsigned char* feature, double* area );
unsigned char* measurePolygon( unsigned char* feature, double* area, bool hasZptr = false );

/**
calculates distance from two points on ellipsoid

0 comments on commit a6081ba

Please sign in to comment.
You can’t perform that action at this time.