1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file tcElevationData.cpp
22 * @brief A block of pixel data representing elevation.
25 #include "tcElevationData.h"
28 * Constructors + destructor
31 /// Default constructor.
32 tcElevationData::tcElevationData()
38 /// Primary constructor.
39 tcElevationData::tcElevationData(int width
, int height
)
40 : Parent(width
, height
)
46 tcElevationData::~tcElevationData()
54 /// Sample elevation at a coordinate.
55 float tcElevationData::elevationAt(const tcGeo
& coord
) const
57 maths::Vector
<2,double> pt
= m_geoToPixels
* coord
;
58 return sampleFloat(pt
[0]/(width()-1), pt
[1]/(height()-1));
61 /// Get the max elevation over a range of pixels.
62 float tcElevationData::maxElevation(const tcGeo
& swCorner
, const tcGeo
& neCorner
, bool* inRange
) const
64 maths::Vector
<2,double> corner1
= m_geoToPixels
* swCorner
;
65 maths::Vector
<2,double> corner2
= m_geoToPixels
* neCorner
;
67 maths::Vector
<2,double> minCorner(qMin(corner1
[0], corner2
[0]),
68 qMin(corner1
[1], corner2
[1]));
69 maths::Vector
<2,double> maxCorner(qMax(corner1
[0], corner2
[0]),
70 qMax(corner1
[1], corner2
[1]));
72 // Go through pixels in this range.
75 int minj
= qMax((int)ceil(minCorner
[1]), 0);
76 int maxj
= qMin((int)ceil(maxCorner
[1]), height());
77 int mini
= qMax((int)ceil(minCorner
[0]), 0);
78 int maxi
= qMin((int)ceil(maxCorner
[0]), width());
79 for (int j
= minj
; j
< maxj
; ++j
)
81 for (int i
= mini
; i
< maxi
; ++i
)
83 int index
= j
*width() + i
;
85 max
= qMax(max
, buffer()[index
]);
96 // Just average the samples
101 // No samples? resort to interpolation
102 maths::Vector
<2,float> mid(corner1
+ corner2
);
104 mid
[0] /= width() -1;
105 mid
[1] /= height()-1;
106 if (mid
[0] >= 0.0f
&& mid
[0] <= 1.0f
&&
107 mid
[1] >= 0.0f
&& mid
[1] <= 1.0f
)
109 return Parent::sampleFloat(mid
[0], mid
[1]);
122 /// Get the mean elevation over a range of pixels.
123 float tcElevationData::meanElevation(const tcGeo
& swCorner
, const tcGeo
& neCorner
, bool* inRange
) const
125 maths::Vector
<2,double> corner1
= m_geoToPixels
* swCorner
;
126 maths::Vector
<2,double> corner2
= m_geoToPixels
* neCorner
;
128 maths::Vector
<2,double> minCorner(qMin(corner1
[0], corner2
[0]),
129 qMin(corner1
[1], corner2
[1]));
130 maths::Vector
<2,double> maxCorner(qMax(corner1
[0], corner2
[0]),
131 qMax(corner1
[1], corner2
[1]));
133 // Go through pixels in this range.
136 int minj
= qMax((int)ceil(minCorner
[1]), 0);
137 int maxj
= qMin((int)ceil(maxCorner
[1]), height());
138 int mini
= qMax((int)ceil(minCorner
[0]), 0);
139 int maxi
= qMin((int)ceil(maxCorner
[0]), width());
140 for (int j
= minj
; j
< maxj
; ++j
)
142 for (int i
= mini
; i
< maxi
; ++i
)
144 int index
= j
*width() + i
;
146 total
+= buffer()[index
];
157 // Just average the samples
158 return total
/ count
;
162 // No samples? resort to interpolation
163 maths::Vector
<2,float> mid(corner1
+ corner2
);
165 mid
[0] /= width() -1;
166 mid
[1] /= height()-1;
167 if (mid
[0] >= 0.0f
&& mid
[0] <= 1.0f
&&
168 mid
[1] >= 0.0f
&& mid
[1] <= 1.0f
)
170 return Parent::sampleFloat(mid
[0], mid
[1]);
183 /// Set the geographical to pixels transformation.
184 void tcElevationData::setGeoToPixels(const tcAffineTransform2
<double>& geoToPixels
)
186 m_geoToPixels
= geoToPixels
;
193 /// Get the coordinate of the most south westerly corner.
194 tcGeo
tcElevationData::swCorner() const
196 tcAffineTransform2
<double> pixelsToGeo
= m_geoToPixels
.inverse();
197 return (tcGeo
)(pixelsToGeo
* maths::Vector
<2,double>(0.0, height()-1));
200 /// Get the coordinate of the most north easterly corner.
201 tcGeo
tcElevationData::neCorner() const
203 tcAffineTransform2
<double> pixelsToGeo
= m_geoToPixels
.inverse();
204 return (tcGeo
)(pixelsToGeo
* maths::Vector
<2,double>(width()-1, 0.0));