Loading...
Searching...
No Matches
GeoFrame.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31#ifndef GEOFRAME_H_
32#define GEOFRAME_H_
33
34#include "Geometry.h"
35#include "drain/util/BoundingBox.h"
36#include "drain/util/Geo.h"
37#include "drain/util/Proj6.h" // for geographical projection of radar data bins
38
39
40namespace drain
41{
42
43
44
45namespace image
46{
47
48class GeoInfo {
49
50public:
51 // TODO: CartesianODIM compatibility
52};
53
55
58class GeoFrame { // See also
59
60public:
61
62 //typedef unsigned int icoord_t;
63
65 GeoFrame(unsigned int width = 0, unsigned int height = 0);
66
67 virtual inline
68 ~GeoFrame(){
69 };
70
71 inline
72 void reset(){
73 setGeometry(0, 0);
74 setBoundingBoxD(0,0,0,0);
75 //bBoxD.set(+180.0, +90.0, -180.0, -90.0);
76 }
77
79
82 inline
83 bool projectionIsSet() const {
84 return projGeo2Native.isSet();
85 };
86
88 inline
89 bool geometryIsSet() const {
90 return ((frameWidth > 0) && (frameHeight > 0));
91 };
92
94
98 inline
99 bool bboxIsSet() const {
100 return (bBoxD.getArea() > 0.0);
101 };
102
104
108 inline
109 bool isDefined() const {
110 return geometryIsSet() && projectionIsSet() && bboxIsSet();
111 };
112
113
114 // Notice that someday this does NOT allocate memory. @see allocate();
115 virtual
116 void setGeometry(unsigned int width, unsigned int height);
117
119 inline
120 int getFrameWidth() const {return frameWidth; };
121
123 inline
124 int getFrameHeight() const {return frameHeight; };
125
126
128
134 void setBoundingBox(double lonLL, double latLL, double lonUR, double latUR);
135
137 inline
139 setBoundingBox(bbox.lowerLeft.x, bbox.lowerLeft.y, bbox.upperRight.x, bbox.upperRight.y);
140 }
141
142
144 //inline
145 void setBoundingBoxD(double lonLL, double latLL, double lonUR, double latUR);
146 // { setBoundingBoxR(DEG2RAD*lonLL, DEG2RAD*latLL, DEG2RAD*lonUR, DEG2RAD*latUR);}
147
149 inline
151 setBoundingBoxD(bboxD.lowerLeft.x, bboxD.lowerLeft.y, bboxD.upperRight.x, bboxD.upperRight.y);
152 }
153
154
156 inline
157 void setBoundingBoxR(double lonLL, double latLL, double lonUR, double latUR){
158 setBoundingBoxD(RAD2DEG*lonLL, RAD2DEG*latLL, RAD2DEG*lonUR, RAD2DEG*latUR);
159 }
160
162 inline
164 setBoundingBoxR(bboxR.lowerLeft.x, bboxR.lowerLeft.y, bboxR.upperRight.x, bboxR.upperRight.y);
165 }
166
167
169 void setBoundingBoxM(double xLL, double yLL, double xUR, double yUR);
170
172 inline
173 /*
174 void setBoundingBoxM(const drain::Rectangle<double> & bboxM) {
175 setBoundingBoxM(bboxM.lowerLeft.x, bboxM.lowerLeft.y, bboxM.upperRight.x, bboxM.upperRight.y);
176 }*/
178 setBoundingBoxM(bboxM[0], bboxM[1], bboxM[2], bboxM[3]);
179 }
180
181protected:
182
184 void updateBoundingBoxR(); //double lonLL, double latLL, double lonUR, double latUR);
185
187 void updateBoundingBoxD(); //double lonLL, double latLL, double lonUR, double latUR);
188
190 void updateBoundingBoxM(); // double lonLL, double latLL, double lonUR, double latUR);
191
192
194 void updateScaling();
195
196public:
197
198
199
201 inline
203
205 inline
207
209 inline
211
212 void getCenterPixel(drain::Rectangle<double> & pixelD) const;
213
215 inline
216 double getXScale() const {
217 return xScale;
218 }
219
221 inline
222 double getYScale() const {
223 return yScale;
224 }
225
226
227
229 /*
230 * \par bboxM - bounding box (xLowerLeft, yLowerLeft, xUpperRight, yUpperRight).
231 */
232 inline
234 cropWithM(bboxM.lowerLeft.x, bboxM.lowerLeft.y, bboxM.upperRight.x, bboxM.upperRight.y);
235 }
236
238 void cropWithM(double xLL, double yLL, double xUR, double yUR);
239
240
242 virtual inline
243 void deg2pix(double lon, double lat, int & i, int & j) const {
244 projGeo2Native.projectFwd(lon, lat, lon, lat); // PROJ6-CRS uses degrees
245 // ...Now (lon,lat) are metric
246 // projGeo2Native.projectFwd(lon*DEG2RAD, lat*DEG2RAD, lon, lat); // PROJ6-CRS uses degrees
247 m2pix(lon, lat, i,j);
248 }
249
251 inline
252 void deg2pix(const drain::Point2D<double> & loc, drain::Point2D<int> & pix) const {
253 deg2pix(loc.x, loc.y, pix.x, pix.y);
254 }
255
257
259 virtual inline
260 void deg2m(double lon, double lat, double &x, double &y) const {
261 projGeo2Native.projectFwd(lon, lat, x, y); // PROJ6-CRS uses degrees
262 }
263
265
267 inline
268 void deg2m(const drain::Point2D<double> & pDeg, drain::Point2D<double> & pMet) const {
269 deg2m(pDeg.x, pDeg.y, pMet.x, pMet.y);
270 }
271
273 virtual inline
274 void pix2deg(int i, int j, double & lon, double & lat) const {
275 pix2m(i,j, lon,lat); //pix2m(i,j, x,y);
276 projGeo2Native.projectInv(lon,lat, lon,lat);
277 // lon *= RAD2DEG; // PROJ6-CRS uses degrees
278 // lat *= RAD2DEG; // PROJ6-CRS uses degrees
279 }
280
282 virtual inline
283 void pix2rad(int i, int j, double & lon, double & lat) const {
284 pix2m(i,j, lon,lat);
285 projGeo2Native.projectInv(lon,lat, lon,lat);
286 // PROJ6-CRS uses degrees:
287 lon *= DEG2RAD;
288 lat *= DEG2RAD;
289 }
290
291
293 inline
294 void pix2deg(const drain::Point2D<int> & pix, drain::Point2D<double> & loc) const {
295 pix2deg(pix.x,pix.y, loc.x,loc.y);
296 }
297
299 virtual inline
300 void pix2LLdeg(int i,int j, double & lon, double & lat) const {
301 double x, y; // metric
302 pix2LLm(i,j, x,y);
303 projGeo2Native.projectInv(x,y, lon,lat);
304 // lon *= RAD2DEG; // PROJ6-CRS uses degrees
305 // lat *= RAD2DEG; // PROJ6-CRS uses degrees
306 }
307
309
311 virtual inline
312 void m2deg(double x, double y, double & lon, double & lat) const {
313 projGeo2Native.projectInv(x,y, lon,lat);
314 // lon *= RAD2DEG; // PROJ6-CRS uses degrees
315 // lat *= RAD2DEG; // PROJ6-CRS uses degrees
316 }
317
319
321 virtual inline
322 void m2deg(const drain::Point2D<double> & pMetric, drain::Point2D<double> & pDeg) const {
323 projGeo2Native.projectInv(pMetric.x, pMetric.y, pDeg.x, pDeg.y); // lon, lat);
324 //pDeg.x *= RAD2DEG; // PROJ6-CRS uses degrees
325 //pDeg.y *= RAD2DEG; // PROJ6-CRS uses degrees
326 }
327
328 /* UNTESTED
329 inline virtual
330 void LLdeg2m(const double & lon, const double & lat, double & x, double & y) const {
331 projGeo2Native.projectFwd(lon,lat, x,y);
332 }
333 */
334
335
337
344 inline virtual
345 void m2pix(double x, double y, int & i, int & j) const {
346 // i = static_cast<int>(0.5+ (x - bBoxNative.lowerLeft.x) / xScale); // xOffset
347 // j = frameHeight-1 - static_cast<int>(0.5+ (y - bBoxNative.lowerLeft.y) / yScale);
348 // j = frameHeight-1 - static_cast<int>(0.5+ (y - bBoxNative.lowerLeft.y) / yScale);
349 i = ::lround((x - bBoxNative.lowerLeft.x) / xScale); // xOffset
350 j = frameHeight-1 - ::lround((y - bBoxNative.lowerLeft.y) / yScale);
351 }
352
353 inline virtual
354 void m2pix(const drain::Point2D<double> & pMetric, drain::Point2D<int> & pImage) const {
355 // pImage.x = static_cast<int>(0.5+ (pMetric.x - bBoxNative.lowerLeft.x) / xScale); // xOffset
356 // pImage.y = frameHeight-1 - static_cast<int>(0.5+ (pMetric.y - bBoxNative.lowerLeft.y) / yScale);
357 // pImage.y = frameHeight-1 - static_cast<int>(0.5+ (pMetric.y - bBoxNative.lowerLeft.y) / yScale);
358 pImage.x = ::lround( (pMetric.x - bBoxNative.lowerLeft.x) / xScale); // xOffset
359 pImage.y = frameHeight-1 - ::lround((pMetric.y - bBoxNative.lowerLeft.y) / yScale);
360 }
361
362
364
371 inline
372 virtual
373 void pix2m(int i, int j, double & x, double & y) const {
374 x = (static_cast<double>(i)+0.5)*xScale + bBoxNative.lowerLeft.x;
375 y = (static_cast<double>(frameHeight-1 - j)+0.5)*yScale + bBoxNative.lowerLeft.y;
376 }
377
379 inline
380 virtual
381 void pix2m(const drain::Point2D<int> & pImage, drain::Point2D<double> & pMetric) const {
382 pMetric.x = (static_cast<double>(pImage.x)+0.5)*xScale + bBoxNative.lowerLeft.x;
383 pMetric.y = (static_cast<double>(frameHeight-1 - pImage.y)+0.5)*yScale + bBoxNative.lowerLeft.y;
384 }
385
387
395 inline
396 virtual
397 void pix2LLm(int i, int j, double & x, double & y) const {
398 x = (static_cast<double>(i))*xScale + bBoxNative.lowerLeft.x;
399 y = (static_cast<double>(frameHeight-1 - j))*yScale + bBoxNative.lowerLeft.y;
400 // y = (static_cast<double>(frameHeight-1 - j))*yScale + bBoxNative.lowerLeft.y;
401 }
402
403
404
405
406
408 inline
409 void setProjection(const std::string & projDef){
412 }
413
415 inline
416 void setProjectionEPSG(int epsg){
419 }
420
422 void updateProjection();
423
425 inline
426 const std::string & getProjection() const { return projGeo2Native.getProjectionDst();};
427
429 // Consider: rename src/input projection coord system
430 inline
431 const std::string & getCoordinateSystem() const { return projGeo2Native.getProjectionSrc();};
432
433
435 inline
436 //const drain::Rectangle<double> & getDataBBoxD() const { return dataBBoxD; };
438
440 inline
441 //const drain::Rectangle<double> & getDataOverlapD() const { return dataOverlapD; };
443
445
448 void updateDataExtentDeg(const drain::Rectangle<double> &inputBBoxDeg);
449
453 void updateDataExtentNat(const drain::Rectangle<double> &inputBBoxNat);
454
455
456 inline
457 bool isLongLat() const {
458 return projGeo2Native.isLongLat();
459 }
460
463
464 //std::ostream & toOStr(std::ostream & ostr) const ;
465 virtual
466 std::ostream & toStream(std::ostream & ostr) const;
467
468
469
470protected:
471
472 // drain::image::AreaGeometry frameGeometry; would be fine, but unsigned caused conversion/cast underflows
473 int frameWidth;
474 int frameHeight;
475
478
481
484
485
486 // experimental
489
490 // experimental
493
495 // drain::Rectangle<double> dataBBoxD;
496
498 //drain::Rectangle<double> dataOverlapD;
499
500 // ... needed in mapping...
501 double xScale = 0.0;
502 double yScale = 0.0;
503
504};
505
506inline
507std::ostream & operator<<(std::ostream & ostr, const GeoFrame & frame){
508 frame.GeoFrame::toStream(ostr);
509 ostr << '\n';
510 return ostr;
511}
512
513
514} // ::image
515} // ::drain
516
517#endif /*COMPOSITOR_R_H_*/
518
519// Drain
Definition Proj6.h:66
void setProjectionDst(const std::string &projDef, Projector::CRS_mode crs=Projector::FORCE_CRS)
Sets destination projection.
Definition Proj6.h:110
bool isLongLat() const
Check if destination projection is longitude-latitude degrees.
Definition Proj6.h:228
const std::string & getProjectionSrc() const
Returns the projection std::string applied by the last setProjection call.
Definition Proj6.h:144
void projectFwd(double &x, double &y) const
Forward projection (in-place)
Definition Proj6.h:172
void setProjection(const std::string &str, CRS_mode crs=FORCE_CRS)
Sets projection defined as Proj string.
Definition Projector.cpp:97
Tuple of N elements of type T.
Definition UniTuple.h:65
Array with georeferencing support.
Definition GeoFrame.h:58
drain::Rectangle< double > bBoxR
Geographical scope in Radians.
Definition GeoFrame.h:477
void setBoundingBox(const drain::Rectangle< double > &bbox)
Sets bounding box in degrees in the target coordinate system.
Definition GeoFrame.h:138
virtual void pix2m(const drain::Point2D< int > &pImage, drain::Point2D< double > &pMetric) const
Scales image coordinates (i,j) to map coordinates (x,y) in the pixel centres.
Definition GeoFrame.h:381
const std::string & getCoordinateSystem() const
Returns the source projection (should be radian array, lon & lat).
Definition GeoFrame.h:431
virtual void m2pix(double x, double y, int &i, int &j) const
Scales geographic map coordinates to image coordinates.
Definition GeoFrame.h:345
const drain::Rectangle< double > & getDataOverlapBBoxNat() const
Return the common overlapping geographical area (intersection) implied by input data.
Definition GeoFrame.h:442
const drain::Rectangle< double > & getBoundingBoxRad() const
Returns the geographical scope in Radians.
Definition GeoFrame.h:210
const std::string & getProjection() const
Returns the projection of the composite image as a proj4 std::string.
Definition GeoFrame.h:426
void setProjectionEPSG(int epsg)
Sets the projection of the image as a EPSG code.
Definition GeoFrame.h:416
void updateScaling()
Geometric scaling.
Definition GeoFrame.cpp:331
virtual void pix2rad(int i, int j, double &lon, double &lat) const
Calculates the geographic coordinates (lon,lat) [rad] of the center of a pixel at (i,...
Definition GeoFrame.h:283
virtual void m2deg(const drain::Point2D< double > &pMetric, drain::Point2D< double > &pDeg) const
Convert metric coordinates to degrees.
Definition GeoFrame.h:322
void updateProjection()
Updates bboxes, if needed.
Definition GeoFrame.cpp:289
void pix2deg(const drain::Point2D< int > &pix, drain::Point2D< double > &loc) const
Calculates the geographic coordinates of the center of a pixel at (i,j).
Definition GeoFrame.h:294
void updateDataExtentNat(const drain::Rectangle< double > &inputBBoxNat)
Definition GeoFrame.cpp:428
void setBoundingBoxR(double lonLL, double latLL, double lonUR, double latUR)
Sets bounding box in radians in the target coordinate system.
Definition GeoFrame.h:157
const drain::Rectangle< double > & getDataBBoxNat() const
Return the actual geographical boundingBox suggested by implied by input data.
Definition GeoFrame.h:437
double xScale
Utility for deriving extent (degrees) required by input data.
Definition GeoFrame.h:501
void updateBoundingBoxR()
Proj 6 NEW: Given BBox in geo coords [deg], adjust geo coords [rad].
Definition GeoFrame.cpp:242
void updateBoundingBoxD()
Given BBox in geo coords [rad], adjust geo coords [deg].
Definition GeoFrame.cpp:234
const drain::Rectangle< double > & getBoundingBoxNat() const
Returns the geographical scope in Meters.
Definition GeoFrame.h:206
bool bboxIsSet() const
Returns true, if the bounding box (geographical extent) has been set.
Definition GeoFrame.h:99
int getFrameHeight() const
Return the nominal height, not the height of the memory array which does not have to be allocated.
Definition GeoFrame.h:124
void updateDataExtentDeg(const drain::Rectangle< double > &inputBBoxDeg)
Extend to include this input.
Definition GeoFrame.cpp:414
virtual void pix2LLdeg(int i, int j, double &lon, double &lat) const
Calculates the geographic coordinates of the lower left corner of a pixel at (i,j).
Definition GeoFrame.h:300
drain::Rectangle< double > dataBBoxNat
For deriving extent (~union) of input data.
Definition GeoFrame.h:488
bool geometryIsSet() const
Return true, if array area is greater than zero.
Definition GeoFrame.h:89
bool projectionIsSet() const
Returns true, if the geographical extent has been set.
Definition GeoFrame.h:83
void setBoundingBox(double lonLL, double latLL, double lonUR, double latUR)
Sets bounding box in degrees OR in metres in the target coordinate system.
Definition GeoFrame.cpp:90
void setBoundingBoxM(double xLL, double yLL, double xUR, double yUR)
Sets bounding box in meters in the target coordinate system.
Definition GeoFrame.cpp:168
virtual void pix2LLm(int i, int j, double &x, double &y) const
Scales image coordinates (i,j) to map coordinates (x,y) of the lower left corner pixel.
Definition GeoFrame.h:397
void setBoundingBoxM(const drain::UniTuple< double, 4 > &bboxM)
Sets bounding box in meters in the target coordinate system.
Definition GeoFrame.h:177
drain::Rectangle< double > bBoxNative
Geographical scope in meters, or degrees in case of long/lat.
Definition GeoFrame.h:483
virtual void pix2m(int i, int j, double &x, double &y) const
Scales image coordinates (i,j) to map coordinates (x,y) in the pixel centres.
Definition GeoFrame.h:373
virtual void deg2m(double lon, double lat, double &x, double &y) const
Convert degrees to native (often metric) coordinates.
Definition GeoFrame.h:260
void setBoundingBoxR(const drain::Rectangle< double > &bboxR)
Sets bounding box in radians in the target coordinate system.
Definition GeoFrame.h:163
void updateBoundingBoxM()
Given BBox in geo coords [rad], adjust metric bounding box. Do not update xScale or yScale.
Definition GeoFrame.cpp:250
virtual void m2deg(double x, double y, double &lon, double &lat) const
Convert metric coordinates to degrees.
Definition GeoFrame.h:312
bool isDefined() const
Returns true, if the projection, array area and geographical extent bounding box has been set.
Definition GeoFrame.h:109
virtual void deg2pix(double lon, double lat, int &i, int &j) const
Projects geographic coordinates to image coordinates.
Definition GeoFrame.h:243
drain::Rectangle< double > dataOverlapBBoxNat
For deriving common extent (~intersection) of input data.
Definition GeoFrame.h:492
virtual void pix2deg(int i, int j, double &lon, double &lat) const
Calculates the geographic coordinates of the center of a pixel at (i,j).
Definition GeoFrame.h:274
const drain::Rectangle< double > & getBoundingBoxDeg() const
Returns the geographical scope in Degrees.
Definition GeoFrame.h:202
void setProjection(const std::string &projDef)
Sets the projection of the image as a Proj string.
Definition GeoFrame.h:409
double getYScale() const
Return vertical resolution of a pixel in meters (if metric) or degrees (if unprojected,...
Definition GeoFrame.h:222
drain::Proj6 projGeo2Native
Radial to metric.
Definition GeoFrame.h:462
void deg2pix(const drain::Point2D< double > &loc, drain::Point2D< int > &pix) const
Project geographic coordinates (degrees) to image coordinates (pixels).
Definition GeoFrame.h:252
void setBoundingBoxD(const drain::Rectangle< double > &bboxD)
Sets bounding box in degrees in the target coordinate system.
Definition GeoFrame.h:150
void cropWithM(drain::Rectangle< double > &bboxM)
Crops the initial bounding box with a given bounding box.
Definition GeoFrame.h:233
double getXScale() const
Return horizontal resolution of a pixel in meters (if metric) or degrees (if unprojected,...
Definition GeoFrame.h:216
void deg2m(const drain::Point2D< double > &pDeg, drain::Point2D< double > &pMet) const
Convert degrees to native (often metric) coordinates.
Definition GeoFrame.h:268
void setBoundingBoxD(double lonLL, double latLL, double lonUR, double latUR)
Sets bounding box in degrees in the target coordinate system.
Definition GeoFrame.cpp:149
drain::Rectangle< double > bBoxD
Geographical scope in Degrees.
Definition GeoFrame.h:480
int getFrameWidth() const
Return the nominal width, not the width of the memory array which does not have to be allocated.
Definition GeoFrame.h:120
Definition GeoFrame.h:48
Definition DataSelector.cpp:1277
Definition Point.h:48
Rectange defined through lower left and upper right coordinates.
Definition Rectangle.h:65