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

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

Fixing issue when there is no SRS in the file you want to return as result of your processing (cf. #77).

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