Isis 3 Programmer Reference
Shape.cpp
1 #include "Shape.h"
2 
3 #include <QBuffer>
4 #include <QDataStream>
5 #include <QDebug>
6 #include <QDir>
7 #include <QFileInfo>
8 #include <QMessageBox>
9 #include <QMutexLocker>
10 #include <QScopedPointer>
11 #include <QString>
12 #include <QUuid>
13 #include <QXmlStreamWriter>
14 
15 #include <geos/geom/MultiPolygon.h>
16 #include <geos/io/WKTReader.h>
17 #include <geos/io/WKTWriter.h>
18 
19 #include "Angle.h"
20 #include "CameraFactory.h"
21 #include "ControlPoint.h"
22 #include "Cube.h"
23 #include "CubeAttribute.h"
24 #include "DisplayProperties.h"
25 #include "Distance.h"
26 #include "FileName.h"
27 #include "IException.h"
28 #include "ImagePolygon.h"
29 #include "IString.h"
30 #include "PolygonTools.h"
31 #include "Project.h"
32 #include "ProjectionFactory.h"
33 #include "SerialNumber.h"
34 #include "ShapeDisplayProperties.h"
35 #include "Target.h"
36 #include "XmlStackedHandlerReader.h"
37 
38 namespace Isis {
45  Shape::Shape(QString imageFileName, QObject *parent) : QObject(parent) {
46 
47  m_fileName = imageFileName;
48 
49  initMemberData();
50  cube();
51  initShape();
52  }
53 
54 
61  Shape::Shape(Cube *shapeCube, QObject *parent) : QObject(parent) {
62 
63  m_fileName = shapeCube->fileName();
64 
65  initMemberData();
66  m_cube = shapeCube;
67  initShape();
68  }
69 
70 
78  Shape::Shape(FileName shapeFolder, XmlStackedHandlerReader *xmlReader, QObject *parent) :
79  QObject(parent) {
80 
81  initMemberData();
82  xmlReader->pushContentHandler(new XmlHandler(this, shapeFolder));
83  }
84 
85 
90  delete m_bodyCode;
91  m_bodyCode = NULL;
92 
93  delete m_cube;
94  m_cube = NULL;
95 
96  delete m_footprint;
97  m_footprint = NULL;
98 
99  delete m_id;
100  m_id = NULL;
101 
102  // Shape is a "Qt" parent of display properties, so the Shape QObject
103  // destructor will take care of deleting the display props. See call to
104  // DisplayProperties' constructor.
105  m_displayProperties = NULL;
106  }
107 
108 
109  void Shape::initMemberData() {
110 
111  m_bodyCode = NULL;
112  m_cube = NULL;
113  m_displayProperties = NULL;
114  m_footprint = NULL;
115  m_id = NULL;
116 
117  m_aspectRatio = Null;
118  m_resolution = Null;
119  m_lineResolution = Null;
120  m_sampleResolution = Null;
121 
122  m_targetName = Null;
123  m_projectionName = Null;
124  m_pixelResolution = Null;
125  m_scale = Null;
126  }
127 
128 
129  void Shape::initShape() {
130 
131  m_displayProperties = new ShapeDisplayProperties(FileName(m_fileName).name(), this);
132  m_id = new QUuid(QUuid::createUuid());
134 
135  m_radiusSource = ControlPoint::RadiusSource::None;
136 
137  if (cube()->hasTable("ShapeModelStatistics")) {
138  m_surfacePointSource = ControlPoint::SurfacePointSource::Basemap;
139  m_radiusSource = ControlPoint::RadiusSource::DEM;
140  m_shapeType = Dem;
141  }
142  // Is this a level 1 or level 2?
143  else {
144  try {
146  m_surfacePointSource = ControlPoint::SurfacePointSource::Basemap;
147  m_radiusSource = ControlPoint::RadiusSource::Ellipsoid;
148  m_shapeType = Basemap;
149  }
150  catch (IException &) {
151  // TODO Determine if unprojected shape has been bundle adjusted. Otherwise, ??
152  try {
154  m_surfacePointSource = ControlPoint::SurfacePointSource::Reference;
155 
156  PvlGroup kernels = cube()->group("Kernels");
157  if (kernels.hasKeyword("ShapeModel")) {
158  QString shapeFile = kernels["ShapeModel"];
159  if (shapeFile.contains("dem")) {
160  m_radiusSource = ControlPoint::RadiusSource::DEM;
161  }
162  else {
163  m_radiusSource = ControlPoint::RadiusSource::Ellipsoid;
164  }
165  }
166  m_shapeType = Unprojected;
167  }
168  catch (IException &e) {
169  m_surfacePointSource = ControlPoint::SurfacePointSource::None;
170  m_radiusSource = ControlPoint::RadiusSource::None;
171  m_shapeType = Unknown;
172  QString message = "Cannot create either Camera or Projections "
173  "for the ground source file [" + displayProperties()->displayName() + "]. "
174  "Check the validity of the cube labels. The cube must either be projected or "
175  " run through spiceinit.";
176  throw IException(e, IException::Io, message, _FILEINFO_);
177  }
178  }
179  }
180 
181  try {
182  if (m_shapeType == Unprojected) {
183  initCamStats();
184  }
185  else if (m_shapeType == Basemap || m_shapeType == Dem) {
186  initMapStats();
187  if (m_shapeType == Dem) {
188  initDemStats();
189  }
190  }
191  }
192  catch (IException &e) {
193  QString message = "Cannot initialize the camera, map or dem statistics for this shape file [" +
194  displayProperties()->displayName() + "]. Check the validity of the cube labels. The "
195  "cube must either be projected or run through spiceinit. \n";
196  message += e.toString();
197  QMessageBox::warning((QWidget *) parent(), "Warning", message);
198  }
199 
200  try {
201  initQuickFootprint();
202  }
203  catch (IException &e) {
204 
205  }
206  }
207 
208 
209  ControlPoint::SurfacePointSource::Source Shape::surfacePointSource() {
210  return m_surfacePointSource;
211  }
212 
213 
214  ControlPoint::RadiusSource::Source Shape::radiusSource() {
215  return m_radiusSource;
216  }
217 
218 
219  Shape::ShapeType Shape::shapeType() {
220  return m_shapeType;
221  }
222 
223 
236  void Shape::fromPvl(const PvlObject &pvl) {
237  QString pvlFileName = ((IString)pvl["FileName"][0]).ToQt();
238  if (m_fileName != pvlFileName) {
240  tr("Tried to load Shape [%1] with properties/information from [%2].")
241  .arg(m_fileName).arg(pvlFileName),
242  _FILEINFO_);
243  }
244 
245  displayProperties()->fromPvl(pvl.findObject("DisplayProperties"));
246 
247  if (pvl.hasKeyword("ID")) {
248  QByteArray hexValues(pvl["ID"][0].toLatin1());
249  QDataStream valuesStream(QByteArray::fromHex(hexValues));
250  valuesStream >> *m_id;
251  }
252  }
253 
254 
269  PvlObject output("Shape");
270 
271  output += PvlKeyword("FileName", m_fileName);
272 
273  // Do m_id
274  QBuffer dataBuffer;
275  dataBuffer.open(QIODevice::ReadWrite);
276 
277  QDataStream idStream(&dataBuffer);
278  idStream << *m_id;
279 
280  dataBuffer.seek(0);
281 
282  output += PvlKeyword("ID", QString(dataBuffer.data().toHex()));
283 
284  output += displayProperties()->toPvl();
285 
286  return output;
287  }
288 
289 
294  bool Shape::isFootprintable() const {
295  bool result = false;
296 
297  if (m_footprint)
298  result = true;
299 
300  if (!result && m_cube) {
301  Blob example = ImagePolygon().toBlob();
302 
303  QString blobType = example.Type();
304  QString blobName = example.Name();
305 
306  Pvl &labels = *m_cube->label();
307 
308  for (int i = 0; i < labels.objects(); i++) {
309  PvlObject &obj = labels.object(i);
310 
311  if (obj.isNamed(blobType) && obj.hasKeyword("Name") && obj["Name"][0] == blobName)
312  result = true;
313  }
314  }
315 
316  return result;
317  }
318 
319 
325  if (!m_cube) {
326  try {
327  m_cube = new Cube(m_fileName);
328  }
329  catch (IException &e) {
330  throw IException(e, IException::Programmer, "Cube cannot be created", _FILEINFO_);
331  }
332  }
333 
334  return m_cube;
335  }
336 
337 
343  if (m_cube) {
344  delete m_cube;
345  m_cube = NULL;
346  }
347  }
348 
349 
356  return m_displayProperties;
357  }
358 
359 
367  return m_displayProperties;
368  }
369 
370 
376  QString Shape::fileName() const {
377  return m_fileName;
378  }
379 
380 
386  return m_serialNumber;
387  }
388 
394  geos::geom::MultiPolygon *Shape::footprint() {
395  return m_footprint;
396  }
397 
398 
402  void Shape::setId(QString id) {
403  *m_id = QUuid(QString("{%1}").arg(id));
404  }
405 
406 
412  const geos::geom::MultiPolygon *Shape::footprint() const {
413  return m_footprint;
414  }
415 
416 
421  bool Shape::initFootprint(QMutex *cameraMutex) {
422  if (!m_footprint) {
423  try {
424  initQuickFootprint();
425  }
426  catch (IException &e) {
427  try {
428  m_footprint = createFootprint(cameraMutex);
429  }
430  catch(IException &e) {
431  IString msg = "Could not read the footprint from cube [" +
432  displayProperties()->displayName() + "]. Please make "
433  "sure footprintinit has been run";
434  throw IException(e, IException::Io, msg, _FILEINFO_);
435  }
436  }
437  }
438 
439  // I'm not sure how this could ever be NULL. -SL
440  return (m_footprint != NULL);
441  }
442 
443 
449  double Shape::aspectRatio() const {
450  return m_aspectRatio;
451  }
452 
453 
459  QString Shape::id() const {
460  return m_id->toString().remove(QRegExp("[{}]"));
461  }
462 
463 
470  double Shape::resolution() const {
471  return m_resolution;
472  }
473 
474 
482  return m_emissionAngle;
483  }
484 
485 
493  return m_incidenceAngle;
494  }
495 
496 
503  double Shape::lineResolution() const {
504  return m_lineResolution;
505  }
506 
507 
515  return m_localRadius;
516  }
517 
518 
526  return m_northAzimuth;
527  }
528 
529 
537  return m_phaseAngle;
538  }
539 
540 
547  double Shape::sampleResolution() const {
548  return m_sampleResolution;
549  }
550 
551 
555  void Shape::copyToNewProjectRoot(const Project *project, FileName newProjectRoot) {
556  if (FileName(newProjectRoot) != FileName(project->projectRoot())) {
557  Cube origShape(m_fileName);
558 
559  FileName newExternalLabelFileName(Project::shapeDataRoot(newProjectRoot.toString()) + "/" +
560  FileName(m_fileName).dir().dirName() + "/" + FileName(m_fileName).name());
561 
562  QScopedPointer<Cube> newExternalLabel(
563  origShape.copy(newExternalLabelFileName, CubeAttributeOutput("+External")));
564 
565  // If this is an ecub (it should be) and is pointing to a relative file name,
566  // then we want to copy the DN cube also.
567  if (!origShape.storesDnData()) {
568  if (origShape.externalCubeFileName().path() == ".") {
569  Cube dnFile(
570  FileName(m_fileName).path() + "/" + origShape.externalCubeFileName().name());
571 
572  FileName newDnFileName = newExternalLabelFileName.setExtension("cub");
573 
574  QScopedPointer<Cube> newDnFile(dnFile.copy(newDnFileName, CubeAttributeOutput()));
575  newDnFile->close();
576 
577  newExternalLabel->relocateDnData(newDnFileName.name());
578  }
579  else {
580  newExternalLabel->relocateDnData(origShape.externalCubeFileName());
581  }
582  }
583  }
584  }
585 
586 
592  bool deleteCubAlso = (cube()->externalCubeFileName().path() == ".");
593  closeCube();
594 
595  if (!QFile::remove(m_fileName)) {
597  tr("Could not remove file [%1]").arg(m_fileName),
598  _FILEINFO_);
599  }
600 
601  if (deleteCubAlso) {
602  FileName cubFile = FileName(m_fileName).setExtension("cub");
603  if (!QFile::remove(cubFile.expanded())) {
605  tr("Could not remove file [%1]").arg(m_fileName),
606  _FILEINFO_);
607  }
608  }
609 
610  // If we're the last thing in the folder, remove the folder too.
611  QDir dir;
612  dir.rmdir(FileName(m_fileName).path());
613  }
614 
615 
623  closeCube();
624 
625  FileName original(m_fileName);
626  FileName newName(project->shapeDataRoot() + "/" +
627  original.dir().dirName() + "/" + original.name());
628  m_fileName = newName.expanded();
629  }
630 
631 
638  geos::geom::MultiPolygon *Shape::createFootprint(QMutex *cameraMutex) {
639  QMutexLocker lock(cameraMutex);
640 
641  // We need to walk the shape to create the polygon...
642  ImagePolygon imgPoly;
643 
644  int sampleStepSize = cube()->sampleCount() / 10;
645  if (sampleStepSize <= 0) sampleStepSize = 1;
646 
647  int lineStepSize = cube()->lineCount() / 10;
648  if (lineStepSize <= 0) lineStepSize = 1;
649 
650  imgPoly.Create(*cube(), sampleStepSize, lineStepSize);
651 
653  tr("Warning: Polygon re-calculated for [%1] which can be very slow")
654  .arg(displayProperties()->displayName()),
655  _FILEINFO_);
656  e.print();
657 
658  return PolygonTools::MakeMultiPolygon(imgPoly.Polys()->clone());
659  }
660 
661 
666  bool hasCamStats = false;
667 
668  Pvl &label = *cube()->label();
669  for (int i = 0; !hasCamStats && i < label.objects(); i++) {
670  PvlObject &obj = label.object(i);
671 
672  try {
673  if (obj.name() == "Table") {
674  if (obj["Name"][0] == "CameraStatistics") {
675  hasCamStats = true;
676  }
677  }
678  }
679  catch (IException &e) {
680  e.print();
681  }
682  }
683 
684  if (hasCamStats) {
685  Table camStatsTable("CameraStatistics", m_fileName, label);
686 
687  int numRecords = camStatsTable.Records();
688  for (int recordIndex = 0; recordIndex < numRecords; recordIndex++) {
689  TableRecord &record = camStatsTable[recordIndex];
690 
691  // The TableField class gives us a std::string with NULL (\0) characters... be careful not
692  // to keep them when going to QString.
693  QString recordName((QString)record["Name"]);
694  double avgValue = (double)record["Average"];
695 
696  if (recordName == "AspectRatio") {
697  m_aspectRatio = avgValue;
698  }
699  else if (recordName == "Resolution") {
700  m_resolution = avgValue;
701  }
702  else if (recordName == "EmissionAngle") {
703  m_emissionAngle = Angle(avgValue, Angle::Degrees);
704  }
705  else if (recordName == "IncidenceAngle") {
706  m_incidenceAngle = Angle(avgValue, Angle::Degrees);
707  }
708  else if (recordName == "LineResolution") {
709  m_lineResolution = avgValue;
710  }
711  else if (recordName == "LocalRadius") {
712  m_localRadius = Distance(avgValue, Distance::Meters);
713  }
714  else if (recordName == "NorthAzimuth") {
715  m_northAzimuth = Angle(avgValue, Angle::Degrees);
716  }
717  else if (recordName == "PhaseAngle") {
718  m_phaseAngle = Angle(avgValue, Angle::Degrees);
719  }
720  else if (recordName == "SampleResolution") {
721  m_sampleResolution = avgValue;
722  }
723  }
724  }
725 
726  for (int i = 0; i < label.objects(); i++) {
727  PvlObject &obj = label.object(i);
728  try {
729  if (obj.hasGroup("Instrument")) {
730  PvlGroup instGroup = obj.findGroup("Instrument");
731 
732  if (instGroup.hasKeyword("SpacecraftName"))
733  m_spacecraftName = obj.findGroup("Instrument")["SpacecraftName"][0];
734 
735  if (instGroup.hasKeyword("InstrumentId"))
736  m_instrumentId = obj.findGroup("Instrument")["InstrumentId"][0];
737  }
738  }
739  catch (IException &e) {
740  e.print();
741  }
742  }
743  }
744 
745 
746  void Shape::initMapStats() {
747 
748  Pvl &label = *cube()->label();
749  for (int i = 0; i < label.objects(); i++) {
750  PvlObject &obj = label.object(i);
751  try {
752  if (obj.hasGroup("Instrument")) {
753  PvlGroup instGroup = obj.findGroup("Instrument");
754 
755  if (instGroup.hasKeyword("SpacecraftName"))
756  m_spacecraftName = obj.findGroup("Instrument")["SpacecraftName"][0];
757 
758  if (instGroup.hasKeyword("InstrumentId"))
759  m_instrumentId = obj.findGroup("Instrument")["InstrumentId"][0];
760  }
761 
762  if (obj.hasGroup("Mapping")) {
763  PvlGroup mapGroup = obj.findGroup("Mapping");
764 
765  if (mapGroup.hasKeyword("TargetName"))
766  m_targetName = obj.findGroup("Mapping")["TargetName"][0];
767 
768  if (mapGroup.hasKeyword("ProjectionName"))
769  m_projectionName = obj.findGroup("Mapping")["ProjectionName"][0];
770 
771  if (mapGroup.hasKeyword("CenterLongitude"))
772  m_centerLongitude = Longitude(toDouble(obj.findGroup("Mapping")["CenterLongitude"][0]),
773  mapGroup, Angle::Degrees);
774 
775  if (mapGroup.hasKeyword("CenterLatitude"))
776  m_centerLatitude = Latitude(toDouble(obj.findGroup("Mapping")["CenterLatitude"][0]),
777  mapGroup, Angle::Degrees);
778 
779  if (mapGroup.hasKeyword("MinimumLatitude"))
780  m_minimumLatitude = Latitude(toDouble(obj.findGroup("Mapping")["MinimumLatitude"][0]),
781  mapGroup, Angle::Degrees);
782 
783  if (mapGroup.hasKeyword("MaximumLatitude"))
784  m_maximumLatitude = Latitude(toDouble(obj.findGroup("Mapping")["MaximumLatitude"][0]),
785  mapGroup, Angle::Degrees);
786 
787  if (mapGroup.hasKeyword("MinimumLongitude"))
788  m_minimumLongitude = Longitude(toDouble(obj.findGroup("Mapping")["MinimumLongitude"][0]),
789  mapGroup, Angle::Degrees);
790 
791  if (mapGroup.hasKeyword("MaximumLongitude"))
792  m_maximumLongitude = Longitude(toDouble(obj.findGroup("Mapping")["MaximumLongitude"][0]),
793  mapGroup, Angle::Degrees);
794 
795  if (mapGroup.hasKeyword("PixelResolution"))
796  m_pixelResolution = obj.findGroup("Mapping")["PixelResolution"];
797 
798  if (mapGroup.hasKeyword("Scale"))
799  m_scale = obj.findGroup("Mapping")["Scale"];
800  }
801  }
802  catch (IException &e) {
803  e.print();
804  }
805  }
806  }
807 
808 
809  void Shape::initDemStats() {
810 
811 
812  }
813 
814 
815  void Shape::initQuickFootprint() {
816  ImagePolygon poly = cube()->readFootprint();
817  m_footprint = PolygonTools::MakeMultiPolygon(poly.Polys()->clone());
818  }
819 
820 
829  m_shape = shape;
830  m_shapeFolder = shapeFolder;
831  }
832 
833 
844  void Shape::save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot)
845  const {
846 
847  stream.writeStartElement("shape");
848 
849  stream.writeAttribute("id", m_id->toString());
850  stream.writeAttribute("fileName", FileName(m_fileName).name());
851  stream.writeAttribute("serialNumber", m_serialNumber);
852 
853  QString type;
854  if (m_shapeType == Unprojected) {
855  type = "Unprojected";
856  }
857  else if (m_shapeType == Basemap) {
858  type = "Basemap";
859  }
860  else {
861  type = "Dem";
862  }
863  stream.writeAttribute("shapeType", type);
864  stream.writeAttribute("surfacePointSource",
865  ControlPoint::SurfacePointSourceToString(m_surfacePointSource));
866  stream.writeAttribute("radiusSource",
867  ControlPoint::RadiusSourceToString(m_radiusSource));
868 
869  if (m_shapeType == Unprojected) {
870  stream.writeAttribute("instrumentId", m_instrumentId);
871  stream.writeAttribute("spacecraftName", m_spacecraftName);
872 
873  if (!IsSpecial(m_aspectRatio)) {
874  stream.writeAttribute("aspectRatio", IString(m_aspectRatio).ToQt());
875  }
876 
877  if (!IsSpecial(m_resolution)) {
878  stream.writeAttribute("resolution", IString(m_resolution).ToQt());
879  }
880 
881  if (m_emissionAngle.isValid()) {
882  stream.writeAttribute("emissionAngle", IString(m_emissionAngle.radians()).ToQt());
883  }
884 
885  if (m_incidenceAngle.isValid()) {
886  stream.writeAttribute("incidenceAngle", IString(m_incidenceAngle.radians()).ToQt());
887  }
888 
889  if (!IsSpecial(m_lineResolution)) {
890  stream.writeAttribute("lineResolution", IString(m_lineResolution).ToQt());
891  }
892 
893  if (m_localRadius.isValid()) {
894  stream.writeAttribute("localRadius", IString(m_localRadius.meters()).ToQt());
895  }
896 
897  if (m_northAzimuth.isValid()) {
898  stream.writeAttribute("northAzimuth", IString(m_northAzimuth.radians()).ToQt());
899  }
900 
901  if (m_phaseAngle.isValid()) {
902  stream.writeAttribute("phaseAngle", IString(m_phaseAngle.radians()).ToQt());
903  }
904 
905  if (!IsSpecial(m_sampleResolution)) {
906  stream.writeAttribute("sampleResolution", IString(m_sampleResolution).ToQt());
907  }
908  }
909  else if (m_shapeType == Basemap) {
910 
911  }
912  else if (m_shapeType == Dem) {
913 
914  }
915 
916  if (m_footprint) {
917  stream.writeStartElement("footprint");
918 
919  geos::io::WKTWriter wktWriter;
920  stream.writeCharacters(QString::fromStdString(wktWriter.write(m_footprint)));
921 
922  stream.writeEndElement();
923  }
924 
925  m_displayProperties->save(stream, project, newProjectRoot);
926 
927  stream.writeEndElement();
928  }
929 
930 
936  bool Shape::XmlHandler::startElement(const QString &namespaceURI, const QString &localName,
937  const QString &qName, const QXmlAttributes &atts) {
938  m_characters = "";
939 
940  if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
941  if (localName == "shape") {
942  QString id = atts.value("id");
943  QString fileName = atts.value("fileName");
944  m_shape->m_serialNumber = atts.value("serialNumber");
945 
946  if (!id.isEmpty()) {
947  delete m_shape->m_id;
948  m_shape->m_id = NULL;
949  m_shape->m_id = new QUuid(id.toLatin1());
950  }
951 
952  if (!fileName.isEmpty()) {
953  m_shape->m_fileName = m_shapeFolder.expanded() + "/" + fileName;
954  }
955 
956  if (m_shape->m_serialNumber.isEmpty()) {
957  m_shape->m_serialNumber = SerialNumber::Compose(*m_shape->cube(), true);
958  }
959 
960  m_shape->m_surfacePointSource =
961  ControlPoint::StringToSurfacePointSource(atts.value("surfacePointSource"));
962  m_shape->m_radiusSource =
963  ControlPoint::StringToRadiusSource(atts.value("radiusSource"));
964  QString shapeType = atts.value("shapeType");
965 
966  if (shapeType == "Unprojected") {
967  m_shape->m_shapeType = Unprojected;
968  QString instrumentId = atts.value("instrumentId");
969  QString spacecraftName = atts.value("spacecraftName");
970 
971  QString aspectRatioStr = atts.value("aspectRatio");
972  QString resolutionStr = atts.value("resolution");
973  QString emissionAngleStr = atts.value("emissionAngle");
974  QString incidenceAngleStr = atts.value("incidenceAngle");
975  QString lineResolutionStr = atts.value("lineResolution");
976  QString localRadiusStr = atts.value("localRadius");
977  QString northAzimuthStr = atts.value("northAzimuth");
978  QString phaseAngleStr = atts.value("phaseAngle");
979  QString sampleResolutionStr = atts.value("sampleResolution");
980 
981  if (!instrumentId.isEmpty()) {
982  m_shape->m_instrumentId = m_shapeFolder.expanded() + "/" + instrumentId;
983  }
984 
985  if (!instrumentId.isEmpty()) {
986  m_shape->m_instrumentId = m_shapeFolder.expanded() + "/" + instrumentId;
987  }
988 
989  if (!spacecraftName.isEmpty()) {
990  m_shape->m_spacecraftName = m_shapeFolder.expanded() + "/" + spacecraftName;
991  }
992 
993  if (!aspectRatioStr.isEmpty()) {
994  m_shape->m_aspectRatio = aspectRatioStr.toDouble();
995  }
996 
997  if (!resolutionStr.isEmpty()) {
998  m_shape->m_resolution = resolutionStr.toDouble();
999  }
1000 
1001  if (!emissionAngleStr.isEmpty()) {
1002  m_shape->m_emissionAngle = Angle(emissionAngleStr.toDouble(), Angle::Radians);
1003  }
1004 
1005  if (!incidenceAngleStr.isEmpty()) {
1006  m_shape->m_incidenceAngle = Angle(incidenceAngleStr.toDouble(), Angle::Radians);
1007  }
1008 
1009  if (!lineResolutionStr.isEmpty()) {
1010  m_shape->m_lineResolution = lineResolutionStr.toDouble();
1011  }
1012 
1013  if (!localRadiusStr.isEmpty()) {
1014  m_shape->m_localRadius = Distance(localRadiusStr.toDouble(), Distance::Meters);
1015  }
1016 
1017  if (!northAzimuthStr.isEmpty()) {
1018  m_shape->m_northAzimuth = Angle(northAzimuthStr.toDouble(), Angle::Radians);
1019  }
1020 
1021  if (!phaseAngleStr.isEmpty()) {
1022  m_shape->m_phaseAngle = Angle(phaseAngleStr.toDouble(), Angle::Radians);
1023  }
1024 
1025  if (!sampleResolutionStr.isEmpty()) {
1026  m_shape->m_sampleResolution = sampleResolutionStr.toDouble();
1027  }
1028  }
1029  else if (shapeType == "Basemap") {
1030  m_shape->m_shapeType = Basemap;
1031  }
1032  else if (shapeType == "Dem") {
1033  m_shape->m_shapeType = Dem;
1034  }
1035  else {
1036  m_shape->m_shapeType = Unknown;
1037  }
1038 
1039 
1040  }
1041  else if (localName == "displayProperties") {
1042  m_shape->m_displayProperties = new ShapeDisplayProperties(reader());
1043  }
1044  }
1045 
1046  return true;
1047  }
1048 
1049 
1050 
1051  bool Shape::XmlHandler::characters(const QString &ch) {
1052  m_characters += ch;
1053 
1054  return XmlStackedHandler::characters(ch);
1055  }
1056 
1057 
1058 
1059  bool Shape::XmlHandler::endElement(const QString &namespaceURI, const QString &localName,
1060  const QString &qName) {
1061  if (localName == "footprint" && !m_characters.isEmpty()) {
1062  geos::io::WKTReader wktReader(*globalFactory);
1063  try {
1064  m_shape->m_footprint = PolygonTools::MakeMultiPolygon(
1065  wktReader.read(m_characters.toStdString()));
1066  }
1067  catch (IException &e) {
1068  e.print();
1069  }
1070  }
1071  else if (localName == "shape" && !m_shape->m_footprint) {
1072  try {
1073  QMutex mutex;
1074  m_shape->initFootprint(&mutex);
1075  m_shape->closeCube();
1076  }
1077  catch (IException &e) {
1078  e.print();
1079  }
1080  }
1081 
1082  m_characters = "";
1083  return XmlStackedHandler::endElement(namespaceURI, localName, qName);
1084  }
1085 }
Isis::Shape::m_spacecraftName
QString m_spacecraftName
Spacecraft name associated with this Shape.
Definition: Shape.h:192
Isis::Angle::Degrees
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:56
Isis::CameraFactory::Create
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
Definition: CameraFactory.cpp:45
QWidget
Isis::Shape::setId
void setId(QString id)
Override the automatically generated ID with the given ID.
Definition: Shape.cpp:402
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::Cube::fileName
virtual QString fileName() const
Returns the opened cube's filename.
Definition: Cube.cpp:1563
Isis::IException::Io
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:155
Isis::Shape::displayProperties
ShapeDisplayProperties * displayProperties()
Get the display (GUI) properties (information) associated with this shape.
Definition: Shape.cpp:355
Isis::PvlObject
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:61
Isis::IException::print
void print() const
Prints a string representation of this exception to stderr.
Definition: IException.cpp:445
Isis::Shape::deleteFromDisk
void deleteFromDisk()
Delete the shape data from disk.
Definition: Shape.cpp:591
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::Cube::group
PvlGroup & group(const QString &group) const
Read a group from the cube into a Label.
Definition: Cube.cpp:1991
Project.h
Isis::Blob::Type
QString Type() const
Accessor method that returns a string containing the Blob type.
Definition: Blob.cpp:124
Isis::FileName::name
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:162
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::IException::Unknown
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:118
Isis::Cube::readFootprint
ImagePolygon readFootprint() const
Read the footprint polygon for the Cube.
Definition: Cube.cpp:866
Isis::XmlStackedHandlerReader::pushContentHandler
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
Definition: XmlStackedHandlerReader.cpp:55
Isis::ImagePolygon::toBlob
Blob toBlob() const
Serialize the ImagePolygon to a Blob.
Definition: ImagePolygon.cpp:1347
Isis::Shape::closeCube
void closeCube()
Cleans up the Cube *.
Definition: Shape.cpp:342
Isis::Shape::createFootprint
geos::geom::MultiPolygon * createFootprint(QMutex *cameraMutex)
Calculate a footprint for an Shape using the camera or projection information.
Definition: Shape.cpp:638
Isis::Shape::m_displayProperties
ShapeDisplayProperties * m_displayProperties
The GUI information for how this Shape ought to be displayed.
Definition: Shape.h:176
Isis::SerialNumber::Compose
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
Definition: SerialNumber.cpp:38
Isis::Cube::copy
Cube * copy(FileName newFile, const CubeAttributeOutput &newFileAttributes)
Copies the cube to the new fileName.
Definition: Cube.cpp:276
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::Project::shapeDataRoot
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name 'shapes' to the project .
Definition: Project.cpp:2087
Isis::Shape::footprint
geos::geom::MultiPolygon * footprint()
Get the footprint of this shape (if available).
Definition: Shape.cpp:394
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::ImagePolygon::Create
void Create(Cube &cube, int sinc=1, int linc=1, int ss=1, int sl=1, int ns=0, int nl=0, int band=1, bool increasePrecision=false)
Create a Polygon from given cube.
Definition: ImagePolygon.cpp:217
Isis::PvlObject::objects
int objects() const
Returns the number of objects.
Definition: PvlObject.h:219
Isis::CubeAttributeOutput
Manipulate and parse attributes of output cube filenames.
Definition: CubeAttribute.h:473
Isis::ShapeDisplayProperties::save
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Saves this object to an XML file.
Definition: ShapeDisplayProperties.cpp:124
Isis::Shape::incidenceAngle
Angle incidenceAngle() const
Get the incidence angle of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:492
Isis::ImagePolygon
Create cube polygons, read/write polygons to blobs.
Definition: ImagePolygon.h:153
Isis::Shape::isFootprintable
bool isFootprintable() const
Test to see if it's possible to create a footprint from this shape.
Definition: Shape.cpp:294
Isis::Shape::initCamStats
void initCamStats()
TODO.
Definition: Shape.cpp:665
Isis::Shape::cube
Cube * cube()
Get the Cube * associated with this display property.
Definition: Shape.cpp:324
Isis::PvlObject::object
PvlObject & object(const int index)
Return the object at the specified index.
Definition: PvlObject.cpp:489
Isis::TableRecord
Definition: TableRecord.h:38
Isis::Shape::northAzimuth
Angle northAzimuth() const
Get the north azimuth of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:525
Isis::XmlStackedHandlerReader
Manage a stack of content handlers for reading XML files.
Definition: XmlStackedHandlerReader.h:30
Isis::Shape::copyToNewProjectRoot
void copyToNewProjectRoot(const Project *project, FileName newProjectRoot)
Copy the cub/ecub files associated with this shape into the new project.
Definition: Shape.cpp:555
Isis::IsSpecial
bool IsSpecial(const double d)
Returns if the input pixel is special.
Definition: SpecialPixel.h:197
Isis::Blob::Name
QString Name() const
Accessor method that returns a string containing the Blob name.
Definition: Blob.cpp:133
Isis::Shape::toPvl
PvlObject toPvl() const
Convert this Shape to PVL.
Definition: Shape.cpp:268
Isis::Shape::m_serialNumber
QString m_serialNumber
This will always be simply the filename and is created on construction.
Definition: Shape.h:184
Isis::ShapeDisplayProperties
This is the GUI communication mechanism for shape objects.
Definition: ShapeDisplayProperties.h:60
Isis::Distance
Distance measurement, usually in meters.
Definition: Distance.h:34
Isis::Project
The main project for ipce.
Definition: Project.h:289
Isis::Shape::fileName
QString fileName() const
Get the file name of the cube that this shape represents.
Definition: Shape.cpp:376
Isis::Shape::emissionAngle
Angle emissionAngle() const
Get the emission angle of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:481
Isis::Shape::m_fileName
QString m_fileName
The on-disk file name of the cube associated with this Shape.
Definition: Shape.h:180
Isis::Cube::externalCubeFileName
FileName externalCubeFileName() const
If this is an external cube label file, this will give you the cube dn file that this label reference...
Definition: Cube.cpp:1535
Isis::ControlPoint::RadiusSourceToString
static QString RadiusSourceToString(RadiusSource::Source source)
Obtain a string representation of a given RadiusSource.
Definition: ControlPoint.cpp:1413
Isis::Shape::fromPvl
void fromPvl(const PvlObject &pvl)
Read the shape settings from a Pvl.
Definition: Shape.cpp:236
Isis::Shape::m_footprint
geos::geom::MultiPolygon * m_footprint
A 0-360 ocentric lon,lat degrees footprint of this Shape.
Definition: Shape.h:196
Isis::Shape::id
QString id() const
Get a unique, identifying string associated with this shape.
Definition: Shape.cpp:459
Isis::Distance::Meters
@ Meters
The distance is being specified in meters.
Definition: Distance.h:43
Isis::Shape::aspectRatio
double aspectRatio() const
Get the aspect ratio of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:449
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::Shape::phaseAngle
Angle phaseAngle() const
Get the phase angle of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:536
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Cube::lineCount
int lineCount() const
Definition: Cube.cpp:1734
Isis::FileName::dir
QDir dir() const
Returns the path of the file's parent directory as a QDir object.
Definition: FileName.cpp:465
Isis::PvlContainer::isNamed
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
Definition: PvlContainer.h:72
Isis::Shape::m_instrumentId
QString m_instrumentId
Instrument id associated with this Shape.
Definition: Shape.h:188
Isis::Project::shapeDataRoot
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
Definition: Project.cpp:2097
Isis::ControlPoint::SurfacePointSourceToString
static QString SurfacePointSourceToString(SurfacePointSource::Source source)
Obtain a string representation of a given SurfacePointSource.
Definition: ControlPoint.cpp:1492
Isis::ControlPoint::StringToSurfacePointSource
static SurfacePointSource::Source StringToSurfacePointSource(QString str)
Obtain a SurfacePoint::Source from a string.
Definition: ControlPoint.cpp:1530
Isis::ControlPoint::StringToRadiusSource
static RadiusSource::Source StringToRadiusSource(QString str)
Obtain a RadiusSource::Source from a string.
Definition: ControlPoint.cpp:1448
Isis::PvlObject::hasKeyword
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
Definition: PvlObject.cpp:236
Isis::Shape::resolution
double resolution() const
Get the resolution of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:470
Isis::Table
Class for storing Table blobs information.
Definition: Table.h:61
Isis::PvlObject::findObject
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:274
Isis::Distance::isValid
bool isValid() const
Test if this distance has been initialized or not.
Definition: Distance.cpp:192
Isis::Shape
This represents a shape in a project-based GUI interface.
Definition: Shape.h:68
Isis::Cube::sampleCount
int sampleCount() const
Definition: Cube.cpp:1807
Isis::DisplayProperties::displayName
QString displayName() const
Returns the display name.
Definition: DisplayProperties.cpp:88
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::PvlContainer::name
QString name() const
Returns the container name.
Definition: PvlContainer.h:63
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::Shape::localRadius
Distance localRadius() const
Get the local radius of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:514
Isis::Angle
Defines an angle and provides unit conversions.
Definition: Angle.h:45
Isis::FileName::toString
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition: FileName.cpp:515
Isis::Shape::m_cube
Cube * m_cube
The cube associated with this Shape.
Definition: Shape.h:168
Isis::Project::projectRoot
QString projectRoot() const
Get the top-level folder of the project.
Definition: Project.cpp:1666
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::ProjectionFactory::CreateFromCube
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
Definition: ProjectionFactory.cpp:1069
Isis::Shape::XmlHandler::startElement
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
Definition: Shape.cpp:936
Isis::Shape::Shape
Shape(QString shapeFileName, QObject *parent=0)
Create an Shape from a cube file on disk.
Definition: Shape.cpp:45
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
Isis::Shape::updateFileName
void updateFileName(Project *)
Change the on-disk file name for this cube to be where the shape ought to be in the given project.
Definition: Shape.cpp:622
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
Isis::PolygonTools::MakeMultiPolygon
static geos::geom::MultiPolygon * MakeMultiPolygon(const geos::geom::Geometry *geom)
Make a geos::geom::MultiPolygon out of the components of the argument.
Definition: PolygonTools.cpp:1369
Isis::Angle::isValid
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid,...
Definition: Angle.cpp:95
Isis::Shape::serialNumber
QString serialNumber()
Get the serial number.
Definition: Shape.cpp:385
Isis::Cube::storesDnData
bool storesDnData() const
This method returns a boolean value.
Definition: Cube.cpp:1904
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::Shape::XmlHandler
Definition: Shape.h:138
Isis::DisplayProperties::toPvl
PvlObject toPvl() const
Convert to Pvl for project files.
Definition: DisplayProperties.cpp:68
Isis::Distance::meters
double meters() const
Get the distance in meters.
Definition: Distance.cpp:85
Isis::Shape::initFootprint
bool initFootprint(QMutex *cameraMutex)
Calculate a footprint for this shape.
Definition: Shape.cpp:421
Isis::Shape::save
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Output format:
Definition: Shape.cpp:844
Isis::Shape::m_bodyCode
SpiceInt * m_bodyCode
The NaifBodyCode value, if it exists in the labels.
Definition: Shape.h:157
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::Shape::m_id
QUuid * m_id
A unique ID for this Shape (useful for others to reference this Shape when saving to disk).
Definition: Shape.h:200
QObject
Isis::Table::Records
int Records() const
Returns the number of records.
Definition: Table.cpp:313
Isis::FileName::setExtension
FileName setExtension(const QString &extension) const
Sets all current file extensions to a new extension in the file name.
Definition: FileName.cpp:265
Isis::Blob
Definition: Blob.h:51
Isis::Shape::XmlHandler::XmlHandler
XmlHandler(Shape *shape, FileName shapeFolder)
Create an XML Handler (reader) that can populate the Shape class data.
Definition: Shape.cpp:828
Isis::Shape::lineResolution
double lineResolution() const
Get the line resolution of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:503
Isis::Shape::sampleResolution
double sampleResolution() const
Get the sample resolution of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:547
Isis::Shape::~Shape
~Shape()
Clean up this shape.
Definition: Shape.cpp:89
Isis::ImagePolygon::Polys
geos::geom::MultiPolygon * Polys()
Return a geos Multipolygon.
Definition: ImagePolygon.h:210
Isis::FileName::path
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:103
Isis::Angle::Radians
@ Radians
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:63
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IString::ToQt
QString ToQt() const
Retuns the object string as a QString.
Definition: IString.cpp:869
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126
Isis::Angle::radians
double radians() const
Convert an angle to a double.
Definition: Angle.h:226