2012-10-05 78 views
2

因此,过去我主要通过手工制作了一些KML/KMZ文件样本,并且发现了几个inconsistencies与谷歌地球的结果。在大多数情况下,我认为我很好地处理了我需要为特定版本的GE所做的工作。最近,我试图为我的KML/KMZ示例文件添加一些自动化功能,以根据给定的点数和其他元数据的CSV值为某些客户端定制它们。无法使用java.util.zip创建KMZ文件

我想与那些有自定义图标或内容从Java创建KMZ文件的经验的人联系。这里是我卡住的皱纹:

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

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

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

如果我将输出KMZ重命名为zip,解压缩并在其中运行KML,则所有内容都按预期工作。如果我重新打包并重新命名为KMZ,则会再次损坏。

虽然这是真正的乐趣。如果我将KML从KMZ中取出,请使用工作区中资源的图标文件夹进行重新包装,另存为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 < 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 
+0

是的,在googleearth中java.util.zip和KWZ存在问题。我终于设法让它工作(痛苦地),我可以向你发送代码示例,但是我在星期一之前无法访问此代码: -/ –

回答

4

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

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

为了减少下面例子中的代码行,Apache公用程序库用于将输入文件复制到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(); 
    } 
} 
+0

请欣赏此处的帮助,但是,通过查看代码并比较我在做什么,没有任何东西会跳出来,导致我遇到的问题。我会用尽可能多的代码更新我的原始主题,希望有人比我看到我不是这样的错误更好。 – mcconcma

+0

您的示例中的问题是您正在创建带有前导'/'的zip路径,因此KMZ文件中的第一个条目是/icons/b-lv.png。 您想剥离领先的'/'以在ZipEntry(arg)中创建类似图标/ b-lv.png的条目,然后使用相对URL(例如)创建参考图标 。 – JasonM1

+0

宾果。发布代码的力量! – mcconcma