otbSampleExtraction.cxx 7.48 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
20 21 22 23 24 25 26 27 28 29

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbImageSampleExtractorFilter.h"

namespace otb
{
namespace Wrapper
{
30 31 32 33 34
/** Utility function to negate std::isalnum */
bool IsNotAlphaNum(char c)
  {
  return !std::isalnum(c);
  }
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

class SampleExtraction : public Application
{
public:
  /** Standard class typedefs. */
  typedef SampleExtraction              Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(SampleExtraction, otb::Application);

  /** Filters typedef */
  typedef otb::ImageSampleExtractorFilter<FloatVectorImageType> FilterType;

private:
Guillaume Pasero's avatar
Guillaume Pasero committed
54
  SampleExtraction() {}
55

56
  void DoInit() override
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  {
    SetName("SampleExtraction");
    SetDescription("Extracts samples values from an image.");

    // Documentation
    SetDocName("Sample Extraction");
    SetDocLongDescription("The application extracts samples values from an"
      "image using positions contained in a vector data file. ");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Learning);

    AddParameter(ParameterType_InputImage,  "in",   "InputImage");
    SetParameterDescription("in", "Support image");

    AddParameter(ParameterType_InputFilename, "vec", "Input sampling positions");
    SetParameterDescription("vec","Vector data file containing sampling"
                                  "positions. (OGR format)");
Guillaume Pasero's avatar
Guillaume Pasero committed
77

78 79 80 81 82
    AddParameter(ParameterType_OutputFilename, "out", "Output samples");
    SetParameterDescription("out","Output vector data file storing sample"
      "values (OGR format). If not given, the input vector data file is updated");
    MandatoryOff("out");

83 84 85 86 87 88 89 90
    AddParameter(ParameterType_Choice, "outfield", "Output field names");
    SetParameterDescription("outfield", "Choice between naming method for output fields");

    AddChoice("outfield.prefix","Use a prefix and an incremental counter");
    SetParameterDescription("outfield.prefix","Use a prefix and an incremental counter");

    AddParameter(ParameterType_String, "outfield.prefix.name", "Output field prefix");
    SetParameterDescription("outfield.prefix.name","Prefix used to form the field names that"
91
      "will contain the extracted values.");
92
    SetParameterString("outfield.prefix.name", "value_");
93 94 95 96 97 98

    AddChoice("outfield.list","Use the given name list");
    SetParameterDescription("outfield.list","Use the given name list");

    AddParameter(ParameterType_StringList, "outfield.list.names", "Output field names");
    SetParameterDescription("outfield.list.names","Full list of output field names.");
99

100 101 102 103
    AddParameter(ParameterType_ListView, "field", "Field Name");
    SetParameterDescription("field","Name of the field carrying the class name in the input vectors.");
    SetListViewSingleSelectionMode("field",true);
    
104 105 106 107
    AddParameter(ParameterType_Int, "layer", "Layer Index");
    SetParameterDescription("layer", "Layer index to read in the input vector file.");
    MandatoryOff("layer");
    SetDefaultParameterInt("layer",0);
Guillaume Pasero's avatar
Guillaume Pasero committed
108

109 110 111 112 113
    AddRAMParameter();

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "support_image.tif");
    SetDocExampleParameterValue("vec", "sample_positions.sqlite");
114 115
    SetDocExampleParameterValue("outfield","prefix");
    SetDocExampleParameterValue("outfield.prefix.name","band_");
116 117
    SetDocExampleParameterValue("field", "label");
    SetDocExampleParameterValue("out","sample_values.sqlite");
118

119
    SetOfficialDocLink();
120 121
  }

122
  void DoUpdateParameters() override
123
  {
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
    if ( HasValue("vec") )
      {
      std::string vectorFile = GetParameterString("vec");
      ogr::DataSource::Pointer ogrDS =
        ogr::DataSource::New(vectorFile, ogr::DataSource::Modes::Read);
      ogr::Layer layer = ogrDS->GetLayer(this->GetParameterInt("layer"));
      ogr::Feature feature = layer.ogr().GetNextFeature();

      ClearChoices("field");
      
      for(int iField=0; iField<feature.ogr().GetFieldCount(); iField++)
        {
        std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef();
        key = item;
        std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum);
        std::transform(key.begin(), end, key.begin(), tolower);
        
        OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType();
        
143
        if(fieldType == OFTString || fieldType == OFTInteger || fieldType == OFTInteger64)
144 145 146 147 148 149
          {
          std::string tmpKey="field."+key.substr(0, end - key.begin());
          AddChoice(tmpKey,item);
          }
        }
      }
150 151
  }

152
  void DoExecute() override
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    {
    ogr::DataSource::Pointer vectors;
    ogr::DataSource::Pointer output;
    if (IsParameterEnabled("out") && HasValue("out"))
      {
      vectors = ogr::DataSource::New(this->GetParameterString("vec"));
      output = ogr::DataSource::New(this->GetParameterString("out"),
                                    ogr::DataSource::Modes::Overwrite);
      }
    else
      {
      // Update mode
      vectors = ogr::DataSource::New(this->GetParameterString("vec"),
                                    ogr::DataSource::Modes::Update_LayerUpdate);
      output = vectors;
      }
Guillaume Pasero's avatar
Guillaume Pasero committed
169

170 171 172 173 174 175 176 177
    // Retrieve the field name
    std::vector<int> selectedCFieldIdx = GetSelectedItems("field");

    if(selectedCFieldIdx.empty())
      {
      otbAppLogFATAL(<<"No field has been selected for data labelling!");
      }

Julien Michel's avatar
Julien Michel committed
178
  std::vector<std::string> cFieldNames = GetChoiceNames("field");  
179 180
  std::string fieldName = cFieldNames[selectedCFieldIdx.front()];
    
181 182 183 184 185 186 187 188 189 190 191 192
    std::vector<std::string> nameList;
    std::string namePrefix("");
    if (this->GetParameterString("outfield").compare("prefix") == 0)
      {
      namePrefix = this->GetParameterString("outfield.prefix.name");
      }
    else if (this->GetParameterString("outfield").compare("list") == 0)
      {
      nameList = this->GetParameterStringList("outfield.list.names");
      }
    else
      {
193
      otbAppLogFATAL("Unknown output field option : " << this->GetParameterString("outfield"));
194 195 196
      }
    

197 198 199 200
    FilterType::Pointer filter = FilterType::New();
    filter->SetInput(this->GetParameterImage("in"));
    filter->SetLayerIndex(this->GetParameterInt("layer"));
    filter->SetSamplePositions(vectors);
201
    filter->SetOutputSamples(output);
202
    filter->SetClassFieldName(fieldName);
203 204
    filter->SetOutputFieldPrefix(namePrefix);
    filter->SetOutputFieldNames(nameList);
205
    filter->GetStreamer()->SetAutomaticAdaptativeStreaming(GetParameterInt("ram"));
Guillaume Pasero's avatar
Guillaume Pasero committed
206

207
    
208 209
    AddProcess(filter->GetStreamer(),"Extracting sample values...");
    filter->Update();
Guillaume Pasero's avatar
Guillaume Pasero committed
210
    output->SyncToDisk();
211 212 213 214 215 216 217 218
    }

};

} // end of namespace Wrapper
} // end of namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::SampleExtraction)