Skip to content

Commit

Permalink
Hack #2 for measuring. Localized numbers, added hectares (ha),
Browse files Browse the repository at this point in the history
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.