diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ffd5d39778a3c7398c8b37a475780ce92a304225 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,2 @@ +project(SimpleExtractionTools) +otb_module_impl() diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000000000000000000000000000000000000..4da74725b66584eff5d9badbc9db127e0e6b8ec1 --- /dev/null +++ b/LICENCE @@ -0,0 +1,507 @@ + +CeCILL FREE SOFTWARE LICENSE AGREEMENT + + + Notice + +This Agreement is a Free Software license agreement that is the result +of discussions between its authors in order to ensure compliance with +the two main principles guiding its drafting: + + * firstly, compliance with the principles governing the distribution + of Free Software: access to source code, broad rights granted to + users, + * secondly, the election of a governing law, French law, with which + it is conformant, both as regards the law of torts and + intellectual property law, and the protection that it offers to + both authors and holders of the economic rights over software. + +The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) +license are: + +Commissariat à l'Energie Atomique - CEA, a public scientific, technical +and industrial research establishment, having its principal place of +business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. + +Centre National de la Recherche Scientifique - CNRS, a public scientific +and technological establishment, having its principal place of business +at 3 rue Michel-Ange, 75794 Paris cedex 16, France. + +Institut National de Recherche en Informatique et en Automatique - +INRIA, a public scientific and technological establishment, having its +principal place of business at Domaine de Voluceau, Rocquencourt, BP +105, 78153 Le Chesnay cedex, France. + + + Preamble + +The purpose of this Free Software license agreement is to grant users +the right to modify and redistribute the software governed by this +license within the framework of an open source distribution model. + +The exercising of these rights is conditional upon certain obligations +for users so as to preserve this status for all subsequent redistributions. + +In consideration of access to the source code and the rights to copy, +modify and redistribute granted by the license, users are provided only +with a limited warranty and the software's author, the holder of the +economic rights, and the successive licensors only have limited liability. + +In this respect, the risks associated with loading, using, modifying +and/or developing or reproducing the software by the user are brought to +the user's attention, given its Free Software status, which may make it +complicated to use, with the result that its use is reserved for +developers and experienced professionals having in-depth computer +knowledge. Users are therefore encouraged to load and test the +suitability of the software as regards their requirements in conditions +enabling the security of their systems and/or data to be ensured and, +more generally, to use and operate it in the same conditions of +security. This Agreement may be freely reproduced and published, +provided it is not altered, and that no provisions are either added or +removed herefrom. + +This Agreement may apply to any or all software for which the holder of +the economic rights decides to submit the use thereof to its provisions. + + + Article 1 - DEFINITIONS + +For the purpose of this Agreement, when the following expressions +commence with a capital letter, they shall have the following meaning: + +Agreement: means this license agreement, and its possible subsequent +versions and annexes. + +Software: means the software in its Object Code and/or Source Code form +and, where applicable, its documentation, "as is" when the Licensee +accepts the Agreement. + +Initial Software: means the Software in its Source Code and possibly its +Object Code form and, where applicable, its documentation, "as is" when +it is first distributed under the terms and conditions of the Agreement. + +Modified Software: means the Software modified by at least one +Contribution. + +Source Code: means all the Software's instructions and program lines to +which access is required so as to modify the Software. + +Object Code: means the binary files originating from the compilation of +the Source Code. + +Holder: means the holder(s) of the economic rights over the Initial +Software. + +Licensee: means the Software user(s) having accepted the Agreement. + +Contributor: means a Licensee having made at least one Contribution. + +Licensor: means the Holder, or any other individual or legal entity, who +distributes the Software under the Agreement. + +Contribution: means any or all modifications, corrections, translations, +adaptations and/or new functions integrated into the Software by any or +all Contributors, as well as any or all Internal Modules. + +Module: means a set of sources files including their documentation that +enables supplementary functions or services in addition to those offered +by the Software. + +External Module: means any or all Modules, not derived from the +Software, so that this Module and the Software run in separate address +spaces, with one calling the other when they are run. + +Internal Module: means any or all Module, connected to the Software so +that they both execute in the same address space. + +GNU GPL: means the GNU General Public License version 2 or any +subsequent version, as published by the Free Software Foundation Inc. + +Parties: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + + + Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the +Licensee of a non-exclusive, transferable and worldwide license for the +Software as set forth in Article 5 hereinafter for the whole term of the +protection granted by the rights over said Software. + + + Article 3 - ACCEPTANCE + +3.1 The Licensee shall be deemed as having accepted the terms and +conditions of this Agreement upon the occurrence of the first of the +following events: + + * (i) loading the Software by any or all means, notably, by + downloading from a remote server, or by loading from a physical + medium; + * (ii) the first time the Licensee exercises any of the rights + granted hereunder. + +3.2 One copy of the Agreement, containing a notice relating to the +characteristics of the Software, to the limited warranty, and to the +fact that its use is restricted to experienced users has been provided +to the Licensee prior to its acceptance as set forth in Article 3.1 +hereinabove, and the Licensee hereby acknowledges that it has read and +understood it. + + + Article 4 - EFFECTIVE DATE AND TERM + + + 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by +the Licensee as set forth in Article 3.1. + + + 4.2 TERM + +The Agreement shall remain in force for the entire legal term of +protection of the economic rights over the Software. + + + Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following +rights over the Software for any or all use, and for the term of the +Agreement, on the basis of the terms and conditions set forth hereinafter. + +Besides, if the Licensor owns or comes to own one or more patents +protecting all or part of the functions of the Software or of its +components, the Licensor undertakes not to enforce the rights granted by +these patents against successive Licensees using, exploiting or +modifying the Software. If these patents are transferred, the Licensor +undertakes to have the transferees subscribe to the obligations set +forth in this paragraph. + + + 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation +as to its fields of application, with it being hereinafter specified +that this comprises: + + 1. permanent or temporary reproduction of all or part of the Software + by any or all means and in any or all form. + + 2. loading, displaying, running, or storing the Software on any or + all medium. + + 3. entitlement to observe, study or test its operation so as to + determine the ideas and principles behind any or all constituent + elements of said Software. This shall apply when the Licensee + carries out any or all loading, displaying, running, transmission + or storage operation as regards the Software, that it is entitled + to carry out hereunder. + + + 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS + +The right to make Contributions includes the right to translate, adapt, +arrange, or make any or all modifications to the Software, and the right +to reproduce the resulting software. + +The Licensee is authorized to make any or all Contributions to the +Software provided that it includes an explicit notice that it is the +author of said Contribution and indicates the date of the creation thereof. + + + 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, +transmit and communicate the Software to the general public on any or +all medium, and by any or all means, and the right to market, either in +consideration of a fee, or free of charge, one or more copies of the +Software by any means. + +The Licensee is further authorized to distribute copies of the modified +or unmodified Software to third parties according to the terms and +conditions set forth hereinafter. + + + 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is authorized to distribute true copies of the Software in +Source Code or Object Code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's + warranty and liability as set forth in Articles 8 and 9, + +and that, in the event that only the Object Code of the Software is +redistributed, the Licensee allows future Licensees unhindered access to +the full Source Code of the Software by indicating how to access it, it +being understood that the additional cost of acquiring the Source Code +shall not exceed the cost of transferring the data. + + + 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee makes a Contribution to the Software, the terms and +conditions for the distribution of the resulting Modified Software +become subject to all the provisions of this Agreement. + +The Licensee is authorized to distribute the Modified Software, in +source code or object code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's + warranty and liability as set forth in Articles 8 and 9, + +and that, in the event that only the object code of the Modified +Software is redistributed, the Licensee allows future Licensees +unhindered access to the full source code of the Modified Software by +indicating how to access it, it being understood that the additional +cost of acquiring the source code shall not exceed the cost of +transferring the data. + + + 5.3.3 DISTRIBUTION OF EXTERNAL MODULES + +When the Licensee has developed an External Module, the terms and +conditions of this Agreement do not apply to said External Module, that +may be distributed under a separate license agreement. + + + 5.3.4 COMPATIBILITY WITH THE GNU GPL + +The Licensee can include a code that is subject to the provisions of one +of the versions of the GNU GPL in the Modified or unmodified Software, +and distribute that entire code under the terms of the same version of +the GNU GPL. + +The Licensee can include the Modified or unmodified Software in a code +that is subject to the provisions of one of the versions of the GNU GPL, +and distribute that entire code under the terms of the same version of +the GNU GPL. + + + Article 6 - INTELLECTUAL PROPERTY + + + 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the economic rights over the Initial Software. Any or +all use of the Initial Software is subject to compliance with the terms +and conditions under which the Holder has elected to distribute its work +and no one shall be entitled to modify the terms and conditions for the +distribution of said Initial Software. + +The Holder undertakes that the Initial Software will remain ruled at +least by this Agreement, for the duration set forth in Article 4.2. + + + 6.2 OVER THE CONTRIBUTIONS + +The Licensee who develops a Contribution is the owner of the +intellectual property rights over this Contribution as defined by +applicable law. + + + 6.3 OVER THE EXTERNAL MODULES + +The Licensee who develops an External Module is the owner of the +intellectual property rights over this External Module as defined by +applicable law and is free to choose the type of agreement that shall +govern its distribution. + + + 6.4 JOINT PROVISIONS + +The Licensee expressly undertakes: + + 1. not to remove, or modify, in any manner, the intellectual property + notices attached to the Software; + + 2. to reproduce said notices, in an identical manner, in the copies + of the Software modified or not. + +The Licensee undertakes not to directly or indirectly infringe the +intellectual property rights of the Holder and/or Contributors on the +Software and to take, where applicable, vis-à -vis its staff, any and all +measures required to ensure respect of said intellectual property rights +of the Holder and/or Contributors. + + + Article 7 - RELATED SERVICES + +7.1 Under no circumstances shall the Agreement oblige the Licensor to +provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The +terms and conditions of such technical assistance, and/or such +maintenance, shall be set forth in a separate instrument. Only the +Licensor offering said maintenance and/or technical assistance services +shall incur liability therefor. + +7.2 Similarly, any Licensor is entitled to offer to its licensees, under +its sole responsibility, a warranty, that shall only be binding upon +itself, for the redistribution of the Software and/or the Modified +Software, under terms and conditions that it is free to decide. Said +warranty, and the financial terms and conditions of its application, +shall be subject of a separate instrument executed between the Licensor +and the Licensee. + + + Article 8 - LIABILITY + +8.1 Subject to the provisions of Article 8.2, the Licensee shall be +entitled to claim compensation for any direct loss it may have suffered +from the Software as a result of a fault on the part of the relevant +Licensor, subject to providing evidence thereof. + +8.2 The Licensor's liability is limited to the commitments made under +this Agreement and shall not be incurred as a result of in particular: +(i) loss due the Licensee's total or partial failure to fulfill its +obligations, (ii) direct or consequential loss that is suffered by the +Licensee due to the use or performance of the Software, and (iii) more +generally, any consequential loss. In particular the Parties expressly +agree that any or all pecuniary or business loss (i.e. loss of data, +loss of profits, operating loss, loss of customers or orders, +opportunity cost, any disturbance to business activities) or any or all +legal proceedings instituted against the Licensee by a third party, +shall constitute consequential loss and shall not provide entitlement to +any or all compensation from the Licensor. + + + Article 9 - WARRANTY + +9.1 The Licensee acknowledges that the scientific and technical +state-of-the-art when the Software was distributed did not enable all +possible uses to be tested and verified, nor for the presence of +possible defects to be detected. In this respect, the Licensee's +attention has been drawn to the risks associated with loading, using, +modifying and/or developing and reproducing the Software which are +reserved for experienced users. + +The Licensee shall be responsible for verifying, by any or all means, +the suitability of the product for its requirements, its good working +order, and for ensuring that it shall not cause damage to either persons +or properties. + +9.2 The Licensor hereby represents, in good faith, that it is entitled +to grant all the rights over the Software (including in particular the +rights set forth in Article 5). + +9.3 The Licensee acknowledges that the Software is supplied "as is" by +the Licensor without any other express or tacit warranty, other than +that provided for in Article 9.2 and, in particular, without any warranty +as to its commercial value, its secured, safe, innovative or relevant +nature. + +Specifically, the Licensor does not warrant that the Software is free +from any error, that it will operate without interruption, that it will +be compatible with the Licensee's own equipment and software +configuration, nor that it will meet the Licensee's requirements. + +9.4 The Licensor does not either expressly or tacitly warrant that the +Software does not infringe any third party intellectual property right +relating to a patent, software or any other property right. Therefore, +the Licensor disclaims any and all liability towards the Licensee +arising out of any or all proceedings for infringement that may be +instituted in respect of the use, modification and redistribution of the +Software. Nevertheless, should such proceedings be instituted against +the Licensee, the Licensor shall provide it with technical and legal +assistance for its defense. Such technical and legal assistance shall be +decided on a case-by-case basis between the relevant Licensor and the +Licensee pursuant to a memorandum of understanding. The Licensor +disclaims any and all liability as regards the Licensee's use of the +name of the Software. No warranty is given as regards the existence of +prior rights over the name of the Software or as regards the existence +of a trademark. + + + Article 10 - TERMINATION + +10.1 In the event of a breach by the Licensee of its obligations +hereunder, the Licensor may automatically terminate this Agreement +thirty (30) days after notice has been sent to the Licensee and has +remained ineffective. + +10.2 A Licensee whose Agreement is terminated shall no longer be +authorized to use, modify or distribute the Software. However, any +licenses that it may have granted prior to termination of the Agreement +shall remain valid subject to their having been granted in compliance +with the terms and conditions hereof. + + + Article 11 - MISCELLANEOUS + + + 11.1 EXCUSABLE EVENTS + +Neither Party shall be liable for any or all delay, or failure to +perform the Agreement, that may be attributable to an event of force +majeure, an act of God or an outside cause, such as defective +functioning or interruptions of the electricity or telecommunications +networks, network paralysis following a virus attack, intervention by +government authorities, natural disasters, water damage, earthquakes, +fire, explosions, strikes and labor unrest, war, etc. + +11.2 Any failure by either Party, on one or more occasions, to invoke +one or more of the provisions hereof, shall under no circumstances be +interpreted as being a waiver by the interested Party of its right to +invoke said provision(s) subsequently. + +11.3 The Agreement cancels and replaces any or all previous agreements, +whether written or oral, between the Parties and having the same +purpose, and constitutes the entirety of the agreement between said +Parties concerning said purpose. No supplement or modification to the +terms and conditions hereof shall be effective as between the Parties +unless it is made in writing and signed by their duly authorized +representatives. + +11.4 In the event that one or more of the provisions hereof were to +conflict with a current or future applicable act or legislative text, +said act or legislative text shall prevail, and the Parties shall make +the necessary amendments so as to comply with said act or legislative +text. All other provisions shall remain effective. Similarly, invalidity +of a provision of the Agreement, for any reason whatsoever, shall not +cause the Agreement as a whole to be invalid. + + + 11.5 LANGUAGE + +The Agreement is drafted in both French and English and both versions +are deemed authentic. + + + Article 12 - NEW VERSIONS OF THE AGREEMENT + +12.1 Any person is authorized to duplicate and distribute copies of this +Agreement. + +12.2 So as to ensure coherence, the wording of this Agreement is +protected and may only be modified by the authors of the License, who +reserve the right to periodically publish updates or new versions of the +Agreement, each with a separate number. These subsequent versions may +address new issues encountered by Free Software. + +12.3 Any Software distributed under a given version of the Agreement may +only be subsequently distributed under the same version of the Agreement +or a subsequent version, subject to the provisions of Article 5.3.4. + + + Article 13 - GOVERNING LAW AND JURISDICTION + +13.1 The Agreement is governed by French law. The Parties agree to +endeavor to seek an amicable solution to any disagreements or disputes +that may arise during the performance of the Agreement. + +13.2 Failing an amicable solution within two (2) months as from their +occurrence, and unless emergency proceedings are necessary, the +disagreements or disputes shall be referred to the Paris Courts having +jurisdiction, by the more diligent Party. + + +Version 2.0 dated 2006-09-05. + diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ad591a5cf23eb8971fe1fec2a2304367f294eaf8 --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required (VERSION 2.8) + +OTB_CREATE_APPLICATION(NAME ExtractBand + SOURCES otbExtractBand.cxx + LINK_LIBRARIES OTBCommon) + +OTB_CREATE_APPLICATION(NAME ExtractGeom + SOURCES otbExtractGeom.cxx + LINK_LIBRARIES OTBCommon) + diff --git a/app/otbExtractBand.cxx b/app/otbExtractBand.cxx new file mode 100644 index 0000000000000000000000000000000000000000..17bc5e0fd242dd7b137c2e1472ae7612facc4f91 --- /dev/null +++ b/app/otbExtractBand.cxx @@ -0,0 +1,110 @@ +/*========================================================================= + + Copyright (c) IRSTEA. All rights reserved. + + + 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 "itkFixedArray.h" +#include "itkObjectFactory.h" + +// Elevation handler +#include "otbWrapperElevationParametersHandler.h" +#include "otbWrapperApplicationFactory.h" + +// Application engine +#include "otbStandardFilterWatcher.h" +#include "itkFixedArray.h" + +// Filter +#include "otbMultiChannelExtractROI.h" + +using namespace std; + +namespace otb +{ + +namespace Wrapper +{ + +class ExtractBand : public Application +{ +public: + /** Standard class typedefs. */ + typedef ExtractBand Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType, + FloatVectorImageType::InternalPixelType> ExtractFilterType; + + /** Standard macro */ + itkNewMacro(Self); + itkTypeMacro(ExtractBand, Application); + + void DoInit() + { + + SetName("ExtractBand"); + SetDescription("Perform single band extraction"); + + // Documentation + SetDocName("ExtractBand"); + SetDocLongDescription("This application performs single band extraction"); + SetDocLimitations("None"); + SetDocAuthors("Remi Cresson"); + SetDocSeeAlso(" "); + + AddDocTag(Tags::Manip); + + AddParameter(ParameterType_InputImage, "inxs", "Input XS Image"); + SetParameterDescription("inxs"," Input XS image."); + + AddParameter(ParameterType_Int, "band", "band index" ); + SetParameterDescription("band","Set the band index to extract" ); + SetMinimumParameterIntValue("band", 1); + + AddParameter(ParameterType_OutputImage, "out", "Output image"); + SetParameterDescription("out"," Output image."); + + AddRAMParameter(); + + // Doc example parameter settings + SetDocExampleParameterValue("band", "2"); + SetDocExampleParameterValue("inxs", "QB_Toulouse_Ortho_XS.tif"); + SetDocExampleParameterValue("out", "Pansharpening.tif uint16"); + + + } + + void DoUpdateParameters() + { + // Nothing to do here : all parameters are independent + } + + void DoExecute() + { + + FloatVectorImageType* xs = GetParameterImage("inxs"); + + unsigned int band = GetParameterInt("band"); + m_Filter = ExtractFilterType::New(); + m_Filter->SetFirstChannel(band); + m_Filter->SetLastChannel(band); + m_Filter->SetInput(xs); + + SetParameterOutputImage("out", m_Filter->GetOutput()); + + } + + ExtractFilterType::Pointer m_Filter; + +}; +} +} + +OTB_APPLICATION_EXPORT( otb::Wrapper::ExtractBand ) diff --git a/app/otbExtractGeom.cxx b/app/otbExtractGeom.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6b9056c7da3baebd1bfd58bcfdb68ec0797fcade --- /dev/null +++ b/app/otbExtractGeom.cxx @@ -0,0 +1,175 @@ +/*========================================================================= + + Copyright (c) IRSTEA. All rights reserved. + + + 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 "itkFixedArray.h" +#include "itkObjectFactory.h" + +// Elevation handler +#include "otbWrapperElevationParametersHandler.h" +#include "otbWrapperApplicationFactory.h" + +// Application engine +#include "otbStandardFilterWatcher.h" +#include "itkFixedArray.h" + +// Filter +#include "otbMultiChannelExtractROI.h" +#include "otbVectorDataToLabelImageCustomFilter.h" +#include "itkMaskImageFilter.h" +#include "otbVectorDataIntoImageProjectionFilter.h" +#include "otbVectorDataProperties.h" +#include "otbRegionComparator.h" + +using namespace std; + +namespace otb +{ + +namespace Wrapper +{ + +class ExtractGeom : public Application +{ +public: + /** Standard class typedefs. */ + typedef ExtractGeom Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Standard macro */ + itkNewMacro(Self); + itkTypeMacro(ExtractGeom, Application); + + /** Filters */ + typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType, + FloatVectorImageType::InternalPixelType> ExtractFilterType; + + /** mask */ + typedef bool TMaskPixelValueType; + typedef otb::Image<TMaskPixelValueType, 2> MaskImageType; + typedef itk::MaskImageFilter<FloatVectorImageType, MaskImageType, + FloatVectorImageType> MaskFilterType; + + /* vector data filters */ + typedef otb::VectorDataIntoImageProjectionFilter<VectorDataType, + FloatVectorImageType> VectorDataReprojFilterType; + typedef otb::VectorDataToLabelImageCustomFilter<VectorDataType, + MaskImageType> RasteriseFilterType; + typedef otb::VectorDataProperties<VectorDataType> VectorDataPropertiesType; + + void DoInit() + { + SetName("ExtractGeom"); + SetDescription("Perform geometric extraction"); + + // Documentation + SetDocName("ExtractGeom"); + SetDocLongDescription("This application performs geometric extraction"); + SetDocLimitations("None"); + SetDocAuthors("RemiCresson"); + SetDocSeeAlso(" "); + + AddDocTag(Tags::Manip); + + AddParameter(ParameterType_InputImage, "in", "Input Image"); + SetParameterDescription("in"," Input image."); + + AddParameter(ParameterType_InputVectorData, "shp", "Input Shapefile" ); + SetParameterDescription("shp","Input Shapefile" ); + + AddParameter(ParameterType_OutputImage, "out", "Output image"); + SetParameterDescription("out"," Output image."); + + AddRAMParameter(); + + // Doc example parameter settings + SetDocExampleParameterValue("shp", "vecteur.shp"); + SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif"); + SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_decoup.tif uint16"); + + + + + } + + void DoUpdateParameters() + { + // Nothing to do here : all parameters are independent + } + + void DoExecute() + { + + // Get inputs + FloatVectorImageType::Pointer xs = GetParameterImage("in"); + VectorDataType* shp = GetParameterVectorData("shp"); + + /* Reproject vector data */ + vdReproj = VectorDataReprojFilterType::New(); + vdReproj->SetInputVectorData(shp); + vdReproj->SetInputImage(xs); + vdReproj->Update(); + + /* Get VectorData bounding box */ + vdProperties = VectorDataPropertiesType::New(); + vdProperties->SetVectorDataObject(vdReproj->GetOutput()); + vdProperties->ComputeBoundingRegion(); + + /* Compute intersecting region */ + otb::RegionComparator<FloatVectorImageType, FloatVectorImageType> comparator; + comparator.SetImage1(xs); + FloatVectorImageType::RegionType roi = + comparator.RSRegionToImageRegion(vdProperties->GetBoundingRegion()); + roi.PadByRadius(1); // avoid extrapolation + if (!roi.Crop(xs->GetLargestPossibleRegion())) + { + otbAppLogFATAL( << " Input VectorData is outside image !" ); + return; + } + + /* Rasterize vector data */ + rasterizer = RasteriseFilterType::New(); + rasterizer->AddVectorData(vdReproj->GetOutput()); + rasterizer->SetOutputOrigin(xs->GetOrigin()); + rasterizer->SetOutputSpacing(xs->GetSpacing()); + rasterizer->SetOutputSize( + xs->GetLargestPossibleRegion().GetSize()); + rasterizer->SetBurnMaxValueMode(true); + rasterizer->SetOutputProjectionRef( + xs->GetProjectionRef()); + rasterizer->Update(); + + /* Mask input image */ + maskFilter = MaskFilterType::New(); + maskFilter->SetInput(xs); + maskFilter->SetMaskImage(rasterizer->GetOutput()); + + /* Extract ROI */ + m_Filter = ExtractFilterType::New(); + m_Filter->SetInput(maskFilter->GetOutput()); + m_Filter->SetExtractionRegion(roi); + + SetParameterOutputImage("out", m_Filter->GetOutput()); + + + } + + ExtractFilterType::Pointer m_Filter; + VectorDataReprojFilterType::Pointer vdReproj; + RasteriseFilterType::Pointer rasterizer; + VectorDataPropertiesType::Pointer vdProperties; + MaskFilterType::Pointer maskFilter; + +}; +} +} + +OTB_APPLICATION_EXPORT( otb::Wrapper::ExtractGeom ) diff --git a/include/otbRegionComparator.h b/include/otbRegionComparator.h new file mode 100644 index 0000000000000000000000000000000000000000..1c2b51a84b6956a6174eac09e7d2a7415abac1c0 --- /dev/null +++ b/include/otbRegionComparator.h @@ -0,0 +1,242 @@ +/*========================================================================= + + Copyright (c) IRSTEA. All rights reserved. + + + 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 otbRegionComparator_H_ +#define otbRegionComparator_H_ + +#include "otbObjectList.h" +#include "itkContinuousIndex.h" +#include "itkImageLinearConstIteratorWithIndex.h" +#include "itkMetaDataDictionary.h" +#include "ogr_api.h" +#include "ogr_feature.h" +#include "otbMetaDataKey.h" +#include "itkMetaDataObject.h" +#include "itkNumericTraits.h" + +#include <iostream> +#include <sstream> +#include <fstream> +#include <string> +#include <algorithm> + +#include "otbRemoteSensingRegion.h" + +#define msg(x) do { std::cout << x << std::endl;} while(0) + +using namespace std; + +namespace otb { + +template<class TInputImage1, class TInputImage2=TInputImage1> class RegionComparator{ +public: + + typedef TInputImage1 InputImage1Type; + typedef typename InputImage1Type::Pointer InputImage1PointerType; + typedef typename InputImage1Type::RegionType InputImage1RegionType; + + typedef TInputImage2 InputImage2Type; + typedef typename InputImage2Type::Pointer InputImage2PointerType; + typedef typename InputImage2Type::RegionType InputImage2RegionType; + + typedef typename otb::RemoteSensingRegion<double> RSRegion; + + void SetImage1(InputImage1PointerType im1) {m_InputImage1 = im1;} + void SetImage2(InputImage2PointerType im2) {m_InputImage2 = im2;} + + InputImage2RegionType GetOverlapInImage1Indices() + { + // Largest region of im2 --> region in im1 + InputImage1RegionType region2 = m_InputImage2->GetLargestPossibleRegion(); + InputImage1RegionType region2_in_1; + OutputRegionToInputRegion(region2, region2_in_1, m_InputImage2, m_InputImage1); + + // Collision test + InputImage2RegionType region1 = m_InputImage1->GetLargestPossibleRegion(); + region2_in_1.Crop(region1); + + // Return overlap + return region2_in_1; + } + + InputImage2RegionType GetOverlapInImage2Indices() + { + // Largest region of im1 --> region in im2 + InputImage1RegionType region1 = m_InputImage1->GetLargestPossibleRegion(); + InputImage1RegionType region1_in_2; + OutputRegionToInputRegion(region1, region1_in_2, m_InputImage1, m_InputImage2); + + // Collision test + InputImage2RegionType region2 = m_InputImage2->GetLargestPossibleRegion(); + region1_in_2.Crop(region2); + + // Return overlap + return region1_in_2; + } + + bool DoesOverlap() + { + // Largest region of im1 --> region in im2 + InputImage1RegionType region1 = m_InputImage1->GetLargestPossibleRegion(); + InputImage1RegionType region1_in_2; + OutputRegionToInputRegion(region1, region1_in_2, m_InputImage1, m_InputImage2); + + // Collision test + InputImage2RegionType region2 = m_InputImage2->GetLargestPossibleRegion(); + return region1_in_2.Crop(region2); + } + + /* + * Converts sourceRegion of im1 into targetRegion of im2 + */ + void OutputRegionToInputRegion(const InputImage1RegionType &sourceRegion, InputImage2RegionType &targetRegion, + const InputImage1PointerType &sourceImage, const InputImage2PointerType &targetImage) + { + + // Source Region (source image indices) + typename InputImage1RegionType::IndexType sourceRegionIndexStart = sourceRegion.GetIndex(); + typename InputImage1RegionType::IndexType sourceRegionIndexEnd; + for(unsigned int dim = 0; dim < InputImage1Type::ImageDimension; ++dim) + sourceRegionIndexEnd[dim]= sourceRegionIndexStart[dim] + sourceRegion.GetSize()[dim]-1; + + // Source Region (Geo) + typename InputImage1Type::PointType sourceRegionIndexStartGeo, sourceRegionIndexEndGeo; + sourceImage->TransformIndexToPhysicalPoint(sourceRegionIndexStart, sourceRegionIndexStartGeo); + sourceImage->TransformIndexToPhysicalPoint(sourceRegionIndexEnd , sourceRegionIndexEndGeo ); + + // Source Region (target image indices) + typename InputImage2RegionType::IndexType targetIndexStart, targetIndexEnd; + targetImage->TransformPhysicalPointToIndex(sourceRegionIndexStartGeo, targetIndexStart); + targetImage->TransformPhysicalPointToIndex(sourceRegionIndexEndGeo , targetIndexEnd); + + // Target Region (target image indices) + typename InputImage2RegionType::IndexType targetRegionStart; + typename InputImage2RegionType::SizeType targetRegionSize; + for(unsigned int dim = 0; dim<InputImage2Type::ImageDimension; ++dim) + { + targetRegionStart[dim] = std::min(targetIndexStart[dim], targetIndexEnd[dim]); + targetRegionSize[dim] = std::max(targetIndexStart[dim], targetIndexEnd[dim]) - targetRegionStart[dim] + 1; + } + InputImage2RegionType computedInputRegion(targetRegionStart, targetRegionSize); + + // Avoid extrapolation + computedInputRegion.PadByRadius(1); + + // Target Region + targetRegion = computedInputRegion; + + } + + /* + * Converts a RemoteSensingREgion into a ImageRegion (image1) + */ + InputImage1RegionType RSRegionToImageRegion(const RSRegion rsRegion) + { + typename itk::ContinuousIndex<double> rsRegionOrigin = rsRegion.GetOrigin(); + typename itk::ContinuousIndex<double> rsRegionSize = rsRegion.GetSize(); + typename itk::ContinuousIndex<double> rsRegionEnd; + for(unsigned int dim = 0; dim<InputImage2Type::ImageDimension; ++dim) + { + rsRegionEnd[dim] = rsRegionOrigin[dim] + rsRegionSize[dim]; + } + typename InputImage1RegionType::IndexType imageRegionStart, imageRegionEnd; + m_InputImage1->TransformPhysicalPointToIndex(rsRegionOrigin, imageRegionStart); + m_InputImage1->TransformPhysicalPointToIndex(rsRegionEnd, imageRegionEnd); + + // Target Region (target image indices) + typename InputImage1RegionType::IndexType targetRegionStart; + typename InputImage1RegionType::SizeType targetRegionSize; + for(unsigned int dim = 0; dim<InputImage2Type::ImageDimension; ++dim) + { + targetRegionStart[dim] = std::min(imageRegionStart[dim], imageRegionEnd[dim]); + targetRegionSize[dim] = std::max(imageRegionStart[dim], imageRegionEnd[dim]) - targetRegionStart[dim] + 1; + } + + InputImage1RegionType region(targetRegionStart, targetRegionSize); + return region; + + } + + /* + * Converts a given region of an image into a remoste sensing region + */ + RSRegion ImageRegionToRSRegion(const InputImage1RegionType &sourceRegion, InputImage1PointerType sourceImage) + { + + // Source Region (source image indices) + typename InputImage1RegionType::IndexType sourceRegionIndexStart = sourceRegion.GetIndex(); + typename InputImage1RegionType::IndexType sourceRegionIndexEnd; + for(unsigned int dim = 0; dim < InputImage1Type::ImageDimension; ++dim) + sourceRegionIndexEnd[dim]= sourceRegionIndexStart[dim] + sourceRegion.GetSize()[dim]-1; + + // Source Region (Geo) + typename InputImage1Type::PointType sourceRegionIndexStartGeo, sourceRegionIndexEndGeo; + sourceImage->TransformIndexToPhysicalPoint(sourceRegionIndexStart, sourceRegionIndexStartGeo); + sourceImage->TransformIndexToPhysicalPoint(sourceRegionIndexEnd , sourceRegionIndexEndGeo ); + + // Source Region (Geo min & max) + typename itk::ContinuousIndex<double> sourceRegionMin, sourceRegionMax, sourceRegionSize; + for(unsigned int dim = 0; dim<InputImage2Type::ImageDimension; ++dim) + { + sourceRegionMin[dim] = std::min(sourceRegionIndexStartGeo[dim], sourceRegionIndexEndGeo[dim]); + sourceRegionMax[dim] = std::max(sourceRegionIndexStartGeo[dim], sourceRegionIndexEndGeo[dim]); + } + RSRegion region; + sourceRegionSize[0] = sourceRegionMax[0] - sourceRegionMin[0]; + sourceRegionSize[1] = sourceRegionMax[1] - sourceRegionMin[1]; + region.SetOrigin(sourceRegionMin); + region.SetSize(sourceRegionSize); + return region; + + } + bool HaveSameProjection() + { + itk::MetaDataDictionary metaData1 = m_InputImage1 -> GetMetaDataDictionary(); + itk::MetaDataDictionary metaData2 = m_InputImage2 -> GetMetaDataDictionary(); + + if (metaData1.HasKey(otb::MetaDataKey::ProjectionRefKey)) + { + if (metaData2.HasKey(otb::MetaDataKey::ProjectionRefKey)) + { + string proj1, proj2; + itk::ExposeMetaData<string>(metaData1, static_cast<string>(otb::MetaDataKey::ProjectionRefKey), proj1); + itk::ExposeMetaData<string>(metaData2, static_cast<string>(otb::MetaDataKey::ProjectionRefKey), proj2); + if (proj1.compare(proj2)==0) + return true; + } + } + return false; + + } + + bool HaveSameNbOfBands() + { + return ( (m_InputImage1->GetNumberOfComponentsPerPixel()) == (m_InputImage2->GetNumberOfComponentsPerPixel()) ); + } + + RSRegion ComputeIntersectingRemoteSensingRegion() + { + InputImage2RegionType region1 = m_InputImage1->GetLargestPossibleRegion(); + InputImage1RegionType region2 = m_InputImage2->GetLargestPossibleRegion(); + RSRegion rsr1 = ImageRegionToRSRegion(region1, m_InputImage1); + RSRegion rsr2 = ImageRegionToRSRegion(region2, m_InputImage2); + rsr1.Crop(rsr2); + return rsr1; + } +private: + + InputImage1PointerType m_InputImage1; + InputImage2PointerType m_InputImage2; + +}; + +} + +#endif /* GTBRegionComparator_H_ */ diff --git a/include/otbStatisticsImageCustomFilter.h b/include/otbStatisticsImageCustomFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..545332b91dce7462db729551296543ea4f08c9b4 --- /dev/null +++ b/include/otbStatisticsImageCustomFilter.h @@ -0,0 +1,199 @@ +/*========================================================================= + + Copyright (c) IRSTEA. All rights reserved. + +Some parts of this code are derived from ITK. See ITKCopyright.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 __otbStatisticsImageCustomFilter_h +#define __otbStatisticsImageCustomFilter_h + +#include "itkImageToImageFilter.h" +#include "itkNumericTraits.h" +#include "itkArray.h" +#include "itkSimpleDataObjectDecorator.h" + +namespace otb +{ +/** \class StatisticsImageCustomFilter + * \brief Compute min. max, variance and mean of an Image. + * + * StatisticsImageCustomFilter computes the minimum, maximum, sum, mean, variance + * sigma of an image. The filter needs all of its input image. It + * behaves as a filter with an input and output. Thus it can be inserted + * in a pipline with other filters and the statistics will only be + * recomputed if a downstream filter changes. + * + * The filter passes its input through unmodified. The filter is + * threaded. It computes statistics in each thread then combines them in + * its AfterThreadedGenerate method. + * + * A value to ignore (in the stats) can be chosen + * + * \ingroup MathematicalStatisticsImageCustomFilters + * \ingroup ITKImageStatistics + * + * \wiki + * \wikiexample{Statistics/StatisticsImageCustomFilter,Compute min\, max\, variance and mean of an Image.} + * \endwiki + */ +template< typename TInputImage > +class StatisticsImageCustomFilter: + public itk::ImageToImageFilter< TInputImage, TInputImage > +{ +public: + /** Standard Self typedef */ + typedef StatisticsImageCustomFilter Self; + typedef itk::ImageToImageFilter< TInputImage, TInputImage > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(StatisticsImageCustomFilter,itk::ImageToImageFilter); + + /** Image related typedefs. */ + typedef typename TInputImage::Pointer InputImagePointer; + + typedef typename TInputImage::RegionType RegionType; + typedef typename TInputImage::SizeType SizeType; + typedef typename TInputImage::IndexType IndexType; + typedef typename TInputImage::PixelType PixelType; + + /** Image related typedefs. */ + itkStaticConstMacro(ImageDimension, unsigned int, + TInputImage::ImageDimension); + + /** Type to use for computations. */ + typedef typename itk::NumericTraits< PixelType >::RealType RealType; + typedef unsigned long LongType; + + /** Smart Pointer type to a DataObject. */ + typedef typename itk::DataObject::Pointer DataObjectPointer; + + /** Type of DataObjects used for scalar outputs */ + typedef itk::SimpleDataObjectDecorator< RealType > RealObjectType; + typedef itk::SimpleDataObjectDecorator< LongType > LongObjectType; + typedef itk::SimpleDataObjectDecorator< PixelType > PixelObjectType; + + /** Return the computed Minimum. */ + PixelType GetMinimum() const + { return this->GetMinimumOutput()->Get(); } + PixelObjectType * GetMinimumOutput(); + + const PixelObjectType * GetMinimumOutput() const; + + /** Return the computed Maximum. */ + PixelType GetMaximum() const + { return this->GetMaximumOutput()->Get(); } + PixelObjectType * GetMaximumOutput(); + + const PixelObjectType * GetMaximumOutput() const; + + /** Return the computed Mean. */ + RealType GetMean() const + { return this->GetMeanOutput()->Get(); } + RealObjectType * GetMeanOutput(); + + const RealObjectType * GetMeanOutput() const; + + /** Return the computed Standard Deviation. */ + RealType GetSigma() const + { return this->GetSigmaOutput()->Get(); } + RealObjectType * GetSigmaOutput(); + + const RealObjectType * GetSigmaOutput() const; + + /** Return the computed Variance. */ + RealType GetVariance() const + { return this->GetVarianceOutput()->Get(); } + RealObjectType * GetVarianceOutput(); + + const RealObjectType * GetVarianceOutput() const; + + /** Return the compute Sum. */ + RealType GetSum() const + { return this->GetSumOutput()->Get(); } + RealObjectType * GetSumOutput(); + + const RealObjectType * GetSumOutput() const; + + /** Return the compute Sum of squares. */ + RealType GetSumOfSquares() const + { return this->GetSumOfSquaresOutput()->Get(); } + RealObjectType * GetSumOfSquaresOutput(); + + const RealObjectType * GetSumOfSquaresOutput() const; + + /** Return the compute count. */ + RealType GetCount() const + { return this->GetCountOutput()->Get(); } + LongObjectType * GetCountOutput(); + + const LongObjectType * GetCountOutput() const; + + /** Make a DataObject of the correct type to be used as the specified + * output. */ + typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; + using Superclass::MakeOutput; + virtual DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx); + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro( InputHasNumericTraitsCheck, + ( itk::Concept::HasNumericTraits< PixelType > ) ); + // End concept checking +#endif + + /** Accessors for ignored value */ + itkGetMacro(IgnoredInputValue, PixelType); + itkSetMacro(IgnoredInputValue, PixelType); + +protected: + StatisticsImageCustomFilter(); + ~StatisticsImageCustomFilter(){} + void PrintSelf(std::ostream & os, itk::Indent indent) const; + + /** Pass the input through unmodified. Do this by Grafting in the + * AllocateOutputs method. + */ + void AllocateOutputs(); + + /** Initialize some accumulators before the threads run. */ + void BeforeThreadedGenerateData(); + + /** Do final mean and variance computation from data accumulated in threads. + */ + void AfterThreadedGenerateData(); + + /** Multi-thread version GenerateData. */ + void ThreadedGenerateData(const RegionType & + outputRegionForThread, + itk::ThreadIdType threadId); + +private: + StatisticsImageCustomFilter(const Self &); //purposely not implemented + void operator=(const Self &); //purposely not implemented + + itk::Array< RealType > m_ThreadSum; + itk::Array< RealType > m_SumOfSquares; + itk::Array< itk::SizeValueType > m_Count; + itk::Array< PixelType > m_ThreadMin; + itk::Array< PixelType > m_ThreadMax; + + PixelType m_IgnoredInputValue; +}; // end of class +} // end namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "otbStatisticsImageCustomFilter.hxx" +#endif + +#endif diff --git a/include/otbStatisticsImageCustomFilter.hxx b/include/otbStatisticsImageCustomFilter.hxx new file mode 100644 index 0000000000000000000000000000000000000000..85eda566ce98ac0136ae317b06eafd8f29116a25 --- /dev/null +++ b/include/otbStatisticsImageCustomFilter.hxx @@ -0,0 +1,397 @@ +/*========================================================================= + + Copyright (c) IRSTEA. All rights reserved. + +Some parts of this code are derived from ITK. See ITKCopyright.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 __otbStatisticsImageCustomFilter_hxx +#define __otbStatisticsImageCustomFilter_hxx +#include "otbStatisticsImageCustomFilter.h" + + +#include "itkImageScanlineIterator.h" +#include "itkProgressReporter.h" + +namespace otb +{ +template< typename TInputImage > +StatisticsImageCustomFilter< TInputImage > +::StatisticsImageCustomFilter():m_ThreadSum(1), m_SumOfSquares(1), + m_Count(1), m_ThreadMin(1), m_ThreadMax(1) +{ + // first output is a copy of the image, DataObject created by + // superclass + // + // allocate the data objects for the outputs which are + // just decorators around pixel types + for ( int i = 1; i < 3; ++i ) + { + typename PixelObjectType::Pointer output = + static_cast< PixelObjectType * >( this->MakeOutput(i).GetPointer() ); + this->itk::ProcessObject::SetNthOutput( i, output.GetPointer() ); + } + // allocate the data objects for the outputs which are + // just decorators around real types + for ( int i = 3; i < 7; ++i ) + { + typename RealObjectType::Pointer output = + static_cast< RealObjectType * >( this->MakeOutput(i).GetPointer() ); + this->itk::ProcessObject::SetNthOutput( i, output.GetPointer() ); + } + + // allocate the data objects for the count output (long type) + typename LongObjectType::Pointer output = + static_cast< LongObjectType * >( this->MakeOutput(7).GetPointer() ); + this->itk::ProcessObject::SetNthOutput( 7, output.GetPointer() ); + + this->GetMinimumOutput()->Set( itk::NumericTraits< PixelType >::max() ); + this->GetMaximumOutput()->Set( itk::NumericTraits< PixelType >::NonpositiveMin() ); + this->GetMeanOutput()->Set( itk::NumericTraits< RealType >::max() ); + this->GetSigmaOutput()->Set( itk::NumericTraits< RealType >::max() ); + this->GetVarianceOutput()->Set( itk::NumericTraits< RealType >::max() ); + this->GetSumOutput()->Set(itk::NumericTraits< RealType >::Zero); + this->GetCountOutput()->Set(itk::NumericTraits< LongType >::Zero); + + m_IgnoredInputValue = itk::NumericTraits<PixelType>::max(); +} + +template< typename TInputImage > +itk::DataObject::Pointer +StatisticsImageCustomFilter< TInputImage > +::MakeOutput(DataObjectPointerArraySizeType output) +{ + switch ( output ) + { + case 0: + return TInputImage::New().GetPointer(); + break; + case 1: + return PixelObjectType::New().GetPointer(); + break; + case 2: + return PixelObjectType::New().GetPointer(); + break; + case 3: + case 4: + case 5: + case 6: + return RealObjectType::New().GetPointer(); + break; + case 7: + return LongObjectType::New().GetPointer(); + break; + default: + // might as well make an image + return TInputImage::New().GetPointer(); + break; + } +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::PixelObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetMinimumOutput() +{ + return static_cast< PixelObjectType * >( this->itk::ProcessObject::GetOutput(1) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::PixelObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetMinimumOutput() const +{ + return static_cast< const PixelObjectType * >( this->itk::ProcessObject::GetOutput(1) ); +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::PixelObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetMaximumOutput() +{ + return static_cast< PixelObjectType * >( this->itk::ProcessObject::GetOutput(2) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::PixelObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetMaximumOutput() const +{ + return static_cast< const PixelObjectType * >( this->itk::ProcessObject::GetOutput(2) ); +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetMeanOutput() +{ + return static_cast< RealObjectType * >( this->itk::ProcessObject::GetOutput(3) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetMeanOutput() const +{ + return static_cast< const RealObjectType * >( this->itk::ProcessObject::GetOutput(3) ); +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetSigmaOutput() +{ + return static_cast< RealObjectType * >( this->itk::ProcessObject::GetOutput(4) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetSigmaOutput() const +{ + return static_cast< const RealObjectType * >( this->itk::ProcessObject::GetOutput(4) ); +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetVarianceOutput() +{ + return static_cast< RealObjectType * >( this->itk::ProcessObject::GetOutput(5) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetVarianceOutput() const +{ + return static_cast< const RealObjectType * >( this->itk::ProcessObject::GetOutput(5) ); +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetSumOutput() +{ + return static_cast< RealObjectType * >( this->itk::ProcessObject::GetOutput(6) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetSumOutput() const +{ + return static_cast< const RealObjectType * >( this->itk::ProcessObject::GetOutput(6) ); +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetSumOfSquaresOutput() +{ + return static_cast< RealObjectType * >( this->itk::ProcessObject::GetOutput(6) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::RealObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetSumOfSquaresOutput() const +{ + return static_cast< const RealObjectType * >( this->itk::ProcessObject::GetOutput(6) ); +} + +template< typename TInputImage > +typename StatisticsImageCustomFilter< TInputImage >::LongObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetCountOutput() +{ + return static_cast< LongObjectType * >( this->itk::ProcessObject::GetOutput(7) ); +} + +template< typename TInputImage > +const typename StatisticsImageCustomFilter< TInputImage >::LongObjectType * +StatisticsImageCustomFilter< TInputImage > +::GetCountOutput() const +{ + return static_cast< const LongObjectType * >( this->itk::ProcessObject::GetOutput(7) ); +} + +template< typename TInputImage > +void +StatisticsImageCustomFilter< TInputImage > +::AllocateOutputs() +{ + // Pass the input through as the output + InputImagePointer image = + const_cast< TInputImage * >( this->GetInput() ); + + this->GraftOutput(image); + + // Nothing that needs to be allocated for the remaining outputs +} + +template< typename TInputImage > +void +StatisticsImageCustomFilter< TInputImage > +::BeforeThreadedGenerateData() +{ + itk::ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + + // Resize the thread temporaries + m_Count.SetSize(numberOfThreads); + m_SumOfSquares.SetSize(numberOfThreads); + m_ThreadSum.SetSize(numberOfThreads); + m_ThreadMin.SetSize(numberOfThreads); + m_ThreadMax.SetSize(numberOfThreads); + + // Initialize the temporaries + m_Count.Fill(itk::NumericTraits< itk::SizeValueType >::Zero); + m_ThreadSum.Fill(itk::NumericTraits< RealType >::Zero); + m_SumOfSquares.Fill(itk::NumericTraits< RealType >::Zero); + m_ThreadMin.Fill( itk::NumericTraits< PixelType >::max() ); + m_ThreadMax.Fill( itk::NumericTraits< PixelType >::NonpositiveMin() ); +} + +template< typename TInputImage > +void +StatisticsImageCustomFilter< TInputImage > +::AfterThreadedGenerateData() +{ + itk::ThreadIdType i; + + itk::ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + + PixelType minimum = this->GetMinimumOutput()->Get(); + PixelType maximum = this->GetMaximumOutput()->Get(); + RealType sum = this ->GetSumOutput()->Get(); + RealType sumOfSquares = this->GetSumOfSquaresOutput()->Get(); + LongType count = this->GetCountOutput()->Get(); + + RealType mean, sigma, variance; + mean = sigma = variance = itk::NumericTraits< RealType >::ZeroValue(); + + // Find the min/max over all threads and accumulate count, sum and + // sum of squares + for ( i = 0; i < numberOfThreads; i++ ) + { + count += m_Count[i]; + sum += m_ThreadSum[i]; + sumOfSquares += m_SumOfSquares[i]; + + if ( m_ThreadMin[i] < minimum ) + { + minimum = m_ThreadMin[i]; + } + if ( m_ThreadMax[i] > maximum ) + { + maximum = m_ThreadMax[i]; + } + } + + // compute statistics + if (count > 1) + { + mean = sum / static_cast< RealType >( count ); + + // unbiased estimate + variance = ( sumOfSquares - ( sum * sum / static_cast< RealType >( count ) ) ) + / ( static_cast< RealType >( count ) - 1 ); + sigma = std::sqrt(variance); + } + + // Update the outputs + this->GetMinimumOutput()->Set(minimum); + this->GetMaximumOutput()->Set(maximum); + this->GetMeanOutput()->Set(mean); + this->GetSigmaOutput()->Set(sigma); + this->GetVarianceOutput()->Set(variance); + this->GetSumOutput()->Set(sum); + this->GetSumOfSquaresOutput()->Set(sumOfSquares); + this->GetCountOutput()->Set(count); +} + +template< typename TInputImage > +void +StatisticsImageCustomFilter< TInputImage > +::ThreadedGenerateData(const RegionType & outputRegionForThread, + itk::ThreadIdType threadId) +{ + const itk::SizeValueType size0 = outputRegionForThread.GetSize(0); + if( size0 == 0) + { + return; + } + RealType realValue; + PixelType value; + + RealType sum = itk::NumericTraits< RealType >::ZeroValue(); + RealType sumOfSquares = itk::NumericTraits< RealType >::ZeroValue(); + itk::SizeValueType count = itk::NumericTraits< itk::SizeValueType >::ZeroValue(); + PixelType min = itk::NumericTraits< PixelType >::max(); + PixelType max = itk::NumericTraits< PixelType >::NonpositiveMin(); + + itk::ImageScanlineConstIterator< TInputImage > it (this->GetInput(), outputRegionForThread); + + // support progress methods/callbacks + const size_t numberOfLinesToProcess = outputRegionForThread.GetNumberOfPixels() / size0; + itk::ProgressReporter progress( this, threadId, numberOfLinesToProcess ); + + // do the work + while ( !it.IsAtEnd() ) + { + while ( !it.IsAtEndOfLine() ) + { + value = it.Get(); + if (value != m_IgnoredInputValue) + { + realValue = static_cast< RealType >( value ); + if ( value < min ) + { + min = value; + } + if ( value > max ) + { + max = value; + } + sum += realValue; + sumOfSquares += ( realValue * realValue ); + ++count; + } + ++it; + } + it.NextLine(); + progress.CompletedPixel(); + } + + m_ThreadSum[threadId] = sum; + m_SumOfSquares[threadId] = sumOfSquares; + m_Count[threadId] = count; + m_ThreadMin[threadId] = min; + m_ThreadMax[threadId] = max; +} + +template< typename TImage > +void +StatisticsImageCustomFilter< TImage > +::PrintSelf(std::ostream & os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + os << indent << "Minimum: " + << static_cast< typename itk::NumericTraits< PixelType >::PrintType >( this->GetMinimum() ) << std::endl; + os << indent << "Maximum: " + << static_cast< typename itk::NumericTraits< PixelType >::PrintType >( this->GetMaximum() ) << std::endl; + os << indent << "Sum: " << this->GetSum() << std::endl; + os << indent << "SumOfSquares: " << this->GetSumOfSquares() << std::endl; + os << indent << "Count: " << this->GetCount() << std::endl; + os << indent << "Mean: " << this->GetMean() << std::endl; + os << indent << "Sigma: " << this->GetSigma() << std::endl; + os << indent << "Variance: " << this->GetVariance() << std::endl; +} +} // end namespace itk +#endif diff --git a/include/otbVectorDataToLabelImageCustomFilter.h b/include/otbVectorDataToLabelImageCustomFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..d1289f1a977fbc01c67b939d0f70a8f8685d6154 --- /dev/null +++ b/include/otbVectorDataToLabelImageCustomFilter.h @@ -0,0 +1,182 @@ +/*========================================================================= + + Copyright (c) IRSTEA. All rights reserved. + + + 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 __gtbVectorDataToLabelImageCustomFilter_h +#define __gtbVectorDataToLabelImageCustomFilter_h + +#include "itkImageToImageFilter.h" +#include "itkImageSource.h" +#include "otbMacro.h" +#include "otbImageMetadataInterfaceFactory.h" +#include "otbVectorData.h" + +#include "gdal.h" +#include "ogr_api.h" +#include <ogrsf_frmts.h> + +namespace otb { + +/** \class VectorDataToLabelImageCustomFilter + * \brief Burn geometries from the specified VectorData into raster + * + * This class handles burning several input VectorDatas into the + * output raster. The burn values are extracted from a field set by + * the user.If no burning field is set, the "FID" is used by default. + * + * A "Burn max value" mode overrides this and makes only the max value + * burnt whenever the burning field. + * + * Setting the output raster informations can be done in two ways by: + * - Setting the Origin/Size/Spacing of the output image + * - Using an existing image as support via SetOutputParametersFromImage(ImageBase) + * + * OGRRegisterAll() method must have been called before applying filter. + * + */ +template <class TVectorData, class TOutputImage > +class ITK_EXPORT VectorDataToLabelImageCustomFilter : + public itk::ImageSource<TOutputImage> +{ +public: + /** Standard class typedefs */ + typedef VectorDataToLabelImageCustomFilter Self; + typedef itk::ImageSource<TOutputImage> Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(VectorDataToLabelImageCustomFilter, itk::ImageSource); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::Pointer OutputImagePointer; + typedef typename OutputImageType::SizeType OutputSizeType; + typedef typename OutputImageType::IndexType OutputIndexType; + typedef typename OutputImageType::SpacingType OutputSpacingType; + typedef typename OutputImageType::PointType OutputOriginType; + typedef typename OutputImageType::RegionType OutputImageRegionType; + typedef typename OutputImageType::PixelType OutputImagePixelType; + typedef typename OutputImageType::InternalPixelType OutputImageInternalPixelType; + + /** VectorData typedefs*/ + typedef TVectorData VectorDataType; + typedef typename VectorDataType::DataTreeType DataTreeType; + typedef typename DataTreeType::TreeNodeType InternalTreeNodeType; + typedef typename DataTreeType::Pointer DataTreePointerType; + typedef typename DataTreeType::ConstPointer DataTreeConstPointerType; + + typedef itk::ImageBase<OutputImageType::ImageDimension> ImageBaseType; + + /** Get Nth input VectorData */ + const VectorDataType* GetInput(unsigned int idx); + + /** Method for adding VectorData to rasterize */ + virtual void AddVectorData(const VectorDataType* vd); + + /** Set the size of the output image. */ + itkSetMacro(OutputSize, OutputSizeType); + + /** Get the size of the output image. */ + itkGetConstReferenceMacro(OutputSize, OutputSizeType); + + /** Burn mode */ + itkSetMacro(BurnMaxValueMode, bool); + itkGetMacro(BurnMaxValueMode, bool); + + + /** Set the origin of the output image. + * \sa GetOrigin() + */ + itkSetMacro(OutputOrigin, OutputOriginType); + virtual void SetOutputOrigin(const double origin[2]); + virtual void SetOutputOrigin(const float origin[2]); + + itkGetConstReferenceMacro(OutputOrigin, OutputOriginType); + + /** Set the spacing (size of a pixel) of the output image. + * \sa GetSpacing() + */ + virtual void SetOutputSpacing(const OutputSpacingType& spacing); + virtual void SetOutputSpacing(const double spacing[2]); + virtual void SetOutputSpacing(const float spacing[2]); + + /** Set/Get Output Projection Ref */ + itkSetStringMacro(OutputProjectionRef); + itkGetStringMacro(OutputProjectionRef); + + itkSetStringMacro(BurnAttribute); + itkGetStringMacro(BurnAttribute); + + /** Useful to set the output parameters from an existing image*/ + void SetOutputParametersFromImage(const ImageBaseType * image); + +protected: + virtual void GenerateData(); + + VectorDataToLabelImageCustomFilter(); + virtual ~VectorDataToLabelImageCustomFilter() + { + // Destroy the geometries stored + for (unsigned int idx = 0; idx < m_SrcDataSetGeometries.size(); ++idx) + { + OGR_G_DestroyGeometry(m_SrcDataSetGeometries[idx]); + } + + if (m_OGRDataSourcePointer != NULL) + { + OGRDataSource::DestroyDataSource(m_OGRDataSourcePointer); + } + } + + virtual void GenerateOutputInformation(); + + void PrintSelf(std::ostream& os, itk::Indent indent) const; + +private: + VectorDataToLabelImageCustomFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + OGRDataSource* m_OGRDataSourcePointer; + + // Vector Of OGRGeometyH + std::vector< OGRGeometryH > m_SrcDataSetGeometries; + + std::vector<double> m_BurnValues; + std::vector<double> m_FullBurnValues; + std::vector<int> m_BandsToBurn; + + // Field used to extract the burn value + std::string m_BurnAttribute; + + // Burn mode + bool m_BurnMaxValueMode; + + // Default burn value + double m_DefaultBurnValue; + + // Output params + std::string m_OutputProjectionRef; + OutputSpacingType m_OutputSpacing; + OutputOriginType m_OutputOrigin; + OutputSizeType m_OutputSize; + OutputIndexType m_OutputStartIndex; +}; // end of class VectorDataToLabelImageCustomFilter + +} // end of namespace otb + + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbVectorDataToLabelImageCustomFilter.hxx" +#endif + +#endif + diff --git a/include/otbVectorDataToLabelImageCustomFilter.hxx b/include/otbVectorDataToLabelImageCustomFilter.hxx new file mode 100644 index 0000000000000000000000000000000000000000..ea0dc57e5cdf84e2cb87450ea302fe922730ce0e --- /dev/null +++ b/include/otbVectorDataToLabelImageCustomFilter.hxx @@ -0,0 +1,334 @@ +/*========================================================================= + + Copyright (c) IRSTEA. All rights reserved. + + + 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 __gtbVectorDataToLabelImageCustomFilter_txx +#define __gtbVectorDataToLabelImageCustomFilter_txx + +#include "otbVectorDataToLabelImageCustomFilter.h" +#include "otbOGRIOHelper.h" +#include "otbGdalDataTypeBridge.h" +#include "otbMacro.h" + +#include "gdal_alg.h" +#include "ogr_srs_api.h" + +#include "itkImageRegionIterator.h" + +namespace otb +{ +template<class TVectorData, class TOutputImage> +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::VectorDataToLabelImageCustomFilter() + : m_OGRDataSourcePointer(0), + m_BurnAttribute("FID"), + m_BurnMaxValueMode(false) + { + this->SetNumberOfRequiredInputs(1); + + // Output parameters initialization + m_OutputSpacing.Fill(1.0); + m_OutputSize.Fill(0); + m_OutputStartIndex.Fill(0); + + // This filter is intended to work with otb::Image + m_BandsToBurn.push_back(1); + + // Default burn value if no burnAttribute available + m_DefaultBurnValue = 1.; + } + +template<class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::AddVectorData(const VectorDataType* vd) + { + this->itk::ProcessObject::PushBackInput( vd ); + } + +template <class TVectorData, class TOutputImage> +const typename VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>::VectorDataType * +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::GetInput(unsigned int idx) + { + return static_cast<const TVectorData *> + (this->itk::ProcessObject::GetInput(idx)); + } + +template <class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::SetOutputSpacing(const OutputSpacingType& spacing) + { + if (this->m_OutputSpacing != spacing) + { + this->m_OutputSpacing = spacing; + this->Modified(); + } + } + +template <class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::SetOutputSpacing(const double spacing[2]) + { + OutputSpacingType s(spacing); + this->SetOutputSpacing(s); + } + +template <class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::SetOutputSpacing(const float spacing[2]) + { + itk::Vector<float, 2> sf(spacing); + OutputSpacingType s; + s.CastFrom(sf); + this->SetOutputSpacing(s); + } + +template <class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::SetOutputOrigin(const double origin[2]) + { + OutputOriginType p(origin); + this->SetOutputOrigin(p); + } + +template <class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::SetOutputOrigin(const float origin[2]) + { + itk::Point<float, 2> of(origin); + OutputOriginType p; + p.CastFrom(of); + this->SetOutputOrigin(p); + } + +template <class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::SetOutputParametersFromImage(const ImageBaseType * src) + { + this->SetOutputOrigin ( src->GetOrigin() ); + this->SetOutputSpacing ( src->GetSpacing() ); + this->SetOutputSize ( src->GetLargestPossibleRegion().GetSize() ); + otb::ImageMetadataInterfaceBase::Pointer imi = otb::ImageMetadataInterfaceFactory::CreateIMI(src->GetMetaDataDictionary()); + this->SetOutputProjectionRef(imi->GetProjectionRef()); + } + +template<class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::GenerateOutputInformation() + { + // get pointer to the output + OutputImagePointer outputPtr = this->GetOutput(); + if (!outputPtr) + { + return; + } + + // Set the size of the output region + typename TOutputImage::RegionType outputLargestPossibleRegion; + outputLargestPossibleRegion.SetSize(m_OutputSize); + //outputLargestPossibleRegion.SetIndex(m_OutputStartIndex); + outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion); + + // Set spacing and origin + outputPtr->SetSpacing(m_OutputSpacing); + outputPtr->SetOrigin(m_OutputOrigin); + + itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary(); + itk::EncapsulateMetaData<std::string> (dict, otb::MetaDataKey::ProjectionRefKey, + static_cast<std::string>(this->GetOutputProjectionRef())); + + // Generate the OGRLayers from the input VectorDatas + // iteration begin from 1 cause the 0th input is a image + for (unsigned int inputIdx = 0; inputIdx < this->GetNumberOfInputs(); ++inputIdx) + { + const VectorDataType* vd = dynamic_cast< const VectorDataType*>(this->itk::ProcessObject::GetInput(inputIdx)); + + // Get the projection ref of the current VectorData + std::string projectionRefWkt = vd->GetProjectionRef(); + bool projectionInformationAvailable = !projectionRefWkt.empty(); + OGRSpatialReference * oSRS = NULL; + + if (projectionInformationAvailable) + { + oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str())); + } + else + { + otbMsgDevMacro(<< "Projection information unavailable"); + } + + // Retrieving root node + DataTreeConstPointerType tree = vd->GetDataTree(); + + // Get the input tree root + InternalTreeNodeType * inputRoot = const_cast<InternalTreeNodeType *>(tree->GetRoot()); + + // Iterative method to build the layers from a VectorData + OGRLayer * ogrCurrentLayer = NULL; + std::vector<OGRLayer *> ogrLayerVector; + otb::OGRIOHelper::Pointer IOConversion = otb::OGRIOHelper::New(); + + // The method ConvertDataTreeNodeToOGRLayers create the + // OGRDataSource but don t release it. Destruction is done in the + // desctructor + m_OGRDataSourcePointer = NULL; + ogrLayerVector = IOConversion->ConvertDataTreeNodeToOGRLayers(inputRoot, + m_OGRDataSourcePointer, + ogrCurrentLayer, + oSRS); + + // From OGRLayer* to OGRGeometryH vector + for (unsigned int idx = 0; idx < ogrLayerVector.size(); ++idx) + { + // test if the layers contain a field m_BurnField; + int burnField = -1; + + if( !m_BurnAttribute.empty() ) + { + burnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( (OGRLayerH)(ogrLayerVector[idx]) ), + m_BurnAttribute.c_str() ); + + // Get the geometries of the layer + OGRFeatureH hFeat; + OGR_L_ResetReading( (OGRLayerH)(ogrLayerVector[idx]) ); + while( ( hFeat = OGR_L_GetNextFeature( (OGRLayerH)(ogrLayerVector[idx]) )) != NULL ) + { + OGRGeometryH hGeom; + if( OGR_F_GetGeometryRef( hFeat ) == NULL ) + { + OGR_F_Destroy( hFeat ); + continue; + } + + hGeom = OGR_G_Clone( OGR_F_GetGeometryRef( hFeat ) ); + m_SrcDataSetGeometries.push_back( hGeom ); + + if (m_BurnMaxValueMode) + { + m_FullBurnValues.push_back(static_cast<double>(itk::NumericTraits<OutputImageInternalPixelType>::max())); + } + else if (burnField == -1 ) + { + // TODO : if no burnAttribute available, warning or raise an exception?? + m_FullBurnValues.push_back(m_DefaultBurnValue++); + itkWarningMacro(<<"Failed to find attribute "<<m_BurnAttribute << " in layer " + << OGR_FD_GetName( OGR_L_GetLayerDefn( (OGRLayerH)(ogrLayerVector[idx]) )) + <<" .Setting burn value to default = " + << m_DefaultBurnValue); + } + else + { + m_FullBurnValues.push_back( OGR_F_GetFieldAsDouble( hFeat, burnField ) ); + } + + OGR_F_Destroy( hFeat ); + } + } + + // Destroy the oSRS + if (oSRS != NULL) + { + OSRRelease(oSRS); + } + } + } + } + +template<class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>::GenerateData() +{ + // Call Superclass GenerateData + this->AllocateOutputs(); + itk::ImageRegionIterator<TOutputImage> it (this->GetOutput(), this->GetOutput()->GetBufferedRegion()); + for (it.GoToBegin(); !it.IsAtEnd(); ++it) + { + it.Set(0); + } + + // Get the buffered region + OutputImageRegionType bufferedRegion = this->GetOutput()->GetBufferedRegion(); + + // nb bands + unsigned int nbBands = this->GetOutput()->GetNumberOfComponentsPerPixel(); + + // register drivers + GDALAllRegister(); + + std::ostringstream stream; + stream << "MEM:::" + << "DATAPOINTER=" << (unsigned long)(this->GetOutput()->GetBufferPointer()) << "," + << "PIXELS=" << bufferedRegion.GetSize()[0] << "," + << "LINES=" << bufferedRegion.GetSize()[1]<< "," + << "BANDS=" << nbBands << "," + << "DATATYPE=" << GDALGetDataTypeName(otb::GdalDataTypeBridge::GetGDALDataType<OutputImageInternalPixelType>()) << "," + << "PIXELOFFSET=" << sizeof(OutputImageInternalPixelType) * nbBands << "," + << "LINEOFFSET=" << sizeof(OutputImageInternalPixelType)*nbBands*bufferedRegion.GetSize()[0] << "," + << "BANDOFFSET=" << sizeof(OutputImageInternalPixelType); + + GDALDatasetH dataset = GDALOpen(stream.str().c_str(), GA_Update); + + // Add the projection ref to the dataset + GDALSetProjection (dataset, this->GetOutput()->GetProjectionRef().c_str()); + + // add the geoTransform to the dataset + itk::VariableLengthVector<double> geoTransform(6); + + // Reporting origin and spacing of the buffered region + // the spacing is unchanged, the origin is relative to the buffered region + OutputIndexType bufferIndexOrigin = bufferedRegion.GetIndex(); + OutputOriginType bufferOrigin; + this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin); + geoTransform[0] = bufferOrigin[0]; + geoTransform[3] = bufferOrigin[1]; + geoTransform[1] = this->GetOutput()->GetSpacing()[0]; + geoTransform[5] = this->GetOutput()->GetSpacing()[1]; + + // FIXME: Here component 1 and 4 should be replaced by the orientation parameters + geoTransform[2] = 0.; + geoTransform[4] = 0.; + GDALSetGeoTransform(dataset,const_cast<double*>(geoTransform.GetDataPointer())); + + // Burn the geometries into the dataset + if (dataset != NULL) + { + GDALRasterizeGeometries( dataset, m_BandsToBurn.size(), + &(m_BandsToBurn[0]), + m_SrcDataSetGeometries.size(), + &(m_SrcDataSetGeometries[0]), + NULL, NULL, &(m_FullBurnValues[0]), + NULL, + GDALDummyProgress, NULL ); + + // release the dataset + GDALClose( dataset ); + } +} + +template<class TVectorData, class TOutputImage> +void +VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> +::PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + } + +} // end namespace otb + +#endif + + diff --git a/otb-module.cmake b/otb-module.cmake new file mode 100644 index 0000000000000000000000000000000000000000..d2d0124d6b375d9223d38edc454d0cf2f07f2dc0 --- /dev/null +++ b/otb-module.cmake @@ -0,0 +1,14 @@ +set(DOCUMENTATION "Extraction of subset of remote sensing images") + +otb_module(SimpleExtractionTools + DEPENDS + OTBCommon + OTBApplicationEngine + OTBConversion + OTBImageBase + TEST_DEPENDS + OTBTestKernel + OTBCommandLine + DESCRIPTION + $DOCUMENTATION +)