source: branches/prototype-v0/zoo-project/zoo-kernel/service_internal_ms.c @ 880

Last change on this file since 880 was 880, checked in by djay, 6 years ago

Modify memory configuration option gesture. Now, in case you don't have setup memory option in the main section your main.cfg file then, the ZOO-Kernel will load everything in memory and will also store the file containing the input. In case you want the old mode, you have to set memory option to 'load' in your main.cfg file. Fix issue with loading R ZOO-Service located in a subdirectory. Support for XML Execute request containing TEXT_NODE when CDATA_NODE should be used.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 48.3 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/**
26 * Cross platform definition of layerObj->class
27 */
28#ifndef WIN32
29#define CLASS class
30#else
31#define CLASS _class
32#endif
33#include "service_internal_ms.h"
34#include "server_internal.h"
35#include "response_print.h"
36#include "caching.h"
37
38/**
39 * Get a list of configuration keys having a corresponding mandatory ows_*.
40 * Map composed by a main.cfg maps name as key and the corresponding
41 * MapServer Mafile Metadata name to use
42 * see doc from here :
43 *  - http://mapserver.org/ogc/wms_server.html
44 *  - http://mapserver.org/ogc/wfs_server.html
45 *  - http://mapserver.org/ogc/wcs_server.html
46 *
47 * @return a new map containing a table linking a name of a configuration key
48 * to a corresponding mandatory ows_* keyword (ie. "fees" => "ows_fees").
49 */
50map* getCorrespondance(){
51  map* res=createMap("encoding","ows_encoding");
52  addToMap(res,"abstract","ows_abstract");
53  addToMap(res,"title","ows_title");
54  addToMap(res,"keywords","ows_keywordlist");
55  addToMap(res,"fees","ows_fees");
56  addToMap(res,"accessConstraints","ows_accessconstraints");
57  addToMap(res,"providerName","ows_attribution_title");
58  addToMap(res,"providerSite","ows_service_onlineresource");
59  addToMap(res,"individualName","ows_contactperson");
60  addToMap(res,"positionName","ows_contactposition");
61  addToMap(res,"providerName","ows_contactorganization");
62  addToMap(res,"role","ows_role");
63  addToMap(res,"addressType","ows_addresstype");
64  addToMap(res,"addressCity","ows_city");
65  addToMap(res,"addressDeliveryPoint","ows_address");
66  addToMap(res,"addressPostalCode","ows_postcode");
67  addToMap(res,"addressAdministrativeArea","ows_stateorprovince");
68  addToMap(res,"addressCountry","ows_country");
69  addToMap(res,"phoneVoice","ows_contactvoicetelephone");
70  addToMap(res,"phoneFacsimile","ows_contactfacsimiletelephone");
71  addToMap(res,"addressElectronicMailAddress","ows_contactelectronicmailaddress");
72  // Missing Madatory Informations
73  addToMap(res,"hoursOfService","ows_hoursofservice");
74  addToMap(res,"contactInstructions","ows_contactinstructions");
75  return res;
76}
77
78/**
79 * Return the current publish_id value
80 * @param elem and maps pointer on which the search occur
81 * @return the integer value of the publish_id field, if any, 0 otherwise
82 */ 
83int getPublishedId(maps* elem){
84  if(elem!=NULL && elem->content!=NULL){
85    map* myIndex=getMap(elem->content,"published_id");
86    if(myIndex!=NULL){
87      return atoi(myIndex->value);
88    }
89  }
90  return 0;
91}
92
93/**
94 * Add width and height keys to an output maps containing the maximum width
95 * and height for displaying the full data extent.
96 * Restriction to an image having a size of 640x480 (width * height)
97 *
98 * @param output
99 * @param minx the lower left x coordinate
100 * @param miny the lower left y coordinate
101 * @param maxx the upper right x coordinate
102 * @param maxy the upper right y coordinate
103 */
104void setMapSize(maps* output,double minx,double miny,double maxx,double maxy){
105  int imyIndex=getPublishedId(output);
106  double maxWidth=640;
107  double maxHeight=480;
108  double deltaX=maxx-minx;
109  double deltaY=maxy-miny;
110  double qWidth;
111  qWidth=maxWidth/deltaX;
112  double qHeight;
113  qHeight=maxHeight/deltaY;
114#ifdef DEBUGMS
115  fprintf(stderr,"deltaX : %.15f \ndeltaY : %.15f\n",deltaX,deltaY);
116  fprintf(stderr,"qWidth : %.15f \nqHeight : %.15f\n",qWidth,qHeight);
117#endif
118
119  double width=deltaX*qWidth;
120  double height=height=deltaY*qWidth;
121  if(deltaX<deltaY){
122    width=deltaX*qHeight;
123    height=deltaY*qHeight;
124  }
125  if(height<0)
126    height=-height;
127  if(width<0)
128    width=-width;
129  char sWidth[1024];
130  char sHeight[1024];
131  sprintf(sWidth,"%.3f",width);
132  sprintf(sHeight,"%.3f",height);
133#ifdef DEBUGMS
134  fprintf(stderr,"sWidth : %.15f \nsHeight : %.15f\n",sWidth,sHeight);
135#endif
136  if(output!=NULL){
137    setMapArray(output->content,"width",imyIndex,sWidth);
138    setMapArray(output->content,"height",imyIndex,sHeight);
139  }
140}
141
142/**
143 * Add a Reference key to an output containing the WMFS/WFS/WCS request for
144 * accessing service result
145 *
146 * @param m the conf maps containing the main.cfg settings
147 * @param tmpI the specific output maps to add the Reference key
148 */
149void setReferenceUrl(maps* m,maps* tmpI){
150  int imyIndex=getPublishedId(tmpI);
151  if(getMapArray(tmpI->content,"ref_wms_link",imyIndex)!=NULL)
152    return;
153  outputMapfile(m,tmpI);
154  map *msUrl=getMapFromMaps(m,"main","mapserverAddress");
155  if(msUrl==NULL){
156    errorException (m, _("Unable to find any mapserverAddress defined in the main.cfg file"),
157                    "InternalError", NULL);
158    exit(-1);
159  }
160  if(getMapArray(tmpI->content,"ref_wms_link",imyIndex)!=NULL)
161    return;
162  int finalProto=-1;
163  map *msOgcVersion=getMapFromMaps(m,"main","msOgcVersion");
164  map *dataPath=getMapFromMaps(m,"main","dataPath");
165  map *sid=getMapFromMaps(m,"lenv","usid");
166  map* format=getMapArray(tmpI->content,"mimeType",imyIndex);
167  map* rformat=getMapArray(tmpI->content,"requestedMimeType",imyIndex);
168  map* width=getMapArray(tmpI->content,"width",imyIndex);
169  map* height=getMapArray(tmpI->content,"height",imyIndex);
170  map* protoMap=getMapArray(tmpI->content,"msOgc",imyIndex);
171  map* versionMap=getMapArray(tmpI->content,"msOgcVersion",imyIndex);
172  map* datatype=getMapArray(tmpI->content,"geodatatype",imyIndex);
173  map* layerName=getMapArray(tmpI->content,"msLayer",imyIndex);
174  char options[4][5][25]={
175    {"WMS","1.3.0","GetMap","layers=%s","wms_extent"},
176    {"WFS","1.0.0","GetFeature","typename=%s","wcs_extent"},
177    {"WCS","2.0.0","GetCoverage","coverageid=%s","wcs_extent"},
178    {"WCS","1.0.0","GetCoverage","coverage=%s","wcs_extent"}
179  };
180  map *nbElements=getMapArray(tmpI->content,"nb_features",imyIndex);
181  if(nbElements==NULL)
182    nbElements=getMapArray(tmpI->content,"nb_pixels",imyIndex);
183  if(datatype==NULL || strncmp(datatype->value,"other",5)==0 || (nbElements!=NULL && atoi(nbElements->value)==0)){
184    map* minNb=getMap(tmpI->content,"minoccurs");
185    map* useMs=getMap(tmpI->content,"useMapserver");
186    if((minNb==NULL || atoi(minNb->value)>=1) && useMs!=NULL && strncasecmp(useMs->value,"true",4)==0){
187      setMapInMaps(m,"lenv","mapError","true");
188      setMapInMaps(m,"lenv","locator",tmpI->name);
189      if(nbElements==NULL)
190        setMapInMaps(m,"lenv","message",_("The ZOO-Kernel was able to retrieve the data but could not read it as geographic data."));
191      else
192        setMapInMaps(m,"lenv","message",_("The ZOO-Kernel was able to retrieve the data but could not access any feature or pixel in te resulting file."));
193      if(getMapFromMaps(m,"lenv","state")==NULL)
194        errorException (m, _("Unable to find any geographic data"), "WrongInputData", tmpI->name);
195    }
196    return;
197  }
198  int proto=0;
199  if(rformat==NULL){
200    rformat=getMapArray(tmpI->content,"mimeType",imyIndex);
201  }
202  if(strncasecmp(rformat->value,"text/xml",8)==0)
203    proto=1;
204  if(strncasecmp(rformat->value,"image/tiff",10)==0 ||
205     strncasecmp(rformat->value,"image/geotiff",10)==0)
206    proto=2;
207  int hasFormat=-1;
208  if(protoMap!=NULL){
209    hasFormat=1;
210    if(strncasecmp(protoMap->value,"WMS",3)==0){
211      proto=0;
212      rformat=createMap("value","image/png");
213    }
214    else{
215      if(strncasecmp(protoMap->value,"WFS",3)==0){
216        proto=1;
217        rformat=createMap("value","text/xml");
218      }
219      else {
220        proto=2;
221        rformat=createMap("value","image/tiff");
222      }
223    }
224  }
225  char *protoVersion=options[proto][1];
226  if(proto==1){
227    if(msOgcVersion!=NULL)
228      protoVersion=msOgcVersion->value;
229    if(versionMap!=NULL)
230      protoVersion=versionMap->value;
231  }
232
233
234  map* extent=getMapArray(tmpI->content,options[proto][4],imyIndex);
235  map* crs=getMapArray(tmpI->content,"crs",imyIndex);
236  int hasCRS=1;
237  if(crs==NULL){
238    crs=getMapFromMaps(m,"main","crs");
239    if(crs==NULL){
240      crs=createMap("crs","epsg:4326");
241      hasCRS=0;
242    }
243  }
244  char layers[128];
245  if(layerName==NULL)
246    sprintf(layers,options[proto][3],tmpI->name);
247  else
248    sprintf(layers,options[proto][3],layerName->value);
249
250  if(format==NULL || width==NULL || height==NULL || extent==NULL){
251    char tmpStr[1024];
252    sprintf(tmpStr,_("Unable to create the mapfile for %s because of missing values."),tmpI->name);
253    errorException (m, tmpStr,
254                    "InternalError", NULL);
255    exit(-1);
256    return;
257  }
258
259  if(proto==0){
260    hasFormat=1;
261    rformat=createMap("mimeType","image/png");
262  }else{
263    if(proto==1){
264      rformat=createMap("mimeType","text/xml");
265      hasFormat=1;
266    }
267    else
268      if(proto==2){
269        rformat=createMap("mimeType","image/tiff");
270        hasFormat=1;
271        finalProto=1;
272      }
273  }
274 
275  char* webService_url=(char*)malloc((strlen(msUrl->value)+strlen(rformat->value)+strlen(tmpI->name)+strlen(width->value)+strlen(height->value)+strlen(extent->value)+256)*sizeof(char));
276
277
278  if(proto>0){
279    if(proto==2)
280      finalProto=1;
281    sprintf(webService_url,
282            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
283            msUrl->value,
284            dataPath->value,
285            tmpI->name,
286            imyIndex,
287            sid->value,
288            options[proto][2],
289            options[proto][0],
290            protoVersion,
291            layers,
292            rformat->value,
293            extent->value,
294            crs->value
295            );
296    if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
297      setMapArray(tmpI->content,"ref_wcs_link",imyIndex,webService_url);
298    }
299    else{
300      setMapArray(tmpI->content,"ref_wfs_link",imyIndex,webService_url);
301    }
302    proto=0;
303    freeMap(&rformat);
304    free(rformat);
305    rformat=createMap("mimeType","image/png");
306  }
307  else{
308    sprintf(webService_url,
309            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&width=%s&height=%s&format=%s&bbox=%s&crs=%s",
310            msUrl->value,
311            dataPath->value,
312            tmpI->name,
313            imyIndex,
314            sid->value,
315            options[proto][2],
316            options[proto][0],
317            protoVersion,
318            layers,
319            width->value,
320            height->value,
321            rformat->value,
322            extent->value,
323            crs->value
324            );
325    setMapArray(tmpI->content,"ref_wms_link",imyIndex,webService_url);
326    if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
327      proto=2;
328      freeMap(&rformat);
329      free(rformat);
330      rformat=createMap("mimeType","image/tiff");
331    }
332    else{
333      proto=1;
334      freeMap(&rformat);
335      free(rformat);
336      rformat=createMap("mimeType","text/xml");
337    }
338  }
339  setMapArray(tmpI->content,"Reference",imyIndex,webService_url);
340  memset(layers,0,128);
341  sprintf(layers,options[proto][3],tmpI->name);
342  protoVersion=options[proto][1];
343  extent=getMapArray(tmpI->content,options[proto][4],imyIndex);
344  memset(webService_url,0,strlen(webService_url));
345  if(proto>0){
346    if(proto==2)
347      finalProto=1;
348    sprintf(webService_url,
349            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
350            msUrl->value,
351            dataPath->value,
352            tmpI->name,
353            imyIndex,
354            sid->value,
355            options[proto][2],
356            options[proto][0],
357            protoVersion,
358            layers,
359            rformat->value,
360            extent->value,
361            crs->value
362            );
363    if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
364      setMapArray(tmpI->content,"ref_wcs_link",imyIndex,webService_url);
365    }
366    else{
367      setMapArray(tmpI->content,"ref_wfs_link",imyIndex,webService_url);
368    }
369  }else{
370    sprintf(webService_url,
371            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&width=%s&height=%s&format=%s&bbox=%s&crs=%s",
372            msUrl->value,
373            dataPath->value,
374            tmpI->name,
375            imyIndex,
376            sid->value,
377            options[proto][2],
378            options[proto][0],
379            protoVersion,
380            layers,
381            width->value,
382            height->value,
383            rformat->value,
384            extent->value,
385            crs->value
386            );
387    setMapArray(tmpI->content,"ref_wms_link",imyIndex,webService_url);
388  }
389  if(finalProto>0){
390    proto=3;
391    memset(layers,0,128);
392    sprintf(layers,options[proto][3],tmpI->name);
393    protoVersion=options[proto][1];
394    extent=getMapArray(tmpI->content,options[proto][4],imyIndex);
395    memset(webService_url,0,strlen(webService_url));
396    freeMap(&rformat);
397    free(rformat);
398    rformat=createMap("value","image/tiff");
399    sprintf(webService_url,
400            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
401            msUrl->value,
402            dataPath->value,
403            tmpI->name,
404            imyIndex,
405            sid->value,
406            options[proto][2],
407            options[proto][0],
408            protoVersion,
409            layers,
410            rformat->value,
411            extent->value,
412            crs->value
413            );
414    setMapArray(tmpI->content,"ref_wcs_preview_link",imyIndex,webService_url);
415  }
416  if(hasCRS==0){
417    freeMap(&crs);
418    free(crs);
419  }
420  freeMap(&rformat);
421  free(rformat);
422  free(webService_url);
423}
424
425/**
426 * Set projection for a layer in a MAPFILE using Authority Code and Name if
427 * available or fallback to proj4 definition if available or fallback to
428 * default EPSG:4326
429 *
430 * @param output the output maps
431 * @param m the opened mapObj
432 * @param myLayer the layerObj
433 * @param pszProjection a char* containing the SRS definition in WKT format
434 */
435void setSrsInformations(maps* output,mapObj* m,layerObj* myLayer,
436                        char* pszProjection){
437  OGRSpatialReferenceH  hSRS;
438  map* msSrs=NULL;
439  int imyIndex=getPublishedId(output);
440  hSRS = OSRNewSpatialReference(NULL);
441  if( pszProjection!=NULL && strlen(pszProjection)>1){
442    if(OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ){
443      char *proj4Str=NULL;
444      if(OSRGetAuthorityName(hSRS,NULL)!=NULL && 
445         OSRGetAuthorityCode(hSRS,NULL)!=NULL){
446        char tmpSrs[20];
447        sprintf(tmpSrs,"%s:%s",
448                OSRGetAuthorityName(hSRS,NULL),OSRGetAuthorityCode(hSRS,NULL));
449        msLoadProjectionStringEPSG(&m->projection,tmpSrs);
450        msLoadProjectionStringEPSG(&myLayer->projection,tmpSrs);
451       
452        char tmpSrss[256];
453        sprintf(tmpSrss,"EPSG:4326 EPSG:900913 EPSG:3857 %s",tmpSrs);
454       
455        msInsertHashTable(&(m->web.metadata), "ows_srs", tmpSrss);
456        msInsertHashTable(&(myLayer->metadata), "ows_srs", tmpSrss);
457       
458#ifdef DEBUGMS
459        fprintf(stderr,"isGeo %b\n\n",OSRIsGeographic(hSRS)==TRUE);
460#endif
461        if(output!=NULL){
462          if(OSRIsGeographic(hSRS)==TRUE)
463            setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
464          else
465            setMapArray(output->content,"crs_isGeographic",imyIndex,"false");
466          setMapArray(output->content,"crs",imyIndex,tmpSrs);
467        }
468      }
469      else{
470        OSRExportToProj4(hSRS,&proj4Str);
471        if(proj4Str!=NULL && strlen(proj4Str)>0){
472#ifdef DEBUGMS
473          fprintf(stderr,"PROJ (%s)\n",proj4Str);
474#endif
475          msLoadProjectionString(&(m->projection),proj4Str);
476          msLoadProjectionString(&(myLayer->projection),proj4Str);
477          if(output!=NULL){ 
478            if(OSRIsGeographic(hSRS)==TRUE)
479              setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
480            else
481              setMapArray(output->content,"crs_isGeographic",imyIndex,"false");
482          }
483          free(proj4Str);
484        }
485        else{
486          msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
487          msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
488          if(output!=NULL){
489            setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
490          }
491        }
492        if(output!=NULL){
493          setMapArray(output->content,"crs",imyIndex,"EPSG:4326");
494          setMapArray(output->content,"real_extent",imyIndex,"true");
495        }
496        msInsertHashTable(&(m->web.metadata),"ows_srs", "EPSG:4326 EPSG:900913 EPSG:3857");
497        msInsertHashTable(&(myLayer->metadata),"ows_srs","EPSG:4326 EPSG:900913 EPSG:3857");
498      }
499    }
500  }
501  else{
502    if(output!=NULL){
503      msSrs=getMapArray(output->content,"msSrs",imyIndex);
504    }
505    if(msSrs!=NULL){
506      msLoadProjectionStringEPSG(&m->projection,msSrs->value);
507      msLoadProjectionStringEPSG(&myLayer->projection,msSrs->value);
508      char tmpSrs[128];
509      sprintf(tmpSrs,"%s EPSG:4326 EPSG:900913 EPSG:3857",msSrs->value);
510      msInsertHashTable(&(m->web.metadata),"ows_srs",tmpSrs);
511      msInsertHashTable(&(myLayer->metadata),"ows_srs",tmpSrs);
512    }else{
513      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
514      msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
515      msInsertHashTable(&(m->web.metadata),"ows_srs","EPSG:4326 EPSG:900913 EPSG:3857");
516      msInsertHashTable(&(myLayer->metadata),"ows_srs","EPSG:4326 EPSG:900913 EPSG:3857");
517    }
518    if(output!=NULL){
519      setMapArray(output->content,"crs",imyIndex,msSrs->value);
520      setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
521    }
522  }
523
524  OSRDestroySpatialReference( hSRS );
525}
526
527/**
528 * Set the MAPFILE extent, the the ows_extent for the layer, add wms_extent and
529 * wfs_extent to the output maps and call setMapSize.
530 *
531 * @param output the specific output
532 * @param m the mapObj
533 * @param myLayer the layerObj
534 * @param minX the lower left x coordinate
535 * @param minY the lower left y coordinate
536 * @param maxX the upper right x coordinate
537 * @param maxY the upper right y coordinate
538 * @see setMapSize
539 */
540void setMsExtent(maps* output,mapObj* m,layerObj* myLayer,
541                 double minX,double minY,double maxX,double maxY){
542  int imyIndex=getPublishedId(output);
543  msMapSetExtent(m,minX,minY,maxX,maxY);
544  m->maxsize=4096;
545#ifdef DEBUGMS
546  fprintf(stderr,"Extent %.15f %.15f %.15f %.15f\n",minX,minY,maxX,maxY);
547#endif
548  char tmpExtent[1024];
549  sprintf(tmpExtent,"%.15f %.15f %.15f %.15f",minX,minY,maxX,maxY);
550#ifdef DEBUGMS
551  fprintf(stderr,"Extent %s\n",tmpExtent);
552#endif
553  msInsertHashTable(&(myLayer->metadata), "ows_extent", tmpExtent);
554 
555  if(output!=NULL){
556    map* test=getMapArray(output->content,"real_extent",imyIndex);
557    pointObj min, max;
558    projectionObj tempSrs;
559    min.x = m->extent.minx;
560    min.y = m->extent.miny;
561    max.x = m->extent.maxx;
562    max.y = m->extent.maxy;
563    char tmpSrsStr[1024];
564    msInitProjection(&tempSrs);
565    msLoadProjectionStringEPSG(&tempSrs,"EPSG:4326");
566
567    msProjectPoint(&(myLayer->projection),&tempSrs,&min);
568    msProjectPoint(&myLayer->projection,&tempSrs,&max);
569 
570    if(test!=NULL){
571      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
572      map* isGeo=getMapArray(output->content,"crs_isGeographic",imyIndex);
573#ifdef DEBUGMS
574      fprintf(stderr,"isGeo = %s\n",isGeo->value);
575#endif
576      if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0){
577        sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
578        setMapArray(output->content,"wgs84_extent",imyIndex,tmpExtent);
579        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
580      }else{
581        sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
582        setMapArray(output->content,"wgs84_extent",imyIndex,tmpExtent);
583      }
584      setMapArray(output->content,"wms_extent",imyIndex,tmpExtent);
585      sprintf(tmpSrsStr,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
586      setMapArray(output->content,"wcs_extent",imyIndex,tmpExtent);
587    }else{
588      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
589      setMapArray(output->content,"wgs84_extent",imyIndex,tmpExtent);
590      sprintf(tmpExtent,"%f,%f,%f,%f",minX, minY, maxX, maxY);
591      map* isGeo=getMapArray(output->content,"crs_isGeographic",imyIndex);
592      if(isGeo!=NULL){
593#ifdef DEBUGMS
594        fprintf(stderr,"isGeo = %s\n",isGeo->value);
595#endif
596        if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
597          sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
598      }
599      setMapArray(output->content,"wms_extent",imyIndex,tmpExtent); 
600      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",minX,minY,maxX,maxY);
601      setMapArray(output->content,"wcs_extent",imyIndex,tmpExtent);
602    }
603  }
604
605  setMapSize(output,minX,minY,maxX,maxY);
606}
607
608/**
609 * Try to open a vector output and define the corresponding layer in the MAPFILE
610 *
611 * @param conf the conf maps containing the main.cfg settings
612 * @param output the specific output maps
613 * @param m the mapObj
614 */
615int tryOgr(maps* conf,maps* output,mapObj* m){
616  int imyIndex=getPublishedId(output);
617  map* tmpMap=getMapArray(output->content,"storage",imyIndex);
618  char *pszDataSource=tmpMap->value;
619
620  /**
621   * Try to open the DataSource using OGR
622   */
623  OGRRegisterAll();
624  /**
625   * Try to load the file as ZIP
626   *
627  OGRDataSourceH poDS1 = NULL;
628  OGRSFDriverH *poDriver1 = NULL;
629  char *dsName=(char*)malloc((8+strlen(pszDataSource)+1)*sizeof(char));
630  char *odsName=zStrdup(pszDataSource);
631  char *sdsName=zStrdup(pszDataSource);
632  char *demo=".data";
633  sdsName[strlen(sdsName)-(strlen(demo)-1)]='d';
634  sdsName[strlen(sdsName)-(strlen(demo)-2)]='i';
635  sdsName[strlen(sdsName)-(strlen(demo)-3)]='r';
636  sdsName[strlen(sdsName)-(strlen(demo)-4)]=0;
637
638  odsName[strlen(odsName)-(strlen(demo)-1)]='z';
639  odsName[strlen(odsName)-(strlen(demo)-2)]='i';
640  odsName[strlen(odsName)-(strlen(demo)-3)]='p';
641  odsName[strlen(odsName)-(strlen(demo)-4)]=0;
642  sprintf(dsName,"/vsizip/%s",odsName);
643
644#ifdef DEBUGMS
645  fprintf(stderr,"Try loading %s, %s, %s\n",dsName,odsName,dsName);
646#endif
647
648  FILE* file = fopen(pszDataSource, "rb");
649  FILE* fileZ = fopen(odsName, "wb");
650  free(odsName);
651  fseek(file, 0, SEEK_END);
652  unsigned long fileLen=ftell(file);
653  fseek(file, 0, SEEK_SET);
654  char *buffer=(char *)malloc(fileLen+1);
655  fread(buffer, fileLen, 1, file);
656  fwrite(buffer,fileLen, 1, fileZ);
657  fclose(file);
658  fclose(fileZ);
659  free(buffer);
660#ifdef DEBUGMS
661  fprintf(stderr,"Try loading %s",dsName);
662#endif
663  poDS1 = OGROpen( dsName, FALSE, poDriver1 );
664  if( poDS1 == NULL ){
665    fprintf(stderr,"Unable to access the DataSource as ZIP File\n");
666    setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
667    fprintf(stderr,"Remove ZIP File!\n");
668    unlink(odsName);
669    //OGR_DS_Destroy(poDS1);
670  }else{
671#ifdef DEBUGMS
672    fprintf(stderr,"The DataSource is a  ZIP File\n");
673#endif
674    char** demo=VSIReadDir(dsName);
675    int i=0;
676    zMkdir(sdsName
677#ifndef WIN32
678                ,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
679#endif
680                );
681    while(demo[i]!=NULL){
682#ifdef DEBUGMS
683      fprintf(stderr,"ZIP File content : %s\n",demo[i]);
684#endif
685      char *tmpDs=(char*)malloc((strlen(dsName)+strlen(demo[i])+2)*sizeof(char));
686      sprintf(tmpDs,"%s/%s",dsName,demo[i]);
687      fprintf(stderr,"read : %s\n",tmpDs);
688     
689      VSILFILE* vsif=VSIFOpenL(tmpDs,"rb");
690#ifdef DEBUGMS
691      fprintf(stderr,"open : %s\n",tmpDs);
692#endif
693      VSIFSeekL(vsif,0,SEEK_END);
694      vsi_l_offset size=VSIFTellL(vsif);
695#ifdef DEBUGMS
696      fprintf(stderr,"size : %d\n",size);
697#endif
698      VSIFSeekL(vsif,0,SEEK_SET);
699      char *vsifcontent=(char*) malloc(((int)size+1)*sizeof(char));
700      VSIFReadL(vsifcontent,1,(size_t)size,vsif);
701      char *fpath=(char*) malloc((strlen(sdsName)+strlen(demo[1])+2)*sizeof(char));
702      sprintf(fpath,"%s/%s",sdsName,demo[i]);
703      int f=zOpen(fpath,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
704      zWrite(f,vsifcontent,(int)size);
705      close(f);
706      chmod(fpath,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH);
707      char* tmpP=strstr(fpath,".shp");
708      if(tmpP==NULL)
709        tmpP=strstr(fpath,".SHP");
710      if(tmpP!=NULL){
711#ifdef DEBUGMS
712        fprintf(stderr,"*** DEBUG %s\n",strstr(tmpP,"."));
713#endif
714        if( strcmp(tmpP,".shp")==0 || strcmp(tmpP,".SHP")==0 ){
715          tmpMap=getMap(output->content,"storage");
716          free(tmpMap->value);
717          tmpMap->value=(char*) malloc((strlen(fpath)+1)*sizeof(char));
718          sprintf(tmpMap->value,"%s",fpath);
719          pszDataSource=tmpMap->value;
720#ifdef DEBUGMS
721          fprintf(stderr,"*** DEBUG %s\n",pszDataSource);
722#endif
723        }
724      }
725      VSIFCloseL(vsif);
726      i++;
727    }
728    OGR_DS_Destroy(poDS1);
729    }
730  free(sdsName);
731  free(dsName);*/
732 
733  OGRDataSourceH poDS = NULL;
734  OGRSFDriverH *poDriver = NULL;
735  poDS = OGROpen( pszDataSource, FALSE, poDriver );
736  if( poDS == NULL ){
737#ifdef DEBUGMS
738    fprintf(stderr,"Unable to access the DataSource %s\n",pszDataSource);
739#endif
740    setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
741#ifdef DEBUGMS
742    fprintf(stderr,"Unable to access the DataSource, exit! \n"); 
743#endif
744    return -1;
745  }
746
747  setMapArray(output->content,"geodatatype",imyIndex,"vector");
748  int iLayer = 0;
749  for( iLayer=0; iLayer < OGR_DS_GetLayerCount(poDS); iLayer++ ){
750    OGRLayerH poLayer = OGR_DS_GetLayer(poDS,iLayer);
751
752    if( poLayer == NULL ){
753#ifdef DEBUGMS
754      fprintf(stderr,"Unable to access the DataSource Layer \n");
755#endif
756      setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
757      return -1;
758    }
759
760    /**
761     * Add a new layer set name, data
762     */
763    layerObj* myLayer=NULL;
764    if(getMapArray(output->content,"msInclude",imyIndex)==NULL){
765      if(msGrowMapLayers(m)==NULL){
766        return -1;
767      }
768      if(initLayer((m->layers[m->numlayers]), m) == -1){
769        return -1;
770      }
771      myLayer=m->layers[m->numlayers];
772    }else{
773      myLayer=m->layers[m->numlayers-1];
774    }
775   
776#ifdef DEBUGMS
777    dumpMaps(output);
778#endif
779    myLayer->name = zStrdup(output->name);
780    myLayer->tileitem=NULL;
781    myLayer->data = zStrdup(OGR_L_GetName(poLayer));
782    myLayer->connection = zStrdup(pszDataSource);
783    myLayer->index = m->numlayers;
784    myLayer->dump = MS_TRUE;
785    myLayer->status = MS_ON;
786    msConnectLayer(myLayer,MS_OGR,pszDataSource);
787
788    addIntToMapArray(output->content,"nb_features",imyIndex,OGR_L_GetFeatureCount(poLayer,1));
789
790    /**
791     * Detect the Geometry Type or use Polygon
792     */
793    if(OGR_L_GetGeomType(poLayer) != wkbUnknown){
794      switch(OGR_L_GetGeomType(poLayer)){
795      case wkbPoint:
796      case wkbMultiPoint:
797      case wkbPoint25D:
798      case wkbMultiPoint25D:
799#ifdef DEBUGMS
800        fprintf(stderr,"POINT DataSource Layer \n");
801#endif
802        myLayer->type = MS_LAYER_POINT;
803        break;
804      case wkbLineString :
805      case wkbMultiLineString :
806      case wkbLineString25D:
807      case wkbMultiLineString25D:
808#ifdef DEBUGMS
809        fprintf(stderr,"LINE DataSource Layer \n");
810#endif
811        myLayer->type = MS_LAYER_LINE;
812        break;
813      case wkbPolygon:
814      case wkbMultiPolygon:
815      case wkbPolygon25D:
816      case wkbMultiPolygon25D:
817#ifdef DEBUGMS
818        fprintf(stderr,"POLYGON DataSource Layer \n");
819#endif
820        myLayer->type = MS_LAYER_POLYGON;
821        break;
822      default:
823        myLayer->type = MS_LAYER_POLYGON;
824        break;
825      }
826    }else
827      myLayer->type = MS_LAYER_POLYGON;
828
829    /**
830     * Detect spatial reference or use WGS84
831     */
832    OGRSpatialReferenceH srs=OGR_L_GetSpatialRef(poLayer);
833    if(srs!=NULL){
834      char *wkt=NULL;
835      OSRExportToWkt(srs,&wkt);
836      setSrsInformations(output,m,myLayer,wkt);
837      free(wkt);
838    }
839    else{
840      setMapArray(output->content,"crs",imyIndex,"EPSG:4326");
841      setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
842      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
843      msInsertHashTable(&(m->web.metadata), "ows_srs", "EPSG:4326 EPSG:900913 EPSG:3857");
844      msInsertHashTable(&(myLayer->metadata), "ows_srs", "EPSG:4326 EPSG:900913 EPSG:3857");
845    }
846
847    OGREnvelope oExt;
848    if (OGR_L_GetExtent(poLayer,&oExt, TRUE) == OGRERR_NONE){
849      setMsExtent(output,m,myLayer,oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY);
850      char extent[1024];
851      memset(&extent,0,1024);
852      sprintf(extent,"%d,%d,%d,%d",oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY);
853      setMapArray(output->content,"boundingbox",imyIndex,extent);
854    }
855 
856    /**
857     * Detect the FID column or use the first attribute field as FID
858     */
859    char *fid=(char*)OGR_L_GetFIDColumn(poLayer);
860    if(strlen(fid)==0){
861      OGRFeatureDefnH def=OGR_L_GetLayerDefn(poLayer);
862      int fIndex=0;
863      for(fIndex=0;fIndex<OGR_FD_GetFieldCount(def);fIndex++){
864        OGRFieldDefnH fdef=OGR_FD_GetFieldDefn(def,fIndex);
865        fid=(char*)OGR_Fld_GetNameRef(fdef);
866        break;
867      }
868    }
869    msInsertHashTable(&(myLayer->metadata), "gml_featureid", fid);
870    msInsertHashTable(&(myLayer->metadata), "gml_include_items", "all");
871    msInsertHashTable(&(myLayer->metadata), "ows_name", output->name);
872    map* tmpMap=getMapArray(output->content,"title",imyIndex);
873    if(tmpMap!=NULL)
874      msInsertHashTable(&(myLayer->metadata), "ows_title", tmpMap->value);
875    else
876      msInsertHashTable(&(myLayer->metadata), "ows_title", "Default Title");
877
878    if(getMapArray(output->content,"msInclude",imyIndex)==NULL){
879      if(msGrowLayerClasses(myLayer) == NULL)
880        return -1;
881      if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
882        return -1;
883      if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
884        return -1;
885      if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
886        return -1;
887      /**
888       * Apply msStyle else fallback to the default style
889       */
890      tmpMap=getMap(output->content,"msStyle");
891      if(tmpMap!=NULL)
892        msUpdateStyleFromString(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles],tmpMap->value,0);
893      else{
894        /**
895         * Set style
896         */
897        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=125;
898        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=125;
899        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=255;
900        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.red=80;
901        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.green=80;
902        myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.blue=80;
903       
904        /**
905         * Set specific style depending on type
906         */
907        if(myLayer->type == MS_LAYER_POLYGON)
908          myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->width=3;
909        if(myLayer->type == MS_LAYER_LINE){
910          myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->width=3;
911          myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinewidth=1.5;
912        }
913        if(myLayer->type == MS_LAYER_POINT){
914          myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->symbol=1;
915          myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->size=15;
916        }
917       
918      }
919      myLayer->CLASS[myLayer->numclasses]->numstyles++;
920      myLayer->numclasses++;
921   
922      m->layerorder[m->numlayers] = m->numlayers;
923      m->numlayers++;
924
925    }
926  }
927  OGR_DS_Destroy(poDS);
928  //OGRCleanupAll();
929
930  return 1;
931}
932
933/**
934 * Try to open a raster output and define the corresponding layer in the MAPFILE
935 *
936 * @param conf the conf maps containing the main.cfg settings
937 * @param output the specific output maps
938 * @param m the mapObj
939 */
940int tryGdal(maps* conf,maps* output,mapObj* m){
941  int imyIndex=getPublishedId(output);
942  map* tmpMap=getMapArray(output->content,"storage",imyIndex);
943  char *pszFilename=tmpMap->value;
944  GDALDatasetH hDataset;
945  GDALRasterBandH hBand;
946  double adfGeoTransform[6];
947  int i, iBand;
948 
949  /**
950   * Try to open the DataSource using GDAL
951   */
952  GDALAllRegister();
953  hDataset = GDALOpen( pszFilename, GA_Update );
954  if( hDataset == NULL ){
955#ifdef DEBUGMS
956    fprintf(stderr,"Unable to access the DataSource %s \n",pszFilename);
957#endif
958    setMapArray(output->content,"geodatatype",imyIndex,"other");
959    setMapInMaps(conf,"lenv","message","gdalinfo failed - unable to open");
960    GDALDestroyDriverManager();
961    return -1;
962  }
963#ifdef DEBUGMS
964  fprintf(stderr,"Accessing the DataSource %s %d\n",pszFilename,__LINE__);
965#endif
966
967  setMapArray(output->content,"geodatatype",imyIndex,"raster");
968  /**
969   * Add a new layer set name, data
970   */
971  if(msGrowMapLayers(m)==NULL){
972    return -1;
973  }
974  if(initLayer((m->layers[m->numlayers]), m) == -1){
975    return -1;
976  }
977  m->layers[m->numlayers]->index=m->numlayers;
978
979  layerObj* myLayer=m->layers[m->numlayers];
980  myLayer->name = zStrdup(output->name);
981  myLayer->tileitem=NULL;
982  myLayer->data = zStrdup(pszFilename);
983  myLayer->index = m->numlayers;
984  myLayer->dump = MS_TRUE;
985  myLayer->status = MS_ON;
986  myLayer->type = MS_LAYER_RASTER;
987
988  char *title=output->name;
989  tmpMap=getMapArray(output->content,"title",imyIndex);
990  if(tmpMap!=NULL)
991    title=tmpMap->value;
992  char *abstract=output->name;
993  tmpMap=getMapArray(output->content,"abstract",imyIndex);
994  if(tmpMap!=NULL)
995    abstract=tmpMap->value;
996
997  msInsertHashTable(&(myLayer->metadata), "ows_label", title);
998  msInsertHashTable(&(myLayer->metadata), "ows_title", title);
999  msInsertHashTable(&(myLayer->metadata), "ows_abstract", abstract);
1000  msInsertHashTable(&(myLayer->metadata), "ows_rangeset_name", output->name);
1001  msInsertHashTable(&(myLayer->metadata), "ows_rangeset_label", title);
1002
1003  /**
1004   * Set Map Size to the raster size
1005   */
1006  m->width=GDALGetRasterXSize( hDataset );
1007  m->height=GDALGetRasterYSize( hDataset );
1008  if(m->width>4096 || m->height>4096){
1009    if(m->width>m->height)
1010      m->maxsize=m->width;
1011    else 
1012      m->maxsize=m->height;
1013  }else
1014    m->maxsize=4096;
1015  addIntToMapArray(output->content,"nb_pixels",imyIndex,GDALGetRasterXSize( hDataset )*GDALGetRasterYSize( hDataset ));
1016  int pixel_type=GDALGetRasterDataType( hDataset );
1017  addIntToMapArray(output->content,"pixel_data_type",imyIndex,pixel_type);
1018
1019  int outputIndex=msGetOutputFormatIndex(m,"tiff");
1020  if(outputIndex>=0){
1021    m->outputformatlist[outputIndex]->imagemode=((pixel_type==GDT_Byte)?MS_IMAGEMODE_BYTE:((pixel_type==GDT_Int16 || pixel_type==GDT_UInt16)?MS_IMAGEMODE_INT16:((pixel_type!=GDT_Float32)?MS_IMAGEMODE_FLOAT32:MS_IMAGEMODE_BYTE)));
1022    outputIndex=msGetOutputFormatIndex(m,"geotiff");
1023    if(outputIndex>=0)
1024      m->outputformatlist[outputIndex]->imagemode=((pixel_type==GDT_Byte)?MS_IMAGEMODE_BYTE:((pixel_type==GDT_Int16 || pixel_type==GDT_UInt16)?MS_IMAGEMODE_INT16:((pixel_type!=GDT_Float32)?MS_IMAGEMODE_FLOAT32:MS_IMAGEMODE_BYTE)));
1025  }
1026  //
1027   
1028  /**
1029   * Set projection using Authority Code and Name if available or fallback to
1030   * proj4 definition if available or fallback to default EPSG:4326
1031   */
1032  const char *tRef=GDALGetProjectionRef( hDataset );
1033  if( tRef != NULL && strlen(tRef)>0 ){
1034    char *pszProjection;
1035    pszProjection = (char *) GDALGetProjectionRef( hDataset );
1036#ifdef DEBUGMS
1037    fprintf(stderr,"Accessing the DataSource %s\n",GDALGetProjectionRef( hDataset ));
1038#endif
1039    setSrsInformations(output,m,myLayer,pszProjection);
1040  }else{
1041    fprintf(stderr,"NO SRS FOUND ! %s\n",GDALGetProjectionRef( hDataset ));
1042    CPLErr sp=GDALSetProjection( hDataset , "+init=epsg:4326" );
1043    if(sp!=CE_None){
1044      fprintf(stderr,"NO SRS FOUND ! %s\n",CPLGetLastErrorMsg());
1045    }
1046  }
1047
1048  /**
1049   * Set extent
1050   */
1051  if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ){
1052    if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ){
1053
1054      double minX = adfGeoTransform[0]
1055        + adfGeoTransform[2] * GDALGetRasterYSize(hDataset);
1056      double minY = adfGeoTransform[3]
1057        + adfGeoTransform[5] * GDALGetRasterYSize(hDataset);
1058
1059      double maxX = adfGeoTransform[0]
1060        + adfGeoTransform[1] * GDALGetRasterXSize(hDataset);
1061      double maxY = adfGeoTransform[3]
1062        + adfGeoTransform[4] * GDALGetRasterXSize(hDataset);
1063
1064      setMsExtent(output,m,myLayer,minX,minY,maxX,maxY);
1065      char extent[1024];
1066      memset(&extent,0,1024);
1067      sprintf(extent,"%d,%d,%d,%d",minX,minY,maxX,maxY);
1068      setMapArray(output->content,"boundingbox",imyIndex,extent);
1069    }
1070  }else{
1071    int scale=1;
1072    if(m->width>2048){
1073      addIntToMapArray(output->content,"width",imyIndex,2048);
1074      scale=2048/m->width;
1075    }else
1076      addIntToMapArray(output->content,"width",imyIndex,m->width);
1077    addIntToMapArray(output->content,"height",imyIndex,m->height*scale);
1078  }
1079
1080  /**
1081   * Extract information about available bands to set the bandcount and the
1082   * processing directive
1083   */
1084  char nBands[3];
1085  memset(&nBands,0,3);
1086  int nBandsI=GDALGetRasterCount( hDataset );
1087  if(nBandsI<100){
1088    sprintf(nBands,"%d",GDALGetRasterCount( hDataset ));
1089    msInsertHashTable(&(myLayer->metadata), "ows_bandcount", nBands);
1090  }
1091  if(nBandsI>=3)
1092    if(nBandsI==4)
1093      msLayerAddProcessing(myLayer,"BANDS=1,2,3,4");
1094    else
1095      msLayerAddProcessing(myLayer,"BANDS=1,2,3");
1096  else if(nBandsI>=2)
1097    msLayerAddProcessing(myLayer,"BANDS=1,2");
1098  else
1099    msLayerAddProcessing(myLayer,"BANDS=1");
1100 
1101
1102  /**
1103   * Name available Bands
1104   */
1105  char lBands[7];
1106  char *nameBands=NULL;
1107  for( iBand = 0; iBand < nBandsI; iBand++ ){
1108    memset(&lBands,0,7);
1109    sprintf(lBands,"Band%d",iBand+1);   
1110    if(nameBands==NULL){
1111      nameBands=(char*)malloc((strlen(lBands)+1)*sizeof(char));
1112      sprintf(nameBands,"%s",lBands);
1113    }else{
1114      /*if(iBand<4)*/{
1115        char *tmpS=zStrdup(nameBands);
1116        nameBands=(char*)realloc(nameBands,(strlen(tmpS)+strlen(lBands)+2)*sizeof(char));
1117        sprintf(nameBands,"%s %s",tmpS,lBands);
1118        free(tmpS);
1119      }
1120    }
1121  }
1122  if(nameBands!=NULL){
1123    msInsertHashTable(&(myLayer->metadata), "ows_bandnames", nameBands);
1124    free(nameBands);
1125  }
1126
1127  /**
1128   * Loops over metadata information to setup specific information
1129   */
1130  for( iBand = 0; iBand < nBandsI; iBand++ ){
1131    double      pdfMin, pdfMax, pdfMean, pdfStdDev;
1132    hBand = GDALGetRasterBand( hDataset, iBand+1 );
1133
1134    CPLErrorReset();
1135    GDALComputeRasterStatistics( hBand, TRUE, &pdfMin, &pdfMax, &pdfMean, &pdfStdDev, NULL,NULL);
1136    char tmpN[21];
1137    sprintf(tmpN,"Band%d",iBand+1);
1138    if (CPLGetLastErrorType() == CE_None){
1139      char tmpMm[100],tmpMp[100];
1140      sprintf(tmpMm,"%.3f %.3f",pdfMin,pdfMax);
1141      sprintf(tmpMp,"SCALE_%d=%.3f,%.3f",iBand+1,pdfMean-(2*pdfStdDev),pdfMean+(2*pdfStdDev));
1142      char tmpI[31];     
1143      sprintf(tmpI,"%s_interval",tmpN);
1144      msInsertHashTable(&(myLayer->metadata), tmpI, tmpMm);
1145      if(pdfMax>255)
1146        msLayerAddProcessing(myLayer,tmpMp);
1147      map* test=getMap(output->content,"msClassify");
1148      if(test!=NULL && strncasecmp(test->value,"true",4)==0){
1149        /**
1150         * Classify one band raster pixel value using regular interval
1151         */
1152        int _tmpColors[10][3]={
1153          {102,153,204},
1154          {51,102,153},
1155          {102,102,204},
1156          {51,204,0},
1157          {153,255,102},
1158          {204,255,102},
1159          {102,204,153},
1160          {255,69,64},
1161          {255,192,115},
1162          {255,201,115}
1163        };
1164         
1165        if(nBandsI==1){
1166          double delta=pdfMax-pdfMin;
1167          double interval=delta/10;
1168          double cstep=pdfMin;
1169          for(i=0;i<10;i++){
1170            /**
1171             * Create a new class
1172             */
1173            if(msGrowLayerClasses(myLayer) == NULL)
1174              return -1;
1175            if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
1176              return -1;
1177            if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
1178              return -1;
1179            if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
1180              return -1;
1181           
1182            /**
1183             * Set class name
1184             */
1185            char className[7];
1186            sprintf(className,"class%d",i);
1187            myLayer->CLASS[myLayer->numclasses]->name=zStrdup(className);
1188           
1189            /**
1190             * Set expression
1191             */
1192            char expression[1024];
1193            if(i+1<10)
1194              sprintf(expression,"([pixel]>=%.3f AND [pixel]<%.3f)",cstep,cstep+interval);
1195            else
1196              sprintf(expression,"([pixel]>=%.3f AND [pixel]<=%.3f)",cstep,cstep+interval);
1197            msLoadExpressionString(&myLayer->CLASS[myLayer->numclasses]->expression,expression);
1198           
1199            /**
1200             * Set color
1201             */
1202            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=_tmpColors[i][0];
1203            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=_tmpColors[i][1];
1204            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=_tmpColors[i][2];
1205            cstep+=interval;
1206            myLayer->CLASS[myLayer->numclasses]->numstyles++;
1207            myLayer->numclasses++;
1208           
1209          }
1210         
1211          char tmpMm[100];
1212          sprintf(tmpMm,"%.3f %.3f",pdfMin,pdfMax);
1213         
1214        }
1215      }
1216      else{
1217        if(nBandsI==1){
1218          myLayer->offsite.red=0;
1219          myLayer->offsite.green=0;
1220          myLayer->offsite.blue=0;
1221        }
1222      }
1223    }
1224    if( strlen(GDALGetRasterUnitType(hBand)) > 0 ){
1225      char tmpU[31];
1226      sprintf(tmpU,"%s_band_uom",tmpN);
1227      msInsertHashTable(&(myLayer->metadata), tmpU, GDALGetRasterUnitType(hBand));
1228    }
1229
1230  }
1231  msLayerAddProcessing(myLayer,"RESAMPLE=BILINEAR");
1232
1233  m->layerorder[m->numlayers] = m->numlayers;
1234  m->numlayers++;
1235  GDALClose( hDataset );
1236  GDALDestroyDriverManager();
1237  CPLCleanupTLS();
1238  storeMd5(pszFilename);
1239  return 1;
1240}
1241
1242/**
1243 * Create a MapFile for WMS, WFS or WCS Service output
1244 *
1245 * @param conf the conf maps containing the main.cfg settings
1246 * @param outputs a specific output maps
1247 */
1248void outputMapfile(maps* conf,maps* outputs){
1249  /**
1250   * First store the value on disk
1251   */
1252  int imyIndex=getPublishedId(outputs);
1253  map* mime=getMapArray(outputs->content,"mimeType",imyIndex);
1254  char *ext="data";
1255  if(mime!=NULL)
1256    if(strncasecmp(mime->value,"application/json",16)==0)
1257      ext="json";
1258
1259  map* storage=getMapArray(outputs->content,"storage",imyIndex);
1260  if(storage==NULL){
1261    map* tmpMap=getMapFromMaps(conf,"main","dataPath");
1262    map* sidMap=getMapFromMaps(conf,"lenv","usid");
1263    char *pszDataSource=(char*)malloc((strlen(tmpMap->value)+strlen(sidMap->value)+strlen(outputs->name)+17)*sizeof(char));
1264    sprintf(pszDataSource,"%s/ZOO_DATA_%d_%s_%s.%s",tmpMap->value,imyIndex,outputs->name,sidMap->value,ext);
1265    int f=zOpen(pszDataSource,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
1266    map *gfile=getMapArray(outputs->content,"generated_file",imyIndex);
1267    if(gfile!=NULL){
1268      readGeneratedFile(conf,outputs->content,gfile->value);       
1269    }
1270    map* sizeMap=getMapArray(outputs->content,"size",imyIndex);
1271    map* vData=getMapArray(outputs->content,"value",imyIndex);
1272    if(sizeMap!=NULL){
1273      zWrite(f,vData->value,atoi(sizeMap->value)*sizeof(char));
1274    }
1275    else{
1276      zWrite(f,vData->value,(strlen(vData->value)+1)*sizeof(char));
1277    }
1278    close(f);
1279    setMapArray(outputs->content,"storage",imyIndex,pszDataSource);
1280    free(pszDataSource);
1281  }
1282
1283  /*
1284   * Create an empty map, set name, default size and extent
1285   */
1286  map* mapfileTemplate=getMapArray(outputs->content,"msInclude",imyIndex);
1287  mapObj *myMap=NULL;
1288  if(mapfileTemplate==NULL){
1289    myMap=msNewMapObj();
1290  }
1291  else{
1292    map* dataPath=getMapFromMaps(conf,"main","dataPath");
1293    map* sid=getMapFromMaps(conf,"lenv","sid");
1294    char *mapfileTemplatePath=(char*)malloc(((strlen(dataPath->value)+strlen(sid->value)+strlen(outputs->name)+10)*sizeof(char)));
1295    sprintf(mapfileTemplatePath,"%s/%s_%s.map",dataPath->value,outputs->name,sid->value);
1296    myMap=msLoadMap(mapfileTemplate->value,mapfileTemplatePath);
1297    if(myMap==NULL){
1298      setMapInMaps(conf,"lenv","message",_("Unable to open your template mapfile!"));
1299      return ;
1300    }
1301  }
1302  free(myMap->name);
1303  myMap->name=zStrdup("ZOO-Project_WXS_Server");
1304  msMapSetSize(myMap,2048,2048);
1305  msMapSetExtent(myMap,-1,-1,1,1);
1306 
1307  /*
1308   * Set imagepath and imageurl using tmpPath and tmpUrl from main.cfg
1309   */
1310  map *tmp1=getMapFromMaps(conf,"main","tmpPath");
1311  myMap->web.imagepath=zStrdup(tmp1->value);
1312  tmp1=getMapFromMaps(conf,"main","tmpUrl");
1313  myMap->web.imageurl=zStrdup(tmp1->value);
1314 
1315  /*
1316   * Define supported output formats
1317   */
1318  outputFormatObj *o1=msCreateDefaultOutputFormat(NULL,"AGG/PNG","png");
1319  o1->imagemode=MS_IMAGEMODE_RGBA;
1320  o1->transparent=MS_TRUE;
1321  o1->inmapfile=MS_TRUE;
1322  msAppendOutputFormat(myMap,msCloneOutputFormat(o1));
1323  msFreeOutputFormat(o1);
1324
1325#ifdef USE_KML
1326  outputFormatObj *o2=msCreateDefaultOutputFormat(NULL,"KML","kml");
1327  if(!o2){
1328    perror("Unable to initialize KML driver");
1329    fprintf(stderr,"Unable to initialize KML driver !\n");
1330  }else{
1331    o2->inmapfile=MS_TRUE; 
1332    msAppendOutputFormat(myMap,msCloneOutputFormat(o2));
1333    msFreeOutputFormat(o2);
1334  }
1335#endif
1336
1337  outputFormatObj *o3=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","tiff");
1338  if(!o3)
1339    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1340  else{
1341    o3->imagemode=MS_IMAGEMODE_INT16;
1342    o3->inmapfile=MS_TRUE; 
1343    msAppendOutputFormat(myMap,msCloneOutputFormat(o3));
1344    msFreeOutputFormat(o3);
1345  }
1346
1347  outputFormatObj *o4=msCreateDefaultOutputFormat(NULL,"GDAL/AAIGRID","grd");
1348  if(!o4)
1349    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1350  else{
1351    o4->imagemode=MS_IMAGEMODE_BYTE;
1352    o4->inmapfile=MS_TRUE; 
1353    msAppendOutputFormat(myMap,msCloneOutputFormat(o4));
1354    msFreeOutputFormat(o4);
1355  }
1356
1357#ifdef USE_CAIRO
1358  outputFormatObj *o5=msCreateDefaultOutputFormat(NULL,"CAIRO/PNG","cairopng");
1359  if(!o5)
1360    fprintf(stderr,"Unable to initialize CAIRO driver !\n");
1361  else{
1362    o5->imagemode=MS_IMAGEMODE_RGBA;
1363    o5->transparent=MS_TRUE;
1364    o5->inmapfile=MS_TRUE;
1365    msAppendOutputFormat(myMap,msCloneOutputFormat(o5));
1366    msFreeOutputFormat(o5);
1367  }
1368#endif
1369
1370 
1371  outputFormatObj *o6=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","geotiff");
1372  if(!o6)
1373    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1374  else{
1375    o6->imagemode=MS_IMAGEMODE_BYTE;
1376    o6->mimetype=strdup("image/geotiff");
1377    o6->inmapfile=MS_TRUE;
1378    msAppendOutputFormat(myMap,msCloneOutputFormat(o6));
1379    msFreeOutputFormat(o6);
1380  }
1381
1382 
1383  /*
1384   * Set default projection to EPSG:4326
1385   */
1386  msLoadProjectionStringEPSG(&myMap->projection,"EPSG:4326");
1387  myMap->transparent=1;
1388
1389  /*
1390   * Set mapserver PROJ_LIB/GDAL_DATA or any other config parameter from
1391   * the main.cfg [mapserver] section if any
1392   */
1393  maps *tmp3=getMaps(conf,"mapserver");
1394  if(tmp3!=NULL){
1395    map* tmp4=tmp3->content;
1396    while(tmp4!=NULL){
1397      msSetConfigOption(myMap,tmp4->name,tmp4->value);
1398      tmp4=tmp4->next;
1399    }
1400  }
1401
1402  /**
1403   * Set a ows_rootlayer_title, 
1404   */
1405  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_name", "ZOO_Project_Layer") == NULL){
1406#ifdef DEBUGMS
1407    fprintf(stderr,"Unable to add metadata");
1408#endif
1409    return;
1410  }
1411  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_title", "ZOO_Project_Layer") == NULL){
1412#ifdef DEBUGMS
1413    fprintf(stderr,"Unable to add metadata");
1414#endif
1415    return;
1416  }
1417
1418  /**
1419   * Enable all the WXS requests using ows_enable_request
1420   * see http://mapserver.org/trunk/development/rfc/ms-rfc-67.html
1421   */
1422  if (msInsertHashTable(&(myMap->web.metadata), "ows_enable_request", "*") == NULL){
1423#ifdef DEBUGMS
1424    fprintf(stderr,"Unable to add metadata");
1425#endif
1426    return;
1427  }
1428  msInsertHashTable(&(myMap->web.metadata), "ows_srs", "EPSG:4326");
1429
1430  /**
1431   * Set metadata extracted from main.cfg file maps
1432   */
1433  maps* cursor=conf;
1434  map* correspondance=getCorrespondance();
1435  while(cursor!=NULL){
1436    if(strstr(cursor->name,"_help")==NULL){
1437      map* _cursor=cursor->content;
1438      map* vMap;
1439      while(_cursor!=NULL){
1440        if((vMap=getMap(correspondance,_cursor->name))!=NULL){
1441          if (msInsertHashTable(&(myMap->web.metadata), vMap->value, _cursor->value) == NULL){
1442#ifdef DEBUGMS
1443            fprintf(stderr,"Unable to add metadata");
1444#endif
1445            freeMap(&correspondance);
1446            free(correspondance);
1447            return;
1448          }
1449        }
1450        _cursor=_cursor->next;
1451      }
1452    }
1453    cursor=cursor->next;
1454  }
1455  freeMap(&correspondance);
1456  free(correspondance);
1457
1458
1459  if(tryOgr(conf,outputs,myMap)<0)
1460    if(tryGdal(conf,outputs,myMap)<0)
1461      return ;
1462
1463  tmp1=getMapFromMaps(conf,"main","dataPath");
1464  char *tmpPath=(char*)malloc((13+strlen(tmp1->value))*sizeof(char));
1465  sprintf(tmpPath,"%s/symbols.sym",tmp1->value);
1466  msInitSymbolSet(&myMap->symbolset);
1467  myMap->symbolset.filename=zStrdup(tmpPath);
1468  free(tmpPath);
1469
1470  map* sid=getMapFromMaps(conf,"lenv","usid");
1471  char *mapPath=
1472    (char*)malloc((14+strlen(sid->value)+strlen(outputs->name)+strlen(tmp1->value))*sizeof(char));
1473  sprintf(mapPath,"%s/%s_%d_%s.map",tmp1->value,outputs->name,imyIndex,sid->value);
1474  msSaveMap(myMap,mapPath);
1475  saveMapNames(conf,outputs,mapPath);
1476  free(mapPath);
1477  //free(myMap->symbolset.filename);
1478  //msFreeSymbolSet(&myMap->symbolset);
1479  msFreeMap(myMap);
1480  //msFree(myMap);
1481  msGDALCleanup();
1482}
1483
1484/**
1485 * Save the map fullpath in a text file (.maps)
1486 * @param conf the main configuration map pointer
1487 * @param output the current output for which a mapfile has been generated
1488 * @param mapfile the mapfile saved to store in the text file
1489 */
1490void saveMapNames(maps* conf,maps* output,char* mapfile){
1491  map* storage=getMap(output->content,"storage");
1492  char *tmp=zStrdup(storage->value);
1493  tmp[strlen(tmp)-strlen(strrchr(tmp,'.'))]=0;
1494  char* mapName=(char*)malloc((strlen(tmp)+6)*sizeof(char*));
1495  sprintf(mapName,"%s.maps",tmp);
1496  FILE* myMaps=fopen(mapName,"a");
1497  if(myMaps!=NULL){
1498    fprintf(myMaps,"%s\n",mapfile);
1499    fclose(myMaps);
1500  } 
1501}
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