[2022 공간빅데이터 경진대회] 5-1. 분석 단위(hexagon unit) 생성

Bob Park·2022년 9월 29일
0

이번 글은

생성 순서

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 # unit: m
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)

  • 총 43,772개 기준점 생성

단계 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)

  • 총 43,772개 정육각형 생성

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)

profile
가치를 만드는 데이터 분석가

0개의 댓글