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

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

Check for md5sum of any file in the cache to avoid sending the same file on HPC server twice. Add the multiple LiteralData? inputs support for HPC services. Remove condition for defining SCALE for every band in the outputed MapServer? mapfile.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 48.4 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 ); /*GA_ReadOnly*/
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 %d ! %s\n",__FILE__,__LINE__,GDALGetProjectionRef( hDataset ));
1042    fflush(stderr);
1043    CPLErr sp=GDALSetProjection( hDataset , "+init=epsg:4326" );
1044    if(sp!=CE_None){
1045      fprintf(stderr,"NO SRS SET ! %s\n",CPLGetLastErrorMsg());
1046    }
1047  }
1048
1049  /**
1050   * Set extent
1051   */
1052  if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ){
1053    if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ){
1054
1055      double minX = adfGeoTransform[0]
1056        + adfGeoTransform[2] * GDALGetRasterYSize(hDataset);
1057      double minY = adfGeoTransform[3]
1058        + adfGeoTransform[5] * GDALGetRasterYSize(hDataset);
1059
1060      double maxX = adfGeoTransform[0]
1061        + adfGeoTransform[1] * GDALGetRasterXSize(hDataset);
1062      double maxY = adfGeoTransform[3]
1063        + adfGeoTransform[4] * GDALGetRasterXSize(hDataset);
1064
1065      setMsExtent(output,m,myLayer,minX,minY,maxX,maxY);
1066      char extent[1024];
1067      memset(&extent,0,1024);
1068      sprintf(extent,"%d,%d,%d,%d",minX,minY,maxX,maxY);
1069      setMapArray(output->content,"boundingbox",imyIndex,extent);
1070    }
1071  }else{
1072    int scale=1;
1073    if(m->width>2048){
1074      addIntToMapArray(output->content,"width",imyIndex,2048);
1075      scale=2048/m->width;
1076    }else
1077      addIntToMapArray(output->content,"width",imyIndex,m->width);
1078    addIntToMapArray(output->content,"height",imyIndex,m->height*scale);
1079  }
1080
1081  /**
1082   * Extract information about available bands to set the bandcount and the
1083   * processing directive
1084   */
1085  char nBands[3];
1086  memset(&nBands,0,3);
1087  int nBandsI=GDALGetRasterCount( hDataset );
1088  if(nBandsI<100){
1089    sprintf(nBands,"%d",GDALGetRasterCount( hDataset ));
1090    msInsertHashTable(&(myLayer->metadata), "ows_bandcount", nBands);
1091  }
1092  if(nBandsI>=3)
1093    if(nBandsI==4)
1094      msLayerAddProcessing(myLayer,"BANDS=1,2,3,4");
1095    else
1096      msLayerAddProcessing(myLayer,"BANDS=1,2,3");
1097  else if(nBandsI>=2)
1098    msLayerAddProcessing(myLayer,"BANDS=1,2");
1099  else
1100    msLayerAddProcessing(myLayer,"BANDS=1");
1101 
1102
1103  /**
1104   * Name available Bands
1105   */
1106  char lBands[7];
1107  char *nameBands=NULL;
1108  for( iBand = 0; iBand < nBandsI; iBand++ ){
1109    memset(&lBands,0,7);
1110    sprintf(lBands,"Band%d",iBand+1);   
1111    if(nameBands==NULL){
1112      nameBands=(char*)malloc((strlen(lBands)+1)*sizeof(char));
1113      sprintf(nameBands,"%s",lBands);
1114    }else{
1115      /*if(iBand<4)*/{
1116        char *tmpS=zStrdup(nameBands);
1117        nameBands=(char*)realloc(nameBands,(strlen(tmpS)+strlen(lBands)+2)*sizeof(char));
1118        sprintf(nameBands,"%s %s",tmpS,lBands);
1119        free(tmpS);
1120      }
1121    }
1122  }
1123  if(nameBands!=NULL){
1124    msInsertHashTable(&(myLayer->metadata), "ows_bandnames", nameBands);
1125    free(nameBands);
1126  }
1127
1128  /**
1129   * Loops over metadata information to setup specific information
1130   */
1131  for( iBand = 0; iBand < nBandsI; iBand++ ){
1132    double      pdfMin, pdfMax, pdfMean, pdfStdDev;
1133    hBand = GDALGetRasterBand( hDataset, iBand+1 );
1134
1135    CPLErrorReset();
1136    GDALGetRasterStatistics( hBand, TRUE, TRUE, &pdfMin, &pdfMax, &pdfMean, &pdfStdDev);
1137    //GDALComputeRasterStatistics( hBand, TRUE, &pdfMin, &pdfMax, &pdfMean, &pdfStdDev, NULL,NULL);
1138    char tmpN[21];
1139    sprintf(tmpN,"Band%d",iBand+1);
1140    if (CPLGetLastErrorType() == CE_None){
1141      char tmpMm[100],tmpMp[100];
1142      sprintf(tmpMm,"%.3f %.3f",pdfMin,pdfMax);
1143      sprintf(tmpMp,"SCALE_%d=%.3f,%.3f",iBand+1,pdfMean-(2*pdfStdDev),pdfMean+(2*pdfStdDev));
1144      char tmpI[31];     
1145      sprintf(tmpI,"%s_interval",tmpN);
1146      msInsertHashTable(&(myLayer->metadata), tmpI, tmpMm);
1147      //if(pdfMax>255)
1148      msLayerAddProcessing(myLayer,tmpMp);
1149      map* test=getMap(output->content,"msClassify");
1150      if(test!=NULL && strncasecmp(test->value,"true",4)==0){
1151        /**
1152         * Classify one band raster pixel value using regular interval
1153         */
1154        int _tmpColors[10][3]={
1155          {102,153,204},
1156          {51,102,153},
1157          {102,102,204},
1158          {51,204,0},
1159          {153,255,102},
1160          {204,255,102},
1161          {102,204,153},
1162          {255,69,64},
1163          {255,192,115},
1164          {255,201,115}
1165        };
1166         
1167        if(nBandsI==1){
1168          double delta=pdfMax-pdfMin;
1169          double interval=delta/10;
1170          double cstep=pdfMin;
1171          for(i=0;i<10;i++){
1172            /**
1173             * Create a new class
1174             */
1175            if(msGrowLayerClasses(myLayer) == NULL)
1176              return -1;
1177            if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
1178              return -1;
1179            if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
1180              return -1;
1181            if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
1182              return -1;
1183           
1184            /**
1185             * Set class name
1186             */
1187            char className[7];
1188            sprintf(className,"class%d",i);
1189            myLayer->CLASS[myLayer->numclasses]->name=zStrdup(className);
1190           
1191            /**
1192             * Set expression
1193             */
1194            char expression[1024];
1195            if(i+1<10)
1196              sprintf(expression,"([pixel]>=%.3f AND [pixel]<%.3f)",cstep,cstep+interval);
1197            else
1198              sprintf(expression,"([pixel]>=%.3f AND [pixel]<=%.3f)",cstep,cstep+interval);
1199            msLoadExpressionString(&myLayer->CLASS[myLayer->numclasses]->expression,expression);
1200           
1201            /**
1202             * Set color
1203             */
1204            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=_tmpColors[i][0];
1205            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=_tmpColors[i][1];
1206            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=_tmpColors[i][2];
1207            cstep+=interval;
1208            myLayer->CLASS[myLayer->numclasses]->numstyles++;
1209            myLayer->numclasses++;
1210           
1211          }
1212         
1213          char tmpMm[100];
1214          sprintf(tmpMm,"%.3f %.3f",pdfMin,pdfMax);
1215         
1216        }
1217      }
1218      else{
1219        if(nBandsI==1){
1220          myLayer->offsite.red=0;
1221          myLayer->offsite.green=0;
1222          myLayer->offsite.blue=0;
1223        }
1224      }
1225    }
1226    if( strlen(GDALGetRasterUnitType(hBand)) > 0 ){
1227      char tmpU[31];
1228      sprintf(tmpU,"%s_band_uom",tmpN);
1229      msInsertHashTable(&(myLayer->metadata), tmpU, GDALGetRasterUnitType(hBand));
1230    }
1231
1232  }
1233  msLayerAddProcessing(myLayer,"RESAMPLE=BILINEAR");
1234
1235  m->layerorder[m->numlayers] = m->numlayers;
1236  m->numlayers++;
1237  GDALClose( hDataset );
1238  GDALDestroyDriverManager();
1239  CPLCleanupTLS();
1240  storeMd5(pszFilename);
1241  return 1;
1242}
1243
1244/**
1245 * Create a MapFile for WMS, WFS or WCS Service output
1246 *
1247 * @param conf the conf maps containing the main.cfg settings
1248 * @param outputs a specific output maps
1249 */
1250void outputMapfile(maps* conf,maps* outputs){
1251  /**
1252   * First store the value on disk
1253   */
1254  int imyIndex=getPublishedId(outputs);
1255  map* mime=getMapArray(outputs->content,"mimeType",imyIndex);
1256  char *ext="data";
1257  if(mime!=NULL)
1258    if(strncasecmp(mime->value,"application/json",16)==0)
1259      ext="json";
1260
1261  map* storage=getMapArray(outputs->content,"storage",imyIndex);
1262  if(storage==NULL){
1263    map* tmpMap=getMapFromMaps(conf,"main","dataPath");
1264    map* sidMap=getMapFromMaps(conf,"lenv","usid");
1265    char *pszDataSource=(char*)malloc((strlen(tmpMap->value)+strlen(sidMap->value)+strlen(outputs->name)+17)*sizeof(char));
1266    sprintf(pszDataSource,"%s/ZOO_DATA_%d_%s_%s.%s",tmpMap->value,imyIndex,outputs->name,sidMap->value,ext);
1267    int f=zOpen(pszDataSource,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
1268    map *gfile=getMapArray(outputs->content,"generated_file",imyIndex);
1269    if(gfile!=NULL){
1270      readGeneratedFile(conf,outputs->content,gfile->value);       
1271    }
1272    map* sizeMap=getMapArray(outputs->content,"size",imyIndex);
1273    map* vData=getMapArray(outputs->content,"value",imyIndex);
1274    if(sizeMap!=NULL){
1275      zWrite(f,vData->value,atoi(sizeMap->value)*sizeof(char));
1276    }
1277    else{
1278      zWrite(f,vData->value,(strlen(vData->value)+1)*sizeof(char));
1279    }
1280    close(f);
1281    setMapArray(outputs->content,"storage",imyIndex,pszDataSource);
1282    free(pszDataSource);
1283  }
1284
1285  /*
1286   * Create an empty map, set name, default size and extent
1287   */
1288  map* mapfileTemplate=getMapArray(outputs->content,"msInclude",imyIndex);
1289  mapObj *myMap=NULL;
1290  if(mapfileTemplate==NULL){
1291    myMap=msNewMapObj();
1292  }
1293  else{
1294    map* dataPath=getMapFromMaps(conf,"main","dataPath");
1295    map* sid=getMapFromMaps(conf,"lenv","sid");
1296    char *mapfileTemplatePath=(char*)malloc(((strlen(dataPath->value)+strlen(sid->value)+strlen(outputs->name)+10)*sizeof(char)));
1297    sprintf(mapfileTemplatePath,"%s/%s_%s.map",dataPath->value,outputs->name,sid->value);
1298    myMap=msLoadMap(mapfileTemplate->value,mapfileTemplatePath);
1299    if(myMap==NULL){
1300      setMapInMaps(conf,"lenv","message",_("Unable to open your template mapfile!"));
1301      return ;
1302    }
1303  }
1304  free(myMap->name);
1305  myMap->name=zStrdup("ZOO-Project_WXS_Server");
1306  msMapSetSize(myMap,2048,2048);
1307  msMapSetExtent(myMap,-1,-1,1,1);
1308 
1309  /*
1310   * Set imagepath and imageurl using tmpPath and tmpUrl from main.cfg
1311   */
1312  map *tmp1=getMapFromMaps(conf,"main","tmpPath");
1313  myMap->web.imagepath=zStrdup(tmp1->value);
1314  tmp1=getMapFromMaps(conf,"main","tmpUrl");
1315  myMap->web.imageurl=zStrdup(tmp1->value);
1316 
1317  /*
1318   * Define supported output formats
1319   */
1320  outputFormatObj *o1=msCreateDefaultOutputFormat(NULL,"AGG/PNG","png");
1321  o1->imagemode=MS_IMAGEMODE_RGBA;
1322  o1->transparent=MS_TRUE;
1323  o1->inmapfile=MS_TRUE;
1324  msAppendOutputFormat(myMap,msCloneOutputFormat(o1));
1325  msFreeOutputFormat(o1);
1326
1327#ifdef USE_KML
1328  outputFormatObj *o2=msCreateDefaultOutputFormat(NULL,"KML","kml");
1329  if(!o2){
1330    perror("Unable to initialize KML driver");
1331    fprintf(stderr,"Unable to initialize KML driver !\n");
1332  }else{
1333    o2->inmapfile=MS_TRUE; 
1334    msAppendOutputFormat(myMap,msCloneOutputFormat(o2));
1335    msFreeOutputFormat(o2);
1336  }
1337#endif
1338
1339  outputFormatObj *o3=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","tiff");
1340  if(!o3)
1341    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1342  else{
1343    o3->imagemode=MS_IMAGEMODE_INT16;
1344    o3->inmapfile=MS_TRUE; 
1345    msAppendOutputFormat(myMap,msCloneOutputFormat(o3));
1346    msFreeOutputFormat(o3);
1347  }
1348
1349  outputFormatObj *o4=msCreateDefaultOutputFormat(NULL,"GDAL/AAIGRID","grd");
1350  if(!o4)
1351    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1352  else{
1353    o4->imagemode=MS_IMAGEMODE_BYTE;
1354    o4->inmapfile=MS_TRUE; 
1355    msAppendOutputFormat(myMap,msCloneOutputFormat(o4));
1356    msFreeOutputFormat(o4);
1357  }
1358
1359#ifdef USE_CAIRO
1360  outputFormatObj *o5=msCreateDefaultOutputFormat(NULL,"CAIRO/PNG","cairopng");
1361  if(!o5)
1362    fprintf(stderr,"Unable to initialize CAIRO driver !\n");
1363  else{
1364    o5->imagemode=MS_IMAGEMODE_RGBA;
1365    o5->transparent=MS_TRUE;
1366    o5->inmapfile=MS_TRUE;
1367    msAppendOutputFormat(myMap,msCloneOutputFormat(o5));
1368    msFreeOutputFormat(o5);
1369  }
1370#endif
1371
1372 
1373  outputFormatObj *o6=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","geotiff");
1374  if(!o6)
1375    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1376  else{
1377    o6->imagemode=MS_IMAGEMODE_BYTE;
1378    o6->mimetype=strdup("image/geotiff");
1379    o6->inmapfile=MS_TRUE;
1380    msAppendOutputFormat(myMap,msCloneOutputFormat(o6));
1381    msFreeOutputFormat(o6);
1382  }
1383
1384 
1385  /*
1386   * Set default projection to EPSG:4326
1387   */
1388  msLoadProjectionStringEPSG(&myMap->projection,"EPSG:4326");
1389  myMap->transparent=1;
1390
1391  /*
1392   * Set mapserver PROJ_LIB/GDAL_DATA or any other config parameter from
1393   * the main.cfg [mapserver] section if any
1394   */
1395  maps *tmp3=getMaps(conf,"mapserver");
1396  if(tmp3!=NULL){
1397    map* tmp4=tmp3->content;
1398    while(tmp4!=NULL){
1399      msSetConfigOption(myMap,tmp4->name,tmp4->value);
1400      tmp4=tmp4->next;
1401    }
1402  }
1403
1404  /**
1405   * Set a ows_rootlayer_title, 
1406   */
1407  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_name", "ZOO_Project_Layer") == NULL){
1408#ifdef DEBUGMS
1409    fprintf(stderr,"Unable to add metadata");
1410#endif
1411    return;
1412  }
1413  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_title", "ZOO_Project_Layer") == NULL){
1414#ifdef DEBUGMS
1415    fprintf(stderr,"Unable to add metadata");
1416#endif
1417    return;
1418  }
1419
1420  /**
1421   * Enable all the WXS requests using ows_enable_request
1422   * see http://mapserver.org/trunk/development/rfc/ms-rfc-67.html
1423   */
1424  if (msInsertHashTable(&(myMap->web.metadata), "ows_enable_request", "*") == NULL){
1425#ifdef DEBUGMS
1426    fprintf(stderr,"Unable to add metadata");
1427#endif
1428    return;
1429  }
1430  msInsertHashTable(&(myMap->web.metadata), "ows_srs", "EPSG:4326");
1431
1432  /**
1433   * Set metadata extracted from main.cfg file maps
1434   */
1435  maps* cursor=conf;
1436  map* correspondance=getCorrespondance();
1437  while(cursor!=NULL){
1438    if(strstr(cursor->name,"_help")==NULL){
1439      map* _cursor=cursor->content;
1440      map* vMap;
1441      while(_cursor!=NULL){
1442        if((vMap=getMap(correspondance,_cursor->name))!=NULL){
1443          if (msInsertHashTable(&(myMap->web.metadata), vMap->value, _cursor->value) == NULL){
1444#ifdef DEBUGMS
1445            fprintf(stderr,"Unable to add metadata");
1446#endif
1447            freeMap(&correspondance);
1448            free(correspondance);
1449            return;
1450          }
1451        }
1452        _cursor=_cursor->next;
1453      }
1454    }
1455    cursor=cursor->next;
1456  }
1457  freeMap(&correspondance);
1458  free(correspondance);
1459
1460
1461  if(tryOgr(conf,outputs,myMap)<0)
1462    if(tryGdal(conf,outputs,myMap)<0)
1463      return ;
1464
1465  tmp1=getMapFromMaps(conf,"main","dataPath");
1466  char *tmpPath=(char*)malloc((13+strlen(tmp1->value))*sizeof(char));
1467  sprintf(tmpPath,"%s/symbols.sym",tmp1->value);
1468  msInitSymbolSet(&myMap->symbolset);
1469  myMap->symbolset.filename=zStrdup(tmpPath);
1470  free(tmpPath);
1471
1472  map* sid=getMapFromMaps(conf,"lenv","usid");
1473  char *mapPath=
1474    (char*)malloc((14+strlen(sid->value)+strlen(outputs->name)+strlen(tmp1->value))*sizeof(char));
1475  sprintf(mapPath,"%s/%s_%d_%s.map",tmp1->value,outputs->name,imyIndex,sid->value);
1476  msSaveMap(myMap,mapPath);
1477  saveMapNames(conf,outputs,mapPath);
1478  free(mapPath);
1479  //free(myMap->symbolset.filename);
1480  //msFreeSymbolSet(&myMap->symbolset);
1481  msFreeMap(myMap);
1482  //msFree(myMap);
1483  msGDALCleanup();
1484}
1485
1486/**
1487 * Save the map fullpath in a text file (.maps)
1488 * @param conf the main configuration map pointer
1489 * @param output the current output for which a mapfile has been generated
1490 * @param mapfile the mapfile saved to store in the text file
1491 */
1492void saveMapNames(maps* conf,maps* output,char* mapfile){
1493  map* storage=getMap(output->content,"storage");
1494  char *tmp=zStrdup(storage->value);
1495  tmp[strlen(tmp)-strlen(strrchr(tmp,'.'))]=0;
1496  char* mapName=(char*)malloc((strlen(tmp)+6)*sizeof(char*));
1497  sprintf(mapName,"%s.maps",tmp);
1498  FILE* myMaps=fopen(mapName,"a");
1499  if(myMaps!=NULL){
1500    fprintf(myMaps,"%s\n",mapfile);
1501    fclose(myMaps);
1502  }
1503  free(mapName);
1504  free(tmp);
1505}
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