Isis 3.0 Programmer Reference
Back | Home
Shape.cpp
1 #include "Shape.h"
2 
3 #include <QBuffer>
4 #include <QDataStream>
5 #include <QDebug>
6 #include <QDir>
7 #include <QFileInfo>
8 #include <QMutexLocker>
9 #include <QScopedPointer>
10 #include <QString>
11 #include <QUuid>
12 #include <QXmlStreamWriter>
13 
14 #include <geos/geom/MultiPolygon.h>
15 #include <geos/io/WKTReader.h>
16 #include <geos/io/WKTWriter.h>
17 
18 #include "Angle.h"
19 #include "CameraFactory.h"
20 #include "Cube.h"
21 #include "CubeAttribute.h"
22 #include "DisplayProperties.h"
23 #include "Distance.h"
24 #include "ShapeDisplayProperties.h"
25 #include "IString.h"
26 #include "FileName.h"
27 #include "ImagePolygon.h"
28 
29 #include "PolygonTools.h"
30 #include "Project.h"
31 #include "ProjectionFactory.h"
32 #include "SerialNumber.h"
33 #include "Target.h"
34 #include "XmlStackedHandlerReader.h"
35 
36 namespace Isis {
43  Shape::Shape(QString imageFileName, QObject *parent) : QObject(parent) {
44 
45  m_fileName = imageFileName;
46  cube();
47 
48  initMemberData();
49  initShape();
50  }
51 
52 
59  Shape::Shape(Cube *shapeCube, QObject *parent) : QObject(parent) {
60 
61  m_fileName = shapeCube->fileName();
62  m_cube = shapeCube;
63 
64  initMemberData();
65  initShape();
66  }
67 
68 
76  Shape::Shape(FileName shapeFolder, XmlStackedHandlerReader *xmlReader, QObject *parent) :
77  QObject(parent) {
78 
79  initMemberData();
80  xmlReader->pushContentHandler(new XmlHandler(this, shapeFolder));
81  }
82 
83 
88  delete m_bodyCode;
89  m_bodyCode = NULL;
90 
91  delete m_cube;
92  m_cube = NULL;
93 
94  delete m_footprint;
95  m_footprint = NULL;
96 
97  delete m_id;
98  m_id = NULL;
99 
100  // Shape is a "Qt" parent of display properties, so the Shape QObject
101  // destructor will take care of deleting the display props. See call to
102  // DisplayProperties' constructor.
103  m_displayProperties = NULL;
104  }
105 
106 
107  void Shape::initMemberData() {
108 
109  m_bodyCode = NULL;
110  m_cube = NULL;
111  m_displayProperties = NULL;
112  m_footprint = NULL;
113  m_id = NULL;
114 
115  m_aspectRatio = Null;
116  m_resolution = Null;
117  m_lineResolution = Null;
118  m_sampleResolution = Null;
119 
120  m_targetName = Null;
121  m_projectionName = Null;
122  m_pixelResolution = Null;
123  m_scale = Null;
124  }
125 
126 
127  void Shape::initShape() {
128 
129  if (cube()->hasTable("ShapeModelStatistics")) {
130  m_shapeType = Dem;
131  }
132  // Is this a level 1 or level 2?
133  else {
134  try {
136  m_shapeType = Basemap;
137  }
138  catch (IException &) {
139  try {
141  m_shapeType = Unprojected;
142  }
143  catch (IException &) {
144  QString message = "Cannot create either Camera or Projections ";
145  message += "for the ground source file. Check the validity of the ";
146  message += " cube labels. The cube must either be projected or ";
147  message += " run through spiceinit.";
148  //TODO 2016-07-25 TLS Where should info msgs go in IPCE?
149  m_shapeType = Unknown;
150  }
151  }
152  }
153 
154  if (m_shapeType == Unprojected) {
155  initCamStats();
156  }
157  else if (m_shapeType == Basemap || m_shapeType == Dem) {
158  initMapStats();
159  if (m_shapeType == Dem) {
160  initDemStats();
161  }
162  }
163 
164  try {
165  initQuickFootprint();
166  }
167  catch (IException &) {
168  }
169 
170  m_displayProperties = new ShapeDisplayProperties(FileName(m_fileName).name(), this);
171 
172  m_id = new QUuid(QUuid::createUuid());
173  }
174 
175 
176  Shape::ShapeType Shape::shapeType() {
177  return m_shapeType;
178  }
179 
180 
193  void Shape::fromPvl(const PvlObject &pvl) {
194  QString pvlFileName = ((IString)pvl["FileName"][0]).ToQt();
195  if (m_fileName != pvlFileName) {
197  tr("Tried to load Shape [%1] with properties/information from [%2].")
198  .arg(m_fileName).arg(pvlFileName),
199  _FILEINFO_);
200  }
201 
202  displayProperties()->fromPvl(pvl.findObject("DisplayProperties"));
203 
204  if (pvl.hasKeyword("ID")) {
205  QByteArray hexValues(pvl["ID"][0].toLatin1());
206  QDataStream valuesStream(QByteArray::fromHex(hexValues));
207  valuesStream >> *m_id;
208  }
209  }
210 
211 
226  PvlObject output("Shape");
227 
228  output += PvlKeyword("FileName", m_fileName);
229 
230  // Do m_id
231  QBuffer dataBuffer;
232  dataBuffer.open(QIODevice::ReadWrite);
233 
234  QDataStream idStream(&dataBuffer);
235  idStream << *m_id;
236 
237  dataBuffer.seek(0);
238 
239  output += PvlKeyword("ID", QString(dataBuffer.data().toHex()));
240 
241  output += displayProperties()->toPvl();
242 
243  return output;
244  }
245 
246 
251  bool Shape::isFootprintable() const {
252  bool result = false;
253 
254  if (m_footprint)
255  result = true;
256 
257  if (!result && m_cube) {
258  // TODO: Move this to Blob!
259  ImagePolygon example;
260 
261  QString blobType = example.Type();
262  QString blobName = example.Name();
263 
264  Pvl &labels = *m_cube->label();
265 
266  for (int i = 0; i < labels.objects(); i++) {
267  PvlObject &obj = labels.object(i);
268 
269  if (obj.isNamed(blobType) && obj.hasKeyword("Name") && obj["Name"][0] == blobName)
270  result = true;
271  }
272  }
273 
274  return result;
275  }
276 
277 
283  if (!m_cube) {
284  try {
285  m_cube = new Cube(m_fileName);
286  }
287  catch (IException &e) {
288  throw IException(e, IException::Programmer, "Cube cannot be created", _FILEINFO_);
289  }
290  }
291 
292  return m_cube;
293  }
294 
295 
301  if (m_cube) {
302  delete m_cube;
303  m_cube = NULL;
304  }
305  }
306 
307 
314  return m_displayProperties;
315  }
316 
317 
325  return m_displayProperties;
326  }
327 
328 
334  QString Shape::fileName() const {
335  return m_fileName;
336  }
337 
338 
344  return SerialNumber::Compose(*(cube()));
345  }
346 
352  geos::geom::MultiPolygon *Shape::footprint() {
353  return m_footprint;
354  }
355 
356 
360  void Shape::setId(QString id) {
361  *m_id = QUuid(QString("{%1}").arg(id));
362  }
363 
364 
370  const geos::geom::MultiPolygon *Shape::footprint() const {
371  return m_footprint;
372  }
373 
374 
379  bool Shape::initFootprint(QMutex *cameraMutex) {
380  if (!m_footprint) {
381  try {
382  initQuickFootprint();
383  }
384  catch (IException &e) {
385  try {
386  m_footprint = createFootprint(cameraMutex);
387  }
388  catch(IException &e) {
389  IString msg = "Could not read the footprint from cube [" +
390  displayProperties()->displayName() + "]. Please make "
391  "sure footprintinit has been run";
392  throw IException(e, IException::Io, msg, _FILEINFO_);
393  }
394  }
395  }
396 
397  // I'm not sure how this could ever be NULL. -SL
398  return (m_footprint != NULL);
399  }
400 
401 
407  double Shape::aspectRatio() const {
408  return m_aspectRatio;
409  }
410 
411 
417  QString Shape::id() const {
418  return m_id->toString().remove(QRegExp("[{}]"));
419  }
420 
421 
428  double Shape::resolution() const {
429  return m_resolution;
430  }
431 
432 
440  return m_emissionAngle;
441  }
442 
443 
451  return m_incidenceAngle;
452  }
453 
454 
461  double Shape::lineResolution() const {
462  return m_lineResolution;
463  }
464 
465 
473  return m_localRadius;
474  }
475 
476 
484  return m_northAzimuth;
485  }
486 
487 
495  return m_phaseAngle;
496  }
497 
498 
505  double Shape::sampleResolution() const {
506  return m_sampleResolution;
507  }
508 
509 
513  void Shape::copyToNewProjectRoot(const Project *project, FileName newProjectRoot) {
514  if (FileName(newProjectRoot) != FileName(project->projectRoot())) {
515  Cube origShape(m_fileName);
516 
517  FileName newExternalLabelFileName(Project::shapeDataRoot(newProjectRoot.toString()) + "/" +
518  FileName(m_fileName).dir().dirName() + "/" + FileName(m_fileName).name());
519 
520  QScopedPointer<Cube> newExternalLabel(
521  origShape.copy(newExternalLabelFileName, CubeAttributeOutput("+External")));
522 
523  // If this is an ecub (it should be) and is pointing to a relative file name,
524  // then we want to copy the DN cube also.
525  if (!origShape.storesDnData()) {
526  if (origShape.externalCubeFileName().path() == ".") {
527  Cube dnFile(
528  FileName(m_fileName).path() + "/" + origShape.externalCubeFileName().name());
529 
530  FileName newDnFileName = newExternalLabelFileName.setExtension("cub");
531 
532  QScopedPointer<Cube> newDnFile(dnFile.copy(newDnFileName, CubeAttributeOutput()));
533  newDnFile->close();
534 
535  newExternalLabel->relocateDnData(newDnFileName.name());
536  }
537  else {
538  newExternalLabel->relocateDnData(origShape.externalCubeFileName());
539  }
540  }
541  }
542  }
543 
544 
550  bool deleteCubAlso = (cube()->externalCubeFileName().path() == ".");
551  closeCube();
552 
553  if (!QFile::remove(m_fileName)) {
555  tr("Could not remove file [%1]").arg(m_fileName),
556  _FILEINFO_);
557  }
558 
559  if (deleteCubAlso) {
560  FileName cubFile = FileName(m_fileName).setExtension("cub");
561  if (!QFile::remove(cubFile.expanded())) {
563  tr("Could not remove file [%1]").arg(m_fileName),
564  _FILEINFO_);
565  }
566  }
567 
568  // If we're the last thing in the folder, remove the folder too.
569  QDir dir;
570  dir.rmdir(FileName(m_fileName).path());
571  }
572 
573 
581  closeCube();
582 
583  FileName original(m_fileName);
584  FileName newName(project->shapeDataRoot() + "/" +
585  original.dir().dirName() + "/" + original.name());
586  m_fileName = newName.expanded();
587  }
588 
589 
596  geos::geom::MultiPolygon *Shape::createFootprint(QMutex *cameraMutex) {
597  QMutexLocker lock(cameraMutex);
598 
599  // We need to walk the shape to create the polygon...
600  ImagePolygon imgPoly;
601 
602  int sampleStepSize = cube()->sampleCount() / 10;
603  if (sampleStepSize <= 0) sampleStepSize = 1;
604 
605  int lineStepSize = cube()->lineCount() / 10;
606  if (lineStepSize <= 0) lineStepSize = 1;
607 
608  imgPoly.Create(*cube(), sampleStepSize, lineStepSize);
609 
611  tr("Warning: Polygon re-calculated for [%1] which can be very slow")
612  .arg(displayProperties()->displayName()),
613  _FILEINFO_);
614  e.print();
615 
616  return PolygonTools::MakeMultiPolygon(imgPoly.Polys()->clone());
617  }
618 
619 
624  bool hasCamStats = false;
625 
626  Pvl &label = *cube()->label();
627  for (int i = 0; !hasCamStats && i < label.objects(); i++) {
628  PvlObject &obj = label.object(i);
629 
630  try {
631  if (obj.name() == "Table") {
632  if (obj["Name"][0] == "CameraStatistics") {
633  hasCamStats = true;
634  }
635  }
636  }
637  catch (IException &) {
638  }
639  }
640 
641  if (hasCamStats) {
642  Table camStatsTable("CameraStatistics", m_fileName, label);
643 
644  int numRecords = camStatsTable.Records();
645  for (int recordIndex = 0; recordIndex < numRecords; recordIndex++) {
646  TableRecord &record = camStatsTable[recordIndex];
647 
648  // The TableField class gives us a std::string with NULL (\0) characters... be careful not
649  // to keep them when going to QString.
650  QString recordName((QString)record["Name"]);
651  double avgValue = (double)record["Average"];
652 
653  if (recordName == "AspectRatio") {
654  m_aspectRatio = avgValue;
655  }
656  else if (recordName == "Resolution") {
657  m_resolution = avgValue;
658  }
659  else if (recordName == "EmissionAngle") {
660  m_emissionAngle = Angle(avgValue, Angle::Degrees);
661  }
662  else if (recordName == "IncidenceAngle") {
663  m_incidenceAngle = Angle(avgValue, Angle::Degrees);
664  }
665  else if (recordName == "LineResolution") {
666  m_lineResolution = avgValue;
667  }
668  else if (recordName == "LocalRadius") {
669  m_localRadius = Distance(avgValue, Distance::Meters);
670  }
671  else if (recordName == "NorthAzimuth") {
672  m_northAzimuth = Angle(avgValue, Angle::Degrees);
673  }
674  else if (recordName == "PhaseAngle") {
675  m_phaseAngle = Angle(avgValue, Angle::Degrees);
676  }
677  else if (recordName == "SampleResolution") {
678  m_sampleResolution = avgValue;
679  }
680  }
681  }
682 
683  for (int i = 0; i < label.objects(); i++) {
684  PvlObject &obj = label.object(i);
685  try {
686  if (obj.hasGroup("Instrument")) {
687  PvlGroup instGroup = obj.findGroup("Instrument");
688 
689  if (instGroup.hasKeyword("SpacecraftName"))
690  m_spacecraftName = obj.findGroup("Instrument")["SpacecraftName"][0];
691 
692  if (instGroup.hasKeyword("InstrumentId"))
693  m_instrumentId = obj.findGroup("Instrument")["InstrumentId"][0];
694  }
695  }
696  catch (IException &) {
697  }
698  }
699  }
700 
701 
702  void Shape::initMapStats() {
703 
704  Pvl &label = *cube()->label();
705  for (int i = 0; i < label.objects(); i++) {
706  PvlObject &obj = label.object(i);
707  try {
708  if (obj.hasGroup("Instrument")) {
709  PvlGroup instGroup = obj.findGroup("Instrument");
710 
711  if (instGroup.hasKeyword("SpacecraftName"))
712  m_spacecraftName = obj.findGroup("Instrument")["SpacecraftName"][0];
713 
714  if (instGroup.hasKeyword("InstrumentId"))
715  m_instrumentId = obj.findGroup("Instrument")["InstrumentId"][0];
716  }
717 
718  if (obj.hasGroup("Mapping")) {
719  PvlGroup mapGroup = obj.findGroup("Mapping");
720 
721  if (mapGroup.hasKeyword("TargetName"))
722  m_targetName = obj.findGroup("Mapping")["TargetName"][0];
723 
724  if (mapGroup.hasKeyword("ProjectionName"))
725  m_projectionName = obj.findGroup("Mapping")["ProjectionName"][0];
726 
727  if (mapGroup.hasKeyword("CenterLongitude"))
728  m_centerLongitude = Longitude(toDouble(obj.findGroup("Mapping")["CenterLongitude"][0]),
729  mapGroup, Angle::Degrees);
730 
731  if (mapGroup.hasKeyword("CenterLatitude"))
732  m_centerLatitude = Latitude(toDouble(obj.findGroup("Mapping")["CenterLatitude"][0]),
733  mapGroup, Angle::Degrees);
734 
735  if (mapGroup.hasKeyword("MinimumLatitude"))
736  m_minimumLatitude = Latitude(toDouble(obj.findGroup("Mapping")["MinimumLatitude"][0]),
737  mapGroup, Angle::Degrees);
738 
739  if (mapGroup.hasKeyword("MaximumLatitude"))
740  m_maximumLatitude = Latitude(toDouble(obj.findGroup("Mapping")["MaximumLatitude"][0]),
741  mapGroup, Angle::Degrees);
742 
743  if (mapGroup.hasKeyword("MinimumLongitude"))
744  m_minimumLongitude = Longitude(toDouble(obj.findGroup("Mapping")["MinimumLongitude"][0]),
745  mapGroup, Angle::Degrees);
746 
747  if (mapGroup.hasKeyword("MaximumLongitude"))
748  m_maximumLongitude = Longitude(toDouble(obj.findGroup("Mapping")["MaximumLongitude"][0]),
749  mapGroup, Angle::Degrees);
750 
751  if (mapGroup.hasKeyword("PixelResolution"))
752  m_pixelResolution = obj.findGroup("Mapping")["PixelResolution"];
753 
754  if (mapGroup.hasKeyword("Scale"))
755  m_scale = obj.findGroup("Mapping")["Scale"];
756  }
757  }
758  catch (IException &) {
759  }
760  }
761  }
762 
763 
764  void Shape::initDemStats() {
765 
766 
767  }
768 
769 
770  void Shape::initQuickFootprint() {
771  ImagePolygon poly;
772  cube()->read(poly);
773  m_footprint = PolygonTools::MakeMultiPolygon(poly.Polys()->clone());
774  }
775 
776 
785  m_shape = shape;
786  m_shapeFolder = shapeFolder;
787  }
788 
789 
800  void Shape::save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot)
801  const {
802 
803  stream.writeStartElement("shape");
804 
805  stream.writeAttribute("id", m_id->toString());
806  stream.writeAttribute("fileName", FileName(m_fileName).name());
807 
808  QString type;
809  if (m_shapeType == Unprojected) {
810  type = "Unprojected";
811  }
812  else if (m_shapeType == Basemap) {
813  type = "Basemap";
814  }
815  else {
816  type = "Dem";
817  }
818  stream.writeAttribute("shapeType", type);
819 
820  if (m_shapeType == Unprojected) {
821  stream.writeAttribute("instrumentId", m_instrumentId);
822  stream.writeAttribute("spacecraftName", m_spacecraftName);
823 
824  if (!IsSpecial(m_aspectRatio)) {
825  stream.writeAttribute("aspectRatio", IString(m_aspectRatio).ToQt());
826  }
827 
828  if (!IsSpecial(m_resolution)) {
829  stream.writeAttribute("resolution", IString(m_resolution).ToQt());
830  }
831 
832  if (m_emissionAngle.isValid()) {
833  stream.writeAttribute("emissionAngle", IString(m_emissionAngle.radians()).ToQt());
834  }
835 
836  if (m_incidenceAngle.isValid()) {
837  stream.writeAttribute("incidenceAngle", IString(m_incidenceAngle.radians()).ToQt());
838  }
839 
840  if (!IsSpecial(m_lineResolution)) {
841  stream.writeAttribute("lineResolution", IString(m_lineResolution).ToQt());
842  }
843 
844  if (m_localRadius.isValid()) {
845  stream.writeAttribute("localRadius", IString(m_localRadius.meters()).ToQt());
846  }
847 
848  if (m_northAzimuth.isValid()) {
849  stream.writeAttribute("northAzimuth", IString(m_northAzimuth.radians()).ToQt());
850  }
851 
852  if (m_phaseAngle.isValid()) {
853  stream.writeAttribute("phaseAngle", IString(m_phaseAngle.radians()).ToQt());
854  }
855 
856  if (!IsSpecial(m_sampleResolution)) {
857  stream.writeAttribute("sampleResolution", IString(m_sampleResolution).ToQt());
858  }
859  }
860  else if (m_shapeType == Basemap) {
861 
862  }
863  else if (m_shapeType == Dem) {
864 
865  }
866 
867  if (m_footprint) {
868  stream.writeStartElement("footprint");
869 
870  geos::io::WKTWriter wktWriter;
871  stream.writeCharacters(QString::fromStdString(wktWriter.write(m_footprint)));
872 
873  stream.writeEndElement();
874  }
875 
876  m_displayProperties->save(stream, project, newProjectRoot);
877 
878  stream.writeEndElement();
879  }
880 
881 
887  bool Shape::XmlHandler::startElement(const QString &namespaceURI, const QString &localName,
888  const QString &qName, const QXmlAttributes &atts) {
889  m_characters = "";
890 
891  if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
892  if (localName == "shape") {
893  QString id = atts.value("id");
894  QString fileName = atts.value("fileName");
895 
896  if (!id.isEmpty()) {
897  delete m_shape->m_id;
898  m_shape->m_id = NULL;
899  m_shape->m_id = new QUuid(id.toLatin1());
900  }
901 
902  if (!fileName.isEmpty()) {
903  m_shape->m_fileName = m_shapeFolder.expanded() + "/" + fileName;
904  }
905 
906  QString shapeType = atts.value("shapeType");
907 
908  if (shapeType == "Unprojected") {
909  m_shape->m_shapeType = Unprojected;
910  QString instrumentId = atts.value("instrumentId");
911  QString spacecraftName = atts.value("spacecraftName");
912 
913  QString aspectRatioStr = atts.value("aspectRatio");
914  QString resolutionStr = atts.value("resolution");
915  QString emissionAngleStr = atts.value("emissionAngle");
916  QString incidenceAngleStr = atts.value("incidenceAngle");
917  QString lineResolutionStr = atts.value("lineResolution");
918  QString localRadiusStr = atts.value("localRadius");
919  QString northAzimuthStr = atts.value("northAzimuth");
920  QString phaseAngleStr = atts.value("phaseAngle");
921  QString sampleResolutionStr = atts.value("sampleResolution");
922 
923  if (!instrumentId.isEmpty()) {
924  m_shape->m_instrumentId = m_shapeFolder.expanded() + "/" + instrumentId;
925  }
926 
927  if (!instrumentId.isEmpty()) {
928  m_shape->m_instrumentId = m_shapeFolder.expanded() + "/" + instrumentId;
929  }
930 
931  if (!spacecraftName.isEmpty()) {
932  m_shape->m_spacecraftName = m_shapeFolder.expanded() + "/" + spacecraftName;
933  }
934 
935  if (!aspectRatioStr.isEmpty()) {
936  m_shape->m_aspectRatio = aspectRatioStr.toDouble();
937  }
938 
939  if (!resolutionStr.isEmpty()) {
940  m_shape->m_resolution = resolutionStr.toDouble();
941  }
942 
943  if (!emissionAngleStr.isEmpty()) {
944  m_shape->m_emissionAngle = Angle(emissionAngleStr.toDouble(), Angle::Radians);
945  }
946 
947  if (!incidenceAngleStr.isEmpty()) {
948  m_shape->m_incidenceAngle = Angle(incidenceAngleStr.toDouble(), Angle::Radians);
949  }
950 
951  if (!lineResolutionStr.isEmpty()) {
952  m_shape->m_lineResolution = lineResolutionStr.toDouble();
953  }
954 
955  if (!localRadiusStr.isEmpty()) {
956  m_shape->m_localRadius = Distance(localRadiusStr.toDouble(), Distance::Meters);
957  }
958 
959  if (!northAzimuthStr.isEmpty()) {
960  m_shape->m_northAzimuth = Angle(northAzimuthStr.toDouble(), Angle::Radians);
961  }
962 
963  if (!phaseAngleStr.isEmpty()) {
964  m_shape->m_phaseAngle = Angle(phaseAngleStr.toDouble(), Angle::Radians);
965  }
966 
967  if (!sampleResolutionStr.isEmpty()) {
968  m_shape->m_sampleResolution = sampleResolutionStr.toDouble();
969  }
970  }
971  else if (shapeType == "Basemap") {
972  m_shape->m_shapeType = Basemap;
973  }
974  else if (shapeType == "Dem") {
975  m_shape->m_shapeType = Dem;
976  }
977  else {
978  m_shape->m_shapeType = Unknown;
979  }
980 
981 
982  }
983  else if (localName == "displayProperties") {
984  m_shape->m_displayProperties = new ShapeDisplayProperties(reader());
985  }
986  }
987 
988  return true;
989  }
990 
991 
992 
993  bool Shape::XmlHandler::characters(const QString &ch) {
994  m_characters += ch;
995 
996  return XmlStackedHandler::characters(ch);
997  }
998 
999 
1000 
1001  bool Shape::XmlHandler::endElement(const QString &namespaceURI, const QString &localName,
1002  const QString &qName) {
1003  if (localName == "footprint" && !m_characters.isEmpty()) {
1004  geos::io::WKTReader wktReader(&globalFactory);
1005  m_shape->m_footprint = PolygonTools::MakeMultiPolygon(
1006  wktReader.read(m_characters.toStdString()));
1007  }
1008  else if (localName == "shape" && !m_shape->m_footprint) {
1009  QMutex mutex;
1010  m_shape->initFootprint(&mutex);
1011  m_shape->closeCube();
1012  }
1013 
1014  m_characters = "";
1015  return XmlStackedHandler::endElement(namespaceURI, localName, qName);
1016  }
1017 }
1018 
1019 
PvlObject & object(const int index)
Return the object at the specified index.
Definition: PvlObject.cpp:460
PvlObject toPvl() const
Convert to Pvl for project files.
int Records() const
Returns the number of records.
Definition: Table.cpp:224
Distance localRadius() const
Get the local radius of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:472
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:109
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
The main project for cnetsuite.
Definition: Project.h:105
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
void closeCube()
Cleans up the Cube *.
Definition: Shape.cpp:300
Angle emissionAngle() const
Get the emission angle of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:439
File name manipulation and expansion.
Definition: FileName.h:111
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:1132
double radians() const
Convert an angle to a double.
Definition: Angle.h:239
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Output format:
Definition: Shape.cpp:800
QString m_spacecraftName
Spacecraft name associated with this Shape.
Definition: Shape.h:189
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:286
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1298
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name &#39;shapes&#39; to the project .
Definition: Project.cpp:1280
void copyToNewProjectRoot(const Project *project, FileName newProjectRoot)
Copy the cub/ecub files associated with this shape into the new project.
Definition: Shape.cpp:513
ShapeDisplayProperties * displayProperties()
Get the display (GUI) properties (information) associated with this shape.
Definition: Shape.cpp:313
geos::geom::MultiPolygon * createFootprint(QMutex *cameraMutex)
Calculate a footprint for an Shape using the camera or projection information.
Definition: Shape.cpp:596
This is the GUI communication mechanism for shape objects.
~Shape()
Clean up this shape.
Definition: Shape.cpp:87
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:686
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:164
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:154
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:163
Distance measurement, usually in meters.
Definition: Distance.h:47
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.
XmlHandler(Shape *shape, FileName shapeFolder)
Create an XML Handler (reader) that can populate the Shape class data.
Definition: Shape.cpp:784
Create cube polygons, read/write polygons to blobs.
Definition: ImagePolygon.h:167
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
Angle northAzimuth() const
Get the north azimuth of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:483
QString m_instrumentId
Instrument id associated with this Shape.
Definition: Shape.h:185
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:207
bool initFootprint(QMutex *cameraMutex)
Calculate a footprint for this shape.
Definition: Shape.cpp:379
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
Definition: Shape.cpp:887
int sampleCount() const
Definition: Cube.cpp:1404
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
Definition: Project.cpp:1290
double meters() const
Get the distance in meters.
Definition: Distance.cpp:97
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:69
double sampleResolution() const
Get the sample resolution of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:505
QString displayName() const
Returns the display name.
PvlObject toPvl() const
Convert this Shape to PVL.
Definition: Shape.cpp:225
QUuid * m_id
A unique ID for this Shape (useful for others to reference this Shape when saving to disk)...
Definition: Shape.h:197
static geos::geom::MultiPolygon * MakeMultiPolygon(const geos::geom::Geometry *geom)
Make a geos::geom::MultiPolygon out of the components of the argument.
Cube * cube()
Get the Cube * associated with this display property.
Definition: Shape.cpp:282
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
void print() const
Prints a string representation of this exception to stderr.
Definition: IException.cpp:461
bool isValid() const
Test if this distance has been initialized or not.
Definition: Distance.cpp:204
int objects() const
Returns the number of objects.
Definition: PvlObject.h:231
QString serialNumber()
Get the serial number.
Definition: Shape.cpp:343
Manipulate and parse attributes of output cube filenames.
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:134
A single keyword-value pair.
Definition: PvlKeyword.h:98
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:126
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:580
QString Type() const
Accessor method that returns a string containing the Blob type.
Definition: Blob.cpp:140
Shape(QString shapeFileName, QObject *parent=0)
Create an Shape from a cube file on disk.
Definition: Shape.cpp:43
ShapeDisplayProperties * m_displayProperties
The GUI information for how this Shape ought to be displayed.
Definition: Shape.h:177
bool IsSpecial(const double d)
Returns if the input pixel is special.
Definition: SpecialPixel.h:199
QString id() const
Get a unique, identifying string associated with this shape.
Definition: Shape.cpp:417
Cube * m_cube
The cube associated with this Shape.
Definition: Shape.h:170
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
geos::geom::MultiPolygon * footprint()
Get the footprint of this shape (if available).
Definition: Shape.cpp:352
Container for cube-like labels.
Definition: Pvl.h:135
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
Definition: Angle.cpp:110
void fromPvl(const PvlObject &pvl)
Read the shape settings from a Pvl.
Definition: Shape.cpp:193
double resolution() const
Get the resolution of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:428
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Saves this object to an XML file.
void initCamStats()
TODO.
Definition: Shape.cpp:623
void setId(QString id)
Override the automatically generated ID with the given ID.
Definition: Shape.cpp:360
Defines an angle and provides unit conversions.
Definition: Angle.h:58
bool isFootprintable() const
Test to see if it&#39;s possible to create a footprint from this shape.
Definition: Shape.cpp:251
double aspectRatio() const
Get the aspect ratio of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:407
void deleteFromDisk()
Delete the shape data from disk.
Definition: Shape.cpp:549
Class for storing Table blobs information.
Definition: Table.h:74
This represents a shape in a project-based GUI interface.
Definition: Shape.h:70
Angle phaseAngle() const
Get the phase angle of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:494
QString Name() const
Accessor method that returns a string containing the Blob name.
Definition: Blob.cpp:149
Isis exception class.
Definition: IException.h:99
QString m_fileName
The on-disk file name of the cube associated with this Shape.
Definition: Shape.h:181
Adds specific functionality to C++ strings.
Definition: IString.h:179
geos::geom::MultiPolygon * m_footprint
A 0-360 ocentric lon,lat degrees footprint of this Shape.
Definition: Shape.h:193
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
Definition: PvlContainer.h:87
QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1160
The distance is being specified in meters.
Definition: Distance.h:56
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition: PvlObject.h:222
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:76
geos::geom::MultiPolygon * Polys()
Return a geos Multipolygon.
Definition: ImagePolygon.h:221
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
int lineCount() const
Definition: Cube.cpp:1331
QString path() const
Returns the path.
Definition: FileName.cpp:88
Angle incidenceAngle() const
Get the incidence angle of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:450
his enables stack-based XML parsing of XML files.
QString projectRoot() const
Get the top-level folder of the project.
Definition: Project.cpp:1087
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
QString fileName() const
Get the file name of the cube that this shape represents.
Definition: Shape.cpp:334
double lineResolution() const
Get the line resolution of this shape, as calculated and attached by camstats.
Definition: Shape.cpp:461
QString name() const
Returns the container name.
Definition: PvlContainer.h:78
SpiceInt * m_bodyCode
The NaifBodyCode value, if it exists in the labels.
Definition: Shape.h:159
IO Handler for Isis Cubes.
Definition: Cube.h:158

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:29:05