네이버 maps api를 쓰다가 카카오가 쉽다는 얘기를 들어서 한번 해봄
나같은 쌩초보 생활코딩러는 난이도가 정말 중요하기에...
근데 별 차이는 없는것 같다. 네이버와 카카오간에 차이점이라면, 네이버는 한달 한도가 있다면 카카오는 1일 한도가 있다는 점? (네이버: 1달 3천만, 카카오: 1일 30만)
1) 카카오디벨로퍼스 가입, 어플리케이션 등록
2) 몽고db에 데이터 업로드
3) 자바스크립트 왕초보 수준의 이해도
4) 서버 생성
나는 코딩공부를 스파르타코딩클럽의 왕초보 난이도밖에 해본 적이 없다. 전공도 아니고 다른데서 배운 적도 없다. 그 중에서도 '웹개발 종합반'에서 배운 내용이 내 코딩의 전부라고 할 수 있다. 위 선행조건 2), 3), 4)는 그곳에서 배운 내용과, 그때 작성했던 코드를 거의 그대로 복붙한 내용이므로, 이번 글의 내용은 딱 저정도 수준에서 우왕좌왕하는 분들에게 적당한 도움이 될 것이라 생각한다.
maps api를 가입 후 플랫폼을 웹, 안드로이드, ios 중에서 웹을 선택한다. 로컬서버에서 돌릴거면 도메인을 localhost, 그게 아니면 아이피와 포트를 입력 후 저장 (예: 123.456.789.012:9999)
데이터는 내가 기존에 가지고 있던 엑셀파일을 토대로, 파이썬으로 몽고db에 업로드했다. 이 당시 내가 가진 정보는 1300여개의 주소였고 이걸 전부 지도에 마커로 띄워야했기 때문에, 코드에 주소좌표를 전부 넣느니 몽고db를 활용하는게 좋겠다고 생각함.
나는 로보3t와 아틀라스를 연동해서 사용하고 있다. 아틀라스는 구글 아이디로 회원가입 후 무료 이용이 가능하고, 로보는 아틀라스 웹페이지보다 시인성이 좋다고 판단했기 때문이다.
*아틀라스와 로보를 연동하는 방법은 구글에 쌔고 쌨으니 생략합니다.
당시 보유하고 있던 주소지 엑셀파일의 컬럼명
위 엑셀파일을 db에 업로드할때 쓴 코드
import pandas as pd
# 아래 3줄은 아트라스 mongoDB 사용시 설정
from pymongo import MongoClient
client = MongoClient('mongodb+srv://아틀라스아이디_:아틀라스비번@cluster0.9ws0c.mongodb.net/?retryWrites=true&w=majority')
db = client.만들db이름
mycoll = db.만들컬렉션이름
df = pd.read_excel(f'D:\\불러올엑셀파일이름.xlsx')
# print(df) # 잘 불러와지나 확인
for i in range(len(df)):
m_name = df.iloc[i]['매장명']
m_addr = df.iloc[i]['전체주소']
m_x = df.iloc[i]['x좌표']
m_y = df.iloc[i]['y좌표']
m_g = df.iloc[i]['권역']
m_n = df.iloc[i]['노선코드'][0:4]
m_gj = df.iloc[i]['거점']
m_gr = (df.iloc[i]['그룹'])
res = {'매장명': m_name, '매장주소': m_addr, 'x좌표': m_x, 'y좌표': m_y,'그룹': m_gr, '거점': int(m_gj), '권역': m_g, '노선코드': m_n}
# print(res) # 원하는 형태로 잘 됐나 확인
mycoll.insert_one(res)
암튼 이런 식으로 db를 만들었고, 이제 웹페이지에서 db의 x,y좌표를 따서 마커를 표시하면 된다!
html파일을 생성하고, 위 사이트에 예제코드를 몇개만 넣으면 지도는 기본적으로 완성이 된다. (아이디 넣는 부분만 잘 수정하면)
그러므로 바로 마커를 만들어야 하는데...
이런게 있네. 근데 나는 1300개를 띄워야 되니까
이걸로 간다.
그리고 마커를 눌렀을 때 주소도 같이 나왔으면 좋겠어서
이것도 같이 추가해줬다.
그래서 내가 만든 파일은 총 3개. html파일 1개와 js파일 2개.
html파일
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<!-- JQuery를 import 합니다 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>
다음지도
</title>
<style>
.ifw {
height: auto;
width: auto;
padding: 5px;
margin-top: -15px;
}
.area {
position: absolute;
background: #fff;
border: 1px solid #888;
border-radius: 3px;
font-size: 12px;
top: -5px;
left: 15px;
padding: 2px;
}
.info {
font-size: 12px;
padding: 5px;
}
.info .title {
font-weight: bold;
}
#btns {
padding: auto;
margin: auto;
align-items: auto;
}
#iw_con_info {
width:auto; height:auto; margin-top: -13px; padding: auto; border: auto;
}
</style>
</head>
<body>
<div id="map" style="width:100%;height:1040px;"></div>
<script type="text/javascript"
src="//dapi.kakao.com/v2/maps/sdk.js?appkey=애플리캐이션 키 입력"></script>
<script src="../static/kakaoscript0.js"></script>
<script src="../static/kakaoscriptAll.js"></script>
</body>
</html>
js파일 첫번째. 카카오맵 기본 설정
// 기본 지도 설정
var container = document.getElementById('map'); //지도를 담을 영역의 DOM 레퍼런스
var options = { //지도를 생성할 때 필요한 기본 옵션
center: new kakao.maps.LatLng(지도의 첫 화면에 놓일 중심 좌표 지정), //지도의 중심좌표.
level: 12 //지도의 레벨(확대, 축소 정도)
};
var map = new kakao.maps.Map(container, options),
customOverlay = new kakao.maps.CustomOverlay({}),
infowindow = new kakao.maps.InfoWindow({ removable: true });; //지도 생성 및 객체 리턴
// 이 위까지가 기본설정 끝
js파일 두번째. 서버를 통해 db에서 데이터를 가져오고 마커를 뿌림
// 아래는 서버한테 데이터 수신
getdatas = []
m_infos = []
positions = []
$.ajax({
type: 'get',
url: "/data",
success: function (response) {
getdatas = response['result']
for (i = 0; i < getdatas.length; i++) {
let m_g = getdatas[i]['매장명']
let m_a = getdatas[i]['매장주소']
let m_x = getdatas[i]['x좌표']
let m_y = getdatas[i]['y좌표']
let m_w = getdatas[i]['권역']
let m_gj = getdatas[i]['거점']
let m_gr = getdatas[i]['그룹']
let m_gc = getdatas[i]['간선코드']
let m_info = { '매장명': m_g, '매장주소': m_a, 'x좌표': m_x, 'y좌표': m_y, '권역': m_w, '거점': m_gj }
m_infos.push(m_info)
}
// 아래는 마커와 인포윈도우 여러개 표시
for (var i = 0; i < m_infos.length; i++) {
var m_i_name = m_infos[i]['매장명']
var m_i_x = m_infos[i]['x좌표']
var m_i_y = m_infos[i]['y좌표']
var m_i_addr = m_infos[i]['매장주소']
var m_i_gw = m_infos[i]['권역']
var m_i_gj = m_infos[i]['거점']
var gb_position = { content: `<div class="ifw"><h5>${m_i_name}</h5><h6>${m_i_addr}</h6><h5> ${m_i_gw}</h5>`, latlng: new kakao.maps.LatLng(m_i_y, m_i_x) }
positions.push(gb_position)
}
for (var i = 0; i < positions.length; i++) {
var m_i_addr2 = m_infos[i]['매장주소']
var m_i_name2 = m_infos[i]['매장명']
var m_i_gw2 = m_infos[i]['권역']
var m_i_gj2 = m_infos[i]['거점']
var marker = new kakao.maps.Marker({
map: map,
position: positions[i].latlng,
clickable: true
})
var iwContent = `<div id="iw_con_info"><h5>${m_i_name2}</h5><h5>${m_i_addr2}</h5><h5>권역: ${m_i_gw2}</h5><h5>거점: ${m_i_gj2}</h5></div>`, // 인포윈도우에 표출될 내용으로 HTML 문자열이나 document element가 가능합니다
iwRemoveable = true; // removeable 속성을 ture 로 설정하면 인포윈도우를 닫을 수 있는 x버튼이 표시됩니다
var infowindow = new kakao.maps.InfoWindow({
content: iwContent,
removable: iwRemoveable
});
kakao.maps.event.addListener(marker, 'click', makeOverListener(map, marker, infowindow));
}
}
})
// 인포윈도우를 표시하는 클로저를 만드는 함수
function makeOverListener(map, marker, infowindow) {
return function () {
infowindow.open(map, marker);
};
}
// 인포윈도우를 닫는 클로저를 만드는 함수
function makeOutListener(infowindow) {
return function () {
infowindow.close();
};
}
결과물
마커를 웹페이지에 올리는 데에 성공했지만, 난 솔직히 이게 어떻게 작동하는지 모르겠다. ㅎㅎㅎㅎ;;;
마커와 인포윈도우를 배열로 관리하라고 하던데, 자바스크립트에서 배열은 파이썬의 리스트와 같은 대괄호 형태인데... 거기서 map, new를 통해 마커를 쫙쫙 뿌려주는건가?
다음번엔 웹페이지에 버튼을 만들어서 구역별로 마커가 따로 출력되는 코드를 짜봐야지