USGS

Isis 3.0 Object Programmers' Reference

Home

FeatureNomenclature.cpp
1 #include "IsisDebug.h"
2 #include "FeatureNomenclature.h"
3 
4 #include <QDebug>
5 #include <QDomElement>
6 #include <QGridLayout>
7 #include <QLabel>
8 #include <QList>
9 #include <QMessageBox>
10 #include <QNetworkAccessManager>
11 #include <QNetworkRequest>
12 #include <QNetworkReply>
13 #include <QPair>
14 #include <QUrl>
15 
16 #include "Distance.h"
17 #include "IException.h"
18 #include "IString.h"
19 #include "iTime.h"
20 #include "Latitude.h"
21 #include "Longitude.h"
22 
23 namespace Isis {
24 
29  m_networkMgr = NULL;
30  m_request = NULL;
31  m_features = NULL;
32 
33  m_networkMgr = new QNetworkAccessManager;
34  connect(m_networkMgr, SIGNAL(finished(QNetworkReply *)),
35  this, SLOT(requestFinished(QNetworkReply *)));
36 
37  m_request = new QNetworkRequest;
38  m_request->setUrl(
39  QUrl("http://planetarynames.wr.usgs.gov/nomenclature/SearchResults"));
40  m_request->setRawHeader("User-Agent",
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");
45  m_lastQuery = true;
46  }
47 
48 
56  m_networkMgr = NULL;
57  m_request = NULL;
58  m_features = NULL;
59 
60  m_networkMgr = new QNetworkAccessManager;
61 
62  connect(m_networkMgr, SIGNAL(finished(QNetworkReply *)),
63  this, SLOT(requestFinished(QNetworkReply *)));
64 
65  m_request = new QNetworkRequest;
66  m_lastQuery = other.m_lastQuery;
67 
68  if (other.m_features)
69  m_features = new QList<Feature>(*other.m_features);
70  }
71 
72 
77  delete m_networkMgr;
78  m_networkMgr = NULL;
79 
80  delete m_request;
81  m_request = NULL;
82 
83  delete m_features;
84  m_features = NULL;
85  }
86 
87 
100  Latitude startLat, Longitude startLon,
101  Latitude endLat, Longitude endLon) {
102 
103  QList< QPair<Longitude, Longitude> > range = Longitude::to360Range(startLon, endLon);
104 
105  if (!range.isEmpty()) {
106  startLon = range[0].first;
107  endLon = range[0].second;
108  }
109 
110  if (range.size() > 1) {
111 
112  Longitude startLon2 = range[1].first;
113  Longitude endLon2 = range[1].second;
114 
115  runQuery(target, startLat, startLon, endLat, endLon);
116  runQuery(target, startLat, startLon2, endLat, endLon2);
117 
118  m_lastQuery = false;
119  }
120  else {
121  runQuery(target, startLat, startLon, endLat, endLon);
122 
123  m_lastQuery = true;
124  }
125  }
126 
127 
136  QList<Feature> featureList;
137 
138  if (m_features)
139  featureList = *m_features;
140 
141  return featureList;
142  }
143 
144 
152  return (m_features != NULL);
153  }
154 
155 
162  std::swap(m_networkMgr, other.m_networkMgr);
163  std::swap(m_request, other.m_request);
164  std::swap(m_features, other.m_features);
165  }
166 
167 
176  const FeatureNomenclature &rhs) {
177  FeatureNomenclature tmp(rhs);
178  swap(tmp);
179  return *this;
180  }
181 
182 
193  const FeatureNomenclature::Feature &lhs,
194  const FeatureNomenclature::Feature &rhs) {
195  Distance lhsDiameter = lhs.diameter();
196  Distance rhsDiameter = rhs.diameter();
197 
198  bool greaterThan = false;
199  if (lhsDiameter.isValid() && rhsDiameter.isValid()) {
200  greaterThan = (lhsDiameter > rhsDiameter);
201  }
202  else {
203  greaterThan = lhsDiameter.isValid();
204  }
205 
206  return greaterThan;
207  }
208 
209 
214  m_xmlRepresenation = NULL;
216  }
217 
218 
222  FeatureNomenclature::Feature::Feature(QDomElement searchResultFeature, IAUStatus status) {
223  m_xmlRepresenation = NULL;
224  m_xmlRepresenation = new QDomElement(searchResultFeature);
225  m_approvalStatus = status;
226  }
227 
228 
235  m_xmlRepresenation = NULL;
236  // QDomElement does a shallow copy.
237  m_approvalStatus = other.m_approvalStatus;
238  m_xmlRepresenation = new QDomElement(*other.m_xmlRepresenation);
239  }
240 
241 
246  delete m_xmlRepresenation;
247  m_xmlRepresenation = NULL;
248  }
249 
250 
259  QWidget *widget = new QWidget;
260 
261  QGridLayout *layout = new QGridLayout;
262  widget->setLayout(layout);
263 
264  int row = 0;
265 
266  QLabel *titleLabel = new QLabel("<h2>Feature Details</h2>");
267  layout->addWidget(titleLabel, row, 0, 1, 2);
268  row++;
269 
271  displayValues;
272 
274  displayValue;
275 
276  displayValue.first = "Feature Name:";
277  displayValue.second = &FeatureNomenclature::Feature::displayName;
278  displayValues.append(displayValue);
279 
280 // displayValue.first = "Feature Name (clean):";
281 // displayValue.second = &FeatureNomenclature::Feature::cleanName;
282 // displayValues.append(displayValue);
283 
284  displayValue.first = "Feature ID:";
285  displayValue.second = &FeatureNomenclature::Feature::id;
286  displayValues.append(displayValue);
287 
288  displayValue.first = "Target:";
289  displayValue.second = &FeatureNomenclature::Feature::target;
290  displayValues.append(displayValue);
291 
292  displayValue.first = "System:";
293  displayValue.second = &FeatureNomenclature::Feature::system;
294  displayValues.append(displayValue);
295 
296  displayValue.first = "Control Network:";
297  displayValue.second = &FeatureNomenclature::Feature::controlNet;
298  displayValues.append(displayValue);
299 
300  displayValue.first = "Diameter:";
301  displayValue.second = &FeatureNomenclature::Feature::diameterString;
302  displayValues.append(displayValue);
303 
304  displayValue.first = "Originating Continent:";
305  displayValue.second =
307  displayValues.append(displayValue);
308 
309  displayValue.first = "Originating Ethnicity:";
310  displayValue.second =
312  displayValues.append(displayValue);
313 
314  displayValue.first = "Feature Type:";
315  displayValue.second =
317  displayValues.append(displayValue);
318 
319  displayValue.first = "Center Latitude:";
320  displayValue.second =
322  displayValues.append(displayValue);
323 
324  displayValue.first = "Center Longitude:";
325  displayValue.second =
327  displayValues.append(displayValue);
328 
329  displayValue.first = "Northern Latitude:";
330  displayValue.second =
332  displayValues.append(displayValue);
333 
334  displayValue.first = "Southern Latitude:";
335  displayValue.second =
337  displayValues.append(displayValue);
338 
339  displayValue.first = "Eastern Longitude:";
340  displayValue.second =
342  displayValues.append(displayValue);
343 
344  displayValue.first = "Western Longitude:";
345  displayValue.second =
347  displayValues.append(displayValue);
348 
349  displayValue.first = "Approval Date:";
350  displayValue.second =
352  displayValues.append(displayValue);
353 
354  displayValue.first = "Approval Status:";
355  displayValue.second =
357  displayValues.append(displayValue);
358 
359  displayValue.first = "Last Updated:";
360  displayValue.second =
362  displayValues.append(displayValue);
363 
364  displayValue.first = "Reference:";
365  displayValue.second =
367  displayValues.append(displayValue);
368 
369  displayValue.first = "Origin:";
370  displayValue.second =
372  displayValues.append(displayValue);
373 
374  displayValue.first = "URL:";
375  displayValue.second =
377  displayValues.append(displayValue);
378 
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);
384 
385  if (valueLabel->text() != "") {
386  layout->addWidget(titleLabel, row, 0);
387  layout->addWidget(valueLabel, row, 1);
388  }
389  else {
390  delete titleLabel;
391  delete valueLabel;
392  }
393 
394  row++;
395  }
396 
397  return widget;
398  }
399 
400 
405  return getTagText("id");
406  }
407 
408 
413  return getTagText("name");
414  }
415 
416 
421  return getTagText("cleanName");
422  }
423 
424 
431  QString targetStr = target();
432  QString cnet = "";
433 
434  if (targetStr.toUpper() == "MOON")
435  cnet = "LOLA";
436  else if (targetStr.toUpper() == "MARS")
437  cnet = "MDIM 2.1";
438  else if (targetStr.toUpper() == "MERCURY")
439  cnet = "Preliminary MESSENGER";
440 
441  return cnet;
442  }
443 
444 
449  QString nameString = name();
450  QString cleanNameString = cleanName();
451 
452  QString displayNameString = nameString;
453 
454  if (nameString != cleanNameString)
455  displayNameString = nameString + " (" + cleanNameString + ")";
456 
457  return displayNameString;
458  }
459 
460 
465  return getTagText("target");
466  }
467 
468 
473  return getTagText("system");
474  }
475 
476 
481  Distance result;
482 
483  try {
484  result = Distance(toDouble(getTagText("diameter")),
486  }
487  catch (IException &) {
488  }
489 
490  return result;
491  }
492 
493 
498  return diameter().toString();
499  }
500 
501 
506  Latitude result;
507 
508  try {
509  result = Latitude(toDouble(getTagText("centerlatitude")), Angle::Degrees);
510  }
511  catch (IException &) {
512  }
513 
514  return result;
515  }
516 
517 
522  return centerLatitude().toString();
523  }
524 
525 
530  Longitude result;
531 
532  try {
533  result = Longitude(toDouble(getTagText("centerlongitude")),
535  }
536  catch (IException &) {
537  }
538 
539  return result;
540  }
541 
542 
547  return centerLongitude().toString();
548  }
549 
550 
555  Latitude result;
556 
557  try {
558  result = Latitude(toDouble(getTagText("northernLatitude")), Angle::Degrees);
559  }
560  catch (IException &) {
561  }
562 
563  return result;
564  }
565 
566 
572  return northernLatitude().toString();
573  }
574 
575 
580  Latitude result;
581 
582  try {
583  result = Latitude(toDouble(getTagText("southernLatitude")), Angle::Degrees);
584  }
585  catch (IException &) {
586  }
587 
588  return result;
589  }
590 
591 
597  return southernLatitude().toString();
598  }
599 
600 
605  Longitude result;
606 
607  try {
608  result = Longitude(toDouble(getTagText("easternLongitude")),
610  }
611  catch (IException &) {
612  }
613 
614  return result;
615  }
616 
617 
623  return easternLongitude().toString();
624  }
625 
626 
631  Longitude result;
632 
633  try {
634  result = Longitude(toDouble(getTagText("westernLongitude")),
636  }
637  catch (IException &) {
638  }
639 
640  return result;
641  }
642 
643 
649  return westernLongitude().toString();
650  }
651 
652 
658  return getTagText("continent");
659  }
660 
661 
666  return getTagText("ethnicity");
667  }
668 
669 
674  return getTagText("approvalstatus");
675  }
676 
677 
682  return getTagText("approvaldate");
683  }
684 
685 
690  return getTagText("featuretype");
691  }
692 
693 
698  return getTagText("reference");
699  }
700 
701 
706  return getTagText("origin");
707  }
708 
709 
714  return getTagText("lastUpdated");
715  }
716 
717 
722  return QUrl("http://planetarynames.wr.usgs.gov/Feature/" + id());
723  }
724 
725 
730  return "<a href='" + referenceUrl().toString() + "'>" +
731  referenceUrl().toString() +
732  "</a>";
733  }
734 
735 
740  return m_approvalStatus;
741  }
742 
743 
750  std::swap(m_xmlRepresenation, other.m_xmlRepresenation);
751  std::swap(m_approvalStatus, other.m_approvalStatus);
752 
753  }
754 
755 
763  const Feature &rhs) {
764  Feature copy(rhs);
765  swap(copy);
766  return *this;
767  }
768 
769 
778  QString FeatureNomenclature::Feature::getTagText(QString tagName) const {
779  QString text;
780 
781  if (m_xmlRepresenation) {
782  QDomNodeList nodes =
783  m_xmlRepresenation->elementsByTagName(tagName);
784 
785  if (nodes.count())
786  text = nodes.at(0).toElement().text().trimmed();
787  }
788 
789  return text;
790  }
791 
792 
800  void FeatureNomenclature::requestFinished(QNetworkReply *reply) {
801  if (reply->error() == QNetworkReply::NoError) {
802 
803  QString errorMsg;
804  int errorLine;
805  int errorCol;
806 
807  QDomDocument xmlResultDocument;
808  if (xmlResultDocument.setContent(reply->readAll(),
809  &errorMsg, &errorLine, &errorCol)) {
810  for (QDomNode node = xmlResultDocument.firstChild();
811  !node.isNull();
812  node = node.nextSibling()) {
813  QDomElement element = node.toElement();
814  if (element.tagName() == "searchresults") {
815  readSearchResults(element);
816  }
817  }
818  }
819  else {
820  QMessageBox::warning(NULL, "Failed to read nomenclature database result",
821  "An error occurred when parsing the data sent back "
822  "from the nomenclature database. "
823  "The XML result was invalid. The parse is [" +
824  errorMsg + "] on line [" +
825  QString(errorLine) +"], column [" +
826  QString(errorCol) + "]");
827  }
828  }
829  else {
830  QMessageBox::warning(NULL, "Failed to query nomenclature database",
831  "An error occurred when querying the nomenclature "
832  "database for features that intersect the qeuried "
833  "ground range. Please make sure you have an active "
834  "internet connection. The error returned was [" +
835  reply->errorString() + "]");
836  }
837 
838  reply->deleteLater();
839 
840  if (m_lastQuery) {
841  emit featuresIdentified(this);
842  }
843  m_lastQuery = true;
844  }
845 
846 
853  void FeatureNomenclature::readSearchResults(QDomElement xmlSearchResults) {
854  ASSERT(xmlSearchResults.tagName() == "searchresults");
855 
856  if (!m_features)
858 
859  for (QDomNode node = xmlSearchResults.firstChild();
860  !node.isNull();
861  node = node.nextSibling()) {
862  QDomElement element = node.toElement();
863  QString approvalID = element.childNodes().item(15).toElement().attribute("id");
864 
865  if (element.tagName() == "feature") {
866 
867  if(approvalID == "5") {
869  }
870  else if(approvalID == "6") {
872  }
873  else if(approvalID == "7") {
875  }
876  else {
878  }
879 
880  m_features->append(Feature(element, m_statusApproval));
881  }
882  }
883  }
884 
885 
900  void FeatureNomenclature::runQuery(QString target,
901  Latitude startLat, Longitude startLon,
902  Latitude endLat, Longitude endLon) {
903 
904  QUrl encodedFormData;
905 
906  // List of XML fields we want from the server
907  encodedFormData.addQueryItem("additionalInfoColumn", "true");
908  encodedFormData.addQueryItem("approvalDateColumn", "true");
909  encodedFormData.addQueryItem("approvalStatusColumn", "true");
910  encodedFormData.addQueryItem("centerLatLonColumn", "true");
911  encodedFormData.addQueryItem("cleanFeatureNameColumn", "true");
912  encodedFormData.addQueryItem("contEthColumn", "true");
913  encodedFormData.addQueryItem("coordSystemColumn", "true");
914  encodedFormData.addQueryItem("diameterColumn", "true");
915  encodedFormData.addQueryItem("featureIDColumn", "true");
916  encodedFormData.addQueryItem("featureNameColumn", "true");
917  encodedFormData.addQueryItem("featureTypeCodeColumn", "true");
918  encodedFormData.addQueryItem("featureTypeColumn", "true");
919  encodedFormData.addQueryItem("lastUpdatedColumn", "true");
920  encodedFormData.addQueryItem("latLonColumn", "true");
921  encodedFormData.addQueryItem("originColumn", "true");
922  encodedFormData.addQueryItem("quadColumn", "true");
923  encodedFormData.addQueryItem("referenceColumn", "true");
924  encodedFormData.addQueryItem("targetColumn", "true");
925 
926  // Data units
927  encodedFormData.addQueryItem("is_0_360", "true");
928  encodedFormData.addQueryItem("is_planetographic", "false");
929  encodedFormData.addQueryItem("is_positive_east", "true");
930 
931  // Format parameters
932  encodedFormData.addQueryItem("displayType", "XML");
933  encodedFormData.addQueryItem("sort_asc", "true");
934  encodedFormData.addQueryItem("sort_column", "name");
935 
936  // Search critera (required even if blank)
937  encodedFormData.addQueryItem("approvalStatus", "");
938  encodedFormData.addQueryItem("beginDate", "");
939  encodedFormData.addQueryItem("continent", "");
940  encodedFormData.addQueryItem("endDate", "");
941  encodedFormData.addQueryItem("ethnicity", "");
942  encodedFormData.addQueryItem("feature", "");
943  encodedFormData.addQueryItem("featureType", "");
944  encodedFormData.addQueryItem("minFeatureDiameter", "");
945  encodedFormData.addQueryItem("maxFeatureDiameter", "");
946  encodedFormData.addQueryItem("reference", "");
947  encodedFormData.addQueryItem("system", "");
948 
949  encodedFormData.addQueryItem("target", target.toUpper());
950  encodedFormData.addQueryItem("easternLongitude",
951  QString::number(endLon.degrees()));
952  encodedFormData.addQueryItem("westernLongitude",
953  QString::number(startLon.degrees()));
954  encodedFormData.addQueryItem("northernLatitude",
955  QString::number(endLat.degrees()));
956  encodedFormData.addQueryItem("southernLatitude",
957  QString::number(startLat.degrees()));
958 
959  m_networkMgr->post(*m_request, QByteArray(encodedFormData.encodedQuery()));
960  }
961 }