SHP GeoJSON 변환
shapefile인 SHP 파일을 GeoJSON 파일로 변환하는 방법에 대해서 GeoJSON 예제 함께 설명드립니다. GeoJSON 포맷과 GeoJSON 변환 Python 스크립트를 함께 설명드리기 때문에 바로 사용할실 수 있습니다. 그리고 원하시는 경우 수정 후 사용 할 수 있습니다. SHP 파일 구조에 대해서 학습하기 위해서는 다음 페이지를 참고해 주시기 바랍니다.
GeoJSON 이란
GeoJSON 이란 간단한 지리정보 특징을 표현하기 위해서 만들어진 공개된 표준 포맷입니다. 좌표 정보와 함께 속성정보등을 함께 저장할 수 있으며 JSON 형태로 저장되게 됩니다. 보다 자세한 내용은 아래의 페이지를 참고해 주시기 바랍니다.
https://en.wikipedia.org/wiki/GeoJSON
GeoJSON 형태는 아래와 같습니다.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"prop0": "value0"
}
}
]
}
GeoJSON 예제
먼저 다음 명령어를 이용하여, 예제 소스코드와 함께 SHP 파일을 다운로드 받아 주시기 바랍니다.
$ git clone https://hiseon.me/reps/shp-file-format.git && cd shp-file-format
$ git submodule init
$ git submodule update
이 글에서 사용될 예제 shp 파일은 pyshp 에서 사용되는 shapefile 파일로 다음과 같이 생겼습니다. 전체 예제 코드는 shp-to-geojson.py 파일의 내용을 참고해 주시기 바랍니다.
SHP GeoJSON 변환
먼저 아래와 같이 Python 모듈인 shapefile과 json을 로드합니다.
import shapefile
import json
그리고 아래의 코드를 이용하여, Reader 객체를 생성합니다.
path = "pyshp/shapefiles/blockgroups"
sf = shapefile.Reader(path)
확장자를 제거한 파일 이름을 지정하면, SHP 파일 및 SHX 등의 관련파일들을 함께 읽습니다.
다음은 고정된 첫번째 필드가 아닌 정의된 필드 정보로부터 필드 이름을 추출합니다.
fields = sf.fields[1:]
field_names = [field[0] for field in fields]
필드이름과 레코드를 결합한 속성 dictionary를 만들고, geometry 속성으로 shape 정보가 저장되도록 합니다.
이러한 데이터 구조로 buffer 리스트에 추가합니다.
buffer = []
for sr in sf.shapeRecords():
atr = dict(zip(field_names, sr.record))
geom = sr.shape.__geo_interface__
buffer.append(dict(type="Feature", geometry=geom, properties=atr))
그리고, 아래와 같은 구조로 GeoJSON 형태를 만들어, 최종적으로 파일을 저장합니다.
geojson = open("pyshp-demo.geojson", "w")
geojson.write(json.dumps({"type": "FeatureCollection", "features": buffer}, indent=2, ensure_ascii=False))
geojson.close()
GeoJSON 파일
위에서 만든 스크립트를 실행한 결과의 일부 내용은 아래와 같습니다.
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-122.420391,
37.863433
],
[
-122.418705,
37.862144
],
[
-122.419893,
37.860309
],
[
-122.420391,
37.863433
]
]
]
]
},
"type": "Feature",
"properties": {
"BKG_KEY": "060750179029",
"AGE_UNDER5": 611,
"MARHH_CHD": 16,
"AGE_30_49": 1513,
"POP1990": 4531,
"BLACK": 726,
"AGE_18_29": 1327,
"AMERI_ES": 37,
"SEPARATED": 62,
"FEMALES": 1912,
"DIVORCED": 106,
"AREA": 0.96761,
"UNITS3_9": 538,
"UNITS50_UP": 0,
"MALES": 2619,
"HOUSEHOLDS": 970,
"HISPANIC": 389,
"HSEHLD_1_M": 43,
"UNITS_1DET": 25,
"HSE_UNITS": 1045,
"HSEHLD_1_F": 20,
"POP90_SQMI": 4682.7,
"MARRIED": 1750,
"MOBILEHOME": 0,
"MARHH_NO_C": 878,
"OWNER_OCC": 0,
"OTHER": 123,
"UNITS10_49": 19,
"AGE_65_UP": 7,
"WHITE": 2943,
"NEVERMARRY": 501,
"MEDIAN_VAL": 0,
"WIDOWED": 19,
"UNITS2": 37,
"FHH_CHILD": 0,
"VACANT": 83,
"AGE_50_64": 51,
"MHH_CHILD": 0,
"UNITS_1ATT": 419,
"ASIAN_PI": 702,
"AGE_5_17": 1022,
"MEDIANRENT": 647,
"RENTER_OCC": 3548
}
}
]
}
( 본문 인용시 출처를 밝혀 주시면 감사하겠습니다.)