2013-04-16 468 views
2

我有以下結構的巨大KML文件:拆分一個巨大的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> 

我需要提取開始1萬個多邊形,使之更易於管理(知道地理DB是終極解決方案 - 尋找快速解決)。

將其加載到一個輕量級的文本編輯器中,只需刪除一些行就可以成爲我的第一通話端口,但懷疑這需要花費一整天的時間(這是10 GB,我有16 GB RAM)。只是想知道是否有一個來自linux終端的更智能的解決方案,避免了將其全部讀入RAM中。我已經看到了perl和bash命令,但是看不到它們如何工作以獲得隨機(或第一百萬)樣本:http://www.unix.com/shell-programming-scripting/159470-filter-kml-file-xml-remove-unwanted-entries.html

回答

1

您可以使用KML解析庫和幾行代碼解析出你在一個大的KML或KMZ文件需要什麼。

例如,GIScore Java library使用STaX一次解析KML源文件的一個功能,因此它不需要將整個文件加載到內存中。該庫運行速度非常快,所以10GB不會很長。

下面是從多邊形提取KML文件,這不要緊KML如何大的文件也沒有,如果標深深嵌套的文件夾內,裏面點一個簡單的Java程序。

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 /主/ JAVA創建源文件Test.java和文件中複製上面的代碼。

如果幾何是MultiGeometry那麼你需要添加一個檢查爲和迭代子的幾何形狀。

使用搖籃,這裏有一個樣本的build.gradle腳本中使用命令來運行上述測試程序: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) 。

0

這可能太晚了,但對您有些想法。

我在傳統上使用通配符搜索在Microsoft Word中修改了這樣的代碼塊。 雖然您的文件對於Word來說可能太大,但這些概念可以與其他類似的工具一起使用。

我拿了一個文件塊並執行三次搜索並替換(1)將名稱插入到標記中,(2)刪除中間的字符塊並將其替換爲= char和(3)刪除最後的代碼塊

它的工作是這樣的:

(其實我做了一些整理,以刪除空格第一 - 這可能是該網站的一個假象,而不是代碼本身)

Replace [<]Placemark[>][<]name[>](**)[<]/name[>] by 「\1」 

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

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

方括號是需要停止使用一些字符作爲轉義字(我可能經常使用它們?)

(**)序列捕獲這些組之間的所有內容,併爲它們提供在替換字段中使用的標籤\ 1。

從理論上講,你應該能夠使用所有這三個一起一重擊要做到這一點,但是這給了一個太複雜的形狀誤差的Word,直到你馬上回基本砍下代碼。所以:

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

實際上會工作。

當然,您可以輕鬆地將結果的格式更改爲所需的格式(即不要在輸出中使用「or =」),並且使用進一步的搜索並替換您可以操作輸出以準備好您想要的任何包對。

通配符搜索並替換的樂趣!

鮑勃J.

PS我已經寫了使用這個概念,以從Excel的一系列文本字符串持有的基本映射在Word VBA編譯器數據並將它們轉換爲完全可用的kml文件。當前輸入文件大於200k字節r 2500線,併產生一個700k kml的文件傳播近19,000行。大約需要30秒才能「編譯」。這與你的情況相反。

-1

我有點晚,但這個問題的答案可能會幫助別人。您可以使用FME DESKTOP完美分割kml文件,這個巨大的軟件!使用ModuloCount變壓器。檢查Split kml file ModuloCount