💚 뭐하고 있어?
인구 밀집 시뮬레이션을 개발을 위해 오늘도 끄적끄적 연구중
카카오맵을 쓸지는 모르겠지만 일단 만져보고 있다.
이것은 인구 밀집을 이런식으로 나타내라 안내해주는 글이 아님을 밝힙니당.. (혼자 삽질 기록용임!)
🧀 카카오맵을 사용하기 앞서
카카오맵을 사용하기 위해서는 개발자 등록(Kakao developers)을 해야한다.
이건 개발 공부하는 사람이라면 다 알거라 생각하니 패스 (절대 귀찮아서가 아니다.)
나는 nodejs + express 로 진행했고, 앱키는 JavaScript키를 이용했다. 각자 개인 페이지에서 필요한 키를 확인해서 쓰면 된다.
카카오 맵 개발을 위한 상세 내용은 이미 가이드 페이지에 상세하게 나오므로 사용방법은 여기에서 알아보자
(나는 지금 카카오맵 연동과 사용법을 소개하려고 글을 쓰는게 아니다!)
https://apis.map.kakao.com/web/guide/
🏃♂️ 어떻게 표현해볼까...
인구 밀집 표현을 위해 카카오맵에서 제공해주는 샘플을 둘러보던 중
클러스터 마커 표시를 알게되었다.
아하! 이걸로 특정 구역에 위·경도 값들로 [원활, 보통, 혼잡, 매우혼잡]을 표시하면 되겠다. 라고 생각했다.
그런데 카카오에서 제공해주는 샘플 데이터들은 전국구로 넓게 분포되어 있어서 인구밀집도(?)라고 생각하기엔 문제가 있다.
아니 json 샘플 파일명도 치킨이다 치킨..! 아마도 어떤 치킨집의 위치인것같다!!!
(샘플파일 Link : https://apis.map.kakao.com/download/web/data/chicken.json)
🛴 밀집도를 표현해보자
나는 홍대 거리 혼잡도를 테스트하기로 했다.
◼ 위경도 값을 사람이라고 가정하고, 홍대 위주로 위경도 값이 400~600개가 있어야함
=> 홍대 위주의 위경도 값을 랜덤으로 생성해야된다.
◼ 지도level을 최소값으로 했을때 마커가 아니라 [원활, 보통, 혼잡, 매우혼잡]으로 나타나야함
(카카오맵 level이 낮을수록 건물들이 자세하게 보이고, 높을수록 구... 지역... 한국지도(?) 이런식으로 ? 표현됨. 레벨은 1~15)
1. 먼저 구글맵에서 위경도를 조사했다.. (카카오맵에서는 위경도를 알려주지 않더라. 내가 못찾는건가?)
대충 범위를 정해서 각 꼭지점의 위경도를 구했다.
37.556473, 126.922957
37.556550, 126.928133
37.554400, 126.922900
37.554887, 126.929416
2. 특정 범위내 위경도 생성 랜덤함수 짜기 + 리스트에 넣기
lat 의 min과 max 의 차이는 약 2150이었고, lng 의 min과 max의 차이는 약 6500이었다.
그래서 먼저 각각 2150, 6500의 랜덤한 수를 생성해서
위경도 값으로 변경하는 작업을 했다.
각각 min값에서 부터 랜덤으로 추출된 값을 더하는 식으로 진행했다.
var list = { positions:[] }
for(var i=0; i<10; i++) {
var lat = Math.floor(Math.random() * 2151);
var lng = Math.floor(Math.random() * 6501);
lat = ((lat+554400) * 0.000001 + 37).toFixed(6);
lng = ((lng+922900) * 0.000001 + 126).toFixed(6);
list.positions.push({lat, lng});
}
console.log(list);
(코드를 더 깔끔하게 할 수 있을것같은데 모르겠다 일단 이렇게..ㅎㅎㅎ..? )
chicken.js가 아래와 같은 형식으로 나타나므로 나도 똑같이 만들어보려고 위와 같이 코드를 작성함.
결과 json 내에 positions 라는 객체가 리스트를 담고 있는 형태
3. index.js
// 2023.04.24 - 만약에 count가 입력되지 않는다면 default로 100건
router.get('/hongdae', function (req, res, next) {
var list = getPosition(100);
res.json(list);
});
// 2023.04.24 - count 특정값 입력가능. 근데 1000 초과는 안됨. 과부하걸릴것같아서 그냥 막음.
router.get('/hongdae/:count', function (req, res, next) {
let count = req.params.count;
if (count > 1000) {
res.send('너무 많습니다.');
} else {
var list = getPosition(count);
res.json(list);
}
})
4. index.ejs 내 script
var container = document.getElementById('map'); //지도를 담을 영역의 DOM 레퍼런스
var options = { //지도를 생성할 때 필요한 기본 옵션
center: new kakao.maps.LatLng(37.557527, 126.9244669), //지도의 중심좌표.
level: 3 //지도의 레벨(확대, 축소 정도)
};
var map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
var clusterer = new kakao.maps.MarkerClusterer({
map: map, // 마커들을 클러스터로 관리하고 표시할 지도 객체
averageCenter: true, // 클러스터에 포함된 마커들의 평균 위치를 클러스터 마커 위치로 설정
minLevel: 1, // 클러스터 할 최소 지도 레벨
calculator: [10, 30, 50], // 클러스터의 크기 구분 값, 각 사이값마다 설정된 text나 style이 적용된다
texts: getTexts, // texts는 ['삐약', '꼬꼬', '꼬끼오', '치멘'] 이렇게 배열로도 설정할 수 있다
styles: [{ // calculator 각 사이 값 마다 적용될 스타일을 지정한다
width : '30px', height : '30px',
background: 'rgba(51, 204, 255, .8)',
borderRadius: '15px',
color: '#000',
textAlign: 'center',
fontWeight: 'bold',
lineHeight: '31px'
},
{
width : '40px', height : '40px',
background: 'rgba(255, 153, 0, .8)',
borderRadius: '20px',
color: '#000',
textAlign: 'center',
fontWeight: 'bold',
lineHeight: '41px'
},
{
width : '50px', height : '50px',
background: 'rgba(255, 51, 204, .8)',
borderRadius: '25px',
color: '#000',
textAlign: 'center',
fontWeight: 'bold',
lineHeight: '51px'
},
{
width : '60px', height : '60px',
background: 'rgba(255, 80, 80, .8)',
borderRadius: '30px',
color: '#000',
textAlign: 'center',
fontWeight: 'bold',
lineHeight: '61px'
}
]
});
// 클러스터 내부에 삽입할 문자열 생성 함수입니다
function getTexts( count ) {
// 한 클러스터 객체가 포함하는 마커의 개수에 따라 다른 텍스트 값을 표시합니다
if(count < 10) {
return '원활';
} else if(count < 30) {
return '보통';
} else if(count < 50) {
return '혼잡';
} else {
return '매우혼잡';
}
}
$.get("/hongdae", function(data) {
console.log(data.positions);
// 데이터에서 좌표 값을 가지고 마커를 표시합니다
// 마커 클러스터러로 관리할 마커 객체는 생성할 때 지도 객체를 설정하지 않습니다
var markers = $(data.positions).map(function(i, position) {
return new kakao.maps.Marker({
position : new kakao.maps.LatLng(position.lat, position.lng)
});
});
// 클러스터러에 마커들을 추가합니다
clusterer.addMarkers(markers);
});
kakao.maps.event.addListener(clusterer, 'clusterclick', function(cluster) {
// 현재 지도 레벨에서 1레벨 확대한 레벨
var level = map.getLevel()-1;
// 지도를 클릭된 클러스터의 마커의 위치를 기준으로 확대합니다
map.setLevel(level, {anchor: cluster.getCenter()});
});
카카오맵 예제에서 긁어왔고, 수정한 내용은 별로없다.
1. clusterer - minLevel 1로 조정
2. 삐약, 꼬꼬, 치멘 등을 원활, 보통, 혼잡으로 수정
3. chicken.js url을 위에서 만든 hongdae로 수정
🍋 결과
내가 원한대로 데이터가 잘 넘어왔고…
정확히 사각형 모양으로 저렇게 분포되었다.
원활, 보통, 혼잡, 매우혼잡 값 범위는 조정하면 될 것 같다..
내가 원했던 작업은 끝!
지도 크기에 따라서 내가 원하는대로 clusterer의 값 제공
💒 그런데 말입니다.
인구 밀집도? 혼잡도를 이런식으로 지도 표시하는게 맞을까?
사실 내가 해야하는건 다중밀집에 대한 내용이었는데 …
교통량 표시하는 것 처럼 길에 빨강, 노랑, 초록 표시를 하는게 맞지 않을까?
(그치만 교통은 정말 도로위의 혼잡도..)
길 위에 선을 긋는 방법을 찾아봐야지.
그런데 고맙게도 카카오맵에서 도형그리기(선그리기)를 지원한다.
다음번에 알아보도록하자.
(없는게 뭐지. 멋있다.)
'기타' 카테고리의 다른 글
[Git] Git 명령어 정리 (0) | 2023.05.16 |
---|---|
[ubuntu] git 설치, git clone, aws에서 서버 실행 - 개인 기록용 (0) | 2023.04.21 |
[ubuntu] npm 설치 (0) | 2023.04.21 |
[AWS EC2] No supported authentication methods available (server sent: publickey) (0) | 2023.04.21 |
[깃허브/github] 기존 프로젝트를 새로 생성한 Repository에 올리기 (0) | 2023.02.21 |