1 #include "MosaicAreaTool.h" 
    7 #include <QDoubleValidator> 
    8 #include <QGraphicsEllipseItem> 
    9 #include <QGraphicsScene> 
   10 #include <QGridLayout> 
   14 #include <QMessageBox> 
   15 #include <QPushButton> 
   20 #include "FindSpotGraphicsItem.h" 
   21 #include "MosaicGraphicsView.h" 
   22 #include "MosaicSceneWidget.h" 
   23 #include "Projection.h" 
   24 #include "TProjection.h" 
   25 #include "PvlKeyword.h" 
   26 #include "PvlObject.h" 
   43     connect(scene, SIGNAL(projectionChanged(
Projection *)),
 
   44             this, SLOT(userChangedBox()));
 
   52   void MosaicAreaTool::userChangedBox() {
 
   53     bool latValid = 
false;
 
   54     bool lonValid = 
false;
 
   55     bool areaValid = 
false;
 
   64     if(latitude != 
"Null" && latitude != 
"") {
 
   66       QValidator::State validLat =
 
   68       if(validLat != QValidator::Acceptable) {
 
   69         QMessageBox::warning(getWidget(), 
"Error",
 
   70                             "Latitude value must be in the range -90 to 90",
 
   71                             QMessageBox::Ok, QMessageBox::NoButton,
 
   72                             QMessageBox::NoButton);
 
   81     if(longitude != 
"Null" && longitude != 
"" && latValid) {
 
   83       QValidator::State validLon =
 
   85       if(validLon != QValidator::Acceptable) {
 
   86         QMessageBox::warning(getWidget(), 
"Error",
 
   87                             "Longitude value invalid",
 
   88                             QMessageBox::Ok, QMessageBox::NoButton,
 
   89                             QMessageBox::NoButton);
 
   97     if(areaString != 
"Null" && areaString != 
"" && latValid && lonValid) {
 
   99       QValidator::State validArea =
 
  101       if(validArea != QValidator::Acceptable) {
 
  102         QMessageBox::warning(getWidget(), 
"Error",
 
  103                             "Area value invalid",
 
  104                             QMessageBox::Ok, QMessageBox::NoButton,
 
  105                             QMessageBox::NoButton);
 
  113     if(latValid && lonValid && areaValid) {
 
  114       double lat = IString(latitude.toStdString()).ToDouble();
 
  115       double lon = IString(longitude.toStdString()).ToDouble();
 
  116       double area = IString(areaString.toStdString()).ToDouble();
 
  118       Projection *projection = getWidget()->getProjection();
 
  122         TProjection * tproj = (TProjection *) projection;
 
  123         if (tproj->SetGround(lat, lon)) {
 
  124           QPointF scenePos(projection->XCoord(), -1 * projection->YCoord());
 
  125           QRectF sceneRect(getWidget()->getView()->sceneRect());
 
  127           if(sceneRect.contains(scenePos)) {
 
  137             double xStep = latLonRange.width() / 100.0;
 
  138             double yStep = latLonRange.height() / 100.0;
 
  140             bool hasPole = (latLonRange.top() == -90 ||
 
  141                             latLonRange.bottom() == 90);
 
  143             double yPos = latLonRange.top();
 
  145               for(
double xPos = latLonRange.left();
 
  146                 xPos <= latLonRange.right();
 
  148                 if (tproj->SetGround(yPos, xPos)) {
 
  149                   QPointF pos(tproj->XCoord(), -1 * tproj->YCoord());
 
  155             double xPos = latLonRange.right();
 
  156             for (
double yPos = latLonRange.top();
 
  157                 !hasPole && yPos <= latLonRange.bottom();
 
  159               if (tproj->SetGround(yPos, xPos)) {
 
  160                 QPointF pos(tproj->XCoord(), -1 * tproj->YCoord());
 
  165             yPos = latLonRange.bottom();
 
  167               for (
double xPos = latLonRange.right();
 
  168                 xPos >= latLonRange.left();
 
  170                 if (tproj->SetGround(yPos, xPos)) {
 
  171                   QPointF pos(tproj->XCoord(), -1 * tproj->YCoord());
 
  177             xPos = latLonRange.left();
 
  178             for (
double yPos = latLonRange.bottom();
 
  179               !hasPole && yPos >= latLonRange.top();
 
  181               if (tproj->SetGround(yPos, xPos)) {
 
  182                 QPointF pos(tproj->XCoord(), -1 * tproj->YCoord());
 
  187             if (boxPoly.size() > 0) {
 
  188               boxPoly << boxPoly[0];
 
  190               m_box = 
new QGraphicsPolygonItem(boxPoly);
 
  191               m_box->setZValue(DBL_MAX);
 
  194               pen.setCosmetic(
true);
 
  197               getWidget()->getScene()->addItem(m_box);
 
  198               getWidget()->getView()->centerOn(scenePos);
 
  202           QString message = 
"Lat/Lon not within this view.";
 
  203           QMessageBox::information(getWidget(), 
"Cannot Calculate Box",
 
  204                                   message, QMessageBox::Ok);
 
  222     m_action->setIcon(
getIcon(
"qmos_area.png"));
 
  223     m_action->setToolTip(
"Show Area (a)");
 
  224     m_action->setShortcut(Qt::Key_A);
 
  226       "<b>Function:</b>  Draw a box given a distance centered on a " 
  227       "latitude/longitude.<br><br>" 
  228       "This tool draws a black square, given an edge length in meters, " 
  229       "centered on a latitude/longitude point. This box would be a square on " 
  230       "the surface of the target, and is designed to be modified and warped by " 
  231       "the current projection." 
  232       "<p><b>Shortcut:</b>  a</p> ";
 
  233     m_action->setWhatsThis(text);
 
  240     m_latLineEdit->setValidator(
new QDoubleValidator(-90.0, 90.0, 99, 
this));
 
  249     QLabel *latLabel = 
new QLabel(
"Latitude");
 
  250     QLabel *lonLabel = 
new QLabel(
"Longitude");
 
  251     QLabel *areaLabel = 
new QLabel(
"Size (meters)");
 
  252     areaLabel->setToolTip(
"This is the width and the height of the box");
 
  255     QPushButton *okButton = 
new QPushButton(
"Update Box");
 
  256     connect(okButton, SIGNAL(clicked()), 
this, SLOT(userChangedBox()));
 
  258     QPushButton *clearButton = 
new QPushButton(
"Clear Box");
 
  259     connect(clearButton, SIGNAL(clicked()), 
this, SLOT(clearBox()));
 
  262     QHBoxLayout *actionLayout = 
new QHBoxLayout();
 
  263     actionLayout->addWidget(latLabel);
 
  265     actionLayout->addWidget(lonLabel);
 
  267     actionLayout->addWidget(areaLabel);
 
  269     actionLayout->addWidget(okButton);
 
  270     actionLayout->addWidget(clearButton);
 
  271     actionLayout->addStretch(1);
 
  272     actionLayout->setMargin(0);
 
  275     toolBarWidget->setLayout(actionLayout);
 
  277     return toolBarWidget;
 
  292   PvlObject MosaicAreaTool::toPvl()
 const {
 
  306   void MosaicAreaTool::fromPvl(
const PvlObject &obj) {
 
  307     if(obj.hasKeyword(
"Visible")) {
 
  308       if(obj.hasKeyword(
"Latitude") && obj[
"Latitude"][0] != 
"Null")
 
  311       if(obj.hasKeyword(
"Longitude") && obj[
"Longitude"][0] != 
"Null")
 
  314       if(obj.hasKeyword(
"Area") && obj[
"Area"][0] != 
"Null")
 
  317       if(
toBool(obj[
"Visible"][0]) != 
false) {
 
  324   QString MosaicAreaTool::projectPvlObjectName()
 const {
 
  325     return "MosaicAreaTool";
 
  343   void MosaicAreaTool::mouseButtonRelease(QPointF mouseLoc, Qt::MouseButton s) {
 
  347     if(s == Qt::LeftButton) {
 
  350       if(tproj && getWidget()->getView()->sceneRect().contains(mouseLoc)) {
 
  352           if(m_drawBox != NULL) {
 
  370   void MosaicAreaTool::clearBox() {
 
  372       getWidget()->getScene()->removeItem(m_box);
 
  389     Distance distanceFromCenter = size / 2.0;
 
  390     QRectF latLonBoundingBox;
 
  398       bool longitudeWraps = 
false;
 
  406       latLonBoundingBox.setTop( (centerLat - deltaLat).degrees() );
 
  408       if (latLonBoundingBox.top() < -90 && centerLatLon.y() != -90) {
 
  411         if (centerLatLon.y() != 90) {
 
  412           qWarning(
"The pole is included in the area but not centered");
 
  413           centerLatLon.setY(-90);
 
  419       else if (centerLatLon.y() == -90) {
 
  420         longitudeWraps = 
true;
 
  423       latLonBoundingBox.setBottom( (centerLat + deltaLat).degrees() );
 
  425       if (latLonBoundingBox.bottom() > 90 && centerLatLon.y() != 90) {
 
  428         if (centerLatLon.y() != -90) {
 
  429           qWarning(
"The pole is included in the area but not centered");
 
  430           centerLatLon.setY(90);
 
  436       else if (centerLatLon.y() == 90) {
 
  437         longitudeWraps = 
true;
 
  442           asin( sin(centerLat.
radians()) /
 
  443                 cos( distanceFromCenter / radius ) ),
 
  446       double valueToASin = sin(distanceFromCenter / radius) /
 
  449       if(valueToASin < -1 || valueToASin > 1)
 
  450         longitudeWraps = 
true;
 
  453       if (longitudeWraps) {
 
  455           latLonBoundingBox.setLeft( 0 );
 
  456           latLonBoundingBox.setRight( 360 );
 
  459           latLonBoundingBox.setLeft( -180 );
 
  460           latLonBoundingBox.setRight( 180 );
 
  465             asin( sin(distanceFromCenter / radius) /
 
  468         latLonBoundingBox.setLeft( (centerLon - deltaLon).degrees() );
 
  469         latLonBoundingBox.setRight( (centerLon + deltaLon).degrees() );
 
  473     return latLonBoundingBox;