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