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

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