source: trunk/zoo-project/zoo-kernel/service_internal_otb.c @ 631

Last change on this file since 631 was 631, checked in by djay, 9 years ago

Add readBase64 function, avoid calling it prior to fork . Add dumpMapsValuesToFiles function used to simplify OTB support.

  • Property svn:keywords set to Id
File size: 15.0 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2015 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 * See Ref: http://hg.orfeo-toolbox.org/OTB/ Copyright
25 * Some parts of this code are derived from ITK. See ITKCopyright.txt for
26 * details.
27 */
28
29#include "service_internal_otb.h"
30
31using namespace otb::Wrapper;
32
33/**
34 * The ZooWatcher list
35 */
36WatcherListType m_WatcherList;
37/**
38 * A pointer to the conf maps containing the main.cfg settings
39 */
40maps* m_Conf;
41
42/**
43 * The command to create a ZooWatcher and add it to the global m_WatcherList
44 */
45class MyCommand : public itk::Command
46{
47 public:
48  itkNewMacro( MyCommand );
49 public:
50
51  /**
52   * The method that defines the action to be taken by the command.
53   *
54   * @param caller an itk::Object pointer
55   * @param event an itk::EventObject pointer
56   */
57  void Execute(itk::Object *caller, const itk::EventObject & event)
58  {
59    Execute( (const itk::Object *)caller, event);
60  }
61 
62  /**
63   * The method that defines the action to be taken by the command.
64   * Create a new ZooWatcher instance then add it to the m_WatcherList.
65   *
66   * @param caller a const itk::Object pointer
67   * @param event an itk::EventObject pointer
68   * @see ZooWatcher,ZooWatcher::SetConf
69   */
70  void Execute(const itk::Object *caller, const itk::EventObject & event)
71  {
72    const AddProcessToWatchEvent* eventToWatch = dynamic_cast< const AddProcessToWatchEvent*> ( &event );
73    std::string m_CurrentDescription = eventToWatch->GetProcessDescription();
74    ZooWatcher * watch = new ZooWatcher(eventToWatch->GetProcess(),
75                                        eventToWatch->GetProcessDescription());
76    watch->SetConf(&m_Conf);
77    m_WatcherList.push_back(watch);
78  }
79
80};
81
82/**
83 * Replace all occurence of from by to in a str string
84 *
85 * @param str the string to transform
86 * @param from the string to replace
87 * @param to the string used as replacement
88 * @return the resulting string
89 */
90std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
91    size_t start_pos = 0;
92    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
93        str.replace(start_pos, from.length(), to);
94        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
95    }
96    return str;
97}
98
99/**
100 * Load and run an OTB Application corresponding to the service by using inputs parameters.
101 * Define the m_Conf
102 *
103 * @param main_conf the conf maps containing the main.cfg settings
104 * @param request the map containing the HTTP request
105 * @param s the service structure
106 * @param real_inputs the maps containing the inputs
107 * @param real_outputs the maps containing the outputs
108 */
109int zoo_otb_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
110  maps* m=*main_conf;
111  maps* inputs=*real_inputs;
112  maps* outputs=*real_outputs;
113  map* tmp0=getMapFromMaps(*main_conf,"lenv","cwd");
114  char *ntmp=tmp0->value;
115  map* tmp=NULL;
116  int res=-1;
117  std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
118  if (list.size() == 0){
119    map* tmps=createMap("text","No OTB Application found.");
120    addToMap(tmps,"code","InternalError");
121    printExceptionReportResponse(m,tmps);
122    freeMap(&tmps);
123    free(tmps);
124    res=-1;
125    return res;
126  }
127  else{
128    dumpMapsValuesToFiles(main_conf,real_inputs);
129    for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it){
130      if(s->name==*it){
131        Application::Pointer m_Application=ApplicationRegistry::CreateApplication(*it);
132        if (m_Application.IsNull()){
133          char tmpS[1024];
134          sprintf(tmpS, "The OTB Application %s cannot be loaded.", (*it).c_str());
135          map* tmps=createMap("text",tmpS);
136          addToMap(tmps,"code","InternalError");
137          printExceptionReportResponse(m,tmps);
138          freeMap(&tmps);
139          free(tmps);
140          res=-1;
141        }else{
142          // Create Observer on AddProcessToWatchEvent
143          m_Conf=m;
144          MyCommand::Pointer myCommand = MyCommand::New();
145          m_Application->AddObserver(AddProcessToWatchEvent(), myCommand);
146          char tmpS[1024];
147          const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
148          for (unsigned int i = 0; i < appKeyList.size(); i++){
149            const std::string paramKey(appKeyList[i]);
150            std::vector<std::string> values;
151            Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
152            ParameterType type = m_Application->GetParameterType(paramKey);
153            if (type != ParameterType_Group && paramKey!="inxml" && paramKey!="outxml"){
154              map* test=getMapFromMaps(inputs,paramKey.c_str(),"cache_file");
155              if(test==NULL){
156                test=getMapFromMaps(inputs,paramKey.c_str(),"inRequest");
157                map* tmpPath=getMapFromMaps(m,"main","tmpPath");
158                map* tmpSid=getMapFromMaps(m,"lenv","usid");
159                char tmp[1024];
160                map* tmpVal=getMapFromMaps(outputs,paramKey.c_str(),"mimeType");
161                maps* tmpMaps=getMaps(outputs,paramKey.c_str());
162                if(test!=NULL && test->value!=NULL && strncasecmp(test->value,"true",4)==0){
163                  test=getMapFromMaps(inputs,paramKey.c_str(),"value");
164                  if(type == ParameterType_OutputImage){
165                    ImagePixelType outPixType = ImagePixelType_float;
166                    if (strncasecmp(test->value,"uint8",5)==0)
167                      outPixType = ImagePixelType_uint8;
168                    else if (strncasecmp(test->value,"int16",5)==0)
169                      outPixType = ImagePixelType_int16;
170                    else if (strncasecmp(test->value,"uint16",6)==0)
171                      outPixType = ImagePixelType_uint16;
172                    else if (strncasecmp(test->value,"int32",5)==0)
173                      outPixType = ImagePixelType_int32;
174                    else if (strncasecmp(test->value,"uint32",6)==0)
175                      outPixType = ImagePixelType_uint32;
176                    else if (strncasecmp(test->value,"double",6)==0)
177                      outPixType = ImagePixelType_double;
178                    const char* ext="tiff";
179                    if(tmpVal!=NULL){
180                      if(strncasecmp(tmpVal->value,"image/jp2",9)==0)
181                         ext="j2k";
182                      else
183                        if(strncasecmp(tmpVal->value,"image/png",9)==0)
184                         ext="png";
185                        else
186                          if(strncasecmp(tmpVal->value,"image/jpeg",10)==0)
187                            ext="jpeg";
188                    }
189                    sprintf(tmp,"%s/%s_%s.%s",tmpPath->value,s->name,tmpSid->value,ext);
190                    m_Application->SetParameterString(paramKey, tmp);
191                    setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
192                    dynamic_cast<OutputImageParameter *> (param.GetPointer())->SetPixelType(outPixType);
193                  }
194                  else{ 
195                    if(test!=NULL && test->value!=NULL)
196                      m_Application->SetParameterString(paramKey, test->value);
197                  }
198                }else{
199                  if(type == ParameterType_OutputVectorData){
200                      char* ext="json";
201                      if(tmpVal!=NULL){
202                        if(strncasecmp(tmpVal->value,"text/xml",8)==0)
203                        ext="gml";
204                      else
205                        if(strncasecmp(tmpVal->value,"applicaton/json",15)==0)
206                          ext="json";
207                        else
208                          if(strncasecmp(tmpVal->value,"application/zip",14)==0)
209                            ext="shp";
210                          else
211                            if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kml+xml",36)==0)
212                              ext="kml";
213                      }
214                      sprintf(tmp,"%s/%s_%s.%s",tmpPath->value,s->name,tmpSid->value,ext);
215                      m_Application->SetParameterString(paramKey, tmp);
216                      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
217                  }
218                  else
219                    if(type == ParameterType_OutputFilename){
220                      char* ext="txt";
221                      if(tmpVal!=NULL){
222                        if(strncasecmp(tmpVal->value,"text/xml",8)==0)
223                          ext="xml";
224                        else
225                          if(strncasecmp(tmpVal->value,"text/csv",15)==0)
226                            ext="csv";
227                          else
228                            if(strncasecmp(tmpVal->value,"application/zip",14)==0)
229                              ext="shp";
230                            else
231                              if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kml+xml",36)==0)
232                                ext="kml";
233                              else
234                                if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kmz",32)==0){
235                                  ext="kmz";
236                                  sprintf(tmp,"%s/%s_%sxt.%s",tmpPath->value,s->name,tmpSid->value,ext);
237                                  m_Application->SetParameterString(paramKey, tmp);
238                                  setMapInMaps(outputs,paramKey.c_str(),"expected_generated_file",tmp);
239                                }
240
241                      }
242                      sprintf(tmp,"%s/%s_%s.%s",tmpPath->value,s->name,tmpSid->value,ext);
243                      m_Application->SetParameterString(paramKey, tmp);
244                      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
245                    }
246
247                }
248              }else{
249                if(type == ParameterType_InputImageList){
250                  values.push_back(test->value);
251                  map* tmpPath=getMapFromMaps(inputs,paramKey.c_str(),"length");
252                  if(tmpPath!=NULL){
253                    int len=atoi(tmpPath->value);
254                    for(int k=1;k<len;k++){
255                      char tmp[15];
256                      sprintf(tmp,"cache_file_%d",k);
257                      map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),tmp);
258                      if(tmpVal!=NULL){
259                        values.push_back(tmpVal->value);
260                      }
261                    }
262                  }
263                  dynamic_cast<InputImageListParameter *> (param.GetPointer())->SetListFromFileName(values);
264                }
265                else
266                  if(type == ParameterType_InputVectorData || type == ParameterType_InputFilename){
267                    map* tmpPath=getMapFromMaps(m,"main","tmpPath");
268                    map* tmpSid=getMapFromMaps(m,"lenv","sid");
269                    char tmp[1024];
270                    map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),"mimeType");
271                    char* ext="json";
272                    if(tmpVal!=NULL){
273                      if(strncasecmp(tmpVal->value,"application/zip",14)==0){
274                        char tmpName[1024];
275                        symlink(test->value,ReplaceAll(test->value,".zca",".zip").c_str());
276                        sprintf(tmpName,"/vsizip/%s",ReplaceAll(test->value,".zca",".zip").c_str());
277                        char **files=VSIReadDir(tmpName);
278                        int nFiles = CSLCount( files );
279                        char tmpSSName[1024];
280                        sprintf(tmpSSName,"%s/Input_%s_%s",tmpPath->value,s->name,tmpSid->value);
281                        mkdir(tmpSSName,0777);
282                           
283                        char tmpSName[1024];
284                        for(int kk=0;kk<nFiles;kk++){
285                          sprintf(tmpSName,"%s/%s",tmpName,files[kk]);
286                          VSILFILE* fmain=VSIFOpenL(tmpSName, "rb");
287                          if(fmain!=NULL){
288                            VSIFSeekL(fmain,0,SEEK_END);
289                            long count=VSIFTellL(fmain);
290                            VSIRewindL(fmain);
291
292                            char *content=(char*) malloc((count+1)*sizeof(char)); 
293                            VSIFReadL(content,1,count*sizeof(char),fmain);
294                         
295                            char tmpSSSName[1024];
296                            sprintf(tmpSSSName,"%s/%s",tmpSSName,files[kk]);
297                           
298                            FILE* fx=fopen(tmpSSSName, "wb");
299                            fwrite(content,1,count,fx);
300                            fclose(fx);
301                            VSIFCloseL(fmain);
302                            free(content);
303                            std::string test1(tmpSSSName);
304                            if(test1.find(".shp")!=std::string::npos){
305                              setMapInMaps(inputs,paramKey.c_str(),"cache_file",tmpSSSName);
306                              test=getMapFromMaps(inputs,paramKey.c_str(),"cache_file");
307                            }
308                          }
309                        }
310                      }
311                    }
312                   
313                    m_Application->SetParameterString(paramKey, test->value);
314                  }
315                  else
316                    if(type == ParameterType_InputImage
317                       || type == ParameterType_ComplexInputImage || type == ParameterType_InputVectorData
318                       || type == ParameterType_InputFilename){
319                      m_Application->SetParameterString(paramKey, test->value);
320                  }
321              }
322            }
323            param->SetUserValue(true);
324            m_Application->UpdateParameters();
325          }
326
327          try{
328            if( m_Application->ExecuteAndWriteOutput() == 0 ){
329              std::vector< std::pair<std::string, std::string> > paramList;
330              paramList = m_Application->GetOutputParametersSumUp();
331              if(paramList.size()>0)
332                for( unsigned int i=0; i<paramList.size(); i++){
333                  setMapInMaps(outputs,paramList[i].first.c_str(),"value",paramList[i].second.c_str());
334                }
335              else{
336                const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
337                for (unsigned int i = 0; i < appKeyList.size(); i++){
338                  const std::string paramKey(appKeyList[i]);
339                  std::vector<std::string> values;
340                  Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
341                  ParameterType type = m_Application->GetParameterType(paramKey);
342                  if (type != ParameterType_Group && paramKey!="inxml" && paramKey!="outxml"
343                      && (type == ParameterType_OutputImage || type == ParameterType_OutputFilename
344                          || type == ParameterType_OutputVectorData ) ){
345                    if(type == ParameterType_OutputImage || type == ParameterType_OutputFilename || type == ParameterType_OutputVectorData){
346                      map* test=getMapFromMaps(outputs,paramKey.c_str(),"mimeType");
347                      if(test!=NULL && strncasecmp(test->value,"application/zip",15)==0){
348                       
349                        test=getMapFromMaps(inputs,paramKey.c_str(),"generated_file");
350                        char tmpName[1024];
351                        sprintf(tmpName,"/vsizip/%s",ReplaceAll(test->value,".shp",".zip").c_str());
352                        VSILFILE* fmain=VSIFOpenL(tmpName, "w");
353                        FILE * file;
354                        char *tmp;
355                        char tmpSName[1024];
356                        long count;
357                       
358                        char *exts[4];
359                        exts[0]=".shp";
360                        exts[1]=".shx";
361                        exts[2]=".dbf";
362                        exts[3]=".prj";
363                        for(int c=0;c<4;c++){
364                          sprintf(tmpSName,"%s/result%s",tmpName,exts[c]);
365                         
366                          file=fopen(ReplaceAll(test->value,".shp",exts[c]).c_str(),"rb");
367                          if(file!=NULL){
368                            fseek(file, 0, SEEK_END);
369                            count = ftell(file);
370                            rewind(file);
371                           
372                            tmp=(char*) malloc((count+1)*sizeof(char)); 
373                            fread(tmp,1,count*sizeof(char),file);
374                           
375                            VSILFILE* fx=VSIFOpenL(tmpSName, "wb");
376                            VSIFWriteL(tmp,1,count,fx);
377                            VSIFCloseL(fx);
378                            fclose(file);
379                            free(tmp);
380                          }
381                        }
382                       
383                        VSIFCloseL(fmain);
384                       
385                        FILE* file1=fopen(ReplaceAll(test->value,".shp",".zip").c_str(), "rb");
386                        fseek(file1, 0, SEEK_END);
387                        count=ftell(file1);
388                        rewind(file1);
389                       
390                        tmp=(char*) malloc((count+1)*sizeof(char)); 
391                        fread(tmp,1,count*sizeof(char),file1);
392                       
393                        file=fopen(ReplaceAll(test->value,".shp",".zip").c_str(),"wb");
394                        fwrite(tmp,1,count,file);
395                        fclose(file);
396                        free(tmp);
397                        fclose(file1);
398                        setMapInMaps(inputs,paramKey.c_str(),"generated_file",ReplaceAll(test->value,".shp",".zip").c_str());
399                      }
400                      test=getMapFromMaps(inputs,paramKey.c_str(),"generated_file");
401
402                      if(test!=NULL){
403                        setMapInMaps(outputs,paramKey.c_str(),"generated_file",test->value);
404                      }
405
406                    }
407                  }
408                }
409              }
410              res=3;
411              break;
412            }
413            else{
414              sprintf(tmpS, "The OTB Application %s cannot be run.", s->name);
415              setMapInMaps(m,"lenv","message",tmpS);
416              res=SERVICE_FAILED;
417            }
418          }
419          catch(std::exception& err){
420            setMapInMaps(m,"lenv","message",err.what());
421            return SERVICE_FAILED;
422           
423          }
424          catch(...){
425            setMapInMaps(m,"lenv","message","An unknown exception has been raised during application execution");
426            res=SERVICE_FAILED;
427          }
428          break;
429        }
430      }
431    }
432  }
433
434  for (unsigned int i = 0; i < m_WatcherList.size(); i++){
435    m_WatcherList[i]->FreeConf();
436    delete m_WatcherList[i];
437    m_WatcherList[i] = NULL;
438  }
439  m_WatcherList.clear();
440
441  return res;
442}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png