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

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