source: trunk/zoo-project/zoo-kernel/service_internal_saga.c @ 636

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

Fix typos

  • Property svn:keywords set to Id
File size: 34.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
25#include <stdlib.h>
26#include <limits.h>
27#include "service_internal_saga.h"
28#include "mimetypes.h"
29
30/**
31 * Observer used to access the ongoing status of a running OTB Application
32 */
33class SagaWatcher
34{
35 public:
36  static int Callback(TSG_UI_Callback_ID ID, CSG_UI_Parameter &Param_1, CSG_UI_Parameter &Param_2);
37  /**
38   * Define the message value
39   *
40   * @param conf the maps pointer to copy
41   */
42  static void SetMessage(const char *mess)
43  {
44    FreeMessage();
45    message=zStrdup(mess);
46  }
47  /**
48   * Free the message value
49   *
50   */
51  static void FreeMessage()
52  {
53    if(message!=NULL)
54      free(message);
55    message=NULL;
56  }
57  /**
58   * Copy the original conf in the m_conf property
59   *
60   * @param conf the maps pointer to copy
61   */
62  void SetConf(maps **conf)
63  {
64    m_conf=dupMaps(conf);
65  }
66  /** 
67   * Get Configuration maps (m_conf)
68   * @return the m_conf property
69   */
70  const maps& GetConf()
71  {
72    return *m_conf;
73  }
74  /** 
75   * Free Configuration maps (m_Conf)
76   */
77  void FreeConf(){
78    freeMaps(&m_conf);
79    free(m_conf);
80  }
81 private:
82  /** Main conf maps */
83  static maps* m_conf;
84  /** Status */
85  static int status;
86  /** Message */
87  static char* message;
88};
89
90maps* SagaWatcher::m_conf;
91char* SagaWatcher::message=zStrdup("");
92int SagaWatcher::status=1;
93
94/**
95 * The callback function called at any SAGA-GIS module step
96 *
97 * @param id a TSG_UI_Callback_ID as defined in api_core.h (line 1290)
98 * @param param1
99 * @param param2
100 */
101int
102SagaWatcher::
103Callback(TSG_UI_Callback_ID id, CSG_UI_Parameter &param1, CSG_UI_Parameter &param2)
104{
105
106  int res = 1;
107  switch( id )
108    {
109    default:
110      res = 0;
111      break;
112
113    case CALLBACK_PROCESS_GET_OKAY:
114      break;
115
116    case CALLBACK_PROCESS_SET_OKAY:
117      break;
118
119    case CALLBACK_PROCESS_SET_PROGRESS:
120      {
121        int cPercent= param2.Number != 0.0 ? 1 + (int)(100.0 * param1.Number / param2.Number) : 100 ;
122        if( cPercent != status ){
123          status=cPercent;
124        }
125      }
126      break;
127
128    case CALLBACK_PROCESS_SET_READY:
129      status=1;
130      break;
131
132    case CALLBACK_PROCESS_SET_TEXT:
133      SetMessage(param1.String.b_str());
134      break;
135
136    case CALLBACK_MESSAGE_ADD:
137      SetMessage(param1.String.b_str());
138      break;
139
140    case CALLBACK_MESSAGE_ADD_ERROR:
141      SetMessage(param1.String.b_str());
142      break;
143
144    case CALLBACK_MESSAGE_ADD_EXECUTION:
145      SetMessage(param1.String.b_str());
146      break;
147
148    case CALLBACK_DLG_MESSAGE:
149      SetMessage((param2.String + ": " + param1.String).b_str());
150      break;
151
152    case CALLBACK_DLG_CONTINUE:
153      break;
154
155    case CALLBACK_DLG_ERROR:
156      break;
157
158    case CALLBACK_DATAOBJECT_ADD:
159      if(SG_Get_Data_Manager().Add((CSG_Data_Object *)param1.Pointer))
160        res = 1 ;
161      else
162        res = 0;
163      break;
164
165    case CALLBACK_DATAOBJECT_UPDATE:
166      break;
167
168    case CALLBACK_DATAOBJECT_SHOW:
169      break;
170
171    case CALLBACK_DATAOBJECT_COLORS_GET:
172      break;
173
174    case CALLBACK_DATAOBJECT_COLORS_SET:
175      break;
176
177    case CALLBACK_DATAOBJECT_PARAMS_GET:
178      break;
179
180    case CALLBACK_DATAOBJECT_PARAMS_SET:
181      break;
182
183    case CALLBACK_DLG_PARAMETERS:
184      break;
185
186    }
187  updateStatus(m_conf,status,message);
188  return( res );
189}
190
191TSG_PFNC_UI_Callback Get_Callback (SagaWatcher watcher){
192  return( &(watcher.Callback) );
193}
194
195
196/**
197 * Get the default file extension for SAGA-GIS parameter type.
198 * Extensions are the following:
199 *  - sgrd for grid and data_object
200 *  - shp for shapes and tin
201 *  - csv for tables
202 *  - spc for points
203 *
204 * @param param a SAGA-GIS Parameter
205 */ 
206const char* sagaGetDefaultExt(CSG_Parameter* param){
207  if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("grid"))
208     || CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("data_object"))){
209    return "sgrd";
210  }
211  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes")) ||
212          CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
213    return "shp";
214  }
215  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
216    return "csv";
217  }
218  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("points"))){
219    return "spc";
220  }
221  return "unknown";
222}
223
224/**
225 * Load a datasource in the SAGA-GIS Data Manager.
226 *
227 * @param param a SAGA-GIS Parameter
228 * @param arg the arguments map passed to a SAGA-GIS module
229 * @return false on failure, true in case of success
230 */
231bool sagaLoadInput(CSG_Parameter* param,map* arg){
232  if(!param->is_Input() || !param->is_Enabled()){
233    return true;
234  }
235  map* carg=getMap(arg,CSG_String(param->Get_Identifier()).b_str());
236  if(carg!=NULL){
237    wxString fileName(carg->value);
238    if(param->is_DataObject()){
239      // In case it there is a single datasource
240      if(!SG_Get_Data_Manager().Find(&fileName) && !SG_Get_Data_Manager().Add(&fileName) && !param->is_Optional() ){
241        return false;
242      }
243      return( param->Set_Value(SG_Get_Data_Manager().Find(&fileName)) );
244    }
245    else
246      if(param->is_DataObject_List()){
247        // In case there are multiple datasources
248        param->asList()->Del_Items();
249        wxString fileNames(fileName);
250        while( fileNames.Length() > 0 ){
251          fileName = fileNames.BeforeFirst(';').Trim(false);
252          fileNames = fileNames.AfterFirst (';');           
253          if( !SG_Get_Data_Manager().Find(&fileName) ){
254            SG_Get_Data_Manager().Add(&fileName);
255          }
256          param->asList()->Add_Item(SG_Get_Data_Manager().Find(&fileName));
257        }
258      }
259  }
260  return true;
261}
262
263/**
264 * Extract all SAGA-GIS parameters from a parameters list and set its values to
265 * the one defined in the map.
266 *
267 * @parap params the parameters list
268 * @parap argument the argument map containing the value to use
269 * @return true in success, false in other case
270 */
271bool sagaSetParameters(CSG_Parameters *params,map* argument){
272
273  int pc=params->Get_Count();
274  params->Restore_Defaults();
275
276  for(int k=0;k<pc;k++){
277    CSG_Parameter * param=params->Get_Parameter(k);
278    if( param->is_Output() ){
279      map* omap=getMap(argument,CSG_String(param->Get_Identifier()).b_str());
280      if( param->is_DataObject() && param->is_Optional() && !param->asDataObject() && omap!=NULL){
281        param->Set_Value(DATAOBJECT_CREATE);
282      }
283    }
284    else
285      if( param->is_Option() && !param->is_Information() ){
286        map* inmap=getMap(argument,CSG_String(param->Get_Identifier()).b_str());
287        if(inmap!=NULL){
288            switch( param->Get_Type() ){
289            case PARAMETER_TYPE_Bool:
290              if(strncasecmp(inmap->value,"true",4)==0 || strncasecmp(inmap->value,"1",1)==0){
291                param->Set_Value(1);
292              }else
293                param->Set_Value(0);
294              break;
295            case PARAMETER_TYPE_Parameters:
296              // TODO: nested inputs gesture
297              break;
298            case PARAMETER_TYPE_Int:
299              param->Set_Value((int)strtol(inmap->value,NULL,10));
300              break;
301            case PARAMETER_TYPE_Double:
302            case PARAMETER_TYPE_Degree:
303              param->Set_Value((double)strtod(inmap->value,NULL));
304              break;
305            case PARAMETER_TYPE_String:
306              param->Set_Value(CSG_String(inmap->value));
307              break;
308            case PARAMETER_TYPE_FilePath:
309              param->Set_Value(CSG_String(inmap->value));
310              break;
311            case PARAMETER_TYPE_FixedTable:
312              {
313                CSG_Table Table(inmap->value);
314                param->asTable()->Assign_Values(&Table);
315              }
316              break;
317            case PARAMETER_TYPE_Choice:
318              {
319                int val=(int)strtol(inmap->value,(char**)NULL,10);
320                if(val==0 && strncasecmp(inmap->value,"0",1)!=0)
321                  param->Set_Value(CSG_String(inmap->value));
322                else
323                  param->Set_Value(val);
324              }
325              break;
326            default:
327              break;
328            }
329        }else{
330          if(param->Get_Type()==PARAMETER_TYPE_Range){
331            inmap=getMap(argument,(CSG_String(param->Get_Identifier())+"_MIN").b_str());
332            if(inmap!=NULL)
333              param->asRange()->Set_LoVal(strtod(inmap->value,NULL));
334            inmap=getMap(argument,(CSG_String(param->Get_Identifier())+"_MAX").b_str());
335            if(inmap!=NULL)
336              param->asRange()->Set_HiVal(strtod(inmap->value,NULL));       
337          }
338          if(inmap==NULL){
339            param->Restore_Default();
340          }
341        }
342      }
343  }
344
345  for(int k=0;k<pc;k++){
346    CSG_Parameter * param=params->Get_Parameter(k);
347    if( param->is_Input() )
348      if(!sagaLoadInput(param,argument)){
349        fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
350        return false;
351      }
352  }
353  return true;
354}
355
356/**
357 * Save all values outputed by a SAGA-GIS module invocation to files
358 *
359 * @param params the parameters list
360 * @param main_conf the conf maps containing the main.cfg settings
361 * @param outputs the maps to set the generated_file for each output
362 */
363bool sagaSaveOutputs(CSG_Parameters *params,maps* main_conf,maps** outputs)
364{
365  for(int j=0; j<params->Get_Count(); j++)
366    {
367      CSG_Parameter *param = params->Get_Parameter(j);
368      maps* cMaps=getMaps(*outputs,CSG_String(param->Get_Identifier()).b_str());
369      // Specific TIN case
370      if(cMaps==NULL && CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin")))
371        cMaps=getMaps(*outputs,(CSG_String(param->Get_Identifier())+"_POINTS").b_str());
372      if(cMaps!=NULL){
373        map* tmpPath=getMapFromMaps(main_conf,"main","tmpPath");
374        map* sid=getMapFromMaps(main_conf,"lenv","usid");
375        const char *file_ext=sagaGetDefaultExt(param);
376
377        if( param->is_Input() )
378          {
379            if( param->is_DataObject() )
380              {
381                CSG_Data_Object *pObject = param->asDataObject();
382               
383                if( pObject && pObject->is_Modified() && SG_File_Exists(pObject->Get_File_Name()) )
384                  {
385                    pObject->Save(pObject->Get_File_Name());
386                    addToMap(cMaps->content,"generated_file",CSG_String(pObject->Get_File_Name()).b_str());
387                  }
388              }
389           
390            else if( param->is_DataObject_List() )
391              {
392                for(int i=0; i<param->asList()->Get_Count(); i++)
393                  {
394                    CSG_Data_Object *pObject = param->asList()->asDataObject(i);
395                   
396                    if( pObject->is_Modified() && SG_File_Exists(pObject->Get_File_Name()) )
397                      {
398                        pObject->Save(pObject->Get_File_Name());
399                        setMapArray(cMaps->content,"generated_file",i,CSG_String(pObject->Get_File_Name()).b_str());
400                      }
401                  }
402              }
403          }
404        else
405          if( param->is_Output() )
406            {
407              char *realFileName=(char*)malloc((strlen(file_ext)+strlen(sid->value)+strlen(cMaps->name)+14)*sizeof(char));
408              char *fullFileName=(char*)malloc((strlen(file_ext)+strlen(sid->value)+strlen(cMaps->name)+strlen(tmpPath->value)+16)*sizeof(char));
409              sprintf(realFileName,"Output_%s_%d_%s",cMaps->name,sagaOutputCounter,sid->value);
410              sprintf(fullFileName,"%s/Output_%s_%d_%s.%s",tmpPath->value,cMaps->name,sagaOutputCounter,sid->value,file_ext);
411              sagaOutputCounter+=1;
412              wxString fileName(fullFileName);
413              addToMap(cMaps->content,"generated_name",realFileName);
414              free(realFileName);
415              free(fullFileName);
416
417              if( param->is_DataObject() )
418                {
419                  if( param->asDataObject() )
420                    {
421                      param->asDataObject()->Save(&fileName);
422                      addToMap(cMaps->content,"generated_file",CSG_String(param->asDataObject()->Get_File_Name()).b_str());
423                    }
424                }
425           
426              else if( param->is_DataObject_List() )
427                {
428                  CSG_Strings   fileNames;
429               
430                  while( fileName.Length() > 0 )
431                    {
432                      CSG_String current_file(&fileName);
433                      current_file = current_file.BeforeFirst(';');
434                      if( current_file.Length() > 0 )
435                        {
436                          fileNames += current_file;
437                          fileName = fileName.AfterFirst(';');
438                        }
439                      else
440                        {
441                          fileNames += &fileName;
442                          fileName.Clear();
443                        }
444                    }
445                 
446                  int nFileNames = param->asList()->Get_Count() <= fileNames.Get_Count() ? fileNames.Get_Count() : fileNames.Get_Count() - 1;
447                  for(int i=0; i<param->asList()->Get_Count(); i++)
448                    {
449                      fileNames[i].Trim();
450                      if( i < nFileNames )
451                        {
452                          param->asList()->asDataObject(i)->Save(fileNames[i]);
453                        }
454                      else
455                        {
456                          param->asList()->asDataObject(i)->Save(CSG_String::Format(SG_T("%s_%0*d"),
457                                                                                    fileNames[fileNames.Get_Count() - 1].c_str(),
458                                                                                    SG_Get_Digit_Count(param->asList()->Get_Count()),
459                                                                                    1 + i - nFileNames
460                                                                                    ));
461                        }
462                      setMapArray(cMaps->content,"generated_file",i,
463                                  CSG_String(param->asList()->asDataObject(i)->Get_File_Name()).b_str());
464                    }
465                }
466            }
467      }
468    }
469  return( true );
470}
471
472/**
473 * Invoke the execution of a SAGA-GIS module.
474 *
475 * @param main_conf the conf maps containing the main.cfg settings
476 * @param lib_name the SAGA-GIS library name
477 * @param module_name the SAGA-GIS module name
478 * @param arguments the map containing the arguments to pass to the module
479 * @param outputs default to NULL, contains the maps to fill with the result
480 */
481int sagaExecuteCmd(maps** main_conf,const char* lib_name,const char* module_name,map* arguments,maps** outputs=NULL){
482  int res=SERVICE_FAILED;
483
484  CSG_Module_Library * library=SG_Get_Module_Library_Manager().Get_Library(CSG_String(lib_name),true);
485  if( library == NULL){
486    char tmp[255];
487    sprintf(tmp,"Counld not load the %s SAGA library",lib_name);
488    setMapInMaps(*main_conf,"lenv","message",tmp);
489    res=SERVICE_FAILED;
490    return res;
491  }
492
493  CSG_Module * module=library->Get_Module(atoi(module_name));
494  if(module == NULL){
495    char tmp[255];
496    sprintf(tmp,"Counld not load the %s module from the %s SAGA library",module_name,lib_name);
497    setMapInMaps(*main_conf,"lenv","message",tmp);
498    res=SERVICE_FAILED;
499    return res;
500  }
501
502  CSG_Parameters * params=module->Get_Parameters();
503  if(!params){
504    char tmp[255];
505    sprintf(tmp,"Counld not find any param for the %s module from the %s SAGA library",module_name,lib_name);
506    setMapInMaps(*main_conf,"lenv","message",tmp);
507    res=SERVICE_FAILED;
508    return res;
509  }
510 
511  sagaSetParameters(params,arguments);
512
513  module->Update_Parameter_States();
514
515  bool retval=false;
516  if(module->On_Before_Execution()){
517    retval=module->Execute();
518    module->On_After_Execution();
519  }
520 
521  if(retval && outputs!=NULL){
522    sagaSaveOutputs(module->Get_Parameters(),*main_conf,outputs);
523    SG_Get_Data_Manager().Delete_Unsaved();
524    return SERVICE_SUCCEEDED;
525  }
526
527  return SERVICE_FAILED;
528
529}
530
531/**
532 * Export a SAGA-GIS Shapes to a file in a specific format (GML,KML,GeoJSON).
533 * saga_cmd io_gdal 4 -FILE my.format -SHAPES my.shp -FORMAT XXX
534 *
535 * @param main_conf the conf maps containing the main.cfg settings
536 * @param in the output maps to fill with the resulting file
537 */
538int sagaExportOGR(maps** conf, maps** in){
539  map* mtype=getMap((*in)->content,"mimeType");
540  map* gfile=getMap((*in)->content,"generated_file");
541  char* fext=NULL;
542  map* arg=NULL;
543  if(strncasecmp(mtype->value,"text/xml",8)==0){
544    fext=zStrdup("xml");
545  }
546  else if(strncasecmp(mtype->value,"application/json",16)==0){
547    fext=zStrdup("json");
548  }
549  else{
550    fext=zStrdup("kml");
551  }
552  char* tmpName=(char*)malloc((strlen(gfile->value)+2)*sizeof(char));
553  strncpy(tmpName,gfile->value,(strlen(gfile->value)-3)*sizeof(char));
554  strncpy(&tmpName[0]+(strlen(gfile->value)-3),fext,(strlen(fext))*sizeof(char));
555  tmpName[strlen(fext)+(strlen(gfile->value)-3)]=0;
556  arg=createMap("SHAPES",gfile->value);
557  addToMap(arg,"FILE",tmpName);
558  if(strncasecmp(mtype->value,"text/xml",8)==0){
559    addToMap(arg,"FORMAT","GML");
560  }
561  else if(strncasecmp(mtype->value,"application/json",16)==0){
562    addToMap(arg,"FORMAT","GeoJSON");
563  }
564  else{
565    addToMap(arg,"FORMAT","LIBKML");
566  }
567  free(fext);
568  free(gfile->value);
569  gfile->value=zStrdup(tmpName);
570  free(tmpName);
571 
572  sagaExecuteCmd(conf,"io_gdal","4",arg);
573  freeMap(&arg);
574  free(arg);
575}
576
577/**
578 * Export a SAGA-GIS pointcloud to a las file.
579 * saga_cmd io_shapes_las 0 -POINTS my.spc -FILE my.las
580 *
581 * @param main_conf the conf maps containing the main.cfg settings
582 * @param in the output maps to fill with the resulting file
583 */
584void sagaExportPC(maps** conf, maps** in){
585  map* mtype=getMap((*in)->content,"mimeType");
586  map* gfile=getMap((*in)->content,"generated_file");
587  char* fext="las";
588  map* arg=NULL;
589  char* tmpName=(char*)malloc((strlen(gfile->value)+2)*sizeof(char));
590  strncpy(tmpName,gfile->value,(strlen(gfile->value)-3)*sizeof(char));
591  strncpy(&tmpName[0]+(strlen(gfile->value)-3),fext,(strlen(fext))*sizeof(char));
592  tmpName[strlen(fext)+(strlen(gfile->value)-3)]=0;
593  arg=createMap("POINTS",gfile->value);
594  addToMap(arg,"FILE",tmpName);
595  free(gfile->value);
596  gfile->value=zStrdup(tmpName);
597  sagaExecuteCmd(conf,"io_shapes_las","0",arg);
598  freeMap(&arg);
599  free(arg);
600  free(tmpName);
601}
602
603/**
604 * Export a SAGA-GIS Grid to a file in a specific format (tiff,hdr,aa).
605 * saga_cmd io_gdal 1 -FILE my.format -GRIDS my.sgrd -FORMAT XXX
606 *
607 * @param main_conf the conf maps containing the main.cfg settings
608 * @param in the output maps to fill with the resulting file
609 */
610int sagaExportGDAL(maps** conf, maps** in/*,CSG_Parameter* param*/){
611  map* mtype=getMap((*in)->content,"extension");
612  map* gfile=getMap((*in)->content,"generated_file");
613  char* fext=NULL;
614  map* arg;
615
616  if(mtype!=NULL)
617    fext=zStrdup(mtype->value);
618  else{
619    fext=zStrdup("tiff");
620  }
621
622  mtype=getMap((*in)->content,"mimeType");
623  if(strncasecmp(mtype->value,"image/tiff",10)==0){
624    arg=createMap("FORMAT","1");
625  }
626  else if(strncasecmp(mtype->value,"application/x-ogc-envi",22)==0){
627    arg=createMap("FORMAT","ENVI .hdr Labelled");
628  }
629  else{
630    arg=createMap("FORMAT","ARC Digitized Raster Graphics");
631  }
632
633  if(gfile!=NULL){
634    char* tmpName=(char*)malloc((strlen(gfile->value)+1)*sizeof(char));
635    strncpy(tmpName,gfile->value,(strlen(gfile->value)-4)*sizeof(char));
636    strncpy(&tmpName[0]+(strlen(gfile->value)-4),fext,(strlen(fext))*sizeof(char));
637    tmpName[strlen(fext)+(strlen(gfile->value)-4)]=0;
638    addToMap(arg,"FILE",tmpName);
639    addToMap(arg,"GRIDS",gfile->value);
640    free(tmpName);
641    free(fext);
642    free(gfile->value);
643    map* tmp=getMap(arg,"FILE");
644    gfile->value=zStrdup(tmp->value);
645    sagaExecuteCmd(conf,"io_gdal","1",arg);
646  }
647  else{
648    // Empty result
649    return true;
650  }
651  freeMap(&arg);
652  free(arg);
653}
654
655/**
656 * Export a SAGA-GIS TIN to a file in a specific format (GML,KML,GeoJSON).
657 * Exporting TIN produce 5 separated files (POINTS, CENTER, EDGES, TRIANGLES
658 * and POLYGONS). Even if a client can choose which result it want to have,
659 * SAGA-GIS module will be invoked in a way that it will produce in any case
660 * each possible outputs. The selection of a specific output is made in the
661 * ZOO-Kernel itself and not specifically at this level.
662 * saga_cmd tin_tools 3 -TIN my.shp -POINTS p.shp ...
663 *
664 * @param conf the conf maps containing the main.cfg settings
665 * @param in the output maps to fill with the resulting file
666 * @see sagaExportOGR
667 */
668int sagaExportTIN(maps** conf, maps** in,const char* tname/*,CSG_Parameter* param*/){
669  map* mtype=getMap((*in)->content,"mimeType");
670  map* gfile=getMap((*in)->content,"generated_file");
671  char* fext="shp";
672  map* arg=createMap("TIN",gfile->value);
673
674  char* tinOut[5]={
675    "POINTS",
676    "CENTER",
677    "EDGES",
678    "TRIANGLES",
679    "POLYGONS"
680  };
681  maps* resouts=NULL;
682
683  int i=0;
684  for(i=0;i<5;i++){
685    char* tmpName=(char*)malloc((strlen(gfile->value)+strlen(tinOut[i])+4)*sizeof(char));
686    strncpy(tmpName,gfile->value,(strlen(gfile->value)-3)*sizeof(char));
687    char *tmpSubName=(char*) malloc((strlen(tinOut[i])+3)*sizeof(char));
688    sprintf(tmpSubName,"_%s.",tinOut[i]);
689    strncpy(&tmpName[0]+(strlen(gfile->value)-4),tmpSubName,(strlen(tmpSubName))*sizeof(char));
690    strncpy(&tmpName[0]+(strlen(gfile->value)+strlen(tmpSubName)-4),fext,(strlen(fext))*sizeof(char));
691    tmpName[strlen(fext)+(strlen(gfile->value)+strlen(tmpSubName)-4)]=0;
692
693    maps* louts=(maps*)malloc(MAPS_SIZE);
694    louts->name=zStrdup(tinOut[i]);
695    louts->content=createMap("mimeType","UNKOWN");
696    louts->next=NULL;
697   
698    addToMap(arg,tinOut[i],tmpName);
699   
700    free(tmpName);
701    if(resouts==NULL)
702      resouts=dupMaps(&louts);
703    else
704      addMapsToMaps(&resouts,louts);
705    freeMaps(&louts);
706    free(louts);
707  }
708 
709  sagaExecuteCmd(conf,"tin_tools","3",arg,&resouts);
710
711  for(i=0;i<5;i++){
712    map* generatedFile=getMapFromMaps(resouts,tinOut[i],"generated_file");
713    setMapInMaps(*in,(CSG_String(tname)+"_"+tinOut[i]).b_str(),"generated_file",generatedFile->value);
714    maps* cout=getMaps(*in,(CSG_String(tname)+"_"+tinOut[i]).b_str());
715    sagaExportOGR(conf,&cout);
716  }
717  return true;
718}
719
720/**
721 * Import GDAL Datasource into SAGA-GIS.
722 * saga_cmd io_gdal 0 -TRANSFORM 0 -FILES my.format -GRIDS /tmpPath/MyGridXXX.sgrd
723 *
724 * @param conf the conf maps containing the main.cfg settings
725 * @param in in the inputs maps
726 */
727int sagaImportGDAL(maps** conf, maps** in){
728  map* l=getMap((*in)->content,"length");
729  bool shouldClean=false;
730  if(l==NULL){
731    l=createMap("length","1");
732    shouldClean=true;
733  }
734  int len=strtol(l->value,NULL,10);
735  int i=0;
736  for(i=0;i<len;i++){
737    map* arg=createMap("TRANSFORM","0");
738    addToMap(arg,"INTERPOL","4");
739    map* v=getMapArray((*in)->content,"cache_file",i);
740    if(v!=NULL)
741      addToMap(arg,"FILES",v->value);
742    addToMap(arg,"GRIDS","");
743
744    maps* louts=(maps*)malloc(MAPS_SIZE);
745    louts->name=zStrdup("GRIDS");
746    louts->content=createMap("mimeType","UNKOWN");
747    louts->next=NULL;
748
749    sagaExecuteCmd(conf,"io_gdal","0",arg,&louts);
750
751    map* tmp=getMapFromMaps(louts,"GRIDS","generated_file");
752    setMapArray((*in)->content,"saga_value",i,tmp->value);
753
754    freeMaps(&louts);
755    free(louts);
756    freeMap(&arg);
757    free(arg);
758  }
759  if(shouldClean){
760    freeMap(&l);
761    free(l);
762  }
763}
764
765/**
766 * Import OGR Datasource into SAGA-GIS.
767 * saga_cmd io_gdal 3 -SHAPES my.shp -FILES my.format
768 *
769 * @param conf the conf maps containing the main.cfg settings
770 * @param in in the inputs maps
771 */
772int sagaImportOGR(maps** conf, maps** in){
773  char *ext;
774  map* arg;
775  map* l=getMap((*in)->content,"length");
776  bool shouldClean=false;
777  if(l==NULL){
778    l=createMap("length","1");
779    shouldClean=true;
780  }
781  int len=strtol(l->value,NULL,10);
782  int i=0;
783  for(i=0;i<len;i++){
784    map* v=getMapArray((*in)->content,"cache_file",i);
785    arg=createMap("SHAPES","");
786    if(v!=NULL)
787      addToMap(arg,"FILES",v->value);
788
789    maps* louts=(maps*)malloc(MAPS_SIZE);
790    louts->name=zStrdup("SHAPES");
791    louts->content=createMap("mimeType","UNKOWN");
792    louts->next=NULL;
793
794    sagaExecuteCmd(conf,"io_gdal","3",arg,&louts);
795
796    map* tmp=getMapFromMaps(louts,"SHAPES","generated_file");
797    setMapArray((*in)->content,"saga_value",i,tmp->value);
798
799    freeMaps(&louts);
800    free(louts);
801    freeMap(&arg);
802    free(arg);
803  }
804  if(shouldClean){
805    freeMap(&l);
806    free(l);
807  }
808}
809
810/**
811 * Import TIN into SAGA-GIS. Calling this function suppose that sagaImportOGR
812 * was called first.
813 * saga_cmd tin_tools 2 -SHAPES myShapes.shp -TIN myTin.shp
814 *
815 * @param conf the conf maps containing the main.cfg settings
816 * @param in in the inputs maps
817 * @see sagaImportOGR
818 */
819bool sagaImportTIN(maps** conf, maps** in){
820  char *ext;
821  map* arg;
822  map* l=getMap((*in)->content,"length");
823  bool shouldClean=false;
824  if(l==NULL){
825    l=createMap("length","1");
826    shouldClean=true;
827  }
828  int len=strtol(l->value,NULL,10);
829  int i=0;
830  for(i=0;i<len;i++){
831    map* v=getMapArray((*in)->content,"saga_value",i);
832    arg=createMap("TIN","");
833    if(v!=NULL)
834      addToMap(arg,"SHAPES",v->value);
835    maps* louts=(maps*)malloc(MAPS_SIZE);
836    louts->name=zStrdup("TIN");
837    louts->content=createMap("mimeType","UNKOWN");
838    louts->next=NULL;
839    sagaExecuteCmd(conf,"tin_tools","2",arg,&louts);
840    map* tmp=getMapFromMaps(louts,"TIN","generated_file");
841    v=getMapArray((*in)->content,"saga_value",i);
842    if(tmp!=NULL){
843      if(v!=NULL){
844        free(v->value);
845        v->value=zStrdup(tmp->value);
846      }
847      else
848        setMapArray((*in)->content,"saga_value",i,tmp->value);
849    }
850    freeMaps(&louts);
851    free(louts);
852    freeMap(&arg);
853    free(arg);
854  }
855  if(shouldClean){
856    freeMap(&l);
857    free(l);
858  }
859  return true;
860}
861
862/**
863 * Import table into SAGA-GIS.
864 * saga_cmd io_table 1 -TABLE myTable -FILENAME myFile -SEPARATOR 2
865 *
866 * @param conf the conf maps containing the main.cfg settings
867 * @param in in the inputs maps
868 */
869int sagaImportTable(maps** conf, maps** in){
870  char *ext;
871  map* arg;
872  map* l=getMap((*in)->content,"length");
873  bool shouldClean=false;
874  if(l==NULL){
875    l=createMap("length","1");
876    shouldClean=true;
877  }
878  int len=strtol(l->value,NULL,10);
879  int i=0;
880  for(i=0;i<len;i++){
881
882    // Create and fill arg map
883    arg=createMap("SEPARATOR","2");
884    addToMap(arg,"TABLE","");
885    map* v=getMapArray((*in)->content,"cache_file",i);
886    if(v!=NULL)
887      addToMap(arg,"FILENAME",v->value);
888
889    // Create the output maps
890    maps* louts=(maps*)malloc(MAPS_SIZE);
891    louts->name=zStrdup("TABLE");
892    louts->content=createMap("mimeType","UNKOWN");
893    louts->next=NULL;
894
895    // Execute the saga command
896    sagaExecuteCmd(conf,"io_table","1",arg,&louts);
897
898    // Fetch result and add it to the original map as saga_value
899    map* tmp=getMapFromMaps(louts,"TABLE","generated_file");
900    setMapArray((*in)->content,"saga_value",i,tmp->value);
901
902    // Cleanup
903    freeMaps(&louts);
904    free(louts);
905    freeMap(&arg);
906    free(arg);
907
908  }
909  // Cleanup if required
910  if(shouldClean){
911    freeMap(&l);
912    free(l);
913  }
914}
915
916/**
917 * Import las file as pointcloud into SAGA-GIS.
918 * saga_cmd io_shapes_las 1 -POINTS my.spc -FILENAME my.las
919 *
920 * @param conf the conf maps containing the main.cfg settings
921 * @param in in the inputs maps
922 */
923int sagaImportPC(maps** conf, maps** in){
924  char *ext;
925  map* arg;
926  map* l=getMap((*in)->content,"length");
927  bool shouldClean=false;
928  if(l==NULL){
929    l=createMap("length","1");
930    shouldClean=true;
931  }
932  int len=strtol(l->value,NULL,10);
933  int i=0;
934  for(i=0;i<len;i++){
935
936    // Create and fill arg map
937    arg=createMap("POINTS","");
938    map* v=getMapArray((*in)->content,"cache_file",i);
939    if(v!=NULL)
940      addToMap(arg,"FILES",v->value);
941
942    // Create the output maps
943    maps* louts=(maps*)malloc(MAPS_SIZE);
944    louts->name=zStrdup("POINTS");
945    louts->content=createMap("mimeType","UNKOWN");
946    louts->next=NULL;
947
948    // Execute the saga command
949    sagaExecuteCmd(conf,"io_shapes_las","1",arg,&louts);
950
951    // Fetch result and add it to the original map as saga_value
952    map* tmp=getMapFromMaps(louts,"POINTS","generated_file");
953    setMapArray((*in)->content,"saga_value",i,tmp->value);
954
955    // Cleanup
956    freeMaps(&louts);
957    free(louts);
958    freeMap(&arg);
959    free(arg);
960
961  }
962  // Cleanup if required
963  if(shouldClean){
964    freeMap(&l);
965    free(l);
966  }
967}
968
969/**
970 * Load and invoke a SAGA-GIS module defined in a service metadata definitions.
971 * Load all the input data into SAGA-GIS using io_gdal, io_tables and
972 * io_shapes_las for SAGA grids/shapes, tables and pointcloud respectively.
973 * Load and run the module from its library and invoke it using the data
974 * imported in SAGA-GIS at first stage. After the execution, export the outputs
975 * to files using io_gdal and io_shapes_las for grids/shapes and pointcloud
976 * respectively.
977 *
978 * @param main_conf the conf maps containing the main.cfg settings
979 * @param request the map containing the HTTP request
980 * @param s the service structure
981 * @param inputs the maps containing the inputs
982 * @param outputs the maps containing the outputs
983 */
984int zoo_saga_support(maps** main_conf,map* request,service* s,maps** inputs,maps** outputs){
985  int res=SERVICE_FAILED;
986  if( !wxInitialize() ){
987    fprintf(stderr,"initialisation failed");
988    return SERVICE_FAILED;
989  }
990  setlocale(LC_NUMERIC, "C");
991  static bool g_bShow_Messages = false;
992
993  dumpMapsValuesToFiles(main_conf,inputs);
994
995  SagaWatcher watcher=SagaWatcher();
996  watcher.SetConf(main_conf);
997
998  SG_Set_UI_Callback(Get_Callback(watcher));
999
1000  int n = SG_Get_Module_Library_Manager().Add_Directory(wxT(MODULE_LIBRARY_PATH),false);
1001  if( SG_Get_Module_Library_Manager().Get_Count() <= 0 ){
1002    setMapInMaps(*main_conf,"lenv","message","Could not load any SAGA tool library");
1003    res=SERVICE_FAILED;
1004    return res;
1005  }
1006
1007  map* serviceProvider=getMap(s->content,"serviceProvider");
1008
1009  // Load the SAGA-GIS library corresponding to the serviceProvider
1010  CSG_Module_Library * library=SG_Get_Module_Library_Manager().Get_Library(CSG_String(serviceProvider->value),true);
1011  if( library == NULL){
1012    char tmp[255];
1013    sprintf(tmp,"Counld not load the %s SAGA library",serviceProvider->value);
1014    setMapInMaps(*main_conf,"lenv","message",tmp);
1015    res=SERVICE_FAILED;
1016    return res;
1017  }
1018 
1019  // Load the SAGA-GIS module corresponding to the service name from the library
1020  CSG_Module * module=library->Get_Module(atoi(s->name));
1021  if(module == NULL){
1022    char tmp[255];
1023    sprintf(tmp,"Counld not load the %s module from the %s SAGA library",
1024            s->name,serviceProvider->value);
1025    setMapInMaps(*main_conf,"lenv","message",tmp);
1026    res=SERVICE_FAILED;
1027    return res;
1028  }
1029
1030  // Load all the parameters defined for the module
1031  CSG_Parameters * params=module->Get_Parameters();
1032  int pc=params->Get_Count();
1033  if(!params){
1034    char tmp[255];
1035    sprintf(tmp,"Counld not find any param for the %s module from the %s SAGA library",
1036            s->name,serviceProvider->value);
1037    setMapInMaps(*main_conf,"lenv","message",tmp);
1038    res=SERVICE_FAILED;
1039    return res;
1040  }
1041
1042  // Loop over each inputs to transform raster files to grid when needed,
1043  // import tables, shapes or point clouds
1044  for(int k=0;k<pc;k++){
1045    CSG_Parameter * param=params->Get_Parameter(k);
1046    if(param!=NULL && !param->is_Output()){
1047      maps* inmap=getMaps(*inputs,CSG_String(param->Get_Identifier()).b_str());
1048      if(inmap!=NULL){
1049        map* tmp=getMap(inmap->content,"value");
1050        if(tmp==NULL || strncasecmp(tmp->value,"NULL",4)!=0){
1051          if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("grid"))){
1052            sagaImportGDAL(main_conf,&inmap);
1053          }
1054          else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
1055            sagaImportOGR(main_conf,&inmap);
1056            sagaImportTIN(main_conf,&inmap);
1057          }
1058          else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes"))){
1059            sagaImportOGR(main_conf,&inmap);
1060          }
1061          else{
1062            if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
1063              sagaImportTable(main_conf,&inmap);
1064            }
1065            else
1066              if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("points"))){
1067                sagaImportPC(main_conf,&inmap);
1068              }
1069          }
1070        }
1071      }
1072    }
1073  }
1074
1075  // Create a map conraining arguments to pass to the SAGA-GIS module
1076  // Fetch all input value (specifically for data imported into SAGA-GIS)
1077  maps* inp=*inputs;
1078  int k=0;
1079  map* cParams=NULL;
1080  while(inp!=NULL){
1081    map* len=getMap(inp->content,"length");
1082    bool shouldClean=false;
1083    if(len==NULL){
1084      len=createMap("length","1");
1085      shouldClean=true;
1086    }
1087    int len0=strtol(len->value,NULL,10);
1088    int i=0;
1089    char *cinput=NULL;
1090    int clen=0;
1091    for(i=0;i<len0;i++){
1092      map* val=getMapArray(inp->content,"saga_value",i);
1093      if(val==NULL)
1094        val=getMapArray(inp->content,"value",i);
1095      if(val!=NULL && strncasecmp(val->value,"NULL",4)!=0){
1096        if(cinput==NULL){
1097          cinput=zStrdup(val->value);
1098        }
1099        else{
1100          cinput=(char*)realloc(cinput,(clen+strlen(val->value)+1)*sizeof(char));
1101          strncpy(&cinput[0]+clen,";",1);
1102          strncpy(&cinput[0]+(clen+1),val->value,strlen(val->value));
1103          clen+=1;
1104        }
1105        clen+=strlen(val->value);
1106        cinput[clen]=0;
1107      }
1108    }
1109    if(cinput!=NULL && strncasecmp(cinput,"NULL",4)!=0){
1110      if(cParams==NULL)
1111        cParams=createMap(inp->name,cinput);
1112      else
1113        addToMap(cParams,inp->name,cinput);
1114      free(cinput);
1115    }
1116    inp=inp->next;
1117  }
1118
1119  // Fetch all output and define a resulting filename
1120  inp=*outputs;
1121  map* tmpPath=getMapFromMaps(*main_conf,"main","tmpPath");
1122  map* sid=getMapFromMaps(*main_conf,"lenv","usid");
1123  while(inp!=NULL){
1124    for(int k=0;k<pc;k++){
1125      CSG_Parameter * param=params->Get_Parameter(k);
1126      if(CSG_String(param->Get_Identifier()).Cmp(inp->name)==0){
1127        const char *file_ext=sagaGetDefaultExt(param);
1128        char *fileName=(char*)malloc((strlen(file_ext)+strlen(sid->value)+strlen(inp->name)+strlen(tmpPath->value)+11)*sizeof(char));
1129        sprintf(fileName,"%s/Output_%s_%s.%s",tmpPath->value,inp->name,sid->value,file_ext);
1130        if(cParams==NULL)
1131          cParams=createMap(inp->name,fileName);
1132        else
1133          addToMap(cParams,inp->name,fileName);
1134      }
1135    }
1136    inp=inp->next;
1137  }
1138
1139  sagaSetParameters(params,cParams);
1140
1141  module->Update_Parameter_States();
1142 
1143  bool retval=false;
1144  if(module->On_Before_Execution()){
1145    retval=module->Execute();
1146    module->On_After_Execution();
1147  }
1148
1149  sagaSaveOutputs(params,*main_conf,outputs);
1150
1151  // Loop over each outputs to transform grid to raster file when needed,
1152  // export tables, shapes or point clouds
1153  for(int k=0;k<pc;k++){
1154    CSG_Parameter * param=params->Get_Parameter(k);
1155    if(param!=NULL && param->is_Output()){
1156      maps* inmap=getMaps(*outputs,CSG_String(param->Get_Identifier()).b_str());
1157      if(inmap!=NULL){
1158        if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("grid"))
1159           || CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("data_object"))){
1160          sagaExportGDAL(main_conf,&inmap);
1161        }else{
1162          if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes"))){
1163            sagaExportOGR(main_conf,&inmap);
1164          }
1165          else{
1166            if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
1167            }
1168            else{
1169              if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
1170                sagaExportTIN(main_conf,&inmap,"TIN");
1171              }
1172              else
1173                if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("points"))){
1174                  sagaExportPC(main_conf,&inmap);
1175              }
1176            }
1177          }
1178        }
1179      }
1180      else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
1181        sagaExportTIN(main_conf,outputs,CSG_String(param->Get_Identifier()).b_str());
1182      }
1183             
1184    }
1185  }
1186
1187  wxUninitialize();
1188
1189  return SERVICE_SUCCEEDED;
1190}
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