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 }
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; }