Load nested kmz/kml files from kmz archive?

Oct 1, 2010 at 4:44 PM


Great project!  After some experimenting with SharpKml, I believe this library is precisely what our team has been searching for.  So far, I have been able to create kml files, open kml/kmz files, and navigate the kml elements in the DOM.  Everything works as expected.

But I do have a question about kmz archives.  I have a kmz archive that contains nested kmz and kml files.  The nested files are referenced from the top-level kml file via networklink elements.  Is there a recommended technique to load the nested kmz/kml files into the DOM?  I am able to open the top-level kmz file without issue, but cannot figure out how to access the information in the nested files.

Is this possible with the current library?  Could you please provide an example of this?


Thanks for all of your hard work!

Oct 1, 2010 at 7:11 PM

Thanks for the kind words!

I think you should be able to handle the Kmz files recursively, using the KmzFile.ReadFile method to extract the nested Kmz file to a byte array then using a MemoryStream to feed into another KmzFile.

Here's a quick demo:

using System;
using System.IO;
using SharpKml.Dom;
using SharpKml.Engine;

class Program
    static KmlFile CreateSampleKml()
        Placemark placemark = new Placemark();
        placemark.Name = "SamplePlacemark";
        return KmlFile.Create(placemark, false);

    static void ListKmzFile(string indentation, KmzFile file)
        foreach (var path in file.Files)
            Console.WriteLine("{0}{1}", indentation, path);

            // Is the file another Kmz file?
            string extension = Path.GetExtension(path);
            if (extension.Equals(".kmz", StringComparison.OrdinalIgnoreCase))
                // Get the contents into a stream so we can create a new KmzFile
                using (var stream = new MemoryStream(file.ReadFile(path)))
                    var child = KmzFile.Open(stream);

                    // Iterate through it's contents recursively
                    ListKmzFile(indentation + "  ", child);

    static void Main(string[] args)
        // Create a kmz file with a nested kmz file
        var root = KmzFile.Create(CreateSampleKml());
        var nested = KmzFile.Create(CreateSampleKml());

        // Save the nested file to a stream to convert it to a byte array
        using (var stream = new MemoryStream())
            root.AddFile("nested.kmz", stream.ToArray());

        // Display the results
        ListKmzFile("  ", root);


The above outputs the following:

Oct 1, 2010 at 8:27 PM

It's much too late on a Friday, but I will try this first thing Monday morning.  :-)

I'll let you know how it goes, and thanks for the help!

Oct 5, 2010 at 4:03 PM

This approach works like a charm -- thanks!