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

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

Fixes for supporting properly the memory=protect which force the ZOO-Kernel to not store any downloaded files in memory. Add footer to the HPC support. Fix the autotools to build service_json and sshapi only when required so, when HPC support is activated, this also avoid adding too much dependencies at compilation time. Store md5 of the downloaded files to avoid uploading on HPC server the same file more than once, in case the md5 correspond.

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