1#include "FeatureNomenclature.h"
9#include <QNetworkAccessManager>
10#include <QNetworkRequest>
11#include <QNetworkReply>
17#include "IException.h"
39 QUrl(
"https://planetarynames.wr.usgs.gov/SearchResults"));
41 "Mozilla/5.0 (X11; Linux i686; rv:6.0) "
42 "Gecko/20100101 Firefox/6.0");
43 m_request->setHeader(QNetworkRequest::ContentTypeHeader,
44 "application/x-www-form-urlencoded");
69 m_features =
new QList<Feature>(*other.m_features);
105 if (!range.isEmpty()) {
106 startLon = range[0].first;
107 endLon = range[0].second;
110 if (range.size() > 1) {
115 runQuery(target, startLat, startLon, endLat, endLon);
116 runQuery(target, startLat, startLon2, endLat, endLon2);
121 runQuery(target, startLat, startLon, endLat, endLon);
136 QList<Feature> featureList;
195 Distance lhsDiameter = lhs.diameter();
196 Distance rhsDiameter = rhs.diameter();
198 bool greaterThan =
false;
199 if (lhsDiameter.isValid() && rhsDiameter.isValid()) {
200 greaterThan = (lhsDiameter > rhsDiameter);
203 greaterThan = lhsDiameter.isValid();
223 m_xmlRepresenation = NULL;
224 m_xmlRepresenation =
new QDomElement(searchResultFeature);
225 m_approvalStatus = status;
235 m_xmlRepresenation = NULL;
237 m_approvalStatus = other.m_approvalStatus;
238 m_xmlRepresenation =
new QDomElement(*other.m_xmlRepresenation);
246 delete m_xmlRepresenation;
247 m_xmlRepresenation = NULL;
261 QGridLayout *layout =
new QGridLayout;
262 widget->setLayout(layout);
266 QLabel *titleLabel =
new QLabel(
"<h2>Feature Details</h2>");
267 layout->addWidget(titleLabel, row, 0, 1, 2);
276 displayValue.first =
"Feature Name:";
278 displayValues.append(displayValue);
284 displayValue.first =
"Feature ID:";
286 displayValues.append(displayValue);
288 displayValue.first =
"Target:";
290 displayValues.append(displayValue);
292 displayValue.first =
"System:";
294 displayValues.append(displayValue);
296 displayValue.first =
"Control Network:";
298 displayValues.append(displayValue);
300 displayValue.first =
"Diameter:";
302 displayValues.append(displayValue);
304 displayValue.first =
"Originating Continent:";
305 displayValue.second =
307 displayValues.append(displayValue);
309 displayValue.first =
"Originating Ethnicity:";
310 displayValue.second =
312 displayValues.append(displayValue);
314 displayValue.first =
"Feature Type:";
315 displayValue.second =
317 displayValues.append(displayValue);
319 displayValue.first =
"Center Latitude:";
320 displayValue.second =
322 displayValues.append(displayValue);
324 displayValue.first =
"Center Longitude:";
325 displayValue.second =
327 displayValues.append(displayValue);
329 displayValue.first =
"Northern Latitude:";
330 displayValue.second =
332 displayValues.append(displayValue);
334 displayValue.first =
"Southern Latitude:";
335 displayValue.second =
337 displayValues.append(displayValue);
339 displayValue.first =
"Eastern Longitude:";
340 displayValue.second =
342 displayValues.append(displayValue);
344 displayValue.first =
"Western Longitude:";
345 displayValue.second =
347 displayValues.append(displayValue);
349 displayValue.first =
"Approval Date:";
350 displayValue.second =
352 displayValues.append(displayValue);
354 displayValue.first =
"Approval Status:";
355 displayValue.second =
357 displayValues.append(displayValue);
359 displayValue.first =
"Last Updated:";
360 displayValue.second =
362 displayValues.append(displayValue);
364 displayValue.first =
"Reference:";
365 displayValue.second =
367 displayValues.append(displayValue);
369 displayValue.first =
"Origin:";
370 displayValue.second =
372 displayValues.append(displayValue);
374 displayValue.first =
"URL:";
375 displayValue.second =
377 displayValues.append(displayValue);
379 for (
int i = 0; i < displayValues.count(); i++) {
380 QLabel *titleLabel =
new QLabel(displayValues[i].first);
381 QLabel *valueLabel =
new QLabel( (this->*(displayValues[i].second))() );
382 valueLabel->setOpenExternalLinks(
true);
383 valueLabel->setWordWrap(
true);
385 if (valueLabel->text() !=
"") {
386 layout->addWidget(titleLabel, row, 0);
387 layout->addWidget(valueLabel, row, 1);
405 return getTagText(
"id");
413 return getTagText(
"name");
421 return getTagText(
"cleanName");
431 QString targetStr = target();
434 if (targetStr.toUpper() ==
"MOON")
436 else if (targetStr.toUpper() ==
"MARS")
438 else if (targetStr.toUpper() ==
"MERCURY")
439 cnet =
"Preliminary MESSENGER";
449 QString nameString = name();
450 QString cleanNameString = cleanName();
452 QString displayNameString = nameString;
454 if (nameString != cleanNameString)
455 displayNameString = nameString +
" (" + cleanNameString +
")";
457 return displayNameString;
465 return getTagText(
"target");
473 return getTagText(
"system");
498 return diameter().toString();
522 return centerLatitude().toString();
547 return centerLongitude().toString();
572 return northernLatitude().toString();
597 return southernLatitude().toString();
623 return easternLongitude().toString();
649 return westernLongitude().toString();
658 return getTagText(
"continent");
666 return getTagText(
"ethnicity");
674 return getTagText(
"approvalstatus");
682 return getTagText(
"approvaldate");
690 return getTagText(
"featuretype");
698 return getTagText(
"reference");
706 return getTagText(
"origin");
714 return getTagText(
"lastUpdated");
722 return QUrl(
"http://planetarynames.wr.usgs.gov/Feature/" +
id());
730 return "<a href='" + referenceUrl().toString() +
"'>" +
731 referenceUrl().toString() +
740 return m_approvalStatus;
750 std::swap(m_xmlRepresenation, other.m_xmlRepresenation);
751 std::swap(m_approvalStatus, other.m_approvalStatus);
781 if (m_xmlRepresenation) {
783 m_xmlRepresenation->elementsByTagName(tagName);
786 text = nodes.at(0).toElement().text().trimmed();
801 if (reply->error() == QNetworkReply::NoError) {
807 QDomDocument xmlResultDocument;
808 if (xmlResultDocument.setContent(reply->readAll(),
809 &errorMsg, &errorLine, &errorCol)) {
810 for (QDomNode node = xmlResultDocument.firstChild();
812 node = node.nextSibling()) {
813 QDomElement element = node.toElement();
814 if (element.tagName() ==
"searchresults") {
819 else if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 301) {
820 IString msg =
"The URL has been permanently moved to " +
821 reply->attribute(QNetworkRequest::RedirectionTargetAttribute)
826 QMessageBox::warning(NULL,
"Failed to read nomenclature database result",
827 "An error occurred when parsing the data sent back "
828 "from the nomenclature database. "
829 "The XML result was invalid. The parse is [" +
830 errorMsg +
"] on line [" +
831 QString::number(errorLine) +
"], column [" +
832 QString::number(errorCol) +
"]");
836 QMessageBox::warning(NULL,
"Failed to query nomenclature database",
837 "An error occurred when querying the nomenclature "
838 "database for features that intersect the queried "
839 "ground range. Please make sure you have an active "
840 "internet connection. The error returned was [" +
841 reply->errorString() +
"]");
844 reply->deleteLater();
864 for (QDomNode node = xmlSearchResults.firstChild();
866 node = node.nextSibling()) {
867 QDomElement element = node.toElement();
868 QString approvalID = element.childNodes().item(15).toElement().attribute(
"id");
870 if (element.tagName() ==
"feature") {
872 if(approvalID ==
"5") {
875 else if(approvalID ==
"6") {
878 else if(approvalID ==
"7") {
912 formQuery.addQueryItem(
"additionalInfoColumn",
"true");
913 formQuery.addQueryItem(
"approvalDateColumn",
"true");
914 formQuery.addQueryItem(
"approvalStatusColumn",
"true");
915 formQuery.addQueryItem(
"centerLatLonColumn",
"true");
916 formQuery.addQueryItem(
"cleanFeatureNameColumn",
"true");
917 formQuery.addQueryItem(
"contEthColumn",
"true");
918 formQuery.addQueryItem(
"coordSystemColumn",
"true");
919 formQuery.addQueryItem(
"diameterColumn",
"true");
920 formQuery.addQueryItem(
"featureIDColumn",
"true");
921 formQuery.addQueryItem(
"featureNameColumn",
"true");
922 formQuery.addQueryItem(
"featureTypeCodeColumn",
"true");
923 formQuery.addQueryItem(
"featureTypeColumn",
"true");
924 formQuery.addQueryItem(
"lastUpdatedColumn",
"true");
925 formQuery.addQueryItem(
"latLonColumn",
"true");
926 formQuery.addQueryItem(
"originColumn",
"true");
927 formQuery.addQueryItem(
"quadColumn",
"true");
928 formQuery.addQueryItem(
"referenceColumn",
"true");
929 formQuery.addQueryItem(
"targetColumn",
"true");
932 formQuery.addQueryItem(
"is_0_360",
"true");
933 formQuery.addQueryItem(
"is_planetographic",
"false");
934 formQuery.addQueryItem(
"is_positive_east",
"true");
937 formQuery.addQueryItem(
"displayType",
"XML");
938 formQuery.addQueryItem(
"sort_asc",
"true");
939 formQuery.addQueryItem(
"sort_column",
"name");
942 formQuery.addQueryItem(
"approvalStatus",
"");
943 formQuery.addQueryItem(
"beginDate",
"");
944 formQuery.addQueryItem(
"continent",
"");
945 formQuery.addQueryItem(
"endDate",
"");
946 formQuery.addQueryItem(
"ethnicity",
"");
947 formQuery.addQueryItem(
"feature",
"");
948 formQuery.addQueryItem(
"featureType",
"");
949 formQuery.addQueryItem(
"minFeatureDiameter",
"");
950 formQuery.addQueryItem(
"maxFeatureDiameter",
"");
951 formQuery.addQueryItem(
"reference",
"");
952 formQuery.addQueryItem(
"system",
"");
954 formQuery.addQueryItem(
"target", target.toUpper());
955 formQuery.addQueryItem(
"easternLongitude",
956 QString::number(endLon.degrees()));
957 formQuery.addQueryItem(
"westernLongitude",
958 QString::number(startLon.degrees()));
959 formQuery.addQueryItem(
"northernLatitude",
960 QString::number(endLat.degrees()));
961 formQuery.addQueryItem(
"southernLatitude",
962 QString::number(startLat.degrees()));
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Distance measurement, usually in meters.
@ Kilometers
The distance is being specified in kilometers.
A named feature on a target.
QUrl referenceUrl() const
QString lastUpdated() const
Latitude northernLatitude() const
Longitude centerLongitude() const
QString referenceString() const
Latitude centerLatitude() const
Longitude easternLongitude() const
QString referenceUrlString() const
~Feature()
Clean up allocated memory by this feature.
QString getTagText(QString tagName) const
Get the string value of an element of the XML.
QString cleanName() const
QString easternLongitudeString() const
IAUStatus m_approvalStatus
The approval status of the feature.
QString originatingContinent() const
QString controlNet() const
QString northernLatitudeString() const
Longitude westernLongitude() const
QWidget * toWidget() const
This converts the data in this feature to a widget.
QString diameterString() const
Distance diameter() const
QString centerLongitudeString() const
QString approvalDate() const
QDomElement * m_xmlRepresenation
This is the XML returned by the nomenclature DB.
QString displayName() const
Feature()
Construct a feature with no data.
Feature & operator=(const Feature &rhs)
Assign the values of this feature from the values of rhs.
QString centerLatitudeString() const
QString westernLongitudeString() const
Latitude southernLatitude() const
QString southernLatitudeString() const
QString approvalStatus() const
QString featureType() const
QString originatingEthnicity() const
void swap(Feature &other)
Swap the member data of this feature with another feature.
Feature nomenclature database querier.
void requestFinished(QNetworkReply *)
This is called when a query is done.
QList< Feature > features() const
This gives you the features found in all of the queries so far.
void readSearchResults(QDomElement)
This is a helper method for requestFinished.
bool m_lastQuery
True if all queries have finished.
QList< Feature > * m_features
These are the features identified by the nomenclature database.
void runQuery(QString target, Latitude startLat, Longitude startLon, Latitude endLat, Longitude endLon)
Query the nomenclature database for features inside the given range on the target.
QNetworkRequest * m_request
Network request sent.
void featuresIdentified(FeatureNomenclature *)
This is emitted when a query is completed.
void swap(FeatureNomenclature &other)
Swap the instances *this and other.
bool hasResult() const
Test if any understandable results have been received from the nomenclature database.
QNetworkAccessManager * m_networkMgr
Network manager does request.
IAUStatus
Enumeration of approval statuses.
@ Dropped
When this status is assigned to a feature, the displayed status will be "Dropped, disallowed" and the...
@ NoStatus
When this status is assigned to a feature, there will be no status displayed and the feature will not...
@ Unapproved
When this status is assigned to a feature, the displayed status will be "Never approved by the IAU" a...
@ Approved
When this status is assigned to a feature, the displayed status will be "Adopted by the IAU" and the ...
~FeatureNomenclature()
Frees allocated memory.
FeatureNomenclature()
Instantiate a feature nomenclature.
FeatureNomenclature & operator=(const FeatureNomenclature &other)
This takes on the data from rhs.
void queryFeatures(QString target, Latitude startLat, Longitude startLon, Latitude endLat, Longitude endLon)
Makes sure the longitudinal ranges are correct.
static bool featureDiameterGreaterThan(const FeatureNomenclature::Feature &lhs, const FeatureNomenclature::Feature &rhs)
Compare the diameter of two features.
IAUStatus m_statusApproval
The approval status of the feature from the database.
@ Programmer
This error is for when a programmer made an API call that was illegal.
Adds specific functionality to C++ strings.
This class is designed to encapsulate the concept of a Latitude.
This class is designed to encapsulate the concept of a Longitude.
static QList< QPair< Longitude, Longitude > > to360Range(Longitude startLon, Longitude endLon)
Calculates where the longitude range is in 0-360.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
double toDouble(const QString &string)
Global function to convert from a string to a double.
This is free and unencumbered software released into the public domain.