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 <drain/util/Units.h>
35#include "Geometry.h"
36#include "drain/util/BoundingBox.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
63 GeoFrame();
64
66 GeoFrame(unsigned int width, unsigned int height);
67
68 virtual inline
69 ~GeoFrame(){
70 };
71
72 inline
73 void reset(){
74 setGeometry(0, 0);
75 setBoundingBoxD(0,0,0,0);
76 //bBoxD.set(+180.0, +90.0, -180.0, -90.0);
77 }
78
80
83 inline
84 bool projectionIsSet() const {
85 return projGeo2Native.isSet();
86 };
87
89 inline
90 bool geometryIsSet() const {
91 return ((frame.width > 0) && (frame.height > 0));
92 };
93
95
99 inline
100 bool bboxIsSet() const {
101 return (bBoxD.getArea() > 0.0);
102 };
103
105
109 inline
110 bool isDefined() const {
111 return geometryIsSet() && projectionIsSet() && bboxIsSet();
112 };
113
114
115 // Notice that someday this does NOT allocate memory. @see allocate();
116 virtual
117 void setGeometry(unsigned int width, unsigned int height);
118
120 inline
121 int getFrameWidth() const {return frame.width; };
122
124 inline
125 int getFrameHeight() const {return frame.height; };
126
127
129
135 void setBoundingBox(double lonLL, double latLL, double lonUR, double latUR);
136
138 inline
140 setBoundingBox(bbox.lowerLeft.x, bbox.lowerLeft.y, bbox.upperRight.x, bbox.upperRight.y);
141 }
142
143
145 //inline
146 void setBoundingBoxD(double lonLL, double latLL, double lonUR, double latUR);
147 // { setBoundingBoxR(DEG2RAD*lonLL, DEG2RAD*latLL, DEG2RAD*lonUR, DEG2RAD*latUR);}
148
150 inline
152 setBoundingBoxD(bboxD.lowerLeft.x, bboxD.lowerLeft.y, bboxD.upperRight.x, bboxD.upperRight.y);
153 }
154
155
157 inline
158 void setBoundingBoxR(double lonLL, double latLL, double lonUR, double latUR){
159 setBoundingBoxD(RAD2DEG*lonLL, RAD2DEG*latLL, RAD2DEG*lonUR, RAD2DEG*latUR);
160 }
161
163 inline
165 setBoundingBoxR(bboxR.lowerLeft.x, bboxR.lowerLeft.y, bboxR.upperRight.x, bboxR.upperRight.y);
166 }
167
168
170 void setBoundingBoxNat(double xLL, double yLL, double xUR, double yUR);
171
173 inline
174 /*
175 void setBoundingBoxNat(const drain::Rectangle<double> & bboxM) {
176 setBoundingBoxNat(bboxM.lowerLeft.x, bboxM.lowerLeft.y, bboxM.upperRight.x, bboxM.upperRight.y);
177 }*/
179 setBoundingBoxNat(bboxM[0], bboxM[1], bboxM[2], bboxM[3]);
180 }
181
182protected:
183
185 void updateBoundingBoxR(); //double lonLL, double latLL, double lonUR, double latUR);
186
188 // void updateBoundingBoxD(); //double lonLL, double latLL, double lonUR, double latUR);
189
191 void updateBoundingBoxNat(); // double lonLL, double latLL, double lonUR, double latUR);
192
193
195 void updateScaling();
196
197public:
198
199
200
202 inline
204
206 inline
208
210 inline
212
213 void getCenterPixel(drain::Rectangle<double> & pixelD) const;
214
216 inline
217 double getXScale() const {
218 return xScale;
219 }
220
222 inline
223 double getYScale() const {
224 return yScale;
225 }
226
227
228
230 /*
231 * \par bboxM - bounding box (xLowerLeft, yLowerLeft, xUpperRight, yUpperRight).
232 */
233 inline
235 cropWithM(bboxM.lowerLeft.x, bboxM.lowerLeft.y, bboxM.upperRight.x, bboxM.upperRight.y);
236 }
237
239 void cropWithM(double xLL, double yLL, double xUR, double yUR);
240
241
243 virtual inline
244 void deg2pix(double lon, double lat, int & i, int & j) const {
245 projGeo2Native.projectFwd(lon, lat, lon, lat); // PROJ6-CRS uses degrees
246 // ...Now (lon,lat) are metric
247 // projGeo2Native.projectFwd(lon*DEG2RAD, lat*DEG2RAD, lon, lat); // PROJ6-CRS uses degrees
248 m2pix(lon, lat, i,j);
249 }
250
252 inline
253 void deg2pix(const drain::Point2D<double> & loc, drain::Point2D<int> & pix) const {
254 deg2pix(loc.x, loc.y, pix.x, pix.y);
255 }
256
258
260 virtual inline
261 void deg2m(double lon, double lat, double &x, double &y) const {
262 projGeo2Native.projectFwd(lon, lat, x, y); // PROJ6-CRS uses degrees
263 }
264
266
268 inline
269 void deg2m(const drain::Point2D<double> & pDeg, drain::Point2D<double> & pMet) const {
270 deg2m(pDeg.x, pDeg.y, pMet.x, pMet.y);
271 }
272
274 virtual inline
275 void pix2deg(int i, int j, double & lon, double & lat) const {
276 pix2m(i,j, lon,lat); //pix2m(i,j, x,y);
277 projGeo2Native.projectInv(lon,lat, lon,lat);
278 // lon *= RAD2DEG; // PROJ6-CRS uses degrees
279 // lat *= RAD2DEG; // PROJ6-CRS uses degrees
280 }
281
283 virtual inline
284 void pix2rad(int i, int j, double & lon, double & lat) const {
285 pix2m(i,j, lon,lat);
286 projGeo2Native.projectInv(lon,lat, lon,lat);
287 // PROJ6-CRS uses degrees:
288 lon *= DEG2RAD;
289 lat *= DEG2RAD;
290 }
291
292
294 inline
295 void pix2deg(const drain::Point2D<int> & pix, drain::Point2D<double> & loc) const {
296 pix2deg(pix.x,pix.y, loc.x,loc.y);
297 }
298
300 virtual inline
301 void pix2LLdeg(int i,int j, double & lon, double & lat) const {
302 double x, y; // metric
303 pix2LLm(i,j, x,y);
304 projGeo2Native.projectInv(x,y, lon,lat);
305 // lon *= RAD2DEG; // PROJ6-CRS uses degrees
306 // lat *= RAD2DEG; // PROJ6-CRS uses degrees
307 }
308
310
312 virtual inline
313 void m2deg(double x, double y, double & lon, double & lat) const {
314 projGeo2Native.projectInv(x,y, lon,lat);
315 // lon *= RAD2DEG; // PROJ6-CRS uses degrees
316 // lat *= RAD2DEG; // PROJ6-CRS uses degrees
317 }
318
320
322 virtual inline
323 void m2deg(const drain::Point2D<double> & pMetric, drain::Point2D<double> & pDeg) const {
324 projGeo2Native.projectInv(pMetric.x, pMetric.y, pDeg.x, pDeg.y); // lon, lat);
325 //pDeg.x *= RAD2DEG; // PROJ6-CRS uses degrees
326 //pDeg.y *= RAD2DEG; // PROJ6-CRS uses degrees
327 }
328
329 /* UNTESTED
330 inline virtual
331 void LLdeg2m(const double & lon, const double & lat, double & x, double & y) const {
332 projGeo2Native.projectFwd(lon,lat, x,y);
333 }
334 */
335
336
338
345 inline virtual
346 void m2pix(double x, double y, int & i, int & j) const {
347 // i = static_cast<int>(0.5+ (x - bBoxNative.lowerLeft.x) / xScale); // xOffset
348 // j = frameHeight-1 - static_cast<int>(0.5+ (y - bBoxNative.lowerLeft.y) / yScale);
349 // j = frameHeight-1 - static_cast<int>(0.5+ (y - bBoxNative.lowerLeft.y) / yScale);
350 i = ::lround((x - bBoxNative.lowerLeft.x) / xScale); // xOffset
351 j = frame.height-1 - ::lround((y - bBoxNative.lowerLeft.y) / yScale);
352 }
353
354 inline // virtual
355 void m2pix(const drain::Point2D<double> & pMetric, drain::Point2D<int> & pImage) const {
356 // pImage.x = ::lround( (pMetric.x - bBoxNative.lowerLeft.x) / xScale); // xOffset
357 // pImage.y = frame.height-1 - ::lround((pMetric.y - bBoxNative.lowerLeft.y) / yScale);
358 m2pix(pMetric.x, pMetric.y, pImage.x, pImage.y);
359 }
360
361
363
373 virtual inline
374 void pix2m(int i, int j, double & x, double & y) const {
375 x = (static_cast<double>(i)+0.5)*xScale + bBoxNative.lowerLeft.x;
376 y = (static_cast<double>(frame.height-1 - j)+0.5)*yScale + bBoxNative.lowerLeft.y;
377 }
378
380
383 virtual inline
384 void pix2m(const drain::Point2D<int> & pImage, drain::Point2D<double> & pMetric) const {
385 pMetric.x = (static_cast<double>(pImage.x)+0.5)*xScale + bBoxNative.lowerLeft.x;
386 pMetric.y = (static_cast<double>(frame.height-1 - pImage.y)+0.5)*yScale + bBoxNative.lowerLeft.y;
387 }
388
390
398 virtual inline
399 void pix2LLm(int i, int j, double & x, double & y) const {
400 x = (static_cast<double>(i))*xScale + bBoxNative.lowerLeft.x;
401 y = (static_cast<double>(frame.height-1 - j))*yScale + bBoxNative.lowerLeft.y;
402 }
403
404
405 inline
406 void setProjection(const Projector & proj){
407 if (proj.getEPSG() > 0){
408 projGeo2Native.setProjectionDst(proj.getEPSG());
409 }
410 else {
411 projGeo2Native.setProjectionDst(proj.getProjDef()); // variant?
412 }
414 }
415
417 inline
418 void setProjection(const std::string & projDef){
421 }
422
424 inline
425 void setProjectionEPSG(int epsg){
427 //projGeo2Native.dst.setProjection(epsg);
428 //projGeo2Native.setDirectMapping(true); // was missing?
430 }
431
432
434 inline
435 const Proj6 & getProj() const {
436 return projGeo2Native;
437 };
438
439 inline
440 int getEPSG() const {
441 return projGeo2Native.getDst().getEPSG();
442 };
443
445 inline
446 const std::string & getProjStr() const {
447 return projGeo2Native.getProjStrDst();
448 };
449
451 // Consider: rename src/input projection coord system
452 inline
453 const std::string & getInputProjStr() const {
455 };
456
457
459 inline
460 //const drain::Rectangle<double> & getDataBBoxD() const { return dataBBoxD; };
462
464 inline
465 //const drain::Rectangle<double> & getDataOverlapD() const { return dataOverlapD; };
467
469
472 void updateDataExtentDeg(const drain::Rectangle<double> &inputBBoxDeg);
473
477 void updateDataExtentNat(const drain::Rectangle<double> &inputBBoxNat);
478
479
480 inline
481 bool isLongLat() const {
482 return projGeo2Native.isLongLat();
483 }
484
485
486 //std::ostream & toOStr(std::ostream & ostr) const ;
487 virtual
488 std::ostream & toStream(std::ostream & ostr) const;
489
490
491
492protected:
493
496
498 void updateProjection();
499
500
501 // drain::image::AreaGeometry frameGeometry; would be fine, but unsigned caused conversion/cast underflows
502 Frame2D<int> frame;
503 // int frameWidth;
504 // int frameHeight;
505
508
511
514
515 // experimental
518
519 // experimental
522
523 // ... needed in mapping...
524 double xScale = 0.0;
525 double yScale = 0.0;
526
527};
528
529inline
530std::ostream & operator<<(std::ostream & ostr, const GeoFrame & frame){
531 frame.GeoFrame::toStream(ostr);
532 ostr << '\n';
533 return ostr;
534}
535
536
537} // ::image
538} // ::drain
539
540#endif /*COMPOSITOR_R_H_*/
541
542// Drain
Something that has width and height.
Definition Frame.h:55
Definition Proj6.h:64
bool isLongLat() const
Check if destination projection is longitude-latitude degrees.
Definition Proj6.h:255
const std::string & getProjStrSrc() const
Returns the projection std::string applied by the last setProjection call.
Definition Proj6.h:161
void projectFwd(double &x, double &y) const
Forward projection (in-place)
Definition Proj6.h:186
void setProjectionDst(const T &...args)
Sets destination projection.
Definition Proj6.h:127
Definition Projector.h:54
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:507
const std::string & getProjStr() const
Returns the projection of the composite image as a proj4 std::string.
Definition GeoFrame.h:446
void setBoundingBox(const drain::Rectangle< double > &bbox)
Sets bounding box in degrees in the target coordinate system.
Definition GeoFrame.h:139
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 center of the pixel.
Definition GeoFrame.h:384
virtual void m2pix(double x, double y, int &i, int &j) const
Scales geographic map coordinates to image coordinates.
Definition GeoFrame.h:346
GeoFrame()
Default constructor.
Definition GeoFrame.cpp:49
const drain::Rectangle< double > & getDataOverlapBBoxNat() const
Return the common overlapping geographical area (intersection) implied by input data.
Definition GeoFrame.h:466
const drain::Rectangle< double > & getBoundingBoxRad() const
Returns the geographical scope in Radians.
Definition GeoFrame.h:211
void setProjectionEPSG(int epsg)
Sets the projection of the image as a EPSG code.
Definition GeoFrame.h:425
void updateScaling()
Geometric scaling.
Definition GeoFrame.cpp:311
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:284
virtual void m2deg(const drain::Point2D< double > &pMetric, drain::Point2D< double > &pDeg) const
Convert metric coordinates to degrees.
Definition GeoFrame.h:323
void updateProjection()
Updates bboxes, if needed.
Definition GeoFrame.cpp:269
const Proj6 & getProj() const
Returns the projection of the composite image as a proj4 std::string.
Definition GeoFrame.h:435
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:295
void updateDataExtentNat(const drain::Rectangle< double > &inputBBoxNat)
Definition GeoFrame.cpp:398
void setBoundingBoxR(double lonLL, double latLL, double lonUR, double latUR)
Sets bounding box in radians in the target coordinate system.
Definition GeoFrame.h:158
const drain::Rectangle< double > & getDataBBoxNat() const
Return the actual geographical boundingBox suggested by implied by input data.
Definition GeoFrame.h:461
void updateBoundingBoxR()
Proj 6 NEW: Given BBox in geo coords [deg], adjust geo coords [rad].
Definition GeoFrame.cpp:219
const drain::Rectangle< double > & getBoundingBoxNat() const
Returns the geographical scope in Meters.
Definition GeoFrame.h:207
bool bboxIsSet() const
Returns true, if the bounding box (geographical extent) has been set.
Definition GeoFrame.h:100
int getFrameHeight() const
Return the nominal height, not the height of the memory array which does not have to be allocated.
Definition GeoFrame.h:125
void updateDataExtentDeg(const drain::Rectangle< double > &inputBBoxDeg)
Extend to include this input.
Definition GeoFrame.cpp:384
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:301
drain::Rectangle< double > dataBBoxNat
For deriving extent (~union) of input data.
Definition GeoFrame.h:517
bool geometryIsSet() const
Return true, if array area is greater than zero.
Definition GeoFrame.h:90
bool projectionIsSet() const
Returns true, if the geographical extent has been set.
Definition GeoFrame.h:84
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:84
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 of the pixel.
Definition GeoFrame.h:399
drain::Rectangle< double > bBoxNative
Geographical scope in meters, or degrees in case of long/lat.
Definition GeoFrame.h:513
virtual void pix2m(int i, int j, double &x, double &y) const
Scales image coordinates (i,j) to map coordinates (x,y) in the center of the pixel.
Definition GeoFrame.h:374
virtual void deg2m(double lon, double lat, double &x, double &y) const
Convert degrees to native (often metric) coordinates.
Definition GeoFrame.h:261
void setBoundingBoxNat(const drain::UniTuple< double, 4 > &bboxM)
Sets bounding box in meters in the target coordinate system.
Definition GeoFrame.h:178
void setBoundingBoxR(const drain::Rectangle< double > &bboxR)
Sets bounding box in radians in the target coordinate system.
Definition GeoFrame.h:164
virtual void m2deg(double x, double y, double &lon, double &lat) const
Convert metric coordinates to degrees.
Definition GeoFrame.h:313
bool isDefined() const
Returns true, if the projection, array area and geographical extent bounding box has been set.
Definition GeoFrame.h:110
virtual void deg2pix(double lon, double lat, int &i, int &j) const
Projects geographic coordinates to image coordinates.
Definition GeoFrame.h:244
const std::string & getInputProjStr() const
Returns the source projection (should be radian array, lon & lat).
Definition GeoFrame.h:453
void setBoundingBoxNat(double xLL, double yLL, double xUR, double yUR)
Sets bounding box in meters in the target coordinate system.
Definition GeoFrame.cpp:143
drain::Rectangle< double > dataOverlapBBoxNat
For deriving common extent (~intersection) of input data.
Definition GeoFrame.h:521
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:275
const drain::Rectangle< double > & getBoundingBoxDeg() const
Returns the geographical scope in Degrees.
Definition GeoFrame.h:203
void setProjection(const std::string &projDef)
Sets the projection of the image as a Proj string.
Definition GeoFrame.h:418
double getYScale() const
Return vertical resolution of a pixel in meters (if metric) or degrees (if unprojected,...
Definition GeoFrame.h:223
drain::Proj6 projGeo2Native
Radial to metric.
Definition GeoFrame.h:495
void deg2pix(const drain::Point2D< double > &loc, drain::Point2D< int > &pix) const
Project geographic coordinates (degrees) to image coordinates (pixels).
Definition GeoFrame.h:253
void setBoundingBoxD(const drain::Rectangle< double > &bboxD)
Sets bounding box in degrees in the target coordinate system.
Definition GeoFrame.h:151
void cropWithM(drain::Rectangle< double > &bboxM)
Crops the initial bounding box with a given bounding box.
Definition GeoFrame.h:234
void updateBoundingBoxNat()
Given BBox in geo coords [rad], adjust geo coords [deg].
Definition GeoFrame.cpp:227
double getXScale() const
Return horizontal resolution of a pixel in meters (if metric) or degrees (if unprojected,...
Definition GeoFrame.h:217
void deg2m(const drain::Point2D< double > &pDeg, drain::Point2D< double > &pMet) const
Convert degrees to native (often metric) coordinates.
Definition GeoFrame.h:269
void setBoundingBoxD(double lonLL, double latLL, double lonUR, double latUR)
Sets bounding box in degrees in the target coordinate system.
Definition GeoFrame.cpp:123
drain::Rectangle< double > bBoxD
Geographical scope in Degrees.
Definition GeoFrame.h:510
int getFrameWidth() const
Return the nominal width, not the width of the memory array which does not have to be allocated.
Definition GeoFrame.h:121
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