2013-04-16 2 views
2

거대한 KML :분할 나는 다음과 같은 구조의 거대한 KML 파일이 파일

나는 그것을 관리 (DB는 최고의 솔루션입니다 지리를 알 수 있도록이에서 100 만 개 폴리곤을 추출해야
<?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> 

- 찾는 빠른 수정).

가벼운 텍스트 편집기에로드하고 일부 라인을 삭제하면 내 첫 번째 포트가되지만 영원히 하루가 걸릴 것으로 예상됩니다 (10Gb, 16Gb RAM이 있음). 리눅스 터미널에서 모든 것을 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 파일 내부의 폴리곤에서 포인트를 추출하는 간단한 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를 만든 다음 위의 코드를 파일에 복사하십시오.

지오메트리가 MultiGeometry 인 경우 해당 지오메트리에 대한 검사를 추가하고 하위 지오메트리를 반복해야합니다. Gradle을 사용

, 여기에 명령을 사용하여 위의 테스트 프로그램을 실행하는 샘플 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 

실제로 작동합니다.

물론 결과의 형식을 원하는대로 변경할 수 있습니다 (예 : 출력에서 ​​"또는 =을 사용하지 않음). 추가 검색 및 대체를 사용하여 원하는 패키지에 대한 출력 준비를 조정할 수 있습니다 위해.

와일드 카드 검색 및 대체합니다 재미있다!

밥 J. 나는 필수 매핑을 유지 엑셀에서 텍스트 문자열의 일련을 위해이 개념을 사용하여 워드 VBA에서 컴파일러를 쓴 PS

데이터를 변환하여 완전한 kml 파일로 변환합니다. 현재 입력 파일은 200k 문자보다 많습니다. r 2500 라인을 지원하며 약 19,000 라인에 걸쳐 700k kml 파일을 생성합니다. '컴파일'하는 데 약 30 초가 걸립니다. 이것은 귀하의 상황과 반대입니다.

-1

조금 늦었지만 그 대답이 도움이 될 수 있습니다. 거대한 소프트웨어 인 FME DESKTOP을 사용하여 kml 파일을 완벽하게 분할 할 수 있습니다! ModuloCount 변환기를 사용하여. 확인해주세요. Split kml file ModuloCount

관련 문제