1 
2 /* ===========================================================================
3    $Id$
4 
5    Project:  MapServer
6    Purpose:  SWIG interface file for mapscript layerObj extensions
7    Author:   Steve Lime
8              Sean Gillies, sgillies@frii.com
9 
10    ===========================================================================
11    Copyright (c) 1996-2001 Regents of the University of Minnesota.
12 
13    Permission is hereby granted, free of charge, to any person obtaining a
14    copy of this software and associated documentation files (the "Software"),
15    to deal in the Software without restriction, including without limitation
16    the rights to use, copy, modify, merge, publish, distribute, sublicense,
17    and/or sell copies of the Software, and to permit persons to whom the
18    Software is furnished to do so, subject to the following conditions:
19 
20    The above copyright notice and this permission notice shall be included
21    in all copies or substantial portions of the Software.
22 
23    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29    DEALINGS IN THE SOFTWARE.
30    ===========================================================================
31 */
32 
33 %extend layerObj
34 {
35 
36     layerObj(mapObj *map=NULL)
37     {
38         layerObj *layer;
39         int result;
40 
41         if (!map) {
42             layer = (layerObj *) malloc(sizeof(layerObj));
43             if (!layer) {
44                 msSetError(MS_MEMERR, "Failed to initialize Layer",
45                                        "layerObj()");
46                 return NULL;
47             }
48             result = initLayer(layer, NULL);
49             if (result == MS_SUCCESS) {
50                 layer->index = -1;
51                 return layer;
52             }
53             else {
54                 msSetError(MS_MEMERR, "Failed to initialize Layer",
55                                        "layerObj()");
56                 return NULL;
57             }
58         }
59         else {
60             if(msGrowMapLayers(map) == NULL)
61                 return(NULL);
62 
63             if (initLayer((map->layers[map->numlayers]), map) == -1)
64                 return(NULL);
65 
66             map->layers[map->numlayers]->index = map->numlayers;
67             map->layerorder[map->numlayers] = map->numlayers;
68             map->numlayers++;
69         MS_REFCNT_INCR(map->layers[map->numlayers-1]);
70 
71             return (map->layers[map->numlayers-1]);
72         }
73     }
74 
setOpacity(int opacity)75     void setOpacity(int opacity)
76     {
77       msSetLayerOpacity(self, opacity);
78     }
79 
getOpacity()80     int getOpacity() {
81       if(self->compositer) return (self->compositer->opacity);
82       return (100);
83     }
84 
~layerObj()85     ~layerObj()
86     {
87         /*if (!self->map) {*/
88         if (self) {
89             if(freeLayer(self)==MS_SUCCESS) {
90                 free(self);
91         }
92         }
93     }
94 
95 #if defined (SWIGJAVA) || defined(SWIGPHP)
96     %newobject cloneLayer;
cloneLayer()97     layerObj *cloneLayer()
98 #else
99     %newobject clone;
100     layerObj *clone()
101 #endif
102     {
103         layerObj *layer;
104         int result;
105 
106         layer = (layerObj *) malloc(sizeof(layerObj));
107         if (!layer) {
108             msSetError(MS_MEMERR, "Failed to initialize Layer",
109                                   "layerObj()");
110             return NULL;
111         }
112         result = initLayer(layer, NULL);
113         if (result != MS_SUCCESS) {
114             msSetError(MS_MEMERR, "Failed to initialize Layer",
115                                   "layerObj()");
116             return NULL;
117         }
118 
119         if (msCopyLayer(layer, self) != MS_SUCCESS) {
120             freeLayer(layer);
121             free(layer);
122             layer = NULL;
123         }
124         layer->map = NULL;
125         layer->index = -1;
126 
127         return layer;
128     }
129 
updateFromString(char * snippet)130     int updateFromString(char *snippet)
131     {
132         return msUpdateLayerFromString(self, snippet, MS_FALSE);
133     }
134 
135     %newobject convertToString;
convertToString()136     char* convertToString()
137     {
138         return msWriteLayerToString(self);
139     }
140 
141 #ifdef SWIGCSHARP
142 %apply SWIGTYPE *SETREFERENCE {classObj *classobj};
143 #endif
144     int insertClass(classObj *classobj, int index=-1)
145     {
146         return msInsertClass(self, classobj, index);
147     }
148 #ifdef SWIGCSHARP
149 %clear classObj *classobj;
150 #endif
151 
152     /* removeClass() */
153     %newobject removeClass;
removeClass(int index)154     classObj *removeClass(int index)
155     {
156         classObj* c = msRemoveClass(self, index);
157     if (c != NULL) {
158         MS_REFCNT_INCR(c);
159     }
160     return c;
161     }
162 
open()163     int open()
164     {
165         int status;
166         status =  msLayerOpen(self);
167         if (status == MS_SUCCESS) {
168             return msLayerGetItems(self);
169         }
170         return status;
171     }
172 
whichShapes(rectObj rect)173     int whichShapes(rectObj rect)
174     {
175         int oldconnectiontype = self->connectiontype;
176         self->connectiontype = MS_INLINE;
177 
178         if(msLayerWhichItems(self, MS_TRUE, NULL) != MS_SUCCESS) {
179             self->connectiontype = oldconnectiontype;
180             return MS_FAILURE;
181         }
182         self->connectiontype = oldconnectiontype;
183 
184         return msLayerWhichShapes(self, rect, MS_FALSE);
185     }
186 
187     %newobject nextShape;
nextShape()188     shapeObj *nextShape()
189     {
190        int status;
191        shapeObj *shape;
192 
193        shape = (shapeObj *)malloc(sizeof(shapeObj));
194        if (!shape) return NULL;
195        msInitShape(shape);
196 
197        status = msLayerNextShape(self, shape);
198        if(status != MS_SUCCESS) {
199          msFreeShape(shape);
200      free(shape);
201      return NULL;
202        } else
203          return shape;
204     }
205 
close()206     void close()
207     {
208         msLayerClose(self);
209     }
210 
211     %newobject getShape;
getShape(resultObj * record)212     shapeObj *getShape(resultObj *record)
213     {
214         int retval;
215         shapeObj *shape;
216 
217         if (!record) return NULL;
218 
219         shape = (shapeObj *)malloc(sizeof(shapeObj));
220         if (!shape) return NULL;
221 
222         msInitShape(shape);
223         shape->type = self->type; /* is this right? */
224 
225         retval = msLayerGetShape(self, shape, record);
226         if(retval != MS_SUCCESS) {
227           msFreeShape(shape);
228           free(shape);
229           return NULL;
230         } else
231         return shape;
232     }
233 
getNumResults()234     int getNumResults()
235     {
236         if (!self->resultcache) return 0;
237         return self->resultcache->numresults;
238     }
239 
240     %newobject getResultsBounds;
getResultsBounds()241     rectObj *getResultsBounds()
242     {
243         rectObj *bounds;
244         if (!self->resultcache) return NULL;
245         bounds = (rectObj *) malloc(sizeof(rectObj));
246         MS_COPYRECT(bounds, &self->resultcache->bounds);
247         return bounds;
248     }
249 
getResult(int i)250     resultObj *getResult(int i)
251     {
252         if (!self->resultcache) return NULL;
253         if (i >= 0 && i < self->resultcache->numresults)
254             return &self->resultcache->results[i];
255         else
256             return NULL;
257     }
258 
259     %newobject getClass;
getClass(int i)260     classObj *getClass(int i)
261     {
262     classObj *result=NULL;
263         if (i >= 0 && i < self->numclasses) {
264             result=self->class[i];
265         MS_REFCNT_INCR(result);
266     }
267     return result;
268     }
269 
getItem(int i)270     char *getItem(int i)
271     {
272 
273         if (i >= 0 && i < self->numitems)
274             return (char *) (self->items[i]);
275         else
276             return NULL;
277     }
278 
setItems(char ** items,int numitems)279     int setItems(char **items, int numitems) {
280         return msLayerSetItems(self, items, numitems);
281     }
282 
draw(mapObj * map,imageObj * image)283     int draw(mapObj *map, imageObj *image)
284     {
285         return msDrawLayer(map, self, image);
286     }
287 
drawQuery(mapObj * map,imageObj * image)288     int drawQuery(mapObj *map, imageObj *image)
289     {
290         return msDrawQueryLayer(map, self, image);
291     }
292 
293     /* For querying, we switch layer status ON and then back to original
294        value before returning. */
295 
queryByFilter(mapObj * map,char * string)296     int queryByFilter(mapObj *map, char *string)
297     {
298         int status;
299         int retval;
300 
301         msInitQuery(&(map->query));
302 
303         map->query.type = MS_QUERY_BY_FILTER;
304         map->query.mode = MS_QUERY_MULTIPLE;
305 
306         map->query.filter.string = msStrdup(string);
307         map->query.filter.type = MS_EXPRESSION;
308 
309         map->query.layer = self->index;
310            map->query.rect = map->extent;
311 
312           status = self->status;
313           self->status = MS_ON;
314         retval = msQueryByFilter(map);
315         self->status = status;
316           return retval;
317     }
318 
queryByAttributes(mapObj * map,char * qitem,char * qstring,int mode)319     int queryByAttributes(mapObj *map, char *qitem, char *qstring, int mode)
320     {
321         int status;
322         int retval;
323 
324         msInitQuery(&(map->query));
325 
326         map->query.type = MS_QUERY_BY_FILTER;
327         map->query.mode = mode;
328 
329         if(qitem) map->query.filteritem = msStrdup(qitem);
330         if(qstring) {
331           msInitExpression(&map->query.filter);
332           msLoadExpressionString(&map->query.filter, qstring);
333         }
334 
335         map->query.layer = self->index;
336         map->query.rect = map->extent;
337 
338         status = self->status;
339         self->status = MS_ON;
340         retval = msQueryByFilter(map);
341         self->status = status;
342 
343         return retval;
344     }
345 
queryByPoint(mapObj * map,pointObj * point,int mode,double buffer)346     int queryByPoint(mapObj *map, pointObj *point, int mode, double buffer)
347     {
348         int status;
349         int retval;
350 
351         msInitQuery(&(map->query));
352 
353         map->query.type = MS_QUERY_BY_POINT;
354         map->query.mode = mode;
355         map->query.point = *point;
356         map->query.buffer = buffer;
357         map->query.layer = self->index;
358 
359         status = self->status;
360         self->status = MS_ON;
361         retval = msQueryByPoint(map);
362         self->status = status;
363 
364         return retval;
365     }
366 
queryByRect(mapObj * map,rectObj rect)367     int queryByRect(mapObj *map, rectObj rect)
368     {
369         int status;
370         int retval;
371 
372         msInitQuery(&(map->query));
373 
374         map->query.type = MS_QUERY_BY_RECT;
375         map->query.mode = MS_QUERY_MULTIPLE;
376         map->query.rect = rect;
377         map->query.layer = self->index;
378 
379         status = self->status;
380         self->status = MS_ON;
381         retval = msQueryByRect(map);
382         self->status = status;
383 
384         return retval;
385     }
386 
queryByFeatures(mapObj * map,int slayer)387     int queryByFeatures(mapObj *map, int slayer)
388     {
389         int status;
390         int retval;
391 
392         map->query.slayer = slayer;
393         map->query.layer = self->index;
394 
395         status = self->status;
396         self->status = MS_ON;
397         retval = msQueryByFeatures(map);
398         self->status = status;
399         return retval;
400     }
401 
queryByShape(mapObj * map,shapeObj * shape)402     int queryByShape(mapObj *map, shapeObj *shape)
403     {
404         int status;
405         int retval;
406 
407         msInitQuery(&(map->query));
408 
409         map->query.type = MS_QUERY_BY_SHAPE;
410         map->query.mode = MS_QUERY_MULTIPLE;
411         map->query.shape = (shapeObj *) malloc(sizeof(shapeObj));
412         msInitShape(map->query.shape);
413         msCopyShape(shape, map->query.shape);
414         map->query.layer = self->index;
415 
416         status = self->status;
417         self->status = MS_ON;
418         retval = msQueryByShape(map);
419         self->status = status;
420         return retval;
421     }
422 
423     int queryByIndex(mapObj *map, int tileindex, int shapeindex, int bAddToQuery=MS_FALSE)
424     {
425         int status;
426         int retval;
427 
428         msInitQuery(&(map->query));
429 
430         map->query.type = MS_QUERY_BY_INDEX;
431         map->query.mode = MS_QUERY_SINGLE;
432         map->query.tileindex = tileindex;
433         map->query.shapeindex = shapeindex;
434         map->query.clear_resultcache = !bAddToQuery;
435         map->query.layer = self->index;
436 
437         status = self->status;
438         self->status = MS_ON;
439         retval = msQueryByIndex(map);
440         self->status = status;
441         return retval;
442     }
443 
getResults(void)444     resultCacheObj *getResults(void)
445     {
446         return self->resultcache;
447     }
448 
setFilter(char * filter)449     int setFilter(char *filter)
450     {
451         if (!filter || strlen(filter) == 0) {
452             msFreeExpression(&self->filter);
453             return MS_SUCCESS;
454         }
455         else return msLoadExpressionString(&self->filter, filter);
456     }
457 
458     %newobject getFilterString;
getFilterString()459     char *getFilterString()
460     {
461         return msGetExpressionString(&(self->filter));
462     }
463 
setWKTProjection(char * wkt)464     int setWKTProjection(char *wkt)
465     {
466         self->project = MS_TRUE;
467         return msOGCWKT2ProjectionObj(wkt, &(self->projection), self->debug);
468     }
469 
470     %newobject getProjection;
getProjection()471     char *getProjection()
472     {
473         return (char *) msGetProjectionString(&(self->projection));
474     }
475 
setProjection(char * proj4)476     int setProjection(char *proj4)
477     {
478         self->project = MS_TRUE;
479         return msLoadProjectionString(&(self->projection), proj4);
480     }
481 
addFeature(shapeObj * shape)482     int addFeature(shapeObj *shape)
483     {
484         self->connectiontype = MS_INLINE;
485         if(self->features != NULL && self->features->tailifhead != NULL)
486             shape->index = self->features->tailifhead->shape.index + 1;
487         else
488             shape->index = 0;
489         if (insertFeatureList(&(self->features), shape) == NULL)
490         return MS_FAILURE;
491         return MS_SUCCESS;
492     }
493 
494     /*
495     Returns the number of inline feature of a layer
496     */
getNumFeatures()497     int getNumFeatures()
498     {
499         return msLayerGetNumFeatures(self);
500     }
501 
502     %newobject getExtent;
getExtent()503     rectObj *getExtent()
504     {
505         rectObj *extent;
506         extent = (rectObj *) malloc(sizeof(rectObj));
507         msLayerGetExtent(self, extent);
508         return extent;
509     }
510 
511     int setExtent(double minx=-1.0, double miny=-1.0,
512                   double maxx=-1.0, double maxy=-1.0)
513     {
514         if (minx > maxx || miny > maxy) {
515             msSetError(MS_RECTERR,
516                 "{ 'minx': %f , 'miny': %f , 'maxx': %f , 'maxy': %f }",
517                 "layerObj::setExtent()", minx, miny, maxx, maxy);
518             return MS_FAILURE;
519         }
520 
521         return msLayerSetExtent(self, minx, miny, maxx, maxy);
522     }
523 
524     /*
525     The following metadata methods are no longer needed since we have
526     promoted the metadata member of layerObj to a first-class mapscript
527     object.  See hashtable.i.  Not yet scheduled for deprecation but
528     perhaps in the next major release?  --SG
529     */
getMetaData(char * name)530     char *getMetaData(char *name)
531     {
532         char *value = NULL;
533         if (!name) {
534             msSetError(MS_HASHERR, "NULL key", "getMetaData");
535         }
536 
537         value = (char *) msLookupHashTable(&(self->metadata), name);
538     /*
539     Umberto, 05/17/2006
540     Exceptions should be reserved for situations when a serious error occurred
541     and normal program flow must be interrupted.
542     In this case returning null should be more that enough.
543     */
544 #ifndef SWIGJAVA
545         if (!value) {
546             msSetError(MS_HASHERR, "Key %s does not exist", "getMetaData", name);
547             return NULL;
548         }
549 #endif
550         return value;
551     }
552 
setMetaData(char * name,char * value)553     int setMetaData(char *name, char *value)
554     {
555         if (msInsertHashTable(&(self->metadata), name, value) == NULL)
556         return MS_FAILURE;
557         return MS_SUCCESS;
558     }
559 
removeMetaData(char * name)560     int removeMetaData(char *name)
561     {
562         return(msRemoveHashTable(&(self->metadata), name));
563     }
564 
getFirstMetaDataKey()565     char *getFirstMetaDataKey()
566     {
567         return (char *) msFirstKeyFromHashTable(&(self->metadata));
568     }
569 
getNextMetaDataKey(char * lastkey)570     char *getNextMetaDataKey(char *lastkey)
571     {
572         return (char *) msNextKeyFromHashTable(&(self->metadata), lastkey);
573     }
574 
575     %newobject getWMSFeatureInfoURL;
getWMSFeatureInfoURL(mapObj * map,int click_x,int click_y,int feature_count,char * info_format)576     char *getWMSFeatureInfoURL(mapObj *map, int click_x, int click_y,
577                                int feature_count, char *info_format)
578     {
579         return (char *) msWMSGetFeatureInfoURL(map, self, click_x, click_y,
580                feature_count, info_format);
581     }
582 
583     %newobject executeWFSGetFeature;
executeWFSGetFeature(layerObj * layer)584     char *executeWFSGetFeature(layerObj *layer)
585     {
586         return (char *) msWFSExecuteGetFeature(layer);
587     }
588 
applySLD(char * sld,char * stylelayer)589     int applySLD(char *sld, char *stylelayer)
590     {
591       return msSLDApplySLD(self->map, sld, self->index, stylelayer, NULL);
592     }
593 
applySLDURL(char * sld,char * stylelayer)594     int applySLDURL(char *sld, char *stylelayer)
595     {
596       return msSLDApplySLDURL(self->map, sld, self->index, stylelayer, NULL);
597     }
598 
599     %newobject generateSLD;
generateSLD()600     char *generateSLD()
601     {
602         return (char *) msSLDGenerateSLD(self->map, self->index, NULL);
603     }
604 
isVisible()605     int isVisible()
606     {
607         if (!self->map)
608         {
609             msSetError(MS_MISCERR,
610                 "visibility has no meaning outside of a map context",
611                 "isVisible()");
612             return MS_FAILURE;
613         }
614         return msLayerIsVisible(self->map, self);
615     }
616 
moveClassUp(int index)617     int moveClassUp(int index)
618     {
619         return msMoveClassUp(self, index);
620     }
621 
moveClassDown(int index)622     int moveClassDown(int index)
623     {
624         return msMoveClassDown(self, index);
625     }
626 
setProcessingKey(const char * key,const char * value)627     void setProcessingKey(const char *key, const char *value)
628     {
629        msLayerSetProcessingKey( self, key, value );
630     }
631 
632     /* this method is deprecated ... should use addProcessing() */
setProcessing(const char * directive)633     void setProcessing(const char *directive )
634     {
635         msLayerAddProcessing( self, directive );
636     }
637 
addProcessing(const char * directive)638     void addProcessing(const char *directive )
639     {
640         msLayerAddProcessing( self, directive );
641     }
642 
getProcessing(int index)643     char *getProcessing(int index)
644     {
645         return (char *) msLayerGetProcessing(self, index);
646     }
647 
getProcessingKey(const char * key)648     char *getProcessingKey(const char *key)
649     {
650       return (char *) msLayerGetProcessingKey(self, key);
651     }
652 
clearProcessing()653     int clearProcessing()
654     {
655         return msLayerClearProcessing(self);
656     }
657 
setConnectionType(int connectiontype,const char * library_str)658     int setConnectionType(int connectiontype, const char *library_str)
659     {
660         /* Caller is responsible to close previous layer correctly before
661          * calling msConnectLayer()
662          */
663         if (msLayerIsOpen(self))
664           msLayerClose(self);
665         return msConnectLayer(self, connectiontype, library_str);
666     }
667 
668     int getClassIndex(mapObj *map, shapeObj *shape, int *classgroup=NULL, int numclasses=0) {
669         return msShapeGetClass(self, map, shape, classgroup, numclasses);
670     }
671 
getGeomTransform()672     char *getGeomTransform()
673     {
674       return self->_geomtransform.string;
675     }
676 
setGeomTransform(char * transform)677     void setGeomTransform(char *transform)
678     {
679       msFree(self->_geomtransform.string);
680       if (!transform || strlen(transform) > 0) {
681         self->_geomtransform.string = msStrdup(transform);
682         self->_geomtransform.type = MS_GEOMTRANSFORM_EXPRESSION;
683       }
684       else {
685         self->_geomtransform.type = MS_GEOMTRANSFORM_NONE;
686         self->_geomtransform.string = NULL;
687       }
688     }
689 
690     %feature("autodoc", "3");
691     %feature("docstring") getItemType
692 "Returns the requested item's field type.
693 A layer must be open to retrieve the item definition.
694 
695 Pass in the attribute index to retrieve the type. The
696 layer's numitems property contains the number of items
697 available, and the first item is index zero."
698 
699     char *getItemType(int i)
700     {
701 
702         char *itemType = NULL;
703 
704         if (i >= 0 && i < self->numitems) {
705             gmlItemListObj *item_list;
706             item_list = msGMLGetItems(self, "G");
707             if (item_list != NULL) {
708                 gmlItemObj *item = item_list->items + i;
709                 itemType = msStrdup(item->type);
710                 msGMLFreeItems(item_list); // destroy the original list
711             }
712         }
713 
714         return itemType;
715 
716     }
717 
718 
719 }
720