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

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

Fix issue with WKT projections which can became empty after converting to proj4 format.

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