대한민국 최신 행정구역 Geometry OpenAPI

대한민국의 행정구역에 대한 Geometry를 얻을 수 있는 OpenAPI 서비스를 지오서비스에서 제공합니다. 이미 오래전부터 아래의 웹페이지를 통해 매년 최신 행정구역에 대한 SHP 파일을 제공해 드리고 있습니다.

대한민국 최신 행정구역(SHP) 다운로드

위 페이지에서 소개해 드리는 방식인 SHP 파일 형태가 아닌 REST OpenAPI 방식으로 행정구역도를 얻을 수 있는 서비스는 그 활용의 폭이 넓은데요. 특히 빅데이터의 처리 결과 등과 같은 통계 데이터에 대한 주제도 작성에 활용될 수 있습니다. 예를들어, 아래와 같은 Javascript 코드를 통해 원하는 행정구역의 지오메트리를 얻을 수 있습니다.

$.ajax({
    url: 'http://geoservice.co.kr:8080/Gp?command=ad2geom;tol=100',
    type: 'POST',
    crossDomain: true,
    data: '전주시 덕진구\n전주시 완산구',
    dataType: "text",
    success: function (response) {
        document.querySelector("#ta").textContent = response;
    },

    error: function (xhr, status) {
        alert("ERROR");
    }
});

위의 코드는 전주시 덕진구와 전주시 완산구에 대한 행정구역을 WKT 포맷으로, 100m 거리값 만큼 토폴로지를 유지한 형태로 단순화(Simplify)된 지오메트리로 그 결과를 아래처럼 JSON으로 받습니다. 실제 내용은 아래보다 훨씬 길어서 축약해 표시 했습니다.

{
    "_EPSG":5179,
    "전주시 덕진구":"POLYGON((957449 1766921, 958719 1763384, ...  , 957449 1766921))",
    "전주시 완산구":"POLYGON((957449 1766921, 958719 1766944, ... , 957449 1766921))"
}

서비스되는 행정구역의 명칭은 시도, 시군구, 읍면동, 리 전체입니다. 행정구역의 명칭은 요약이나 별칭도 가능합니다. 즉, 서울특별시 뿐만 아니라 서울, 서울시가 가능하고, 전라북도 뿐만 아니라 전북도 가능합니다. 이 서비스는 별도의 공지가 없는 한 자유롭게 사용하실 수 있습니다.

지오서비스는 위치기반 서비스와 관련된 또 다른 유용한 서비스로써 편리하게 사용할 수 있는 주소/좌표간의 변환툴(Geocoding Tool)을 무료로 제공하고 있는데요. 아래의 URL을 통해 자세한 내용을 살펴보실 수 있습니다.

주소 좌표 변환 툴, Geocoder-Xr

수치미분(접선)의 결과를 그래프로 표현하기

다음과 같은 함수가 있을 때.. 이 함수를 미분한 결과는 이 함수의 그래프에 대한 접선의 방정식이 됩니다.

위 함수에 대한 코드 정의는 다음과 같습니다.

def fx(x):
    return x**3 + x

미분은, 중앙차분 방식으로 정의하면 다음과 같구요.

def numerical_diff(f, x):
    h = 1e-4
    return (f(x+h) - f(x-h)) / (2*h)

미분 결과는 접선인데, 이 접선을 표현하는 함수를 반환하는 함수는 다음과 같습니다.

def tangent_line(f, x):
    d = numerical_diff(f, x)
    y = f(x) - d*x
    return lambda t: d*t + y

이제 x 절편의 범위를 0~20까지 잡고 함수의 그래프와 이 함수의 x = 11에서의 접선을 그리는 코드는 다음과 같습니다.

import numpy as np
import matplotlib.pylab as plt

# def numerical_diff(f, x):
# def tangent_line(f, x):
# def fx(x):

x = np.arange(0.0, 20.0, 0.1)
y = fx(x)
plt.plot(x,y)

tf = tangent_line(fx, 11)
y2 = tf(x)
plt.plot(x, y2)

plt.show()

결과 그래프는 다음과 같습니다.

이와 같은 미분에 대한 파이선 코드는 기계 학습이나 신경망 학습에서 가중치와 편향에 대한 최적의 값을 얻기 위해 활용되는 경사하강법(Gradient Descent Method)에서 사용됩니다.

넥스젠(NexGen)의 공간 데이터 편집 기능

NexGen은 서비스 되는 모든 수치지도 레이어를 편집할 수 있는 범용 기능을 제공합니다. 또한 서비스 되는 모든 수치지도는 NexGen에서 바로 SHP 파일로 다운로드 받을 수 있습니다. 또한 편집에 대한 편의 기능으로 편집 이력의 Undo/Redo와 정점 및 선분에 대한 스냅핑 기능을 제공합니다. 아래는 메인 편집 UI입니다.

보시는 것처럼 편집 대상이 되는 레이어를 선택할 수 있고, 편집하고자 하는 도형을 선택하여 편집하거나 신규 도형을 추가할 수 있으며, 기존의 도형을 삭제할 수 있는 버튼과 함께 Undo/Redo 기능 등이 보입니다.

편집 대상이 되는 도형을 선택하거나 새롭게 생성하면 해당 도형에 대한 속성을 편집할 수 있는 창이 아래처럼 표시됩니다. 모든 수치지도 레이에 대한 범용 편집 기능이므로 필드명과 필드값으로 표시됩니다.

위의 UI를 통해 도형 편집 뿐만 아니라 연관된 속성 데이터도 편집할 수 있습니다. 이러한 편집 기능은 범용적인 목적으로 사용되는 편집으로, 특정 목적을 가지는 수치지도에 대한 편집에 대해 다양한 제약조건(코드값 입력 등)은 별도의 커스터마이징으로 추가가 가능합니다.

편집에 대한 편의 기능으로써 정점과 선분에 대한 스냅핑 기능을 제공하는데요. 아래의 직관적인 UI를 통해 원하는 레이어에 대해서 정점과 선분을 개별적으로 선택해 스냅핑을 적용할 수 있습니다.

아래는 이러한 편집 기능에 대한 소개 동영상입니다. 건물, 도로, 지적도, POI에 대한 편집을 NexGen의 수치지도 범용 편집기능을 통해 편집하는 내용을 담고 있습니다.

넥스젠(NexGen)의 스타쿼리(* Query) 기능

스타쿼리는 와일드 카드 문자 중에서 모든 것을 의미하는 스타(*) 문자의 의미대로 위치기반 데이터 중 사용자가 검색하고자 하는 모든 것(*)을 하나의 기능만으로 쉽고 빠르며 정확하게 검색할 수 있는 기능입니다.

스타쿼리를 이용하여 행정구역명, 도로명, 지번주소, 도로명주소, 건물명을 기본적으로 검색할 수 있습니다. 또 여기에 사용자가 검색하고자 하는 특화된 데이터를 추가하여 검색할 수 있도록 커스터마이징이 가능합니다.

스타쿼리의 사용자 인터페이스(UI)는 아래처럼 매우 심플합니다.

검색 대상의 종류마다 상이한 UI가 아닌 공통된 하나의 UI만을 제공함으로써 사용자는 부차적인 기능을 학습할 필요없이 원하는 것을 바로 얻을 수 있습니다.

이 UI에 사용자가 검색하고자 하는 키워드를 입력하고 엔터 또는 검색 버튼을 클릭하기만 하면 연관된 결과가 검색창에 표시됩니다. 아래처럼요~!

검색 결과 중 하나를 선택하면 선택된 항목의 위치로 지도가 빠르게 이동합니다. 검색 결과는 물론 지도의 이동까지 너무 빠르죠~! 넥스젠은 사용자가 어떤 결과를 얻기 위해 기다리는 상황이 생기지 않습니다~!

아래는 스타쿼리에 대한 기능을 동영상으로 소개하고 있습니다.

위의 기능 소개에 대한 동영상을 보시면, 도로명 주소와 지번 주소에 대한 위치 검색은 지오코딩(Geocoding) 서비스를 활용합니다. 이 지오코딩 서비스 역시 NexGen의 한 기능이며, 완전한 표준주소가 아닌 불완전한 주소의 경우에도 주소정제(Address Cleaning)을 통해 위치 검색이 가능합니다.

Python과 OpenCV – 54 : 이미지 복원(Image Inpainting)

이 글의 원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_photo/py_inpainting/py_inpainting.html 입니다.

이 글에서는 오래된 사진의 작은 흡집 등을 제거하는 방법인 Inpainting에 대해 살펴보고, 이를 OpenCV의 예제를 통해 살펴 보겠습니다.

아래의 이미지의 왼쪽처럼 오래된 훼손된 사진에는 작은 흠집이 있는데, 이 흠집을 제거하고 원래의 사진으로 복구할 수 없을까요? 단순하게 이 흠짐을 사진에서 지우는 것만으로는 충분하지 않습니다. 이런 경우 Image Inpainting이라는 기술을 사용할 수 있습니다. 기본 아이디어는 단순합니다. 흠집에 위치한 픽셀을 그 이웃 픽셀을 가져와 교체하는 것입니다.

이런 목적을 위해 설계된 여러가지 알고리즘이 있으며, OpenCV에서는 2가지를 제공합니다. 이 2가지 모두 cv2.inpaint() 함수를 통해 활용할 수 있습니다.

첫번째 알고리즘은 2004년 Alexandru Telea의 논문 “An Image Inpainting Technique Based on the Fast Marching Method”에 기반합니다. 이 알고리즘은 Fast Marching Method에 기반합니다. 복원(Inpainting)하고자 하는 영역에 대해 생각해 봅시다. 이 알고리즘은 먼저 이 영역의 경계로부터 시작하며 영역 내부를 영역의 외곽선부터 시작해 점진적으로 채웁니다. 복원될 곳의 픽셀 주위의 이웃(인근)에 작은 범위의 픽셀을 구합니다. 구해진 픽셀들의 정규화된 가중치 합으로 계산되어진 값으로 복원될 픽셀이 교체됩니다. 가중치 값의 선택은 매우 중요한 문제입니다. 복원 지점에 가깝게 놓여져 있을수록 더 많은 가중치값이 주어집니다. 일단 하나의 픽셀이 복원되면, Fast Matching Method를 사용해 가장 가까운 다음 픽셀로 이동합니다. 이 알고리즘은 cv2.INPAINT_TELEA 플래그를 사용해 활성화됩니다.

두번째 알고리즘은 2001년의 논문인 “Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting”에 기반합니다. 이 알고리즘은 부분 편차 방정식과 유체역학에 기반합니다. 기반 이론은 휴리스틱 방식이며 cv2.INPAINT_NS 플래그를 활성화하여 이 알고리즘을 사용합니다.

이제 2가지의 알고리즘을 OpenCV의 함수를 통해 살펴보겠습니다. 먼저 복원하고자 하는 영역에 해당하는 픽셀에 0이 아닌 값을 담고 있는 마스크 이미지가 필요한데, 이 이미지는 입력 이미지와 크기가 동일해야 합니다. 먼저 cv2.INPAINT_TELEA 프래그에 대한 예제입니다.

import numpy as np
import cv2

img = cv2.imread('./data/inpainting_input.png')
mask = cv2.imread('./data/inpainting_mask.png',0)

dst = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)

cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.INPAINT_NS에 대한 알고리즘은 7번 코드의 함수의 인자를 변경하기만 하면 됩니다. 아래의 이미지는 복원되어질 이미지와 마스크 이미지 그리고 2가지 알고리즘에 수행 결과를 모두 표시한 것입니다.

4개의 이미지 중 좌하단의 이미지는 cv2.INPAINT_TELEA에 대한 결과이며, 우하단의 이미지는 cv2.INPAINT_NS의 결과 입니다.