0

具体的には、dom4jを使用してKMLドキュメントを読み込み、XMLのデータの一部を解析していました。URLを文字列形式でリーダーに渡すだけで、非常にシンプルになり、ファイルシステムのURLとWebのURLの両方を処理できます。

SAXReader reader = new SAXReader();
Document document = reader.read(url);

問題は、私のコードがKMZドキュメントを処理する必要がある場合があることです。これは、基本的にXML(KML)ドキュメントを圧縮したものです。残念ながら、SAXReaderでこれを処理する便利な方法はありません。特定のファイルがZIPファイルであるかどうかを判断するためのあらゆる種類のファンキーな解決策を見つけましたが、私のコードはすぐに爆発して厄介になります-ストリームの読み取り、ファイルの作成、最初の「魔法の」16進バイトのチェック、抽出など。

これを処理するための迅速でクリーンな方法はありますか?任意のURLに接続し、圧縮されている場合はコンテンツを抽出する簡単な方法です。それ以外の場合は、単にXMLを取得しますか?

4

1 に答える 1

0

うーん、KMZDOMLoaderがWeb上のkmzファイルを処理していないようです。kmzが動的に読み込まれている可能性があるため、常にa)ファイル参照またはb)特に.kmz拡張子が付いているとは限りません。コンテンツタイプによって決定する必要があります。

私がやったことは、URLオブジェクトを作成してから、プロトコルを取得することでした。ローカルファイルまたはWeb上のドキュメントを処理するための個別のロジックがあります。次に、これらの各ロジックブロック内で、圧縮されているかどうかを判断する必要がありました。SAXReader read()メソッドは入力ストリームを受け取るので、kmzsにZipInputStreamを使用できることがわかりました。

これが私が最終的に得たコードです:

private static final long ZIP_MAGIC_NUMBERS = 0x504B0304;
private static final String KMZ_CONTENT_TYPE = "application/vnd.google-earth.kmz";

private Document getDocument(String urlString) throws IOException, DocumentException, URISyntaxException {
        InputStream inputStream = null;
        URL url = new URL(urlString);
        String protocol = url.getProtocol();

        /*
         * Figure out how to get the XML from the URL -- there are 4 possibilities:
         * 
         * 1)  a KML (uncompressed) doc on the filesystem
         * 2)  a KMZ (compressed) doc on the filesystem
         * 3)  a KML (uncompressed) doc on the web
         * 4)  a KMZ (compressed) doc on the web
         */
        if (protocol.equalsIgnoreCase("file")) {
            // the provided input URL points to a file on a file system
            File file = new File(url.toURI());
            RandomAccessFile raf = new RandomAccessFile(file, "r");
            long n = raf.readInt();
            raf.close();

            if (n == KmlMetadataExtractorAdaptor.ZIP_MAGIC_NUMBERS) {
                // the file is a KMZ file
                inputStream = new ZipInputStream(new FileInputStream(file));
                ((ZipInputStream) inputStream).getNextEntry();
            } else {
                // the file is a KML file
                inputStream = new FileInputStream(file);
            }

        } else if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) {
            // the provided input URL points to a web location
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            String contentType = connection.getContentType();

            if (contentType.contains(KmlMetadataExtractorAdaptor.KMZ_CONTENT_TYPE)) {
                // the target resource is KMZ
                inputStream = new ZipInputStream(connection.getInputStream());
                ((ZipInputStream) inputStream).getNextEntry();
            } else {
                // the target resource is KML
                inputStream = connection.getInputStream();
            }

        }

        Document document = new SAXReader().read(inputStream);
        inputStream.close();

        return document;
    }
于 2013-01-16T14:27:20.440 に答える