3

次の構造の巨大な kml ファイルがあります。

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <Style id="transBluePoly">
      <LineStyle>
        <width>1.5</width>
      </LineStyle>
      <PolyStyle>
        <color>30ffa911</color>
      </PolyStyle>
    </Style>
    <Style id="labelStyle">
       <IconStyle>
          <color>ffffa911</color>
          <scale>0.35</scale>
       </IconStyle>
       <LabelStyle>
         <color>ffffffff</color>
         <scale>0.35</scale>
      </LabelStyle>
    </Style>
    <Placemark>
      <name>9840229084|2013-03-06 13:41:34.0|rent|0.0|2|0|0|1|T|5990F529FB98F28A1F17D182152201A4|0|null|null|null|null|null|null|null|null|null|null|F|F|0|NO_POSTCODE</name>
      <styleUrl>#transBluePoly</styleUrl>
      <Polygon>
        <outerBoundaryIs>
          <LinearRing>
            <coordinates>
            -1.5191200,53.4086600
            -1.5214300,53.4011900
            -1.5303600,53.4028800
            -1.5435800,53.4033900
            -1.5404900,53.4083600
            -1.5191200,53.4086600
            </coordinates>
          </LinearRing>
        </outerBoundaryIs>
      </Polygon>
    </Placemark>
    <Placemark>
      <name>9840031669|2013-03-06 13:14:22.0|rent|0.0|0|0|0|1|F|E5BAC836984F53F91D7F60F247920F0C|0|null|null|null|null|null|null|null|null|null|null|F|F|3641161|DE4 3JT</name>
      <styleUrl>#transBluePoly</styleUrl>
      <Polygon>
        <outerBoundaryIs>
          <LinearRing>
            <coordinates>
            -1.2370933,53.1227587
            -1.2304837,53.1690463
            -1.1783129,53.2226956
            -1.2016444,53.2833233
            -1.3213687,53.3248921
            -1.4809916,53.3039582
            -1.6167192,53.2438689
            -1.5593782,53.1336370
            -1.4296123,53.0962399
            -1.3205129,53.1024090
            -1.2370933,53.1227587
            </coordinates>
          </LinearRing>
        </outerBoundaryIs>
      </Polygon>
    </Placemark>

ここから 100 万個のポリゴンを抽出して管理しやすくする必要があります (geo DB が究極のソリューションであることを知っています。簡単な修正を探しています)。

それを軽量のテキストエディターにロードして、いくつかの行を削除するだけが私の最初の呼び出しポートですが、これには永遠に1日かかると思われます(10 Gbで、16 Gb RAMがあります)。すべてをRAMに読み込む必要を回避する、Linuxターミナルからのよりインテリジェントなソリューションがあるかどうか疑問に思っています。これを行うためのperlおよびbashコマンドを見てきましたが、ランダム(または最初の100万)サンプルを取得するためにそれらがどのように機能するかわかりません:http://www.unix.com/shell-programming-scripting/159470-filter -kml-file-xml-remove-unwanted-entries.html

4

3 に答える 3

1

KML 解析ライブラリと数行のコードを使用して、大きな KML または KMZ ファイルで必要なものを解析できます。

ジャワ

たとえば、GIScore Java ライブラリは、STaX を使用して KML ソース ファイルを一度に 1 フィーチャずつ解析するため、ファイル全体をメモリにロードする必要はありません。ライブラリは非常に高速に動作するため、10 GB ではそれほど時間はかかりません。

KML ファイル内のポリゴンからポイントを抽出する単純な Java プログラムを次に示します。これは、KML ファイルがどれほど大きいか、または Placemark がフォルダー内で深くネストされているかどうかに関係ありません。

import org.opensextant.geodesy.Geodetic2DPoint;
import org.opensextant.giscore.events.*;
import org.opensextant.giscore.geometry.*;
import org.opensextant.giscore.input.kml.KmlInputStream;

import java.io.FileInputStream;
import java.io.IOException;
import java.text.DecimalFormat;

public class Test {

  public static void main(String[] args) throws IOException {
    KmlInputStream kis = new KmlInputStream(new FileInputStream("test.kml"));
    IGISObject obj;
    DecimalFormat df = new DecimalFormat("0.0#####");
    while((obj = kis.read()) != null) {
      if (obj instanceof Feature) {
        Feature f = (Feature)obj;
        Geometry g = f.getGeometry();
        if (g instanceof Polygon) {
          System.out.println("Points");
          for(Point p : ((Polygon)g).getOuterRing().getPoints()) {
            // do something with the points (e.g. insert in database, etc.)
            Geodetic2DPoint pt = p.asGeodetic2DPoint();
            System.out.printf("%s,%s%n",
                    df.format(pt.getLatitudeAsDegrees()),
                    df.format(pt.getLongitudeAsDegrees()));
          }
        }
      }
    }
    kis.close();
  }
}

実行するには、ディレクトリ src/main/java にソース ファイル Test.java を作成し、上記のコードをファイルにコピーします。

Geometry がMultiGeometryの場合は、そのチェックを追加して、サブジオメトリを反復処理する必要があります。

Gradle を使用して、コマンドgradle runを使用して上記のテスト プログラムを実行するサンプルのbuild.gradleスクリプトを次に示します。

apply plugin: 'java'

repositories {
    mavenCentral()
}

task run (dependsOn: 'compileJava', type: JavaExec) {
    main = 'Test'
    classpath = sourceSets.main.runtimeClasspath
}

dependencies {
    compile 'org.opensextant:geodesy:2.0.1'
    compile 'org.opensextant:giscore:2.0.1'
}

これには、 GradleJava Development Kit (JDK)の両方をインストールする必要があります。

パイソン

または、Python とpykmlライブラリを使用して KML を解析できます。ポリゴンを分割したり、ポリゴン ジオメトリ フィーチャを PostgreSQL データベースに挿入したりするロジックを使用して、複数の小さな KML ファイルを作成できますタグを使用して、stackoverflow で pykml がサポートされています。

from pykml import parser
import re

with open('data.kml', 'r') as fp:
  doc = parser.parse(fp)

for pm in doc.getroot().Document.Placemark:
  print(pm.name)
  # Get the coordinates from either polygon or polygon inside multigeometry
  if hasattr(pm, 'MultiGeometry'):
    pm = pm.MultiGeometry
  if hasattr(pm, 'Polygon'):
    pcoords = pm.Polygon.outerBoundaryIs.LinearRing.coordinates.text
    # extract coords into a list of lon,lat coord pairs
    coords = re.split(r'\s+', pcoords.strip())
    for coord in coords:
        lonlat = coord.split(',')
        if len(lonlat) > 1:
            print(lonlat[0], lonlat[1])
            # add logic here - insert points into DB, etc.
于 2015-06-29T16:44:25.060 に答える
0

これは遅すぎるかもしれませんが、あなたのためにいくつかの考えがあります。

私は伝統的にワイルド カード検索を使用して、Microsoft Word でそのようなコード ブロックを変更してきました。ファイルが Word には大きすぎるかもしれませんが、概念は他の同様のツールでも機能します。

私はあなたのファイルの 1 つのブロックを取得し、3 つの検索と置換を実行しました (1) 名前を取得して " マークに挿入する、(2) 文字の中間ブロックを削除して = char に置き換える、および (3)最後のコード ブロックを削除します。

次のように機能しました。

(実際には、最初にスペースを削除するためにいくつかの整理を行いました - これらはおそらく、コード自体ではなく、この Web サイトのアーティファクトです)

Replace  [<]Placemark[>][<]name[>](**)[<]/name[>]   by   “\1”

Replace  [<]styleUrl(**)[<]coordinates[>]             by   =

Replace  [<]/coordinates(**)[<]Placemark[>]         by   nothing

角括弧は、エスケープとしていくつかの文字を使用して単語を停止するために必要です (私はそれらをあまりにも頻繁に使用したのでしょうか?)

(**) シーケンスは、これらのグループ間のすべてをキャプチャし、置換フィールドで使用されるラベル \1 を付与します。

理論的には、3 つすべてを一緒に使用して 1 回のヒットでこれを実行できるはずですが、基本に戻ってコードを削減するまで、Word では複雑すぎるフォーム エラーが発生します。そう:

Replace [<]Place**name[>](**)[<]/name**nates[>](**)[<]/coord**mark[>] by "\1"=\3

実際に動作します。

もちろん、結果の形式を必要なものに簡単に変更できます (つまり、出力で " または = を使用しない)。さらに検索と置換を使用して、必要なパッケージの準備ができている出力を操作できます。

ワイルドカード検索と置換は楽しいです!

ボブ J.

PS私は、この概念を使用してWord vbaでコンパイラを作成し、Excelから一連のテキスト文字列を取得して、重要なマッピングデータを保持し、それらを完全に機能するkmlファイルに変換しました。現在の入力ファイルは 2500 行にわたって 200k 文字を超えており、約 19,000 行にわたる 700k kml ファイルを生成します。「コンパイル」には約 30 秒かかります。これはあなたの状況の逆です。

于 2013-05-06T23:19:37.363 に答える