[Flask] 초간단! HTML과 Flask 통신 - 3
2024. 2. 4. 23:02ㆍBE/Flask
본 포스팅에서는 Naver Cloud Flatform의 API를 이용해 Flask서버에서 지도 정보를 받아서 웹 페이지에서 지도를 그려주는 것에 관해 다룹니다.
Naver Cloud Flatform에서는 네이버 지도에 관한 여러 어플리케이션e.g.WebDynamicMap,Geocoding을 API로 제공합니다. 회원 가입을 하고 ID를 발급 받는 과정등은 추후에 다른 포스팅에서 다루도록하고 본 포스팅에서는 geocoding을 이용하여 어떻게 지도를 불러오고 웹페이지에 그리는지에 대해 다루도록 하겠습니다.
먼저 flask서버에서 geocoding을 이용할 수 있도록 관련 설정을 해주고, requests 라이브러리의 get함수를 통해서 url의 정보를 가져옵니다. 그 후, 이것을 parsing하여 원하는 정보를 추출합니다. API의 response에 대한 정보는 코드 아래와 같습니다.
client_id = "CLIENT_ID"
client_secret = "CLIENT_SECRET"
endpoint = "https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode"
headers = {
"X-NCP-APIGW-API-KEY-ID": client_id,
"X-NCP-APIGW-API-KEY": client_secret,
}
address = "불정로 6"
@app.route('/userPost')
def userPost():
url = f"{endpoint}?query={address}"
res = requests.get(url, headers=headers)
if res.json()['addresses']:
return render_template('userPost.html', lat=res.json()['addresses'][0]['x'], lon=res.json()['addresses'][0]['y'])
else:
return render_template('userPost.html', lat=127.1052133, lon=37.3595316)
{
"status": "OK",
"meta": {
"totalCount": 1,
"page": 1,
"count": 1
},
"addresses": [
{
"roadAddress": "경기도 성남시 분당구 불정로 6 그린팩토리",
"jibunAddress": "경기도 성남시 분당구 정자동 178-1 그린팩토리",
"englishAddress": "6, Buljeong-ro, Bundang-gu, Seongnam-si, Gyeonggi-do, Republic of Korea",
"addressElements": [
{
"types": [
"POSTAL_CODE"
],
"longName": "13561",
"shortName": "",
"code": ""
}
],
"x": "127.10522081658463",
"y": "37.35951219616309",
"distance": 20.925857741585514
}
],
"errorMessage": ""
}
위의 플라스크 서버에서 lat, lon을 전달해주었으므로, HTML 파일에서는 jinaj2 템플릿 엔진을 통해 아래와 같이 정보를 이용할 수 있습니다. 먼저 div 태그를 통해 지도가 들어갈 크기를 정해주고, script 태그에서는 지도 div 태그의 아이디를 이용하여 지도를 그려줍니다. 아래의 예시에서는 지도를 확대, 축소하는 여러가지 기능들이 포함되어 있으므로 기호에 맞게 사용하면 됩니다.
<div id="map" style="width: 70%; height: 300px; margin:auto"></div>
<script id="code">
var center = new naver.maps.LatLng("{{lon}}", "{{lat}}");
var map = new naver.maps.Map('map', {
center: center,
zoom: 13,
minZoom: 7, //지도의 최소 줌 레벨
zoomControl: true, //줌 컨트롤의 표시 여부
zoomControlOptions: { //줌 컨트롤의 옵션
position: naver.maps.Position.TOP_RIGHT
}
});
map.setOptions("mapTypeControl", true); //지도 유형 컨트롤의 표시 여부
naver.maps.Event.addListener(map, 'zoom_changed', function (zoom) {
console.log('zoom:' + zoom);
});
map.setOptions('minZoom', 10);
console.log('잘못된 참조 시점', map.getOptions('minZoom'), map.getOptions('minZoom') === 10);
// 지도의 옵션 참조는 init 이벤트 이후에 참조해야 합니다.
naver.maps.Event.once(map, 'init', function () {
console.log('올바른 참조 시점', map.getOptions('minZoom') === 10);
});
// 지도 인터랙션 옵션
$("#interaction").on("click", function (e) {
e.preventDefault();
if (map.getOptions("draggable")) {
map.setOptions({ //지도 인터랙션 끄기
draggable: false,
pinchZoom: false,
scrollWheel: false,
keyboardShortcuts: false,
disableDoubleTapZoom: true,
disableDoubleClickZoom: true,
disableTwoFingerTapZoom: true
});
$(this).removeClass("control-on");
} else {
map.setOptions({ //지도 인터랙션 켜기
draggable: true,
pinchZoom: true,
scrollWheel: true,
keyboardShortcuts: true,
disableDoubleTapZoom: false,
disableDoubleClickZoom: false,
disableTwoFingerTapZoom: false
});
$(this).addClass("control-on");
}
});
// 관성 드래깅 옵션
$("#kinetic").on("click", function (e) {
e.preventDefault();
if (map.getOptions("disableKineticPan")) {
map.setOptions("disableKineticPan", false); //관성 드래깅 켜기
$(this).addClass("control-on");
} else {
map.setOptions("disableKineticPan", true); //관성 드래깅 끄기
$(this).removeClass("control-on");
}
});
// 타일 fadeIn 효과
$("#tile-transition").on("click", function (e) {
e.preventDefault();
if (map.getOptions("tileTransition")) {
map.setOptions("tileTransition", false); //타일 fadeIn 효과 끄기
$(this).removeClass("control-on");
} else {
map.setOptions("tileTransition", true); //타일 fadeIn 효과 켜기
$(this).addClass("control-on");
}
});
// min/max 줌 레벨
$("#min-max-zoom").on("click", function (e) {
e.preventDefault();
if (map.getOptions("minZoom") === 10) {
map.setOptions({
minZoom: 7,
maxZoom: 21
});
$(this).val(this.name + ': 7 ~ 21');
} else {
map.setOptions({
minZoom: 10,
maxZoom: 21
});
$(this).val(this.name + ': 10 ~ 21');
}
});
//지도 컨트롤
$("#controls").on("click", function (e) {
e.preventDefault();
if (map.getOptions("scaleControl")) {
map.setOptions({ //모든 지도 컨트롤 숨기기
scaleControl: false,
logoControl: false,
mapDataControl: false,
zoomControl: false,
mapTypeControl: false
});
$(this).removeClass('control-on');
} else {
map.setOptions({ //모든 지도 컨트롤 보이기
scaleControl: true,
logoControl: true,
mapDataControl: true,
zoomControl: true,
mapTypeControl: true
});
$(this).addClass('control-on');
}
});
$("#interaction, #tile-transition, #controls").addClass("control-on");
</script>
'BE > Flask' 카테고리의 다른 글
[Flask] 초간단! HTML과 Jinja2 0 | 2024.01.30 |
---|---|
[Flask] 초간단! HTML과 Flask 통신 - 2 2 | 2024.01.29 |
[Flask] 초간단! HTML과 Flask 통신 - 1 1 | 2024.01.29 |