2

そのため、過去にいくつかのサンプル KML/KMZ ファイルを主に手作業で作成しましたが、この作業の結果、Google Earth とのいくつかの矛盾を発見しました。ほとんどの場合、特定のバージョンの GE に対して何をする必要があるかをよく把握していると思いました。最近、ポイントやその他のメタデータの特定の CSV に基づいて特定のクライアント向けにカスタマイズするために、KML/KMZ サンプル ファイルに自動化を追加しようとしました。

カスタム アイコンまたはコンテンツを使用して Java から KMZ ファイルを作成した経験のある方に連絡したいと思います。これが私が立ち往生しているしわです:

クライアント データをより適切に表示するために、多数のスタイルとカスタム アイコンを手作業で作成しました。最近、KML/KMZ の作成を自動化することで時間を大幅に節約できる Java アプリを作成しました。これらのスタイルは、例から Java コードに直接コピーされました (適切な場所にエスケープがあります)。Java コードは最初に KML を構築し、次にサンプルのアイコン フォルダーを使用して KML をパッケージ化し、圧縮して KMZ として保存しました。すべてうまくいきました。

次に、主にこの例に基づいてコード ブロックを追加し、すべてのアイコンをリソースとして jar に追加しました。次に、ファイルを .zip として作成し、KML ファイルとアイコン ファイル (適切なフォルダー内) が zip に含まれていることを確認しました。彼らはいた。すべてが世界に満足していました。

次に、出力ファイル名を .zip ではなく .kmz に変更し、出力を Google で実行しようとしました。カスタム アイコンが読み込まれません。KML は正常に動作し、ポイントとポリゴンは適切なスタイルの色で表示されますが、アイコンにアクセスできないかのように、中央に X が表示されたボックスがあります。

出力 KMZ の名前を zip に変更し、その中で KML を解凍して実行すると、すべてが期待どおりに機能します。再圧縮して KMZ に名前を変更すると、再び壊れます。

ここが本当の楽しみです。KML を KMZ から取り出し、ワークスペースのリソースからアイコン フォルダーを使用して再パックし、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
4

1 に答える 1

7

ルート KML ファイルと画像ファイル エントリを含む ZipOutputStreamを使用して、サンプル 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();
    }   
}   
于 2012-10-06T18:57:04.157 に答える