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

Last change on this file since 962 was 962, checked in by djay, 14 months ago

Update OGC API - Processes documentation and implementation, providing a browsable User Interface to Processes.

  • Property svn:keywords set to Id
File size: 17.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#include "response_print.h"
31#include "server_internal.h"
32
33using namespace otb::Wrapper;
34
35/**
36 * Global OTB counter
37 */
38int otbCounter=0;
39
40/**
41 * The ZooWatcher list
42 */
43WatcherListType m_WatcherList;
44/**
45 * A pointer to the conf maps containing the main.cfg settings
46 */
47maps* m_Conf;
48
49/**
50 * The command to create a ZooWatcher and add it to the global m_WatcherList
51 */
52class MyCommand : public itk::Command
53{
54 public:
55  itkNewMacro( MyCommand );
56 public:
57
58  /**
59   * The method that defines the action to be taken by the command.
60   *
61   * @param caller an itk::Object pointer
62   * @param event an itk::EventObject pointer
63   */
64  void Execute(itk::Object *caller, const itk::EventObject & event)
65  {
66    Execute( (const itk::Object *)caller, event);
67  }
68 
69  /**
70   * The method that defines the action to be taken by the command.
71   * Create a new ZooWatcher instance then add it to the m_WatcherList.
72   *
73   * @param caller a const itk::Object pointer
74   * @param event an itk::EventObject pointer
75   * @see ZooWatcher,ZooWatcher::SetConf
76   */
77  void Execute(const itk::Object *caller, const itk::EventObject & event)
78  {
79    const AddProcessToWatchEvent* eventToWatch = dynamic_cast< const AddProcessToWatchEvent*> ( &event );
80    std::string m_CurrentDescription = eventToWatch->GetProcessDescription();
81    ZooWatcher * watch = new ZooWatcher(eventToWatch->GetProcess(),
82                                        eventToWatch->GetProcessDescription());
83    watch->SetConf(&m_Conf);
84    m_WatcherList.push_back(watch);
85  }
86
87};
88
89/**
90 * Replace all occurence of from by to in a str string
91 *
92 * @param str the string to transform
93 * @param from the string to replace
94 * @param to the string used as replacement
95 * @return the resulting string
96 */
97std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
98    size_t start_pos = 0;
99    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
100        str.replace(start_pos, from.length(), to);
101        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
102    }
103    return str;
104}
105
106/**
107 * Load and run an OTB Application corresponding to the service by using inputs parameters.
108 * Define the m_Conf
109 *
110 * @param main_conf the conf maps containing the main.cfg settings
111 * @param request the map containing the HTTP request
112 * @param s the service structure
113 * @param real_inputs the maps containing the inputs
114 * @param real_outputs the maps containing the outputs
115 */
116int zoo_otb_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
117  maps* m=*main_conf;
118  maps* inputs=*real_inputs;
119  maps* outputs=*real_outputs;
120  map* tmp0=getMapFromMaps(*main_conf,"lenv","cwd");
121  char *ntmp=tmp0->value;
122  map* tmp=NULL;
123  int res=-1;
124  int saved_stdout = zDup (fileno (stdout));
125  zDup2 (fileno (stderr), fileno (stdout));
126  std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
127  if (list.size() == 0){
128    map* tmps=createMap("text","No OTB Application found.");
129    addToMap(tmps,"code","InternalError");
130    zDup2 (saved_stdout, fileno (stdout));
131    zClose(saved_stdout);
132    printExceptionReportResponse(m,tmps);
133    freeMap(&tmps);
134    free(tmps);
135    res=-1;
136    return res;
137  }
138  else{
139    dumpMapsValuesToFiles(main_conf,real_inputs);
140    for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it){
141      if(s->name==*it){
142        Application::Pointer m_Application=ApplicationRegistry::CreateApplication(*it);
143        if (m_Application.IsNull()){
144          char tmpS[1024];
145          sprintf(tmpS, "The OTB Application %s cannot be loaded.", (*it).c_str());
146          map* tmps=createMap("text",tmpS);
147          addToMap(tmps,"code","InternalError");
148          zDup2 (saved_stdout, fileno (stdout));
149          zClose(saved_stdout);
150          printExceptionReportResponse(m,tmps);
151          freeMap(&tmps);
152          free(tmps);
153          res=-1;
154        }else{
155          // Create Observer on AddProcessToWatchEvent
156          m_Conf=m;
157          MyCommand::Pointer myCommand = MyCommand::New();
158          m_Application->AddObserver(AddProcessToWatchEvent(), myCommand);
159          char tmpS[1024];
160          const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
161          for (unsigned int i = 0; i < appKeyList.size(); i++){
162            const std::string paramKey(appKeyList[i]);
163            Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
164            ParameterType type = m_Application->GetParameterType(paramKey);
165            if (type != ParameterType_Group && paramKey!="inxml" && paramKey!="outxml"){
166              map* test=getMapFromMaps(inputs,paramKey.c_str(),"cache_file");
167              if(test==NULL){
168                test=getMapFromMaps(inputs,paramKey.c_str(),"inRequest");
169                map* tmpPath=getMapFromMaps(m,"main","tmpPath");
170                map* tmpSid=getMapFromMaps(m,"lenv","usid");
171                char tmp[1024];
172                map* tmpVal=getMapFromMaps(outputs,paramKey.c_str(),"mimeType");
173                maps* tmpMaps=getMaps(outputs,paramKey.c_str());
174                if(tmpMaps!=NULL && test!=NULL && test->value!=NULL && strncasecmp(test->value,"true",4)==0){
175                  test=getMapFromMaps(inputs,paramKey.c_str(),"value");
176                  if(type == ParameterType_OutputImage){
177                    ImagePixelType outPixType = ImagePixelType_float;
178                    if (strncasecmp(test->value,"uint8",5)==0)
179                      outPixType = ImagePixelType_uint8;
180                    else if (strncasecmp(test->value,"int16",5)==0)
181                      outPixType = ImagePixelType_int16;
182                    else if (strncasecmp(test->value,"uint16",6)==0)
183                      outPixType = ImagePixelType_uint16;
184                    else if (strncasecmp(test->value,"int32",5)==0)
185                      outPixType = ImagePixelType_int32;
186                    else if (strncasecmp(test->value,"uint32",6)==0)
187                      outPixType = ImagePixelType_uint32;
188                    else if (strncasecmp(test->value,"double",6)==0)
189                      outPixType = ImagePixelType_double;
190                    const char* ext="tiff";
191                    if(tmpVal!=NULL){
192                      if(strncasecmp(tmpVal->value,"image/jp2",9)==0)
193                         ext="j2k";
194                      else
195                        if(strncasecmp(tmpVal->value,"image/png",9)==0)
196                         ext="png";
197                        else
198                          if(strncasecmp(tmpVal->value,"image/jpeg",10)==0)
199                            ext="jpeg";
200                    }
201                    sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
202                    otbCounter++;
203                    m_Application->SetParameterString(paramKey, tmp);
204                    setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
205                    dynamic_cast<OutputImageParameter *> (param.GetPointer())->SetPixelType(outPixType);
206                  }
207                  else{                 
208                    if(test!=NULL && test->value!=NULL)                 
209                      m_Application->SetParameterString(paramKey, test->value);                 
210                  } 
211                }else{
212                  if(type == ParameterType_OutputVectorData){
213                      char* ext="json";
214                      if(tmpVal!=NULL){
215                        if(strncasecmp(tmpVal->value,"text/xml",8)==0)
216                        ext="gml";
217                      else
218                        if(strncasecmp(tmpVal->value,"applicaton/json",15)==0)
219                          ext="json";
220                        else
221                          if(strncasecmp(tmpVal->value,"application/zip",14)==0)
222                            ext="shp";
223                          else
224                            if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kml+xml",36)==0)
225                              ext="kml";
226                      }
227                      sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
228                      otbCounter++;
229                      m_Application->SetParameterString(paramKey, tmp);
230                      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
231                  }
232                  else
233                    if(type == ParameterType_OutputFilename){
234                      char* ext="txt";
235                      if(tmpVal!=NULL){
236                        if(strncasecmp(tmpVal->value,"text/xml",8)==0)
237                          ext="xml";
238                        else
239                          if(strncasecmp(tmpVal->value,"text/csv",15)==0)
240                            ext="csv";
241                          else
242                            if(strncasecmp(tmpVal->value,"application/zip",14)==0)
243                              ext="shp";
244                            else
245                              if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kml+xml",36)==0)
246                                ext="kml";
247                              else
248                                if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kmz",32)==0){
249                                  ext="kmz";
250                                  sprintf(tmp,"%s/%s_%d_%sxt.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
251                                  m_Application->SetParameterString(paramKey, tmp);
252                                  setMapInMaps(outputs,paramKey.c_str(),"expected_generated_file",tmp);
253                                }
254
255                      }
256                      sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
257                      otbCounter++;
258                      m_Application->SetParameterString(paramKey, tmp);
259                      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
260                    }
261                    else{
262                      test=getMapFromMaps(inputs,paramKey.c_str(),"value");
263                      if(test!=NULL && type!=ParameterType_ListView){
264                        m_Application->SetParameterString(paramKey, test->value);
265                      }
266                      else
267                        if(type==ParameterType_ListView){
268                          std::vector<std::string> values;
269                          values.push_back(test->value);
270                          map* tmpLength=getMapFromMaps(inputs,paramKey.c_str(),"length");
271                          if(tmpLength!=NULL){
272                            int len=atoi(tmpLength->value);
273                            for(int k=1;k<len;k++){
274                              char tmp[15];
275                              sprintf(tmp,"cache_file_%d",k);
276                              map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),tmp);
277                              if(tmpVal!=NULL){
278                                values.push_back(tmpVal->value);
279                              }
280                            }
281                          }
282                          dynamic_cast<ListViewParameter *> (param.GetPointer())->SetSelectedItems(values);
283                        }
284                    }
285                }
286              }else{
287                if(type == ParameterType_InputImageList){
288                  std::vector<std::string> values;
289                  values.push_back(test->value);
290                  map* tmpPath=getMapFromMaps(inputs,paramKey.c_str(),"length");
291                  if(tmpPath!=NULL){
292                    int len=atoi(tmpPath->value);
293                    for(int k=1;k<len;k++){
294                      char tmp[15];
295                      sprintf(tmp,"cache_file_%d",k);
296                      map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),tmp);
297                      if(tmpVal!=NULL){
298                        values.push_back(tmpVal->value);
299                      }
300                    }
301                  }
302                  dynamic_cast<InputImageListParameter *> (param.GetPointer())->SetListFromFileName(values);
303                }
304                else
305                  if(type == ParameterType_InputVectorData || type == ParameterType_InputFilename){
306                    map* tmpPath=getMapFromMaps(m,"main","tmpPath");
307                    map* tmpSid=getMapFromMaps(m,"lenv","sid");
308                    char tmp[1024];
309                    map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),"mimeType");
310                    char* ext="json";
311                    if(tmpVal!=NULL){
312                      if(strncasecmp(tmpVal->value,"application/zip",14)==0){
313                        char *tmpName=(char*)malloc((strlen(test->value)+9)*sizeof(char));
314                        std::string test0(test->value);
315                        if(test0.find(".zca")!=std::string::npos){
316                          symlink(test->value,ReplaceAll(test->value,".zca",".zip").c_str());
317                          sprintf(tmpName,"/vsizip/%s",ReplaceAll(test->value,".zca",".zip").c_str());
318                        }else
319                          sprintf(tmpName,"/vsizip/%s",test->value);
320                        char **files=VSIReadDir(tmpName);
321                        int nFiles = CSLCount( files );
322                        char *tmpSSName=(char*)malloc((strlen(tmpPath->value)+strlen(paramKey.c_str())+strlen(tmpSid->value)+9)*sizeof(char));
323                        sprintf(tmpSSName,"%s/Input_%s_%s",tmpPath->value,paramKey.c_str(),tmpSid->value);
324                        mkdir(tmpSSName,0777);
325                           
326                        for(int kk=0;kk<nFiles;kk++){
327                          char *tmpSName=(char*)malloc((strlen(tmpName)+strlen(files[kk])+2)*sizeof(char));
328                          sprintf(tmpSName,"%s/%s",tmpName,files[kk]);
329                          VSILFILE* fmain=VSIFOpenL(tmpSName, "rb");
330                          if(fmain!=NULL){
331                            VSIFSeekL(fmain,0,SEEK_END);
332                            long count=VSIFTellL(fmain);
333                            VSIRewindL(fmain);
334
335                            char *content=(char*) malloc((count+1)*sizeof(char)); 
336                            VSIFReadL(content,1,count*sizeof(char),fmain);
337                         
338                            char *tmpSSSName=(char*)malloc((strlen(tmpSSName)+strlen(files[kk])+2)*sizeof(char));
339                            sprintf(tmpSSSName,"%s/%s",tmpSSName,files[kk]);
340                           
341                            FILE* fx=fopen(tmpSSSName, "wb");
342                            fwrite(content,1,count,fx);
343                            fclose(fx);
344                            VSIFCloseL(fmain);
345                            free(content);
346                            std::string test1(tmpSSSName);
347                            if(test1.find(".shp")!=std::string::npos){
348                              setMapInMaps(inputs,paramKey.c_str(),"cache_file",tmpSSSName);
349                              test=getMapFromMaps(inputs,paramKey.c_str(),"cache_file");
350                            }
351                            free(tmpSSSName);
352                          }
353                          free(tmpSName);
354                        }
355                        free(tmpSSName);
356                        free(tmpName);
357                      }
358                    }
359                   
360                    m_Application->SetParameterString(paramKey, test->value);
361                  }
362                  else
363                    if(type == ParameterType_InputImage
364                       || type == ParameterType_ComplexInputImage || type == ParameterType_InputVectorData
365                       || type == ParameterType_InputFilename){
366                      m_Application->SetParameterString(paramKey, test->value);
367                  }
368              }
369            }
370            param->SetUserValue(true);
371            m_Application->UpdateParameters();
372          }
373
374          try{
375            if( m_Application->ExecuteAndWriteOutput() == 0 ){
376              std::vector< std::pair<std::string, std::string> > paramList;
377              paramList = m_Application->GetOutputParametersSumUp();
378              if(paramList.size()>0)
379                for( unsigned int i=0; i<paramList.size(); i++){
380                  setMapInMaps(outputs,paramList[i].first.c_str(),"value",paramList[i].second.c_str());
381                }
382              else{
383                const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
384                for (unsigned int i = 0; i < appKeyList.size(); i++){
385                  const std::string paramKey(appKeyList[i]);
386                  std::vector<std::string> values;
387                  Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
388                  ParameterType type = m_Application->GetParameterType(paramKey);
389                  if (type != ParameterType_Group && paramKey!="inxml" && paramKey!="outxml"
390                      && (type == ParameterType_OutputImage || type == ParameterType_OutputFilename
391                          || type == ParameterType_OutputVectorData ) ){
392                    if(type == ParameterType_OutputImage || type == ParameterType_OutputFilename || type == ParameterType_OutputVectorData){
393                      map* test=getMapFromMaps(outputs,paramKey.c_str(),"mimeType");
394                      if(test!=NULL && strncasecmp(test->value,"application/zip",15)==0){
395                       
396                        test=getMapFromMaps(inputs,paramKey.c_str(),"generated_file");
397                        char tmpName[1024];
398                        sprintf(tmpName,"/vsizip/%s",ReplaceAll(test->value,".shp",".zip").c_str());
399                        VSILFILE* fmain=VSIFOpenL(tmpName, "w");
400                        FILE * file;
401                        char *tmp;
402                        char tmpSName[1024];
403                        long count;
404                       
405                        char *exts[4];
406                        exts[0]=".shp";
407                        exts[1]=".shx";
408                        exts[2]=".dbf";
409                        exts[3]=".prj";
410                        for(int c=0;c<4;c++){
411                          sprintf(tmpSName,"%s/result%s",tmpName,exts[c]);
412                         
413                          file=fopen(ReplaceAll(test->value,".shp",exts[c]).c_str(),"rb");
414                          if(file!=NULL){
415                            fseek(file, 0, SEEK_END);
416                            count = ftell(file);
417                            rewind(file);
418                           
419                            tmp=(char*) malloc((count+1)*sizeof(char)); 
420                            fread(tmp,1,count*sizeof(char),file);
421                           
422                            VSILFILE* fx=VSIFOpenL(tmpSName, "wb");
423                            VSIFWriteL(tmp,1,count,fx);
424                            VSIFCloseL(fx);
425                            fclose(file);
426                            free(tmp);
427                          }
428                        }
429                       
430                        VSIFCloseL(fmain);
431                       
432                        FILE* file1=fopen(ReplaceAll(test->value,".shp",".zip").c_str(), "rb");
433                        fseek(file1, 0, SEEK_END);
434                        count=ftell(file1);
435                        rewind(file1);
436                       
437                        tmp=(char*) malloc((count+1)*sizeof(char)); 
438                        fread(tmp,1,count*sizeof(char),file1);
439                       
440                        file=fopen(ReplaceAll(test->value,".shp",".zip").c_str(),"wb");
441                        fwrite(tmp,1,count,file);
442                        fclose(file);
443                        free(tmp);
444                        fclose(file1);
445                        setMapInMaps(inputs,paramKey.c_str(),"generated_file",ReplaceAll(test->value,".shp",".zip").c_str());
446                      }
447                      test=getMapFromMaps(inputs,paramKey.c_str(),"generated_file");
448
449                      if(test!=NULL){
450                        setMapInMaps(outputs,paramKey.c_str(),"generated_file",test->value);
451                      }
452
453                    }
454                  }
455                }
456              }
457              res=3;
458              break;
459            }
460            else{
461              sprintf(tmpS, "The OTB Application %s cannot be run.", s->name);
462              setMapInMaps(m,"lenv","message",tmpS);
463              res=SERVICE_FAILED;
464            }
465          }
466          catch(std::exception& err){
467            setMapInMaps(m,"lenv","message",err.what());
468            zDup2 (saved_stdout, fileno (stdout));
469            zClose(saved_stdout);
470            return SERVICE_FAILED;
471           
472          }
473          catch(...){
474            setMapInMaps(m,"lenv","message","An unknown exception has been raised during application execution");
475            res=SERVICE_FAILED;
476          }
477          break;
478        }
479      }
480    }
481  }
482
483  for (unsigned int i = 0; i < m_WatcherList.size(); i++){
484    m_WatcherList[i]->FreeConf();
485    delete m_WatcherList[i];
486    m_WatcherList[i] = NULL;
487  }
488  m_WatcherList.clear();
489  fflush(stdout);
490  zDup2 (saved_stdout, fileno (stdout));
491  zClose(saved_stdout);
492  return res;
493}
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