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#include <drain/util/ClassXML.h>
43
44#include "radar/Composite.h"
45#include "radar/RadarProj.h"
46
47
48namespace rack {
49
50class Graphic {
51
52public:
53
54 enum GRAPHIC {
55 // VECTOR_OVERLAY, // Standard subgroup name inside IMAGE_PANEL group.
56 HIGHLIGHT, // CSS: activated on tool tip
57 GRID, // overlapping with element class?
58 DOT, // Marker for radar location
59 RAY, // Line illustrating radar beam
60 SECTOR, // Radar sector
61 ANNULUS, // Radar range, optionally not starting from radar.
62 CIRCLE, // Circe illustrating maximal radar range. Not filled.
63 RECTANGLE, // Box, freely located or located at radar site
64 SPOT, // External
65 LABEL, // External
66 // OVERLAY, // Standard subgroup name inside IMAGE_PANEL group.
67 };
68
69 const drain::ClassXML cls;
70
71
72 inline
73 Graphic(GRAPHIC g = RAY) : cls(drain::Enum<GRAPHIC>::dict.getKey(g)) {
74 }
75
76 inline
77 Graphic(const Graphic & g) : cls(g.cls) {
78 }
79
80 inline
81 Graphic(const drain::ClassXML & cls) : cls(cls) {
82 }
83
84 static
85 drain::image::TreeSVG & getGraphicStyle(drain::image::TreeSVG & svgDoc);
86
87
88};
89
90
91}
92
93
94
95DRAIN_ENUM_DICT(rack::Graphic::GRAPHIC);
96DRAIN_ENUM_OSTREAM(rack::Graphic::GRAPHIC);
97
98namespace drain {
99DRAIN_ENUM_CLASSXML(rack::Graphic::GRAPHIC);
100}
101
102namespace rack {
103
104class PolarRadarConf : public RadarProj {
105
106public:
107
108 inline
109 void deriveMaxRange(const Hi5Tree & srcPolar){
111 }
112
113 inline
114 double getRange(double r=1.0){
115 // double getRange(double r, double maxRange){
116 if (r < -1.0){
117 return r;
118 }
119 else if (r > +1.0){
120 return r;
121 }
122 else {
123 return r*maxRange;
124 }
125 };
126
127protected:
128
129 // Maximum range of the latest radar input.
130 double maxRange = 0.0; // metres
131
132};
133
135
142class RadarSVG {
143public:
144
145
146 inline
147 RadarSVG(int radialBezierResolution = 0){
148 if (radialBezierResolution > 0){
149 setRadialResolution(radialBezierResolution);
150 }
151 else {
152 setRadialResolution(drain::image::FileSVG::radialBezierResolution);
153 }
154 };
155
156 inline
157 RadarSVG(const RadarSVG & radarSvg){
158 setRadialResolution(radarSvg.radialBezierResolution);
159 };
160
161
162 /*
163 enum StyleClasses {
164 VECTOR_OVERLAY, // this is more for group ID/name
165 HIGHLIGHT, // CSS: activated on tool tip
166 // ^ rename VECTORS VECTOR_GRAPHICS
167 GRID, // CSS
168 };
169 */
170
172
177 // static
178 // drain::image::TreeSVG & getOverlayStyle(drain::image::TreeSVG & svgDoc);
179
180
181 // Projection of the latest radar input.
183
184
186 /*
187 static inline
188 double getRange(double r=1.0){
189 // double getRange(double r, double maxRange){
190 if (r < -1.0){
191 return r;
192 }
193 else if (r > +1.0){
194 return r;
195 }
196 else {
197 return r*maxRange;
198 }
199 };
200 */
201
202 std::string source;
203
206
208
212
214
218 // template <class T>
219 // void updateCartesianConf(const drain::SmartMap<T> & where);
221
222 void updateCartesianConf(const Composite & comp);
223
225 inline
227 if (n>1){
228 getCubicBezierConf(conf, n);
229 radialBezierResolution = n;
230 }
231 else {
233 mout.error("To small radialBezierResolution: ", n);
234 }
235 }
236
240 /*
241 void getCubicCoeff(int n, double & radialCoeff, double & angularOffset) const {
242 double theta = 2.0*M_PI / static_cast<double>(n);
243 double k = 4.0/3.0 * ::tan(theta/4.0);
244 radialCoeff = sqrt(1.0 + k*k);
245 angularOffset = ::atan(k);
246 }
247 */
248
250 // int sectorCount;
252 double delta = 0.0;
253 double radialCoeff = 1.0;
254 double angularOffset = 0.0;
255 };
256
257 CubicBezierConf conf;
258
259 /***
260 * \param n -sectors
261 */
262 inline
263 void getCubicBezierConf(CubicBezierConf & conf, int n) const {
264 getCubicBezierConf(conf, 0.0, 2.0*M_PI / static_cast<double>(n));
265 }
266
267 void getCubicBezierConf(CubicBezierConf & conf, double angleStartR, double angleEndR) const;
268
269 // typedef DRAIN_SVG_ELEM_CLS(PATH) svgPath;
270 inline
271 void convert(double radius, double azimuth, drain::Point2D<int> & imgPoint) const {
273 polarToMeters(radius, azimuth, geoPoint);
274 // radarProj.projectFwd(radius*::sin(azimuth), radius*::cos(azimuth), geoPoint.x, geoPoint.y);
276 };
277
278 inline
279 void polarToMeters(double radius, double azimuth, drain::Point2D<double> & geoPoint) const {
280 radarProj.projectFwd(radius*::sin(azimuth), radius*::cos(azimuth), geoPoint.x, geoPoint.y);
281 //geoFrame.m2pix(geoPoint, imgPoint);
282 };
283
284 inline
285 void radarGeoToCompositeImage(drain::Point2D<double> & radarPoint, drain::Point2D<int> & imagePoint) const {
286 drain::Point2D<double> compositePoint;
287 radarProj.projectFwd(radarPoint, compositePoint);
288 geoFrame.m2pix(compositePoint, imagePoint);
289 }
290
291
293
296 inline
297 void moveTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthR) const {
298 convert(radiusM, azimuthR, imgPoint);
299 elem.absolute<drain::svgPATH::MOVE>(imgPoint.x, imgPoint.y);
300 }
301
302 // Simple version not sharing end point.
306 inline
307 void moveTo(drain::svgPATH & elem, double radius, double azimuth) const {
309 moveTo(elem, imgPoint, radius, azimuth);
310 }
311
312 inline
313 void lineTo(drain::svgPATH & elem, double radius, double azimuth) const {
314 drain::Point2D<int> imgPoint;
315 lineTo(elem, imgPoint, radius, azimuth);
316 }
317
318 inline
319 void lineTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthR) const {
320 convert(radiusM, azimuthR, imgPoint);
321 elem.absolute<drain::svgPATH::LINE>(imgPoint.x, imgPoint.y);
322 }
323
324
326
332 void cubicBezierTo(drain::svgPATH & elem, double radiusM, double azimuthStartR, double azimuthEndR) const ;
333
341 void cubicBezierTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthStartR, double azimuthEndR) const;
342
343 inline
344 void close(drain::svgPATH & elem) const {
345 // No difference for absolute/relative
346 elem.absolute<drain::svgPATH::CLOSE>();
347 }
348
350
354 void drawSector(drain::svgPATH & elem, const drain::Range<double> & radius, const drain::Range<double> & azimuthR = {0.0, 0.0}) const;
355
357
361 inline
362 void drawCircle(drain::svgPATH & elem, const drain::Range<double> & radius) const {
363 drawSector(elem, radius, {0.0, 0.0});
364 }
365
366protected:
367
368 int radialBezierResolution;
369
370 // Maximum range of the latest radar input.
371 // double maxRange = 0.0; // metres
372
373};
374
375/*
376template <class T>
377void RadarSVG::updateCartesianConf(const drain::SmartMap<T> & where) {
378
379 drain::Logger mout(__FILE__, __FUNCTION__);
380 // Todo: also support fully cartesian input (without single-site metadata)
381 // radarProj.setSiteLocationDeg(where["lon"], where["lat"]);
382
383 const int epsg = where.get("epsg", 0); // non-standard
384 if (epsg){
385 mout.attention("EPSG found: ", epsg);
386 geoFrame.setProjectionEPSG(epsg);
387 // radarProj.setProjectionDst(epsg);
388 }
389 else {
390 const std::string projdef = where.get("projdef", ""); // otherwise gets "null"
391 geoFrame.setProjection(projdef);
392 // radarProj.setProjectionDst(projdef);
393 }
394 geoFrame.setBoundingBoxD(where["LL_lon"], where["LL_lat"], where["UR_lon"], where["UR_lat"]);
395 geoFrame.setGeometry(where["xsize"], where["ysize"]);
396
397}
398*/
399
400} // rack::
401
402/*
403
404
405DRAIN_ENUM_DICT(rack::RadarSVG::StyleClasses);
406
407DRAIN_ENUM_OSTREAM(rack::RadarSVG::StyleClasses);
408
409*/
410
411namespace drain {
412
413
414template <> // for T (Tree class)
415template <> // for K (path elem arg)
416inline
417const image::TreeSVG & image::TreeSVG::operator[](const rack::Graphic::GRAPHIC & cls) const {
418 return (*this)[Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, false)];
419}
420
421template <> // for T (Tree class)
422template <> // for K (path elem arg)
423inline
424image::TreeSVG & image::TreeSVG::operator[](const rack::Graphic::GRAPHIC & cls) {
425 return (*this)[Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, false)];
426}
427
428template <> // for T (Tree class)
429template <> // for K (path elem arg)
430inline
431bool image::TreeSVG::hasChild(const rack::Graphic::GRAPHIC & cls) const {
432 return hasChild(Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, true)); // no error
433}
434
435}
436
437#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:326
void projectFwd(double &x, double &y) const
Forward projection (in-place)
Definition Proj6.h:190
Definition Range.h:52
A map of Variables.
Definition VariableMap.h:61
Array with georeferencing support.
Definition GeoFrame.h:56
virtual void m2pix(double x, double y, int &i, int &j) const
Scales geographic map coordinates to image coordinates.
Definition GeoFrame.h:349
Cartesian composite (mosaic) of data from several radars.
Definition Composite.h:102
A map of radar data, indexed by quantity code (DBZH, VRAD, etc).
Definition Data.h:1293
static int getMaxRange(const Hi5Tree &src, bool projected=true)
Definition DataTools.cpp:439
Definition graphics-radar.h:50
Definition graphics-radar.h:104
Definition RadarProj.h:99
Vector graphics for both composites and single radar data (polar coordinates).
Definition graphics-radar.h:142
void setRadialResolution(int n)
Number of "sectors" in a sphere.
Definition graphics-radar.h:226
drain::image::GeoFrame geoFrame
Geographic extent and projection (Cartesian)
Definition graphics-radar.h:205
std::string source
If r is inside +/-100% = [-1.0,1.0], return that portion of maximum range, else the argument as such.
Definition graphics-radar.h:202
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:210
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:297
void drawCircle(drain::svgPATH &elem, const drain::Range< double > &radius) const
Convenience: draw circle (disk or annulus)
Definition graphics-radar.h:362
void cubicBezierTo(drain::svgPATH &elem, double radiusM, double azimuthStartR, double azimuthEndR) const
Single command to draw arc.
Definition graphics-radar.cpp:283
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:350
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:189
PolarRadarConf radarProj
Sets some CSS properties applicable in radar graphics (grids, sectors).
Definition graphics-radar.h:182
Definition Data.h:1473
Definition AltitudeOp.cpp:42
A container for a static dictionary of enumeration values.
Definition Enum.h:51
Definition Point.h:48
Definition graphics-radar.h:249
double delta
Sector angle.
Definition graphics-radar.h:252