File: plotMapProjection.cpp

package info (click to toggle)
groops 0%2Bgit20250907%2Bds-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 11,140 kB
  • sloc: cpp: 135,607; fortran: 1,603; makefile: 20
file content (329 lines) | stat: -rw-r--r-- 11,555 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/***********************************************/
/**
* @file plotMapProjection.cpp
*
* @brief Map projections used for plotting.
*
* @author Andreas Kvas
* @author Torsten Mayer-Guerr
* @date 2015-10-23
*
*/
/***********************************************/

#define DOCSTRING_PlotMapProjection

#include "base/import.h"
#include "config/configRegister.h"
#include "plotMapProjection.h"
#include "plotMisc.h"

/***********************************************/

static const char *docstringPlotMapProjectionRobinson = R"(
\subsection{Robinson}
The Robinson projection, presented by Arthur H. Robinson in 1963,
is a modified cylindrical projection that is neither conformal nor equal-area.
Central meridian and all parallels are straight lines; other meridians are curved.
It uses lookup tables rather than analytic expressions to make the world map look right.
)";

class PlotMapProjectionRobinson : public PlotMapProjection
{
  Angle L0;

public:
  PlotMapProjectionRobinson(Config &config)
  {
    readConfig(config, "centralMeridian", L0, Config::DEFAULT, "0", "central meridian [degree]");
  }

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    ss<<"-JN"<<L0*RAD2DEG<<"/"<<width<<"c";
    return ss.str();
  }

  Double aspectRatio() const override {return (1+1./80.)/2;}
};

/***********************************************/

static const char *docstringPlotMapProjectionMollweide = R"(
\subsection{Mollweide}
This pseudo-cylindrical, equal-area projection was developed by Mollweide in 1805. Parallels are unequally spaced straight
lines with the meridians being equally spaced elliptical arcs. The scale is only true along latitudes 40$^{o}$44' north and south.
The projection is used mainly for global maps showing data distributions.
)";

class PlotMapProjectionMollweide : public PlotMapProjection
{
  Angle L0;

public:
  PlotMapProjectionMollweide(Config &config)
  {
    readConfig(config, "centralMeridian", L0, Config::DEFAULT, "0", "central meridian [degree]");
  }

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    ss<<"-JW"<<L0*RAD2DEG<<"/"<<width<<"c";
    return ss.str();
  }

  Double aspectRatio() const override {return 0.5;}
};

/***********************************************/

static const char *docstringPlotMapProjectionOrthographic = R"(
\subsection{Orthographic}
The orthographic azimuthal projection is a perspective projection from infinite distance.
It is therefore often used to give the appearance of a globe viewed from space.
)";

class PlotMapProjectionOrthographic : public PlotMapProjection
{
  Angle L0, B0;

public:
  PlotMapProjectionOrthographic(Config &config)
  {
    readConfig(config, "lambdaCenter", L0, Config::DEFAULT, "30", "central point [degree]");
    readConfig(config, "phiCenter",    B0, Config::DEFAULT, "30", "central point [degree]");
  }

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    ss<<"-JG"<<L0*RAD2DEG<<"/"<<B0*RAD2DEG<<"/"<<width<<"c";
    return ss.str();
  }
};

/***********************************************/

static const char *docstringPlotMapProjectionPerspectiveSphere = R"(
\subsection{Perspective sphere}
The orthographic azimuthal projection is a perspective projection from infinite distance.
It is therefore often used to give the appearance of a globe viewed from space.
)";

class PlotMapProjectionPerspectiveSphere : public PlotMapProjection
{
  Angle  L0, B0;
  Angle  azimuth, tilt;
  Angle  viewpointTwist, viewpointWidth, viewpointHeight;
  Double altitude;

public:
  PlotMapProjectionPerspectiveSphere(Config &config)
  {
    readConfig(config, "lambdaCenter",    L0,              Config::DEFAULT,  "10",   "longitude of central point in degrees");
    readConfig(config, "phiCenter",       B0,              Config::DEFAULT,  "40",   "latitude of central point in degrees");
    readConfig(config, "altitude",        altitude,        Config::DEFAULT,  "1500", "[km]");
    readConfig(config, "azimuth",         azimuth,         Config::DEFAULT,  "0",    "to the east of north of view [degrees]");
    readConfig(config, "tilt",            tilt,            Config::DEFAULT,  "0",    "upward tilt of the plane of projection, if negative, then the view is centered on the horizon [degrees]");
    readConfig(config, "viewpointTwist",  viewpointTwist,  Config::DEFAULT,  "0",    "clockwise twist of the viewpoint [degrees]");
    readConfig(config, "viewpointWidth",  viewpointWidth,  Config::DEFAULT,  "0",    "width of the viewpoint [degrees]");
    readConfig(config, "viewpointHeight", viewpointHeight, Config::DEFAULT,  "0",    "height of the viewpoint [degrees]");
  }

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    ss<<"-JG"<<L0*RAD2DEG<<"/"<<B0*RAD2DEG<<"/"<<altitude<<"/"<<azimuth*RAD2DEG<<"/"<<tilt*RAD2DEG
             <<"/"<<viewpointTwist*RAD2DEG<<"/"<<viewpointWidth*RAD2DEG<<"/"<<viewpointHeight*RAD2DEG
             <<"/"<<width<<"c";
    return ss.str();
  }
};

/***********************************************/

static const char *docstringPlotMapProjectionPolar = R"(
\subsection{Polar}
Stereographic projection around given central point.
)";

class PlotMapProjectionPolar : public PlotMapProjection
{
  Angle L0, B0;

public:
  PlotMapProjectionPolar(Config &config)
  {
   readConfig(config, "lambdaCenter", L0, Config::DEFAULT, "0",   "longitude of central point in degrees");
   readConfig(config, "phiCenter",    B0, Config::DEFAULT, "-90", "latitude of central point in degrees");
  }

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    ss<<"-JS"<<L0*RAD2DEG<<"/"<<B0*RAD2DEG<<"/"<<width<<"c";
    return ss.str();
  }
};

/***********************************************/

static const char *docstringPlotMapProjectionSkyplot = R"(
\subsection{Skyplot}
Skyplot used to plot azimuth/elevation data as generated by
\program{GnssAntennaDefinition2Skyplot} or \program{GnssResiduals2Skyplot}.
)";

class PlotMapProjectionSkyplot : public PlotMapProjection
{
public:
  PlotMapProjectionSkyplot(Config &/*config*/) {}

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    if(PlotBasics::gmtVersion() >= 610)
      ss<<"-JP"<<width<<"c+a+fe";
    else
      ss<<"-JPa"<<width<<"cr";
    return ss.str();
  }
};

/***********************************************/

static const char *docstringPlotMapProjectionUtm = R"(
\subsection{UTM}
A particular subset of the transverse Mercator is the Universal Transverse Mercator (UTM)
which was adopted by the US Army for large-scale military maps.
Here, the globe is divided into 60 zones between 84$^{o}$S and 84$^{o}$N, most of which are 6$^{o}$ wide.
Each of these UTM zones have their unique central meridian.
)";

class PlotMapProjectionUtm : public PlotMapProjection
{
  std::string zone;

public:
  PlotMapProjectionUtm(Config &config)
  {
    readConfig(config, "zone", zone, Config::MUSTSET, "", "UTM zone code (e.g. 33N)");
  }

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    ss<<"-JU"<<zone<<"/"<<width<<"c";
    return ss.str();
  }

  virtual Double aspectRatio() const override {return 0;}
};

/***********************************************/

static const char *docstringPlotMapProjectionLambert = R"(
\subsection{Lambert}
This conic projection was designed by Lambert (1772) and has been used extensively for mapping of regions with predominantly east-west orientation.
)";

class PlotMapProjectionLambert : public PlotMapProjection
{
  Angle L0, B0, par1, par2;

public:
  PlotMapProjectionLambert(Config &config)
  {
    readConfig(config, "lambda0", L0,   Config::MUSTSET, "", "longitude of projection center [deg]");
    readConfig(config, "phi0",    B0,   Config::MUSTSET, "", "latitude of projection centert [deg]");
    readConfig(config, "phi1",    par1, Config::MUSTSET, "", "latitude of first standard parallel [deg]");
    readConfig(config, "phi2",    par2, Config::MUSTSET, "", "latitude of first standard parallel [deg]");
  }

  std::string scriptEntry(Double width, Double /*height*/) const override
  {
    std::stringstream ss;
    ss<<"-JL"<<L0*RAD2DEG<<"/"<<B0*RAD2DEG<<"/"<<par1*RAD2DEG<<"/"<<par2*RAD2DEG<<"/"<<width<<"c";
    return ss.str();
  }
};

/***********************************************/

static const char *docstringPlotMapProjectionLinear = R"(
\subsection{Linear}
Linear mapping of longitude/latitude to x/y (Plate Caree).
)";

class PlotMapProjectionLinear : public PlotMapProjection
{
public:
  PlotMapProjectionLinear(Config &/*config*/) {}

  std::string scriptEntry(Double width, Double height) const override
  {
    std::stringstream ss;
    ss<<"-JX"<<width<<"cd/"<<height<<"cd";
    return ss.str();
  }

  virtual Double aspectRatio() const override {return 0;}
};

/***********************************************/
/***********************************************/

GROOPS_REGISTER_CLASS(PlotMapProjection, "plotMapProjectionType",
                      PlotMapProjectionRobinson,
                      PlotMapProjectionOrthographic,
                      PlotMapProjectionPerspectiveSphere,
                      PlotMapProjectionPolar,
                      PlotMapProjectionSkyplot,
                      PlotMapProjectionUtm,
                      PlotMapProjectionLambert,
                      PlotMapProjectionLinear,
                      PlotMapProjectionMollweide)

GROOPS_READCONFIG_CLASS(PlotMapProjection, "plotMapProjectionType")

/***********************************************/

PlotMapProjectionPtr PlotMapProjection::create(Config &config, const std::string &name)
{
  try
  {
    PlotMapProjectionPtr proj;
    std::string  type;

    readConfigChoice(config, name, type, Config::MUSTSET, "", "plot layers");
    if(readConfigChoiceElement(config, "robinson",     type, "robinson projection"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionRobinson(config));
    if(readConfigChoiceElement(config, "orthographic", type, "orthographic projection"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionOrthographic(config));
    if(readConfigChoiceElement(config, "perspective",  type, "perspective sphere"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionPerspectiveSphere(config));
    if(readConfigChoiceElement(config, "polar",        type, "polar stereographic"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionPolar(config));
    if(readConfigChoiceElement(config, "skyplot",      type, "skyplot"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionSkyplot(config));
    if(readConfigChoiceElement(config, "linear",       type, "linear (plate carree) projection"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionLinear(config));
    if(readConfigChoiceElement(config, "Utm",          type, "UTM projection"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionUtm(config));
    if(readConfigChoiceElement(config, "lambert",      type, "lambert conformal conic"))
      proj = PlotMapProjectionPtr(new PlotMapProjectionLambert(config));
    if(readConfigChoiceElement(config, "mollweide",    type, "mollweide projection "))
      proj = PlotMapProjectionPtr(new PlotMapProjectionMollweide(config));
    endChoice(config);

    return proj;
  }
  catch(std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

/***********************************************/