Loading...
Searching...
No Matches
graphics-radar.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
32
33#ifndef RACK_GRAPHICS_RADAR
34#define RACK_GRAPHICS_RADAR
35
36
37//#include "resources-image.h"
38//#include "resources.h"
39
40#include <drain/image/GeoFrame.h>
41#include <drain/image/TreeElemUtilsSVG.h>
42
43#include "radar/Composite.h"
44#include "radar/RadarProj.h"
45
46
47namespace rack {
48
49class Graphic {
50
51public:
52
53 enum GRAPHIC {
54 VECTOR_OVERLAY, // this is more for group ID/name
55 HIGHLIGHT, // CSS: activated on tool tip
56 GRID, // overlapping with element class?
57 DOT,
58 RAY,
59 SECTOR,
60 ANNULUS,
61 CIRCLE,
62 SPOT, // External
63 LABEL, // External
64 };
65
66 const drain::ClassXML cls;
67
68
69 inline
70 Graphic(GRAPHIC g = RAY) : cls(drain::Enum<GRAPHIC>::dict.getKey(g)) {
71 }
72
73 inline
74 Graphic(const Graphic & g) : cls(g.cls) {
75 }
76
77 inline
78 Graphic(const drain::ClassXML & cls) : cls(cls) {
79 }
80
81 static
82 drain::image::TreeSVG & getGraphicStyle(drain::image::TreeSVG & svgDoc);
83
84
85};
86
87
88}
89
90DRAIN_ENUM_DICT(rack::Graphic::GRAPHIC);
91DRAIN_ENUM_OSTREAM(rack::Graphic::GRAPHIC);
92
93namespace rack {
94
95class PolarRadarConf : public RadarProj {
96
97public:
98
99 inline
100 void deriveMaxRange(const Hi5Tree & srcPolar){
101 maxRange = DataTools::getMaxRange(srcPolar);
102 }
103
104 inline
105 double getRange(double r=1.0){
106 // double getRange(double r, double maxRange){
107 if (r < -1.0){
108 return r;
109 }
110 else if (r > +1.0){
111 return r;
112 }
113 else {
114 return r*maxRange;
115 }
116 };
117
118protected:
119
120 // Maximum range of the latest radar input.
121 double maxRange = 0.0; // metres
122
123};
124
126
133class RadarSVG {
134public:
135
136
137 inline
138 RadarSVG(int radialBezierResolution = 0){
139 if (radialBezierResolution > 0){
140 setRadialResolution(radialBezierResolution);
141 }
142 else {
143 setRadialResolution(drain::image::FileSVG::radialBezierResolution);
144 }
145 };
146
147 inline
148 RadarSVG(const RadarSVG & radarSvg){
149 setRadialResolution(radarSvg.radialBezierResolution);
150 };
151
152
153 /*
154 enum StyleClasses {
155 VECTOR_OVERLAY, // this is more for group ID/name
156 HIGHLIGHT, // CSS: activated on tool tip
157 // ^ rename VECTORS VECTOR_GRAPHICS
158 GRID, // CSS
159 };
160 */
161
163
168 // static
169 // drain::image::TreeSVG & getOverlayStyle(drain::image::TreeSVG & svgDoc);
170
172
175 static
176 drain::image::TreeSVG & getOverlayGroup(drain::image::TreeSVG & svgDoc);
177
178
179 // Projection of the latest radar input.
180 //RadarProj radarProj;
181 PolarRadarConf radarProj;
182
183 /*
184 inline
185 void deriveMaxRange(const Hi5Tree & srcPolar){
186 maxRange = DataTools::getMaxRange(srcPolar);
187 }
188 */
189
191 /*
192 static inline
193 double getRange(double r=1.0){
194 // double getRange(double r, double maxRange){
195 if (r < -1.0){
196 return r;
197 }
198 else if (r > +1.0){
199 return r;
200 }
201 else {
202 return r*maxRange;
203 }
204 };
205 */
206
207
210
212
215 void updateRadarConf(const drain::VariableMap & where);
216
218
222 // template <class T>
223 // void updateCartesianConf(const drain::SmartMap<T> & where);
224 void updateCartesianConf(const drain::VariableMap & where);
225
226 void updateCartesianConf(const Composite & comp);
227
229 inline
231 if (n>1){
232 getCubicBezierConf(conf, n);
233 radialBezierResolution = n;
234 }
235 else {
236 drain::Logger mout(__FILE__, __FUNCTION__);
237 mout.error("To small radialBezierResolution: ", n);
238 }
239 }
240
244 /*
245 void getCubicCoeff(int n, double & radialCoeff, double & angularOffset) const {
246 double theta = 2.0*M_PI / static_cast<double>(n);
247 double k = 4.0/3.0 * ::tan(theta/4.0);
248 radialCoeff = sqrt(1.0 + k*k);
249 angularOffset = ::atan(k);
250 }
251 */
252
254 // int sectorCount;
256 double delta = 0.0;
257 double radialCoeff = 1.0;
258 double angularOffset = 0.0;
259 };
260
261 CubicBezierConf conf;
262
263 /***
264 * \param n -sectors
265 */
266 inline
267 void getCubicBezierConf(CubicBezierConf & conf, int n) const {
268 getCubicBezierConf(conf, 0.0, 2.0*M_PI / static_cast<double>(n));
269 }
270
271 void getCubicBezierConf(CubicBezierConf & conf, double angleStartR, double angleEndR) const;
272
273 // typedef DRAIN_SVG_ELEM_CLS(PATH) svgPath;
274 inline
275 void convert(double radius, double azimuth, drain::Point2D<int> & imgPoint) const {
276 drain::Point2D<double> geoPoint;
277 polarToMeters(radius, azimuth, geoPoint);
278 // radarProj.projectFwd(radius*::sin(azimuth), radius*::cos(azimuth), geoPoint.x, geoPoint.y);
279 geoFrame.m2pix(geoPoint, imgPoint);
280 };
281
282 inline
283 void polarToMeters(double radius, double azimuth, drain::Point2D<double> & geoPoint) const {
284 radarProj.projectFwd(radius*::sin(azimuth), radius*::cos(azimuth), geoPoint.x, geoPoint.y);
285 //geoFrame.m2pix(geoPoint, imgPoint);
286 };
287
288 inline
289 void radarGeoToCompositeImage(drain::Point2D<double> & radarPoint, drain::Point2D<int> & imagePoint) const {
290 drain::Point2D<double> compositePoint;
291 radarProj.projectFwd(radarPoint, compositePoint);
292 geoFrame.m2pix(compositePoint, imagePoint);
293 }
294
295
297
300 inline
301 void moveTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthR) const {
302 convert(radiusM, azimuthR, imgPoint);
303 elem.absolute<drain::svgPATH::MOVE>(imgPoint.x, imgPoint.y);
304 }
305
306 // Simple version not sharing end point.
310 inline
311 void moveTo(drain::svgPATH & elem, double radius, double azimuth) const {
312 drain::Point2D<int> imgPoint;
313 moveTo(elem, imgPoint, radius, azimuth);
314 }
315
316 inline
317 void lineTo(drain::svgPATH & elem, double radius, double azimuth) const {
318 drain::Point2D<int> imgPoint;
319 lineTo(elem, imgPoint, radius, azimuth);
320 }
321
322 inline
323 void lineTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthR) const {
324 convert(radiusM, azimuthR, imgPoint);
325 elem.absolute<drain::svgPATH::LINE>(imgPoint.x, imgPoint.y);
326 }
327
328
330
333 void cubicBezierTo(drain::svgPATH & elem, double radiusM, double azimuthStartR, double azimuthEndR) const ;
334
338 void cubicBezierTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthStartR, double azimuthEndR) const;
339
340 inline
341 void close(drain::svgPATH & elem) const {
342 // No difference for absolute/relative
343 elem.absolute<drain::svgPATH::CLOSE>();
344 }
345
347
351 void drawSector(drain::svgPATH & elem, const drain::Range<double> & radius, const drain::Range<double> & azimuthR = {0.0, 0.0}) const;
352
354
358 inline
359 void drawCircle(drain::svgPATH & elem, const drain::Range<double> & radius) const {
360 drawSector(elem, radius, {0.0, 0.0});
361 }
362
363protected:
364
365 int radialBezierResolution;
366
367 // Maximum range of the latest radar input.
368 // double maxRange = 0.0; // metres
369
370};
371
372/*
373template <class T>
374void RadarSVG::updateCartesianConf(const drain::SmartMap<T> & where) {
375
376 drain::Logger mout(__FILE__, __FUNCTION__);
377 // Todo: also support fully cartesian input (without single-site metadata)
378 // radarProj.setSiteLocationDeg(where["lon"], where["lat"]);
379
380 const int epsg = where.get("epsg", 0); // non-standard
381 if (epsg){
382 mout.attention("EPSG found: ", epsg);
383 geoFrame.setProjectionEPSG(epsg);
384 // radarProj.setProjectionDst(epsg);
385 }
386 else {
387 const std::string projdef = where.get("projdef", ""); // otherwise gets "null"
388 geoFrame.setProjection(projdef);
389 // radarProj.setProjectionDst(projdef);
390 }
391 geoFrame.setBoundingBoxD(where["LL_lon"], where["LL_lat"], where["UR_lon"], where["UR_lat"]);
392 geoFrame.setGeometry(where["xsize"], where["ysize"]);
393
394}
395*/
396
397} // rack::
398
399/*
400
401
402DRAIN_ENUM_DICT(rack::RadarSVG::StyleClasses);
403
404DRAIN_ENUM_OSTREAM(rack::RadarSVG::StyleClasses);
405
406*/
407
408namespace drain {
409
410
411template <> // for T (Tree class)
412template <> // for K (path elem arg)
413inline
414const image::TreeSVG & image::TreeSVG::operator[](const rack::Graphic::GRAPHIC & cls) const {
415 return (*this)[Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, false)];
416}
417
418template <> // for T (Tree class)
419template <> // for K (path elem arg)
420inline
421image::TreeSVG & image::TreeSVG::operator[](const rack::Graphic::GRAPHIC & cls) {
422 return (*this)[Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, false)];
423}
424
425template <> // for T (Tree class)
426template <> // for K (path elem arg)
427inline
428bool image::TreeSVG::hasChild(const rack::Graphic::GRAPHIC & cls) const {
429 return hasChild(Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, true)); // no error
430}
431
432}
433
434#endif
A wrapper marking string an CSS effect.
Definition ClassXML.h:57
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & error(const TT &... args)
Echoes.
Definition Log.h:417
void projectFwd(double &x, double &y) const
Forward projection (in-place)
Definition Proj6.h:186
Definition Range.h:52
A map of Variables.
Definition VariableMap.h:61
Array with georeferencing support.
Definition GeoFrame.h:58
virtual void m2pix(double x, double y, int &i, int &j) const
Scales geographic map coordinates to image coordinates.
Definition GeoFrame.h:345
Cartesian composite (mosaic) of data from several radars.
Definition Composite.h:102
static int getMaxRange(const Hi5Tree &src, bool projected=true)
Definition DataTools.cpp:326
Definition graphics-radar.h:49
Definition graphics-radar.h:95
Definition RadarProj.h:99
Vector graphics for both composites and single radar data (polar coordinates).
Definition graphics-radar.h:133
void setRadialResolution(int n)
Number of "sectors" in a sphere.
Definition graphics-radar.h:230
drain::image::GeoFrame geoFrame
If r is inside +/-100% = [-1.0,1.0], return that portion of maximum range, else the argument as such.
Definition graphics-radar.h:209
static drain::image::TreeSVG & getOverlayGroup(drain::image::TreeSVG &svgDoc)
Sets some CSS properties applicable in radar graphics (grids, sectors).
Definition graphics-radar.cpp:138
void updateCartesianConf(const drain::VariableMap &where)
Read meta data related to Cartesian data, that is, geographic configuration of a radar composite.
Definition graphics-radar.cpp:180
void moveTo(drain::svgPATH &elem, drain::Point2D< int > &imgPoint, double radiusM, double azimuthR) const
Move to image point at (radius, azimuth)
Definition graphics-radar.h:301
void drawCircle(drain::svgPATH &elem, const drain::Range< double > &radius) const
Convenience: draw circle (disk or annulus)
Definition graphics-radar.h:359
void cubicBezierTo(drain::svgPATH &elem, double radiusM, double azimuthStartR, double azimuthEndR) const
Single command to draw arc.
Definition graphics-radar.cpp:245
void drawSector(drain::svgPATH &elem, const drain::Range< double > &radius, const drain::Range< double > &azimuthR={0.0, 0.0}) const
Convenience: draw sector, starting from radius.min, ending at radius.max, in azimuth range azimuthR....
Definition graphics-radar.cpp:312
void updateRadarConf(const drain::VariableMap &where)
Read meta data related to polar coordinates, that is, geographic configuration of a single radar.
Definition graphics-radar.cpp:160
Definition DataSelector.cpp:1277
Definition DataSelector.cpp:44
A container for a static dictionary of enumeration values.
Definition Enum.h:51
Definition Point.h:48
Definition graphics-radar.h:253
double delta
Sector angle.
Definition graphics-radar.h:256