Isis 3 Programmer Reference
ProcessGroundPolygons.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "ProcessGroundPolygons.h"
8 
9 #include <vector>
10 
11 #include "geos/geom/CoordinateSequence.h"
12 #include "geos/geom/CoordinateArraySequence.h"
13 #include "geos/geom/LineString.h"
14 #include "geos/geosAlgorithm.h"
15 
16 #include "Application.h"
17 #include "BoxcarCachingAlgorithm.h"
18 #include "IException.h"
19 #include "PolygonTools.h"
20 #include "Projection.h"
21 
22 using namespace std;
23 namespace Isis {
24 
25  ProcessGroundPolygons::ProcessGroundPolygons() {
26  p_groundMap = NULL;
27  }
28 
29 
40  void ProcessGroundPolygons::Rasterize(std::vector<double> &lat,
41  std::vector<double> &lon,
42  std::vector<double> &values) {
43 
44  // Decide if we need to split the poly on the 360 boundry
45  // Yes, we can do this better. The lat and lon vectors should be passed in as polygons, but
46  // for now this is reusing older code.
47  bool crosses = false;
48  for (unsigned int i = 0; i < lon.size() - 1; i++) {
49  if (fabs(lon[i] - lon[i+1]) > 180.0) {
50  crosses = true;
51  break;
52  }
53  }
54 
55  if (crosses) {
56  // Make a polygon from the lat/lon vectors and split it on 360
57  geos::geom::CoordinateSequence *pts = new geos::geom::CoordinateArraySequence();
58  for (unsigned int i = 0; i < lat.size(); i++) {
59  pts->add(geos::geom::Coordinate(lon[i], lat[i]));
60  }
61  pts->add(geos::geom::Coordinate(lon[0], lat[0]));
62 
63  geos::geom::Polygon *crossingPoly = Isis::globalFactory->createPolygon(
64  globalFactory->createLinearRing(pts), NULL);
65 
66  geos::geom::MultiPolygon *splitPoly = NULL;
67  try {
68  splitPoly = PolygonTools::SplitPolygonOn360(crossingPoly);
69  }
70  // Ignore any pixel footprints that could not be split. This should only be pixels
71  // that contain the pole.
72  catch (IException &) {
73  // See leading comment
74  }
75 
76  delete crossingPoly;
77 
78  if (splitPoly != NULL) {
79  // Process the polygons in the split multipolygon as if we were still using the lat/lon vectors
80  for (unsigned int g = 0; g < splitPoly->getNumGeometries(); ++g) {
81  const geos::geom::Polygon *poly =
82  dynamic_cast<const geos::geom::Polygon *>(splitPoly->getGeometryN(g));
83 
84  geos::geom::CoordinateSequence *llcoords = poly->getExteriorRing()->getCoordinates();
85 
86  // Move each coordinate in the exterior ring of this lat/lon polygon to vectors
87  // Ignore any holes in the polygon
88  std::vector<double> tlat;
89  std::vector<double> tlon;
90  for (unsigned int cord = 0; cord < llcoords->getSize() - 1; ++cord) {
91  tlon.push_back(llcoords->getAt(cord).x);
92  tlat.push_back(llcoords->getAt(cord).y);
93  }
94 
95  Convert(tlat, tlon);
96  ProcessPolygons::Rasterize(p_samples, p_lines, values);
97  }
98  delete splitPoly;
99  }
100  }
101  else {
102  Convert(lat, lon);
103  ProcessPolygons::Rasterize(p_samples, p_lines, values);
104  }
105  }
106 
107 
118  void ProcessGroundPolygons::Rasterize(std::vector<double> &lat,
119  std::vector<double> &lon,
120  int &band, double &value) {
121 
122  Convert(lat, lon);
123  ProcessPolygons::Rasterize(p_samples, p_lines, band, value);
124  }
125 
126 
134  void ProcessGroundPolygons::Convert(std::vector<double> &lat,
135  std::vector<double> &lon) {
136 
137  p_samples.clear();
138  p_lines.clear();
139 
140  for (unsigned int i = 0; i < lat.size(); i++) {
141  if (p_groundMap->SetUniversalGround(lat[i], lon[i])) {
142  p_samples.push_back(p_groundMap->Sample());
143  p_lines.push_back(p_groundMap->Line());
144  }
145  }
146  }
147 
148 
156  void ProcessGroundPolygons::EndProcess() {
157 
158  if(p_groundMap != NULL) {
159  delete p_groundMap;
160  }
161 
162  ProcessPolygons::EndProcess();
163  }
164 
165 
172  void ProcessGroundPolygons::Finalize() {
173 
174  if(p_groundMap != NULL) {
175  delete p_groundMap;
176  }
177 
178  ProcessPolygons::Finalize();
179  }
180 
181 
189  void ProcessGroundPolygons::AppendOutputCube(QString &cubeStr,
190  const QString &avgFileName,
191  const QString &countFileName) {
192  /*We need a ground map for converting lat/long to line/sample see Convert()*/
193  Cube cube(cubeStr, "r");
194  p_groundMap = new UniversalGroundMap(cube);
195  ProcessPolygons::AppendOutputCube(avgFileName, countFileName);
196 
197  }
198 
199 
209  void ProcessGroundPolygons::SetStatCubes(const QString &avgFileName,
210  const QString &countFileName,
211  Isis::CubeAttributeOutput &outAtts,
212  QString &cubeStr) {
213  /*We need a ground map for converting lat/long to line/sample see Convert()*/
214  Cube cube(cubeStr);
215  p_groundMap = new UniversalGroundMap(cube);
216 
217  /*setup input cube to transfer projection or camera labels*/
218  CubeAttributeInput inAtts;
219  Isis::Process::SetInputCube(cubeStr, inAtts, 0);
220  int nBands = this->InputCubes[0]->bandCount();
221  int nLines = this->InputCubes[0]->lineCount();
222  int nSamples = this->InputCubes[0]->sampleCount();
223 
224  this->Process::SetOutputCube(avgFileName, outAtts, nSamples, nLines, nBands);
225  this->Process::SetOutputCube(countFileName, outAtts, nSamples, nLines, nBands);
226 
227  OutputCubes[0]->addCachingAlgorithm(new BoxcarCachingAlgorithm());
228  OutputCubes[1]->addCachingAlgorithm(new BoxcarCachingAlgorithm());
229 
230  ClearInputCubes();
231 
232  }
233 
234 
244  void ProcessGroundPolygons::SetStatCubes(const QString &parameter,
245  QString &cube) {
246 
247  QString avgString =
248  Application::GetUserInterface().GetFileName(parameter);
249  CubeAttributeOutput atts =
250  Application::GetUserInterface().GetOutputAttribute(parameter);
251 
252  FileName file(avgString);
253  QString path = file.path();
254  QString filename = file.baseName();
255  QString countString = path + "/" + filename + "-count-";
256 
257  SetStatCubes(avgString, countString, atts, cube);
258 
259  }
260 
261 
269  void ProcessGroundPolygons::SetStatCubes(const QString &parameter,
270  Isis::Pvl &map, int bands) {
271 
272  QString avgString =
273  Application::GetUserInterface().GetFileName(parameter);
274  CubeAttributeOutput atts =
275  Application::GetUserInterface().GetOutputAttribute(parameter);
276 
277  FileName file(avgString);
278  QString path = file.path();
279  QString filename = file.baseName();
280  QString countString = path + "/" + filename + "-count-";
281 
282  SetStatCubes(avgString, countString, atts, map, bands);
283 
284  }
285 
286 
301  void ProcessGroundPolygons::SetStatCubes(const QString &avgFileName,
302  const QString &countFileName,
304  Isis::Pvl &map, int bands) {
305  int samples, lines;
306 
307  Projection *proj = ProjectionFactory::CreateForCube(map, samples, lines,
308  false);
309 
310  this->ProcessPolygons::SetStatCubes(avgFileName, countFileName, atts,
311  samples, lines, bands);
312 
313  OutputCubes[0]->addCachingAlgorithm(new BoxcarCachingAlgorithm());
314  OutputCubes[1]->addCachingAlgorithm(new BoxcarCachingAlgorithm());
315 
316  /*Write the pvl group to the cube files.*/
317 
318  PvlGroup group = map.findGroup("Mapping", Pvl::Traverse);
319 
320  OutputCubes[0]->putGroup(group);
321  OutputCubes[1]->putGroup(group);
322 
323  // If there is an alpha cube in the label passed, attach to output cubes
324  if (map.hasGroup("AlphaCube")) {
325  PvlGroup alpha = map.findGroup("AlphaCube", Pvl::Traverse);
326  OutputCubes[0]->putGroup(alpha);
327  OutputCubes[1]->putGroup(alpha);
328  }
329 
330  /*We need a ground map for converting lat/long to line/sample see Convert()*/
331  p_groundMap = new UniversalGroundMap(*OutputCubes[0]);
332 
333  delete proj;
334  }
335 
336 } /* end namespace isis*/
337 
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::UniversalGroundMap
Universal Ground Map.
Definition: UniversalGroundMap.h:69
Isis::BoxcarCachingAlgorithm
This algorithm is designed for applications that jump around between a couple of spots in the cube wi...
Definition: BoxcarCachingAlgorithm.h:32
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::PvlObject::hasGroup
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition: PvlObject.h:210
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::CubeAttributeOutput
Manipulate and parse attributes of output cube filenames.
Definition: CubeAttribute.h:473
Isis::FileName::baseName
QString baseName() const
Returns the name of the file without the path and without extensions.
Definition: FileName.cpp:145
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Process::SetInputCube
virtual Isis::Cube * SetInputCube(const QString &parameter, const int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
Definition: Process.cpp:136
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::IException
Isis exception class.
Definition: IException.h:91
std
Namespace for the standard library.
Isis::CubeAttributeInput
Manipulate and parse attributes of input cube filenames.
Definition: CubeAttribute.h:381
Isis::Projection
Base class for Map Projections.
Definition: Projection.h:155
Isis::FileName::path
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:103
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16