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

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

Add support for output style definition depending on geometry type (msStylePoly, msStylePoint, msStrylLine). Upload shared data in remote_persitent_data_path rather than remote_data_path (used for not shared data). In case output data should be published and the data is empty (nb_pixels or nb_features is set to 0) then, the ZOO-Kernel returns an ExceptionReport? with an Exception for every output.

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