Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Hack #2 for measuring. Localized numbers, added hectares (ha),
centralized pretty printing of units and made special cases for
projection on and projection off.


git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@6450 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
homann committed Jan 21, 2007
1 parent 2df4c40 commit f5ba57c
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 66 deletions.
8 changes: 3 additions & 5 deletions src/app/qgsmaptoolidentify.cpp
Expand Up @@ -215,7 +215,7 @@ void QgsMapToolIdentify::identifyVectorLayer(QgsVectorLayer* layer, const QgsPoi

// init distance/area calculator
QgsDistanceArea calc;
calc.setProjectionsEnabled(TRUE); // always project
calc.setProjectionsEnabled(mCanvas->projectionsEnabled()); // project?
calc.setEllipsoid(ellipsoid);
calc.setSourceSRS(layer->srs().srsid());

Expand Down Expand Up @@ -265,15 +265,13 @@ void QgsMapToolIdentify::identifyVectorLayer(QgsVectorLayer* layer, const QgsPoi
if (layer->vectorType() == QGis::Line)
{
double dist = calc.measure(feat.geometry());
QString str = QString::number(dist/1000, 'f', 3);
str += " km";
QString str = calc.textUnit(dist, 3, mCanvas->mapUnits(), false);
mResults->addDerivedAttribute(featureNode, QObject::tr("Length"), str);
}
else if (layer->vectorType() == QGis::Polygon)
{
double area = calc.measure(feat.geometry());
QString str = QString::number(area/1000000, 'f', 3);
str += " km^2";
QString str = calc.textUnit(area, 3, mCanvas->mapUnits(), true);
mResults->addDerivedAttribute(featureNode, QObject::tr("Area"), str);
}

Expand Down
70 changes: 9 additions & 61 deletions src/app/qgsmeasure.cpp
Expand Up @@ -27,6 +27,7 @@

#include "QMessageBox"
#include <QSettings>
#include <QLocale>
#include <iostream>


Expand Down Expand Up @@ -184,12 +185,11 @@ void QgsMeasure::addPoint(QgsPoint &point)
editTotal->setText(formatDistance(mTotal));


int row = mPoints.size()-2;
mTable->setText(row, 0, QString::number(d, 'f',1));
//mTable->setText ( row, 1, QString::number(mTotal) );
int row = mPoints.size()-2;
mTable->setText(row, 0, QLocale::system().toString(d, 'f', 2));
mTable->setNumRows ( mPoints.size() );

mTable->setText(row + 1, 0, QString::number(0, 'f',1));
mTable->setText(row + 1, 0, QLocale::system().toString(0.0, 'f', 2));
mTable->ensureCellVisible(row + 1,0);
}

Expand Down Expand Up @@ -232,7 +232,8 @@ void QgsMeasure::mouseMove(QgsPoint &point)
QgsPoint p1 = tmpPoints[last], p2 = tmpPoints[last+1];

double d = mCanvas->mapRender()->distArea()->measureLine(p1,p2);
mTable->setText(last, 0, QString::number(d, 'f',1));
//mTable->setText(last, 0, QString::number(d, 'f',1));
mTable->setText(last, 0, QLocale::system().toString(d, 'f', 2));
editTotal->setText(formatDistance(mTotal + d));
}
}
Expand Down Expand Up @@ -299,66 +300,13 @@ QString QgsMeasure::formatDistance(double distance)
QString unitLabel;

QGis::units myMapUnits = mCanvas->mapUnits();
switch (myMapUnits)
{
case QGis::METERS:
if (distance > 1000.0)
{
unitLabel=tr(" km");
distance = distance/1000;
}
else if (distance < 0.01)
{
unitLabel=tr(" mm");
distance = distance*1000;
}
else if (distance < 0.1)
{
unitLabel=tr(" cm");
distance = distance*100;
}
else
unitLabel=tr(" m");
break;
case QGis::FEET:
if (distance == 1.0)
unitLabel=tr(" foot");
else
unitLabel=tr(" feet");
break;
case QGis::DEGREES:
if (distance == 1.0)
unitLabel=tr(" degree");
else
unitLabel=tr(" degrees");
break;
case QGis::UNKNOWN:
unitLabel=tr(" unknown");
default:
std::cout << "Error: not picked up map units - actual value = "
<< myMapUnits << std::endl;
};

txt = QString::number(distance,'f',1);
txt += unitLabel;

return txt;
return QgsDistanceArea::textUnit(distance, 2, myMapUnits, false);
}

QString QgsMeasure::formatArea(double area)
{
QString txt;
if (area < 10000)
{
txt = QString::number(area,'f',0);
txt += " m2";
}
else
{
txt = QString::number(area/1000000,'f',3);
txt += " km2";
}
return txt;
QGis::units myMapUnits = mCanvas->mapUnits();
return QgsDistanceArea::textUnit(area, 2, myMapUnits, true);
}

void QgsMeasure::updateUi()
Expand Down
113 changes: 113 additions & 0 deletions src/core/qgsdistancearea.cpp
Expand Up @@ -17,6 +17,9 @@
#include <cmath>
#include <sqlite3.h>
#include <QDir>
#include <QString>
#include <QLocale>
#include <QObject>

#include "qgis.h"
#include "qgspoint.h"
Expand Down Expand Up @@ -529,6 +532,10 @@ double QgsDistanceArea::computePolygonArea(const std::vector<QgsPoint>& points)
double Qbar1, Qbar2;
double area;

if (! mProjectionsEnabled)
{
return computePolygonFlatArea(points);
}
int n = points.size();
x2 = DEG2RAD(points[n-1].x());
y2 = DEG2RAD(points[n-1].y());
Expand Down Expand Up @@ -573,3 +580,109 @@ double QgsDistanceArea::computePolygonArea(const std::vector<QgsPoint>& points)
return area;
}

double QgsDistanceArea::computePolygonFlatArea(const std::vector<QgsPoint>& points)
{
// Normal plane area calculations.
double area = 0.0;
int i, size;

size = points.size();

// QgsDebugMsg("New area calc, nr of points: " + QString::number(size));
for(i = 0; i < size; i++)
{
// QgsDebugMsg("Area from point: " + (points[i]).stringRep(2));
// Using '% size', so that we always end with the starting point
// and thus close the polygon.
area = area + points[i].x()*points[(i+1) % size].y() - points[(i+1) % size].x()*points[i].y();
}
// QgsDebugMsg("Area from point: " + (points[i % size]).stringRep(2));
area = area / 2.0;
return area;
}

QString QgsDistanceArea::textUnit(double value, int decimals, QGis::units u, bool isArea)
{
QString unitLabel;


switch (u)
{
case QGis::METERS:
if (isArea)
{
if (value > 1000000.0)
{
unitLabel = QObject::tr(" km2");
value = value / 1000000.0;
}
else if (value > 1000.0)
{
unitLabel = QObject::tr(" ha");
value = value / 10000.0;
}
else
{
unitLabel = QObject::tr(" m2");
}
}
else
{
if (value > 1000.0)
{
unitLabel=QObject::tr(" km");
value = value/1000;
}
else if (value < 0.01)
{
unitLabel=QObject::tr(" mm");
value = value*1000;
}
else if (value < 0.1)
{
unitLabel=QObject::tr(" cm");
value = value*100;
}
else
{
unitLabel=QObject::tr(" m");
}
}
break;
case QGis::FEET:
if (isArea)
{
unitLabel = QObject::tr(" sq ft");
}
else
{
if (value == 1.0)
unitLabel=QObject::tr(" foot");
else
unitLabel=QObject::tr(" feet");
}
break;
case QGis::DEGREES:
if (isArea)
{
unitLabel = QObject::tr(" sq.deg.");
}
else
{
if (value == 1.0)
unitLabel=QObject::tr(" degree");
else
unitLabel=QObject::tr(" degrees");
}
break;
case QGis::UNKNOWN:
unitLabel=QObject::tr(" unknown");
default:
std::cout << "Error: not picked up map units - actual value = "
<< u << std::endl;
};


return QLocale::system().toString(value, 'f', decimals) + unitLabel;

}
4 changes: 4 additions & 0 deletions src/core/qgsdistancearea.h
Expand Up @@ -84,6 +84,8 @@ class CORE_EXPORT QgsDistanceArea
//! compute bearing - in radians
double getBearing(const QgsPoint& p1, const QgsPoint& p2);

static QString textUnit(double value, int decimals, QGis::units u, bool isArea);

protected:

//! measures line distance, line points are extracted from WKB
Expand Down Expand Up @@ -111,6 +113,8 @@ class CORE_EXPORT QgsDistanceArea
*/
double computePolygonArea(const std::vector<QgsPoint>& points);

double computePolygonFlatArea(const std::vector<QgsPoint>& points);

/**
precalculates some values
Expand Down

0 comments on commit f5ba57c

Please sign in to comment.