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

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

Fix issue #163 and add support for extra cookie through definition of ecookie array map and the corresponding ecookie_lenght. This give the capability to return more than only a single Cookie.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 48.2 KB
RevLine 
[579]1/*
[379]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
[586]25/**
26 * Cross platform definition of layerObj->class
27 */
[370]28#ifndef WIN32
29#define CLASS class
30#else
31#define CLASS _class
32#endif
[297]33#include "service_internal_ms.h"
[640]34#include "server_internal.h"
35#include "response_print.h"
[297]36
37/**
[586]38 * Get a list of configuration keys having a corresponding mandatory ows_*.
[297]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
[586]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").
[297]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
[586]77/**
[860]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){
[867]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    }
[860]88  }
89  return 0;
90}
[867]91
[860]92/**
[586]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 */
[297]103void setMapSize(maps* output,double minx,double miny,double maxx,double maxy){
[860]104  int imyIndex=getPublishedId(output);
[297]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){
[860]136    setMapArray(output->content,"width",imyIndex,sWidth);
137    setMapArray(output->content,"height",imyIndex,sHeight);
[297]138  }
139}
140
[586]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 */
[297]148void setReferenceUrl(maps* m,maps* tmpI){
[862]149  int imyIndex=getPublishedId(tmpI);
150  if(getMapArray(tmpI->content,"ref_wms_link",imyIndex)!=NULL)
151    return;
152  outputMapfile(m,tmpI);
[297]153  map *msUrl=getMapFromMaps(m,"main","mapserverAddress");
[607]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  }
[860]159  if(getMapArray(tmpI->content,"ref_wms_link",imyIndex)!=NULL)
160    return;
[854]161  int finalProto=-1;
[297]162  map *msOgcVersion=getMapFromMaps(m,"main","msOgcVersion");
163  map *dataPath=getMapFromMaps(m,"main","dataPath");
[453]164  map *sid=getMapFromMaps(m,"lenv","usid");
[860]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);
[862]172  map* layerName=getMapArray(tmpI->content,"msLayer",imyIndex);
[854]173  char options[4][5][25]={
[297]174    {"WMS","1.3.0","GetMap","layers=%s","wms_extent"},
[862]175    {"WFS","1.0.0","GetFeature","typename=%s","wcs_extent"},
[854]176    {"WCS","2.0.0","GetCoverage","coverageid=%s","wcs_extent"},
[862]177    {"WCS","1.0.0","GetCoverage","coverage=%s","wcs_extent"}
[297]178  };
[862]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)){
[860]183    map* minNb=getMap(tmpI->content,"minoccurs");
[862]184    map* useMs=getMap(tmpI->content,"useMapserver");
185    if((minNb==NULL || atoi(minNb->value)>=1) && useMs!=NULL && strncasecmp(useMs->value,"true",4)==0){
[860]186      setMapInMaps(m,"lenv","mapError","true");
187      setMapInMaps(m,"lenv","locator",tmpI->name);
[862]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."));
[860]192      if(getMapFromMaps(m,"lenv","state")==NULL)
193        errorException (m, _("Unable to find any geographic data"), "WrongInputData", tmpI->name);
194    }
[854]195    return;
196  }
[297]197  int proto=0;
198  if(rformat==NULL){
[860]199    rformat=getMapArray(tmpI->content,"mimeType",imyIndex);
[297]200  }
201  if(strncasecmp(rformat->value,"text/xml",8)==0)
202    proto=1;
[839]203  if(strncasecmp(rformat->value,"image/tiff",10)==0 ||
204     strncasecmp(rformat->value,"image/geotiff",10)==0)
[297]205    proto=2;
[860]206  int hasFormat=-1;
[490]207  if(protoMap!=NULL){
[860]208    hasFormat=1;
209    if(strncasecmp(protoMap->value,"WMS",3)==0){
[297]210      proto=0;
[860]211      rformat=createMap("value","image/png");
212    }
[490]213    else{
[860]214      if(strncasecmp(protoMap->value,"WFS",3)==0){
[490]215        proto=1;
[860]216        rformat=createMap("value","text/xml");
217      }
218      else {
[490]219        proto=2;
[860]220        rformat=createMap("value","image/tiff");
221      }
[490]222    }
223  }
[297]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
[860]232
233  map* extent=getMapArray(tmpI->content,options[proto][4],imyIndex);
234  map* crs=getMapArray(tmpI->content,"crs",imyIndex);
[402]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  }
[297]243  char layers[128];
[862]244  if(layerName==NULL)
245    sprintf(layers,options[proto][3],tmpI->name);
246  else
247    sprintf(layers,options[proto][3],layerName->value);
[867]248
[860]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  }
[850]273 
[860]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
[357]277  if(proto>0){
[854]278    if(proto==2)
279      finalProto=1;
[851]280    sprintf(webService_url,
[860]281            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
[851]282            msUrl->value,
283            dataPath->value,
284            tmpI->name,
[860]285            imyIndex,
[851]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){
[860]296      setMapArray(tmpI->content,"ref_wcs_link",imyIndex,webService_url);
[851]297    }
298    else{
[860]299      setMapArray(tmpI->content,"ref_wfs_link",imyIndex,webService_url);
[851]300    }
[850]301    proto=0;
[860]302    freeMap(&rformat);
303    free(rformat);
[850]304    rformat=createMap("mimeType","image/png");
[357]305  }
306  else{
[851]307    sprintf(webService_url,
[860]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",
[851]309            msUrl->value,
310            dataPath->value,
311            tmpI->name,
[860]312            imyIndex,
[851]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            );
[860]324    setMapArray(tmpI->content,"ref_wms_link",imyIndex,webService_url);
[850]325    if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
326      proto=2;
[860]327      freeMap(&rformat);
328      free(rformat);
[850]329      rformat=createMap("mimeType","image/tiff");
330    }
331    else{
332      proto=1;
[860]333      freeMap(&rformat);
334      free(rformat);
[850]335      rformat=createMap("mimeType","text/xml");
336    }
[357]337  }
[860]338  setMapArray(tmpI->content,"Reference",imyIndex,webService_url);
[854]339  memset(layers,0,128);
340  sprintf(layers,options[proto][3],tmpI->name);
[850]341  protoVersion=options[proto][1];
[860]342  extent=getMapArray(tmpI->content,options[proto][4],imyIndex);
[850]343  memset(webService_url,0,strlen(webService_url));
344  if(proto>0){
[854]345    if(proto==2)
346      finalProto=1;
[851]347    sprintf(webService_url,
[860]348            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
[851]349            msUrl->value,
350            dataPath->value,
351            tmpI->name,
[860]352            imyIndex,
[851]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){
[860]363      setMapArray(tmpI->content,"ref_wcs_link",imyIndex,webService_url);
[851]364    }
365    else{
[860]366      setMapArray(tmpI->content,"ref_wfs_link",imyIndex,webService_url);
[851]367    }
368  }else{
369    sprintf(webService_url,
[860]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",
[851]371            msUrl->value,
372            dataPath->value,
373            tmpI->name,
[860]374            imyIndex,
[851]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            );
[860]386    setMapArray(tmpI->content,"ref_wms_link",imyIndex,webService_url);
[850]387  }
[854]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];
[860]393    extent=getMapArray(tmpI->content,options[proto][4],imyIndex);
[854]394    memset(webService_url,0,strlen(webService_url));
[860]395    freeMap(&rformat);
396    free(rformat);
397    rformat=createMap("value","image/tiff");
[854]398    sprintf(webService_url,
[860]399            "%s?map=%s/%s_%d_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
[854]400            msUrl->value,
401            dataPath->value,
402            tmpI->name,
[860]403            imyIndex,
[854]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            );
[860]413    setMapArray(tmpI->content,"ref_wcs_preview_link",imyIndex,webService_url);
[854]414  }
[402]415  if(hasCRS==0){
416    freeMap(&crs);
417    free(crs);
418  }
[851]419  freeMap(&rformat);
420  free(rformat);
[492]421  free(webService_url);
[297]422}
423
424/**
[586]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
[297]433 */
434void setSrsInformations(maps* output,mapObj* m,layerObj* myLayer,
435                        char* pszProjection){
436  OGRSpatialReferenceH  hSRS;
437  map* msSrs=NULL;
[860]438  int imyIndex=getPublishedId(output);
[297]439  hSRS = OSRNewSpatialReference(NULL);
[451]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];
[776]452        sprintf(tmpSrss,"EPSG:4326 EPSG:900913 EPSG:3857 %s",tmpSrs);
[451]453       
454        msInsertHashTable(&(m->web.metadata), "ows_srs", tmpSrss);
455        msInsertHashTable(&(myLayer->metadata), "ows_srs", tmpSrss);
456       
[297]457#ifdef DEBUGMS
[451]458        fprintf(stderr,"isGeo %b\n\n",OSRIsGeographic(hSRS)==TRUE);
[297]459#endif
[451]460        if(output!=NULL){
[297]461          if(OSRIsGeographic(hSRS)==TRUE)
[860]462            setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
[297]463          else
[860]464            setMapArray(output->content,"crs_isGeographic",imyIndex,"false");
465          setMapArray(output->content,"crs",imyIndex,tmpSrs);
[297]466        }
467      }
468      else{
[451]469        OSRExportToProj4(hSRS,&proj4Str);
[475]470        if(proj4Str!=NULL && strlen(proj4Str)>0){
[451]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)
[860]478              setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
[451]479            else
[860]480              setMapArray(output->content,"crs_isGeographic",imyIndex,"false");
[451]481          }
[492]482          free(proj4Str);
[451]483        }
484        else{
485          msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
486          msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
487          if(output!=NULL){
[860]488            setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
[451]489          }
490        }
[297]491        if(output!=NULL){
[860]492          setMapArray(output->content,"crs",imyIndex,"EPSG:4326");
493          setMapArray(output->content,"real_extent",imyIndex,"true");
[297]494        }
[776]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");
[297]497      }
498    }
499  }
500  else{
501    if(output!=NULL){
[860]502      msSrs=getMapArray(output->content,"msSrs",imyIndex);
[297]503    }
504    if(msSrs!=NULL){
505      msLoadProjectionStringEPSG(&m->projection,msSrs->value);
[330]506      msLoadProjectionStringEPSG(&myLayer->projection,msSrs->value);
[297]507      char tmpSrs[128];
[776]508      sprintf(tmpSrs,"%s EPSG:4326 EPSG:900913 EPSG:3857",msSrs->value);
[297]509      msInsertHashTable(&(m->web.metadata),"ows_srs",tmpSrs);
510      msInsertHashTable(&(myLayer->metadata),"ows_srs",tmpSrs);
511    }else{
512      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
[330]513      msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
[776]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");
[297]516    }
[362]517    if(output!=NULL){
[860]518      setMapArray(output->content,"crs",imyIndex,msSrs->value);
519      setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
[362]520    }
[297]521  }
522
523  OSRDestroySpatialReference( hSRS );
524}
525
[586]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 */
[297]539void setMsExtent(maps* output,mapObj* m,layerObj* myLayer,
540                 double minX,double minY,double maxX,double maxY){
[860]541  int imyIndex=getPublishedId(output);
[297]542  msMapSetExtent(m,minX,minY,maxX,maxY);
[862]543  m->maxsize=4096;
[297]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){
[860]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 
[357]569    if(test!=NULL){
570      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
[860]571      map* isGeo=getMapArray(output->content,"crs_isGeographic",imyIndex);
[434]572#ifdef DEBUGMS
[360]573      fprintf(stderr,"isGeo = %s\n",isGeo->value);
[434]574#endif
[860]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);
[360]578        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
[860]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);
[360]584      sprintf(tmpSrsStr,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
[860]585      setMapArray(output->content,"wcs_extent",imyIndex,tmpExtent);
[357]586    }else{
[860]587      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
588      setMapArray(output->content,"wgs84_extent",imyIndex,tmpExtent);
[357]589      sprintf(tmpExtent,"%f,%f,%f,%f",minX, minY, maxX, maxY);
[860]590      map* isGeo=getMapArray(output->content,"crs_isGeographic",imyIndex);
[402]591      if(isGeo!=NULL){
[434]592#ifdef DEBUGMS
[402]593        fprintf(stderr,"isGeo = %s\n",isGeo->value);
[434]594#endif
[402]595        if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
596          sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
597      }
[860]598      setMapArray(output->content,"wms_extent",imyIndex,tmpExtent); 
[357]599      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",minX,minY,maxX,maxY);
[860]600      setMapArray(output->content,"wcs_extent",imyIndex,tmpExtent);
[357]601    }
[297]602  }
603
604  setMapSize(output,minX,minY,maxX,maxY);
605}
606
[586]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 */
[297]614int tryOgr(maps* conf,maps* output,mapObj* m){
[860]615  int imyIndex=getPublishedId(output);
616  map* tmpMap=getMapArray(output->content,"storage",imyIndex);
[297]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
[854]625   *
[364]626  OGRDataSourceH poDS1 = NULL;
[297]627  OGRSFDriverH *poDriver1 = NULL;
628  char *dsName=(char*)malloc((8+strlen(pszDataSource)+1)*sizeof(char));
[453]629  char *odsName=zStrdup(pszDataSource);
630  char *sdsName=zStrdup(pszDataSource);
[623]631  char *demo=".data";
[297]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");
[492]649  free(odsName);
[297]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);
[434]659#ifdef DEBUGMS
[297]660  fprintf(stderr,"Try loading %s",dsName);
[434]661#endif
[297]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");
[854]666    fprintf(stderr,"Remove ZIP File!\n");
667    unlink(odsName);
[839]668    //OGR_DS_Destroy(poDS1);
[297]669  }else{
[434]670#ifdef DEBUGMS
[297]671    fprintf(stderr,"The DataSource is a  ZIP File\n");
[434]672#endif
[297]673    char** demo=VSIReadDir(dsName);
674    int i=0;
[453]675    zMkdir(sdsName
[364]676#ifndef WIN32
677                ,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
678#endif
679                );
[297]680    while(demo[i]!=NULL){
[434]681#ifdef DEBUGMS
[297]682      fprintf(stderr,"ZIP File content : %s\n",demo[i]);
[434]683#endif
[297]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");
[434]689#ifdef DEBUGMS
[297]690      fprintf(stderr,"open : %s\n",tmpDs);
[434]691#endif
[297]692      VSIFSeekL(vsif,0,SEEK_END);
[453]693      vsi_l_offset size=VSIFTellL(vsif);
[434]694#ifdef DEBUGMS
[297]695      fprintf(stderr,"size : %d\n",size);
[434]696#endif
[297]697      VSIFSeekL(vsif,0,SEEK_SET);
[453]698      char *vsifcontent=(char*) malloc(((int)size+1)*sizeof(char));
699      VSIFReadL(vsifcontent,1,(size_t)size,vsif);
[297]700      char *fpath=(char*) malloc((strlen(sdsName)+strlen(demo[1])+2)*sizeof(char));
701      sprintf(fpath,"%s/%s",sdsName,demo[i]);
[453]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);
[297]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){
[434]710#ifdef DEBUGMS
[297]711        fprintf(stderr,"*** DEBUG %s\n",strstr(tmpP,"."));
[434]712#endif
[297]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;
[434]719#ifdef DEBUGMS
[297]720          fprintf(stderr,"*** DEBUG %s\n",pszDataSource);
[434]721#endif
[297]722        }
723      }
724      VSIFCloseL(vsif);
725      i++;
726    }
[851]727    OGR_DS_Destroy(poDS1);
[854]728    }
[492]729  free(sdsName);
[854]730  free(dsName);*/
[850]731 
[364]732  OGRDataSourceH poDS = NULL;
[297]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
[860]746  setMapArray(output->content,"geodatatype",imyIndex,"vector");
[297]747  int iLayer = 0;
748  for( iLayer=0; iLayer < OGR_DS_GetLayerCount(poDS); iLayer++ ){
[364]749    OGRLayerH poLayer = OGR_DS_GetLayer(poDS,iLayer);
[297]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     */
[862]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];
[297]773    }
[862]774   
[434]775#ifdef DEBUGMS
[297]776    dumpMaps(output);
[434]777#endif
[453]778    myLayer->name = zStrdup(output->name);
[297]779    myLayer->tileitem=NULL;
[453]780    myLayer->data = zStrdup(OGR_L_GetName(poLayer));
781    myLayer->connection = zStrdup(pszDataSource);
[297]782    myLayer->index = m->numlayers;
783    myLayer->dump = MS_TRUE;
784    myLayer->status = MS_ON;
785    msConnectLayer(myLayer,MS_OGR,pszDataSource);
786
[860]787    addIntToMapArray(output->content,"nb_features",imyIndex,OGR_L_GetFeatureCount(poLayer,1));
[854]788
[297]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);
[492]836      free(wkt);
[297]837    }
838    else{
[860]839      setMapArray(output->content,"crs",imyIndex,"EPSG:4326");
840      setMapArray(output->content,"crs_isGeographic",imyIndex,"true");
[297]841      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
[776]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");
[297]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);
[839]849      char extent[1024];
850      memset(&extent,0,1024);
851      sprintf(extent,"%d,%d,%d,%d",oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY);
[860]852      setMapArray(output->content,"boundingbox",imyIndex,extent);
[297]853    }
854 
855    /**
856     * Detect the FID column or use the first attribute field as FID
857     */
[364]858    char *fid=(char*)OGR_L_GetFIDColumn(poLayer);
[297]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);
[364]864        fid=(char*)OGR_Fld_GetNameRef(fdef);
[297]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);
[860]871    map* tmpMap=getMapArray(output->content,"title",imyIndex);
[297]872    if(tmpMap!=NULL)
873      msInsertHashTable(&(myLayer->metadata), "ows_title", tmpMap->value);
874    else
875      msInsertHashTable(&(myLayer->metadata), "ows_title", "Default Title");
[862]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;
[297]886      /**
[862]887       * Apply msStyle else fallback to the default style
[297]888       */
[862]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       
[297]917      }
[862]918      myLayer->CLASS[myLayer->numclasses]->numstyles++;
919      myLayer->numclasses++;
[379]920   
[862]921      m->layerorder[m->numlayers] = m->numlayers;
922      m->numlayers++;
[297]923
[862]924    }
[297]925  }
[851]926  OGR_DS_Destroy(poDS);
[839]927  //OGRCleanupAll();
[297]928
929  return 1;
930}
931
[586]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 */
[297]939int tryGdal(maps* conf,maps* output,mapObj* m){
[860]940  int imyIndex=getPublishedId(output);
941  map* tmpMap=getMapArray(output->content,"storage",imyIndex);
[297]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();
[854]952  hDataset = GDALOpen( pszFilename, GA_Update );
[297]953  if( hDataset == NULL ){
954#ifdef DEBUGMS
[366]955    fprintf(stderr,"Unable to access the DataSource %s \n",pszFilename);
[297]956#endif
[860]957    setMapArray(output->content,"geodatatype",imyIndex,"other");
[297]958    setMapInMaps(conf,"lenv","message","gdalinfo failed - unable to open");
959    GDALDestroyDriverManager();
960    return -1;
961  }
962#ifdef DEBUGMS
[451]963  fprintf(stderr,"Accessing the DataSource %s %d\n",pszFilename,__LINE__);
[297]964#endif
965
[860]966  setMapArray(output->content,"geodatatype",imyIndex,"raster");
[297]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  }
[451]976  m->layers[m->numlayers]->index=m->numlayers;
[297]977
978  layerObj* myLayer=m->layers[m->numlayers];
[453]979  myLayer->name = zStrdup(output->name);
[297]980  myLayer->tileitem=NULL;
[453]981  myLayer->data = zStrdup(pszFilename);
[297]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;
[860]988  tmpMap=getMapArray(output->content,"title",imyIndex);
[297]989  if(tmpMap!=NULL)
990    title=tmpMap->value;
991  char *abstract=output->name;
[860]992  tmpMap=getMapArray(output->content,"abstract",imyIndex);
[297]993  if(tmpMap!=NULL)
994    abstract=tmpMap->value;
[451]995
[297]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 );
[862]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;
[860]1014  addIntToMapArray(output->content,"nb_pixels",imyIndex,GDALGetRasterXSize( hDataset )*GDALGetRasterYSize( hDataset ));
[862]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    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)));   
1023  }
1024  //
1025   
[297]1026  /**
1027   * Set projection using Authority Code and Name if available or fallback to
1028   * proj4 definition if available or fallback to default EPSG:4326
1029   */
[366]1030  const char *tRef=GDALGetProjectionRef( hDataset );
1031  if( tRef != NULL && strlen(tRef)>0 ){
[297]1032    char *pszProjection;
1033    pszProjection = (char *) GDALGetProjectionRef( hDataset );
[607]1034#ifdef DEBUGMS
[297]1035    fprintf(stderr,"Accessing the DataSource %s\n",GDALGetProjectionRef( hDataset ));
[607]1036#endif
[297]1037    setSrsInformations(output,m,myLayer,pszProjection);
[453]1038  }else{
[854]1039    fprintf(stderr,"NO SRS FOUND ! %s\n",GDALGetProjectionRef( hDataset ));
1040    CPLErr sp=GDALSetProjection( hDataset , "+init=epsg:4326" );
1041    if(sp!=CE_None){
1042      fprintf(stderr,"NO SRS FOUND ! %s\n",CPLGetLastErrorMsg());
1043    }
[453]1044  }
[297]1045
1046  /**
1047   * Set extent
1048   */
1049  if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ){
1050    if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ){
1051
1052      double minX = adfGeoTransform[0]
1053        + adfGeoTransform[2] * GDALGetRasterYSize(hDataset);
1054      double minY = adfGeoTransform[3]
1055        + adfGeoTransform[5] * GDALGetRasterYSize(hDataset);
1056
1057      double maxX = adfGeoTransform[0]
1058        + adfGeoTransform[1] * GDALGetRasterXSize(hDataset);
1059      double maxY = adfGeoTransform[3]
1060        + adfGeoTransform[4] * GDALGetRasterXSize(hDataset);
1061
[839]1062      setMsExtent(output,m,myLayer,minX,minY,maxX,maxY);
1063      char extent[1024];
1064      memset(&extent,0,1024);
1065      sprintf(extent,"%d,%d,%d,%d",minX,minY,maxX,maxY);
[860]1066      setMapArray(output->content,"boundingbox",imyIndex,extent);
[297]1067    }
[854]1068  }else{
1069    int scale=1;
1070    if(m->width>2048){
[860]1071      addIntToMapArray(output->content,"width",imyIndex,2048);
[854]1072      scale=2048/m->width;
1073    }else
[860]1074      addIntToMapArray(output->content,"width",imyIndex,m->width);
1075    addIntToMapArray(output->content,"height",imyIndex,m->height*scale);
[297]1076  }
1077
1078  /**
1079   * Extract information about available bands to set the bandcount and the
1080   * processing directive
1081   */
[781]1082  char nBands[3];
[839]1083  memset(&nBands,0,3);
[297]1084  int nBandsI=GDALGetRasterCount( hDataset );
[839]1085  if(nBandsI<100){
1086    sprintf(nBands,"%d",GDALGetRasterCount( hDataset ));
1087    msInsertHashTable(&(myLayer->metadata), "ows_bandcount", nBands);
1088  }
[297]1089  if(nBandsI>=3)
[854]1090    if(nBandsI==4)
1091      msLayerAddProcessing(myLayer,"BANDS=1,2,3,4");
1092    else
1093      msLayerAddProcessing(myLayer,"BANDS=1,2,3");
[297]1094  else if(nBandsI>=2)
1095    msLayerAddProcessing(myLayer,"BANDS=1,2");
1096  else
1097    msLayerAddProcessing(myLayer,"BANDS=1");
[854]1098 
[297]1099
1100  /**
1101   * Name available Bands
1102   */
[781]1103  char lBands[7];
[297]1104  char *nameBands=NULL;
1105  for( iBand = 0; iBand < nBandsI; iBand++ ){
[854]1106    memset(&lBands,0,7);
[839]1107    sprintf(lBands,"Band%d",iBand+1);   
[297]1108    if(nameBands==NULL){
1109      nameBands=(char*)malloc((strlen(lBands)+1)*sizeof(char));
1110      sprintf(nameBands,"%s",lBands);
1111    }else{
[854]1112      /*if(iBand<4)*/{
[453]1113        char *tmpS=zStrdup(nameBands);
[839]1114        nameBands=(char*)realloc(nameBands,(strlen(tmpS)+strlen(lBands)+2)*sizeof(char));
[297]1115        sprintf(nameBands,"%s %s",tmpS,lBands);
1116        free(tmpS);
1117      }
1118    }
1119  }
[839]1120  if(nameBands!=NULL){
1121    msInsertHashTable(&(myLayer->metadata), "ows_bandnames", nameBands);
1122    free(nameBands);
1123  }
1124
[297]1125  /**
[781]1126   * Loops over metadata information to setup specific information
[297]1127   */
1128  for( iBand = 0; iBand < nBandsI; iBand++ ){
[854]1129    double      pdfMin, pdfMax, pdfMean, pdfStdDev;
[297]1130    hBand = GDALGetRasterBand( hDataset, iBand+1 );
1131
1132    CPLErrorReset();
[854]1133    GDALComputeRasterStatistics( hBand, TRUE, &pdfMin, &pdfMax, &pdfMean, &pdfStdDev, NULL,NULL);
[297]1134    char tmpN[21];
1135    sprintf(tmpN,"Band%d",iBand+1);
1136    if (CPLGetLastErrorType() == CE_None){
[854]1137      char tmpMm[100],tmpMp[100];
1138      sprintf(tmpMm,"%.3f %.3f",pdfMin,pdfMax);
1139      sprintf(tmpMp,"SCALE_%d=%.3f,%.3f",iBand+1,pdfMean-(2*pdfStdDev),pdfMean+(2*pdfStdDev));
[839]1140      char tmpI[31];     
[297]1141      sprintf(tmpI,"%s_interval",tmpN);
1142      msInsertHashTable(&(myLayer->metadata), tmpI, tmpMm);
[854]1143      if(pdfMax>255)
1144        msLayerAddProcessing(myLayer,tmpMp);
[300]1145      map* test=getMap(output->content,"msClassify");
1146      if(test!=NULL && strncasecmp(test->value,"true",4)==0){
1147        /**
1148         * Classify one band raster pixel value using regular interval
1149         */
1150        int _tmpColors[10][3]={
1151          {102,153,204},
1152          {51,102,153},
1153          {102,102,204},
1154          {51,204,0},
1155          {153,255,102},
1156          {204,255,102},
1157          {102,204,153},
1158          {255,69,64},
1159          {255,192,115},
1160          {255,201,115}
1161        };
1162         
1163        if(nBandsI==1){
[854]1164          double delta=pdfMax-pdfMin;
[300]1165          double interval=delta/10;
[854]1166          double cstep=pdfMin;
[300]1167          for(i=0;i<10;i++){
1168            /**
1169             * Create a new class
1170             */
1171            if(msGrowLayerClasses(myLayer) == NULL)
[364]1172              return -1;
[370]1173            if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
[364]1174              return -1;
[370]1175            if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
[364]1176              return -1;
[370]1177            if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
[364]1178              return -1;
[300]1179           
1180            /**
1181             * Set class name
1182             */
1183            char className[7];
1184            sprintf(className,"class%d",i);
[453]1185            myLayer->CLASS[myLayer->numclasses]->name=zStrdup(className);
[300]1186           
1187            /**
1188             * Set expression
1189             */
1190            char expression[1024];
1191            if(i+1<10)
1192              sprintf(expression,"([pixel]>=%.3f AND [pixel]<%.3f)",cstep,cstep+interval);
1193            else
1194              sprintf(expression,"([pixel]>=%.3f AND [pixel]<=%.3f)",cstep,cstep+interval);
[370]1195            msLoadExpressionString(&myLayer->CLASS[myLayer->numclasses]->expression,expression);
[300]1196           
1197            /**
1198             * Set color
1199             */
[370]1200            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=_tmpColors[i][0];
1201            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=_tmpColors[i][1];
1202            myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=_tmpColors[i][2];
[300]1203            cstep+=interval;
[370]1204            myLayer->CLASS[myLayer->numclasses]->numstyles++;
[300]1205            myLayer->numclasses++;
1206           
1207          }
1208         
1209          char tmpMm[100];
[854]1210          sprintf(tmpMm,"%.3f %.3f",pdfMin,pdfMax);
[300]1211         
[297]1212        }
1213      }
[752]1214      else{
1215        if(nBandsI==1){
1216          myLayer->offsite.red=0;
1217          myLayer->offsite.green=0;
1218          myLayer->offsite.blue=0;
1219        }
1220      }
[297]1221    }
1222    if( strlen(GDALGetRasterUnitType(hBand)) > 0 ){
[839]1223      char tmpU[31];
[297]1224      sprintf(tmpU,"%s_band_uom",tmpN);
1225      msInsertHashTable(&(myLayer->metadata), tmpU, GDALGetRasterUnitType(hBand));
1226    }
1227
1228  }
[854]1229  msLayerAddProcessing(myLayer,"RESAMPLE=BILINEAR");
[297]1230
1231  m->layerorder[m->numlayers] = m->numlayers;
1232  m->numlayers++;
1233  GDALClose( hDataset );
1234  GDALDestroyDriverManager();
1235  CPLCleanupTLS();
1236  return 1;
1237}
1238
1239/**
1240 * Create a MapFile for WMS, WFS or WCS Service output
[586]1241 *
1242 * @param conf the conf maps containing the main.cfg settings
1243 * @param outputs a specific output maps
[297]1244 */
1245void outputMapfile(maps* conf,maps* outputs){
1246  /**
[586]1247   * First store the value on disk
[297]1248   */
[860]1249  int imyIndex=getPublishedId(outputs);
1250  map* mime=getMapArray(outputs->content,"mimeType",imyIndex);
[360]1251  char *ext="data";
1252  if(mime!=NULL)
1253    if(strncasecmp(mime->value,"application/json",16)==0)
1254      ext="json";
[458]1255
[860]1256  map* storage=getMapArray(outputs->content,"storage",imyIndex);
[854]1257  if(storage==NULL){
1258    map* tmpMap=getMapFromMaps(conf,"main","dataPath");
1259    map* sidMap=getMapFromMaps(conf,"lenv","usid");
1260    char *pszDataSource=(char*)malloc((strlen(tmpMap->value)+strlen(sidMap->value)+strlen(outputs->name)+17)*sizeof(char));
[860]1261    sprintf(pszDataSource,"%s/ZOO_DATA_%d_%s_%s.%s",tmpMap->value,imyIndex,outputs->name,sidMap->value,ext);
[854]1262    int f=zOpen(pszDataSource,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
[860]1263    map *gfile=getMapArray(outputs->content,"generated_file",imyIndex);
[854]1264    if(gfile!=NULL){
1265      readGeneratedFile(conf,outputs->content,gfile->value);       
1266    }
[860]1267    map* sizeMap=getMapArray(outputs->content,"size",imyIndex);
1268    map* vData=getMapArray(outputs->content,"value",imyIndex);
[854]1269    if(sizeMap!=NULL){
1270      zWrite(f,vData->value,atoi(sizeMap->value)*sizeof(char));
1271    }
1272    else{
1273      zWrite(f,vData->value,(strlen(vData->value)+1)*sizeof(char));
1274    }
1275    close(f);
[860]1276    setMapArray(outputs->content,"storage",imyIndex,pszDataSource);
[854]1277    free(pszDataSource);
[550]1278  }
[297]1279
1280  /*
1281   * Create an empty map, set name, default size and extent
1282   */
[862]1283  map* mapfileTemplate=getMapArray(outputs->content,"msInclude",imyIndex);
1284  mapObj *myMap=NULL;
1285  if(mapfileTemplate==NULL){
1286    myMap=msNewMapObj();
1287  }
1288  else{
1289    map* dataPath=getMapFromMaps(conf,"main","dataPath");
1290    map* sid=getMapFromMaps(conf,"lenv","sid");
1291    char *mapfileTemplatePath=(char*)malloc(((strlen(dataPath->value)+strlen(sid->value)+strlen(outputs->name)+10)*sizeof(char)));
1292    sprintf(mapfileTemplatePath,"%s/%s_%s.map",dataPath->value,outputs->name,sid->value);
1293    myMap=msLoadMap(mapfileTemplate->value,mapfileTemplatePath);
1294    if(myMap==NULL){
1295      setMapInMaps(conf,"lenv","message",_("Unable to open your template mapfile!"));
1296      return ;
1297    }
1298  }
[297]1299  free(myMap->name);
[453]1300  myMap->name=zStrdup("ZOO-Project_WXS_Server");
[297]1301  msMapSetSize(myMap,2048,2048);
1302  msMapSetExtent(myMap,-1,-1,1,1);
1303 
1304  /*
1305   * Set imagepath and imageurl using tmpPath and tmpUrl from main.cfg
1306   */
1307  map *tmp1=getMapFromMaps(conf,"main","tmpPath");
[453]1308  myMap->web.imagepath=zStrdup(tmp1->value);
[297]1309  tmp1=getMapFromMaps(conf,"main","tmpUrl");
[453]1310  myMap->web.imageurl=zStrdup(tmp1->value);
[297]1311 
1312  /*
1313   * Define supported output formats
1314   */
1315  outputFormatObj *o1=msCreateDefaultOutputFormat(NULL,"AGG/PNG","png");
1316  o1->imagemode=MS_IMAGEMODE_RGBA;
1317  o1->transparent=MS_TRUE;
1318  o1->inmapfile=MS_TRUE;
1319  msAppendOutputFormat(myMap,msCloneOutputFormat(o1));
1320  msFreeOutputFormat(o1);
1321
1322#ifdef USE_KML
1323  outputFormatObj *o2=msCreateDefaultOutputFormat(NULL,"KML","kml");
[822]1324  if(!o2){
1325    perror("Unable to initialize KML driver");
1326    fprintf(stderr,"Unable to initialize KML driver !\n");
1327  }else{
1328    o2->inmapfile=MS_TRUE; 
1329    msAppendOutputFormat(myMap,msCloneOutputFormat(o2));
1330    msFreeOutputFormat(o2);
1331  }
[297]1332#endif
1333
1334  outputFormatObj *o3=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","tiff");
1335  if(!o3)
1336    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1337  else{
[862]1338    o3->imagemode=MS_IMAGEMODE_INT16;
[297]1339    o3->inmapfile=MS_TRUE; 
1340    msAppendOutputFormat(myMap,msCloneOutputFormat(o3));
1341    msFreeOutputFormat(o3);
1342  }
1343
1344  outputFormatObj *o4=msCreateDefaultOutputFormat(NULL,"GDAL/AAIGRID","grd");
1345  if(!o4)
1346    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1347  else{
[862]1348    o4->imagemode=MS_IMAGEMODE_BYTE;
[297]1349    o4->inmapfile=MS_TRUE; 
1350    msAppendOutputFormat(myMap,msCloneOutputFormat(o4));
1351    msFreeOutputFormat(o4);
1352  }
1353
1354#ifdef USE_CAIRO
1355  outputFormatObj *o5=msCreateDefaultOutputFormat(NULL,"CAIRO/PNG","cairopng");
1356  if(!o5)
1357    fprintf(stderr,"Unable to initialize CAIRO driver !\n");
1358  else{
1359    o5->imagemode=MS_IMAGEMODE_RGBA;
1360    o5->transparent=MS_TRUE;
1361    o5->inmapfile=MS_TRUE;
1362    msAppendOutputFormat(myMap,msCloneOutputFormat(o5));
1363    msFreeOutputFormat(o5);
1364  }
1365#endif
1366
[862]1367 
[854]1368  outputFormatObj *o6=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","geotiff");
1369  if(!o6)
1370    fprintf(stderr,"Unable to initialize GDAL driver !\n");
1371  else{
1372    o6->imagemode=MS_IMAGEMODE_BYTE;
1373    o6->mimetype=strdup("image/geotiff");
1374    o6->inmapfile=MS_TRUE;
1375    msAppendOutputFormat(myMap,msCloneOutputFormat(o6));
1376    msFreeOutputFormat(o6);
1377  }
1378
[862]1379 
[297]1380  /*
1381   * Set default projection to EPSG:4326
1382   */
1383  msLoadProjectionStringEPSG(&myMap->projection,"EPSG:4326");
1384  myMap->transparent=1;
1385
[364]1386  /*
1387   * Set mapserver PROJ_LIB/GDAL_DATA or any other config parameter from
1388   * the main.cfg [mapserver] section if any
1389   */
1390  maps *tmp3=getMaps(conf,"mapserver");
1391  if(tmp3!=NULL){
1392    map* tmp4=tmp3->content;
1393    while(tmp4!=NULL){
1394      msSetConfigOption(myMap,tmp4->name,tmp4->value);
1395      tmp4=tmp4->next;
1396    }
1397  }
1398
[297]1399  /**
1400   * Set a ows_rootlayer_title, 
1401   */
1402  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_name", "ZOO_Project_Layer") == NULL){
1403#ifdef DEBUGMS
1404    fprintf(stderr,"Unable to add metadata");
1405#endif
1406    return;
1407  }
1408  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_title", "ZOO_Project_Layer") == NULL){
1409#ifdef DEBUGMS
1410    fprintf(stderr,"Unable to add metadata");
1411#endif
1412    return;
1413  }
1414
1415  /**
1416   * Enable all the WXS requests using ows_enable_request
1417   * see http://mapserver.org/trunk/development/rfc/ms-rfc-67.html
1418   */
1419  if (msInsertHashTable(&(myMap->web.metadata), "ows_enable_request", "*") == NULL){
1420#ifdef DEBUGMS
1421    fprintf(stderr,"Unable to add metadata");
1422#endif
1423    return;
1424  }
1425  msInsertHashTable(&(myMap->web.metadata), "ows_srs", "EPSG:4326");
1426
[865]1427  /**
1428   * Set metadata extracted from main.cfg file maps
1429   */
1430  maps* cursor=conf;
1431  map* correspondance=getCorrespondance();
1432  while(cursor!=NULL){
1433    if(strstr(cursor->name,"_help")==NULL){
1434      map* _cursor=cursor->content;
1435      map* vMap;
1436      while(_cursor!=NULL){
1437        if((vMap=getMap(correspondance,_cursor->name))!=NULL){
1438          if (msInsertHashTable(&(myMap->web.metadata), vMap->value, _cursor->value) == NULL){
1439#ifdef DEBUGMS
1440            fprintf(stderr,"Unable to add metadata");
1441#endif
1442            freeMap(&correspondance);
1443            free(correspondance);
1444            return;
1445          }
1446        }
1447        _cursor=_cursor->next;
1448      }
1449    }
1450    cursor=cursor->next;
1451  }
1452  freeMap(&correspondance);
1453  free(correspondance);
1454
1455
[297]1456  if(tryOgr(conf,outputs,myMap)<0)
1457    if(tryGdal(conf,outputs,myMap)<0)
[364]1458      return ;
[297]1459
1460  tmp1=getMapFromMaps(conf,"main","dataPath");
1461  char *tmpPath=(char*)malloc((13+strlen(tmp1->value))*sizeof(char));
1462  sprintf(tmpPath,"%s/symbols.sym",tmp1->value);
1463  msInitSymbolSet(&myMap->symbolset);
[453]1464  myMap->symbolset.filename=zStrdup(tmpPath);
[297]1465  free(tmpPath);
1466
[453]1467  map* sid=getMapFromMaps(conf,"lenv","usid");
[297]1468  char *mapPath=
[860]1469    (char*)malloc((14+strlen(sid->value)+strlen(outputs->name)+strlen(tmp1->value))*sizeof(char));
1470  sprintf(mapPath,"%s/%s_%d_%s.map",tmp1->value,outputs->name,imyIndex,sid->value);
[297]1471  msSaveMap(myMap,mapPath);
[862]1472  saveMapNames(conf,outputs,mapPath);
[492]1473  free(mapPath);
[862]1474  //free(myMap->symbolset.filename);
[854]1475  //msFreeSymbolSet(&myMap->symbolset);
1476  msFreeMap(myMap);
1477  //msFree(myMap);
[492]1478  msGDALCleanup();
[297]1479}
1480
[862]1481/**
1482 * Save the map fullpath in a text file (.maps)
1483 * @param conf the main configuration map pointer
1484 * @param output the current output for which a mapfile has been generated
1485 * @param mapfile the mapfile saved to store in the text file
1486 */
1487void saveMapNames(maps* conf,maps* output,char* mapfile){
1488  map* storage=getMap(output->content,"storage");
1489  char *tmp=zStrdup(storage->value);
1490  tmp[strlen(tmp)-strlen(strrchr(tmp,'.'))]=0;
1491  char* mapName=(char*)malloc((strlen(tmp)+6)*sizeof(char*));
1492  sprintf(mapName,"%s.maps",tmp);
1493  FILE* myMaps=fopen(mapName,"a");
1494  if(myMaps!=NULL){
1495    fprintf(myMaps,"%s\n",mapfile);
1496    fclose(myMaps);
1497  } 
1498}
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