source: trunk/zoo-project/zoo-kernel/service_internal_ms.c @ 379

Last change on this file since 379 was 379, checked in by djay, 11 years ago

Fix handling of multiple outputs. Small fix to build with bleeding edge gcc. Add missing copyright in service_internal_ms.c/h. Better gesture of session data. Update HISTORY.txt content.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 33.6 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2010-2011 Fondazione Edmund Mach. 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#ifdef USE_MS
26#ifndef WIN32
27#define CLASS class
28#else
29#define CLASS _class
30#endif
31#include "service_internal_ms.h"
32
33/**
34 * Map composed by a main.cfg maps name as key and the corresponding
35 * MapServer Mafile Metadata name to use
36 * see doc from here :
37 *  - http://mapserver.org/ogc/wms_server.html
38 *  - http://mapserver.org/ogc/wfs_server.html
39 *  - http://mapserver.org/ogc/wcs_server.html
40 */
41map* getCorrespondance(){
42  map* res=createMap("encoding","ows_encoding");
43  addToMap(res,"abstract","ows_abstract");
44  addToMap(res,"title","ows_title");
45  addToMap(res,"keywords","ows_keywordlist");
46  addToMap(res,"fees","ows_fees");
47  addToMap(res,"accessConstraints","ows_accessconstraints");
48  addToMap(res,"providerName","ows_attribution_title");
49  addToMap(res,"providerSite","ows_service_onlineresource");
50  addToMap(res,"individualName","ows_contactperson");
51  addToMap(res,"positionName","ows_contactposition");
52  addToMap(res,"providerName","ows_contactorganization");
53  addToMap(res,"role","ows_role");
54  addToMap(res,"addressType","ows_addresstype");
55  addToMap(res,"addressCity","ows_city");
56  addToMap(res,"addressDeliveryPoint","ows_address");
57  addToMap(res,"addressPostalCode","ows_postcode");
58  addToMap(res,"addressAdministrativeArea","ows_stateorprovince");
59  addToMap(res,"addressCountry","ows_country");
60  addToMap(res,"phoneVoice","ows_contactvoicetelephone");
61  addToMap(res,"phoneFacsimile","ows_contactfacsimiletelephone");
62  addToMap(res,"addressElectronicMailAddress","ows_contactelectronicmailaddress");
63  // Missing Madatory Informations
64  addToMap(res,"hoursOfService","ows_hoursofservice");
65  addToMap(res,"contactInstructions","ows_contactinstructions");
66  return res;
67}
68
69void setMapSize(maps* output,double minx,double miny,double maxx,double maxy){
70  double maxWidth=640;
71  double maxHeight=480;
72  double deltaX=maxx-minx;
73  double deltaY=maxy-miny;
74  double qWidth;
75  qWidth=maxWidth/deltaX;
76  double qHeight;
77  qHeight=maxHeight/deltaY;
78#ifdef DEBUGMS
79  fprintf(stderr,"deltaX : %.15f \ndeltaY : %.15f\n",deltaX,deltaY);
80  fprintf(stderr,"qWidth : %.15f \nqHeight : %.15f\n",qWidth,qHeight);
81#endif
82
83  double width=deltaX*qWidth;
84  double height=height=deltaY*qWidth;
85  if(deltaX<deltaY){
86    width=deltaX*qHeight;
87    height=deltaY*qHeight;
88  }
89  if(height<0)
90    height=-height;
91  if(width<0)
92    width=-width;
93  char sWidth[1024];
94  char sHeight[1024];
95  sprintf(sWidth,"%.3f",width);
96  sprintf(sHeight,"%.3f",height);
97#ifdef DEBUGMS
98  fprintf(stderr,"sWidth : %.15f \nsHeight : %.15f\n",sWidth,sHeight);
99#endif
100  if(output!=NULL){
101    addToMap(output->content,"width",sWidth);
102    addToMap(output->content,"height",sHeight);
103  }
104}
105
106void setReferenceUrl(maps* m,maps* tmpI){
107  //dumpMaps(tmpI);
108  outputMapfile(m,tmpI);
109  map *msUrl=getMapFromMaps(m,"main","mapserverAddress");
110  map *msOgcVersion=getMapFromMaps(m,"main","msOgcVersion");
111  map *dataPath=getMapFromMaps(m,"main","dataPath");
112  map *sid=getMapFromMaps(m,"lenv","sid");
113  map* format=getMap(tmpI->content,"mimeType");
114  map* rformat=getMap(tmpI->content,"requestedMimeType");
115  map* width=getMap(tmpI->content,"width");
116  map* height=getMap(tmpI->content,"height");
117  map* protoMap=getMap(tmpI->content,"msOgc");
118  map* versionMap=getMap(tmpI->content,"msOgcVersion");
119  char options[3][5][25]={
120    {"WMS","1.3.0","GetMap","layers=%s","wms_extent"},
121    {"WFS","1.1.0","GetFeature","typename=%s","wms_extent"},
122    {"WCS","1.1.0","GetCoverage","coverage=%s","wcs_extent"}
123  };
124  int proto=0;
125  if(rformat==NULL){
126    rformat=getMap(tmpI->content,"mimeType");
127  }
128  if(strncasecmp(rformat->value,"text/xml",8)==0)
129    proto=1;
130  if(strncasecmp(rformat->value,"image/tiff",10)==0)
131    proto=2;
132  if(protoMap!=NULL)
133    if(strncasecmp(protoMap->value,"WMS",3)==0)
134      proto=0;
135    else if(strncasecmp(protoMap->value,"WFS",3)==0)
136      proto=1;
137    else 
138      proto=2;
139 
140  char *protoVersion=options[proto][1];
141  if(proto==1){
142    if(msOgcVersion!=NULL)
143      protoVersion=msOgcVersion->value;
144    if(versionMap!=NULL)
145      protoVersion=versionMap->value;
146  }
147
148  map* extent=getMap(tmpI->content,options[proto][4]);
149  map* crs=getMap(tmpI->content,"crs");
150  char layers[128];
151  sprintf(layers,options[proto][3],tmpI->name);
152
153  char* webService_url=(char*)malloc((strlen(msUrl->value)+strlen(format->value)+strlen(tmpI->name)+strlen(width->value)+strlen(height->value)+strlen(extent->value)+256)*sizeof(char));
154
155  if(proto>0){
156    sprintf(webService_url,
157            "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
158            msUrl->value,
159            dataPath->value,
160            tmpI->name,
161            sid->value,
162            options[proto][2],
163            options[proto][0],
164            protoVersion,
165            layers,
166            rformat->value,
167            extent->value,
168            crs->value
169            );
170  }
171  else{
172    sprintf(webService_url,
173            "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&width=%s&height=%s&format=%s&bbox=%s&crs=%s",
174            msUrl->value,
175            dataPath->value,
176            tmpI->name,
177            sid->value,
178            options[proto][2],
179            options[proto][0],
180            protoVersion,
181            layers,
182            width->value,
183            height->value,
184            rformat->value,
185            extent->value,
186            crs->value
187            );
188  }
189  addToMap(tmpI->content,"Reference",webService_url);
190
191}
192
193/**
194 * Set projection using Authority Code and Name if available or fallback to
195 * proj4 definition if available or fallback to default EPSG:4326
196 */
197void setSrsInformations(maps* output,mapObj* m,layerObj* myLayer,
198                        char* pszProjection){
199  OGRSpatialReferenceH  hSRS;
200  map* msSrs=NULL;
201  hSRS = OSRNewSpatialReference(NULL);
202  if( pszProjection!=NULL && strlen(pszProjection)>1 &&
203      OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ){
204    char *proj4Str=NULL;
205    if(OSRGetAuthorityName(hSRS,NULL)!=NULL && 
206       OSRGetAuthorityCode(hSRS,NULL)!=NULL){
207      char tmpSrs[20];
208      sprintf(tmpSrs,"%s:%s",
209              OSRGetAuthorityName(hSRS,NULL),OSRGetAuthorityCode(hSRS,NULL));
210      msLoadProjectionStringEPSG(&m->projection,tmpSrs);
211      msLoadProjectionStringEPSG(&myLayer->projection,tmpSrs);
212     
213      char tmpSrss[256];
214      sprintf(tmpSrss,"EPSG:4326 EPSG:900913 %s",tmpSrs);
215
216      msInsertHashTable(&(m->web.metadata), "ows_srs", tmpSrss);
217      msInsertHashTable(&(myLayer->metadata), "ows_srs", tmpSrss);
218
219#ifdef DEBUGMS
220      fprintf(stderr,"isGeo %b\n\n",OSRIsGeographic(hSRS)==TRUE);
221#endif
222      if(output!=NULL){
223        if(OSRIsGeographic(hSRS)==TRUE)
224          addToMap(output->content,"crs_isGeographic","true");
225        else
226          addToMap(output->content,"crs_isGeographic","false");
227        addToMap(output->content,"crs",tmpSrs);
228      }
229    }
230    else{
231      OSRExportToProj4(hSRS,&proj4Str);
232      if(proj4Str!=NULL){
233#ifdef DEBUGMS
234        fprintf(stderr,"PROJ (%s)\n",proj4Str);
235#endif
236        msLoadProjectionString(&(m->projection),proj4Str);
237        msLoadProjectionString(&(myLayer->projection),proj4Str);
238        if(output!=NULL){ 
239          if(OSRIsGeographic(hSRS)==TRUE)
240            addToMap(output->content,"crs_isGeographic","true");
241          else
242            addToMap(output->content,"crs_isGeographic","false");
243        }
244      }
245      else{
246        msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
247        msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
248        if(output!=NULL){
249          addToMap(output->content,"crs_isGeographic","true");
250        }
251      }
252      if(output!=NULL){
253        addToMap(output->content,"crs","EPSG:4326");
254        addToMap(output->content,"real_extent","true");
255      }
256      msInsertHashTable(&(m->web.metadata),"ows_srs", "EPSG:4326 EPSG:900913");
257      msInsertHashTable(&(myLayer->metadata),"ows_srs","EPSG:4326 EPSG:900913");
258
259
260    }
261  }
262  else{
263    if(output!=NULL){
264      msSrs=getMap(output->content,"msSrs");
265    }
266    if(msSrs!=NULL){
267      msLoadProjectionStringEPSG(&m->projection,msSrs->value);
268      msLoadProjectionStringEPSG(&myLayer->projection,msSrs->value);
269      char tmpSrs[128];
270      sprintf(tmpSrs,"%s EPSG:4326 EPSG:900913",msSrs);
271      msInsertHashTable(&(m->web.metadata),"ows_srs",tmpSrs);
272      msInsertHashTable(&(myLayer->metadata),"ows_srs",tmpSrs);
273    }else{
274      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
275      msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
276      msInsertHashTable(&(m->web.metadata),"ows_srs","EPSG:4326 EPSG:900913");
277      msInsertHashTable(&(myLayer->metadata),"ows_srs","EPSG:4326 EPSG:900913");
278    }
279    if(output!=NULL){
280      addToMap(output->content,"crs",msSrs->value);
281      addToMap(output->content,"crs_isGeographic","true");
282    }
283  }
284
285  OSRDestroySpatialReference( hSRS );
286}
287
288void setMsExtent(maps* output,mapObj* m,layerObj* myLayer,
289                 double minX,double minY,double maxX,double maxY){
290  msMapSetExtent(m,minX,minY,maxX,maxY);
291#ifdef DEBUGMS
292  fprintf(stderr,"Extent %.15f %.15f %.15f %.15f\n",minX,minY,maxX,maxY);
293#endif
294  char tmpExtent[1024];
295  sprintf(tmpExtent,"%.15f %.15f %.15f %.15f",minX,minY,maxX,maxY);
296#ifdef DEBUGMS
297  fprintf(stderr,"Extent %s\n",tmpExtent);
298#endif
299  msInsertHashTable(&(myLayer->metadata), "ows_extent", tmpExtent);
300 
301  if(output!=NULL){
302
303    map* test=getMap(output->content,"real_extent");
304    if(test!=NULL){
305      pointObj min, max;
306      projectionObj tempSrs;
307
308      min.x = m->extent.minx;
309      min.y = m->extent.miny;
310      max.x = m->extent.maxx;
311      max.y = m->extent.maxy;
312      char tmpSrsStr[1024];
313
314
315      msInitProjection(&tempSrs);
316      msLoadProjectionStringEPSG(&tempSrs,"EPSG:4326");
317
318      msProjectPoint(&(m->projection),&tempSrs,&min);
319      msProjectPoint(&m->projection,&tempSrs,&max);
320     
321      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
322      map* isGeo=getMap(output->content,"crs_isGeographic");
323      fprintf(stderr,"isGeo = %s\n",isGeo->value);
324      if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
325        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
326      addToMap(output->content,"wms_extent",tmpExtent);
327      sprintf(tmpSrsStr,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
328      addToMap(output->content,"wcs_extent",tmpExtent);
329      //dumpMap(output->content);
330
331    }else{
332      sprintf(tmpExtent,"%f,%f,%f,%f",minX, minY, maxX, maxY);
333      map* isGeo=getMap(output->content,"crs_isGeographic");
334      fprintf(stderr,"isGeo = %s\n",isGeo->value);
335      if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
336        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
337      addToMap(output->content,"wms_extent",tmpExtent); 
338      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",minX,minY,maxX,maxY);
339      addToMap(output->content,"wcs_extent",tmpExtent);
340     
341    }
342
343  }
344
345  setMapSize(output,minX,minY,maxX,maxY);
346}
347
348int tryOgr(maps* conf,maps* output,mapObj* m){
349
350  map* tmpMap=getMap(output->content,"storage");
351  char *pszDataSource=tmpMap->value;
352
353  /**
354   * Try to open the DataSource using OGR
355   */
356  OGRRegisterAll();
357  /**
358   * Try to load the file as ZIP
359   */
360
361  OGRDataSourceH poDS1 = NULL;
362  OGRSFDriverH *poDriver1 = NULL;
363  char *dsName=(char*)malloc((8+strlen(pszDataSource)+1)*sizeof(char));
364  char *odsName=strdup(pszDataSource);
365  char *sdsName=strdup(pszDataSource);
366  char *demo=strstr(odsName,".");
367  sdsName[strlen(sdsName)-(strlen(demo)-1)]='d';
368  sdsName[strlen(sdsName)-(strlen(demo)-2)]='i';
369  sdsName[strlen(sdsName)-(strlen(demo)-3)]='r';
370  sdsName[strlen(sdsName)-(strlen(demo)-4)]=0;
371
372  odsName[strlen(odsName)-(strlen(demo)-1)]='z';
373  odsName[strlen(odsName)-(strlen(demo)-2)]='i';
374  odsName[strlen(odsName)-(strlen(demo)-3)]='p';
375  odsName[strlen(odsName)-(strlen(demo)-4)]=0;
376  sprintf(dsName,"/vsizip/%s",odsName);
377
378#ifdef DEBUGMS
379  fprintf(stderr,"Try loading %s, %s, %s\n",dsName,odsName,dsName);
380#endif
381
382  FILE* file = fopen(pszDataSource, "rb");
383  FILE* fileZ = fopen(odsName, "wb");
384  fseek(file, 0, SEEK_END);
385  unsigned long fileLen=ftell(file);
386  fseek(file, 0, SEEK_SET);
387  char *buffer=(char *)malloc(fileLen+1);
388  fread(buffer, fileLen, 1, file);
389  fwrite(buffer,fileLen, 1, fileZ);
390  fclose(file);
391  fclose(fileZ);
392  free(buffer);
393  fprintf(stderr,"Try loading %s",dsName);
394  poDS1 = OGROpen( dsName, FALSE, poDriver1 );
395  if( poDS1 == NULL ){
396    fprintf(stderr,"Unable to access the DataSource as ZIP File\n");
397    setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
398    OGR_DS_Destroy(poDS1);
399  }else{
400    fprintf(stderr,"The DataSource is a  ZIP File\n");
401    char** demo=VSIReadDir(dsName);
402    int i=0;
403    mkdir(sdsName
404#ifndef WIN32
405                ,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
406#endif
407                );
408    while(demo[i]!=NULL){
409      fprintf(stderr,"ZIP File content : %s\n",demo[i]);
410      char *tmpDs=(char*)malloc((strlen(dsName)+strlen(demo[i])+2)*sizeof(char));
411      sprintf(tmpDs,"%s/%s",dsName,demo[i]);
412      fprintf(stderr,"read : %s\n",tmpDs);
413     
414      VSILFILE* vsif=VSIFOpenL(tmpDs,"rb");
415      fprintf(stderr,"open : %s\n",tmpDs);
416      VSIFSeekL(vsif,0,SEEK_END);
417      int size=VSIFTellL(vsif);
418      fprintf(stderr,"size : %d\n",size);
419      VSIFSeekL(vsif,0,SEEK_SET);
420      char *vsifcontent=(char*) malloc((size+1)*sizeof(char));
421      VSIFReadL(vsifcontent,1,size,vsif);
422      char *fpath=(char*) malloc((strlen(sdsName)+strlen(demo[1])+2)*sizeof(char));
423      sprintf(fpath,"%s/%s",sdsName,demo[i]);
424      int f=open(fpath,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
425      write(f,vsifcontent,size);
426      close(f);
427      chmod(fpath,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH);
428      char* tmpP=strstr(fpath,".shp");
429      if(tmpP==NULL)
430        tmpP=strstr(fpath,".SHP");
431      if(tmpP!=NULL){
432        fprintf(stderr,"*** DEBUG %s\n",strstr(tmpP,"."));
433        if( strcmp(tmpP,".shp")==0 || strcmp(tmpP,".SHP")==0 ){
434          tmpMap=getMap(output->content,"storage");
435          free(tmpMap->value);
436          tmpMap->value=(char*) malloc((strlen(fpath)+1)*sizeof(char));
437          sprintf(tmpMap->value,"%s",fpath);
438          pszDataSource=tmpMap->value;
439          fprintf(stderr,"*** DEBUG %s\n",pszDataSource);
440        }
441      }
442      VSIFCloseL(vsif);
443      i++;
444    }
445
446  }
447
448  OGRDataSourceH poDS = NULL;
449  OGRSFDriverH *poDriver = NULL;
450  poDS = OGROpen( pszDataSource, FALSE, poDriver );
451  if( poDS == NULL ){
452#ifdef DEBUGMS
453    fprintf(stderr,"Unable to access the DataSource %s\n",pszDataSource);
454#endif
455    setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
456    OGR_DS_Destroy(poDS);
457    OGRCleanupAll();
458#ifdef DEBUGMS
459    fprintf(stderr,"Unable to access the DataSource, exit! \n"); 
460#endif
461    return -1;
462  }
463
464  int iLayer = 0;
465  for( iLayer=0; iLayer < OGR_DS_GetLayerCount(poDS); iLayer++ ){
466    OGRLayerH poLayer = OGR_DS_GetLayer(poDS,iLayer);
467
468    if( poLayer == NULL ){
469#ifdef DEBUGMS
470      fprintf(stderr,"Unable to access the DataSource Layer \n");
471#endif
472      setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
473      return -1;
474    }
475
476    /**
477     * Add a new layer set name, data
478     */
479    if(msGrowMapLayers(m)==NULL){
480      return -1;
481    }
482    if(initLayer((m->layers[m->numlayers]), m) == -1){
483      return -1;
484    }
485
486    layerObj* myLayer=m->layers[m->numlayers];
487    dumpMaps(output);
488    myLayer->name = strdup(output->name);
489    myLayer->tileitem=NULL;
490    myLayer->data = strdup(OGR_L_GetName(poLayer));
491    myLayer->connection = strdup(pszDataSource);
492    myLayer->index = m->numlayers;
493    myLayer->dump = MS_TRUE;
494    myLayer->status = MS_ON;
495    msConnectLayer(myLayer,MS_OGR,pszDataSource);
496
497    /**
498     * Detect the Geometry Type or use Polygon
499     */
500    if(OGR_L_GetGeomType(poLayer) != wkbUnknown){
501      switch(OGR_L_GetGeomType(poLayer)){
502      case wkbPoint:
503      case wkbMultiPoint:
504      case wkbPoint25D:
505      case wkbMultiPoint25D:
506#ifdef DEBUGMS
507        fprintf(stderr,"POINT DataSource Layer \n");
508#endif
509        myLayer->type = MS_LAYER_POINT;
510        break;
511      case wkbLineString :
512      case wkbMultiLineString :
513      case wkbLineString25D:
514      case wkbMultiLineString25D:
515#ifdef DEBUGMS
516        fprintf(stderr,"LINE DataSource Layer \n");
517#endif
518        myLayer->type = MS_LAYER_LINE;
519        break;
520      case wkbPolygon:
521      case wkbMultiPolygon:
522      case wkbPolygon25D:
523      case wkbMultiPolygon25D:
524#ifdef DEBUGMS
525        fprintf(stderr,"POLYGON DataSource Layer \n");
526#endif
527        myLayer->type = MS_LAYER_POLYGON;
528        break;
529      default:
530        myLayer->type = MS_LAYER_POLYGON;
531        break;
532      }
533    }else
534      myLayer->type = MS_LAYER_POLYGON;
535
536    /**
537     * Detect spatial reference or use WGS84
538     */
539    OGRSpatialReferenceH srs=OGR_L_GetSpatialRef(poLayer);
540    if(srs!=NULL){
541      char *wkt=NULL;
542      OSRExportToWkt(srs,&wkt);
543      setSrsInformations(output,m,myLayer,wkt);
544    }
545    else{
546      addToMap(output->content,"crs","EPSG:4326");
547      addToMap(output->content,"crs_isGeographic","true");
548      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
549      msInsertHashTable(&(m->web.metadata), "ows_srs", "EPSG:4326 EPSG:900913");
550      msInsertHashTable(&(myLayer->metadata), "ows_srs", "EPSG:4326 EPSG:900913");
551    }
552
553    map* crs=getMap(output->content,"crs");
554    map* isGeo=getMap(output->content,"crs_isGeographic");
555
556    OGREnvelope oExt;
557    if (OGR_L_GetExtent(poLayer,&oExt, TRUE) == OGRERR_NONE){
558      setMsExtent(output,m,myLayer,oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY);
559    }
560 
561    /**
562     * Detect the FID column or use the first attribute field as FID
563     */
564    char *fid=(char*)OGR_L_GetFIDColumn(poLayer);
565    if(strlen(fid)==0){
566      OGRFeatureDefnH def=OGR_L_GetLayerDefn(poLayer);
567      int fIndex=0;
568      for(fIndex=0;fIndex<OGR_FD_GetFieldCount(def);fIndex++){
569        OGRFieldDefnH fdef=OGR_FD_GetFieldDefn(def,fIndex);
570        fid=(char*)OGR_Fld_GetNameRef(fdef);
571        break;
572      }
573    }
574    msInsertHashTable(&(myLayer->metadata), "gml_featureid", fid);
575    msInsertHashTable(&(myLayer->metadata), "gml_include_items", "all");
576    msInsertHashTable(&(myLayer->metadata), "ows_name", output->name);
577    map* tmpMap=getMap(output->content,"title");
578    if(tmpMap!=NULL)
579      msInsertHashTable(&(myLayer->metadata), "ows_title", tmpMap->value);
580    else
581      msInsertHashTable(&(myLayer->metadata), "ows_title", "Default Title");
582   
583    if(msGrowLayerClasses(myLayer) == NULL)
584      return -1;
585    if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
586      return -1;
587    myLayer->CLASS[myLayer->numclasses]->type = myLayer->type;
588    if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
589      return -1;
590    if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
591      return -1;
592    /**
593     * Apply msStyle else fallback to the default style
594     */
595    tmpMap=getMap(output->content,"msStyle");
596    if(tmpMap!=NULL)
597      msUpdateStyleFromString(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles],tmpMap->value,0);
598    else{
599      /**
600       * Set style
601       */
602      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=125;
603      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=125;
604      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=255;
605      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.red=80;
606      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.green=80;
607      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.blue=80;
608     
609      /**
610       * Set specific style depending on type
611       */
612      if(myLayer->type == MS_LAYER_POLYGON)
613        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->width=3;
614      if(myLayer->type == MS_LAYER_LINE){
615        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->width=3;
616        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinewidth=1.5;
617      }
618      if(myLayer->type == MS_LAYER_POINT){
619        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->symbol=1;
620        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->size=15;
621      }
622     
623    }
624    myLayer->CLASS[myLayer->numclasses]->numstyles++;
625    myLayer->numclasses++;
626   
627    m->layerorder[m->numlayers] = m->numlayers;
628    m->numlayers++;
629
630  }
631
632  OGR_DS_Destroy(poDS);
633  OGRCleanupAll();
634
635  return 1;
636}
637
638
639int tryGdal(maps* conf,maps* output,mapObj* m){
640  map* tmpMap=getMap(output->content,"storage");
641  char *pszFilename=tmpMap->value;
642  GDALDatasetH hDataset;
643  GDALRasterBandH hBand;
644  double adfGeoTransform[6];
645  int i, iBand;
646 
647  /**
648   * Try to open the DataSource using GDAL
649   */
650  GDALAllRegister();
651  hDataset = GDALOpen( pszFilename, GA_ReadOnly );
652  if( hDataset == NULL ){
653#ifdef DEBUGMS
654    fprintf(stderr,"Unable to access the DataSource %s \n",pszFilename);
655#endif
656    setMapInMaps(conf,"lenv","message","gdalinfo failed - unable to open");
657    GDALDestroyDriverManager();
658    return -1;
659  }
660#ifdef DEBUGMS
661    fprintf(stderr,"Accessing the DataSource %s %d\n",pszFilename,__LINE__);
662#endif
663
664  /**
665   * Add a new layer set name, data
666   */
667  if(msGrowMapLayers(m)==NULL){
668    return -1;
669  }
670  if(initLayer((m->layers[m->numlayers]), m) == -1){
671    return -1;
672  }
673
674  layerObj* myLayer=m->layers[m->numlayers];
675  myLayer->name = strdup(output->name);
676  myLayer->tileitem=NULL;
677  myLayer->data = strdup(pszFilename);
678  myLayer->index = m->numlayers;
679  myLayer->dump = MS_TRUE;
680  myLayer->status = MS_ON;
681  myLayer->type = MS_LAYER_RASTER;
682
683  char *title=output->name;
684  tmpMap=getMap(output->content,"title");
685  if(tmpMap!=NULL)
686    title=tmpMap->value;
687  char *abstract=output->name;
688  tmpMap=getMap(output->content,"abstract");
689  if(tmpMap!=NULL)
690    abstract=tmpMap->value;
691  msInsertHashTable(&(myLayer->metadata), "ows_label", title);
692  msInsertHashTable(&(myLayer->metadata), "ows_title", title);
693  msInsertHashTable(&(myLayer->metadata), "ows_abstract", abstract);
694  msInsertHashTable(&(myLayer->metadata), "ows_rangeset_name", output->name);
695  msInsertHashTable(&(myLayer->metadata), "ows_rangeset_label", title);
696
697  /**
698   * Set Map Size to the raster size
699   */
700  m->width=GDALGetRasterXSize( hDataset );
701  m->height=GDALGetRasterYSize( hDataset );
702 
703  /**
704   * Set projection using Authority Code and Name if available or fallback to
705   * proj4 definition if available or fallback to default EPSG:4326
706   */
707  const char *tRef=GDALGetProjectionRef( hDataset );
708  if( tRef != NULL && strlen(tRef)>0 ){
709    OGRSpatialReferenceH  hSRS;
710    char *pszProjection;
711    pszProjection = (char *) GDALGetProjectionRef( hDataset );
712#ifdef DEBUGMS
713    fprintf(stderr,"Accessing the DataSource %s\n",GDALGetProjectionRef( hDataset ));
714#endif
715    setSrsInformations(output,m,myLayer,pszProjection);
716    }
717
718
719  /**
720   * Set extent
721   */
722  if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ){
723    if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ){
724
725      double minX = adfGeoTransform[0]
726        + adfGeoTransform[2] * GDALGetRasterYSize(hDataset);
727      double minY = adfGeoTransform[3]
728        + adfGeoTransform[5] * GDALGetRasterYSize(hDataset);
729
730      double maxX = adfGeoTransform[0]
731        + adfGeoTransform[1] * GDALGetRasterXSize(hDataset);
732      double maxY = adfGeoTransform[3]
733        + adfGeoTransform[4] * GDALGetRasterXSize(hDataset);
734
735       setMsExtent(output,m,myLayer,minX,minY,maxX,maxY);
736
737    }
738  }
739
740  /**
741   * Extract information about available bands to set the bandcount and the
742   * processing directive
743   */
744  char nBands[2];
745  int nBandsI=GDALGetRasterCount( hDataset );
746  sprintf(nBands,"%d",GDALGetRasterCount( hDataset ));
747  msInsertHashTable(&(myLayer->metadata), "ows_bandcount", nBands);
748  if(nBandsI>=3)
749    msLayerAddProcessing(myLayer,"BANDS=1,2,3");
750  else if(nBandsI>=2)
751    msLayerAddProcessing(myLayer,"BANDS=1,2");
752  else
753    msLayerAddProcessing(myLayer,"BANDS=1");
754
755  /**
756   * Name available Bands
757   */
758  char lBands[6];
759  char *nameBands=NULL;
760  for( iBand = 0; iBand < nBandsI; iBand++ ){
761    sprintf(lBands,"Band%d",iBand+1);
762    if(nameBands==NULL){
763      nameBands=(char*)malloc((strlen(lBands)+1)*sizeof(char));
764      sprintf(nameBands,"%s",lBands);
765    }else{
766      if(iBand<4){
767        char *tmpS=strdup(nameBands);
768        nameBands=(char*)realloc(nameBands,(strlen(nameBands)+strlen(lBands)+1)*sizeof(char));
769        sprintf(nameBands,"%s %s",tmpS,lBands);
770        free(tmpS);
771      }
772    }
773  }
774  msInsertHashTable(&(myLayer->metadata), "ows_bandnames", nameBands);
775 
776  /**
777   * Loops over metadata informations to setup specific informations
778   */
779  for( iBand = 0; iBand < nBandsI; iBand++ ){
780    int         bGotNodata, bSuccess;
781    double      adfCMinMax[2], dfNoData;
782    int         nBlockXSize, nBlockYSize, nMaskFlags;
783    double      dfMean, dfStdDev;
784    hBand = GDALGetRasterBand( hDataset, iBand+1 );
785
786    CPLErrorReset();
787    GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax );
788    char tmpN[21];
789    sprintf(tmpN,"Band%d",iBand+1);
790    if (CPLGetLastErrorType() == CE_None){
791      char tmpMm[100];
792      sprintf(tmpMm,"%.3f %.3f",adfCMinMax[0],adfCMinMax[1]);
793      char tmpI[21];
794      sprintf(tmpI,"%s_interval",tmpN);
795      msInsertHashTable(&(myLayer->metadata), tmpI, tmpMm);
796
797      map* test=getMap(output->content,"msClassify");
798      if(test!=NULL && strncasecmp(test->value,"true",4)==0){
799        /**
800         * Classify one band raster pixel value using regular interval
801         */
802        int _tmpColors[10][3]={
803          {102,153,204},
804          {51,102,153},
805          {102,102,204},
806          {51,204,0},
807          {153,255,102},
808          {204,255,102},
809          {102,204,153},
810          {255,69,64},
811          {255,192,115},
812          {255,201,115}
813        };
814         
815        if(nBandsI==1){
816          double delta=adfCMinMax[1]-adfCMinMax[0];
817          double interval=delta/10;
818          double cstep=adfCMinMax[0];
819          for(i=0;i<10;i++){
820            /**
821             * Create a new class
822             */
823            if(msGrowLayerClasses(myLayer) == NULL)
824              return -1;
825            if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
826              return -1;
827            myLayer->CLASS[myLayer->numclasses]->type = myLayer->type;
828            if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
829              return -1;
830            if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
831              return -1;
832           
833            /**
834             * Set class name
835             */
836            char className[7];
837            sprintf(className,"class%d",i);
838            myLayer->CLASS[myLayer->numclasses]->name=strdup(className);
839           
840            /**
841             * Set expression
842             */
843            char expression[1024];
844            if(i+1<10)
845              sprintf(expression,"([pixel]>=%.3f AND [pixel]<%.3f)",cstep,cstep+interval);
846            else
847              sprintf(expression,"([pixel]>=%.3f AND [pixel]<=%.3f)",cstep,cstep+interval);
848            msLoadExpressionString(&myLayer->CLASS[myLayer->numclasses]->expression,expression);
849           
850            /**
851             * Set color
852             */
853            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=_tmpColors[i][0];
854            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=_tmpColors[i][1];
855            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=_tmpColors[i][2];
856            cstep+=interval;
857            myLayer->CLASS[myLayer->numclasses]->numstyles++;
858            myLayer->numclasses++;
859           
860          }
861         
862          char tmpMm[100];
863          sprintf(tmpMm,"%.3f %.3f",adfCMinMax[0],adfCMinMax[1]);
864         
865        }
866      }
867    }
868    if( strlen(GDALGetRasterUnitType(hBand)) > 0 ){
869      char tmpU[21];
870      sprintf(tmpU,"%s_band_uom",tmpN);
871      msInsertHashTable(&(myLayer->metadata), tmpU, GDALGetRasterUnitType(hBand));
872    }
873
874  }
875
876  m->layerorder[m->numlayers] = m->numlayers;
877  m->numlayers++;
878  GDALClose( hDataset );
879  GDALDestroyDriverManager();
880  CPLCleanupTLS();
881  return 1;
882}
883
884/**
885 * Create a MapFile for WMS, WFS or WCS Service output
886 */
887void outputMapfile(maps* conf,maps* outputs){
888
889  /**
890   * Firs store the value on disk
891   */
892  map* mime=getMap(outputs->content,"mimeType");
893  char *ext="data";
894  if(mime!=NULL)
895    if(strncasecmp(mime->value,"application/json",16)==0)
896      ext="json";
897 
898  map* tmpMap=getMapFromMaps(conf,"main","dataPath");
899  map* sidMap=getMapFromMaps(conf,"lenv","sid");
900  char *pszDataSource=(char*)malloc((strlen(tmpMap->value)+strlen(sidMap->value)+strlen(outputs->name)+17)*sizeof(char));
901  sprintf(pszDataSource,"%s/ZOO_DATA_%s_%s.%s",tmpMap->value,outputs->name,sidMap->value,ext);
902  int f=open(pszDataSource,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
903  map* sizeMap=getMap(outputs->content,"size");
904  map* vData=getMap(outputs->content,"value");
905  if(sizeMap!=NULL){
906    write(f,vData->value,atoi(sizeMap->value)*sizeof(char));
907  }
908  else{
909    write(f,vData->value,strlen(vData->value)*sizeof(char));
910  }
911  close(f);
912  //exit(-1);
913  addToMap(outputs->content,"storage",pszDataSource);
914
915  /*
916   * Create an empty map, set name, default size and extent
917   */
918  mapObj *myMap=msNewMapObj();
919  free(myMap->name);
920  myMap->name=strdup("ZOO-Project_WXS_Server");
921  msMapSetSize(myMap,2048,2048);
922  msMapSetExtent(myMap,-1,-1,1,1);
923 
924  /*
925   * Set imagepath and imageurl using tmpPath and tmpUrl from main.cfg
926   */
927  map *tmp1=getMapFromMaps(conf,"main","tmpPath");
928  myMap->web.imagepath=strdup(tmp1->value);
929  tmp1=getMapFromMaps(conf,"main","tmpUrl");
930  myMap->web.imageurl=strdup(tmp1->value);
931 
932  /*
933   * Define supported output formats
934   */
935  outputFormatObj *o1=msCreateDefaultOutputFormat(NULL,"AGG/PNG","png");
936  o1->imagemode=MS_IMAGEMODE_RGBA;
937  o1->transparent=MS_TRUE;
938  o1->inmapfile=MS_TRUE;
939  msAppendOutputFormat(myMap,msCloneOutputFormat(o1));
940  msFreeOutputFormat(o1);
941
942#ifdef USE_KML
943  outputFormatObj *o2=msCreateDefaultOutputFormat(NULL,"KML","kml");
944  o2->inmapfile=MS_TRUE; 
945  msAppendOutputFormat(myMap,msCloneOutputFormat(o2));
946  msFreeOutputFormat(o2);
947#endif
948
949  outputFormatObj *o3=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","tiff");
950  if(!o3)
951    fprintf(stderr,"Unable to initialize GDAL driver !\n");
952  else{
953    o3->imagemode=MS_IMAGEMODE_BYTE;
954    o3->inmapfile=MS_TRUE; 
955    msAppendOutputFormat(myMap,msCloneOutputFormat(o3));
956    msFreeOutputFormat(o3);
957  }
958
959  outputFormatObj *o4=msCreateDefaultOutputFormat(NULL,"GDAL/AAIGRID","grd");
960  if(!o4)
961    fprintf(stderr,"Unable to initialize GDAL driver !\n");
962  else{
963    o4->imagemode=MS_IMAGEMODE_INT16;
964    o4->inmapfile=MS_TRUE; 
965    msAppendOutputFormat(myMap,msCloneOutputFormat(o4));
966    msFreeOutputFormat(o4);
967  }
968
969#ifdef USE_CAIRO
970  outputFormatObj *o5=msCreateDefaultOutputFormat(NULL,"CAIRO/PNG","cairopng");
971  if(!o5)
972    fprintf(stderr,"Unable to initialize CAIRO driver !\n");
973  else{
974    o5->imagemode=MS_IMAGEMODE_RGBA;
975    o5->transparent=MS_TRUE;
976    o5->inmapfile=MS_TRUE;
977    msAppendOutputFormat(myMap,msCloneOutputFormat(o5));
978    msFreeOutputFormat(o5);
979  }
980#endif
981
982  /*
983   * Set default projection to EPSG:4326
984   */
985  msLoadProjectionStringEPSG(&myMap->projection,"EPSG:4326");
986  myMap->transparent=1;
987
988  /**
989   * Set metadata extracted from main.cfg file maps
990   */
991  maps* cursor=conf;
992  map* correspondance=getCorrespondance();
993  while(cursor!=NULL){
994    map* _cursor=cursor->content;
995    map* vMap;
996    while(_cursor!=NULL){
997      if((vMap=getMap(correspondance,_cursor->name))!=NULL){
998        if (msInsertHashTable(&(myMap->web.metadata), vMap->value, _cursor->value) == NULL){
999#ifdef DEBUGMS
1000          fprintf(stderr,"Unable to add metadata");
1001#endif
1002          return;
1003        }
1004      }
1005      _cursor=_cursor->next;
1006    }
1007    cursor=cursor->next;
1008  }
1009
1010  /*
1011   * Set mapserver PROJ_LIB/GDAL_DATA or any other config parameter from
1012   * the main.cfg [mapserver] section if any
1013   */
1014  maps *tmp3=getMaps(conf,"mapserver");
1015  if(tmp3!=NULL){
1016    map* tmp4=tmp3->content;
1017    while(tmp4!=NULL){
1018      msSetConfigOption(myMap,tmp4->name,tmp4->value);
1019      tmp4=tmp4->next;
1020    }
1021  }
1022
1023  /**
1024   * Set a ows_rootlayer_title, 
1025   */
1026  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_name", "ZOO_Project_Layer") == NULL){
1027#ifdef DEBUGMS
1028    fprintf(stderr,"Unable to add metadata");
1029#endif
1030    return;
1031  }
1032  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_title", "ZOO_Project_Layer") == NULL){
1033#ifdef DEBUGMS
1034    fprintf(stderr,"Unable to add metadata");
1035#endif
1036    return;
1037  }
1038
1039  /**
1040   * Enable all the WXS requests using ows_enable_request
1041   * see http://mapserver.org/trunk/development/rfc/ms-rfc-67.html
1042   */
1043  if (msInsertHashTable(&(myMap->web.metadata), "ows_enable_request", "*") == NULL){
1044#ifdef DEBUGMS
1045    fprintf(stderr,"Unable to add metadata");
1046#endif
1047    return;
1048  }
1049  msInsertHashTable(&(myMap->web.metadata), "ows_srs", "EPSG:4326");
1050
1051  if(tryOgr(conf,outputs,myMap)<0)
1052    if(tryGdal(conf,outputs,myMap)<0)
1053      return ;
1054
1055  tmp1=getMapFromMaps(conf,"main","dataPath");
1056  char *tmpPath=(char*)malloc((13+strlen(tmp1->value))*sizeof(char));
1057  sprintf(tmpPath,"%s/symbols.sym",tmp1->value);
1058  msInitSymbolSet(&myMap->symbolset);
1059  myMap->symbolset.filename=strdup(tmpPath);
1060  free(tmpPath);
1061
1062  map* sid=getMapFromMaps(conf,"lenv","sid");
1063  char *mapPath=
1064    (char*)malloc((16+strlen(outputs->name)+strlen(tmp1->value))*sizeof(char));
1065  sprintf(mapPath,"%s/%s_%s.map",tmp1->value,outputs->name,sid->value);
1066  msSaveMap(myMap,mapPath);
1067  msFreeMap(myMap);
1068}
1069
1070#endif
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