|
Isis 3 Programmer Reference
|
9 #include <QMutexLocker>
10 #include <QScopedPointer>
13 #include <QXmlStreamWriter>
15 #include <geos/geom/MultiPolygon.h>
16 #include <geos/io/WKTReader.h>
17 #include <geos/io/WKTWriter.h>
20 #include "CameraFactory.h"
21 #include "ControlPoint.h"
23 #include "CubeAttribute.h"
24 #include "DisplayProperties.h"
27 #include "IException.h"
28 #include "ImagePolygon.h"
30 #include "PolygonTools.h"
32 #include "ProjectionFactory.h"
33 #include "SerialNumber.h"
34 #include "ShapeDisplayProperties.h"
36 #include "XmlStackedHandlerReader.h"
109 void Shape::initMemberData() {
117 m_aspectRatio =
Null;
119 m_lineResolution =
Null;
120 m_sampleResolution =
Null;
123 m_projectionName =
Null;
124 m_pixelResolution =
Null;
129 void Shape::initShape() {
132 m_id =
new QUuid(QUuid::createUuid());
135 m_radiusSource = ControlPoint::RadiusSource::None;
137 if (
cube()->hasTable(
"ShapeModelStatistics")) {
138 m_surfacePointSource = ControlPoint::SurfacePointSource::Basemap;
139 m_radiusSource = ControlPoint::RadiusSource::DEM;
146 m_surfacePointSource = ControlPoint::SurfacePointSource::Basemap;
147 m_radiusSource = ControlPoint::RadiusSource::Ellipsoid;
148 m_shapeType = Basemap;
150 catch (IException &) {
154 m_surfacePointSource = ControlPoint::SurfacePointSource::Reference;
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;
163 m_radiusSource = ControlPoint::RadiusSource::Ellipsoid;
166 m_shapeType = Unprojected;
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 "
174 "Check the validity of the cube labels. The cube must either be projected or "
175 " run through spiceinit.";
182 if (m_shapeType == Unprojected) {
185 else if (m_shapeType == Basemap || m_shapeType == Dem) {
187 if (m_shapeType == Dem) {
192 catch (IException &e) {
193 QString message =
"Cannot initialize the camera, map or dem statistics for this shape file [" +
195 "cube must either be projected or run through spiceinit. \n";
196 message += e.toString();
197 QMessageBox::warning((
QWidget *) parent(),
"Warning", message);
201 initQuickFootprint();
203 catch (IException &e) {
209 ControlPoint::SurfacePointSource::Source Shape::surfacePointSource() {
210 return m_surfacePointSource;
214 ControlPoint::RadiusSource::Source Shape::radiusSource() {
215 return m_radiusSource;
219 Shape::ShapeType Shape::shapeType() {
237 QString pvlFileName = ((
IString)pvl[
"FileName"][0]).ToQt();
240 tr(
"Tried to load Shape [%1] with properties/information from [%2].")
248 QByteArray hexValues(pvl[
"ID"][0].toLatin1());
249 QDataStream valuesStream(QByteArray::fromHex(hexValues));
250 valuesStream >> *
m_id;
275 dataBuffer.open(QIODevice::ReadWrite);
277 QDataStream idStream(&dataBuffer);
282 output +=
PvlKeyword(
"ID", QString(dataBuffer.data().toHex()));
303 QString blobType = example.
Type();
304 QString blobName = example.
Name();
308 for (
int i = 0; i < labels.
objects(); i++) {
311 if (obj.
isNamed(blobType) && obj.
hasKeyword(
"Name") && obj[
"Name"][0] == blobName)
403 *
m_id = QUuid(QString(
"{%1}").arg(
id));
424 initQuickFootprint();
431 IString msg =
"Could not read the footprint from cube [" +
433 "sure footprintinit has been run";
450 return m_aspectRatio;
460 return m_id->toString().remove(QRegExp(
"[{}]"));
482 return m_emissionAngle;
493 return m_incidenceAngle;
504 return m_lineResolution;
515 return m_localRadius;
526 return m_northAzimuth;
548 return m_sampleResolution;
562 QScopedPointer<Cube> newExternalLabel(
577 newExternalLabel->relocateDnData(newDnFileName.
name());
597 tr(
"Could not remove file [%1]").arg(
m_fileName),
603 if (!QFile::remove(cubFile.
expanded())) {
605 tr(
"Could not remove file [%1]").arg(
m_fileName),
627 original.
dir().dirName() +
"/" + original.
name());
639 QMutexLocker lock(cameraMutex);
645 if (sampleStepSize <= 0) sampleStepSize = 1;
648 if (lineStepSize <= 0) lineStepSize = 1;
650 imgPoly.
Create(*
cube(), sampleStepSize, lineStepSize);
653 tr(
"Warning: Polygon re-calculated for [%1] which can be very slow")
666 bool hasCamStats =
false;
669 for (
int i = 0; !hasCamStats && i < label.
objects(); i++) {
673 if (obj.
name() ==
"Table") {
674 if (obj[
"Name"][0] ==
"CameraStatistics") {
687 int numRecords = camStatsTable.
Records();
688 for (
int recordIndex = 0; recordIndex < numRecords; recordIndex++) {
693 QString recordName((QString)record[
"Name"]);
694 double avgValue = (double)record[
"Average"];
696 if (recordName ==
"AspectRatio") {
697 m_aspectRatio = avgValue;
699 else if (recordName ==
"Resolution") {
700 m_resolution = avgValue;
702 else if (recordName ==
"EmissionAngle") {
705 else if (recordName ==
"IncidenceAngle") {
708 else if (recordName ==
"LineResolution") {
709 m_lineResolution = avgValue;
711 else if (recordName ==
"LocalRadius") {
714 else if (recordName ==
"NorthAzimuth") {
717 else if (recordName ==
"PhaseAngle") {
720 else if (recordName ==
"SampleResolution") {
721 m_sampleResolution = avgValue;
726 for (
int i = 0; i < label.
objects(); i++) {
746 void Shape::initMapStats() {
749 for (
int i = 0; i < label.
objects(); i++) {
763 PvlGroup mapGroup = obj.
findGroup(
"Mapping");
765 if (mapGroup.hasKeyword(
"TargetName"))
766 m_targetName = obj.
findGroup(
"Mapping")[
"TargetName"][0];
768 if (mapGroup.hasKeyword(
"ProjectionName"))
769 m_projectionName = obj.
findGroup(
"Mapping")[
"ProjectionName"][0];
771 if (mapGroup.hasKeyword(
"CenterLongitude"))
772 m_centerLongitude = Longitude(
toDouble(obj.
findGroup(
"Mapping")[
"CenterLongitude"][0]),
775 if (mapGroup.hasKeyword(
"CenterLatitude"))
776 m_centerLatitude = Latitude(
toDouble(obj.
findGroup(
"Mapping")[
"CenterLatitude"][0]),
779 if (mapGroup.hasKeyword(
"MinimumLatitude"))
780 m_minimumLatitude = Latitude(
toDouble(obj.
findGroup(
"Mapping")[
"MinimumLatitude"][0]),
783 if (mapGroup.hasKeyword(
"MaximumLatitude"))
784 m_maximumLatitude = Latitude(
toDouble(obj.
findGroup(
"Mapping")[
"MaximumLatitude"][0]),
787 if (mapGroup.hasKeyword(
"MinimumLongitude"))
788 m_minimumLongitude = Longitude(
toDouble(obj.
findGroup(
"Mapping")[
"MinimumLongitude"][0]),
791 if (mapGroup.hasKeyword(
"MaximumLongitude"))
792 m_maximumLongitude = Longitude(
toDouble(obj.
findGroup(
"Mapping")[
"MaximumLongitude"][0]),
795 if (mapGroup.hasKeyword(
"PixelResolution"))
796 m_pixelResolution = obj.
findGroup(
"Mapping")[
"PixelResolution"];
798 if (mapGroup.hasKeyword(
"Scale"))
799 m_scale = obj.
findGroup(
"Mapping")[
"Scale"];
802 catch (IException &e) {
809 void Shape::initDemStats() {
815 void Shape::initQuickFootprint() {
830 m_shapeFolder = shapeFolder;
847 stream.writeStartElement(
"shape");
849 stream.writeAttribute(
"id",
m_id->toString());
854 if (m_shapeType == Unprojected) {
855 type =
"Unprojected";
857 else if (m_shapeType == Basemap) {
863 stream.writeAttribute(
"shapeType", type);
864 stream.writeAttribute(
"surfacePointSource",
866 stream.writeAttribute(
"radiusSource",
869 if (m_shapeType == Unprojected) {
874 stream.writeAttribute(
"aspectRatio",
IString(m_aspectRatio).ToQt());
878 stream.writeAttribute(
"resolution",
IString(m_resolution).ToQt());
881 if (m_emissionAngle.
isValid()) {
885 if (m_incidenceAngle.
isValid()) {
890 stream.writeAttribute(
"lineResolution",
IString(m_lineResolution).ToQt());
897 if (m_northAzimuth.
isValid()) {
906 stream.writeAttribute(
"sampleResolution",
IString(m_sampleResolution).ToQt());
909 else if (m_shapeType == Basemap) {
912 else if (m_shapeType == Dem) {
917 stream.writeStartElement(
"footprint");
919 geos::io::WKTWriter wktWriter;
920 stream.writeCharacters(QString::fromStdString(wktWriter.write(
m_footprint)));
922 stream.writeEndElement();
927 stream.writeEndElement();
937 const QString &qName,
const QXmlAttributes &atts) {
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");
947 delete m_shape->m_id;
948 m_shape->m_id = NULL;
949 m_shape->m_id =
new QUuid(
id.toLatin1());
953 m_shape->m_fileName = m_shapeFolder.expanded() +
"/" +
fileName;
956 if (m_shape->m_serialNumber.isEmpty()) {
960 m_shape->m_surfacePointSource =
962 m_shape->m_radiusSource =
964 QString shapeType = atts.value(
"shapeType");
966 if (shapeType ==
"Unprojected") {
967 m_shape->m_shapeType = Unprojected;
968 QString instrumentId = atts.value(
"instrumentId");
969 QString spacecraftName = atts.value(
"spacecraftName");
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");
981 if (!instrumentId.isEmpty()) {
982 m_shape->m_instrumentId = m_shapeFolder.expanded() +
"/" + instrumentId;
985 if (!instrumentId.isEmpty()) {
986 m_shape->m_instrumentId = m_shapeFolder.expanded() +
"/" + instrumentId;
989 if (!spacecraftName.isEmpty()) {
990 m_shape->m_spacecraftName = m_shapeFolder.expanded() +
"/" + spacecraftName;
993 if (!aspectRatioStr.isEmpty()) {
994 m_shape->m_aspectRatio = aspectRatioStr.toDouble();
997 if (!resolutionStr.isEmpty()) {
998 m_shape->m_resolution = resolutionStr.toDouble();
1001 if (!emissionAngleStr.isEmpty()) {
1005 if (!incidenceAngleStr.isEmpty()) {
1009 if (!lineResolutionStr.isEmpty()) {
1010 m_shape->m_lineResolution = lineResolutionStr.toDouble();
1013 if (!localRadiusStr.isEmpty()) {
1017 if (!northAzimuthStr.isEmpty()) {
1021 if (!phaseAngleStr.isEmpty()) {
1025 if (!sampleResolutionStr.isEmpty()) {
1026 m_shape->m_sampleResolution = sampleResolutionStr.toDouble();
1029 else if (shapeType ==
"Basemap") {
1030 m_shape->m_shapeType = Basemap;
1032 else if (shapeType ==
"Dem") {
1033 m_shape->m_shapeType = Dem;
1036 m_shape->m_shapeType = Unknown;
1041 else if (localName ==
"displayProperties") {
1051 bool Shape::XmlHandler::characters(
const QString &ch) {
1054 return XmlStackedHandler::characters(ch);
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);
1065 wktReader.read(m_characters.toStdString()));
1067 catch (IException &e) {
1071 else if (localName ==
"shape" && !m_shape->m_footprint) {
1074 m_shape->initFootprint(&mutex);
1075 m_shape->closeCube();
1077 catch (IException &e) {
1083 return XmlStackedHandler::endElement(namespaceURI, localName, qName);
QString m_spacecraftName
Spacecraft name associated with this Shape.
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
void setId(QString id)
Override the automatically generated ID with the given ID.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
virtual QString fileName() const
Returns the opened cube's filename.
@ Io
A type of error that occurred when performing an actual I/O operation.
ShapeDisplayProperties * displayProperties()
Get the display (GUI) properties (information) associated with this shape.
Contains Pvl Groups and Pvl Objects.
void print() const
Prints a string representation of this exception to stderr.
void deleteFromDisk()
Delete the shape data from disk.
A single keyword-value pair.
PvlGroup & group(const QString &group) const
Read a group from the cube into a Label.
QString Type() const
Accessor method that returns a string containing the Blob type.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
File name manipulation and expansion.
@ Unknown
A type of error that cannot be classified as any of the other error types.
ImagePolygon readFootprint() const
Read the footprint polygon for the Cube.
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
Blob toBlob() const
Serialize the ImagePolygon to a Blob.
void closeCube()
Cleans up the Cube *.
geos::geom::MultiPolygon * createFootprint(QMutex *cameraMutex)
Calculate a footprint for an Shape using the camera or projection information.
ShapeDisplayProperties * m_displayProperties
The GUI information for how this Shape ought to be displayed.
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
Cube * copy(FileName newFile, const CubeAttributeOutput &newFileAttributes)
Copies the cube to the new fileName.
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name 'shapes' to the project .
geos::geom::MultiPolygon * footprint()
Get the footprint of this shape (if available).
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Container for cube-like labels.
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.
int objects() const
Returns the number of objects.
Manipulate and parse attributes of output cube filenames.
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Saves this object to an XML file.
Angle incidenceAngle() const
Get the incidence angle of this shape, as calculated and attached by camstats.
Create cube polygons, read/write polygons to blobs.
bool isFootprintable() const
Test to see if it's possible to create a footprint from this shape.
Cube * cube()
Get the Cube * associated with this display property.
PvlObject & object(const int index)
Return the object at the specified index.
Angle northAzimuth() const
Get the north azimuth of this shape, as calculated and attached by camstats.
Manage a stack of content handlers for reading XML files.
void copyToNewProjectRoot(const Project *project, FileName newProjectRoot)
Copy the cub/ecub files associated with this shape into the new project.
bool IsSpecial(const double d)
Returns if the input pixel is special.
QString Name() const
Accessor method that returns a string containing the Blob name.
PvlObject toPvl() const
Convert this Shape to PVL.
QString m_serialNumber
This will always be simply the filename and is created on construction.
This is the GUI communication mechanism for shape objects.
Distance measurement, usually in meters.
The main project for ipce.
QString fileName() const
Get the file name of the cube that this shape represents.
Angle emissionAngle() const
Get the emission angle of this shape, as calculated and attached by camstats.
QString m_fileName
The on-disk file name of the cube associated with this Shape.
FileName externalCubeFileName() const
If this is an external cube label file, this will give you the cube dn file that this label reference...
static QString RadiusSourceToString(RadiusSource::Source source)
Obtain a string representation of a given RadiusSource.
void fromPvl(const PvlObject &pvl)
Read the shape settings from a Pvl.
geos::geom::MultiPolygon * m_footprint
A 0-360 ocentric lon,lat degrees footprint of this Shape.
QString id() const
Get a unique, identifying string associated with this shape.
@ Meters
The distance is being specified in meters.
double aspectRatio() const
Get the aspect ratio of this shape, as calculated and attached by camstats.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Angle phaseAngle() const
Get the phase angle of this shape, as calculated and attached by camstats.
Contains multiple PvlContainers.
QDir dir() const
Returns the path of the file's parent directory as a QDir object.
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
QString m_instrumentId
Instrument id associated with this Shape.
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
static QString SurfacePointSourceToString(SurfacePointSource::Source source)
Obtain a string representation of a given SurfacePointSource.
static SurfacePointSource::Source StringToSurfacePointSource(QString str)
Obtain a SurfacePoint::Source from a string.
static RadiusSource::Source StringToRadiusSource(QString str)
Obtain a RadiusSource::Source from a string.
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 ...
double resolution() const
Get the resolution of this shape, as calculated and attached by camstats.
Class for storing Table blobs information.
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
bool isValid() const
Test if this distance has been initialized or not.
This represents a shape in a project-based GUI interface.
QString displayName() const
Returns the display name.
IO Handler for Isis Cubes.
QString name() const
Returns the container name.
Distance localRadius() const
Get the local radius of this shape, as calculated and attached by camstats.
Defines an angle and provides unit conversions.
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Cube * m_cube
The cube associated with this Shape.
QString projectRoot() const
Get the top-level folder of the project.
const double Null
Value for an Isis Null pixel.
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
Shape(QString shapeFileName, QObject *parent=0)
Create an Shape from a cube file on disk.
double toDouble(const QString &string)
Global function to convert from a string to a double.
void updateFileName(Project *)
Change the on-disk file name for this cube to be where the shape ought to be in the given project.
@ Programmer
This error is for when a programmer made an API call that was illegal.
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid,...
QString serialNumber()
Get the serial number.
bool storesDnData() const
This method returns a boolean value.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
PvlObject toPvl() const
Convert to Pvl for project files.
double meters() const
Get the distance in meters.
bool initFootprint(QMutex *cameraMutex)
Calculate a footprint for this shape.
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Output format:
SpiceInt * m_bodyCode
The NaifBodyCode value, if it exists in the labels.
Adds specific functionality to C++ strings.
QUuid * m_id
A unique ID for this Shape (useful for others to reference this Shape when saving to disk).
int Records() const
Returns the number of records.
FileName setExtension(const QString &extension) const
Sets all current file extensions to a new extension in the file name.
XmlHandler(Shape *shape, FileName shapeFolder)
Create an XML Handler (reader) that can populate the Shape class data.
double lineResolution() const
Get the line resolution of this shape, as calculated and attached by camstats.
double sampleResolution() const
Get the sample resolution of this shape, as calculated and attached by camstats.
~Shape()
Clean up this shape.
geos::geom::MultiPolygon * Polys()
Return a geos Multipolygon.
QString path() const
Returns the path of the file name.
@ Radians
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
This is free and unencumbered software released into the public domain.
QString ToQt() const
Retuns the object string as a QString.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
double radians() const
Convert an angle to a double.