티스토리 뷰
포스터는 다음과 같이 진행될 예정.
[Kakao 지도 API를 이용한 길찾기 웹 만들기]
(1) Kakao 지도 API 키 발급 및 HTML5 + Javascript 적용
(2) Kakao 지도 Javascript를 이용해 Marker 이용해보기
(3) Kakao 지도 Javascript를 이용해 InfoWindow 이용해보기
(4) Kakao 지도 Python API 공공데이터 활용해 Javascript로 Polyline 그리기 𖦹현재 포스터𖦹
(5) 길찾기 API ODsay, Python을 이용한 실시간 길찾기 데이터 불러오기
(6) 백엔드로 불러온 실시간 길찾기 데이터 지도에 polyline 찍어보기
동기들과 구현해본 길찾기 서비스에 대한 기록.
학부생 수준으로 진행한 것이라 메모리 사용량이든 디스크 사용량이든 정말 비효율적으로 만들어지긴 했는데,
지도를 입문하거나, 길찾기를 지도에 적용하고 싶은데 너무 막연하게 느껴진다면 도움은 될 것 같다.
[포스터 참고]
(1) Kakao 지도 API 키 발급 및 HTML5 + Javascript 적용: https://hyewon-s-dev.tistory.com/16
[Web/Map] Kakao 지도 API 키 발급 및 HTML5 + Javascript 적용/위도경도 찾는 법
포스터는 다음과 같이 진행될 예정. [Kakao 지도 API를 이용한 길찾기 웹 만들기] (1) Kakao 지도 API 키 발급 및 HTML5 + Javascript 적용 𖦹현재 포스터𖦹 (2) Javascript를 이용한 Kakao 지도 Marker, Polyline, InfoWi
hyewon-s-dev.tistory.com
(2) Javascript를 이용한 Kakao 지도 Marker, Polyline, InfoWindow 이용해보기 - Marker :https://hyewon-s-dev.tistory.com/17
[Web/Map] Javascript를 이용한 Kakao 지도 Marker, Polyline, InfoWindow 이용해보기(1) - Marker
포스터는 다음과 같이 진행될 예정. [Kakao 지도 API를 이용한 길찾기 웹 만들기] (1) Kakao 지도 API 키 발급 및 HTML5 + Javascript 적용 (2) Javascript를 이용한 Kakao 지도 Marker, Polyline, InfoWindow 이용해보기 - Ma
hyewon-s-dev.tistory.com
(3) Javascript를 이용한 Kakao 지도 Marker, Polyline, InfoWindow 이용해보기 - InfoWindow :https://hyewon-s-dev.tistory.com/17
[Web/Map] Javascript를 이용한 Kakao 지도 Marker, Polyline, InfoWindow 이용해보기(1) - Marker
포스터는 다음과 같이 진행될 예정. [Kakao 지도 API를 이용한 길찾기 웹 만들기] (1) Kakao 지도 API 키 발급 및 HTML5 + Javascript 적용 (2) Javascript를 이용한 Kakao 지도 Marker, Polyline, InfoWindow 이용해보기 - Ma
hyewon-s-dev.tistory.com
+ 이상한 부분이나 틀린 부분, 피드백 대환영입니다.
흔히 길찾기 서비스를 이용하게 되면, 출발지와 도착지의 위치를 찍어주는 핀, 지도 위에서 출발지와 도착지를 연결해주는 색깔 선, 그리고 그 장소에 대해 설명해주는 말풍선 창이 뜨곤 한다. 여기서
출발지와 도착지의 위치를 찍어주는 핀 → 마커
지도 위에서 출발지에서 도착지까지 가는 경로를 그려준 색깔 선 → 폴리라인
출발지와 도착지 등 특정 장소에 대해 설명해주는 말풍선 창 → 인포윈도우
로, 이것들을 이용하고, 응용 해보고자 함
(1)번 포스터에서 언급한 vscode 에디터, HTML Live Server 확장자를 설치하면 실습에 따라오기 더 편할 것 같다.
[코드 기본 셋팅] main.html👇👇👇
<!DOCTYPE html>
<html>
<head>
<title>카카오 지도</title>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey={{javascript 키}}&libraries=services,clusterer,drawing"></script>
</head>
<body>
<div id="map" style="width:500px;height:400px;"></div>
<script>
var container = document.getElementById('map');
var options = {
center: new kakao.maps.LatLng(33.450701, 126.570667),
level: 5
};
var map = new kakao.maps.Map(container, options);
</script>
</body>
</html>
1. 지도에 선긋기
일단 가장 기본적인 선 긋는 방법부터 실습.
선은 `kakao.maps.Polyline` 모듈 이용. linePath로 선을 그을 좌표를 list 형태를 지정해준 후,
선의 색깔, 스타일, 투명도 등과 같은 옵션 사용해서 그리게 된다.
공식 홈페이지에 있는 예시 코드이며, 위 기본 코드 중 map 변수 아래에 js 언어로 작성해주면 됨.
// 선을 구성하는 좌표 배열입니다. 이 좌표들을 이어서 선을 표시합니다
var linePath = [
new kakao.maps.LatLng(33.452344169439975, 126.56878163224233),
new kakao.maps.LatLng(33.452739313807456, 126.5709308145358),
new kakao.maps.LatLng(33.45178067090639, 126.5726886938753)
];
var polyline = new kakao.maps.Polyline({
path: linePath, // 선을 구성하는 좌표배열 입니다
strokeWeight: 5, // 선의 두께 입니다
strokeColor: '#FFAE00', // 선의 색깔입니다
strokeOpacity: 0.7, // 선의 불투명도 입니다 1에서 0 사이의 값이며 0에 가까울수록 투명합니다
strokeStyle: 'solid' // 선의 스타일입니다
});
// 지도에 선을 표시합니다
polyline.setMap(map);
일반적으로, 위와 같은 선이 그어져있는 곳을 생각한다면,
로드뷰를 보고싶을 때, 클릭 가능한 위치를 띄울 때에도 지도 속에 라인이 그려져있고,
길찾기를 했을 때, 출발 지점부터 도착 지점까지 선이 그어져있는 것을 확인할 수 있다.
위와 같은 방법으로 선을 찍으려고 한다면, 선의 모서리 부분에 대한 좌표의 데이터를 가지고 있으면 된다. (아래 사진 참고)
만약 선이 직선이 아니라면, 위와 같이 좌표를 쪼개서 선을 그려주면 되는 것임.
2. 공공데이터를 활용해 지도에 Polyline 그려보기
Python을 이용하여 API로 데이터를 불러와, Python 웹 프레임워크 Flask 를 이용하여 데이터를 프론트로 이동시키고,
이동된 데이터를 활용해 지도에 Polyline을 찍는 흐름으로 진행. 주제에 벗어나지 않는 선으로 작성.
[사용할 데이터] 서울특별시_서울시 자치구별 도보 네트워크 공간정보
http://data.seoul.go.kr/dataList/OA-21208/S/1/datasetView.do
서울시 자치구별 도보 네트워크 공간정보
서울시내 보행자도로를 노드 링크 기반으로 표현한 위치정보 서비스입니다. <br />대로변의 횡단보도와 육교, 버스정류장, 지하철 출입구 등의 정보를 확인할 수 있습니다. ('20년 기준) <br />좌표
data.seoul.go.kr
먼저 간단하게 필요한 데이터를 분석해보면,
Column 이름 | Value 값 종류 | 설명 |
노드 링크 유형 | LINK | 선으로 연결된 데이터 |
NODE | 지점 하나 | |
노드 WKT | - | 노드 링크 유형이 NODE일 경우, 특정 지점(POINT)의 위도, 경도 |
링크 WKT | - | 노드 링크 유형이 LINK일 경우, 도보로 다닐 수 있는 거리에 대한 선의 위도/경도 |
이렇게 4가지가 될 것 같다. 데이터를 Python을 이용해 불러오는 코드는 파일 생성해서 아래 코드 작성.
# modules.py
def api_json(url):
import ssl, json
from urllib.request import Request, urlopen
request = Request(url)
context = ssl._create_unverified_context()
response = urlopen(request, context=context) # 데이터 불러오기
response_body = response.read().decode('utf-8')
return json.loads(response_body)
class network_geo_info:
def __init__(self, city_country):
self.s_key = '{플랫폼에서 받은 secret key}'
self.city_country = city_country
self.link_list = []
self.node_list = []
def list_total_count(self):
from urllib.parse import quote
query = quote(self.city_country)
url = f'http://openapi.seoul.go.kr:8088/{self.s_key}/json/TbTraficWlkNet/0/1/' + query
data_json = api_json(url)
total_idx = int(data_json['TbTraficWlkNet']['list_total_count'])
return total_idx
def read_data_json(self, strt_pg, end_pg):
from urllib.parse import quote
query = quote(self.city_country)
url = f'http://openapi.seoul.go.kr:8088/{self.s_key}/json/TbTraficWlkNet/{strt_pg}/{end_pg}/' + query
data_json = api_json(url)
return data_json
def make_link_list(self, data_json):
for idx in range(len(data_json['TbTraficWlkNet']['row'])):
if data_json['TbTraficWlkNet']['row'][idx]['TYPE'] == 'LINK':
link_list4append = []
position_str = data_json['TbTraficWlkNet']['row'][idx]['LINK_WKT'].lstrip('LINESTRING').strip('('')')
_position_list = position_str.split(',')
for position in _position_list:
link_list4append.append(position.split(' '))
self.link_list.append(link_list4append)
elif data_json['TbTraficWlkNet']['row'][idx]['TYPE'] == 'NODE':
node_position = data_json['TbTraficWlkNet']['row'][idx]['NODE_WKT'].lstrip('POINT').strip('('')').split(' ')
self.node_list.append(node_position)
간단한 실행은 위 함수 작성한 아래에 아래 코드 넣어서 실행해보면 됨
NW_info = network_geo_info("노원구") # 시군구명 적어넣으면 됨. 여기선 예시로 노원구
data_json = NW_info.read_data_json(0, 999) # 시작 index와 끝 index 작성
NW_info.make_link_list(data_json) # link, node 데이터 각각 따로 저장
# print로 확인해보기
NW_link_list = NW_info.link_list
NW_node_list = NW_info.node_list
print(NW_link_list)
print(NW_node_list)
[기본 셋팅]
참고 - Flask는 폴더 생성 경로, 폴더명이 매우 중요. 아래 사진 참고(빨간건 무시해주세요.)
1. 프로젝트 폴더 하나 만들어준 다음(여기서는 myprj로 만듦), 그 안에 가상환경 설치(링크 참고)
2. main.py 파일 생성
3. modules.py 파일 생성 후 위 코드 복붙
4. 폴더명 templates 으로 폴더 생성
5. templates 폴더 안에 main.html 파일 생성
파이썬 코드는 간단하게 넘어가겠습니다.
# main.py --> flask가 실행되는 가장 메인이 되는 파이썬 파일
from flask import Flask, render_template, jsonify
from modules import api_json, network_geo_info
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
@app.route('/')
def main():
NW_info = network_geo_info("노원구")
NW_total_count = NW_info.list_total_count()
for idx in range(0, NW_total_count, 1000):
data_json = NW_info.read_data_json(idx, idx+999)
NW_info.make_link_list(data_json)
# print(NW_info.link_list[0]) # [['127.08374812215546', '37.64624447253883'], ['127.08403711977205', '37.646315129324364']]
# print(NW_info.node_list[0]) # ['127.06406830919677', '37.658457824591615']
return render_template('main.html', NW_link_list=NW_info.link_list)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
프론트를 구성하는 main.html 전체 코드
<!DOCTYPE html>
<html>
<head>
<title>카카오 지도</title>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey={{javascript 키}}&libraries=services,clusterer,drawing"></script>
<script>
var NW_link_list = {{ NW_link_list|tojson }};
</script>
</head>
<body>
<div id="map" style="width:1000px;height:1000px;"></div>
<script>
var container = document.getElementById('map');
var options = {
center: new kakao.maps.LatLng(37.6574151, 127.0678763),
level: 4
};
var map = new kakao.maps.Map(container, options);
for (var i = 0; i < NW_link_list.length; i++) {
var linePath = []; // 선을 구성하는 좌표 배열입니다. 이 좌표들을 이어서 선을 표시합니다
for (var j = 0; j < NW_link_list[i].length; j++) {
linePath.push(new kakao.maps.LatLng(NW_link_list[i][j][1], NW_link_list[i][j][0]));
}
var polyline = new kakao.maps.Polyline({
path: linePath, // 선을 구성하는 좌표배열 입니다
strokeWeight: 5, // 선의 두께 입니다
strokeColor: '#FF0000', // 선의 색깔입니다
strokeOpacity: 0.7, // 선의 불투명도 입니다 1에서 0 사이의 값이며 0에 가까울수록 투명합니다
strokeStyle: 'solid' // 선의 스타일입니다
});
// 지도에 선을 표시합니다
polyline.setMap(map);
}
</script>
</body>
</html>
구체적으로 보자면, 파이썬을 실행시키면서 받아온 데이터를
<script>
var NW_link_list = {{ NW_link_list|tojson }};
</script>
이 코드를 통해서 NW_link_list 라는 변수에 저장함. 여기 빨간줄 뜰텐데, 아무 문제 없으니 넘어가도 괜찮.
가장 중요한 polyline을 찍는 js 코드.
for (var i = 0; i < NW_link_list.length; i++) {
var linePath = []; // 선을 구성하는 좌표 배열입니다. 이 좌표들을 이어서 선을 표시합니다
for (var j = 0; j < NW_link_list[i].length; j++) {
linePath.push(new kakao.maps.LatLng(NW_link_list[i][j][1], NW_link_list[i][j][0]));
}
var polyline = new kakao.maps.Polyline({
path: linePath, // 선을 구성하는 좌표배열 입니다
strokeWeight: 5, // 선의 두께 입니다
strokeColor: '#FF0000', // 선의 색깔입니다
strokeOpacity: 0.7, // 선의 불투명도 입니다 1에서 0 사이의 값이며 0에 가까울수록 투명합니다
strokeStyle: 'solid' // 선의 스타일입니다
});
// 지도에 선을 표시합니다
polyline.setMap(map);
}
여기서 NW_link_list 같은 경우, main.py 에 있는 print 주석을 해제한 후 보게되면,
[['127.08374812215546', '37.64624447253883'], ['127.08403711977205', '37.646315129324364']]
위의 값이 하나이다. 이 리스트에서 첫 번째 좌표(위도, 경도)와 두 번째 좌표를 이어서 link를 만든다는 의미이다.
따라서 위 1번 코드와 비교해보았을 때, linePath 변수에 이 link를 모두 넣어주고,
link 값들이 들어간 linePath 라는 변수를 polyline 코드와 같이 작성해서 setMap 시켜준 것이다.
실행시키면 아래와 같은 실행 화면을 볼 수 있을 것임. 실행 방법은 아래 참고
터미널 창에 입력. 경로는 myprj 에서 입력하기
# 맥에서 실행: export FLASK_APP=main.py && flask run
# 윈도우에서 실행: set FLASK_APP=main && $env:FLASK_APP = "main.py" && flask run
윈도우에서 실행 시, && 말고 한줄 씩 입력해주세요
+ 설명 부족한 부분이나 코드 실행 안되는 부분 댓글 남겨주세요.
[출처]
https://apis.map.kakao.com/web/sample/drawShape/
'FrontEnd' 카테고리의 다른 글
- Total
- Today
- Yesterday
- 가상환경
- redis
- Python
- dockerfile
- nginx
- haproxy
- django
- 수동설치
- Database
- venv
- vim
- 일괄변경
- Linux
- cache
- docker
- static서버
- uwsgi
- Error
- PostgreSQL
- flask
- css적용
- 웹배포
- loadBalancing
- vi
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |