diff --git a/Code/Common/otbVectorDataExtractROI.h b/Code/Common/otbVectorDataExtractROI.h index e2b76baa16296a0dcc97fffc4d5e6e5e8a906b6a..c5b6b72297aa8db617d4655fc649cd4e7b56c36c 100644 --- a/Code/Common/otbVectorDataExtractROI.h +++ b/Code/Common/otbVectorDataExtractROI.h @@ -68,6 +68,7 @@ public: typedef typename VectorDataType::DataTreeType DataTreeType; typedef typename DataNodeType::PolygonPointerType PolygonPointerType; typedef typename DataNodeType::PolygonType PolygonType; + typedef typename DataNodeType::LineType LineType; typedef typename DataNodeType::LinePointerType LinePointerType; typedef typename DataNodeType::PointType PointType; diff --git a/Code/Common/otbVectorDataExtractROI.txx b/Code/Common/otbVectorDataExtractROI.txx index 4b46df2ca408790cbd99c5a29878b2bba3c1e855..f3bba1adda0b5c3f4b464fd51a20e12d6bbd57df 100644 --- a/Code/Common/otbVectorDataExtractROI.txx +++ b/Code/Common/otbVectorDataExtractROI.txx @@ -249,9 +249,26 @@ bool VectorDataExtractROI<TVectorData> ::IsPolygonIntersectionNotNull(PolygonPointerType polygon) { -// RegionType region = ComputeVertexListBoundingRegion(polygon->GetVertexList()); - RegionType region(polygon->GetBoundingRegion()); - return region.Crop(m_GeoROI); + // Get the VertexList + // -2 cause we don't want the last point + // wich is the same as the first one (closed Ring) + for (unsigned int i = 0 ; i<polygon->GetVertexList()->Size() - 2 ; i++ ) + { + // Get the components of the polygon 2 by 2 + VertexType firstVertex; + VertexType secondVertex; + firstVertex = polygon->GetVertexList()->GetElement(i); + secondVertex = polygon->GetVertexList()->GetElement(i+1); + + // Build a line with each two vertex + typename LineType::Pointer line = LineType::New(); + line->AddVertex(firstVertex); + line->AddVertex(secondVertex); + + if (this->IsLineIntersectionNotNull(line)) + return true; + } + return false; } /** @@ -262,9 +279,66 @@ bool VectorDataExtractROI<TVectorData> ::IsLineIntersectionNotNull(LinePointerType line) { -// RegionType region = ComputeVertexListBoundingRegion(line->GetVertexList()); - RegionType region(line->GetBoundingRegion()); - return region.Crop(m_GeoROI); + RegionType lineRegion(line->GetBoundingRegion()); + + // if the line bounding box have a null + // intersection with the geoROI + // the line and the region do not intersect + if (!lineRegion.Crop(m_GeoROI)) + { + return false; + } + else + { + // Get the VertexList + for (unsigned int i = 0 ; i<line->GetVertexList()->Size() -1 ; i++ ) + { + // Get the components of the line 2 by 2 + VertexType firstVertex; + VertexType secondVertex; + firstVertex = line->GetVertexList()->GetElement(i); + secondVertex = line->GetVertexList()->GetElement(i+1); + + // ------------------- + // Case 1 : Check if one of the two points are in the region + PointType firstPoint,secondPoint; + firstPoint[0] = firstVertex[0]; + firstPoint[1] = firstVertex[1]; + + secondPoint[0] = secondVertex[0]; + secondPoint[1] = secondVertex[1]; + + if (m_GeoROI.IsInside(this->PointToContinuousIndex(firstPoint)) + | m_GeoROI.IsInside(this->PointToContinuousIndex(secondPoint))) + { + return true; + } + else + { + // ------------------- + // Case 2 : If any of the point is in the region + if (!m_GeoROI.IsInside(this->PointToContinuousIndex(firstPoint)) + && !m_GeoROI.IsInside(this->PointToContinuousIndex(secondPoint))) + { + // Build a line with each two vertex + typename LineType::Pointer tempLine = LineType::New(); + tempLine->AddVertex(firstVertex); + tempLine->AddVertex(secondVertex); + + // Check if the intersection is not null + RegionType region(tempLine->GetBoundingRegion()); + if (region.Crop(m_GeoROI)) + return true; + + // ------------------- + // TODO : check if the segment cut + // one of the region edges + } + } + } + } + + return false; } /** diff --git a/Code/IO/otbMapFileProductWriter.h b/Code/IO/otbMapFileProductWriter.h index aaa42ccbe4d99775030978805a94bce5b0601adf..dc8873d693209f174df2a78e3ebf966a7eab55aa 100644 --- a/Code/IO/otbMapFileProductWriter.h +++ b/Code/IO/otbMapFileProductWriter.h @@ -38,7 +38,20 @@ namespace otb { /** \class MapFileProductWriter - * \brief This class writes Map Product file format (MapFile and MapFiles) + * \brief This class produces Map file product ie a file .map, + * the tiles to draw in a mapserver, and finally + * a shapefile wich describe the tiles and where to find them + * on the disk. + * + * This filter begins by tiling the input image. An accessor + * SetTileSize allows to set the size of each tile. For each tile + * generated, an entry is added to the shapefile to store the location + * where the file is saved on the disk. + * The product generated are a mapfile wich is the configuration file + * for mapservers, a tile index and finally the tiles. + * + * NOTE : The user must edit the *.map file generated to put the right + * informations concerning the field 'wms_onlineresource'. * * \ingroup IO * @@ -104,12 +117,14 @@ public: const InputImageType * GetInput(void); const InputImageType * GetInput(unsigned int idx); - // Accessors macros + /** Method to set the filename of the mapfile generated */ itkSetStringMacro(FileName); + + /** Set/Get the size of each tile*/ itkSetMacro(TileSize,unsigned int); itkGetMacro(TileSize,unsigned int); - /** Update Method */ + /** Update Method : Call a porotected Write method */ virtual void Update() { this->Write(); diff --git a/Code/IO/otbMapFileProductWriter.txx b/Code/IO/otbMapFileProductWriter.txx index c76b5aba2ada3a502c06574a4c9d84ba8ea868f7..d83df12c7d7025b20dcb306b4d7ac4ccdde5689f 100644 --- a/Code/IO/otbMapFileProductWriter.txx +++ b/Code/IO/otbMapFileProductWriter.txx @@ -23,6 +23,10 @@ namespace otb { + +/** + * Constructor + */ template <class TInputImage> MapFileProductWriter<TInputImage> ::MapFileProductWriter(): m_UseExtendMode(true), m_TileSize(256) @@ -31,6 +35,10 @@ MapFileProductWriter<TInputImage> this->SetNumberOfRequiredInputs(1); } + +/** + * Desctructor + */ template <class TInputImage> MapFileProductWriter<TInputImage> ::~MapFileProductWriter() @@ -79,7 +87,7 @@ MapFileProductWriter<TInputImage> } /** - * + * Get the idx input */ template <class TInputImage> const typename MapFileProductWriter<TInputImage>::InputImageType * @@ -90,6 +98,11 @@ MapFileProductWriter<TInputImage> (this->ProcessObject::GetInput(idx)); } + +/** + * Write lauch the tiling and the mapFile generation and write on the + * disk the indexfile as a shapefile + */ template <class TInputImage> void MapFileProductWriter<TInputImage> @@ -98,7 +111,7 @@ MapFileProductWriter<TInputImage> // Get the input Image m_VectorImage = const_cast<TInputImage *>(this->GetInput()); m_VectorImage->UpdateOutputInformation(); - + // Initialize the filename, the vectordatas this->Initialize(); @@ -115,7 +128,10 @@ MapFileProductWriter<TInputImage> writer->Update(); } - +/** + * Initialize the path, the filename, the vectordata used to store + * each bounding box of a tile as a feature + */ template <class TInputImage> void MapFileProductWriter<TInputImage> @@ -155,7 +171,9 @@ MapFileProductWriter<TInputImage> m_VectorDataIndexTile->GetDataTree()->Add(m_Folder, document); } - +/** + * Do the tiling + */ template <class TInputImage> void MapFileProductWriter<TInputImage> @@ -307,7 +325,7 @@ MapFileProductWriter<TInputImage> std::ostringstream ossFileName; ossFileName << m_Path<<"/"; ossFileName << "tiles/tile_"; - ossFileName << m_CurrentDepth<<"_"; + ossFileName << m_CurrentDepth<<"_"; ossFileName << x<<"_"; ossFileName << y; ossFileName << ".tif"; @@ -358,7 +376,7 @@ MapFileProductWriter<TInputImage> m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint); outputPoint = m_Transform->TransformPoint(inputPoint); OutputPointType lowerLeftCorner = outputPoint; - + // Compute lower right corner indexTile[0] = extractIndex[0] + sizeTile[0]; indexTile[1] = extractIndex[1] + sizeTile[1]; @@ -382,9 +400,9 @@ MapFileProductWriter<TInputImage> // Build The indexTile this->AddBBoxToIndexTile(lowerLeftCorner, - lowerRightCorner, - upperRightCorner, - upperLeftCorner,x,y); + lowerRightCorner, + upperRightCorner, + upperLeftCorner,x,y); /** END GX LAT LON */ y++; @@ -396,8 +414,9 @@ MapFileProductWriter<TInputImage> } /** -*/ - + * Add the bounding box and the location of the generated tile as + * field of the vectordata + */ template <class TInputImage> void MapFileProductWriter<TInputImage> @@ -448,6 +467,7 @@ MapFileProductWriter<TInputImage> } /** + * Write the mapFile on the disk */ template <class TInputImage> void @@ -458,71 +478,72 @@ MapFileProductWriter<TInputImage> file << fixed << setprecision(6); file <<"MAP" << std::endl; - file <<" NAME Level0" << std::endl; - file <<" # Map image size" << std::endl; - file <<" SIZE "<< m_TileSize <<" "<< m_TileSize << std::endl; - file <<" UNITS dd" << std::endl<<std::endl; - file <<" EXTENT -180 -90 180 90" << std::endl; - file <<" PROJECTION" << std::endl; - file <<" \"init=epsg:4326\"" << std::endl; - file <<" END" << std::endl; - - file <<" # Background color for the map canvas -- change as desired" << std::endl; - file <<" IMAGECOLOR 192 192 192" << std::endl; - file <<" IMAGEQUALITY 95" << std::endl; - file <<" IMAGETYPE PNG" << std::endl; - file <<" OUTPUTFORMAT" << std::endl; - file <<" NAME PNG" << std::endl; - file <<" DRIVER 'GD/PNG'" << std::endl; - file <<" MIMETYPE 'image/png'" << std::endl; - file <<" IMAGEMODE RGB" << std::endl; - file <<" FORMATOPTION INTERLACE=OFF" << std::endl; - file <<" EXTENSION 'png'" << std::endl; - file <<" END" << std::endl; - - - file <<" # Web interface definition. Only the template parameter" << std::endl; - file <<" # is required to display a map. See MapServer documentation" << std::endl; - file <<" WEB" << std::endl; - file <<" # Set IMAGEPATH to the path where MapServer should" << std::endl; - file <<" # write its output." << std::endl; + file <<"\tNAME Level0" << std::endl; + file <<"\t# Map image size" << std::endl; + file <<"\tSIZE "<< m_TileSize <<" "<< m_TileSize << std::endl; + file <<"\tUNITS dd" << std::endl<<std::endl; + file <<"\tEXTENT -180 -90 180 90" << std::endl; + file <<"\tPROJECTION" << std::endl; + file <<"\t \"init=epsg:4326\"" << std::endl; + file <<"\tEND" << std::endl; + + file <<"\t# Background color for the map canvas -- change as desired" << std::endl; + file <<"\tIMAGECOLOR 192 192 192" << std::endl; + file <<"\tIMAGEQUALITY 95" << std::endl; + file <<"\tIMAGETYPE PNG" << std::endl; + file <<"\tOUTPUTFORMAT" << std::endl; + file <<"\t\tNAME PNG" << std::endl; + file <<"\t\tDRIVER 'GD/PNG'" << std::endl; + file <<"\t\tMIMETYPE 'image/png'" << std::endl; + file <<"\t\tIMAGEMODE RGB" << std::endl; + file <<"\t\tFORMATOPTION INTERLACE=OFF" << std::endl; + file <<"\t\tEXTENSION 'png'" << std::endl; + file <<"\tEND" << std::endl; + + + file <<"\t# Web interface definition. Only the template parameter" << std::endl; + file <<"\t# is required to display a map. See MapServer documentation" << std::endl; + file <<"\tWEB" << std::endl; + file <<"\t\t# Set IMAGEPATH to the path where MapServer should" << std::endl; + file <<"\t\t# write its output." << std::endl; //file <<" #IMAGEPATH \'D:\OSGeo4W_bis2/tmp/ms_tmp/\'" << std::endl; - file <<" # Set IMAGEURL to the url that points to IMAGEPATH" << std::endl; - file <<" # as defined in your web server configuration" << std::endl; - file <<" #IMAGEURL '/ms_tmp/'" << std::endl; - - file <<" # WMS server settings" << std::endl; - file <<" METADATA" << std::endl; - file <<" 'wms_title' 'Level0'" << std::endl; - // XXXX Set the path to this file - file <<" \'wms_onlineresource\' \'http://127.0.0.1/cgi-bin/mapserv.exe?map=D:\\PARTAGE\\testsmapserver2\\niveau1_raster.map&\'" << std::endl; - file <<" \'wms_srs\' \'EPSG:4326\'" << std::endl; - file <<" END" << std::endl; - file <<" END" << std::endl; + file <<"\t\t# Set IMAGEURL to the url that points to IMAGEPATH" << std::endl; + file <<"\t\t# as defined in your web server configuration" << std::endl; + file <<"\t\t#IMAGEURL '/ms_tmp/'" << std::endl; + + file <<"\t\t# WMS server settings" << std::endl; + file <<"\t\t# NOTE : the user must change the path to the mapserver excecutable in the "<<std::endl; + file <<"\t\t wms_onlineresource field"<<std::endl; + file <<"\t\tMETADATA" << std::endl; + file <<"\t\t 'wms_title' 'Level0'" << std::endl; + file <<"\t\t \'wms_onlineresource\' \'http://127.0.0.1/cgi-bin/mapserv.exe?map="<<m_FileName<<"&\'" << std::endl; + file <<"\t\t \'wms_srs\' \'EPSG:4326\'" << std::endl; + file <<"\t\tEND" << std::endl; + file <<"\tEND" << std::endl; // Get the name of the layer std::ostringstream tempIndexShapeName; tempIndexShapeName << itksys::SystemTools::GetFilenameWithoutExtension(m_FileName); - file <<" LAYER" << std::endl; - file <<" NAME '"<<tempIndexShapeName.str()<<"'" << std::endl; - file <<" #GROUP 'earthsat'" << std::endl; - file <<" TYPE RASTER" << std::endl; - file <<" TILEITEM 'LOCATION'" << std::endl; - file <<" TILEINDEX \'"<<m_IndexShapeFileName<<"\'" << std::endl; - file <<" METADATA" << std::endl; - file <<" 'wms_title' 'earthsat'" << std::endl; - file <<" 'wms_name' 'earthsat'" << std::endl; - file <<" END" << std::endl; - file <<" PROCESSING \"RESAMPLE=AVERAGE\"" << std::endl; - file <<" STATUS OFF" << std::endl; - file <<" TRANSPARENCY 100" << std::endl; - file <<" PROJECTION" << std::endl; - file <<" \"init=epsg:4326\"" << std::endl; - file <<" END" << std::endl; - file <<" MINSCALE 250000" << std::endl; - file <<" END" << std::endl; + file <<"\tLAYER" << std::endl; + file <<"\t\tNAME '"<<tempIndexShapeName.str()<<"'" << std::endl; + file <<"\t\t\t#GROUP 'earthsat'" << std::endl; + file <<"\t\t\tTYPE RASTER" << std::endl; + file <<"\t\t\tTILEITEM 'LOCATION'" << std::endl; + file <<"\t\t\tTILEINDEX \'"<<m_IndexShapeFileName<<"\'" << std::endl; + file <<"\t\t\tMETADATA" << std::endl; + file <<"\t\t\t 'wms_title' 'earthsat'" << std::endl; + file <<"\t\t\t 'wms_name' 'earthsat'" << std::endl; + file <<"\t\t\tEND" << std::endl; + file <<"\t\t\tPROCESSING \"RESAMPLE=AVERAGE\"" << std::endl; + file <<"\t\t\tSTATUS OFF" << std::endl; + file <<"\t\t\tTRANSPARENCY 100" << std::endl; + file <<"\t\t\tPROJECTION" << std::endl; + file <<"\t\t\t \"init=epsg:4326\"" << std::endl; + file <<"\t\t\tEND" << std::endl; + file <<"\t\t#MINSCALE 250000" << std::endl; + file <<"\tEND" << std::endl; file <<"END" << std::endl; file.close(); diff --git a/Code/Visualization/otbDragFullWindowActionHandler.h b/Code/Visualization/otbDragFullWindowActionHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..73f1ffbd99cdd99c7e0c1a0471518a57cfd3d79e --- /dev/null +++ b/Code/Visualization/otbDragFullWindowActionHandler.h @@ -0,0 +1,160 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __otbDragFullWindowActionHandler_h +#define __otbDragFullWindowActionHandler_h + +#include "otbCurves2DWidget.h" +#include "otbVerticalAsymptoteCurve.h" + +#include "otbImageWidgetActionHandler.h" + +namespace otb +{ +/** \class DragFullWindowActionHandler +* \brief Implements basic Full widget Dragging . +* +* \sa ImageWidgetController +* \sa ImageWidgetActionHandler +* \ingroup Visualization + */ + +template <class TModel, class TView, class TRenderingFunction> +class ITK_EXPORT DragFullWindowActionHandler + : public ImageWidgetActionHandler +{ +public: + /** Standard class typedefs */ + typedef DragFullWindowActionHandler Self; + typedef ImageWidgetActionHandler Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Method for creation through the object factory */ + itkNewMacro(Self); + + /** Runtime information */ + itkTypeMacro(DragFullWindowActionHandler, ImageWidgetActionHandler); + + /** Model typedefs */ + typedef TModel ModelType; + typedef typename ModelType::Pointer ModelPointerType; + typedef typename ModelType::RegionType RegionType; + typedef typename ModelType::IndexType IndexType; + + /** View typedefs */ + typedef TView ViewType; + typedef typename ViewType::Pointer ViewPointerType; + typedef typename ViewType::ImageWidgetType::PointType PointType; + + /** Rendering Function Type */ + typedef TRenderingFunction RenderingFunctionType; + typedef typename RenderingFunctionType::Pointer RenderingFunctionPointerType; + typedef typename RenderingFunctionType::ParametersType ParametersType; + + /** Handle vertical asymptotes translation + * \param widgetId The id of the handled Curve widget + * \param event kind of event ot handle : FL_DRAG , FL_PUSH, FL_RELEASE + */ + virtual bool HandleWidgetEvent(std::string widgetId, int event) + { + + if (widgetId == m_View->GetFullWidget()->GetIdentifier()) + { + switch (event) + { + case FL_PUSH: + { + PointType screenPoint = m_View->GetFullWidget()->GetMousePosition(); + PointType ImagePoint = m_View->GetFullWidget()->GetScreenToImageTransform()->TransformPoint(screenPoint); + m_IndexPushed[0] = ImagePoint[0]; + m_IndexPushed[1] = ImagePoint[1]; + return true; + } + case FL_RELEASE: + { + PointType screenPoint = m_View->GetFullWidget()->GetMousePosition(); + PointType ImagePoint = m_View->GetFullWidget()->GetScreenToImageTransform()->TransformPoint(screenPoint); + m_IndexReleased[0] = ImagePoint[0]; + m_IndexReleased[1] = ImagePoint[1]; + + // Compute the shift + m_MoveX = -m_IndexReleased[0] + m_IndexPushed[0]; + m_MoveY = -m_IndexReleased[1] + m_IndexPushed[1]; + + // Compute the origin and the size of the visible region + IndexType indexBegin,indexEnd; + indexBegin[0] = static_cast<unsigned int>(m_Model->GetExtractRegion().GetIndex()[0] + m_MoveX); + indexBegin[1] = static_cast<unsigned int>(m_Model->GetExtractRegion().GetIndex()[1] + m_MoveY); + indexEnd[0] = indexBegin[0] + m_Model->GetExtractRegion().GetSize()[0]; + indexEnd[1] = indexBegin[1] + m_Model->GetExtractRegion().GetSize()[1]; + m_Model->SetExtractRegionByIndex(indexBegin, indexEnd); + m_Model->Update(); + return true; + } + } + return false; + } + } + + /** Set/Get the pointer to the view */ + itkSetObjectMacro(View, ViewType); + itkGetObjectMacro(View, ViewType); + + /** Set/Get the pointer to the model */ + itkSetObjectMacro(Model, ModelType); + itkGetObjectMacro(Model, ModelType); + + /** Set/Get the rendering Function */ + itkSetObjectMacro(RenderingFunction, RenderingFunctionType); + +protected: + /** Constructor */ + DragFullWindowActionHandler() : m_View(), m_Model(), m_RenderingFunction() + { } + + /** Destructor */ + virtual ~DragFullWindowActionHandler(){} + /** Printself method */ + void PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + } + +private: + DragFullWindowActionHandler(const Self &); // purposely not implemented + void operator =(const Self&); // purposely not implemented + + // Pointer to the view + ViewPointerType m_View; + + // Pointer to the model + ModelPointerType m_Model; + + // StandardRenderingFunction + RenderingFunctionPointerType m_RenderingFunction; + + // Move + double m_MoveX; + double m_MoveY; + + IndexType m_IndexPushed; + IndexType m_IndexReleased; + +}; // end class +} // end namespace otb +#endif diff --git a/Code/Visualization/otbVectorDataGlComponent.txx b/Code/Visualization/otbVectorDataGlComponent.txx index bc39b0397c6b7aab7acc99e0ca8d4f4519b82e7f..f234b2e25220063d7618a7f0ab95269fdd8753a0 100644 --- a/Code/Visualization/otbVectorDataGlComponent.txx +++ b/Code/Visualization/otbVectorDataGlComponent.txx @@ -294,6 +294,7 @@ VectorDataGlComponent<TVectorData> // Render each child for (typename ChildrenListType::iterator it = children.begin(); it != children.end(); ++it) { + this->Render(*it, extent, space2ScreenTransform); } } diff --git a/Code/Visualization/otbVectorDataModel.cxx b/Code/Visualization/otbVectorDataModel.cxx index 349cf8460a8db3e2794f1cb8668a87ecfa714802..41b0c23d7ffcdf692df59d58ad55d5b53450f66e 100644 --- a/Code/Visualization/otbVectorDataModel.cxx +++ b/Code/Visualization/otbVectorDataModel.cxx @@ -42,9 +42,8 @@ void VectorDataModel::Update(void) this->NotifyAll(); } -void VectorDataModel::AddPointToGeometry(VertexType& vertex) +void VectorDataModel::AddPointToGeometry(VertexType& vertex, bool callUpdate) { - std::cout<<"AddPointToGeometry"<<std::endl; VertexType newPoint; newPoint[0] = m_Origin[0] + vertex[0] / m_Spacing[0]; newPoint[1] = m_Origin[1] + vertex[1] / m_Spacing[1]; @@ -57,7 +56,6 @@ void VectorDataModel::AddPointToGeometry(VertexType& vertex) if (m_CurrentNodeType == FEATURE_POINT) { - std::cout<<"Creating and adding new point"<<std::endl; otbMsgDevMacro(<< "VectorDataModel::AddPointToGeometry: Creating and adding new point"); if (m_CurrentGeometry.IsNull()) { @@ -76,7 +74,6 @@ void VectorDataModel::AddPointToGeometry(VertexType& vertex) } else if (m_CurrentNodeType == FEATURE_POLYGON) { - std::cout<<"Creating and adding new FEATURE_POLYGON"<<std::endl; if (m_CurrentGeometry.IsNull()) { otbMsgDevMacro(<< "VectorDataModel::AddPointToGeometry: Creating new polygon"); @@ -109,7 +106,11 @@ void VectorDataModel::AddPointToGeometry(VertexType& vertex) { itkExceptionMacro(<< "Node type not (yet) supported: " << m_CurrentNodeType); } - this->Update(); + + if(callUpdate == true) + { + this->Update(); + } } void VectorDataModel::EndGeometry(void) @@ -236,4 +237,88 @@ void VectorDataModel::SetSelectedGeometry(int n) m_SelectedGeometry = GetNthDataNode(n); } + +void +VectorDataModel::AddVectorData( VectorDataPointer vData ) +{ + this->EndGeometry(); + DataTreeType::Pointer tree = vData->GetDataTree(); + TreeNodeType * root = const_cast<TreeNodeType *>(tree->GetRoot()); + this->AddNode( root ); + this->Update(); +} + + +void +VectorDataModel::AddNode( TreeNodeType * node ) +{ + // From VEctorDataGlComponent + // Render the current node + switch (node->Get()->GetNodeType()) + { + case FEATURE_POINT: + { + m_CurrentNodeType = FEATURE_POINT; + PointType point = node->Get()->GetPoint(); + VertexType vertex; + vertex[0] = point[0]; + vertex[1] = point[1]; + this->AddPointToGeometry(vertex, false); + this->EndGeometry(); + break; + } + case FEATURE_LINE: + { + m_CurrentNodeType = FEATURE_LINE; + const LineType * line = node->Get()->GetLine(); + LineType::VertexListType::ConstIterator vIt = line->GetVertexList()->Begin(); + + while (vIt != line->GetVertexList()->End()) + { + PointType point = vIt.Value(); + VertexType vertex; + vertex[0] = point[0]; + vertex[1] = point[1]; + this->AddPointToGeometry(vertex, false); + } + this->EndGeometry(); + break; + } + case FEATURE_POLYGON: + { + m_CurrentNodeType = FEATURE_POLYGON; + const PolygonType * extRing = node->Get()->GetPolygonExteriorRing(); + PolygonType::VertexListType::ConstIterator vIt = extRing->GetVertexList()->Begin(); + + while (vIt != extRing->GetVertexList()->End()) + { + PointType point = vIt.Value(); + VertexType vertex; + vertex[0] = point[0]; + vertex[1] = point[1]; + this->AddPointToGeometry(vertex, false); + vIt++; + } + this->EndGeometry(); + break; + } + default: + { + // discard + break; + } + } + + // Get the children list from the input node + ChildrenListType children = node->GetChildrenList(); + + // Render each child + ChildrenListType::iterator it = children.begin(); + while ( it != children.end() ) + { + this->AddNode(*it); + ++it; + } +} + } diff --git a/Code/Visualization/otbVectorDataModel.h b/Code/Visualization/otbVectorDataModel.h index dde6807c79bcd40cf22cd97c75a46e3798693dfe..45291ca2b0eaf1d93e1bf0baeac71907348f1c2b 100644 --- a/Code/Visualization/otbVectorDataModel.h +++ b/Code/Visualization/otbVectorDataModel.h @@ -45,7 +45,11 @@ public: typedef itk::SmartPointer<const Self> ConstPointer; typedef otb::VectorData<double, 2> VectorDataType; + typedef VectorDataType::Pointer VectorDataPointer; typedef VectorDataType::DataNodeType DataNodeType; + typedef VectorDataType::DataTreeType DataTreeType; + typedef DataTreeType::TreeNodeType TreeNodeType; + typedef TreeNodeType::ChildrenListType ChildrenListType; typedef VectorDataType::PointType PointType; typedef VectorDataType::SpacingType SpacingType; typedef VectorDataType::PolygonType PolygonType; @@ -67,8 +71,12 @@ public: /** Return a pointer to the vector data */ itkGetObjectMacro(VectorData, VectorDataType); - - void AddPointToGeometry(VertexType& vertex); + + /** Load a vector data. */ + void AddVectorData( VectorDataPointer vData ); + void AddNode( TreeNodeType * node ); + + void AddPointToGeometry(VertexType& vertex, bool callUpdate = true); void EndGeometry(void); void DeleteGeometry(void); @@ -94,8 +102,8 @@ private: VectorDataModel(const Self &); void operator =(const Self&); - VectorDataType::Pointer m_VectorData; - NodeType m_CurrentNodeType; + VectorDataPointer m_VectorData; + NodeType m_CurrentNodeType; /** Node where the next geometry should be attached */ DataNodeType::Pointer m_CurrentRootNode; diff --git a/Testing/Code/Visualization/CMakeLists.txt b/Testing/Code/Visualization/CMakeLists.txt index 135577919b04dbcd7ed600f8be859488adaecb39..f902627e0c8b70b2a0a313be5b6f5f6221057328 100644 --- a/Testing/Code/Visualization/CMakeLists.txt +++ b/Testing/Code/Visualization/CMakeLists.txt @@ -355,6 +355,13 @@ ${LARGEINPUTDATA}/QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS ) ENDIF(OTB_DATA_USE_LARGEINPUT) +ADD_TEST(vrTvVectorDataModelAddVectorDataTest ${VISUREFAC_TESTS1} +otbVectorDataModelAddVectorDataTest +${INPUTDATA}/QB_Toulouse_Ortho_XS.tif +200 500 200 0 +${INPUTDATA}/Capitole-Shadows.shp +) + # Testing srcs SET(Visualization_SRCS1 otbVisualizationTests1.cxx @@ -404,6 +411,7 @@ otbSplittedWidgetManagerNew.cxx otbVerticalAsymptoteCurveNew.cxx otbVectorDataModelNew.cxx otbVectorDataModelTest.cxx +otbVectorDataModelAddVectorDataTest.cxx ) OTB_ADD_EXECUTABLE(otbVisualizationTests1 "${Visualization_SRCS1}" "OTBVisualization;OTBIO;OTBTesting") diff --git a/Testing/Code/Visualization/otbVectorDataModelAddVectorDataTest.cxx b/Testing/Code/Visualization/otbVectorDataModelAddVectorDataTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ca5835d687200c3eef8977d6e585e8fbff8c6141 --- /dev/null +++ b/Testing/Code/Visualization/otbVectorDataModelAddVectorDataTest.cxx @@ -0,0 +1,251 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "otbImageLayerRenderingModel.h" +#include "otbVectorImage.h" +#include "itkRGBPixel.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "otbImageLayerGenerator.h" +#include "otbImageLayer.h" +#include "otbImageView.h" +#include <FL/Fl.H> +#include "otbImageWidgetController.h" +#include "otbWidgetResizingActionHandler.h" +#include "otbChangeScaledExtractRegionActionHandler.h" +#include "otbChangeExtractRegionActionHandler.h" +#include "otbChangeScaleActionHandler.h" +#include "otbPixelDescriptionModel.h" +#include "otbPixelDescriptionActionHandler.h" +#include "otbPixelDescriptionView.h" + +// Vector data includes +#include "otbVectorData.h" +#include "otbVectorDataFileReader.h" +#include "otbVectorDataProjectionFilter.h" +#include "otbVectorDataGlComponent.h" +#include "otbVectorDataModel.h" +#include "otbVectorDataActionHandler.h" +#include "otbVectorDataFileReader.h" +#include "otbVectorDataProjectionFilter.h" + + +int otbVectorDataModelAddVectorDataTest(int argc, char * argv[]) +{ + // params + const char * infname = argv[1]; + const unsigned int scrollSize = atoi(argv[2]); + const unsigned int fullSize = atoi(argv[3]); + const unsigned int zoomSize = atoi(argv[4]); + const double run = atoi(argv[5]); + const char * vdataName = argv[6]; + + // typedefs + typedef int PixelType; + typedef itk::RGBPixel<unsigned char> RGBPixelType; + typedef otb::Image<RGBPixelType, 2> OutputImageType; + typedef otb::VectorImage<PixelType, 2> ImageType; + typedef otb::ImageLayer<ImageType, OutputImageType> LayerType; + typedef otb::ImageFileReader<ImageType> ReaderType; + typedef otb::ImageLayerGenerator<LayerType> LayerGeneratorType; + typedef otb::ImageLayerRenderingModel<OutputImageType> ModelType; + typedef otb::ImageView<ModelType> ViewType; + typedef otb::ImageWidgetController ControllerType; + typedef otb::WidgetResizingActionHandler + <ModelType, ViewType> ResizingHandlerType; + typedef otb::ChangeScaledExtractRegionActionHandler + <ModelType, ViewType> ChangeScaledRegionHandlerType; + typedef otb::ChangeExtractRegionActionHandler + <ModelType, ViewType> ChangeRegionHandlerType; + typedef otb::ChangeScaleActionHandler + <ModelType, ViewType> ChangeScaleHandlerType; + typedef otb::PixelDescriptionModel<OutputImageType> PixelDescriptionModelType; + typedef otb::PixelDescriptionActionHandler + <PixelDescriptionModelType, ViewType> PixelDescriptionActionHandlerType; + typedef otb::PixelDescriptionView + <PixelDescriptionModelType> PixelDescriptionViewType; + typedef otb::VectorDataActionHandler + <otb::VectorDataModel, ViewType> VectorDataActionHandlerType; + // VectorData + typedef otb::VectorDataModel::VectorDataType VectorDataType; + typedef otb::VectorDataFileReader<VectorDataType> VectorDataFileReaderType; + typedef otb::VectorDataProjectionFilter<VectorDataType, + VectorDataType> + VectorDataProjectionFilterType; + typedef otb::VectorDataGlComponent<VectorDataType> VectorDataGlComponentType; + typedef otb::VectorDataFileReader<VectorDataType> VectorDataReaderType; + + + // Instantiation + ModelType::Pointer model = ModelType::New(); + PixelDescriptionModelType::Pointer pixelModel = PixelDescriptionModelType::New(); + pixelModel->SetLayers(model->GetLayers()); + + // Reading input image + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName(infname); + reader->GenerateOutputInformation(); + + // Generate the layer + LayerGeneratorType::Pointer generator = LayerGeneratorType::New(); + generator->SetImage(reader->GetOutput()); + generator->GenerateLayer(); + + // Add the layer to the model + model->AddLayer(generator->GetLayer()); + + // Build a view + ViewType::Pointer view = ViewType::New(); + view->SetModel(model); + + // Build the VectorDataModel + otb::VectorDataModel::Pointer vdModel = otb::VectorDataModel::New(); + vdModel->RegisterListener(view); + + VectorDataGlComponentType::Pointer vgl = VectorDataGlComponentType::New(); + vgl->SetVectorData(vdModel->GetVectorData()); + + view->GetScrollWidget()->AddGlComponent(vgl); + view->GetFullWidget()->AddGlComponent(vgl); + view->GetZoomWidget()->AddGlComponent(vgl); + + // Build a controller + ControllerType::Pointer controller = ControllerType::New(); + view->SetController(controller); + + // Add the resizing handler + ResizingHandlerType::Pointer resizingHandler = ResizingHandlerType::New(); + resizingHandler->SetModel(model); + resizingHandler->SetView(view); + controller->AddActionHandler(resizingHandler); + + // Add the change scaled region handler + ChangeScaledRegionHandlerType::Pointer changeScaledHandler = ChangeScaledRegionHandlerType::New(); + changeScaledHandler->SetModel(model); + changeScaledHandler->SetView(view); + changeScaledHandler->SetMouseButton(2); + controller->AddActionHandler(changeScaledHandler); + + // Add the change extract region handler + ChangeRegionHandlerType::Pointer changeHandler = ChangeRegionHandlerType::New(); + changeHandler->SetModel(model); + changeHandler->SetView(view); + changeHandler->SetMouseButton(2); + controller->AddActionHandler(changeHandler); + + // Add the change scaled handler + ChangeScaleHandlerType::Pointer changeScaleHandler = ChangeScaleHandlerType::New(); + changeScaleHandler->SetModel(model); + changeScaleHandler->SetView(view); + controller->AddActionHandler(changeScaleHandler); + + // Add the pixel description action handler + PixelDescriptionActionHandlerType::Pointer pixelActionHandler = PixelDescriptionActionHandlerType::New(); + pixelActionHandler->SetView(view); + pixelActionHandler->SetModel(pixelModel); + controller->AddActionHandler(pixelActionHandler); + + // Add the VectorData action handler + VectorDataActionHandlerType::Pointer vdHandler = VectorDataActionHandlerType::New(); + vdHandler->SetView(view); + vdHandler->SetModel(vdModel); + controller->AddActionHandler(vdHandler); + + // Build a pixel description view + PixelDescriptionViewType::Pointer pixelView = PixelDescriptionViewType::New(); + pixelView->SetModel(pixelModel); + + Fl_Window pixelWindow(fullSize, 50); + if (fullSize > 0) + { + pixelWindow.add(pixelView->GetPixelDescriptionWidget()); + pixelWindow.resizable(pixelView->GetPixelDescriptionWidget()); + pixelWindow.show(); + pixelView->GetPixelDescriptionWidget()->show(); + pixelView->GetPixelDescriptionWidget()->resize(0, 0, fullSize, 50); + } + + Fl_Window scrollWindow(scrollSize, scrollSize); + if (scrollSize > 0) + { + scrollWindow.add(view->GetScrollWidget()); + scrollWindow.resizable(view->GetScrollWidget()); + scrollWindow.show(); + view->GetScrollWidget()->show(); + view->GetScrollWidget()->resize(0, 0, scrollSize, scrollSize); + } + + Fl_Window fullWindow(fullSize, fullSize); + if (fullSize > 0) + { + fullWindow.add(view->GetFullWidget()); + fullWindow.resizable(view->GetFullWidget()); + fullWindow.show(); + view->GetFullWidget()->show(); + view->GetFullWidget()->resize(0, 0, fullSize, fullSize); + } + + Fl_Window zoomWindow(zoomSize, zoomSize); + if (zoomSize > 0) + { + zoomWindow.add(view->GetZoomWidget()); + zoomWindow.resizable(view->GetZoomWidget()); + zoomWindow.show(); + view->GetZoomWidget()->show(); + view->GetZoomWidget()->resize(0, 0, zoomSize, zoomSize); + } + + VectorDataReaderType::Pointer vdReader = VectorDataReaderType::New(); + vdReader->SetFileName(vdataName); + vdReader->Update(); + typedef otb::VectorDataProjectionFilter<VectorDataType,VectorDataType> ProjectionFilterType; + ProjectionFilterType::Pointer vectorDataProjection = ProjectionFilterType::New(); + vectorDataProjection->SetInput(vdReader->GetOutput()); + + ImageType::PointType lNewOrigin; + // polygons are recorded with a 0.5 shift... + lNewOrigin[0] = reader->GetOutput()->GetOrigin()[0]+0.5; + lNewOrigin[1] = reader->GetOutput()->GetOrigin()[1]+0.5; + + vectorDataProjection->SetOutputOrigin(lNewOrigin); + vectorDataProjection->SetOutputSpacing(reader->GetOutput()->GetSpacing()); + + std::string projectionRef; + itk::ExposeMetaData<std::string>(reader->GetOutput()->GetMetaDataDictionary(), + otb::MetaDataKey::ProjectionRefKey, projectionRef ); + vectorDataProjection->SetOutputProjectionRef(projectionRef); + vectorDataProjection->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + vectorDataProjection->Update(); + + vdModel->AddVectorData(vectorDataProjection->GetOutput()); + + if (run) + { + Fl::run(); + } + else + { + Fl::check(); + } + + zoomWindow.remove(view->GetZoomWidget()); + scrollWindow.remove(view->GetScrollWidget()); + fullWindow.remove(view->GetFullWidget()); + pixelWindow.remove(pixelView->GetPixelDescriptionWidget()); + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Visualization/otbVisualizationTests1.cxx b/Testing/Code/Visualization/otbVisualizationTests1.cxx index f95fbfe6d62bdd48d0c9112363e54bad5b923e1d..a7d8bd4cf6d55162a5f17723137d0bce72256b87 100644 --- a/Testing/Code/Visualization/otbVisualizationTests1.cxx +++ b/Testing/Code/Visualization/otbVisualizationTests1.cxx @@ -71,4 +71,5 @@ void RegisterTests() REGISTER_TEST(otbVerticalAsymptoteCurveNew); REGISTER_TEST(otbVectorDataModelNew); REGISTER_TEST(otbVectorDataModelTest); + REGISTER_TEST(otbVectorDataModelAddVectorDataTest); }