2012-10-05 4 views
2

J'ai donc fait quelques exemples de fichiers KML/KMZ dans le passé, en grande partie à la main, et j'ai découvert quelques inconsistencies avec Google Earth à la suite de ce travail. Pour la plupart, je pensais avoir une bonne idée de ce que je devais faire pour des versions spécifiques de GE. Récemment, j'ai tenté d'ajouter une certaine automatisation à mes fichiers d'exemple KML/KMZ pour les personnaliser pour certains clients en fonction d'un CSV donné de points et d'autres métadonnées.Impossible de créer un fichier KMZ en utilisant java.util.zip

Je veux atteindre ceux qui ont de l'expérience dans la création de fichiers KMZ à partir de Java avec des icônes ou du contenu personnalisés. Voici la ride sur laquelle je suis coincé:

J'ai créé, à la main, un tas de styles et d'icônes personnalisées pour mieux afficher les données client. Récemment, j'ai créé une application Java qui me permet d'économiser beaucoup de temps en automatisant la production KML/KMZ. Ces styles ont été copiés directement à partir des exemples dans mon code Java (avec des échappements à leur place légitime). Le code Java initialement construit le KML, puis j'ai emballé le KML avec le dossier des icônes de mes exemples, zippé et enregistré en tant que KMZ. Tout a bien fonctionné.

J'ai ensuite ajouté un bloc de code largement basé sur this example et ajouté toutes mes icônes comme ressources au pot. J'ai ensuite construit le fichier en .zip et vérifié que les fichiers KML et Icon (dans les dossiers appropriés) étaient dans le zip. Ils étaient. Tout était content du monde. J'ai ensuite changé le nom de fichier de sortie en .kmz au lieu de .zip et j'ai essayé d'exécuter la sortie dans Google. Aucune de mes icônes personnalisées n'est chargée. Le KML fonctionne bien, les points et les polygones sont là avec les couleurs de style correctes, mais il y a des boîtes avec des X au milieu comme si elles ne pouvaient pas accéder aux icônes.

Si je renomme la sortie KMZ en zip, décompressez et exécutez le fichier KML à l'intérieur, tout fonctionne comme prévu. Si je regrette et rebaptise KMZ, c'est encore cassé.

Mais c'est vraiment amusant. Si je retire le KML de la KMZ, remballer avec le dossier des icônes à partir des ressources de mon espace de travail, enregistrer en tant que KMZ et charger dans Google Earth, cela fonctionne correctement. J'ai l'impression que cela me dit que mon code java.util.zip est en quelque sorte corrompant les images à un point où GE ne sait pas quoi faire avec eux. Mais je suis complètement confus quant à la raison pour laquelle ils fonctionnent bien lorsqu'ils ne sont pas emballés, mais ils sont de nouveau cassés lorsqu'ils sont reconditionnés au même endroit.

Vous avez des idées? Excuses d'avance pour ne pas poster de code. Je posterai ce que je peux si nous pouvons réduire un peu l'espace problème.

est ici code autant que je peux retranscrire au 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 
+0

Oui, il y a un problème avec java.util.zip et KWZ dans googleearth. J'ai finalement réussi à le faire fonctionner (douloureusement), je peux vous envoyer des échantillons de codes, mais je n'ai pas accès à ce code jusqu'à lundi: -/ –

Répondre

4

est ici le code Java pour créer un fichier KMZ exemple à l'aide ZipOutputStream avec le fichier KML racine et une entrée de fichier d'image. Si vous ne fermez pas correctement l'entrée KML avant d'ajouter les entrées d'image, le fichier KMZ peut être corrompu.

IMPORTANT: Vous devez vous assurer que les entrées de fichier zip correspondent exactement aux références d'URL dans le fichier KML. Les entrées du fichier zip doivent PAS commencer par '/' ou '../' ou 'C: /'. De même, les références URL/href aux entrées KMZ dans le fichier KML doivent être relatives (par exemple icons/b-lv.png) au fichier KML particulier.

Pour réduire les lignes de code dans l'exemple ci-dessous, la bibliothèque Apache commons IOUtils est utilisée pour copier le fichier d'entrée dans le flux de sortie KMZ et pour fermer le flux.

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

Appréciez l'aide ici, cependant, en regardant à travers votre code et en comparant ce que je fais avec le mien, rien ne me saute dessus qui causerait les problèmes que j'ai. Je mettrai à jour mon sujet original avec autant de code que je peux dans l'espoir que quelqu'un de bien mieux que moi voit l'erreur que je ne suis pas. – mcconcma

+0

Un problème avec votre exemple est que vous créez des chemins zip avec '/' en tête donc la première entrée dans le fichier KMZ est /icons/b-lv.png. Vous voulez supprimer le premier '/' pour créer une entrée comme icons/b-lv.png dans ZipEntry (arg), puis référencer les icônes avec les URL relatives (par exemple ). – JasonM1

+0

Bingo. Le pouvoir de poster du code! – mcconcma

Questions connexes