File failed to load: https://isis.astrogeology.usgs.gov/9.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
UniversalGroundMap.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "UniversalGroundMap.h"
8
9#include <QPointF>
10
11#include "Camera.h"
12#include "CameraFactory.h"
13#include "ImagePolygon.h"
14#include "Latitude.h"
15#include "Longitude.h"
16#include "Latitude.h"
17#include "Longitude.h"
18#include "PolygonTools.h"
19#include "Projection.h"
20#include "RingPlaneProjection.h"
21#include "TProjection.h"
22#include "ProjectionFactory.h"
23#include "SurfacePoint.h"
24#include "Target.h"
25
26namespace Isis {
34 p_camera = NULL;
35 p_projection = NULL;
36
37 Pvl &pvl = *cube.label();
38 try {
39 if(priority == CameraFirst)
41 else
43 }
44 catch (IException &firstError) {
45 p_camera = NULL;
46 p_projection = NULL;
47
48 try {
49 if(priority == CameraFirst)
51 else
53 }
54 catch (IException &secondError) {
55 p_projection = NULL;
56 QString msg = "Could not create camera or projection for [" +
57 cube.fileName() + "]";
58 IException realError(IException::Unknown, msg, _FILEINFO_);
59 realError.append(firstError);
60 realError.append(secondError);
61 throw realError;
62 }
63 }
64 }
65
72 void UniversalGroundMap::SetBand(const int band) {
73 if (p_camera != NULL)
74 p_camera->SetBand(band);
75 }
76
77
78
81 if (p_camera != NULL) {
82 delete p_camera;
83 p_camera = NULL;
84 }
85
86 if (p_projection != NULL) {
87 delete p_projection;
88 p_projection = NULL;
89 }
90 }
91
102 bool UniversalGroundMap::SetUniversalGround(double lat, double lon) {
103 if (p_camera != NULL) {
104 if (p_camera->SetUniversalGround(lat, lon)) { // This should work for rings (radius,azimuth)
105 return p_camera->InCube();
106 }
107 else {
108 return false;
109 }
110 }
111 else {
112 return p_projection->SetUniversalGround(lat, lon); // This should work for rings (radius,azimuth)
113 }
114 }
115
116
128 if(p_camera != NULL) {
129 if(p_camera->SetGround(lat, lon)) { // This should work for rings (radius,azimuth)
130 return p_camera->InCube();
131 }
132 else {
133 return false;
134 }
135 }
136 else {
137 double universalLat = lat.degrees();
138 double universalLon = lon.degrees();
139 return p_projection->SetUniversalGround(universalLat, universalLon); // This should work for rings (radius,azimuth)
140 }
141 }
142
143
155 if(p_camera != NULL) {
156 if(p_camera->SetGround(lat, lon)) { // This should work for rings (radius,azimuth)
157 return p_camera->InCube();
158 }
159 else {
160 return false;
161 }
162 }
163 else {
164 double universalLat = lat.degrees();
165 double universalLon = lon.degrees();
166 return p_projection->SetUnboundUniversalGround(universalLat, universalLon);
167 }
168 }
169
170
181 if (p_camera != NULL) {
182 if (p_camera->SetGround(sp)) {
183 return p_camera->InCube();
184 }
185 else {
186 return false;
187 }
188 }
189 else {
190 return p_projection->SetUniversalGround(sp.GetLatitude().degrees(),
191 sp.GetLongitude().degrees()); // This should work for rings (radius,azimuth)
192 }
193 }
194
201 if (p_camera != NULL) {
202 return p_camera->Sample();
203 }
204 else {
205 return p_projection->WorldX();
206 }
207 }
208
215 if (p_camera != NULL) {
216 return p_camera->Line();
217 }
218 else {
219 return p_projection->WorldY();
220 }
221 }
222
233 bool UniversalGroundMap::SetImage(double sample, double line) {
234 if (p_camera != NULL) {
235 return p_camera->SetImage(sample, line);
236 }
237 else {
238 return p_projection->SetWorld(sample, line);
239 }
240 }
241
248 if (p_camera != NULL) {
249 return p_camera->UniversalLatitude();
250 }
251 else {
252 // Is this a triaxial projection or ring projection. If ring return Radius as latitude
253 Projection::ProjectionType projType = p_projection->projectionType();
254 if (projType == Projection::Triaxial) {
256 return tproj->UniversalLatitude();
257 }
258 else {
260 return rproj->RingRadius();
261 }
262 }
263 }
264
271 if (p_camera != NULL) {
272 return p_camera->UniversalLongitude();
273 }
274 else {
275 // Is this a triaxial projection or ring projection. If ring return ring longitude as
276 // longitude
277 Projection::ProjectionType projType = p_projection->projectionType();
278 if (projType == Projection::Triaxial) {
280 return tproj->UniversalLongitude();
281 }
282 else {
284 return rproj->RingLongitude();
285 }
286 }
287 }
288
295 if (p_camera != NULL) {
296 return p_camera->PixelResolution();
297 }
298 else {
299 return p_projection->Resolution();
300 }
301 }
302
303
321 Latitude &maxLat, Longitude &minLon, Longitude &maxLon,
322 bool allowEstimation) {
323 // Do we need a RingRange method?
324 // For now just return false
325 if (HasCamera())
326 if (p_camera->target()->shape()->name() == "Plane") return false;
327 if (HasProjection())
328 if (p_projection->projectionType() == Projection::RingPlane) return false;
329
330 minLat = Latitude();
331 maxLat = Latitude();
332 minLon = Longitude();
333 maxLon = Longitude();
334
335 // If we have a footprint, use it
336 try {
337 if (cube) {
338 ImagePolygon poly = cube->readFootprint();
339 geos::geom::MultiPolygon *footprint = PolygonTools::MakeMultiPolygon(
340 poly.Polys()->clone().release());
341
342 geos::geom::Geometry *envelope = footprint->getEnvelope().release();
343 geos::geom::CoordinateSequence *coords = envelope->getCoordinates().release();
344
345 for (unsigned int i = 0; i < coords->getSize(); i++) {
346 const geos::geom::Coordinate &coord = coords->getAt(i);
347
348 Latitude coordLat(coord.y, Angle::Degrees);
349 Longitude coordLon(coord.x, Angle::Degrees);
350
351 if (!minLat.isValid() || minLat > coordLat)
352 minLat = coordLat;
353 if (!maxLat.isValid() || maxLat < coordLat)
354 maxLat = coordLat;
355
356 if (!minLon.isValid() || minLon > coordLon)
357 minLon = coordLon;
358 if (!maxLon.isValid() || maxLon < coordLon)
359 maxLon = coordLon;
360 }
361
362 delete coords;
363 coords = NULL;
364
365 delete envelope;
366 envelope = NULL;
367
368 delete footprint;
369 footprint = NULL;
370 }
371 }
372 catch (IException &) {
373 }
374
375 if (!minLat.isValid() || !maxLat.isValid() ||
376 !minLon.isValid() || !maxLon.isValid()) {
377 if (HasCamera()) {
378 // Footprint failed, ask the camera
379 PvlGroup mappingGrp("Mapping");
380 mappingGrp += PvlKeyword("LatitudeType", "Planetocentric");
381 mappingGrp += PvlKeyword("LongitudeDomain", "360");
382 mappingGrp += PvlKeyword("LongitudeDirection", "PositiveEast");
383
384 Pvl mappingPvl;
385 mappingPvl += mappingGrp;
386 double minLatDouble;
387 double maxLatDouble;
388 double minLonDouble;
389 double maxLonDouble;
390 p_camera->GroundRange(
391 minLatDouble, maxLatDouble,
392 minLonDouble, maxLonDouble, mappingPvl);
393 minLat = Latitude(minLatDouble, Angle::Degrees);
394 maxLat = Latitude(maxLatDouble, Angle::Degrees);
395 minLon = Longitude(minLonDouble, Angle::Degrees);
396 maxLon = Longitude(maxLonDouble, Angle::Degrees);
397 }
398 else if (HasProjection()) {
399 // Footprint failed, look in the mapping group
400 PvlGroup mappingGrp = p_projection->Mapping();
401 if (mappingGrp.hasKeyword("MinimumLatitude") &&
402 mappingGrp.hasKeyword("MaximumLatitude") &&
403 mappingGrp.hasKeyword("MinimumLongitude") &&
404 mappingGrp.hasKeyword("MaximumLongitude")) {
405
406 minLat = Latitude(mappingGrp["MinimumLatitude"],
407 mappingGrp, Angle::Degrees);
408 maxLat = Latitude(mappingGrp["MaximumLatitude"],
409 mappingGrp, Angle::Degrees);
410 minLon = Longitude(mappingGrp["MinimumLongitude"],
411 mappingGrp, Angle::Degrees);
412 maxLon = Longitude(mappingGrp["MaximumLongitude"],
413 mappingGrp, Angle::Degrees);
414
415 }
416 else if (allowEstimation && cube) {
417 // Footprint and mapping failed... no lat/lon range of any kind is
418 // available. Let's test points in the image to try to make our own
419 // extent.
420 QList<QPointF> imagePoints;
421
422 // Reset to TProjection
424
425 /*
426 * This is where we're testing:
427 *
428 * |---------------|
429 * |***************|
430 * |** * **|
431 * |* * * * *|
432 * |* * * * *|
433 * |***************|
434 * |* * * * *|
435 * |* * * * *|
436 * |** * **|
437 * |***************|
438 * |---------------|
439 *
440 * We'll test at the edges, a plus (+) and an (X) to help DEMs work.
441 */
442
443 int sampleCount = cube->sampleCount();
444 int lineCount = cube->lineCount();
445
446 int stepsPerLength = 20; //number of steps per length
447 double aspectRatio = (double)lineCount / (double)sampleCount;
448 double xStepSize = sampleCount / stepsPerLength;
449 double yStepSize = xStepSize * aspectRatio;
450
451 if (lineCount > sampleCount) {
452 aspectRatio = (double)sampleCount / (double)lineCount;
453 yStepSize = lineCount / stepsPerLength;
454 xStepSize = yStepSize * aspectRatio;
455 }
456
457 double yWalked = 0.5;
458
459 //3 vertical lines
460 for (int i = 0; i < 3; i++) {
461 double xValue = 0.5 + ( i * (sampleCount / 2) );
462
463 while (yWalked <= lineCount) {
464 imagePoints.append( QPointF(xValue, yWalked) );
465 yWalked += yStepSize;
466 }
467
468 yWalked = 0.5;
469 }
470
471 double xWalked = 0.5;
472
473 //3 horizontal lines
474 for (int i = 0; i < 3; i++) {
475 double yValue = 0.5 + ( i * (lineCount / 2) );
476
477 while (xWalked <= sampleCount) {
478 imagePoints.append( QPointF(xWalked, yValue) );
479 xWalked += xStepSize;
480 }
481
482 xWalked = 0.5;
483 }
484
485 double xDiagonalWalked = 0.5;
486 double yDiagonalWalked = 0.5;
487 xStepSize = sampleCount / stepsPerLength;
488 yStepSize = lineCount / stepsPerLength;
489
490 //Top-Down Diagonal
491 while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked <= lineCount) ) {
492 imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) );
493 xDiagonalWalked += xStepSize;
494 yDiagonalWalked += yStepSize;
495 }
496
497 xDiagonalWalked = 0.5;
498
499 //Bottom-Up Diagonal
500 while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked >= 0) ) {
501 imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) );
502 xDiagonalWalked += xStepSize;
503 yDiagonalWalked -= yStepSize;
504 }
505
506 foreach (QPointF imagePoint, imagePoints) {
507 if (tproj->SetWorld(imagePoint.x(), imagePoint.y())) {
508 Latitude latResult(tproj->UniversalLatitude(),
510 Longitude lonResult(tproj->UniversalLongitude(),
512 if (minLat.isValid())
513 minLat = qMin(minLat, latResult);
514 else
515 minLat = latResult;
516
517 if (maxLat.isValid())
518 maxLat = qMax(maxLat, latResult);
519 else
520 maxLat = latResult;
521
522 if (minLon.isValid())
523 minLon = qMin(minLon, lonResult);
524 else
525 minLon = lonResult;
526
527 if (maxLon.isValid())
528 maxLon = qMax(maxLon, lonResult);
529 else
530 maxLon = lonResult;
531 }
532 }
533 }
534 }
535 }
536
537 return (minLat.isValid() && maxLat.isValid() &&
538 minLon.isValid() && maxLon.isValid() &&
539 minLat < maxLat && minLon < maxLon);
540 }
541}
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid,...
Definition Angle.cpp:95
double degrees() const
Get the angle in units of Degrees.
Definition Angle.h:232
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition Angle.h:56
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
IO Handler for Isis Cubes.
Definition Cube.h:168
ImagePolygon readFootprint() const
Read the footprint polygon for the Cube.
Definition Cube.cpp:879
int lineCount() const
Definition Cube.cpp:1767
int sampleCount() const
Definition Cube.cpp:1840
virtual QString fileName() const
Returns the opened cube's filename.
Definition Cube.cpp:1596
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1734
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
void append(const IException &exceptionSource)
Appends the given exception (and its list of previous exceptions) to this exception's causational exc...
Create cube polygons, read/write polygons to blobs.
geos::geom::MultiPolygon * Polys()
Return a geos Multipolygon.
This class is designed to encapsulate the concept of a Latitude.
Definition Latitude.h:51
This class is designed to encapsulate the concept of a Longitude.
Definition Longitude.h:40
static geos::geom::MultiPolygon * MakeMultiPolygon(const geos::geom::Geometry *geom)
Make a geos::geom::MultiPolygon out of the components of the argument.
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
ProjectionType
This enum defines the subclasses of Projection supported in Isis.
Definition Projection.h:166
@ Triaxial
These projections are used to map triaxial and irregular-shaped bodies.
Definition Projection.h:166
@ RingPlane
These projections are used to map ring planes.
Definition Projection.h:168
virtual bool SetWorld(const double x, const double y)
This method is used to set a world coordinate.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
Base class for Map Projections of plane shapes.
double RingRadius() const
This returns a radius.
double RingLongitude() const
This returns a ring longitude with correct ring longitude direction and domain as specified in the la...
This class defines a body-fixed surface point.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Base class for Map TProjections.
virtual double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain).
virtual double UniversalLatitude()
This returns a universal latitude (planetocentric).
Isis::Projection * p_projection
The projection (if the image is projected)
double Sample() const
Returns the current line value of the camera model or projection.
double UniversalLongitude() const
Returns the universal longitude of the camera model or projection.
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection.
double Resolution() const
Returns the resolution of the camera model or projection.
~UniversalGroundMap()
Destroys the UniversalGroundMap object.
void SetBand(const int band)
Set the image band number.
Isis::Camera * p_camera
The camera (if the image has a camera)
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
bool SetUnboundGround(Latitude lat, Longitude lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
double Line() const
Returns the current line value of the camera model or projection.
bool HasProjection()
Returns whether the ground map has a projection or not.
CameraPriority
This enum is used to define whether to use a camera or projection primarily, and which to fall back o...
@ CameraFirst
This is the default because cameras are projection-aware.
bool HasCamera()
Returns whether the ground map has a camera or not.
UniversalGroundMap(Cube &cube, CameraPriority priority=CameraFirst)
Constructs a UniversalGroundMap object from a cube.
bool SetUniversalGround(double lat, double lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
bool SetGround(Latitude lat, Longitude lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
bool GroundRange(Cube *cube, Latitude &minLat, Latitude &maxLat, Longitude &minLon, Longitude &maxLon, bool allowEstimation=true)
Find the lat/lon range of the image.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16