无法使用java.util.zip创建KMZ文件 [英] Unable to create KMZ file using java.util.zip

查看:86
本文介绍了无法使用java.util.zip创建KMZ文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我过去主要手工制作了一些示例KML/KMZ文件,并发现了一些

So, I have made some sample KML/KMZ files in the past, largely by hand, and have discovered a few inconsistencies with Google Earth as a result of this work. For the most part, I thought I had a good handle on what I needed to do for specific versions of GE. Recently, I attempted to add some automation to my KML/KMZ sample files to customize them for certain clients based on a given CSV of points and other metadata.

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

I want to reach out to those with experience creating KMZ files from Java with custom icons or content. Here's the wrinkle I'm stuck on:

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

I created, by hand, a bunch of styles and custom icons to better display client data. Recently, I created a Java app that allows me to save a great deal of time by automating the KML/KMZ production. These styles were copied directly from the examples into my Java code (with escapes in their rightful places). The Java code initially built the KML, then I packaged the KML with the icons folder from my examples, zipped and saved as KMZ. All worked fine.

然后,我添加了一个代码块,该代码块主要基于此示例,并将我所有的图标作为资源添加到了jar中.然后,我将文件构建为.zip,并验证了KML和Icon文件(在适当的文件夹中)在zip中.他们是.所有人都对这个世界感到高兴.

I then added a code block largely based on this example and added all my icons as resources to the jar. I then built the file as a .zip and verified that the KML and Icon files (in appropriate folders) were in the zip. They were. All was happy with the world.

然后我将输出文件名更改为.kmz而不是.zip,并尝试在Google中运行输出.我的自定义图标均未加载. KML可以正常工作,其中的点和多边形具有适当的样式颜色,但是中间有带有X的框,好像它无法访问图标一样.

I then changed the output filename to .kmz instead of .zip and tried to run the output in Google. None of my custom icons are loaded. The KML works fine, points and polygons are there with the proper style colors, but there are boxes with X's in the middle as if it can't access the icons.

如果我将输出KMZ重命名为zip,解压缩并在其中运行KML,一切都会按预期进行.如果我重新压缩并重命名为KMZ,它将再次损坏.

If I rename the output KMZ to zip, unpack and run the KML inside it, everything works as expected. If I rezip and rename to KMZ, it's broken again.

这是真正的乐趣.如果我将KML从KMZ中取出,请从工作区中的资源重新打包图标文件夹,另存为KMZ并加载到Google Earth中,就可以了.

Here's the real fun though. If I take the KML out of the KMZ, repack with the icons folder from the resources from my workspace, save as KMZ and load into google earth, it works OK.

我感觉这是在告诉我,我的java.util.zip代码以某种方式破坏了图像,使GE都不知道如何处理这些图像.但是我对为什么它们在拆开包装后仍能正常工作却又在从同一位置重新包装拆开后又再次损坏却感到困惑.

I feel like that is telling me that my java.util.zip code is somehow corrupting the images to a point where GE doesn't know what to do with them. But I'm completely confused as to why they work fine when unpackaged, but then again broke when repackaged from the same location.

有人有什么想法吗?对于未发布代码而提前致歉.如果可以缩小问题空间,我将发表我的文章.

Anyone have any ideas? Apologies in advance for not posting code. I will post what I can if we can narrow down the problem space a little.

此刻我可以转录的代码很多:

Here's as much code as I can transcribe at the moment:

//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

推荐答案

此处的Java代码使用

Here's Java code to create a sample KMZ file using ZipOutputStream with root KML file and an image file entry. If you don't properly close the KML entry before adding the image entries then the KMZ file can become corrupt.

重要提示:您必须确保zip文件条目与KML中的URL引用完全匹配.压缩文件条目应以"/"或"../"或"C:/"开头.同样,对KML中的KMZ条目的URL/href引用应相对于特定的KML文件(例如 icons/b-lv.png ).

IMPORTANT: You must make sure the zip file entries match exactly to the URL references within the KML. The zip file entries should NOT start with '/' or '../' or 'C:/'. Likewise, the URL/href references to the KMZ entries in the KML should be relative (e.g. icons/b-lv.png) to the particular KML file.

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

To reduce the lines of code in the example below, the Apache commons IOUtils library is used to copy the input file to the KMZ output stream and to close the stream.

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();
    }   
}   

这篇关于无法使用java.util.zip创建KMZ文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆