29using namespace Qt::StringLiterals;
38 const QList< Qgis::CrsAxisDirection > axisList = horizontalCrs.
axisOrdering();
39 if ( axisList.size() < 2 )
103 return QObject::tr(
"N",
"axis" );
105 return QObject::tr(
"NNE",
"axis" );
107 return QObject::tr(
"SSE",
"axis" );
109 return QObject::tr(
"S",
"axis" );
111 return QObject::tr(
"SSW",
"axis" );
113 return QObject::tr(
"NNW",
"axis" );
115 return QObject::tr(
"Y",
"axis" );
117 return QObject::tr(
"Up",
"axis" );
119 return QObject::tr(
"Down",
"axis" );
121 return QObject::tr(
"NE",
"axis" );
123 return QObject::tr(
"ENE",
"axis" );
125 return QObject::tr(
"E",
"axis" );
127 return QObject::tr(
"ESE",
"axis" );
129 return QObject::tr(
"SE",
"axis" );
131 return QObject::tr(
"SW",
"axis" );
133 return QObject::tr(
"WSW",
"axis" );
135 return QObject::tr(
"W",
"axis" );
137 return QObject::tr(
"WNW",
"axis" );
139 return QObject::tr(
"NW",
"axis" );
141 return QObject::tr(
"X",
"axis" );
143 return QObject::tr(
"Disp. R",
"axis" );
145 return QObject::tr(
"Disp. L",
"axis" );
147 return QObject::tr(
"Z",
"axis" );
149 return QObject::tr(
"U",
"axis" );
151 return QObject::tr(
"D",
"axis" );
153 return QObject::tr(
"F",
"axis" );
155 return QObject::tr(
"A",
"axis" );
157 return QObject::tr(
"P",
"axis" );
159 return QObject::tr(
"STBD",
"axis" );
161 return QObject::tr(
"CW",
"axis" );
163 return QObject::tr(
"CCW",
"axis" );
165 return QObject::tr(
"C+",
"axis" );
167 return QObject::tr(
"C-",
"axis" );
169 return QObject::tr(
"R+",
"axis" );
171 return QObject::tr(
"R-",
"axis" );
173 return QObject::tr(
"F",
"axis" );
175 return QObject::tr(
"P",
"axis" );
177 return QObject::tr(
"T",
"axis" );
179 return QObject::tr(
"AF",
"axis" );
192 return QObject::tr(
"Unknown" );
194 return QObject::tr(
"Other" );
196 return QObject::tr(
"Geodetic" );
198 return QObject::tr(
"Geocentric" );
200 return QObject::tr(
"Geographic (2D)" );
202 return QObject::tr(
"Geographic (3D)" );
204 return QObject::tr(
"Vertical" );
206 return QObject::tr(
"Projected" );
208 return QObject::tr(
"Compound" );
210 return QObject::tr(
"Temporal" );
212 return QObject::tr(
"Engineering" );
214 return QObject::tr(
"Bound" );
216 return QObject::tr(
"Derived projected" );
223 if ( projection ==
"adams_ws2"_L1 )
224 return QObject::tr(
"Adams World in a Square II" );
225 if ( projection ==
"aea"_L1 )
226 return QObject::tr(
"Albers Equal Area" );
227 if ( projection ==
"aeqd"_L1 )
228 return QObject::tr(
"Azimuthal Equidistant" );
229 if ( projection ==
"airy"_L1 )
230 return QObject::tr(
"Airy" );
231 if ( projection ==
"aitoff"_L1 )
232 return QObject::tr(
"Aitoff" );
233 if ( projection ==
"alsk"_L1 )
234 return QObject::tr(
"Modified Stererographics of Alaska" );
235 if ( projection ==
"apian"_L1 )
236 return QObject::tr(
"Apian Globular I" );
237 if ( projection ==
"august"_L1 )
238 return QObject::tr(
"August Epicycloidal" );
239 if ( projection ==
"bacon"_L1 )
240 return QObject::tr(
"Bacon Globular" );
241 if ( projection ==
"bipc"_L1 )
242 return QObject::tr(
"Bipolar Conic of Western Hemisphere" );
243 if ( projection ==
"boggs"_L1 )
244 return QObject::tr(
"Boggs Eumorphic" );
245 if ( projection ==
"bonne"_L1 )
246 return QObject::tr(
"Bonne (Werner lat_1=90)" );
247 if ( projection ==
"cass"_L1 )
248 return QObject::tr(
"Cassini" );
249 if ( projection ==
"cc"_L1 )
250 return QObject::tr(
"Central Cylindrical" );
251 if ( projection ==
"cea"_L1 )
252 return QObject::tr(
"Equal Area Cylindrical" );
253 if ( projection ==
"chamb"_L1 )
254 return QObject::tr(
"Chamberlin Trimetric" );
255 if ( projection ==
"col_urban"_L1 )
256 return QObject::tr(
"Colombia Urban" );
257 if ( projection ==
"collg"_L1 )
258 return QObject::tr(
"Collignon" );
259 if ( projection ==
"comill"_L1 )
260 return QObject::tr(
"Compact Miller" );
261 if ( projection ==
"crast"_L1 )
262 return QObject::tr(
"Craster Parabolic (Putnins P4)" );
263 if ( projection ==
"denoy"_L1 )
264 return QObject::tr(
"Denoyer Semi-Elliptical" );
265 if ( projection ==
"eck1"_L1 )
266 return QObject::tr(
"Eckert I" );
267 if ( projection ==
"eck2"_L1 )
268 return QObject::tr(
"Eckert II" );
269 if ( projection ==
"eck3"_L1 )
270 return QObject::tr(
"Eckert III" );
271 if ( projection ==
"eck4"_L1 )
272 return QObject::tr(
"Eckert IV" );
273 if ( projection ==
"eck5"_L1 )
274 return QObject::tr(
"Eckert V" );
275 if ( projection ==
"eck6"_L1 )
276 return QObject::tr(
"Eckert VI" );
277 if ( projection ==
"eqc"_L1 )
278 return QObject::tr(
"Equidistant Cylindrical (Plate Carrée)" );
279 if ( projection ==
"eqdc"_L1 )
280 return QObject::tr(
"Equidistant Conic" );
281 if ( projection ==
"eqearth"_L1 )
282 return QObject::tr(
"Equal Earth" );
283 if ( projection ==
"euler"_L1 )
284 return QObject::tr(
"Euler" );
285 if ( projection ==
"fahey"_L1 )
286 return QObject::tr(
"Fahey" );
287 if ( projection ==
"fouc"_L1 )
288 return QObject::tr(
"Foucaut" );
289 if ( projection ==
"fouc_s"_L1 )
290 return QObject::tr(
"Foucaut Sinusoidal" );
291 if ( projection ==
"gall"_L1 )
292 return QObject::tr(
"Gall (Gall Stereographic)" );
293 if ( projection ==
"geocent"_L1 )
294 return QObject::tr(
"Geocentric" );
295 if ( projection ==
"geos"_L1 )
296 return QObject::tr(
"Geostationary Satellite View" );
297 if ( projection ==
"gins8"_L1 )
298 return QObject::tr(
"Ginsburg VIII (TsNIIGAiK)" );
299 if ( projection ==
"gn_sinu"_L1 )
300 return QObject::tr(
"General Sinusoidal Series" );
301 if ( projection ==
"gnom"_L1 )
302 return QObject::tr(
"Gnomonic" );
303 if ( projection ==
"goode"_L1 )
304 return QObject::tr(
"Goode Homolosine" );
305 if ( projection ==
"gs48"_L1 )
306 return QObject::tr(
"Modified Stererographics of 48 U.S." );
307 if ( projection ==
"gs50"_L1 )
308 return QObject::tr(
"Modified Stererographics of 50 U.S." );
309 if ( projection ==
"hammer"_L1 )
310 return QObject::tr(
"Hammer & Eckert-Greifendorff" );
311 if ( projection ==
"hatano"_L1 )
312 return QObject::tr(
"Hatano Asymmetrical Equal Area" );
313 if ( projection ==
"igh"_L1 )
314 return QObject::tr(
"Interrupted Goode Homolosine" );
315 if ( projection ==
"igh_o"_L1 )
316 return QObject::tr(
"Interrupted Goode Homolosine (Oceanic View)" );
317 if ( projection ==
"imw_p"_L1 )
318 return QObject::tr(
"International Map of the World Polyconic" );
319 if ( projection ==
"kav5"_L1 )
320 return QObject::tr(
"Kavraisky V" );
321 if ( projection ==
"kav7"_L1 )
322 return QObject::tr(
"Kavraisky VII" );
323 if ( projection ==
"krovak"_L1 )
324 return QObject::tr(
"Krovak" );
325 if ( projection ==
"labrd"_L1 )
326 return QObject::tr(
"Laborde" );
327 if ( projection ==
"laea"_L1 )
328 return QObject::tr(
"Lambert Azimuthal Equal Area" );
329 if ( projection ==
"lagrng"_L1 )
330 return QObject::tr(
"Lagrange" );
331 if ( projection ==
"larr"_L1 )
332 return QObject::tr(
"Larrivee" );
333 if ( projection ==
"lask"_L1 )
334 return QObject::tr(
"Laskowski" );
335 if ( projection ==
"longlat"_L1 )
336 return QObject::tr(
"Long/lat (Geodetic Alias)" );
337 if ( projection ==
"latlong"_L1 )
338 return QObject::tr(
"Lat/long (Geodetic Alias)" );
339 if ( projection ==
"lcc"_L1 )
340 return QObject::tr(
"Lambert Conformal Conic" );
341 if ( projection ==
"lcca"_L1 )
342 return QObject::tr(
"Lambert Conformal Conic Alternative" );
343 if ( projection ==
"leac"_L1 )
344 return QObject::tr(
"Lambert Equal Area Conic" );
345 if ( projection ==
"lee_os"_L1 )
346 return QObject::tr(
"Lee Oblated Stereographic" );
347 if ( projection ==
"loxim"_L1 )
348 return QObject::tr(
"Loximuthal" );
349 if ( projection ==
"lsat"_L1 )
350 return QObject::tr(
"Space Oblique for LANDSAT" );
351 if ( projection ==
"mbt_s"_L1 )
352 return QObject::tr(
"McBryde-Thomas Flat-Polar Sine (No. 1)" );
353 if ( projection ==
"mbt_fps"_L1 )
354 return QObject::tr(
"McBryde-Thomas Flat-Pole Sine (No. 2)" );
355 if ( projection ==
"mbtfpp"_L1 )
356 return QObject::tr(
"McBride-Thomas Flat-Polar Parabolic" );
357 if ( projection ==
"mbtfpq"_L1 )
358 return QObject::tr(
"McBryde-Thomas Flat-Polar Quartic" );
359 if ( projection ==
"mbtfps"_L1 )
360 return QObject::tr(
"McBryde-Thomas Flat-Polar Sinusoidal" );
361 if ( projection ==
"merc"_L1 )
362 return QObject::tr(
"Mercator" );
363 if ( projection ==
"mil_os"_L1 )
364 return QObject::tr(
"Miller Oblated Stereographic" );
365 if ( projection ==
"mill"_L1 )
366 return QObject::tr(
"Miller Cylindrical" );
367 if ( projection ==
"mod_krovak"_L1 )
368 return QObject::tr(
"Modified Krovak" );
369 if ( projection ==
"moll"_L1 )
370 return QObject::tr(
"Mollweide" );
371 if ( projection ==
"murd1"_L1 )
372 return QObject::tr(
"Murdoch I" );
373 if ( projection ==
"murd2"_L1 )
374 return QObject::tr(
"Murdoch II" );
375 if ( projection ==
"murd3"_L1 )
376 return QObject::tr(
"Murdoch III" );
377 if ( projection ==
"natearth"_L1 )
378 return QObject::tr(
"Natural Earth" );
379 if ( projection ==
"natearth2"_L1 )
380 return QObject::tr(
"Natural Earth II" );
381 if ( projection ==
"nell"_L1 )
382 return QObject::tr(
"Nell" );
383 if ( projection ==
"nell_h"_L1 )
384 return QObject::tr(
"Nell-Hammer" );
385 if ( projection ==
"nicol"_L1 )
386 return QObject::tr(
"Nicolosi Globular" );
387 if ( projection ==
"nsper"_L1 )
388 return QObject::tr(
"Near-sided Perspective" );
389 if ( projection ==
"nzmg"_L1 )
390 return QObject::tr(
"New Zealand Map Grid" );
391 if ( projection ==
"ob_tran"_L1 )
392 return QObject::tr(
"General Oblique Transformation" );
393 if ( projection ==
"ocea"_L1 )
394 return QObject::tr(
"Oblique Cylindrical Equal Area" );
395 if ( projection ==
"oea"_L1 )
396 return QObject::tr(
"Oblated Equal Area" );
397 if ( projection ==
"omerc"_L1 )
398 return QObject::tr(
"Oblique Mercator" );
399 if ( projection ==
"ortel"_L1 )
400 return QObject::tr(
"Ortelius Oval" );
401 if ( projection ==
"ortho"_L1 )
402 return QObject::tr(
"Orthographic" );
403 if ( projection ==
"patterson"_L1 )
404 return QObject::tr(
"Patterson" );
405 if ( projection ==
"pconic"_L1 )
406 return QObject::tr(
"Perspective Conic" );
407 if ( projection ==
"peirce_q"_L1 )
408 return QObject::tr(
"Peirce Quincuncial" );
409 if ( projection ==
"poly"_L1 )
410 return QObject::tr(
"Polyconic (American)" );
411 if ( projection ==
"putp1"_L1 )
412 return QObject::tr(
"Putnins P1" );
413 if ( projection ==
"putp2"_L1 )
414 return QObject::tr(
"Putnins P2" );
415 if ( projection ==
"putp3"_L1 )
416 return QObject::tr(
"Putnins P3" );
417 if ( projection ==
"putp3p"_L1 )
418 return QObject::tr(
"Putnins P3'" );
419 if ( projection ==
"putp4p"_L1 )
420 return QObject::tr(
"Putnins P4'" );
421 if ( projection ==
"putp5"_L1 )
422 return QObject::tr(
"Putnins P5" );
423 if ( projection ==
"putp5p"_L1 )
424 return QObject::tr(
"Putnins P5'" );
425 if ( projection ==
"putp6"_L1 )
426 return QObject::tr(
"Putnins P6" );
427 if ( projection ==
"putp6p"_L1 )
428 return QObject::tr(
"Putnins P6'" );
429 if ( projection ==
"qua_aut"_L1 )
430 return QObject::tr(
"Quartic Authalic" );
431 if ( projection ==
"robin"_L1 )
432 return QObject::tr(
"Robinson" );
433 if ( projection ==
"rouss"_L1 )
434 return QObject::tr(
"Roussilhe Stereographic" );
435 if ( projection ==
"rpoly"_L1 )
436 return QObject::tr(
"Rectangular Polyconic" );
437 if ( projection ==
"sinu"_L1 )
438 return QObject::tr(
"Sinusoidal (Sanson-Flamsteed)" );
439 if ( projection ==
"spilhaus"_L1 )
440 return QObject::tr(
"Spilhaus" );
441 if ( projection ==
"somerc"_L1 )
442 return QObject::tr(
"Swiss Oblique Mercator" );
443 if ( projection ==
"stere"_L1 )
444 return QObject::tr(
"Stereographic" );
445 if ( projection ==
"sterea"_L1 )
446 return QObject::tr(
"Oblique Stereographic Alternative" );
447 if ( projection ==
"tcc"_L1 )
448 return QObject::tr(
"Transverse Central Cylindrical" );
449 if ( projection ==
"tcea"_L1 )
450 return QObject::tr(
"Transverse Cylindrical Equal Area" );
451 if ( projection ==
"times"_L1 )
452 return QObject::tr(
"Times" );
453 if ( projection ==
"tissot"_L1 )
454 return QObject::tr(
"Tissot" );
455 if ( projection ==
"tmerc"_L1 )
456 return QObject::tr(
"Transverse Mercator" );
457 if ( projection ==
"tmerczoned"_L1 )
458 return QObject::tr(
"Transverse Mercator Zoned Grid System" );
459 if ( projection ==
"tpeqd"_L1 )
460 return QObject::tr(
"Two Point Equidistant" );
461 if ( projection ==
"tpers"_L1 )
462 return QObject::tr(
"Tilted Perspective" );
463 if ( projection ==
"ups"_L1 )
464 return QObject::tr(
"Universal Polar Stereographic" );
465 if ( projection ==
"urm5"_L1 )
466 return QObject::tr(
"Urmaev V" );
467 if ( projection ==
"urmfps"_L1 )
468 return QObject::tr(
"Urmaev Flat-Polar Sinusoidal" );
469 if ( projection ==
"utm"_L1 )
470 return QObject::tr(
"Universal Transverse Mercator (UTM)" );
471 if ( projection ==
"vandg"_L1 )
472 return QObject::tr(
"van der Grinten (I)" );
473 if ( projection ==
"vandg2"_L1 )
474 return QObject::tr(
"van der Grinten II" );
475 if ( projection ==
"vandg3"_L1 )
476 return QObject::tr(
"van der Grinten III" );
477 if ( projection ==
"vandg4"_L1 )
478 return QObject::tr(
"van der Grinten IV" );
479 if ( projection ==
"vitk1"_L1 )
480 return QObject::tr(
"Vitkovsky I" );
481 if ( projection ==
"wag1"_L1 )
482 return QObject::tr(
"Wagner I (Kavraisky VI)" );
483 if ( projection ==
"wag2"_L1 )
484 return QObject::tr(
"Wagner II" );
485 if ( projection ==
"wag3"_L1 )
486 return QObject::tr(
"Wagner III" );
487 if ( projection ==
"wag4"_L1 )
488 return QObject::tr(
"Wagner IV" );
489 if ( projection ==
"wag5"_L1 )
490 return QObject::tr(
"Wagner V" );
491 if ( projection ==
"wag6"_L1 )
492 return QObject::tr(
"Wagner VI" );
493 if ( projection ==
"wag7"_L1 )
494 return QObject::tr(
"Wagner VII" );
495 if ( projection ==
"weren"_L1 )
496 return QObject::tr(
"Werenskiold I" );
497 if ( projection ==
"wink1"_L1 )
498 return QObject::tr(
"Winkel I" );
499 if ( projection ==
"wink2"_L1 )
500 return QObject::tr(
"Winkel II" );
501 if ( projection ==
"wintri"_L1 )
502 return QObject::tr(
"Winkel Tripel" );
503 if ( projection ==
"gstmerc"_L1 )
504 return QObject::tr(
"Gauss-Schreiber" );
512 double topoLat = 0.0, topoLon = 0.0;
519 if ( std::abs( topoLat ) < degreeStep )
520 topoLat = topoLat >= 0 ? degreeStep : -degreeStep;
522 const double topoLonRad = topoLon * M_PI / 180.0;
523 const double topoLatRad = topoLat * M_PI / 180.0;
527 QVector<double> x, y;
528 const int pointCount =
static_cast< int >( 360.0 / degreeStep ) + 2;
529 x.reserve( pointCount );
530 y.reserve( pointCount );
531 for (
double lon = -180.0; lon <= 180.0; lon += degreeStep )
533 const double lonRad = lon * M_PI / 180.0;
534 const double latRad = std::atan( -std::cos( lonRad - topoLonRad ) / std::tan( topoLatRad ) );
536 y.append( latRad * 180.0 / M_PI );
541 const double pole = topoLat > 0 ? 90.0 : -90.0;
547 auto exteriorRing = std::make_unique< QgsLineString >( x, y );
548 QgsGeometry horizonGeom( std::make_unique< QgsPolygon >( exteriorRing.release() ) );
558 QgsMessageLog::logMessage( QObject::tr(
"Topocentric horizon geometry transform error caught: %1" ).arg( cse.
what() ), QObject::tr(
"CRS" ) );
CrsType
Coordinate reference system types.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ DerivedProjected
Derived projected CRS.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
CoordinateOrder
Order of coordinates.
@ XY
Easting/Northing (or Longitude/Latitude for geographic CRS).
@ YX
Northing/Easting (or Latitude/Longitude for geographic CRS).
CrsAxisDirection
Coordinate reference system axis directions.
@ ColumnPositive
Column positive.
@ SouthSouthEast
South South East.
@ ColumnNegative
Column negative.
@ RowPositive
Row positive.
@ DisplayDown
Display down.
@ GeocentricZ
Geocentric (Z).
@ DisplayRight
Display right.
@ WestSouthWest
West South West.
@ RowNegative
Row negative.
@ NorthNorthEast
North North East.
@ EastNorthEast
East North East.
@ Unspecified
Unspecified.
@ NorthNorthWest
North North West.
@ GeocentricY
Geocentric (Y).
@ CounterClockwise
Counter clockwise.
@ SouthSouthWest
South South West.
@ DisplayLeft
Display left.
@ WestNorthWest
West North West.
@ EastSouthEast
East South East.
@ GeocentricX
Geocentric (X).
static QgsGeometry topocentricHorizonGeometry(const QgsCoordinateReferenceSystem &topocentricCrs, const QgsCoordinateReferenceSystem &outputCrs, const QgsCoordinateTransformContext &transformContext, double degreeStep=1.0)
Builds the geometry of the visible horizon (in outputCrs) when topocentricCrs is a topocentric CRS.
static QString crsTypeToString(Qgis::CrsType type)
Returns a translated string representing a CRS type.
static QString translateProjection(const QString &projection)
Returns a translated string for a projection method.
static Qgis::CoordinateOrder defaultCoordinateOrderForCrs(const QgsCoordinateReferenceSystem &crs)
Returns the default coordinate order to use for the specified crs.
static QString axisDirectionToAbbreviatedString(Qgis::CrsAxisDirection axis)
Returns a translated abbreviation representing an axis direction.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QgsCoordinateReferenceSystem horizontalCrs() const
Returns the horizontal CRS associated with this CRS object.
QgsCoordinateReferenceSystem toGeographicCrs() const
Returns the geographic CRS associated with this CRS object.
QList< Qgis::CrsAxisDirection > axisOrdering() const
Returns an ordered list of the axis directions reflecting the native axis order for the CRS.
bool topocentricOrigin(double &latitude, double &longitude) const
Returns the topocentric origin of a topocentric compatible CRS.
Contains information about the context in which a coordinate transform is executed.
Custom exception class for Coordinate Reference System related exceptions.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).