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 RECTANGLE, // Internal or External
63 SPOT, // External
64 LABEL, // External
65 };
66
67 const drain::ClassXML cls;
68
69
70 inline
71 Graphic(GRAPHIC g = RAY) : cls(drain::Enum<GRAPHIC>::dict.getKey(g)) {
72 }
73
74 inline
75 Graphic(const Graphic & g) : cls(g.cls) {
76 }
77
78 inline
79 Graphic(const drain::ClassXML & cls) : cls(cls) {
80 }
81
82 static
83 drain::image::TreeSVG & getGraphicStyle(drain::image::TreeSVG & svgDoc);
84
85
86};
87
88
89}
90
91DRAIN_ENUM_DICT(rack::Graphic::GRAPHIC);
92DRAIN_ENUM_OSTREAM(rack::Graphic::GRAPHIC);
93
94namespace rack {
95
96class PolarRadarConf : public RadarProj {
97
98public:
99
100 inline
101 void deriveMaxRange(const Hi5Tree & srcPolar){
102 maxRange = DataTools::getMaxRange(srcPolar);
103 }
104
105 inline
106 double getRange(double r=1.0){
107 // double getRange(double r, double maxRange){
108 if (r < -1.0){
109 return r;
110 }
111 else if (r > +1.0){
112 return r;
113 }
114 else {
115 return r*maxRange;
116 }
117 };
118
119protected:
120
121 // Maximum range of the latest radar input.
122 double maxRange = 0.0; // metres
123
124};
125
127
134class RadarSVG {
135public:
136
137
138 inline
139 RadarSVG(int radialBezierResolution = 0){
140 if (radialBezierResolution > 0){
141 setRadialResolution(radialBezierResolution);
142 }
143 else {
144 setRadialResolution(drain::image::FileSVG::radialBezierResolution);
145 }
146 };
147
148 inline
149 RadarSVG(const RadarSVG & radarSvg){
150 setRadialResolution(radarSvg.radialBezierResolution);
151 };
152
153
154 /*
155 enum StyleClasses {
156 VECTOR_OVERLAY, // this is more for group ID/name
157 HIGHLIGHT, // CSS: activated on tool tip
158 // ^ rename VECTORS VECTOR_GRAPHICS
159 GRID, // CSS
160 };
161 */
162
164
169 // static
170 // drain::image::TreeSVG & getOverlayStyle(drain::image::TreeSVG & svgDoc);
171
173
176 static
177 drain::image::TreeSVG & getOverlayGroup(drain::image::TreeSVG & svgDoc);
178
179
180 // Projection of the latest radar input.
181 //RadarProj radarProj;
182 PolarRadarConf radarProj;
183
184 /*
185 inline
186 void deriveMaxRange(const Hi5Tree & srcPolar){
187 maxRange = DataTools::getMaxRange(srcPolar);
188 }
189 */
190
192 /*
193 static inline
194 double getRange(double r=1.0){
195 // double getRange(double r, double maxRange){
196 if (r < -1.0){
197 return r;
198 }
199 else if (r > +1.0){
200 return r;
201 }
202 else {
203 return r*maxRange;
204 }
205 };
206 */
207
208
211
213
216 void updateRadarConf(const drain::VariableMap & where);
217
219
223 // template <class T>
224 // void updateCartesianConf(const drain::SmartMap<T> & where);
225 void updateCartesianConf(const drain::VariableMap & where);
226
227 void updateCartesianConf(const Composite & comp);
228
230 inline
232 if (n>1){
233 getCubicBezierConf(conf, n);
234 radialBezierResolution = n;
235 }
236 else {
237 drain::Logger mout(__FILE__, __FUNCTION__);
238 mout.error("To small radialBezierResolution: ", n);
239 }
240 }
241
245 /*
246 void getCubicCoeff(int n, double & radialCoeff, double & angularOffset) const {
247 double theta = 2.0*M_PI / static_cast<double>(n);
248 double k = 4.0/3.0 * ::tan(theta/4.0);
249 radialCoeff = sqrt(1.0 + k*k);
250 angularOffset = ::atan(k);
251 }
252 */
253
255 // int sectorCount;
257 double delta = 0.0;
258 double radialCoeff = 1.0;
259 double angularOffset = 0.0;
260 };
261
262 CubicBezierConf conf;
263
264 /***
265 * \param n -sectors
266 */
267 inline
268 void getCubicBezierConf(CubicBezierConf & conf, int n) const {
269 getCubicBezierConf(conf, 0.0, 2.0*M_PI / static_cast<double>(n));
270 }
271
272 void getCubicBezierConf(CubicBezierConf & conf, double angleStartR, double angleEndR) const;
273
274 // typedef DRAIN_SVG_ELEM_CLS(PATH) svgPath;
275 inline
276 void convert(double radius, double azimuth, drain::Point2D<int> & imgPoint) const {
277 drain::Point2D<double> geoPoint;
278 polarToMeters(radius, azimuth, geoPoint);
279 // radarProj.projectFwd(radius*::sin(azimuth), radius*::cos(azimuth), geoPoint.x, geoPoint.y);
280 geoFrame.m2pix(geoPoint, imgPoint);
281 };
282
283 inline
284 void polarToMeters(double radius, double azimuth, drain::Point2D<double> & geoPoint) const {
285 radarProj.projectFwd(radius*::sin(azimuth), radius*::cos(azimuth), geoPoint.x, geoPoint.y);
286 //geoFrame.m2pix(geoPoint, imgPoint);
287 };
288
289 inline
290 void radarGeoToCompositeImage(drain::Point2D<double> & radarPoint, drain::Point2D<int> & imagePoint) const {
291 drain::Point2D<double> compositePoint;
292 radarProj.projectFwd(radarPoint, compositePoint);
293 geoFrame.m2pix(compositePoint, imagePoint);
294 }
295
296
298
301 inline
302 void moveTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthR) const {
303 convert(radiusM, azimuthR, imgPoint);
304 elem.absolute<drain::svgPATH::MOVE>(imgPoint.x, imgPoint.y);
305 }
306
307 // Simple version not sharing end point.
311 inline
312 void moveTo(drain::svgPATH & elem, double radius, double azimuth) const {
313 drain::Point2D<int> imgPoint;
314 moveTo(elem, imgPoint, radius, azimuth);
315 }
316
317 inline
318 void lineTo(drain::svgPATH & elem, double radius, double azimuth) const {
319 drain::Point2D<int> imgPoint;
320 lineTo(elem, imgPoint, radius, azimuth);
321 }
322
323 inline
324 void lineTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthR) const {
325 convert(radiusM, azimuthR, imgPoint);
326 elem.absolute<drain::svgPATH::LINE>(imgPoint.x, imgPoint.y);
327 }
328
329
331
334 void cubicBezierTo(drain::svgPATH & elem, double radiusM, double azimuthStartR, double azimuthEndR) const ;
335
339 void cubicBezierTo(drain::svgPATH & elem, drain::Point2D<int> & imgPoint, double radiusM, double azimuthStartR, double azimuthEndR) const;
340
341 inline
342 void close(drain::svgPATH & elem) const {
343 // No difference for absolute/relative
344 elem.absolute<drain::svgPATH::CLOSE>();
345 }
346
348
352 void drawSector(drain::svgPATH & elem, const drain::Range<double> & radius, const drain::Range<double> & azimuthR = {0.0, 0.0}) const;
353
355
359 inline
360 void drawCircle(drain::svgPATH & elem, const drain::Range<double> & radius) const {
361 drawSector(elem, radius, {0.0, 0.0});
362 }
363
364protected:
365
366 int radialBezierResolution;
367
368 // Maximum range of the latest radar input.
369 // double maxRange = 0.0; // metres
370
371};
372
373/*
374template <class T>
375void RadarSVG::updateCartesianConf(const drain::SmartMap<T> & where) {
376
377 drain::Logger mout(__FILE__, __FUNCTION__);
378 // Todo: also support fully cartesian input (without single-site metadata)
379 // radarProj.setSiteLocationDeg(where["lon"], where["lat"]);
380
381 const int epsg = where.get("epsg", 0); // non-standard
382 if (epsg){
383 mout.attention("EPSG found: ", epsg);
384 geoFrame.setProjectionEPSG(epsg);
385 // radarProj.setProjectionDst(epsg);
386 }
387 else {
388 const std::string projdef = where.get("projdef", ""); // otherwise gets "null"
389 geoFrame.setProjection(projdef);
390 // radarProj.setProjectionDst(projdef);
391 }
392 geoFrame.setBoundingBoxD(where["LL_lon"], where["LL_lat"], where["UR_lon"], where["UR_lat"]);
393 geoFrame.setGeometry(where["xsize"], where["ysize"]);
394
395}
396*/
397
398} // rack::
399
400/*
401
402
403DRAIN_ENUM_DICT(rack::RadarSVG::StyleClasses);
404
405DRAIN_ENUM_OSTREAM(rack::RadarSVG::StyleClasses);
406
407*/
408
409namespace drain {
410
411
412template <> // for T (Tree class)
413template <> // for K (path elem arg)
414inline
415const image::TreeSVG & image::TreeSVG::operator[](const rack::Graphic::GRAPHIC & cls) const {
416 return (*this)[Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, false)];
417}
418
419template <> // for T (Tree class)
420template <> // for K (path elem arg)
421inline
422image::TreeSVG & image::TreeSVG::operator[](const rack::Graphic::GRAPHIC & cls) {
423 return (*this)[Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, false)];
424}
425
426template <> // for T (Tree class)
427template <> // for K (path elem arg)
428inline
429bool image::TreeSVG::hasChild(const rack::Graphic::GRAPHIC & cls) const {
430 return hasChild(Enum<rack::Graphic::GRAPHIC>::dict.getKey(cls, true)); // no error
431}
432
433}
434
435#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:346
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:96
Definition RadarProj.h:100
Vector graphics for both composites and single radar data (polar coordinates).
Definition graphics-radar.h:134
void setRadialResolution(int n)
Number of "sectors" in a sphere.
Definition graphics-radar.h:231
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:210
static drain::image::TreeSVG & getOverlayGroup(drain::image::TreeSVG &svgDoc)
Sets some CSS properties applicable in radar graphics (grids, sectors).
Definition graphics-radar.cpp:184
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:226
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:302
void drawCircle(drain::svgPATH &elem, const drain::Range< double > &radius) const
Convenience: draw circle (disk or annulus)
Definition graphics-radar.h:360
void cubicBezierTo(drain::svgPATH &elem, double radiusM, double azimuthStartR, double azimuthEndR) const
Single command to draw arc.
Definition graphics-radar.cpp:294
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:361
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:206
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:254
double delta
Sector angle.
Definition graphics-radar.h:257