source: trunk/thirds/zcfg2sql/zcfg2sql.c @ 917

Last change on this file since 917 was 903, checked in by djay, 6 years ago

Fix issue with UOM definitions

  • Property svn:keywords set to Id
File size: 17.6 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 *  Copyright (c) 2017-2019 GeoLabs SARL. All rights reserved.
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 "service.h"
26
27extern int getServiceFromFile (maps *, const char *, service **);
28
29/**
30 * Dump an elements on stderr using the SQL syntaxe
31 *
32 * @param e the elements to dump
33 */
34void dumpElementsAsSQL(const char* type,elements* e,int index,int level,FILE* f){
35  elements* tmp=e;
36  int i;
37  while(tmp!=NULL){
38    fprintf(f,"--\n-- %s %s \n--\n",type,tmp->name);
39    map* mcurs=tmp->content;
40    iotype* tmpio=tmp->defaults;
41    int ioc=0;
42    if(tmp->format!=NULL){
43      //fprintf(stderr,"%s:\n",tmp->format);
44      if(strncmp(tmp->format,"Complex",7)==0){
45        while(tmpio!=NULL){
46          map* values[3]={
47            getMap(tmpio->content,"mimeType"),
48            getMap(tmpio->content,"encoding"),
49            getMap(tmpio->content,"schema")
50          };
51          char cond[3][256]={
52            "mime_type is NULL",
53            "encoding is NULL",
54            "schema is NULL"
55          };
56          char *condNames[3]={
57            "mime_type",
58            "encoding",
59            "schema"
60          };
61          for(i=0;i<3;i++)
62            if(values[i]!=NULL){
63              sprintf(cond[i],"%s='%s'",condNames[i],values[i]->value);
64            }
65          fprintf(f,"INSERT INTO CollectionDB.ows_Format"
66                  " (def,primitive_format_id) VALUES \n(true,");
67          fprintf(f,"(SELECT id from CollectionDB.PrimitiveFormats"
68                  " WHERE %s AND %s AND %s));\n",cond[0],cond[1],cond[2]);
69          fprintf(f,"INSERT INTO CollectionDB.ows_DataDescription (format_id)"
70                  " VALUES ((SELECT last_value FROM CollectionDB.ows_Format_id_seq));\n");
71          tmpio=tmpio->next;
72          ioc++;
73        }
74      }else{
75        if(strncmp(tmp->format,"Literal",7)==0){
76          while(tmpio!=NULL){
77            map* values[4]={
78              getMap(tmpio->content,"dataType"),
79              getMap(tmpio->content,"value"),
80              getMap(tmpio->content,"uom"),
81              getMap(tmpio->content,"AllowedValues")
82            };
83            char *fields[20]={
84              "default_value",
85              "def"
86            };
87            fprintf(f,"INSERT INTO CollectionDB.LiteralDataDomain"
88                    " (def,data_type_id) VALUES \n(true,");
89            fprintf(f,"(SELECT id from CollectionDB.PrimitiveDatatypes"
90                    " where name = '%s'));\n",values[0]->value);
91            if(values[1]!=NULL)
92              fprintf(f,"UPDATE CollectionDB.LiteralDataDomain \n"
93                      "set %s = $q$%s$q$ \n WHERE id = \n"
94                      "  ((SELECT last_value FROM CollectionDB.ows_DataDescription_id_seq));\n ",
95                      fields[0],values[1]->value);
96            if(values[2]!=NULL)
97              fprintf(f,"UPDATE CollectionDB.LiteralDataDomain \n"
98                      "set uom = (SELECT id from CollectionDB.PrimitiveUOM WHERE uom=$q$%s$q$) \n WHERE id = \n"
99                      "  (SELECT last_value FROM CollectionDB.ows_DataDescription_id_seq);\n ",
100                      values[2]->value);
101            if(values[3]!=NULL){
102              char *tmp=strtok(values[3]->value,",");
103              while(tmp!=NULL){
104                fprintf(f,"INSERT INTO CollectionDB.AllowedValues (allowed_value) VALUES ('%s');\n",tmp);
105                fprintf(f,"INSERT INTO CollectionDB.AllowedValuesAssignment"
106                        " (allowed_value_id,literal_data_domain_id) VALUES "
107                        "((SELECT last_value FROM CollectionDB.AllowedValues_id_seq),"
108                        "(SELECT last_value FROM CollectionDB.ows_DataDescription_id_seq));\n",tmp);
109                tmp=strtok(NULL,",");
110              }
111            }
112            tmpio=tmpio->next;
113            ioc++;
114          }       
115        }
116      }
117
118    }
119   
120    map* values[4]={
121      getMap(tmp->content,"Title"),
122      getMap(tmp->content,"Abstract"),
123      getMap(tmp->content,"minOccurs"),
124      getMap(tmp->content,"maxOccurs")
125    };
126    char *toto=",min_occurs,max_occurs";
127    if(strcmp(type,"Input")==0){
128      fprintf(f,"INSERT INTO CollectionDB.ows_Input "
129              "(identifier,title,abstract,min_occurs,max_occurs)"
130              " VALUES "
131              "($q$%s$q$,\n$q$%s$q$,\n$q$%s$q$,\n%s,\n%s);\n",
132              tmp->name,
133              values[0]->value,
134              values[1]->value,
135              values[2]->value,
136              values[3]->value
137              );
138      if(tmp->format!=NULL)
139        fprintf(f,"INSERT INTO CollectionDB.InputDataDescriptionAssignment"
140                " (input_id,data_description_id) VALUES "
141                "((select last_value as id "
142                "from CollectionDB.Descriptions_id_seq),"
143                "(select last_value "
144                "from CollectionDB.ows_DataDescription_id_seq));\n");
145      if(level==0)
146        fprintf(f,"INSERT INTO CollectionDB.ProcessInputAssignment"
147                "(process_id,input_id)"
148                " VALUES"
149                "((select id from pid),"
150                "(select last_value as id from CollectionDB.Descriptions_id_seq));\n");
151      else
152        fprintf(f,"INSERT INTO CollectionDB.InputInputAssignment"
153                "(parent_input,child_input)"
154                " VALUES"
155                "((select id from cid_%d),"
156                "(select last_value as id from CollectionDB.Descriptions_id_seq));\n",level-1);
157    }
158    else{
159      fprintf(f,"INSERT INTO CollectionDB.ows_Output\n"
160              "\t(identifier,title,abstract)\n"
161              "\t VALUES \n"
162              "($q$%s$q$,$q$%s$q$,$q$%s$q$);\n",
163              tmp->name,
164              values[0]->value,
165              values[1]->value
166              );
167      if(tmp->format!=NULL)
168        fprintf(f,"INSERT INTO CollectionDB.OutputDataDescriptionAssignment"
169                " (output_id,data_description_id) VALUES "
170                "((select last_value as id "
171                "from CollectionDB.Descriptions_id_seq),"
172                "(select last_value "
173                "from CollectionDB.ows_DataDescription_id_seq));\n");
174      if(level==0)
175        fprintf(f,"INSERT INTO CollectionDB.ProcessOutputAssignment"
176                "(process_id,output_id)"
177                " VALUES"
178                "((select id from pid),"
179                "(select last_value as id from CollectionDB.Descriptions_id_seq));\n");
180      else
181        fprintf(f,"INSERT INTO CollectionDB.OutputOutputAssignment"
182                "(parent_output,child_output)"
183                " VALUES"
184                "((select id from cid_%d),"
185                "(select last_value as id from CollectionDB.Descriptions_id_seq));\n",level-1);
186    }
187
188    map* mcurs1=tmp->metadata;
189    if(mcurs1!=NULL){
190      while(mcurs1!=NULL){
191        if(strncasecmp(mcurs1->name,"title",5)==0){
192          fprintf(stdout,"INSERT INTO CollectionDB.ows_Metadata (title) "
193                  "VALUES ($q$%s$q$);\n",mcurs->value);
194        tryagain0:
195          if(mcurs1->next!=NULL){
196            if(strncasecmp(mcurs->next->name,"role",4)==0){
197              fprintf(stdout,"UPDATE CollectionDB.ows_Metadata set role = \n"
198                      "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_Metadata_id_seq);\n",mcurs1->next->value);
199              mcurs1=mcurs1->next;
200              goto tryagain0;
201            }
202            else{
203              if(strncasecmp(mcurs1->next->name,"href",4)==0){
204                fprintf(stdout,"UPDATE CollectionDB.ows_Metadata set href = \n"
205                        "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_Metadata_id_seq);\n",mcurs1->next->value);
206                mcurs1=mcurs1->next;
207                goto tryagain0;
208              }
209            }
210          }
211          fprintf(stdout,"INSERT INTO CollectionDB.DescriptionsMetadataAssignment (descriptions_id,metadata_id) "
212                  "VALUES ((select last_value as id from CollectionDB.Descriptions_id_seq),"
213                  "(SELECT last_value FROM CollectionDB.ows_Metadata_id_seq));\n");       
214        }
215        mcurs1=mcurs1->next;
216      }
217    }
218    mcurs=tmp->additional_parameters;
219    if(mcurs!=NULL){
220      while(mcurs!=NULL){
221        if(strncasecmp(mcurs->name,"title",5)==0){
222          fprintf(stdout,"INSERT INTO CollectionDB.ows_AdditionalParameters (title) "
223                  "VALUES ($q$%s$q$);\n",mcurs->value);
224        tryagain:
225          if(mcurs->next!=NULL){
226            if(strncasecmp(mcurs->next->name,"role",4)==0){
227              fprintf(stdout,"UPDATE CollectionDB.ows_AdditionalParameters set role = \n"
228                      "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq);\n",mcurs->next->value);
229              mcurs=mcurs->next;
230              goto tryagain;
231            }
232            else{
233              if(strncasecmp(mcurs->next->name,"href",4)==0){
234                fprintf(stdout,"UPDATE CollectionDB.ows_AdditionalParameters set href = \n"
235                        "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq);\n",mcurs->next->value);
236                mcurs=mcurs->next;
237                goto tryagain;
238              }
239            }
240          }
241          fprintf(stdout,"INSERT INTO CollectionDB.DescriptionsAdditionalParametersAssignment (descriptions_id,additional_parameters_id) "
242                  "VALUES ((select last_value as id from CollectionDB.Descriptions_id_seq),"
243                  "(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq));\n");   
244        }else{
245          fprintf(stdout,"INSERT INTO CollectionDB.ows_AdditionalParameter (key,value,additional_parameters_id) "
246                  "VALUES ($q$%s$q$,$q$%s$q$,"
247                  "(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq));\n",mcurs->name,mcurs->value);         
248        }
249        mcurs=mcurs->next;
250      }
251    }
252
253    if(tmp->format!=NULL){
254      tmpio=tmp->supported;
255      if(strncmp(tmp->format,"Complex",7)==0){
256        while(tmpio!=NULL){
257          map* values[3]={
258            getMap(tmpio->content,"mimeType"),
259            getMap(tmpio->content,"encoding"),
260            getMap(tmpio->content,"schema")
261          };
262          char cond[3][256]={
263            "mime_type is NULL",           
264            "encoding is NULL",
265            "schema is NULL",
266          };
267          char *condNames[3]={
268            "mime_type",
269            "encoding",
270            "schema"
271          };
272          for(i=0;i<3;i++)
273            if(values[i]!=NULL){
274              sprintf(cond[i],"%s='%s'",condNames[i],values[i]->value);
275            }
276          fprintf(f,"INSERT INTO CollectionDB.ows_Format"
277                  " (def,primitive_format_id) VALUES \n(false,");
278          fprintf(f,"(SELECT id from CollectionDB.PrimitiveFormats"
279                  " WHERE %s AND %s AND %s));\n",cond[0],cond[1],cond[2]);
280          fprintf(f,"INSERT INTO CollectionDB.ows_DataDescription (format_id)"
281                  " VALUES ((SELECT last_value FROM CollectionDB.ows_Format_id_seq));\n");
282          fprintf(f,"INSERT INTO CollectionDB.%sDataDescriptionAssignment"
283                  " (%s_id,data_description_id) VALUES "
284                  "((select last_value as id "
285                  "from CollectionDB.Descriptions_id_seq),"
286                  "(select last_value "
287                  "from CollectionDB.ows_DataDescription_id_seq));\n",
288                  type,type);     
289          tmpio=tmpio->next;
290          ioc++;
291        }
292      }else{
293        if(strncmp(tmp->format,"Literal",7)==0){
294          while(tmpio!=NULL){
295            map* values[4]={
296              getMap(tmpio->content,"dataType"),
297              getMap(tmpio->content,"value"),
298              getMap(tmpio->content,"uom"),
299              getMap(tmpio->content,"AllowedValues")
300            };
301            map* values0[4]={
302              getMap(tmp->defaults->content,"dataType"),
303              getMap(tmp->defaults->content,"value"),
304              getMap(tmp->defaults->content,"uom"),
305              getMap(tmp->defaults->content,"AllowedValues")
306            };
307            char *fields[20]={
308              "default_value",
309              "def"
310            };
311            fprintf(f,"INSERT INTO CollectionDB.LiteralDataDomain"
312                    " (def,data_type_id) VALUES \n(false,");
313            if(values[0]!=NULL)
314              fprintf(f,"(SELECT id from CollectionDB.PrimitiveDatatypes"
315                      " where name = '%s'));\n",values[0]->value);
316            else
317              fprintf(f,"(SELECT id from CollectionDB.PrimitiveDatatypes"
318                      " where name = '%s'));\n",values0[0]->value);
319            if(values[1]!=NULL)
320              fprintf(f,"UPDATE CollectionDB.LiteralDataDomain \n"
321                      "set %s = $q$%s$q$ \n WHERE id = \n"
322                      "  ((SELECT last_value FROM CollectionDB.ows_DataDescription_id_seq));\n ",
323                      fields[0],values[1]->value);
324            if(values[2]!=NULL)
325              fprintf(f,"UPDATE CollectionDB.LiteralDataDomain \n"
326                      "set uom = (SELECT id from CollectionDB.PrimitiveUOM WHERE uom=$q$%s$q$) \n WHERE id = \n"
327                      "  (SELECT last_value FROM CollectionDB.ows_DataDescription_id_seq);\n ",
328                      values[2]->value);
329            if(type!=NULL)
330            fprintf(f,"INSERT INTO CollectionDB.%sDataDescriptionAssignment"
331                    " (%s_id,data_description_id) VALUES "
332                    "((select last_value "
333                    "from CollectionDB.Descriptions_id_seq),"
334                    "(select last_value "
335                    "from CollectionDB.ows_DataDescription_id_seq));\n",
336                    type,type);   
337            tmpio=tmpio->next;
338            ioc++;
339          }       
340        }
341      }
342    }
343
344    if(tmp->format==NULL){
345      fprintf(f,"--\n-- Child %d \n--\n",level);
346      fprintf(f,"CREATE TEMPORARY TABLE cid_%d AS (select last_value as id from CollectionDB.Descriptions_id_seq) ;\n",level);
347      if(tmp->child!=NULL)
348        dumpElementsAsSQL(type,tmp->child,0,level+1,f);
349      fprintf(f,"DROP TABLE cid_%d;\n",level);
350      fprintf(f,"--\n-- End Child %d \n--\n",level);
351    }
352    tmp=tmp->next;
353  }
354}
355
356
357int main(int argc, char *argv[]) {
358  service* s=NULL;
359  maps *m=NULL;
360  char conf_file[1024];
361  snprintf(conf_file,1024,"%s",argv[1]);
362  s=(service*)malloc(SERVICE_SIZE);
363  if(s == NULL){
364    fprintf(stderr,"Unable to allocate memory");
365    return -1;
366  }
367  int t=getServiceFromFile(m,conf_file,&s);
368
369  fprintf(stdout,"--\n-- Load from %s %d \n--",__FILE__,__LINE__);
370  int i;
371  fprintf(stdout,"--\n-- Service %s\n--\n",s->name);
372  if(s->content!=NULL){
373    map* values[4]={
374      getMap(s->content,"Title"),
375      getMap(s->content,"Abstract"),
376      getMap(s->content,"serviceProvider"),
377      getMap(s->content,"serviceType")
378    };
379    fprintf(stdout,"INSERT INTO CollectionDB.zoo_DeploymentMetadata\n"
380            "(executable_name,service_type_id)\n"
381            "\nVALUES\n"
382            "($q$%s$q$,\n(SELECT id from CollectionDB.zoo_ServiceTypes WHERE service_type=$q$%s$q$));\n\n",
383            values[2]->value,
384            values[3]->value);
385    fprintf(stdout,"INSERT INTO CollectionDB.zoo_PrivateMetadata"
386            "(id) VALUES (default);\n"); 
387    fprintf(stdout,"INSERT INTO CollectionDB.PrivateMetadataDeploymentMetadataAssignment"
388            "(private_metadata_id,deployment_metadata_id) VALUES \n"
389            "((SELECT last_value FROM CollectionDB.zoo_PrivateMetadata_id_seq),\n"
390            "(SELECT last_value FROM CollectionDB.zoo_DeploymentMetadata_id_seq));\n");
391    fprintf(stdout,"INSERT INTO CollectionDB.ows_Process\n"
392            "(identifier,title,abstract,private_metadata_id,"
393            "availability)\n"
394            "\nVALUES\n"
395            "($q$%s$q$,\n$q$%s$q$,\n$q$%s$q$,(SELECT last_value FROM CollectionDB.PrivateMetadataDeploymentMetadataAssignment_id_seq),\ntrue);\n\n",
396            s->name,
397            values[0]->value,
398            values[1]->value);
399    fprintf(stdout,"CREATE TEMPORARY TABLE pid AS "
400            "(select last_value as id from CollectionDB.Descriptions_id_seq);\n");
401    map* mcurs=s->content;
402    //dumpMap(mcurs);
403    mcurs=s->metadata;
404    if(mcurs!=NULL){
405      while(mcurs!=NULL){
406        if(strncasecmp(mcurs->name,"title",5)==0){
407          fprintf(stdout,"INSERT INTO CollectionDB.ows_Metadata (title) "
408                  "VALUES ($q$%s$q$);\n",mcurs->value);
409        tryagain0:
410          if(mcurs->next!=NULL){
411            if(strncasecmp(mcurs->next->name,"role",4)==0){
412              fprintf(stdout,"UPDATE CollectionDB.ows_Metadata set role = \n"
413                      "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_Metadata_id_seq);\n",mcurs->next->value);
414              mcurs=mcurs->next;
415              goto tryagain0;
416            }
417            else{
418              if(strncasecmp(mcurs->next->name,"href",4)==0){
419                fprintf(stdout,"UPDATE CollectionDB.ows_Metadata set href = \n"
420                        "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_Metadata_id_seq);\n",mcurs->next->value);
421                mcurs=mcurs->next;
422                goto tryagain0;
423              }
424            }
425          }
426          fprintf(stdout,"INSERT INTO CollectionDB.DescriptionsMetadataAssignment (descriptions_id,metadata_id) "
427                  "VALUES ((select last_value as id from CollectionDB.Descriptions_id_seq),"
428                  "(SELECT last_value FROM CollectionDB.ows_Metadata_id_seq));\n");       
429        }
430        mcurs=mcurs->next;
431      }
432    }
433    mcurs=s->additional_parameters;
434    if(mcurs!=NULL){
435      while(mcurs!=NULL){
436        if(strncasecmp(mcurs->name,"title",5)==0){
437          fprintf(stdout,"INSERT INTO CollectionDB.ows_AdditionalParameters (title) "
438                  "VALUES ($q$%s$q$);\n",mcurs->value);
439        tryagain:
440          if(mcurs->next!=NULL){
441            if(strncasecmp(mcurs->next->name,"role",4)==0){
442              fprintf(stdout,"UPDATE CollectionDB.ows_AdditionalParameters set role = \n"
443                      "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq);\n",mcurs->next->value);
444              mcurs=mcurs->next;
445              goto tryagain;
446            }
447            else{
448              if(strncasecmp(mcurs->next->name,"href",4)==0){
449                fprintf(stdout,"UPDATE CollectionDB.ows_AdditionalParameters set href = \n"
450                        "$q$%s$q$ where id=(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq);\n",mcurs->next->value);
451                mcurs=mcurs->next;
452                goto tryagain;
453              }
454            }
455          }
456          fprintf(stdout,"INSERT INTO CollectionDB.DescriptionsAdditionalParametersAssignment (descriptions_id,additional_parameters_id) "
457                  "VALUES ((select last_value as id from CollectionDB.Descriptions_id_seq),"
458                  "(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq));\n");   
459        }else{
460          fprintf(stdout,"INSERT INTO CollectionDB.ows_AdditionalParameter (key,value,additional_parameters_id) "
461                  "VALUES ($q$%s$q$,$q$%s$q$,"
462                  "(SELECT last_value FROM CollectionDB.ows_AdditionalParameters_id_seq));\n",mcurs->name,mcurs->value);         
463        }
464        mcurs=mcurs->next;
465      }
466    }
467   
468  }
469  if(s->inputs!=NULL){
470    //fprintf(stderr,"\ninputs:\n");
471    dumpElementsAsSQL("Input",s->inputs,0,0,stdout);
472  }
473  if(s->outputs!=NULL){
474    //fprintf(stderr,"\noutputs:\n");
475    dumpElementsAsSQL("Output",s->outputs,0,0,stdout);
476  }
477  fprintf(stdout,"--\n-- Load from %s %d \n--",__FILE__,__LINE__);
478
479 
480 
481  /*fprintf(stderr,"--\n-- Load from %s %d \n--",__FILE__,__LINE__);
482  fflush(stderr);
483  printf("--\n-- Load from %s %d \n--",__FILE__,__LINE__);
484  if(t>=0){
485    fprintf(stderr,"--\n-- Service %s\n--",s->name);
486    fflush(stderr);
487    dumpServiceAsSQL(s);
488    fprintf(stderr,"--\n-- Service %s\n--",s->name);
489    fflush(stderr);
490  }
491  */
492  fflush(stderr);
493  return 0;
494}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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