This project has moved. For the latest updates, please go here.

Exception thrown when MultiGeometry contains 2 Polygons: "Cannot add child element to this instance because it belongs to another instance."

Oct 5, 2013 at 5:52 AM
Hi

I'm trying to add a placemark (retrieved from a larger KML file) but receive an Exception:

"Cannot add child element to this instance because it belongs to another instance."

Here is the self-contained code to reproduce the problem:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SharpKml.Base;
using SharpKml.Dom;
using SharpKml.Engine;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            ReproduceProblem();
        }


        private static void ReproduceProblem()
        {
            string xml = @"<kml xmlns='http://www.opengis.com/kml/2.2'> 
                         <Placemark>
                            <name>LS14 1</name>
                            <styleUrl>#Sty1</styleUrl>
                            <MultiGeometry>
                               <Polygon>
                                  <tessellate>1</tessellate>
                                  <outerBoundaryIs>
                                     <LinearRing>
                                        <coordinates>-1.456725,53.844119,0 -1.457119,53.843288,0 -1.460048,53.83946,0 -1.459529,53.839012,0 -1.459416,53.838689,0 -1.460247,53.83812,0 -1.459717,53.837399,0 -1.459876,53.837222,0 -1.459957,53.83717,0 -1.4601,53.835867,0 -1.459958,53.835824,0 -1.459862,53.835744,0 -1.459486,53.835527,0 -1.460075,53.83449,0 -1.459078,53.833503,0 -1.458972,53.833326,0 -1.460616,53.832201,0 -1.461086,53.832008,0 -1.461205,53.831877,0 -1.459185,53.829798,0 -1.457232,53.828967,0 -1.457242,53.828945,0 -1.456735,53.826853,0 -1.456212,53.826485,0 -1.456549,53.825307,0 -1.456206,53.824937,0 -1.456523,53.824034,0 -1.4565,53.823992,0 -1.45575,53.823717,0 -1.45518,53.822903,0 -1.454709,53.822646,0 -1.454584,53.822435,0 -1.457487,53.821608,0 -1.45795,53.82247,0 -1.45876,53.822856,0 -1.458802,53.822952,0 -1.458753,53.823244,0 -1.460195,53.823953,0 -1.460538,53.8239,0 -1.46144,53.824088,0 -1.461797,53.823859,0 -1.462886,53.823743,0 -1.463501,53.823177,0 -1.464137,53.823363,0 -1.465586,53.823266,0 -1.46591,53.823153,0 -1.466061,53.823013,0 -1.466166,53.822999,0 -1.467433,53.821941,0 -1.46909,53.822545,0 -1.469583,53.822624,0 -1.470115,53.822267,0 -1.471189,53.822053,0 -1.471494,53.822077,0 -1.472278,53.821547,0 -1.474424,53.821183,0 -1.474468,53.821229,0 -1.476077,53.821704,0 -1.476872,53.820715,0 -1.478762,53.820796,0 -1.479085,53.8207,0 -1.479751,53.82114,0 -1.480168,53.821674,0 -1.480289,53.822108,0 -1.480284,53.82215,0 -1.48031,53.822198,0 -1.480867,53.822471,0 -1.481554,53.822905,0 -1.481908,53.82364,0 -1.4819,53.823696,0 -1.482363,53.82412,0 -1.483449,53.824487,0 -1.483461,53.824505,0 -1.482395,53.826217,0 -1.481618,53.82645,0 -1.481459,53.826465,0 -1.480913,53.827145,0 -1.481078,53.828004,0 -1.480427,53.830012,0 -1.480059,53.830174,0 -1.479636,53.830239,0 -1.479157,53.830404,0 -1.477839,53.830558,0 -1.4759,53.83179,0 -1.475711,53.832558,0 -1.475666,53.833118,0 -1.473495,53.833721,0 -1.47234,53.835296,0 -1.472535,53.836063,0 -1.471478,53.836061,0 -1.469539,53.836237,0 -1.469261,53.836462,0 -1.470441,53.837911,0 -1.470438,53.837913,0 -1.469527,53.838021,0 -1.468834,53.837893,0 -1.46815,53.83803,0 -1.467703,53.838359,0 -1.468736,53.839471,0 -1.468686,53.83997,0 -1.467921,53.84062,0 -1.467145,53.840104,0 -1.465721,53.839663,0 -1.464527,53.839945,0 -1.463798,53.840985,0 -1.463672,53.841985,0 -1.462278,53.842423,0 -1.461459,53.842558,0 -1.456725,53.844119,0</coordinates>
                                     </LinearRing>
                                  </outerBoundaryIs>
                               </Polygon>
                               <Polygon>
                                  <tessellate>1</tessellate>
                                  <outerBoundaryIs>
                                     <LinearRing>
                                        <coordinates>-1.441308,53.837198,0 -1.444601,53.837292,0 -1.448558,53.837734,0 -1.450209,53.838432,0 -1.450219,53.838438,0 -1.451244,53.839384,0 -1.451284,53.840002,0 -1.45093,53.842718,0 -1.444127,53.842386,0 -1.441308,53.837198,0</coordinates>
                                     </LinearRing>
                                  </outerBoundaryIs>
                               </Polygon>
                            </MultiGeometry>
                         </Placemark>
                    </kml>";

            Parser parser = new Parser();
            parser.ParseString(xml, false); // Ignore the namespaces
            KmlFile kmlFile = KmlFile.Create(parser.Root, true);

            Document document = new Document() { Name = "Test1" };
            Style style = CreateTestStyle();
            Placemark storePlacemark = CreateTestPlacemark(style);

            document.AddStyle(style);
            document.AddFeature(storePlacemark);

            Folder folder = new Folder() { Name = "Sectors" };
            document.AddFeature(folder);

            Placemark placemark = kmlFile.Root.Flatten().OfType<Placemark>().Where(s => s.Name == "LS14 1").First();
            if (placemark != null)
            {
                folder.AddFeature(placemark);  // <<--- Exception on this line: "Cannot add child element to this instance because it belongs to another instance."
            }
        }

        private static Placemark CreateTestPlacemark(Style style)
        {
            var placemark = new Placemark()
            {
                Name = "StyleTest1",
                Description = new Description() { Text = "Description" },
                StyleUrl = new Uri("#" + style.Id, UriKind.Relative),
                Geometry = new Point { Coordinate = new Vector(-13.163959, -72.545992) }
            };

            return placemark;
        }

        private static Style CreateTestStyle()
        {
            var style = new Style()
            {
                Id = "Test1Icon",
                Icon = new IconStyle()
                {
                    Color = new Color32(255, 0, 255, 0),
                    ColorMode = ColorMode.Normal,
                    Icon = new IconStyle.IconLink(new Uri("http://maps.google.com/mapfiles/kml/pal3/icon21.png")),
                    Scale = 1.2
                },
                Label = new LabelStyle() { Color = new Color32(255, 0, 255, 0) }
            };

            return style;
        }

    }
}
Coordinator
Oct 6, 2013 at 4:39 PM
The exception is being thrown because the placemark you are trying to add already belongs to another element.

To copy it you can use the Clone extension method in the SharpKml.Engine namespace - there's an example of this inside Clone.cs in the Examples folder of the source code.

Hope it helps,
Sam
Oct 6, 2013 at 11:25 PM
Cheers Sam, I wasn't aware that cloning was necessary.

Thanks for such a quick reply.
Mitch
Oct 6, 2013 at 11:27 PM
Do you think adding this to the error message would be useful?:

"Cannot add child element to this instance because it belongs to another instance. Have you cloned the element?"