AOI(Area of Interest)는 GIS 분야에서 매일 들릴만큼 중요한 요소로 작용합니다. AOI를 저장하는 방식에 다양한 Polygon 저장 형태가 있지만 그 중에서도 xml기반의 kml파일로 저장하는 케이스를 보이고자 합니다.
다음의 과정을 위해서는 GeoServer와 지구 대륙 데이터가 필요합니다.
다음 두 가지 요소를 사용하여 지구 전체 데이터 대한 AOI를 추출해보고자 한다
# Z = 17, Tile : 32,951,762,944
# Z = 8, Tile : 48311 / 125952 ->
# Z = 7, Tile : 13237 / 31744
# Z = 6, Tile : 3738 / 7936 -> 3797
# Z = 5, Tile : 1123 / 1984 -> 1163
# Z = 4, Tile : 361 / 512 -> 386
import requests
import simplekml
import os
# minx,miny,maxx,maxy, z = 0, 1, 511, 246, 8
# minx,miny,maxx,maxy, z = 0, 0, 255, 123, 7
# minx,miny,maxx,maxy, z = 0, 0, 127, 61, 6
# minx,miny,maxx,maxy, z = 0, 0, 63, 30, 5
minx,miny,maxx,maxy, z = 0, 0, 31, 15, 4
# For Small Data
# minx,miny,maxx,maxy, z = 0, 0, 5, 5, 4
WORKSPACE = ""
LAYER = ""
GEOSERVER_URL = ""
FILENAME = f"earth_{LAYER}_zoomLevel_{z}"
TMS_URL = f'http://{GEOSERVER_URL}/geoserver/gwc/service/tms/1.0.0/{WORKSPACE}:{LAYER}@EPSG:4326@geojson'
count, aoi = 0, 0
kml = simplekml.Kml()
# Style
sharedstyle = simplekml.Style()
sharedstyle.linestyle.color = "ff000ff"
sharedstyle.polystyle.fill = 0
f = kml.newfolder(name = FILENAME)
# 가능한 X,Y의 모든 조합
for x in range(minx, maxx + 1):
for y in range(miny, maxy + 1):
res = requests.get(TMS_URL + f'/{z}/{x}/{y}.geojson')
resData = res.json()
if "features" in resData and resData["features"]:
count += 1
for data in resData["features"]:
if len(data['geometry']['coordinates']) == 1: data['geometry']['coordinates'] = [data['geometry']['coordinates']]
for coors in data['geometry']['coordinates']:
for idx,coor in enumerate(coors):
# print(coor)
aoi += 1
try:
mminx=min(coor, key=lambda data : data[0])[0]
mmaxx=max(coor, key=lambda data : data[0])[0]
mminy=min(coor, key=lambda data : data[1])[1]
mmaxy=max(coor, key=lambda data : data[1])[1]
# print(f"mminx : {mminx} | mmaxx : {mmaxx}")
# print(f"mminy : {mminy} | mmaxy : {mmaxy}\n")
pol = f.newpolygon(name = data['id']+f"_{idx}")
pol.outerboundaryis = [ (mminx,mminy), (mminx,mmaxy),
(mmaxx,mmaxy), (mmaxx,mminy),
(mminx,mminy)]
except Exception as e:
print(e, coor)
pol.style = sharedstyle
kml.save(os.getcwd() + '/' + FILENAME+".kml")
print(f"Count : {count} | Aoi Count : {count}")
현재 Zoom level 8의 데이터로 대략 12만 여개의 대륙 타일 데이터를 생성해볼 수 있었지만 중간 중간 원인 모를 이유로 데이터가 누락된 것을 확인 할 수 있었다.
소스코드의 수정이 필요해보이지만 지구 대륙 데이터를 원하는 만큼 잘랐을 때 데이터 양이 너무 많기 때문에 사용하지 않기로 결정하였다.