示例#1
0
AddVertices::AddVertices(MultipointObjectImp* pObject, const vector<LocationType>& oldVertices,
                         const vector<LocationType>& oldGeoVertices, const vector<LocationType>& newVertices,
                         const vector<LocationType>& newGeoVertices) :
   UndoAction(dynamic_cast<SessionItem*>(pObject)),
   mOldVertices(oldVertices),
   mOldGeoVertices(oldGeoVertices),
   mNewVertices(newVertices),
   mNewGeoVertices(newGeoVertices)
{
   if (pObject != NULL)
   {
      GraphicLayer* pLayer = pObject->getLayer();
      if (pLayer != NULL)
      {
         View* pView = pLayer->getView();
         if (pView != NULL)
         {
            mViewId = pView->getId();
         }

         mLayerId = pLayer->getId();
      }
   }

   setText("Add Vertices");
}
示例#2
0
void ScaleBarObjectImp::updateAttachments()
{
   if (mpGeoreference.get() == NULL)
   {
      const RasterElement* pGeoreference = getGeoreferenceElement();
      if (pGeoreference != NULL)
      {
         mpGeoreference.reset(const_cast<RasterElement*>(pGeoreference));
         mXgsd = GeoAlgorithms::getXaxisGSD(pGeoreference);
         mNeedsLayout = true;
      }
   }

   if (mpView.get() == NULL)
   {
      GraphicLayer* pLayer = getLayer();
      if (pLayer != NULL)
      {
         PerspectiveView* pPerspectiveView = dynamic_cast<PerspectiveView*>(pLayer->getView());
         if (pPerspectiveView != NULL)
         {
            mpView.reset(pPerspectiveView);
            mNeedsLayout = true;
         }
      }
   }
}
void MeasurementObjectImp::updateGeoreferenceAttachment()
{
   if (mpGeoreference.get() != NULL)
   {
      return;
   }

   RasterElement* pGeoreference = NULL;

   // Must find Georeference through the view, since the GraphicElement is a root element.
   GraphicLayer* pLayer = getLayer();
   if (pLayer != NULL)
   {
      SpatialDataView* pView = dynamic_cast<SpatialDataView*>(pLayer->getView());
      if (pView != NULL)
      {
         LayerList* pLayerList = pView->getLayerList();
         VERIFYNRV(pLayerList != NULL);
         pGeoreference = pLayerList->getPrimaryRasterElement();
      }
   }

   if (pGeoreference != NULL && pGeoreference->isGeoreferenced())
   {
      mpGeoreference.reset(pGeoreference);
      enableGeo();
      generateGeoStrings();
   }
}
示例#4
0
void FrameLabelObjectImp::updateAnimationList(bool force)
{
   if (getAutoMode() == false)
   {
      return;
   }

   const bool wasLocked = getLocked();
   if (force == true)
   {
      setLocked(false);
   }

   if (getLocked() == false)
   {
      View* pView = NULL;
      GraphicLayer* pLayer = getLayer();
      if (pLayer != NULL)
      {
         pView = pLayer->getView();
      }

      setAnimations(pView);
   }

   if (force == true)
   {
      setLocked(wasLocked);
   }
}
void linkInputLabels()
{
    GraphicLayer* layer = GraphicLayer::sharedLayer();
    CCArray* children = layer->getChildren();
    if(children != NULL)
    {
        for(int i = 0 ; i < children->count(); i++)
        {
            RawObject* child = (RawObject*)children->objectAtIndex(i);
            //Force actualization of content size and fontSize after everything is loaded because the nodeToWorldTransform is only right after
            if(isKindOfClass(child, InputLabel))
            {
                InputLabel* input = (InputLabel*)child;
                child->getNode()->setContentSize(child->getNode()->getContentSize());
                if(input->getOriginalInfos() != NULL)
                {
                    ((ui::EditBox*)child->getNode())->setFontSize(input->getOriginalInfos()->getFontSize());
                }
            }
            if((isKindOfClass(child, InputLabel)) && child->getEventInfos()->objectForKey("LinkTo") != NULL && isKindOfClass(child->getEventInfos()->objectForKey("LinkTo"), CCString))
            {
                InputLabel* input = (InputLabel*)child;
                if(input->getLinkTo() == NULL)
                {
                    CCString* linkTo = (CCString*)child->getEventInfos()->objectForKey("LinkTo");
                    CCArray* matchs = layer->allObjectsWithName(linkTo);
                    for(long j = 0; j < matchs->count(); j++)
                    {
                        RawObject* match = (RawObject*)matchs->objectAtIndex(j);
                        if(isKindOfClass(match, LabelTTF))
                        {
                            input->setLinkTo((LabelTTF*)match);
                            j = matchs->count();
                        }
                    }
                }
            }
            else if((isKindOfClass(child, DropDownList)) && child->getEventInfos()->objectForKey("LinkTo") != NULL && isKindOfClass(child->getEventInfos()->objectForKey("LinkTo"), CCString))
            {
                DropDownList* dropDownList = (DropDownList*)child;
                if(dropDownList->getLinkTo() == NULL)
                {
                    CCString* linkTo = (CCString*)child->getEventInfos()->objectForKey("LinkTo");
                    CCArray* matchs = layer->allObjectsWithName(linkTo);
                    for(long j = 0; j < matchs->count(); j++)
                    {
                        RawObject* match = (RawObject*)matchs->objectAtIndex(j);
                        if(isKindOfClass(match, LabelTTF))
                        {
                            dropDownList->setLinkTo((LabelTTF*)match);
                            j = matchs->count();
                        }
                    }
                }
            }
        }
    }
}
示例#6
0
void GroupUngroupGraphicObjects::group()
{
   GraphicLayer* pLayer = dynamic_cast<GraphicLayer*>(getSessionItem());
   if (pLayer != NULL)
   {
      list<GraphicObject*> selectedObjects;
      pLayer->getSelectedObjects(selectedObjects);
      pLayer->deselectAllObjects();

      for (list<string>::const_iterator iter = mObjectIds.begin(); iter != mObjectIds.end(); ++iter)
      {
         string objectId = *iter;
         if (objectId.empty() == false)
         {
            string viewId;

            View* pView = pLayer->getView();
            if (pView != NULL)
            {
               viewId = pView->getId();
            }

            GraphicObject* pObject = GraphicUndoUtilities::getObject(viewId, pLayer->getId(), objectId);
            if (pObject != NULL)
            {
               pLayer->selectObject(pObject);
            }
         }
      }

      pLayer->groupSelection();

      list<GraphicObject*> newSelectedObjects;
      pLayer->getSelectedObjects(newSelectedObjects);
      VERIFYNRV(newSelectedObjects.size() == 1);

      GraphicGroup* pGroup = dynamic_cast<GraphicGroup*>(newSelectedObjects.front());
      VERIFYNRV(pGroup != NULL);

      for (list<GraphicObject*>::iterator iter = selectedObjects.begin(); iter != selectedObjects.end(); ++iter)
      {
         GraphicObject* pObject = *iter;
         if ((pObject != NULL) && (pGroup->hasObject(pObject) == false))
         {
            pLayer->selectObject(pObject);
         }
      }

      string oldGroupId = mGroupId;
      mGroupId = pGroup->getId();
      emit sessionItemChanged(oldGroupId, mGroupId);
   }
}
示例#7
0
void reorderZindex()
{
    GraphicLayer* layer = GraphicLayer::sharedLayer();
    CCArray* children = layer->getChildren();
    if(children != NULL)
    {
        for(int i = 0 ; i < children->count(); i++)
        {
            RawObject* child = (RawObject*)children->objectAtIndex(i);
            if(child->getZOrder() != 0)
            {
                layer->reorderChild(child, child->getZOrder());
            }
        }
    }
}
示例#8
0
void GraphicLayerMemento::toLayer(Layer* pLayer) const
{
   GraphicLayer* pGraphicLayer = dynamic_cast<GraphicLayer*>(pLayer);
   if (pGraphicLayer != NULL)
   {
      GraphicElement* pElement = dynamic_cast<GraphicElement*>(pGraphicLayer->getDataElement());
      if (pElement != NULL)
      {
         GraphicGroupImp* pGroup = dynamic_cast<GraphicGroupImp*>(pElement->getGroup());
         if (pGroup != NULL)
         {
            pGroup->setLayer(pGraphicLayer);
         }
      }
   }
}
示例#9
0
void GroupUngroupGraphicObjects::ungroup()
{
   GraphicLayer* pLayer = dynamic_cast<GraphicLayer*>(getSessionItem());
   if ((pLayer != NULL) && (mGroupId.empty() == false))
   {
      string viewId;

      View* pView = pLayer->getView();
      if (pView != NULL)
      {
         viewId = pView->getId();
      }

      GraphicGroup* pGroup = dynamic_cast<GraphicGroup*>(GraphicUndoUtilities::getObject(viewId,
         pLayer->getId(), mGroupId));
      if (pGroup != NULL)
      {
         list<GraphicObject*> selectedObjects;
         pLayer->getSelectedObjects(selectedObjects);

         pLayer->deselectAllObjects();
         pLayer->selectObject(pGroup);
         pLayer->ungroupSelection();

         list<GraphicObject*> objects;
         pLayer->getSelectedObjects(objects);

         mObjectIds.clear();
         for (list<GraphicObject*>::iterator iter = objects.begin(); iter != objects.end(); ++iter)
         {
            GraphicObject* pObject = *iter;
            if (pObject != NULL)
            {
               string objectId = pObject->getId();
               if (objectId.empty() == false)
               {
                  mObjectIds.push_back(objectId);
               }
            }
         }

         for (list<GraphicObject*>::iterator iter = selectedObjects.begin(); iter != selectedObjects.end(); ++iter)
         {
            GraphicObject* pObject = *iter;
            if ((pObject != NULL) && (pObject != pGroup))
            {
               pLayer->selectObject(pObject);
            }
         }
      }
   }
}
示例#10
0
QFont TextObjectImp::getScaledFont(double minSize, double maxSize)
{
   QFont scaledFont = getFont();

   GraphicLayer* pLayer = getLayer();
   if (pLayer != NULL)
   {
      // Scale the point size
      double pointSize = scaledFont.pointSizeF();

      PerspectiveView* pPerspectiveView = dynamic_cast<PerspectiveView*>(pLayer->getView());
      if (pPerspectiveView != NULL)
      {
         // Zoom percentage
         double zoomPercent = pPerspectiveView->getZoomPercentage();
         pointSize *= zoomPercent / 100.0;

         // Product DPI
         ProductView* pProductView = dynamic_cast<ProductView*>(pPerspectiveView);
         if (pProductView != NULL)
         {
            int dpi = pProductView->getDpi();
            pointSize *= dpi / 72.0;
         }
      }

      // Restrict to the minimum size
      if (minSize > 0.0)
      {
         pointSize = max(pointSize, minSize);
      }

      // Restrict to the maximum size
      if (maxSize > 0.0)
      {
         pointSize = min(pointSize, maxSize);
      }

      // Set the scaled point size in the font
      scaledFont.setPointSizeF(pointSize);
   }

   return scaledFont;
}
示例#11
0
NewPath::NewPath(PolylineObjectImp* pObject, unsigned int path) :
   UndoAction(dynamic_cast<SessionItem*>(pObject)),
   mPath(path)
{
   if (pObject != NULL)
   {
      GraphicLayer* pLayer = pObject->getLayer();
      if (pLayer != NULL)
      {
         View* pView = pLayer->getView();
         if (pView != NULL)
         {
            mViewId = pView->getId();
         }

         mLayerId = pLayer->getId();
      }
   }

   setText("New Path");
}
示例#12
0
文件: Scene.cpp 项目: makkajai/FenneX
void Scene::onTouchMoved(Touch *touch, Event *pEvent)
{
    //CCLOG("onTouchMoved started...");
    if(linker->linkedObjectOf(touch) != NULL
       && isKindOfClass(linker->linkedObjectOf(touch), const Image))
    {
        Image* toggle = (Image*)linker->linkedObjectOf(touch);
        GraphicLayer* layer = GraphicLayer::sharedLayer();
        char *end = strrchr(toggle->getImageFile().c_str(), '-');
        if(end && strcmp(end, "-on") == 0 && !layer->allObjectsAtPosition(Scene::touchPosition(touch))->containsObject(toggle))
        {
            this->switchButton(toggle, false);
        }
    }
    
    for(GenericRecognizer* receiver : touchReceiversList)
    {
        receiver->onTouchMoved(touch, pEvent);
    }
    //CCLOG("onTouchMoved ended");
}
示例#13
0
SetGraphicObjectName::SetGraphicObjectName(GraphicObject *pObject, const string &oldName, const string &newName) :
   UndoAction(pObject),
   mOldName(oldName),
   mNewName(newName)
{
   GraphicObjectImp* pObjectImp = dynamic_cast<GraphicObjectImp*>(pObject);
   if (pObjectImp != NULL)
   {
      GraphicLayer* pLayer = pObjectImp->getLayer();
      if (pLayer != NULL)
      {
         View* pView = pLayer->getView();
         if (pView != NULL)
         {
            mViewId = pView->getId();
         }

         mLayerId = pLayer->getId();
      }
   }
   setText("Rename Graphic Object");
}
示例#14
0
SetGraphicObjectProperty::SetGraphicObjectProperty(GraphicObject* pObject, const GraphicProperty* pOldProperty,
                                                   const GraphicProperty* pNewProperty) :
   UndoAction(pObject),
   mpOldProperty(NULL),
   mpNewProperty(NULL)
{
   GraphicObjectImp* pObjectImp = dynamic_cast<GraphicObjectImp*>(pObject);
   if (pObjectImp != NULL)
   {
      GraphicLayer* pLayer = pObjectImp->getLayer();
      if (pLayer != NULL)
      {
         View* pView = pLayer->getView();
         if (pView != NULL)
         {
            mViewId = pView->getId();
         }

         mLayerId = pLayer->getId();
      }
   }

   QString actionText = "Set Object Property";
   if ((pOldProperty != NULL) && (pNewProperty != NULL))
   {
      string oldName = pOldProperty->getName();
      string newName = pNewProperty->getName();
      if (oldName == newName)
      {
         actionText = "Set Object " + QString::fromStdString(oldName);
         mpOldProperty = pOldProperty->copy();
         mpNewProperty = pNewProperty->copy();
      }
   }

   setText(actionText);
}
示例#15
0
void TextObjectImp::updateBoundingBox()
{
   // Get the width and height of the bounding box in screen pixels based on the scaled text image size
   int iWidth = 0;
   int iHeight = 0;

   string text = getSubstitutedText();
   if (text.empty() == false)
   {
      QString strMessage = QString::fromStdString(text);
      QFont scaledFont = getScaledFont();

      int iMaxSize = 0;
      glGetIntegerv(GL_MAX_TEXTURE_SIZE, &iMaxSize);

      int iAlignment = getTextAlignment();

      QFontMetrics ftMetrics(scaledFont);
      QRect boundingBox = ftMetrics.boundingRect(0, 0, iMaxSize, iMaxSize,
         iAlignment | Qt::TextWordWrap, strMessage);

      iWidth = boundingBox.width();
      iHeight = boundingBox.height();
   }

   // Get the current bounding box
   LocationType llCorner = getLlCorner();
   LocationType urCorner = getUrCorner();

   // Use the lower left corner as the anchor and compute the data coordinate of the upper right corner
   GraphicLayer* pLayer = getLayer();
   if (pLayer != NULL)
   {
      // Compute the upper right coordinate
      PerspectiveView* pView = dynamic_cast<PerspectiveView*>(pLayer->getView());
      if (pView != NULL)
      {
         double zoomFactor = 100.0 / pView->getZoomPercentage();
         double xScale = zoomFactor / pLayer->getXScaleFactor();
         double yScale = zoomFactor / pLayer->getYScaleFactor();

         urCorner.mX = llCorner.mX + (iWidth * xScale);
         urCorner.mY = llCorner.mY + (iHeight * yScale);
      }

      if (dynamic_cast<OrthographicView*>(pLayer->getView()) != NULL)
      {
         double dScreenX = 0.0;
         double dScreenY = 0.0;
         pLayer->translateDataToScreen(llCorner.mX, llCorner.mY, dScreenX, dScreenY);
         pLayer->translateScreenToData(dScreenX + iWidth, dScreenY + iHeight, urCorner.mX, urCorner.mY);
      }
   }
   else
   {
      urCorner.mX = llCorner.mX + iWidth;
      urCorner.mY = llCorner.mY + iHeight;
   }

   // Update the bounding box and selection handles
   setBoundingBox(llCorner, urCorner);
   updateHandles();

   mUpdateBoundingBox = false;
}
示例#16
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;
}
示例#17
0
string MeasurementObjectImp::generateGeoStrings() const
{
   LocationType llCorner = getLlCorner();
   LocationType urCorner = getUrCorner();
   LocationType llCornerLatLon;
   LocationType urCornerLatLon;
   bool unitsValid = false;

   // Get lat lon coordinates and terrain raster
   const RasterElement* pTerrain = NULL;

   bool geoValid(false);
   if (mpGeoreference.get() != NULL)
   {
      GraphicLayer* pLayer = getLayer();
      if (pLayer != NULL)
      {
         SpatialDataView* pView = dynamic_cast<SpatialDataView*>(pLayer->getView());
         if (pView != NULL)
         {
            LayerList* pLayerList = pView->getLayerList();
            VERIFYRV(pLayerList != NULL, "");
            VERIFYRV(pLayerList->getPrimaryRasterElement() == mpGeoreference.get(), "");

            pTerrain = mpGeoreference->getTerrain();

            Layer* pPrimaryRasterLayer = pLayerList->getLayer(RASTER, mpGeoreference.get());
            if (pPrimaryRasterLayer != NULL)
            {
               pPrimaryRasterLayer->translateWorldToData(llCorner.mX, llCorner.mY, llCorner.mX, llCorner.mY);
               pPrimaryRasterLayer->translateWorldToData(urCorner.mX, urCorner.mY, urCorner.mX, urCorner.mY);
            }
         }
      }

      if (mpGeoreference->isGeoreferenced())
      {
         bool llValid(false);
         bool urValid(false);
         llCornerLatLon = mpGeoreference->convertPixelToGeocoord(llCorner, false, &llValid);
         urCornerLatLon = mpGeoreference->convertPixelToGeocoord(urCorner, false, &urValid);
         geoValid = llValid && urValid;
      }
   }

   mUsingInaccurateGeocoords = !geoValid;
   unitsValid = geoValid;

   //String Variables
   string startLoc = "";
   string endLoc = "";
   string distance = "";
   string bearing = "";
   string distanceUnit = "";

   GeoAlgorithms algs;
   double distanceVal = 0;
   double azimuthVal = 0;

   // Create GeoPoint objects
   LatLonPoint startLlPoint = llCornerLatLon;
   LatLonPoint endLlPoint = urCornerLatLon;
   UtmPoint startUtmPoint = startLlPoint;
   UtmPoint endUtmPoint = endLlPoint;
   MgrsPoint startMgrsPoint = startLlPoint;
   MgrsPoint endMgrsPoint = endLlPoint;

   // find elevations
   double elevation1(0.0);
   double elevation2(0.0);
   if (pTerrain != NULL)
   {
      const RasterDataDescriptor* pDescriptor =
         dynamic_cast<const RasterDataDescriptor*>(pTerrain->getDataDescriptor());
      if (pDescriptor != NULL)
      {
         const vector<DimensionDescriptor>& activeRows = pDescriptor->getRows();
         const vector<DimensionDescriptor>& activeColumns = pDescriptor->getColumns();
         if ( llCorner.mY >= 0 && llCorner.mY < activeRows.size() &&
              llCorner.mX >= 0 && llCorner.mX < activeColumns.size() &&
              urCorner.mY >= 0 && urCorner.mY < activeRows.size() &&
              urCorner.mX >= 0 && urCorner.mX < activeColumns.size() )
         {
            DimensionDescriptor llRowDim(activeRows[llCorner.mY]);
            DimensionDescriptor llColumnDim(activeColumns[llCorner.mX]);
            DimensionDescriptor urRowDim(activeRows[urCorner.mY]);
            DimensionDescriptor urColumnDim(activeColumns[urCorner.mX]);
            elevation1 = pTerrain->getPixelValue(llColumnDim, llRowDim, DimensionDescriptor(), COMPLEX_MAGNITUDE);
            elevation2 = pTerrain->getPixelValue(urColumnDim, urRowDim, DimensionDescriptor(), COMPLEX_MAGNITUDE);
            const Units* pElevationUnits = pDescriptor->getUnits();
            if (pElevationUnits != NULL)
            {
               double scale = pElevationUnits->getScaleFromStandard();
               elevation1 *= scale;
               elevation2 *= scale;
            }
         }
      }
   }

   if (unitsValid == true)
   {
      // Calculate bearing and distance
      distanceVal = algs.getPythagoreanOrVincentyDistance(startLlPoint.getLatitude().getValue(),
         startLlPoint.getLongitude().getValue(), endLlPoint.getLatitude().getValue(),
         endLlPoint.getLongitude().getValue(), elevation1, elevation2);
      azimuthVal = algs.getVincentyAzimuth(startLlPoint.getLatitude().getValue(),
         startLlPoint.getLongitude().getValue(), endLlPoint.getLatitude().getValue(),
         endLlPoint.getLongitude().getValue());
      azimuthVal = GeoConversions::convertRadToDeg(azimuthVal);

      // Set distance text
      if (mDrawnDistanceUnit == KILOMETER)
      {
         distanceUnit = "km";
         distanceVal = distanceVal/1000;
      }
      else if (mDrawnDistanceUnit == MILE)
      {
         distanceUnit = "mi";
         distanceVal = GeoConversions::convertMetersToMiles(distanceVal);
      }
      else if (mDrawnDistanceUnit == NAUTICAL_MILE)
      {
         distanceUnit = "Nm";
         distanceVal = GeoConversions::convertMetersToNm(distanceVal);
      }
      else if (mDrawnDistanceUnit == METER)
      {
         distanceUnit = "m";
      }
      else if (mDrawnDistanceUnit == YARD)
      {
         distanceUnit = "yd";
         distanceVal = GeoConversions::convertMetersToFeet(distanceVal)/3;
      }
      else if (mDrawnDistanceUnit == FOOT)
      {
         distanceUnit = "ft";
         distanceVal = GeoConversions::convertMetersToFeet(distanceVal);
      }

      // set location text
      switch (mDrawnGeocoord)
      {
      case GEOCOORD_LATLON:
         startLoc = startLlPoint.getText(mDrawnDmsFormat, mEndPointsPrecision);
         endLoc = endLlPoint.getText(mDrawnDmsFormat, mEndPointsPrecision);
         break;

      case GEOCOORD_UTM:
         startLoc = startUtmPoint.getText();
         endLoc = endUtmPoint.getText();
         break;

      case GEOCOORD_MGRS:
         startLoc = startMgrsPoint.getText();
         endLoc = endMgrsPoint.getText();
         break;

      default:
         startLoc = "(" + QString::number(llCorner.mX, 'f', mEndPointsPrecision).toStdString() + ", " +
            QString::number(llCorner.mY, 'f', mEndPointsPrecision).toStdString() + ")";
         endLoc = "(" + QString::number(urCorner.mX, 'f', mEndPointsPrecision).toStdString() + ", " +
            QString::number(urCorner.mY, 'f', mEndPointsPrecision).toStdString() + ")";
         break;
      }
   }
   else
   {
      startLoc = "(" + QString::number(llCorner.mX, 'f', mEndPointsPrecision).toStdString() + ", " +
         QString::number(llCorner.mY, 'f', mEndPointsPrecision).toStdString() + ")";
      endLoc = "(" + QString::number(urCorner.mX, 'f', mEndPointsPrecision).toStdString() + ", " +
         QString::number(urCorner.mY, 'f', mEndPointsPrecision).toStdString() + ")";
      azimuthVal = algs.getPythagoreanAzimuth(llCorner.mX, llCorner.mY, urCorner.mX, urCorner.mY);
      azimuthVal = GeoConversions::convertRadToDeg(azimuthVal);
      distanceVal = algs.getPythagoreanDistance(urCorner.mX, urCorner.mY, llCorner.mX, llCorner.mY);
      distanceUnit = "pix";
   }

   bearing = QString::number(azimuthVal, 'f', mBearingPrecision).toStdString();
   distance = QString::number(distanceVal, 'f', mDistancePrecision).toStdString();

   QString bearingText = QString::fromStdString(bearing) + " deg";
   QString distanceText = QString::fromStdString(distance) + " " + QString::fromStdString(distanceUnit);
   QString startLocText = QString::fromStdString(startLoc);
   QString endLocText = QString::fromStdString(endLoc);

   // Final strings
   if (bearingText != mBearingText)
   {
      mBearingText = bearingText;
      mBearingTextTexture.invalidate();
   }

   if (distanceText != mDistanceText)
   {
      mDistanceText = distanceText;
      mDistanceTextTexture.invalidate();
   }
   if (startLocText != mStartLocText)
   {
      mStartLocText = startLocText;
      mStartLocTextTexture.invalidate();
   }
   if (endLocText != mEndLocText)
   {
      mEndLocText = endLocText;
      mEndLocTextTexture.invalidate();
   }

   string rtnVal = "DISTANCE: " + distanceText.toStdString() + " : LOCATION: " + startLoc + " to " +
      endLoc + " at " + bearingText.toStdString();
   return rtnVal;
}
示例#18
0
bool ArcObjectImp::hit(LocationType pixelCoord) const
{
    int iStart = static_cast<int>(getStartAngle());
    if (iStart < 0)
    {
        iStart--;
    }

    int iStop = static_cast<int>(getStopAngle());
    if (iStop < 0)
    {
        iStop--;
    }

    if (iStart == iStop)
    {
        iStart = 0;
        iStop = 360;
    }

    ArcRegion eArcRegion = getArcRegion();

    DrawUtil::initializeCircle();
    LocationType center = getCenter();

    bool bHit = false;

    // Filled area
    FillStyle eFillStyle = getFillStyle();
    if (eFillStyle != EMPTY_FILL)
    {
        int iSize = abs(iStop - iStart) + 1;
        if (eArcRegion == ARC_CENTER)
        {
            iSize += 2;
        }
        else if (eArcRegion == ARC_CHORD)
        {
            iSize += 1;
        }

        double* pXVertices = new double[iSize];
        double* pYVertices = new double[iSize];

        int i = 0;
        int iIndex = 0;
        for (i = iStart, iIndex = 0; i <= iStop; i++, iIndex++)
        {
            LocationType arcPoint = getLocation(static_cast<double>(i));
            pXVertices[iIndex] = arcPoint.mX;
            pYVertices[iIndex] = arcPoint.mY;
        }

        if ((eArcRegion == ARC_CENTER) || (eArcRegion == ARC_CHORD))
        {
            if (eArcRegion == ARC_CENTER)
            {
                pXVertices[iSize - 2] = center.mX;
                pYVertices[iSize - 2] = center.mY;
            }

            pXVertices[iSize - 1] = pXVertices[0];
            pYVertices[iSize - 1] = pYVertices[0];
        }

        bHit = DrawUtil::isWithin(pixelCoord.mX, pixelCoord.mY, pXVertices, pYVertices, iSize);

        delete [] pXVertices;
        delete [] pYVertices;
    }

    // Line
    if (bHit == false)
    {
        bool bLine = false;
        bLine = getLineState();
        if (bLine == true)
        {
            // Check the arc line
            double size = 1.0;

            GraphicLayer* pLayer = NULL;
            pLayer = getLayer();
            if (pLayer != NULL)
            {
                View* pView = pLayer->getView();
                if (pView != NULL)
                {
                    size = pView->getPixelSize(center, center);
                }

                size *= min(pLayer->getXScaleFactor(), pLayer->getYScaleFactor());
            }

            LocationType basePoint;
            for (int i = iStart; i <= iStop; i++)
            {
                LocationType currentPoint = getLocation(static_cast<double>(i));
                if (i != iStart)
                {
                    bHit = DrawUtil::lineHit(currentPoint, basePoint, pixelCoord, 2.0/size);
                    if (bHit == true)
                    {
                        break;
                    }
                }

                basePoint.mX = currentPoint.mX;
                basePoint.mY = currentPoint.mY;
            }

            // Check the arc region lines
            if (bHit == false)
            {
                LocationType startPoint = getLocation(static_cast<double>(iStart));
                LocationType stopPoint = getLocation(static_cast<double>(iStop));

                if (eArcRegion == ARC_CENTER)
                {
                    bHit = DrawUtil::lineHit(startPoint, center, pixelCoord, 2.0/size);
                    if (bHit == false)
                    {
                        bHit = DrawUtil::lineHit(stopPoint, center, pixelCoord, 2.0/size);
                    }
                }
                else if (eArcRegion == ARC_CHORD)
                {
                    bHit = DrawUtil::lineHit(startPoint, stopPoint, pixelCoord, 2.0/size);
                }
            }
        }
    }

    return bHit;
}
示例#19
0
void loadNodeToFenneX(Node* baseNode, Panel* parent)
{
    GraphicLayer* layer = GraphicLayer::sharedLayer();
    if(parent == NULL)
    {
        layer->useBaseLayer((Layer*)baseNode);
#if VERBOSE_LOAD_CCB
        CCLOG("replaced base layer by CCB node : position : %f, %f, scale : %f", baseNode->getPosition().x, baseNode->getPosition().y, baseNode->getScale());
#endif
    }
    
    //Use an index because InputLabel modify the array, so you need to rewind a bit at some point
    for(int i = 0; i < baseNode->getChildren().size(); i++)
    {
        Node* node = baseNode->getChildren().at(i);
#if VERBOSE_LOAD_CCB
        CCLOG("doing child %d from parent %s ...", i, parent != NULL ? parent->getName() != "" ? parent->getName().c_str() : "Panel" : "base layer");
#endif
        RawObject* result = NULL;
        if(isKindOfClass(node, Label))
        {
            Label* label = (Label*)node;
#if VERBOSE_LOAD_CCB
            CCLOG("label, font : %s", label->getSystemFontName().c_str());
#endif
            CCString* translationKey = isKindOfClass(label, CustomBaseNode) ? (CCString*)dynamic_cast<CustomBaseNode*>(label)->getParameters()->objectForKey("translationKey") : NULL;
            const std::string translated = Localization::getLocalizedString(translationKey != NULL ? translationKey->getCString() : label->getString());
            if(translationKey == NULL || translationKey->compare(translated.c_str()) != 0)
            { //Don't replace the string if it's the same, as it may only be a key, not a real label
                label->setString(translated);
            }
            result = layer->createLabelTTFromLabel(label, parent);
        }
        else if(isKindOfClass(node, CustomDropDownList))
        {
#if VERBOSE_LOAD_CCB
            CCLOG("DropDownList");
#endif
            Sprite* sprite = (Sprite*)node;
            result = layer->createDropDownListFromSprite(sprite, parent);
        }
        else if(isKindOfClass(node, Sprite))
        {
#if VERBOSE_LOAD_CCB
            CCLOG("image");
#endif
            Sprite* sprite = (Sprite*)node;
            result = layer->createImageFromSprite(sprite, parent);
        }
        else if(isKindOfClass(node, CustomInput))
        {
#if VERBOSE_LOAD_CCB
            CCLOG("input label");
#endif
            ui::Scale9Sprite* sprite = (ui::Scale9Sprite*)node;
            
            CCString* translationKey = isKindOfClass(sprite, CustomBaseNode) ? (CCString*)dynamic_cast<CustomBaseNode*>(sprite)->getParameters()->objectForKey("translationKey") : NULL;
            std::string placeHolder = isKindOfClass(sprite, CustomInput) ? ((CustomInput*) sprite)->getPlaceHolder()->getCString() : "";
            
            result = layer->createInputLabelFromScale9Sprite(sprite, parent);
            
            const std::string text = Localization::getLocalizedString(translationKey != NULL ? translationKey->getCString() : placeHolder.c_str());
            if(translationKey == NULL || translationKey->compare(text.c_str()) != 0)
            {
                ((InputLabel*) result)->setInitialText(text);
            }
            i--;
        }
        else if(isKindOfClass(node, ui::Scale9Sprite))
        {
#if VERBOSE_LOAD_CCB
            CCLOG("scale sprite");
#endif
            ui::Scale9Sprite* sprite = (ui::Scale9Sprite*)node;
            result = layer->createCustomObjectFromNode(sprite, parent);
        }
        else if(!isKindOfClass(node, ui::EditBox))
        {
#if VERBOSE_LOAD_CCB
            CCLOG("Edit Box");
#endif
            result = layer->createPanelFromNode(node, parent);
        }
#if VERBOSE_LOAD_CCB
        if(result != NULL)
        {
            CCLOG("Child %d loaded : position : %f, %f, scale : %f", i, result->getPosition().x, result->getPosition().y, result->getScale());
        }
        else
        {
            CCLOG("Problem loading child %d !", i);
        }
#endif
    }
}
示例#20
0
void TextObjectImp::draw(double zoomFactor) const
{
   RectangleObjectImp::draw(zoomFactor);
   if (QGLContext::currentContext() != mpDrawContext || mUpdateTexture == true)
   {
      (const_cast<TextObjectImp*> (this))->updateTexture();
   }

   if (mpDrawContext == NULL)
   {
      return;
   }

   LocationType llCorner = getLlCorner();
   LocationType urCorner = getUrCorner();
   glEnable(GL_TEXTURE_2D);

   // switch to using this tile's texture
   GLuint textureId = mTextureResource;
   if (mpDrawContext == mTempTextureResource.getContext())
   {
      textureId = mTempTextureResource;
   }

   glBindTexture(GL_TEXTURE_2D, textureId);

   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   double maxS = mDataWidth / static_cast<double>(mTextureWidth);
   double maxT = mDataHeight / static_cast<double>(mTextureHeight);

   ColorType color = getTextColor();
   glBegin(GL_QUADS);
   glColor4ub(color.mRed, color.mGreen, color.mBlue, 255);

   // Determine if the bounding box is flipped based on its screen locations
   bool bHorizontalFlip = false;
   bool bVerticalFlip = false;

   GraphicLayer* pLayer = getLayer();
   if (pLayer != NULL)
   {
      pLayer->isFlipped(llCorner, urCorner, bHorizontalFlip, bVerticalFlip);

      // Account for the difference between screen origin (upper left) and OpenGL origin (lower left)
      bVerticalFlip = !bVerticalFlip;
   }

   // Draw the text left to right and right side up
   if ((bHorizontalFlip == false) && (bVerticalFlip == false))
   {
      glTexCoord2f(0.0, 0.0);
      glVertex3f(llCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(maxS, 0.0);
      glVertex3f(urCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(maxS, maxT);
      glVertex3f(urCorner.mX, urCorner.mY, 0.0);

      glTexCoord2f(0.0, maxT);
      glVertex3f(llCorner.mX, urCorner.mY, 0.0);
   }
   else if ((bHorizontalFlip == true) && (bVerticalFlip == false))
   {
      glTexCoord2f(maxS, 0.0);
      glVertex3f(llCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(0.0, 0.0);
      glVertex3f(urCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(0.0, maxT);
      glVertex3f(urCorner.mX, urCorner.mY, 0.0);

      glTexCoord2f(maxS, maxT);
      glVertex3f(llCorner.mX, urCorner.mY, 0.0);
   }
   else if ((bHorizontalFlip == true) && (bVerticalFlip == true))
   {
      glTexCoord2f(maxS, maxT);
      glVertex3f(llCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(0.0, maxT);
      glVertex3f(urCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(0.0, 0.0);
      glVertex3f(urCorner.mX, urCorner.mY, 0.0);

      glTexCoord2f(maxS, 0.0);
      glVertex3f(llCorner.mX, urCorner.mY, 0.0);
   }
   else if ((bHorizontalFlip == false) && (bVerticalFlip == true))
   {
      glTexCoord2f(0.0, maxT);
      glVertex3f(llCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(maxS, maxT);
      glVertex3f(urCorner.mX, llCorner.mY, 0.0);

      glTexCoord2f(maxS, 0.0);
      glVertex3f(urCorner.mX, urCorner.mY, 0.0);

      glTexCoord2f(0.0, 0.0);
      glVertex3f(llCorner.mX, urCorner.mY, 0.0);
   }

   glEnd();

   glDisable(GL_BLEND);
   glDisable(GL_ALPHA_TEST);
   glDisable(GL_TEXTURE_2D);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

   // mTempTextureResource is allocated by the updateTexture method when the gl context has changed
   // Free the texture here; more importantly set mpDrawContext to mTextureResource so that the next
   // draw operation completes successfully without the need to recreate the texture.
   if (mTempTextureResource.get() != NULL)
   {
      TextObjectImp* pNonConst = const_cast<TextObjectImp*>(this);
      pNonConst->mTempTextureResource = GlTextureResource(0);
      pNonConst->mpDrawContext = mTextureResource.getContext();
   }
}
示例#21
0
bool EllipseObjectImp::hit(LocationType pixelCoord) const
{ 
   LocationType llCorner = getLlCorner();
   LocationType urCorner = getUrCorner();

   double xVertices[DrawUtil::VERTEX_COUNT + 1];
   double yVertices[DrawUtil::VERTEX_COUNT + 1];
   DrawUtil::initializeCircle();

   LocationType center;
   center.mX = (llCorner.mX + urCorner.mX) / 2.0;
   center.mY = (llCorner.mY + urCorner.mY) / 2.0;

   LocationType radii;
   radii.mX = fabs (llCorner.mX - urCorner.mX) / 2.0;
   radii.mY = fabs (llCorner.mY - urCorner.mY) / 2.0;

   int i = 0;
   for (i = 0; i < DrawUtil::VERTEX_COUNT; i++)
   {
      xVertices[i] = center.mX + radii.mX * DrawUtil::sCirclePoints[i].mX;
      yVertices[i] = center.mY + radii.mY * DrawUtil::sCirclePoints[i].mY;
   }

   xVertices[DrawUtil::VERTEX_COUNT] = xVertices[0];
   yVertices[DrawUtil::VERTEX_COUNT] = yVertices[0];

   bool bHit = false;

   // Filled area
   FillStyle eFillStyle = getFillStyle();
   if (eFillStyle != EMPTY_FILL)
   {
      bHit = DrawUtil::isWithin(pixelCoord.mX, pixelCoord.mY, xVertices, yVertices, DrawUtil::VERTEX_COUNT+1);
   }

   // Line
   if (bHit == false)
   {
      bool bLine = false;
      bLine = getLineState();
      if (bLine == true)
      {
         double size = 1.0;

         GraphicLayer* pLayer = NULL;
         pLayer = getLayer();
         if (pLayer != NULL)
         {
            View* pView = pLayer->getView();
            if (pView != NULL)
            {
               size = pView->getPixelSize(llCorner, urCorner);
            }
            size *= min(pLayer->getXScaleFactor(), pLayer->getYScaleFactor());
         }

         LocationType basePoint;
         for (i = 0; i < DrawUtil::VERTEX_COUNT; i++)
         {
            LocationType currentPoint(xVertices[i], yVertices[i]);

            if (i != 0)
            {
               bHit = DrawUtil::lineHit(currentPoint, basePoint, pixelCoord, 2.0/size);
               if (bHit == true)
               {
                  break;
               }
            }

            basePoint = currentPoint;
         }
      }
   }

   return bHit;
}
void EastArrowObjectImp::orient()
{
   if (isOriented() == true)
   {
      return;
   }

   GraphicLayer* pLayer = NULL;
   pLayer = getLayer();
   if (pLayer == NULL)
   {
      return;
   }

   View* pView = NULL;
   pView = pLayer->getView();
   if (pView == NULL)
   {
      return;
   }

   SpatialDataView* pSpatialDataView = NULL;
   if (pView->isKindOf("SpatialDataView") == true)
   {
      pSpatialDataView = static_cast<SpatialDataView*> (pView);
   }
   else if (pView->isKindOf("ProductView") == true)
   {
      ProductView* pProductView = static_cast<ProductView*> (pView);

      GraphicLayer* pLayoutLayer = NULL;
      pLayoutLayer = pProductView->getLayoutLayer();
      if (pLayoutLayer == pLayer)
      {
         list<GraphicObject*> viewObjects;
         pLayoutLayer->getObjects(VIEW_OBJECT, viewObjects);

         list<GraphicObject*>::iterator iter = viewObjects.begin();
         while (iter != viewObjects.end())
         {
            GraphicObject* pObject = *iter;
            if (pObject != NULL)
            {
               View* pObjectView = pObject->getObjectView();
               if (pObjectView != NULL)
               {
                  if (pObjectView->isKindOf("SpatialDataView") == true)
                  {
                     pSpatialDataView = static_cast<SpatialDataView*> (pObjectView);
                  }
               }
            }

            ++iter;
         }
      }
   }

   if (pSpatialDataView == NULL)
   {
      return;
   }

   LayerList* pLayerList = pSpatialDataView->getLayerList();
   VERIFYNRV(pLayerList != NULL);
   RasterElement* pRaster = pLayerList->getPrimaryRasterElement();
   VERIFYNRV(pRaster != NULL);
   if (!pRaster->isGeoreferenced())
   {
      return;
   }

   // Calculate the angle of the object relative to the pixel coordinates
   updateHandles();

   LocationType pixelStart = mHandles[7];

   ProductView* pProductView = dynamic_cast<ProductView*> (pView);
   if (pProductView != NULL)
   {
      // Convert to the screen coordinate system
      double dScreenX = 0;
      double dScreenY = 0;
      pLayer->translateDataToWorld(pixelStart.mX, pixelStart.mY, pixelStart.mX, pixelStart.mY);
      pProductView->translateWorldToScreen(pixelStart.mX, pixelStart.mY, dScreenX, dScreenY);
      
      // Convert to the spatial data view coordinate system
      pSpatialDataView->translateScreenToWorld(dScreenX,
         dScreenY, pixelStart.mX, pixelStart.mY);
      pLayer->translateWorldToData(pixelStart.mX, pixelStart.mY, pixelStart.mX, pixelStart.mY);
   }

   double dAngle;
   if (GeoAlgorithms::getAngleToNorth(pRaster, dAngle, pixelStart) == false)
   {
      return;
   }

   // Update the angle if the object is in the layout layer
   if (pProductView != NULL)
   {
      // Rotation
      dAngle -= pSpatialDataView->getRotation();

      // Pitch
      double dPitch = pSpatialDataView->getPitch();
      if (dPitch > 0.0)
      {
         dAngle *= -1.0;
      }
   }

   // Rotate the object
   setRotation(dAngle);

   // Update the orientation flag
   DirectionalArrowObjectImp::orient();
}
示例#23
0
void ScaleBarObjectImp::updateLayout()
{
   if (mNeedsLayout == false)
   {
      return;
   }

   LocationType llCorner = getLlCorner();
   LocationType urCorner = getUrCorner();

   bool bHorizontalFlip = false;
   bool bVerticalFlip = false;

   GraphicLayer* pLayer = getLayer();
   if (pLayer != NULL)
   {
      pLayer->isFlipped(llCorner, urCorner, bHorizontalFlip, bVerticalFlip);
   }

   if (bHorizontalFlip == true)
   {
      double temp = llCorner.mX;
      llCorner.mX = urCorner.mX;
      urCorner.mX = temp;
   }

   if (bVerticalFlip == true)
   {
      double temp = llCorner.mY;
      llCorner.mY = urCorner.mY;
      urCorner.mY = temp;
   }

   double barHeight = urCorner.mY - llCorner.mY;

   double spacingScale = 1.0;
   string unitsText = "pix";
   double unitScale = 1.0; //mXgsd is calculated in meters
   if (mpGeoreference.get() != NULL)
   {
      if (getUnitSystem() == UNIT_KFT)
      {
         unitsText = "ft";
      }
      else if (getUnitSystem() == UNIT_KM)
      {
         unitsText = "m";
      }
      else if (getUnitSystem() == UNIT_MI)
      {
         unitsText = "mi";
      }

      // if the scalebar is an object in the layout layer, we need to scale the
      // scalebar length to scene pixels from page coordinates
      if (getUnitSystem() == UNIT_KFT)
      {
         unitScale = GeoConversions::convertMetersToFeet(1);
      }
      else if (getUnitSystem() == UNIT_MI)
      {
         unitScale = GeoConversions::convertMetersToMiles(1);
      }
   }
   else
   {
      mXgsd = 1.0;
   }

   double deltaX = urCorner.mX - llCorner.mX;
   double lengthBar = fabs(deltaX * mXgsd * unitScale);
   double totalLengthPixels = fabs(deltaX);
   double ticksize = 0.0; //ticksize in pixels
   double ticksizeDistance = pow(10.0, floor(log10(lengthBar / 5.0))); //ticksize in specific units (feet or meters)

   if (ticksizeDistance * 5.0 * 5.0 > lengthBar)
   {
      if (ticksizeDistance * 2.0 * 5.0 > lengthBar)
      {
         // times 1.0;
      }
      else
      {
         ticksizeDistance *= 2.0;
      }
   }
   else
   {
      ticksizeDistance *= 5.0;
   }

   if (mpGeoreference.get() == NULL || getUnitSystem() == UNIT_KM || getUnitSystem() == UNIT_KFT)
   {
      if (ticksizeDistance >= (1000 / 5.0)) // 5 ticks >= 1000 base units (either meters or feet)
      {
         spacingScale /= 1000.0; //meters to kilometers, feet to kilofeet
         unitsText = "k" + unitsText;
      }
   }
   else if (getUnitSystem() == UNIT_MI)
   {
      if (ticksizeDistance < (0.25 / 5.0)) //5 ticks is less than 1/4 mile, convert to feet.
      {
         spacingScale = GeoConversions::convertMilesToFeet(spacingScale);
         unitsText = "ft";
      }
   }

   // need to divide ticksize by gsd here
   if (lengthBar != 0.0)
   {
      ticksize = DrawUtil::sign(deltaX) * ticksizeDistance * totalLengthPixels / lengthBar; // ticksize in pixels
   }

   ostringstream center;
   center << (ticksizeDistance * 5.0) * spacingScale << unitsText;
   TextStringProperty centerText(center.str());

   ostringstream right;
   right << lengthBar * spacingScale << unitsText;
   string newRightVal = right.str();
   TextStringProperty rightText(right.str());
   TextStringProperty leftText("0" + unitsText);

   double width = 0.0;
   double height = 0.0;

   int i = 0;
   list<GraphicObject*> objects = mpGroup->getObjects();
   list<GraphicObject*>::iterator it = objects.begin();

   for (i = 0; it != objects.end(); ++it, ++i)
   {
      GraphicObjectImp* pObj = dynamic_cast<GraphicObjectImp*>(*it);
      TextObjectImp* pText = NULL;

      if (pObj == NULL)
      {
         continue;
      }

      LocationType llObjCorner = pObj->getLlCorner();
      LocationType urObjCorner = pObj->getUrCorner();

      switch (i)
      {
         case 0:
            // big, stretchy rectangle
            llObjCorner.mX = llCorner.mX;
            urObjCorner.mX = urCorner.mX;
            llObjCorner.mY = llCorner.mY + barHeight * (1.0-BOX_HEIGHT);
            urObjCorner.mY = llObjCorner.mY + barHeight * BOX_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            
            pObj->updateHandles();
            break;
         case 1:
         case 2:
         case 3:
         case 4:
         case 5:
            // 5 rectangles
            llObjCorner.mX = ((i-1) * ticksize) + llCorner.mX;
            urObjCorner.mX = (i * ticksize) + llCorner.mX;
            llObjCorner.mY = llCorner.mY + barHeight * (1.0-BOX_HEIGHT);
            urObjCorner.mY = llObjCorner.mY + barHeight * BOX_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            pObj->updateHandles();
            break;
         case 6:
            //center line
            llObjCorner.mX = (5.0 * ticksize) + llCorner.mX;
            urObjCorner.mX = llObjCorner.mX;
            llObjCorner.mY = llCorner.mY + barHeight * (1.0-BOX_HEIGHT - CENTER_LINE_HEIGHT);
            urObjCorner.mY = llObjCorner.mY + barHeight * CENTER_LINE_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            pObj->updateHandles();
            break;
         case 7:
            // left line
            llObjCorner.mX = llCorner.mX;
            urObjCorner.mX = llCorner.mX;
            llObjCorner.mY = llCorner.mY + barHeight * TEXT_HEIGHT;
            urObjCorner.mY = llObjCorner.mY + barHeight * LINE_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            pObj->updateHandles();
            break;
         case 8:
            //right line
            llObjCorner.mX = urCorner.mX;
            urObjCorner.mX = llObjCorner.mX;
            llObjCorner.mY = llCorner.mY + barHeight * TEXT_HEIGHT;
            urObjCorner.mY = llObjCorner.mY + barHeight * LINE_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            pObj->updateHandles();
            break;
         case 9:
         {
            //left text
            pText = dynamic_cast<TextObjectImp*>(pObj);
            VERIFYNRV(pText != NULL);
            if (pObj->getText() != leftText.getString())
            {
               pText->setProperty(&leftText);
               pText->updateTexture();
            }
            else
            {
               pText->updateBoundingBox();
            }

            LocationType textLlCorner = pText->getLlCorner();
            LocationType textUrCorner = pText->getUrCorner();
            width = textUrCorner.mX - textLlCorner.mX;
            height = textUrCorner.mY - textLlCorner.mY;
            llObjCorner.mX = llCorner.mX;
            llObjCorner.mY = llCorner.mY;
            if (height != 0.0)
            {
               urObjCorner.mX = llObjCorner.mX + width * barHeight * TEXT_HEIGHT / height;
            }
            else
            {
               urObjCorner.mX = llObjCorner.mX + width;
            }
            urObjCorner.mY = llObjCorner.mY + barHeight * TEXT_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            break;
         }
         case 10:
         {
            //center text
            pText = dynamic_cast<TextObjectImp*>(pObj);
            VERIFYNRV(pText != NULL);
            if (pObj->getText() != centerText.getString())
            {
               pText->setProperty(&centerText);
               pText->updateTexture();
            }
            else
            {
               pText->updateBoundingBox();
            }

            LocationType textLlCorner = pText->getLlCorner();
            LocationType textUrCorner = pText->getUrCorner();
            width = textUrCorner.mX - textLlCorner.mX;
            height = textUrCorner.mY - textLlCorner.mY;

            if (height != 0.0)
            {
               llObjCorner.mX = llCorner.mX + (5.0 * ticksize) - (width / 2.0) * barHeight * TEXT_HEIGHT / height;
               urObjCorner.mX = llObjCorner.mX + width * barHeight * TEXT_HEIGHT / height;
            }
            else
            {
               llObjCorner.mX = llCorner.mX + (5.0 * ticksize);
               urObjCorner.mX = llObjCorner.mX + width;
            }
            llObjCorner.mY = llCorner.mY + (1.0-BOX_HEIGHT-TEXT_HEIGHT-CENTER_LINE_HEIGHT)*barHeight;
            urObjCorner.mY = llObjCorner.mY + barHeight*TEXT_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            break;
         }
         case 11:
         {
            //right text
            pText = dynamic_cast<TextObjectImp*>(pObj);
            VERIFYNRV(pText != NULL);
            if (pObj->getText() != rightText.getString())
            {
               pText->setProperty(&rightText);
               pText->updateTexture();
            }
            else
            {
               pText->updateBoundingBox();
            }

            LocationType textLlCorner = pText->getLlCorner();
            LocationType textUrCorner = pText->getUrCorner();
            width = textUrCorner.mX - textLlCorner.mX;
            height = textUrCorner.mY - textLlCorner.mY;
            if (height != 0.0)
            {
               llObjCorner.mX = urCorner.mX - width * barHeight * TEXT_HEIGHT / height;
               urObjCorner.mX = llObjCorner.mX + width * barHeight * TEXT_HEIGHT / height;
            }
            else
            {
               llObjCorner.mX = urCorner.mX;
               urObjCorner.mX = llObjCorner.mX + width;
            }
            llObjCorner.mY = llCorner.mY;
            urObjCorner.mY = llObjCorner.mY + barHeight*TEXT_HEIGHT;
            pObj->setBoundingBox(llObjCorner, urObjCorner);
            break;
         }

         default:
            break;
      }
   }

   mpGroup->updateBoundingBox();
   mNeedsLayout = false;
}