오늘 회사에서 이것과 씨름을 했다. http://openapi.nsdi.go.kr/nsdi/eios/ServiceDetail.do?svcSe=F&svcId=F018&provOrg=NIDO 에 광역시나 도별로 GIS 건물정보를 받을 수 있다. 파일을 다운 받아서 압축을 해제하면 .shp, .dbf, .prj 파일들이 있다. 
 이 파일의 의미를 처음으로 알게되었는데,  .shp 파일은 맵의 위치, 도형정보가 들어있다. 이 파일을 잘 이용하면 실제 위도, 경도를 계산할 수 있다. .dbf 는 DB파일이다. 다운받은파일에서는 건물 주소, 건물명, 사용승인일등이 들어 있다. .shp 에 매핑되는 지점의 정보가 들어 있는 것이다. 그리고 .prj 는 .shp 파일의 맵의 위치정보가 어떤 좌표계를 사용했는지 알려주는 것 같은데 실제 이용되는 데이터인지는 모르겠다. 

 이 작업을 하면서 알게 되었는데, 우리가 흔히 위도 경로라는 것도 좌표계의 하나로 WGS84 경위도: GPS가 사용하는 좌표계를 이용해야 한다. 그리고 해당 파일의 좌표계는 "EPSG:5174" 이다. 

파이썬 코드를 작성해 보면 아래와 같다.

import shapefile
from shapely.geometry import Polygon
from dbfread import DBF
from pyproj import CRS, Transformer

# https://www.osgeo.kr/17
# EPSG:5174
EPSG5174 = """+proj=tmerc +lat_0=38 +lon_0=127.0028902777778 +k=1
+x_0=200000 +y_0=500000 +ellps=bessel +units=m +no_defs
+towgs84=-115.80,474.99,674.11,1.16,-2.31,-1.63,6.43"""


# Projection 정의
# EPSG:5174
epsg5174_crs = CRS(EPSG5174)
  

# WGS84 경위도: GPS가 사용하는 좌표계 EPSG:4326
epsg4326_crs = CRS('epsg:4326')

transformer = Transformer.from_crs(epsg5174_crs, epsg4326_crs)

fileName = './res/AL_11_D164_20230125'
sf = shapefile.Reader(shp=(fileName + ".shp"))
dbf = DBF(fileName + ".dbf" , encoding="CP949")
# records = sf.records()

index = -1
shapes = sf.shapes()
for record in dbf:
	index += 1
	if index % 10000 != 0:
		continue
	print("index : " + str(index))
	print("n_count : " + str(n_count))

	shape = shapes[index]
	polygon = Polygon(shape.points)
	center = polygon.centroid
	gis = transformer.transform(center.x, center.y)
	# gis = proj.transform(center.x, center.y)
	print("중심좌표 : " + gis)
  

print("======== END ========")


사용한 파이썬 라이브러리는 shapefile, dbfread, pyproj 이다. shapefile은 shp 파일을 불러오는 역할을 한다. 이 라이브러리을 통해 dbf 파일도 같이 읽을 수는 있는데 속도가 느려서 dbfread 라이브러리를 사용했다. pyproj 는 shapefile 라이브러리를 통해 얻어온 좌표를 변환할 때 사용한다. 이 라이브러리를 통해 위도 경도 값을 얻을 수 있다. 
 gis 변수에 위도, 경도 tuple 이 있고, record에는 dbf 파일의 정보가 있다. 서로 같은 순서를 가지기 때문에 이렇게 하면 동일한 건물에 대해 위도,경도와 기타 정보를 같이 획득할 수 있다. 


내 설명이 많이 불친절하긴 한데, 다른 사이트들에 개념은 잘 설명되어 있다. 그런데 파이썬 코드가 없어서 이 글을 올린다.