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

Last change on this file since 379 was 379, checked in by djay, 9 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