안녕하세요! 이번 포스팅에서는 공공데이터포털에서 제공하는 아파트 평면도 이미지를 파이썬을 이용해 자동으로 불러오고 PNG 파일로 변환하는 방법에 대해 알아보겠습니다. 부동산 관련 데이터를 분석하거나, 건축/인테리어 분야에서 평면도 이미지가 필요한 경우 유용하게 활용할 수 있는 팁입니다.
1. 공공데이터포털이란?
공공데이터포털은 정부 및 공공기관이 보유한 다양한 공공데이터를 한곳에 모아 국민에게 개방하는 서비스입니다. 이곳에서 제공하는 데이터는 누구나 자유롭게 이용할 수 있으며, API 형태로 제공되는 경우도 많아 개발자들이 프로그램으로 쉽게 접근할 수 있습니다.
2. 왜 아파트 평면도 이미지를 불러와야 할까요?
- 데이터베이스 구축: 자체적인 평면도 이미지 데이터베이스를 구축하여 다양한 서비스에 활용할 수 있습니다. 특히 전 가구를 배치하는 용도로 평면도를 이용하려 하였습니다
3. 공공데이터포털에서 사용된 데이터 개요
이번 포스팅에서 사용된 데이터는 공공데이터포털의 "한국토지주택공사 주택 평면도 현황" 데이터셋입니다. 이 데이터셋은 한국토지주택공사(LH)가 관리하는 주택(공공분양, 공공임대 등)의 평면도 정보를 JSON(이미지 파일 변환) 형태로 제공합니다.
- 데이터셋 명칭: 한국토지주택공사 주택 평면도 현황
- 제공 기관: 한국토지주택공사
- 데이터 유형: JSON (내부에 Base64 인코딩된 이미지 포함)
- 설명: 평면도는 집의 구조적 모습을 보기 위해 수평으로 나타내어진 그림입니다.
- 최신 업데이트: 2024년 12월 18일 (수정일 기준)
- 누적 다운로드: 13953회 (주간 다운로드 3872회)
- 이용 허락 범위: 공공누리 제1유형 (출처표시)
이 데이터셋은 연도별, 지역별로 구분되어 있으며, 각 폴더 내에 개별 평면도에 대한 JSON 파일이 포함되어 있습니다. 각 JSON 파일은 평면도 이미지를 Base64 문자열 형태로 담고 있어, 이를 파이썬 코드로 추출하고 변환하는 과정이 필요합니다.





4. 파이썬 코드로 평면도 이미지 불러오기 및 변환하기
공공데이터포털의 API를 통해 평면도 데이터를 요청하면, 이미지 데이터가 Base64 문자열 형태로 JSON 응답에 포함되어 있는 경우가 많습니다. 이 Base64 문자열을 디코딩하여 실제 이미지 파일(PNG)로 저장하는 과정이 필요합니다.
아래 코드는 이러한 과정을 자동화하는 예시입니다. 이 코드는 특정 JSON 파일에 Base64 인코딩된 이미지 데이터가 포함되어 있다고 가정하고, 해당 데이터를 추출하여 PNG 파일로 저장합니다. 공공데이터포털에서 직접 API를 호출하여 JSON 응답을 받는 부분은 API마다 구조가 다르므로, 해당 API의 문서를 참고하여 requests 라이브러리로 호출하는 코드를 추가해야 합니다.
json 파일의 형태에 따라 추출하는 방식이 달라 코드를 두가지 사용하여 png 파일로 변환하였습니다
💛 특정 JSON 구조 (예: 59A.json 형태) 추출 코드 설명
단일 JSON 파일, 예를 들어 59A.json과 같은 파일에서 Base64 인코딩된 이미지 데이터를 추출하여 PNG로 변환하는 데 사용될 수 있습니다. 이 코드는 특히 JSON 파일 내에서 Base64 문자열이 어떤 키에 포함되어 있는지에 대한 여러 시나리오를 처리하도록 설계되었습니다.


import json
import base64
import os
# re 모듈은 이 특정 코드 스니펫에는 사용되지 않았지만,
# 일반적으로 Base64 데이터 URI 접두사를 처리하는 데 유용합니다.
# 이 코드 스니펫에서는 'base64,' 문자열을 기준으로 직접 분할합니다.
# 59A.json 파일 경로 지정
# 현재 작업 디렉토리(os.getcwd()) 아래 'floorplan_json' 폴더에 '59A.json' 파일이 있다고 가정합니다.
json_path = os.path.join(os.getcwd(), 'floorplan_json', '59A.json')
# 저장할 폴더 및 파일 경로 지정
# 현재 작업 디렉토리 아래 'floorplan_image' 폴더에 '59A.png'로 저장할 경로를 정의합니다.
output_dir = os.path.join(os.getcwd(), 'floorplan_image')
output_png = os.path.join(output_dir, '59A.png')
# 폴더가 없으면 생성
# 이미지를 저장할 'floorplan_image' 폴더가 존재하지 않으면 새로 생성합니다.
os.makedirs(output_dir, exist_ok=True)
# JSON 파일 열기
# 지정된 경로의 JSON 파일을 읽기 모드('r')로 열고, UTF-8 인코딩을 사용합니다.
# 'with' 문을 사용하여 파일이 자동으로 닫히도록 합니다.
with open(json_path, 'r', encoding='utf-8') as f:
# json.load(f)를 사용하여 파일 객체 f에서 JSON 데이터를 로드하여 파이썬 딕셔너리 'data'에 저장합니다.
data = json.load(f)
# base64 문자열 추출 (구조에 따라 경로 수정 필요)
# JSON 'data' 딕셔너리에서 Base64 문자열을 찾습니다.
if 'data' in data:
# 만약 'data' 키가 최상위에 직접 존재하면 그 값을 Base64 문자열로 사용합니다.
base64_str = data['data']
elif 'image' in data and '@attributes' in data['image'] and 'xlink:href' in data['image']['@attributes']:
# 만약 'image' -> '@attributes' -> 'xlink:href' 경로에 Base64 문자열이 있다면 그 값을 사용합니다.
# 이는 SVG 이미지 데이터에서 흔히 볼 수 있는 구조입니다.
base64_str = data['image']['@attributes']['xlink:href']
else:
# 위의 두 가지 일반적인 경로에서 Base64 문자열을 찾지 못했을 경우,
# 딕셔너리의 모든 최상위 값들을 순회하며 'base64,' 문자열을 포함하는 첫 번째 문자열을 찾습니다.
base64_str = None
for value in data.values():
if isinstance(value, str) and 'base64,' in value:
base64_str = value
break # 찾으면 루프를 종료합니다.
if base64_str is None:
# Base64 문자열을 끝까지 찾지 못하면 ValueError를 발생시킵니다.
raise ValueError('Base64 문자열을 찾을 수 없습니다.')
# 'base64,' 이후 부분만 추출
# Base64 문자열에 'base64,' 접두사가 포함되어 있다면, 이 접두사를 제거하고 실제 Base64 데이터만 추출합니다.
if 'base64,' in base64_str:
base64_data = base64_str.split('base64,')[1]
else:
# 접두사가 없다면 Base64 문자열 전체를 사용합니다.
base64_data = base64_str
# 디코딩 및 PNG 파일로 저장
# Base64 데이터를 바이너리 형식으로 디코딩합니다.
# 디코딩된 데이터를 'output_png' 경로에 바이너리 쓰기 모드('wb')로 PNG 파일로 저장합니다.
with open(output_png, 'wb') as img_file:
img_file.write(base64.b64decode(base64_data))
# 이미지 저장 완료 메시지 출력
print(f'이미지 저장 완료: {output_png}')
💛 특정 JSON 구조 (예: 84C.json 형태) 추출 코드 설명
공공데이터포털에서 제공하는 일부 JSON 파일은 이미지 데이터가 {"image": {"mime": "image/png", "data": "..."}}와 같은 특정 구조로 포함되어 있습니다. 특히 data 키의 값이 Base64 인코딩된 이미지 문자열인 경우, 이를 직접 추출하여 PNG 파일로 변환할 수 있습니다. 아래 코드는 이러한 형태의 JSON 파일을 처리하는 데 사용됩니다.


import json # JSON 데이터 처리를 위한 모듈
import base64 # Base64 인코딩/디코딩을 위한 모듈
import re # 정규 표현식 사용을 위한 모듈
import os # 파일 시스템 경로 조작을 위한 모듈
# 84C.json 파일 경로 지정
# 현재 작업 디렉토리(os.getcwd()) 아래 'floorplan_json' 폴더에 '84C.json' 파일이 있다고 가정합니다.
json_path = os.path.join(os.getcwd(), 'floorplan_json', '84C.json')
# 저장할 폴더 및 파일 경로 지정
# 현재 작업 디렉토리 아래 'floorplan_image' 폴더에 '84C.png'로 저장할 경로를 정의합니다.
output_dir = os.path.join(os.getcwd(), 'floorplan_image')
output_png = os.path.join(output_dir, '84C.png')
# 폴더가 없으면 생성
# 이미지를 저장할 'floorplan_image' 폴더가 존재하지 않으면 새로 생성합니다.
os.makedirs(output_dir, exist_ok=True)
# JSON 파일 열기 및 전체 텍스트 읽기
# 지정된 경로의 JSON 파일을 읽기 모드('r')로 열고, UTF-8 인코딩을 사용합니다.
# 'with' 문을 사용하여 파일이 자동으로 닫히도록 합니다.
with open(json_path, 'r', encoding='utf-8') as f:
# f.read()를 사용하여 파일의 전체 내용을 문자열로 읽어와 'json_text' 변수에 저장합니다.
# 이는 JSON 파싱 전에 특정 패턴을 검색하기 위함입니다.
json_text = f.read()
# "data":" 다음부터 마지막 따옴표(") 또는 작은따옴표(') 전까지 추출 (줄바꿈 포함)
# re.search()를 사용하여 'json_text'에서 특정 정규 표현식 패턴을 검색합니다.
# r'"data"\s*:\s*["\']([^"\']+)["\']' 패턴 설명:
# - '"data"\s*:\s*': "data" 문자열, 콜론(:), 그리고 그 사이에 있을 수 있는 공백(\s*)을 찾습니다.
# - '["\']': 큰따옴표(") 또는 작은따옴표(') 중 하나를 찾습니다.
# - '([^"\']+)': 이 부분이 핵심입니다. 큰따옴표나 작은따옴표를 제외한 모든 문자(.)가 하나 이상(+) 반복되는 것을 캡처 그룹으로 지정합니다.
# 이는 Base64 데이터가 포함된 부분입니다. 줄바꿈 문자도 포함될 수 있습니다.
# - '["\']': 닫는 큰따옴표(") 또는 작은따옴표(')를 찾습니다.
match = re.search(r'"data"\s*:\s*["\']([^"\']+)["\']', json_text)
if not match:
# 만약 패턴을 찾지 못했다면, Base64 문자열을 찾을 수 없다는 ValueError를 발생시킵니다.
raise ValueError('"data":" 다음에 base64 문자열을 찾을 수 없습니다.')
# match.group(1)은 정규 표현식의 첫 번째 캡처 그룹(즉, Base64 데이터 부분)을 반환합니다.
base64_data = match.group(1)
# base64 디코딩 및 이미지 파일로 저장
# base64.b64decode()를 사용하여 Base64 데이터를 바이너리 형식으로 디코딩합니다.
# 디코딩된 데이터를 'output_png' 경로에 바이너리 쓰기 모드('wb')로 PNG 파일로 저장합니다.
with open(output_png, 'wb') as img_file:
img_file.write(base64.b64decode(base64_data))
# 이미지 저장 완료 메시지 출력
print(f'이미지 저장 완료: {output_png}')
위 코드를 이용하여 아파트 평면도를 추출하였습니다.
'프로젝트 > 이집맞집' 카테고리의 다른 글
| 3차프로젝트(6/30-8/22) (2) | 2025.07.10 |
|---|