root/tags/rel-5-0-2/mapserver/mapcopy.c

Revision 7255, 33.0 kB (checked in by sdlime, 6 months ago)

Fixed a problem copying attribute bindings between style and labels. (bug #2465)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /******************************************************************************
2  * Project: MapServer
3  * Purpose: Functions to allow copying/cloning of maps
4  * Author:  Sean Gillies, sgillies@frii.com
5  *
6  * Notes: These functions are not in mapfile.c because that file is
7  * cumbersome enough as it is.  There is agreement that this code and
8  * that in mapfile.c should eventually be split up by object into
9  * mapobj.c, layerobj.c, etc.  Or something like that. 
10  *
11  * Unit tests are written in Python using PyUnit and are in
12  * mapscript/python/tests/testCopyMap.py.  The tests can be
13  * executed from the python directory as
14  *
15  *   python2 tests/testCopyMap.py
16  *
17  * I just find Python to be very handy for unit testing, that's all.
18  *
19  ******************************************************************************
20  * Copyright (c) 1996-2005 Regents of the University of Minnesota.
21  *
22  * Permission is hereby granted, free of charge, to any person obtaining a
23  * copy of this software and associated documentation files (the "Software"),
24  * to deal in the Software without restriction, including without limitation
25  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
26  * and/or sell copies of the Software, and to permit persons to whom the
27  * Software is furnished to do so, subject to the following conditions:
28  *
29  * The above copyright notice and this permission notice shall be included in
30  * all copies of this Software or works derived from this Software.
31  *
32  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
33  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
35  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
37  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
38  * DEALINGS IN THE SOFTWARE.
39  ****************************************************************************/
40
41 #include <assert.h>
42 #include "mapserver.h"
43 #include "mapsymbol.h"
44
45 MS_CVSID("$Id$")
46
47 #include "mapcopy.h"
48
49 /***********************************************************************
50  * msCopyProjection()                                                  *
51  *                                                                     *
52  * Copy a projectionObj                                                *
53  **********************************************************************/
54
55 int msCopyProjection(projectionObj *dst, projectionObj *src) {
56
57 #ifdef USE_PROJ
58     int i;
59    
60     MS_COPYSTELEM(numargs);
61
62     for (i = 0; i < dst->numargs; i++) {
63         /* Our destination consists of unallocated pointers */
64         dst->args[i] = strdup(src->args[i]);
65     }
66     if (dst->numargs != 0) {
67         if (msProcessProjection(dst) != MS_SUCCESS)
68             return MS_FAILURE;
69
70     }
71 #endif
72     return MS_SUCCESS;
73 }
74
75 /***********************************************************************
76  * msCopyLine()                                                        *
77  *                                                                     *
78  * Copy a lineObj, using msCopyPoint()                                 *
79  **********************************************************************/
80 int msCopyLine(lineObj *dst, lineObj *src) {
81  
82     int i;
83
84     dst->numpoints = src->numpoints;
85     for (i = 0; i < dst->numpoints; i++) {
86         MS_COPYPOINT(&(dst->point[i]), &(src->point[i]));
87     }
88
89     return MS_SUCCESS;
90 }
91
92 /***********************************************************************
93  * msCopyShape()                                                       *
94  *                                                                     *
95  * Copy a shapeObj, using msCopyLine(), msCopyRect()                   *
96  * Not completely implemented or tested.                               *
97  **********************************************************************/
98 /*
99 int msCopyShapeObj(shapeObj *dst, shapeObj *src) {
100   int i;
101   copyProperty(&(dst->numlines), &(src->numlines), sizeof(int));
102   for (i = 0; i < dst->numlines; i++) {
103     msCopyLine(&(dst->line[i]), &(src->line[i]));
104   }
105   msCopyRect(&(dst->bounds), &(src->bounds));
106   copyProperty(&(dst->type), &(src->type), sizeof(int));
107   copyProperty(&(dst->index), &(src->index), sizeof(long));
108   copyProperty(&(dst->tileindex), &(src->tileindex), sizeof(int));
109   copyProperty(&(dst->classindex), &(src->classindex), sizeof(int));
110   copyStringPropertyRealloc(&(dst->text), src->text);
111   copyProperty(&(dst->numvalues), &(src->numvalues), sizeof(int));
112   for (i = 0; i < dst->numvalues; i++) {
113     copyStringPropertyRealloc(&(dst->values[i]), src->values[i]);
114   }
115
116   return(0);
117 }
118 */
119
120 /**********************************************************************
121  * msCopyItem()                                                        *
122  *                                                                     *
123  * Copy an itemObj                                                     *
124  **********************************************************************/
125
126 int msCopyItem(itemObj *dst, itemObj *src) {
127    
128     MS_COPYSTRING(dst->name, src->name);
129     MS_COPYSTELEM(type);
130     MS_COPYSTELEM(index);
131     MS_COPYSTELEM(size);
132     MS_COPYSTELEM(numdecimals);
133
134     return MS_SUCCESS;
135 }
136
137 /***********************************************************************
138  * msCopyHashTable()                                                   *
139  *                                                                     *
140  * Copy a hashTableObj, using msInsertHashTable()                      *
141  **********************************************************************/
142
143 int msCopyHashTable(hashTableObj *dst, hashTableObj *src) {
144     const char *key=NULL;
145     while (1) {
146         key = msNextKeyFromHashTable(src, key);
147         if (!key)
148             break;
149         else
150             msInsertHashTable(dst, key, msLookupHashTable(src, key));
151     }
152     return MS_SUCCESS;
153 }
154
155 /***********************************************************************
156  * msCopyFontSet()                                                     *
157  *                                                                     *
158  * Copy a fontSetObj, using msCreateHashTable() and msCopyHashTable()  *
159  **********************************************************************/
160
161 int msCopyFontSet(fontSetObj *dst, fontSetObj *src, mapObj *map)
162 {
163
164     MS_COPYSTRING(dst->filename, src->filename);
165     MS_COPYSTELEM(numfonts);
166     if (&(src->fonts)) {
167         /* if (!dst->fonts) */
168         /* dst->fonts = msCreateHashTable(); */
169         if (msCopyHashTable(&(dst->fonts), &(src->fonts)) != MS_SUCCESS)
170             return MS_FAILURE;
171     }
172
173     dst->map = map;
174
175     return MS_SUCCESS;
176 }
177
178 /***********************************************************************
179  * msCopyExpression(                                                   *
180  *                                                                     *
181  * Copy an expressionObj, but only its string and type                 *
182  **********************************************************************/
183
184 int msCopyExpression(expressionObj *dst, expressionObj *src)
185 {
186     MS_COPYSTRING(dst->string, src->string);
187     MS_COPYSTELEM(type);
188     dst->compiled = MS_FALSE;
189
190     return MS_SUCCESS;
191 }
192
193 /***********************************************************************
194  * msCopyJoin()                                                        *
195  *                                                                     *
196  * Copy a joinObj                                                      *
197  **********************************************************************/
198
199 int msCopyJoin(joinObj *dst, joinObj *src)
200 {
201     MS_COPYSTRING(dst->name, src->name);
202
203     /* makes no sense to copy the items or values
204        since they are runtime additions to the mapfile */
205
206     MS_COPYSTRING(dst->table, src->table);
207     MS_COPYSTRING(dst->from, src->from);
208     MS_COPYSTRING(dst->to, src->to);
209     MS_COPYSTRING(dst->header, src->header);
210 #ifndef __cplusplus
211     MS_COPYSTRING(dst->template, src->template);
212 #else
213     MS_COPYSTRING(dst->_template, src->_template);
214 #endif
215     MS_COPYSTRING(dst->footer, src->footer);
216     dst->type = src->type;
217     MS_COPYSTRING(dst->connection, src->connection);
218
219     MS_COPYSTELEM(connectiontype);
220
221     /* TODO: need to handle joininfo (probably should be just set to NULL) */
222     dst->joininfo = NULL;
223
224     return MS_SUCCESS;
225 }
226
227 /***********************************************************************
228  * msCopyQueryMap()                                                    *
229  *                                                                     *
230  * Copy a queryMapObj, using msCopyColor()                             *
231  **********************************************************************/
232
233 int msCopyQueryMap(queryMapObj *dst, queryMapObj *src)
234 {
235     MS_COPYSTELEM(height);
236     MS_COPYSTELEM(width);
237     MS_COPYSTELEM(status);
238     MS_COPYSTELEM(style);
239     MS_COPYCOLOR(&(dst->color), &(src->color));
240
241   return MS_SUCCESS;
242 }
243
244 /***********************************************************************
245  * msCopyLabel()                                                       *
246  *                                                                     *
247  * Copy a labelObj, using msCopyColor()                                *
248  **********************************************************************/
249
250 int msCopyLabel(labelObj *dst, labelObj *src)
251 {
252   int i;
253
254   for(i=0; i<MS_LABEL_BINDING_LENGTH; i++) {
255     MS_COPYSTRING(dst->bindings[i].item, src->bindings[i].item);
256     dst->bindings[i].index = src->bindings[i].index; /* no way to use the macros */
257   }
258   MS_COPYSTELEM(numbindings);
259
260     MS_COPYSTRING(dst->font, src->font);
261     MS_COPYSTELEM(type);
262
263     MS_COPYCOLOR(&(dst->color), &(src->color));
264     MS_COPYCOLOR(&(dst->outlinecolor), &(src->outlinecolor));
265     MS_COPYCOLOR(&(dst->shadowcolor), &(src->shadowcolor));
266
267     MS_COPYSTELEM(shadowsizex);
268     MS_COPYSTELEM(shadowsizey);
269
270     MS_COPYCOLOR(&(dst->backgroundcolor), &(src->backgroundcolor));
271     MS_COPYCOLOR(&(dst->backgroundshadowcolor), &(src->backgroundshadowcolor));
272
273     MS_COPYSTELEM(backgroundshadowsizex);
274     MS_COPYSTELEM(backgroundshadowsizey);
275     MS_COPYSTELEM(size);
276     MS_COPYSTELEM(minsize);
277     MS_COPYSTELEM(maxsize);
278     MS_COPYSTELEM(position);
279     MS_COPYSTELEM(offsetx);
280     MS_COPYSTELEM(offsety);
281     MS_COPYSTELEM(angle);
282     MS_COPYSTELEM(autoangle);   
283     MS_COPYSTELEM(autofollow);
284     MS_COPYSTELEM(buffer);
285     MS_COPYSTELEM(antialias);
286     MS_COPYSTELEM(wrap);
287     MS_COPYSTELEM(minfeaturesize);
288
289     MS_COPYSTELEM(autominfeaturesize);
290
291     MS_COPYSTELEM(mindistance);
292     MS_COPYSTELEM(partials);
293     MS_COPYSTELEM(force);
294     MS_COPYSTELEM(priority);
295
296     MS_COPYSTRING(dst->encoding, src->encoding);
297
298     return MS_SUCCESS;
299 }
300
301 /***********************************************************************
302  * msCopyWeb()                                                         *
303  *                                                                     *
304  * Copy webObj, using msCopyRect(), msCreateHashTable(), and           *
305  * msCopyHashTable()                                                   *
306  **********************************************************************/
307
308 int msCopyWeb(webObj *dst, webObj *src, mapObj *map)
309 {
310
311     MS_COPYSTRING(dst->log, src->log);
312     MS_COPYSTRING(dst->imagepath, src->imagepath);
313     MS_COPYSTRING(dst->imageurl, src->imageurl);
314     dst->map = map;
315 #ifndef __cplusplus
316     MS_COPYSTRING(dst->template, src->template);
317 #else
318     MS_COPYSTRING(dst->_template, src->_template);
319 #endif
320     MS_COPYSTRING(dst->header, src->header);
321     MS_COPYSTRING(dst->footer, src->footer);
322     MS_COPYSTRING(dst->empty, src->empty);
323     MS_COPYSTRING(dst->error, src->error);
324
325     MS_COPYRECT(&(dst->extent), &(src->extent));
326
327     MS_COPYSTELEM(minscaledenom);
328     MS_COPYSTELEM(maxscaledenom);
329     MS_COPYSTRING(dst->mintemplate, src->mintemplate);
330     MS_COPYSTRING(dst->maxtemplate, src->maxtemplate);
331
332     if (&(src->metadata)) {
333         /* dst->metadata = msCreateHashTable(); */
334         if (msCopyHashTable(&(dst->metadata), &(src->metadata)) != MS_SUCCESS)
335             return MS_FAILURE;
336     }
337
338     MS_COPYSTRING(dst->queryformat, src->queryformat);
339     MS_COPYSTRING(dst->legendformat, src->legendformat);
340     MS_COPYSTRING(dst->browseformat, src->browseformat);
341
342     return MS_SUCCESS ;
343 }
344
345 /***********************************************************************
346  * msCopyStyle()                                                       *
347  *                                                                     *
348  * Copy a styleObj, using msCopyColor()                                *
349  **********************************************************************/
350
351 int msCopyStyle(styleObj *dst, styleObj *src)
352 {
353   int i;
354
355   for(i=0; i<MS_STYLE_BINDING_LENGTH; i++) {
356     MS_COPYSTRING(dst->bindings[i].item, src->bindings[i].item);
357     dst->bindings[i].index = src->bindings[i].index; /* no way to use the macros */
358   }
359   MS_COPYSTELEM(numbindings);
360
361     MS_COPYCOLOR(&(dst->color), &(src->color));
362     MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor));
363     MS_COPYCOLOR(&(dst->backgroundcolor), &(src->backgroundcolor));
364    
365     MS_COPYCOLOR(&(dst->mincolor), &(src->mincolor));
366     MS_COPYCOLOR(&(dst->maxcolor), &(src->maxcolor));
367
368     MS_COPYSTRING(dst->symbolname, src->symbolname);
369
370     MS_COPYSTELEM(symbol);
371     MS_COPYSTELEM(size);
372     MS_COPYSTELEM(minsize);
373     MS_COPYSTELEM(maxsize);
374     MS_COPYSTELEM(width);
375     MS_COPYSTELEM(minwidth);
376     MS_COPYSTELEM(maxwidth);
377     MS_COPYSTELEM(offsetx);
378     MS_COPYSTELEM(offsety);
379     MS_COPYSTELEM(antialias);
380     MS_COPYSTELEM(angle);
381     MS_COPYSTELEM(minvalue);
382     MS_COPYSTELEM(maxvalue);
383     MS_COPYSTELEM(opacity);
384
385     MS_COPYSTRING(dst->rangeitem, src->rangeitem);
386     MS_COPYSTELEM(rangeitemindex);
387
388     /* TODO: add copy for bindings */
389
390     return MS_SUCCESS;
391 }
392
393 /***********************************************************************
394  * msCopyClass()                                                       *
395  *                                                                     *
396  * Copy a classObj, using msCopyExpression(), msCopyStyle(),           *
397  * msCopyLabel(), msCreateHashTable(), msCopyHashTable()               *
398  **********************************************************************/
399
400 int msCopyClass(classObj *dst, classObj *src, layerObj *layer)
401 {
402     int i, return_value;
403
404     return_value = msCopyExpression(&(dst->expression),&(src->expression));
405     if (return_value != MS_SUCCESS) {
406         msSetError(MS_MEMERR, "Failed to copy expression.", "msCopyClass()");
407         return MS_FAILURE;
408     }
409
410     MS_COPYSTELEM(status);
411
412     /* free any previous styles on the dst layer*/
413     for(i=0;i<dst->numstyles;i++) { /* each style     */
414       if (dst->styles[i]!=NULL) {
415         if( freeStyle(dst->styles[i]) == MS_SUCCESS ) {
416           msFree(dst->styles[i]);
417         }
418       }
419     }
420     msFree(dst->styles);
421     dst->numstyles = 0;
422
423     for (i = 0; i < src->numstyles; i++) {
424         if (msGrowClassStyles(dst) == NULL)
425             return MS_FAILURE;
426         if (initStyle(dst->styles[i]) != MS_SUCCESS) {
427             msSetError(MS_MEMERR, "Failed to init style.", "msCopyClass()");
428             return MS_FAILURE;
429         }
430         if (msCopyStyle(dst->styles[i], src->styles[i]) != MS_SUCCESS) {
431             msSetError(MS_MEMERR, "Failed to copy style.", "msCopyClass()");
432             return MS_FAILURE;
433         }
434
435         dst->numstyles++;
436     }
437
438     if (msCopyLabel(&(dst->label), &(src->label)) != MS_SUCCESS) {
439         msSetError(MS_MEMERR, "Failed to copy label.", "msCopyClass()");
440         return MS_FAILURE;
441     }
442
443     MS_COPYSTRING(dst->keyimage, src->keyimage);
444     MS_COPYSTRING(dst->name, src->name);
445     MS_COPYSTRING(dst->title, src->title);
446
447     if (msCopyExpression(&(dst->text), &(src->text)) != MS_SUCCESS) {
448         msSetError(MS_MEMERR, "Failed to copy text.", "msCopyClass()");
449         return MS_FAILURE;
450     }
451
452 #ifndef __cplusplus
453     MS_COPYSTRING(dst->template, src->template);
454 #else
455     MS_COPYSTRING(dst->_template, src->_template);
456 #endif
457     MS_COPYSTELEM(type);
458
459     if (&(src->metadata) != NULL) {
460         /* dst->metadata = msCreateHashTable(); */
461         msCopyHashTable(&(dst->metadata), &(src->metadata));
462     }
463
464     MS_COPYSTELEM(minscaledenom);
465     MS_COPYSTELEM(maxscaledenom);
466     MS_COPYSTELEM(layer);
467     MS_COPYSTELEM(debug);
468
469     return MS_SUCCESS;
470 }
471
472 /***********************************************************************
473  * msCopyLabelCacheMember()                                            *
474  *                                                                     *
475  * Copy a labelCacheMemberObj using msCopyStyle(), msCopyPoint()       *
476  *                                                                     *
477  * Note: since it seems most users will want to clone maps rather than *
478  * make exact copies, this method might not get much use.              *
479  **********************************************************************/
480
481 int msCopyLabelCacheMember(labelCacheMemberObj *dst,
482                            labelCacheMemberObj *src)
483 {
484     int i;
485
486     MS_COPYSTRING(dst->text, src->text);
487     MS_COPYSTELEM(featuresize);
488     MS_COPYSTELEM(numstyles);
489
490     for (i = 0; i < dst->numstyles; i++) {
491         msCopyStyle(&(dst->styles[i]), &(src->styles[i]));
492     }
493
494     msCopyLabel(&(dst->label), &(src->label));
495     MS_COPYSTELEM(layerindex);
496     MS_COPYSTELEM(classindex);
497     MS_COPYSTELEM(tileindex);
498     MS_COPYSTELEM(shapeindex);
499     MS_COPYPOINT(&(dst->point), &(src->point));
500     /* msCopyShape(&(dst->poly), &(src->poly)); */
501     MS_COPYSTELEM(status);
502
503     return MS_SUCCESS;
504 }
505
506 /***********************************************************************
507  * msCopyMarkerCacheMember()                                           *
508  *                                                                     *
509  * Copy a markerCacheMemberObj                                         *
510  **********************************************************************/
511
512 int msCopyMarkerCacheMember(markerCacheMemberObj *dst,
513                             markerCacheMemberObj *src)
514
515     MS_COPYSTELEM(id);
516  
517     /* msCopyShape(&(dst->poly), &(src->poly)); */
518     return MS_SUCCESS;
519 }
520
521 /***********************************************************************
522  * msCopyLabelCacheSlot()                                                  *
523  **********************************************************************/
524
525 int msCopyLabelCacheSlot(labelCacheSlotObj *dst, labelCacheSlotObj *src)
526 {
527     int i;
528
529     for (i = 0; i < dst->numlabels; i++) {
530         msCopyLabelCacheMember(&(dst->labels[i]), &(src->labels[i]));
531     }
532     MS_COPYSTELEM(cachesize);
533     MS_COPYSTELEM(nummarkers);
534     for (i = 0; i < dst->nummarkers; i++) {
535         msCopyMarkerCacheMember(&(dst->markers[i]), &(src->markers[i]));
536     }
537     MS_COPYSTELEM(markercachesize);
538
539     return MS_SUCCESS;
540 }
541
542 /***********************************************************************
543  * msCopyLabelCache()                                                  *
544  **********************************************************************/
545
546 int msCopyLabelCache(labelCacheObj *dst, labelCacheObj *src)
547 {
548     int p;
549     MS_COPYSTELEM(numlabels);
550
551     for (p=0; p<MS_MAX_LABEL_PRIORITY; p++) {
552         msCopyLabelCacheSlot(&(dst->slots[p]), &(src->slots[p]));
553     }
554
555     return MS_SUCCESS;
556 }
557
558 /***********************************************************************
559  * msCopyMarkerCacheMember()                                           *
560  *                                                                     *
561  * Copy a markerCacheMemberObj                                         *
562  **********************************************************************/
563
564 int msCopyResultCacheMember(resultCacheMemberObj *dst,
565                             resultCacheMemberObj *src)
566 {
567     MS_COPYSTELEM(shapeindex);
568     MS_COPYSTELEM(tileindex);
569     MS_COPYSTELEM(classindex);
570
571     return MS_SUCCESS;
572 }
573
574 /***********************************************************************
575  * msCopyResultCache()                                                 *
576  **********************************************************************/
577
578 int msCopyResultCache(resultCacheObj *dst, resultCacheObj *src)
579 {
580     int i;
581     MS_COPYSTELEM(cachesize);
582     MS_COPYSTELEM(numresults);
583     for (i = 0; i < dst->numresults; i++) {
584         msCopyResultCacheMember(&(dst->results[i]), &(src->results[i]));
585     }
586     MS_COPYRECT(&(dst->bounds), &(src->bounds));
587
588     return MS_SUCCESS;
589 }
590
591 /***********************************************************************
592  * msCopyReferenceMap()                                                *
593  *                                                                     *
594  * Copy a referenceMapObj using mapfile.c:initReferenceMap(),          *
595  * msCopyRect(), msCopyColor()                                         *
596  **********************************************************************/
597
598 int msCopyReferenceMap(referenceMapObj *dst, referenceMapObj *src,
599                        mapObj *map)
600 {
601
602     initReferenceMap(dst);
603
604     MS_COPYRECT(&(dst->extent), &(src->extent));
605
606     MS_COPYSTELEM(height);
607     MS_COPYSTELEM(width);
608
609
610     MS_COPYCOLOR(&(dst->color), &(src->color));
611     MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor));
612     MS_COPYSTRING(dst->image, src->image);
613
614     MS_COPYSTELEM(status);
615     MS_COPYSTELEM(marker);
616     MS_COPYSTRING(dst->markername, src->markername);
617     MS_COPYSTELEM(markersize);
618     MS_COPYSTELEM(minboxsize);
619     MS_COPYSTELEM(maxboxsize);
620     dst->map = map;
621
622     return MS_SUCCESS;
623 }
624
625 /***********************************************************************
626  * msCopyScalebar()                                                    *
627  *                                                                     *
628  * Copy a scalebarObj, using initScalebar(), msCopyColor(),            *
629  * and msCopyLabel()                                                   *
630  **********************************************************************/
631
632 int msCopyScalebar(scalebarObj *dst, scalebarObj *src)
633 {
634
635     initScalebar(dst);
636
637     MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor));
638     MS_COPYSTELEM(height);
639     MS_COPYSTELEM(width);
640     MS_COPYSTELEM(style);
641     MS_COPYSTELEM(intervals);
642
643     if (msCopyLabel(&(dst->label), &(src->label)) != MS_SUCCESS) {
644         msSetError(MS_MEMERR, "Failed to copy label.","msCopyScalebar()");
645         return MS_FAILURE;
646     }
647
648     MS_COPYCOLOR(&(dst->color), &(src->color));
649     MS_COPYCOLOR(&(dst->backgroundcolor), &(src->backgroundcolor));
650
651     MS_COPYCOLOR(&(dst->outlinecolor), &(src->outlinecolor));
652
653     MS_COPYSTELEM(units);
654     MS_COPYSTELEM(status);
655     MS_COPYSTELEM(position);
656     MS_COPYSTELEM(transparent);
657     MS_COPYSTELEM(interlace);
658     MS_COPYSTELEM(postlabelcache);
659
660     return MS_SUCCESS;
661 }
662
663 /***********************************************************************
664  * msCopyLegend()                                                      *
665  *                                                                     *
666  * Copy a legendObj, using msCopyColor()                               *
667  **********************************************************************/
668
669 int msCopyLegend(legendObj *dst, legendObj *src, mapObj *map)
670 {
671     int return_value;
672
673     MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor));
674
675     return_value = msCopyLabel(&(dst->label), &(src->label));
676     if (return_value != MS_SUCCESS) {
677         msSetError(MS_MEMERR, "Failed to copy label.",
678             "msCopyLegend()");
679         return MS_FAILURE;
680     }
681
682     MS_COPYSTELEM(keysizex);
683     MS_COPYSTELEM(keysizey);
684     MS_COPYSTELEM(keyspacingx);
685     MS_COPYSTELEM(keyspacingy);
686
687     MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor));
688
689     MS_COPYSTELEM(status);
690     MS_COPYSTELEM(height);
691     MS_COPYSTELEM(width);
692     MS_COPYSTELEM(position);
693     MS_COPYSTELEM(transparent);
694     MS_COPYSTELEM(interlace);
695     MS_COPYSTELEM(postlabelcache);
696
697 #ifndef __cplusplus
698     MS_COPYSTRING(dst->template, src->template);
699 #else
700     MS_COPYSTRING(dst->_template, src->_template);
701 #endif
702     dst->map = map;
703
704     return MS_SUCCESS;
705 }
706
707 /***********************************************************************
708  * msCopyLayer()                                                       *
709  *                                                                     *
710  * Copy a layerObj, using mapfile.c:initClass(), msCopyClass(),        *
711  * msCopyColor(), msCopyProjection(), msSHPOpenFile(),                 *
712  * msCreateHashTable(), msCopyHashTable(), msCopyExpression()          *
713  *                                                                     *
714  * As it stands, we are not copying a layer's resultcache              *
715  **********************************************************************/
716
717 int msCopyLayer(layerObj *dst, layerObj *src)
718 {
719     int i, return_value;
720     featureListNodeObjPtr current;
721
722     MS_COPYSTELEM(index);
723     MS_COPYSTRING(dst->classitem, src->classitem);
724
725     MS_COPYSTELEM(classitemindex);
726
727     for (i = 0; i < src->numclasses; i++) {
728         if (msGrowLayerClasses(dst) == NULL)
729             return MS_FAILURE;
730 #ifndef __cplusplus
731         initClass(dst->class[i]);
732         return_value = msCopyClass(dst->class[i], src->class[i], dst);
733 #else
734         initClass(dst->_class[i]);
735         return_value = msCopyClass(dst->_class[i], src->_class[i], dst);
736 #endif
737         if (return_value != MS_SUCCESS) {
738             msSetError(MS_MEMERR, "Failed to copy class.", "msCopyLayer()");
739             return MS_FAILURE;
740         }
741         dst->numclasses++;
742     }
743     MS_COPYSTRING(dst->header, src->header);
744     MS_COPYSTRING(dst->footer, src->footer);
745 #ifndef __cplusplus
746     MS_COPYSTRING(dst->template, src->template);
747 #else
748     MS_COPYSTRING(dst->_template, src->_template);
749 #endif
750
751     MS_COPYSTRING(dst->name, src->name);
752     MS_COPYSTRING(dst->group, src->group);
753     MS_COPYSTRING(dst->data, src->data);
754    
755     MS_COPYSTELEM(status);
756     MS_COPYSTELEM(type);
757     MS_COPYSTELEM(annotate);
758     MS_COPYSTELEM(tolerance);
759     MS_COPYSTELEM(toleranceunits);
760     MS_COPYSTELEM(symbolscaledenom);
761     MS_COPYSTELEM(scalefactor);
762     MS_COPYSTELEM(minscaledenom);
763     MS_COPYSTELEM(maxscaledenom);
764
765     MS_COPYSTELEM(labelminscaledenom);
766     MS_COPYSTELEM(labelmaxscaledenom);
767
768     MS_COPYSTELEM(sizeunits);
769     MS_COPYSTELEM(maxfeatures);
770
771     MS_COPYCOLOR(&(dst->offsite), &(src->offsite));
772
773     MS_COPYSTELEM(transform);
774     MS_COPYSTELEM(labelcache);
775     MS_COPYSTELEM(postlabelcache);
776
777     MS_COPYSTRING(dst->labelitem, src->labelitem);
778     MS_COPYSTELEM(labelitemindex);
779
780     MS_COPYSTRING(dst->tileitem, src->tileitem);
781     MS_COPYSTELEM(tileitemindex);
782
783     MS_COPYSTRING(dst->tileindex, src->tileindex);
784
785     return_value = msCopyProjection(&(dst->projection),&(src->projection));
786     if (return_value != MS_SUCCESS) {
787         msSetError(MS_MEMERR, "Failed to copy projection.", "msCopyLayer()");
788         return MS_FAILURE;
789     }
790
791     MS_COPYSTELEM(project);
792     MS_COPYSTELEM(units);
793
794     current = src->features;
795     while(current != NULL) {
796         insertFeatureList(&(dst->features), &(current->shape));
797         current = current->next;
798     }
799
800     MS_COPYSTRING(dst->connection, src->connection);
801     MS_COPYSTELEM(connectiontype);
802
803     MS_COPYSTRING(dst->plugin_library, src->plugin_library);
804     MS_COPYSTRING(dst->plugin_library_original, src->plugin_library_original);
805        
806     /* Do not copy *layerinfo, items, or iteminfo. these are all initialized
807        when the copied layer is opened */
808
809     return_value = msCopyExpression(&(dst->filter), &(src->filter));
810     if (return_value != MS_SUCCESS) {
811         msSetError(MS_MEMERR, "Failed to copy filter.", "msCopyLayer()");
812         return MS_FAILURE;
813     }
814
815     MS_COPYSTRING(dst->filteritem, src->filteritem);
816     MS_COPYSTELEM(filteritemindex);
817
818     MS_COPYSTRING(dst->styleitem, src->styleitem);
819     MS_COPYSTELEM(styleitemindex);
820
821     MS_COPYSTRING(dst->requires, src->requires);
822     MS_COPYSTRING(dst->labelrequires, src->labelrequires);
823
824     if (&(src->metadata)) {
825         msCopyHashTable(&(dst->metadata), &(src->metadata));
826     }
827
828     MS_COPYSTELEM(opacity);
829     MS_COPYSTELEM(dump);
830     MS_COPYSTELEM(debug);
831
832     /* No need to copy the numprocessing member, as it is incremented by
833        msLayerAddProcessing */
834     for (i = 0; i < src->numprocessing; i++)
835     {
836         msLayerAddProcessing(dst, msLayerGetProcessing(src, i));
837     }
838
839     MS_COPYSTELEM(numjoins);
840
841     for (i = 0; i < dst->numjoins; i++) {
842         initJoin(&(dst->joins[i]));
843         return_value = msCopyJoin(&(dst->joins[i]), &(src->joins[i]));
844         if (return_value != MS_SUCCESS)
845             return MS_FAILURE;
846     }
847
848                 MS_COPYRECT(&(dst->extent), &(src->extent));
849    
850     return MS_SUCCESS;
851 }
852
853 /***********************************************************************
854  * msCopyMap()                                                         *
855  *                                                                     *
856  * Copy a mapObj, using mapfile.c:initLayer(), msCopyLayer(),          *
857
858  * msCopyLegend(), msCopyScalebar(), msCopyProjection()                *
859  * msCopyOutputFormat(), msCopyWeb(), msCopyReferenceMap()             *
860  **********************************************************************/
861
862 int msCopyMap(mapObj *dst, mapObj *src)
863 {
864     int i, return_value;
865     outputFormatObj *format;
866
867     MS_COPYSTRING(dst->name, src->name);
868     MS_COPYSTELEM(status);
869     MS_COPYSTELEM(height);
870     MS_COPYSTELEM(width);
871
872     for (i = 0; i < src->numlayers; i++) {
873         if (msGrowMapLayers(dst) == NULL)
874             return MS_FAILURE;
875         initLayer((GET_LAYER(dst, i)), dst);
876
877         return_value = msCopyLayer((GET_LAYER(dst, i)), (GET_LAYER(src, i)));
878         if (return_value != MS_SUCCESS) {
879             msSetError(MS_MEMERR, "Failed to copy layer.", "msCopyMap()");
880             return MS_FAILURE;
881         }
882         dst->numlayers++;
883     }
884    
885     return_value = msCopyFontSet(&(dst->fontset), &(src->fontset), dst);
886     if (return_value != MS_SUCCESS) {
887         msSetError(MS_MEMERR, "Failed to copy fontset.", "msCopyMap()");
888         return MS_FAILURE;
889     }
890    
891     return_value = msCopySymbolSet(&(dst->symbolset), &(src->symbolset), dst);
892     if(return_value != MS_SUCCESS) {
893         msSetError(MS_MEMERR, "Failed to copy symbolset.", "msCopyMap()");
894         return MS_FAILURE;
895     }
896
897     /* msCopyLabelCache(&(dst->labelcache), &(src->labelcache)); */
898     MS_COPYSTELEM(transparent);
899     MS_COPYSTELEM(interlace);
900     MS_COPYSTELEM(imagequality);
901
902     MS_COPYRECT(&(dst->extent), &(src->extent));
903
904     MS_COPYSTELEM(cellsize);
905     MS_COPYSTELEM(units);
906     MS_COPYSTELEM(scaledenom);
907     MS_COPYSTELEM(resolution);
908     MS_COPYSTRING(dst->shapepath, src->shapepath);
909     MS_COPYSTRING(dst->mappath, src->mappath);
910
911     MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor));
912
913     /* clear existing destination format list */
914     if( dst->outputformat && --dst->outputformat->refcount < 1 )
915     {
916         msFreeOutputFormat( dst->outputformat );
917         dst->outputformat = NULL;
918     }
919
920     for(i=0; i < dst->numoutputformats; i++ ) {
921         if( --dst->outputformatlist[i]->refcount < 1 )
922             msFreeOutputFormat( dst->outputformatlist[i] );
923     }
924     if( dst->outputformatlist != NULL )
925         msFree( dst->outputformatlist );
926     dst->outputformatlist = NULL;
927     dst->outputformat = NULL;
928     dst->numoutputformats = 0;
929
930     for (i = 0; i < src->numoutputformats; i++)
931         msAppendOutputFormat( dst,
932         msCloneOutputFormat( src->outputformatlist[i]) );
933
934     /* set the active output format */
935     MS_COPYSTRING(dst->imagetype, src->imagetype);
936     format = msSelectOutputFormat( dst, dst->imagetype );
937     msApplyOutputFormat(&(dst->outputformat), format, MS_NOOVERRIDE,
938         MS_NOOVERRIDE, MS_NOOVERRIDE );
939
940     return_value = msCopyProjection(&(dst->projection),&(src->projection));
941     if (return_value != MS_SUCCESS) {
942         msSetError(MS_MEMERR, "Failed to copy projection.", "msCopyMap()");
943         return MS_FAILURE;
944     }
945
946     /* No need to copy latlon projection */
947
948     return_value = msCopyReferenceMap(&(dst->reference),&(src->reference),
949         dst);
950     if (return_value != MS_SUCCESS) {
951         msSetError(MS_MEMERR, "Failed to copy reference.", "msCopyMap()");
952         return MS_FAILURE;
953     }
954