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

mcc*_*cma 2 java zip kml google-earth kmz

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

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

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

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

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

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

这是真正的乐趣.如果我将KML从KMZ中取出,使用来自我工作区的资源中的icons文件夹重新打包,保存为KMZ并加载到google earth中,它可以正常工作.

我觉得这样告诉我,我的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 < resourceFiles.length; i++){
    //Previously wrote kml file, time to read it in and add to zip
    if (i == 0){
        FileInputStream fin = new FileInoutStream(fileOut);
        zout.putNextEntry(new ZipEntry(fileOut.getName());
        int length;
        while ((length = fin.read(buffer)) > 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
Run Code Online (Sandbox Code Playgroud)

Jas*_*nM1 5

这是使用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("<?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("<Placemark>");
        // add reference to image via inline style
        ps.println("  <Style><IconStyle>");
        ps.println("    <Icon><href>image.png</href></Icon>");
        ps.println("  </IconStyle></Style>");
        ps.println("</Placemark>");
        ps.println("</kml>");
        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();
    }   
}   
Run Code Online (Sandbox Code Playgroud)