이번 글은
생성 순서
1. 원점의 X값에서 radius(한 변 길이)의 3배 만큼 오른쪽으로 이동하여 새로운 기준점 생성
2. 기준점을 우측 끝까지 생성한 뒤 원점으로 돌아와서,
X값은 (1.5 x radius) 만큼 증가, Y값은 (√3/2 x radius) 만큼 증가 후 단계 1 반복

3. 기준점을 우측 상단까지 생성한 뒤 종료
4. 원점(point 1)에서 반시계 방향으로 각 꼭지점 추가하여 폴리곤 생성(1->2->3->4->5->6->7)

생성 작업
변수 설정
import pandas as pd
sido_code = '11'
table_name = 'hexagon_unit'
radius = 100
sido_box_point = pd.DataFrame(
{
'min_x_cor':[935035.2548847208],
'max_x_cor':[972067.5689105988],
'min_y_cor':[1936665.5480976123],
'max_y_cor':[1966987.1586933173]
}
)
DB 연결
import psycopg2
dbCon_source = psycopg2.connect(
'host=localhost port=5432 dbname=postgres user=postgres password=postgres',
options='-c search_path=sbd'
)
dbCon_source.set_session(autocommit=True)
cur_source = dbCon_source.cursor()
단계 1~3. 기준점 목록 생성
from math import sqrt
origin_list = []
x_origin = sido_box_point.min_x_cor[0]
y_origin = sido_box_point.min_y_cor[0]
y_order = 1
while y_origin - sqrt(3) * radius <= sido_box_point.max_y_cor[0]:
while x_origin - radius <= sido_box_point.max_x_cor[0]:
origin_list.append([x_origin,y_origin])
x_origin += 3 * radius
x_origin = sido_box_point.min_x_cor[0] if y_order % 2 == 0 else sido_box_point.min_x_cor[0] + 1.5 * radius
y_order += 1
y_origin += sqrt(3) / 2 * radius
origin_list[0:5]

len(origin_list)

단계 4. 기준점에서 폴리곤 생성
def make_hexagon_geometry_text_from_origin(origin,radius):
x,y = origin
hexagon_geometry_text = 'polygon(('
for i in range(0,7):
hexagon_geometry_text += str(x + cos(i / 3 * pi) * radius) + ' ' + str(y + (sin(i / 3 * pi) * radius) if i < 6 else y + 0.0) + (',' if i < 6 else '))')
return hexagon_geometry_text
import geopandas as gpd
from math import sqrt,sin,cos,pi
hexagon_unit = gpd.GeoDataFrame(
gpd.GeoSeries.from_wkt(
[
make_hexagon_geometry_text_from_origin(origin,radius)
for origin
in origin_list
]
),
columns = ['geometry']
)
hexagon_unit.geometry[0]

len(hexagon_unit)

id 컬럼 생성
hexagon_unit['id'] = [
sido_code + '_' + str(no).zfill(len(str(len(hexagon_unit))))
for no
in range(len(hexagon_unit))
]
좌표계 초기 설정(EPSG:5179)
hexagon_unit = hexagon_unit.set_crs(5179)
hexagon_unit.crs

테이블 생성
cur_source.execute(
f'''
select count(*)
from information_schema.tables
where table_name ~ '{table_name}'
'''
)
if not cur_source.fetchone()[0]:
cur_source.execute(
open('project/2022_SpatialBigdata/sql/sbd-create_table_hexagon_unit.sql', 'r').read()
)
데이터 업로드
cur_source.execute(
f'''
select column_name
from information_schema.columns
where
table_name = '{table_name}' and
column_default is null
order by ordinal_position asc;
'''
)
column_name = [cn[0] for cn in cur_source.fetchall()]
cur_source.execute(
f'''
delete from {table_name} where substr(id,1,2) = '{sido_code}'
'''
)
from sqlalchemy import create_engine
gcon_source = create_engine(
f'''postgresql://postgres:postgres@localhost:5432/postgres'''
)
hexagon_unit = hexagon_unit[column_name]
hexagon_unit.to_postgis(
table_name,
con = gcon_source,
schema = 'sbd',
if_exists = 'append',
chunksize = 100_000
)
업로드 데이터 확인(in PostgreSQL)
