Ejemplo n.º 1
0
void Kml::generatePolygonalLayer(const GraphicLayer* pGraphicLayer, bool visible, int order, const Layer* pGeoLayer)
{
   VERIFYNRV(pGeoLayer != NULL);
   if (pGraphicLayer == NULL)
   {
      return;
   }
   RasterElement* pGeoElement = dynamic_cast<RasterElement*>(pGeoLayer->getDataElement());
   mXml.pushAddPoint(mXml.addElement("Folder"));
   string name = pGraphicLayer->getDisplayName();
   if (name.empty())
   {
      name = pGraphicLayer->getName();
   }
   mXml.addText(name, mXml.addElement("name"));
   mXml.addText(pGraphicLayer->getDisplayText(), mXml.addElement("description"));
   mXml.addText(visible ? "1" : "0", mXml.addElement("visibility"));
   list<GraphicObject*> objects;
   pGraphicLayer->getObjects(objects);
   for (list<GraphicObject*>::const_iterator object = objects.begin(); object != objects.end(); ++object)
   {
      GraphicObject* pObject = *object;
      if (pObject == NULL)
      {
         continue;
      }
      mXml.pushAddPoint(mXml.addElement("Placemark"));
      mXml.addText(pObject->getName(), mXml.addElement("name"));
      mXml.addText(pObject->isVisible() ? "1" : "0", mXml.addElement("visibility"));
      mXml.pushAddPoint(mXml.addElement("Style"));
      mXml.pushAddPoint(mXml.addElement("PolyStyle"));
      ColorType c = pObject->getFillColor();
      QChar fc('0');
      mXml.addText(QString("%1%2%3%4").arg(c.mAlpha, 2, 16, fc).arg(c.mBlue, 2, 16, fc).arg(
         c.mGreen, 2, 16, fc).arg(c.mRed, 2, 16, fc).toAscii().data(),
         mXml.addElement("color"));
      mXml.addText(pObject->getLineState() ? "1" : "0", mXml.addElement("outline"));
      mXml.addText(pObject->getFillState() ? "1" : "0", mXml.addElement("fill"));
      mXml.popAddPoint(); // PolyStyle
      mXml.pushAddPoint(mXml.addElement("LineStyle"));
      c = pObject->getLineColor();
      mXml.addText(QString("%1%2%3%4").arg(c.mAlpha, 2, 16, fc).arg(c.mBlue, 2, 16, fc).arg(
         c.mGreen, 2, 16, fc).arg(c.mRed, 2, 16, fc).toAscii().data(),
         mXml.addElement("color"));
      mXml.addText(StringUtilities::toXmlString(pObject->getLineWidth()), mXml.addElement("width"));
      mXml.popAddPoint(); // LineStyle
      mXml.popAddPoint(); // Style
      switch (pObject->getGraphicObjectType())
      {
      case MULTIPOINT_OBJECT:
         {
            mXml.pushAddPoint(mXml.addElement("MultiGeometry"));
            vector<LocationType> vertices = static_cast<MultipointObject*>(pObject)->getVertices();
            for (vector<LocationType>::const_iterator vertex = vertices.begin(); vertex != vertices.end(); ++vertex)
            {
               mXml.pushAddPoint(mXml.addElement("Point"));
               mXml.addText(QString::number(order).toAscii().data(), mXml.addElement("drawOrder"));
               LocationType geo = pGeoElement->convertPixelToGeocoord(*vertex);
               mXml.addText(QString("%1,%2").arg(geo.mY, 0, 'f', 10).arg(geo.mX, 0, 'f', 10).toAscii().data(),
                  mXml.addElement("coordinates"));
               mXml.popAddPoint(); // Point
            }
            mXml.popAddPoint();
            break;
         }
      case LINE_OBJECT:
      case POLYLINE_OBJECT:
      case HLINE_OBJECT:
      case VLINE_OBJECT:
      case ROW_OBJECT:
      case COLUMN_OBJECT:
         {
            mXml.pushAddPoint(mXml.addElement("LineString"));
            mXml.addText(QString::number(order).toAscii().data(), mXml.addElement("drawOrder"));
            mXml.addText("1", mXml.addElement("tessellate"));
            QStringList coords;
            vector<LocationType> vertices;
            if (pObject->getGraphicObjectType() == POLYLINE_OBJECT)
            {
               vertices = static_cast<PolylineObject*>(pObject)->getVertices();
            }
            else
            {
               LocationType ll = pObject->getLlCorner();
               LocationType ur = pObject->getUrCorner();
               vertices.push_back(ll);
               vertices.push_back(ur);
            }
            for (vector<LocationType>::const_iterator vertex = vertices.begin(); vertex != vertices.end(); ++vertex)
            {
               LocationType geo = pGeoElement->convertPixelToGeocoord(*vertex);
               coords << QString("%1,%2").arg(geo.mY, 0, 'f', 10).arg(geo.mX, 0, 'f', 10);
            }
            mXml.addText(coords.join(" ").toAscii().data(), mXml.addElement("coordinates"));
            mXml.popAddPoint(); // LineString
            break;
         }
      case RECTANGLE_OBJECT:
      case TRIANGLE_OBJECT:
      case POLYGON_OBJECT:
         {
            mXml.pushAddPoint(mXml.addElement("Polygon"));
            mXml.addText(QString::number(order).toAscii().data(), mXml.addElement("drawOrder"));
            mXml.addText("1", mXml.addElement("tessellate"));
            mXml.pushAddPoint(mXml.addElement("LinearRing", mXml.addElement("outerBoundaryIs")));
            QStringList coords;
            vector<LocationType> vertices;
            LocationType ll = pObject->getLlCorner();
            LocationType ur = pObject->getUrCorner();
            LocationType center = (ll + ur);
            center.mX /= 2.0;
            center.mY /= 2.0;
            if (pObject->getGraphicObjectType() == RECTANGLE_OBJECT)
            {
               vertices.push_back(ll);
               vertices.push_back(LocationType(ll.mX, ur.mY));
               vertices.push_back(ur);
               vertices.push_back(LocationType(ur.mX, ll.mY));
            }
            else if (pObject->getGraphicObjectType() == TRIANGLE_OBJECT)
            {
               double apex = pObject->getApex();
               vertices.push_back(ll);
               vertices.push_back(LocationType(ur.mX, ll.mY));
               vertices.push_back(LocationType(ll.mX + apex * (ur.mX - ll.mX), ur.mY));
               vertices.push_back(ll);
            }
            else
            {
               vertices = static_cast<PolygonObject*>(pObject)->getVertices();
            }
            QPointF qcenter(center.mX, center.mY);
            QMatrix matrix;
            matrix.rotate(pObject->getRotation());
            for (vector<LocationType>::const_iterator vertex = vertices.begin(); vertex != vertices.end(); ++vertex)
            {
               QPointF point(vertex->mX - center.mX, vertex->mY - center.mY);
               point = point * matrix;
               point += qcenter;
               LocationType geo = pGeoElement->convertPixelToGeocoord(LocationType(point.x(), point.y()));
               coords << QString("%1,%2").arg(geo.mY, 0, 'f', 10).arg(geo.mX, 0, 'f', 10);
            }
            mXml.addText(coords.join(" ").toAscii().data(), mXml.addElement("coordinates"));
            mXml.popAddPoint(); // LinearRing
            mXml.popAddPoint(); // Polygon
            break;
         }
      default: // not supported
         break;
      }
      mXml.popAddPoint(); // Placemark
   }
   mXml.popAddPoint(); // Folder
}
Ejemplo n.º 2
0
bool ChangeUpDirection::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList)
{
   if (pInArgList == NULL || pOutArgList == NULL)
   {
      return false;
   }
   ProgressTracker progress(pInArgList->getPlugInArgValue<Progress>(Executable::ProgressArg()),
      "Rotating data.", "app", "{11adadb9-c133-49de-8cf5-a16372da2578}");

   RasterElement* pData = pInArgList->getPlugInArgValue<RasterElement>(Executable::DataElementArg());
   if (pData == NULL)
   {
      progress.report("No data element specified.", 0, ERRORS, true);
      return false;
   }
   bool display = false;
   if (!pInArgList->getPlugInArgValue("Display Results", display))
   {
      progress.report("Unsure if results should be displayed. Invalid argument.", 0, ERRORS, true);
      return false;
   }
   double rotation = 0.0;
   SpatialDataView* pOrigView = NULL;
   if (isBatch())
   {
      if (!pInArgList->getPlugInArgValue("Rotation", rotation))
      {
         progress.report("No rotation specified.", 0, ERRORS, true);
         return false;
      }
   }
   else
   {
      pOrigView = pInArgList->getPlugInArgValue<SpatialDataView>(Executable::ViewArg());
      if (pOrigView == NULL)
      {
         progress.report("No view specified.", 0, ERRORS, true);
         return false;
      }
      GraphicLayer* pLayer = dynamic_cast<GraphicLayer*>(pOrigView->getActiveLayer());
      if (pLayer == NULL)
      {
         pLayer = dynamic_cast<GraphicLayer*>(pOrigView->getTopMostLayer(ANNOTATION));
      }
      GraphicObject* pArrow = NULL;
      if (pLayer != NULL)
      {
         std::list<GraphicObject*> objects;
         pLayer->getObjects(ARROW_OBJECT, objects);
         if (!objects.empty())
         {
            pArrow = objects.back();
         }
         if (objects.size() > 1)
         {
            progress.report("Multiple arrow objects found. Using the most recently added one.", 0, WARNING, true);
         }
      }
      if (pArrow == NULL)
      {
         progress.report("Unable to locate up direction. Add an arrow annotation and re-run this plugin.",
            0, ERRORS, true);
         return false;
      }
      LocationType ur = pArrow->getUrCorner();
      LocationType ll = pArrow->getLlCorner();
      double xlen = ur.mX - ll.mX;
      double ylen = ur.mY - ll.mY;

      // Initial rotatation value. The 90 degrees is due to the difference
      // in the "0 point" (right vs. up). Also account for explicit rotation
      // of the annotation object. Convert this to radians.
      rotation = GeoConversions::convertDegToRad(90 + pArrow->getRotation());

      // Determine a rotation adjustment based on the bounding box
      rotation += atan2(ylen, xlen);
   }

   progress.report("Rotating data.", 10, NORMAL);
   ModelResource<RasterElement> pRotated(pData->copyShallow(pData->getName() + "_rotated", pData->getParent()));
   if (pRotated.get() == NULL)
   {
      progress.report("Unable to create destination raster element.", 0, ERRORS, true);
      return false;
   }

   int defaultBadValue(0);  // the rotate method will handle setting the default bad values into the rotated raster
   if (!RasterUtilities::rotate(pRotated.get(), pData, rotation, defaultBadValue,
      INTERP_NEAREST_NEIGHBOR, progress.getCurrentProgress(), &mAbort))
   {
      // error message already reported by rotate()
      return false;
   }
   pOutArgList->setPlugInArgValue("Rotated Element", pRotated.get());

   if (display)
   {
      SpatialDataWindow* pWindow = static_cast<SpatialDataWindow*>(
         Service<DesktopServices>()->createWindow(pRotated->getName(), SPATIAL_DATA_WINDOW));
      SpatialDataView* pView = (pWindow == NULL) ? NULL : pWindow->getSpatialDataView();
      if (pView == NULL)
      {
         Service<DesktopServices>()->deleteWindow(pWindow);
         progress.report("Unable to create view.", 0, ERRORS, true);
         return false;
      }
      pView->setPrimaryRasterElement(pRotated.get());

      RasterLayer* pLayer = NULL;
      { // scope
         UndoLock lock(pView);
         pLayer = static_cast<RasterLayer*>(pView->createLayer(RASTER, pRotated.get()));
      }
      if (pLayer == NULL)
      {
//#pragma message(__FILE__ "(" STRING(__LINE__) ") : warning : This would be cleaner with a WindowResource. If one " \
//                                              "becomes available, use it instead. (tclarke)")
         Service<DesktopServices>()->deleteWindow(pWindow);
         progress.report("Unable to create layer.", 0, ERRORS, true);
         return false;
      }
      pOutArgList->setPlugInArgValue("View", pView);
   }

   pRotated.release();
   progress.report("Rotation complete.", 100, NORMAL);
   progress.upALevel();
   return true;
}