无法使用java.util.zip创建KMZ文件

所以,我过去制作了一些样本KML / KMZ文件,主要是手工制作,并且由于这项工作发现了一些与Google Earth 不一致的内容。 在大多数情况下,我认为我能够很好地处理特定版本的GE需要做的事情。 最近,我尝试在我的KML / KMZ示例文件中添加一些自动化,以根据给定的点和其他元数据CSV为某些客户端自定义它们。

我想与具有使用自定义图标或内容从Java创建KMZ文件的经验的人联系。 这是我坚持的皱纹:

我手工创建了一堆样式和自定义图标,以更好地显示客户端数据。 最近,我创建了一个Java应用程序,通过自动化KML / KMZ生成,我可以节省大量时间。 这些样式直接从示例复制到我的Java代码中(在合法的位置有转义)。 Java代码最初构建了KML,然后我用我的示例中的icons文件夹打包了KML,压缩并保存为KMZ。 一切正常。

然后我在很大程度上基于这个例子添加了一个代码块,并将我的所有图标作为资源添加到jar中。 然后我将文件构建为.zip并validationKML和Icon文件(在适当的文件夹中)是否在zip中。 他们是。 所有人都对世界感到满意。

然后我将输出文件名更改为.kmz而不是.zip,并尝试在Google中运行输出。 我的自定义图标都没有加载。 KML工作得很好,点和多边形都有适当的样式颜色,但是中间有X个盒子,好像它不能访问图标一样。

如果我将输出KMZ重命名为zip,解压缩并在其中运行KML,一切都按预期工作。 如果我重新剪辑并重命名为KMZ,它又会被打破。

这是真正的乐趣。 如果我从KZ中取出KML,从我工作区的资源中重新包装图标文件夹,保存为KMZ并加载到谷歌地球,它可以正常工作。

我觉得这样告诉我,我的java.util.zip代码以某种方式破坏了图像,以至于GE不知道如何处理它们。 但是我完全感到困惑的是,为什么它们在打包时工作正常,但是当从同一位置重新包装时再次破坏。

有人有主意吗? 不要发布代码,请提前道歉。 如果我们可以稍微缩小问题空间,我会发布我可以发布的内容。

这是我现在可以转录的代码:

//Create new file output based on file-name of previously made KML file (fileOut) //nameToken exists to pop KML extension off the back end of fileOut.getName() File fileOut2 = new File(fileOut.getParent(), nameToken2[0] + ".kmz"); FileOutputStream foutstream = new FileOutputStream(fileOut2); ZipOutputStream zout = new ZipOutputStream(foutstream); byte[] buffer = new byte[1024]; String[] resourceFiles = {null,"/icons/b-lv.png",...}; //many files listed here for(int i = 0; i  0){ zout.write(buffer,0,length); } zout.closeEntry(); fin.close(); } //Read in resource icon files and add to zip else{ InputStream inStream = this.getClass().getResourceAsStream(resourceFiles[i]); zout.putNextEntry(new ZipEntry(resourceFiles[i])); int length; while((length = inStream.read(buffer)) > 0){ zout.write(buffer,0,length); } zout.closeEntry(); inStream.close(); } } zout.flush(); zout.close(); foutstream.close(); fileOut.delete(); //Deletes previously made KML file 

这是使用ZipOutputStream和根KML文件以及图像文件条目创建示例KMZ文件的Java代码。 如果在添加图像条目之前未正确关闭KML条目,则KMZ文件可能会损坏。

重要信息:您必须确保zip文件条目与KML中的URL引用完全匹配。 zip文件条目不应以’/’或’../’或’C:/’开头。 同样,对KML中的KMZ条目的URL / href引用应该是特定KML文件的相对(例如icons / b-lv.png )。

为了减少下面示例中的代码行,Apache commons IOUtils库用于将输入文件复制到KMZ输出流并关闭流。

 import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.apache.commons.io.IOUtils; import java.io.*; public class TestKmz { public static void main(String[] args) throws IOException { createKMZ(); System.out.println("file out.kmz created"); } public static void createKMZ() throws IOException { FileOutputStream fos = new FileOutputStream("out.kmz"); ZipOutputStream zoS = new ZipOutputStream(fos); ZipEntry ze = new ZipEntry("doc.kml"); zoS.putNextEntry(ze); PrintStream ps = new PrintStream(zoS); ps.println(""); ps.println(""); // write out contents of KML file ... ps.println(""); // add reference to image via inline style ps.println(" "); ps.println(""); ps.println(""); ps.flush(); zoS.closeEntry(); // close KML entry // now add image file entry to KMZ FileInputStream is = null; try { is = new FileInputStream("image.png"); ZipEntry zEnt = new ZipEntry("image.png"); zoS.putNextEntry(zEnt); // copy image input to KMZ output // write contents to entry within compressed KMZ file IOUtils.copy(is, zoS); } finally { IOUtils.closeQuietly(is); } zoS.closeEntry(); zoS.close(); } }