Create KMZ in C#

2,205 views
Skip to first unread message

David

unread,
Aug 3, 2007, 10:49:36 PM8/3/07
to KML Developer Support - Advanced Support
I am creating an asp.net webpage that needs to create a KMZ file from
a .png and a .kml file I have found code that uses the
ICSharpCode.SharpZipLib.dll but when it creates it the .png has a
problem and when I try to open the KMZ in google earth I get this
error.

Open of file "FileName.kmz" failed: Parse error at line 1, column 2:

not well formed (invalid token)

I assume it has something to do with the ICSharpCode.SharpZipLib.dll
but I do not know of another way of creating a KMZ through C#, can
anyody tell me how to create a KMZ?

Thank You

Jonathan van Tuijl

unread,
Aug 4, 2007, 12:01:21 AM8/4/07
to KML Developer Support - Advanced Support
David wrote:
> I am creating an asp.net webpage that needs to create a KMZ file from
> a .png and a .kml file I have found code that uses the
> ICSharpCode.SharpZipLib.dll but when it creates it the .png has a
> problem

You're losing me here.

> and when I try to open the KMZ in google earth I get this error.
>
> Open of file "FileName.kmz" failed: Parse error at line 1, column 2:
>
> not well formed (invalid token)

That means that Google Earth managed to find a supposedly-KML file
inside the KMZ, but failed parsing at the second character already!
You should check your KML, and if it's OK, whether something goes
wrong packing the KMZ. Try decompressing it like a normal zip and
checking its contents. If you're still clueless you can upload a
problematic KMZ file so people here can check it.

> I assume it has something to do with the ICSharpCode.SharpZipLib.dll
> but I do not know of another way of creating a KMZ through C#, can
> anyody tell me how to create a KMZ?

Can't help you with C#.

Jonathan

David

unread,
Aug 4, 2007, 12:53:06 AM8/4/07
to KML Developer Support - Advanced Support
How do I upload the KMZ file?

Here is the code I used to test this out, this is just simply the code
that you use to make a .zip file, it takes in a directory that
contains the KML and the PNG file then creates a zip file from those
files.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Perform some simple parameter checking. More could be
done
// like checking the target file name is ok, disk space,
and lots
// of other things, but for a demo this covers some
obvious traps.
string DirectoryName = @"C:\Users\David\Desktop\TestKMZ
\TestKMZ\";
string ZipFileName = @"C:\Users\David\Desktop\TestKMZ
\TestKMZ.kmz";
if (!Directory.Exists(DirectoryName))
{
Console.WriteLine("Cannot find directory '{0}'",
DirectoryName);
return;
}

try
{
// Depending on the directory this could be very large
and would require more attention
// in a commercial package.
string[] filenames =
Directory.GetFiles(DirectoryName);

// 'using' statements gaurantee the stream is closed
properly which is a big source
// of problems otherwise. Its exception safe as well
which is great.
using (ZipOutputStream s = new
ZipOutputStream(File.Create(ZipFileName)))
{

s.SetLevel(9); // 0 - store only to 9 - means best
compression

byte[] buffer = new byte[4096];

foreach (string file in filenames)
{

// Using GetFileName makes the result
compatible with XP
// as the resulting path is not absolute.
ZipEntry entry = new
ZipEntry(Path.GetFileName(file));

// Setup the entry data as required.

// Crc and size are handled by the library for
seakable streams
// so no need to do them here.

// Could also use the last write time or
similar for the file.
entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);

using (FileStream fs = File.OpenRead(file))
{

// Using a fixed size buffer here makes no
noticeable difference for output
// but keeps a lid on memory usage.
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0,
buffer.Length);
s.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
}

// Finish/Close arent needed strictly as the using
statement does this automatically

// Finish is important to ensure trailing
information for a Zip file is appended. Without this
// the created file would be invalid.
s.Finish();

// Close is important to wrap things up and unlock
the file.
s.Close();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception during processing {0}",
ex);

// No need to rethrow the exception as for our
purposes its handled.

Jonathan van Tuijl

unread,
Aug 4, 2007, 11:10:18 AM8/4/07
to KML Developer Support - Advanced Support
David wrote:
> How do I upload the KMZ file?

Notice the files link: http://groups.google.com/group/kml-support/files

> Here is the code I used to test this out, this is just simply the code
> that you use to make a .zip file, it takes in a directory that
> contains the KML and the PNG file then creates a zip file from those
> files.

I don't see anything that's obviously wrong.

Jonathan

David

unread,
Aug 5, 2007, 8:06:33 AM8/5/07
to KML Developer Support - Advanced Support

Jonathan van Tuijl

unread,
Aug 5, 2007, 5:10:32 PM8/5/07
to KML Developer Support - Advanced Support
David wrote:
> http://groups.google.com/group/kml-support/web/TestKMZ.kmz

The sizes are stored in zip64 format, which GE probably doesn't like.
Can you turn it off? You don't need it if your files are smaller than
4 GB anyway. If you can't, is there a way to send it the entire file
at once, i.e. not using a stream but one large buffer? If you do that,
it might decide to use non-64 zip because it can predict the size.

Jonathan

David

unread,
Aug 5, 2007, 10:06:44 PM8/5/07
to KML Developer Support - Advanced Support
Any code suggestions I tried several different things and nothing
worked. Thank you for your help so far.

Jonathan van Tuijl

unread,
Aug 6, 2007, 10:32:58 AM8/6/07
to KML Developer Support - Advanced Support
David wrote:
> Any code suggestions I tried several different things and nothing
> worked. Thank you for your help so far.

Other than creating a zip file the hard way as I've once done (that's
why I could analyze your file) or looking harder at the API, no.

Jonathan

David

unread,
Aug 6, 2007, 10:09:29 PM8/6/07
to KML Developer Support - Advanced Support
I have figured it out in ICSharpCode.SharpZipLib.zip there is a
property called UseZip64 this was set to Dynamic i set it to Off and
it worked, thank you, your answer of it being Zip64 led me to this
Reply all
Reply to author
Forward
0 new messages