kmz compression for google earth images with java
-
22-07-2019 - |
Question
Does anyone know what compression to use in Java for creating KMZ files that have images stored within them? I tried using standard Java compression (and various modes, BEST_COMPRESSION, DEFAULT_COMPRESSION, etc), but my compressed file and the kmz file always come out slightly different don't load in google earth. It seems like my png images in particular (the actual kml file seems to compress the same way).
Has anyone successfully created a kmz archive that links to local images (and gets stored in the files directory) from outside of google earth?
thanks
Jeff
Solution
The key to understanding this is the answer from @fraser, which is supported by this snippet from KML Developer Support:
The only supported compression method is ZIP (PKZIP-compatible), so neither gzip nor bzip would work. KMZ files compressed with this method are fully supported by the API.
KMZ in Google Earth API & KML Compression in a Unix environment
Apache Commons has an archive handling library which would be handy for this: http://commons.apache.org/proper/commons-vfs/filesystems.html
OTHER TIPS
KMZ is simply a zip file with a KML file and assets. For example, the london_eye.kmz
kmz file contains:
$ unzip -l london_eye.kmz
Archive: london_eye.kmz
Length Date Time Name
-------- ---- ---- ----
451823 09-27-07 08:47 doc.kml
0 09-26-07 07:39 files/
1796 12-31-79 00:00 files/Blue_Tile.JPG
186227 12-31-79 00:00 files/Legs.dae
3960 12-31-79 00:00 files/Olive.JPG
1662074 12-31-79 00:00 files/Wheel.dae
65993 12-31-79 00:00 files/Wooden_Fence.jpg
7598 12-31-79 00:00 files/a0.gif
7596 12-31-79 00:00 files/a1.gif
7556 12-31-79 00:00 files/a10.gif
7569 12-31-79 00:00 files/a11.gif
7615 12-31-79 00:00 files/a12.gif
7587 12-31-79 00:00 files/a13.gif
7565 12-31-79 00:00 files/a14.gif
7603 12-31-79 00:00 files/a15.gif
7599 12-31-79 00:00 files/a16.gif
7581 12-31-79 00:00 files/a17.gif
7606 12-31-79 00:00 files/a18.gif
7613 12-31-79 00:00 files/a19.gif
7607 12-31-79 00:00 files/a2.gif
7592 12-31-79 00:00 files/a3.gif
7615 12-31-79 00:00 files/a4.gif
7618 12-31-79 00:00 files/a5.gif
7618 12-31-79 00:00 files/a6.gif
7578 12-31-79 00:00 files/a7.gif
7609 12-31-79 00:00 files/a8.gif
7603 12-31-79 00:00 files/a9.gif
57185 12-31-79 00:00 files/capsule.dae
310590 12-31-79 00:00 files/groundoverlay.jpg
224927 12-31-79 00:00 files/mechanism.dae
160728 12-31-79 00:00 files/shadowoverlay.jpg
33044 12-31-79 00:00 files/shed.dae
-------- -------
3310275 32 files
You can build this with java.util.zip, or even with jar
if you want.
As far as the images go, they should not be compressed, since they already contain compressed data. You don't get any significant savings.
By default the ZipOutputStream class in Java will create a compatible KMZ file that Google Earth can read.
In the ZipEntry you can specify either STORED or DEFLATED compression method, both of which are compatible with Google Earth.
- Note whichever ZIP library or API you use, you must make sure to specify ZIP 2.0 or "legacy" compression methods (i.e., STORED and DEFLATE methods) unless these are the default methods. DEFLATE method is called SuperFast and STORED is called None or 'No Compression' in WinZip documentation.
- Maximum or enhanced deflate method often displayed with the short name "Defl:X" is also supported in Google Earth.
- More advanced compression methods (e.g., bzip2, LZMA, etc.) are NOT compatible with Google Earth and such KMZ files will be silently ignored if opened.
Here's simple code snippet to create a KMZ file in Java.
FileOutputStream fos = new FileOutputStream("example.kmz");
ZipOutputStream zoS = new ZipOutputStream(fos);
ZipEntry ze = new ZipEntry("doc.kml");
zoS.putNextEntry(ze);
PrintStream ps = new PrintStream(zoS);
ps.println("<?xml version='1.0' encoding='UTF-8'?>");
ps.println("<kml xmlns='http://www.opengis.net/kml/2.2'>");
// write out contents of KML file ...
ps.println("<Document>");
ps.println("<Placemark>");
// ...
ps.println("</Placemark>");
ps.println("</Document>");
ps.println("</kml>");
ps.flush();
zoS.closeEntry(); // close KML entry
// include and write other files (E.g. icons, overlays, other KML files, etc.)
zoS.close();
Sure, I have package Kmz files with images in c#. AFAIK the only compression method that is supported is ZIP (PKZIP-compatible). What library in Java are you using?
There is a library for dealing with KML in Java called JAK (Java API for KML).
Unfortunately, it seems to have a bug: Issue 1: save KMZ file does not work - so it looks like you're not the first one who has problems with generating a KMZ file...
As simsong said, KMZ is simply zipped KML. One thing I did notice is that doc.kml needs to be the first entry in the zip file for it to work reliably. I don't recall doing anything special with the images (apart from putting everything but doc.kml in a subdirectory). My KMZ files are generated using java.util.zip.