본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Html 캔버스/Html 캔버스 에니메이션

Html Canvas에 대한민국 지도 쉽계 계산하여 표현 하기

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2021. 4. 8.

 

* 게시글 하단의 제 깃허브 주소를 통해 실제 구현된 모습을 볼 수 있습니다

 

이전 시간에 만들었던 대한민국 차트는 위경도 값을 다소 복잡한 방법을 통해서 그려냈었습니다.

lts0606.tistory.com/420

 

Html Korea map, Html 캔버스 대한민국 지도 제작(이벤트 포함)

우리나라의 위도와 경도값을 토대로 캔버스에 그려준 뒤에 이벤트를 부여하는 기능입니다. 우리나라 지도의 차트기능 만들 때 사용하였습니다. 우리나라의 위도경도 값은 구글링하면 쉽게 받

lts0606.tistory.com

 

이러한 방법은 틀린 것은 아니나, 나중에 기능 수정 및 버그발생시에 해당 코드를 매번 보지 않는 경우라면 어렵고 이해하기 힘들 것 입니다.

사실...지금 살펴봐도 이해가 잘 안되어 힘들었습니다..

조금 더 간단하고 쉬운방법을 고민하던 중 생각 해 낸 방식이 바로 비율(rate)을 적용 해 보는 것 이였습니다!

먼저 지형정보(geo)에 대한 데이터를 가져옵니다.

오랜만에 보는 대량의 geojson 형태의 데이터 입니다.

 

여기서 각각의 지역에 대한 위도(latitude)와 경도(longitude) 값을 우리는 구할 수 있습니다.

그러면 변수를 하나 만든 다음에 해당 위도(latitude)의 최소값, 최댓값을 구하여 넣어 줍니다.

마찬가지로 경도(longitude)의 최소값과 최대값을 구해서 넣어 줍니다.

json.features.forEach( target => {
    target.geometry.coordinates.forEach( depth1 => {
        depth1.forEach( depth2 => {
            if(depth2.length <= 1){  //지역구분이 1개로 되어있는 경우
                checkMinMax(depth2)
            } else {  //지역 구분이 다중으로 된 경우
                depth2.forEach(depth3 => {
                    checkMinMax(depth3)
                });
            }
        });
    });
});


//위경도의 각각의 최대 최솟값을 찾아 줍니다.
function checkMinMax(arr){
    let lon = arr[0]  //경도
    let lat = arr[1]  //위도
    if(lon < metaInfo.minLon){
        metaInfo.minLon = lon
    } else if(lon > metaInfo.maxLon){
        metaInfo.maxLon = lon
    }
    if(lat < metaInfo.minLat){
        metaInfo.minLat = lat
    } else if(lat > metaInfo.maxLat){
        metaInfo.maxLat = lat
    }    
}

 

해당 값을 담을 변수를 정하여 아래 사진처럼 데이터를 만들어 냅니다.

metaInfo라는 변수에 내용을 담았습니다.

이런식으로 들어가졌네요~

 

당연히 위도, 경도값은 캔버스에 표시를 할 수 없습니다.

그러면 이제 Javascript에서의 좌표 개념인 x와 y값으로 변환을 시켜야 됩니다.

위에 만들어 놓은 metaInfo라는 변수는 위경도의 최소, 최대값이 담긴 변수 입니다.

아래 개념을 살펴봅니다.

let 비율1 = (내위도 - 최소위도) / (최대위도 - 최소위도)
let 비율2 = (내경도 - 최소경도) / (최대경도 - 최소경도)

 

위 개념에 의하면 내가 위치한 위경도가 최대인 경우에는 1이라는 값이 나올 것 입니다.

마찬가지로 내가 위치한 위경도 값이 최소인 경우에는 아마도..0.1정도의 값이 나올 것 입니다.

바로 이 비율을 그대로 내가 그릴 캔버스의 높이와 넓이에 곱하여 줍니다.

//위경도 값을 좌표값으로 바꾸는 함수1
function changeX(x) {
    let rate = (x - metaInfo.minLon) / (metaInfo.maxLon - metaInfo.minLon); 
    return WIDTH * rate;  
}
//위경도 값을 좌표값으로 바꾸는 함수2
function changeY(y) {
    let rate = (y - metaInfo.minLat) / (metaInfo.maxLat - metaInfo.minLat); 
    return HEIGHT*rate;
}

 

위 공식에 의해서 데이터를 변환하여 줍니다.

그러면 무언가 그럴싸해 보이는 데이터가 나오게 됩니다.

뭔가...캔버스의 좌표처럼 보입니다!?!

 

이제 두근거리는 마음을 가지고 그림을 그려봅니다.

각각의 데이터의 시작할 지점은 moveTo를 활용하여 캔버스가 시작되는 점을 움직여주고,

이후에는 lineTo를 활용하여 선을 이어줍니다.

선을 전부 이은 다음에는 바로 stroke fill을 통해 그림을 완성합니다.

여기서는 stroke 함수를 사용 하였습니다.

엥..사진이 뒤집혔습니다??

 

그림을 그리고 나니 사진이 뒤집혔습니다.

캔버스에서의 y좌표값은 아래로 향할 수록 커지기 때문 입니다.

하지만 우리가 가지고온 위도의 값은 위로 갈 수록 커지고 아래로 갈 수록 작아지기 때문에 이와같은 현상이 발생 한 것 입니다.

해결방법은 매우 간단합니다.

만들어놓은 changeY 함수에서 캔버스의 높이값을 빼 주면 위아래가 바뀌게 됩니다.

쫜~ 뒤집혔습니다.

 

만약 좌우 여백이나 위치를 좀더 조정을 한 다면 아래 방법 처럼 metaInfo의 위경도의 최대/최소값을 조정하면 원하는 만큼 비율을 조정 할 수 있을 것 입니다.

metaInfo.maxLat +=0.25
metaInfo.minLon -=0.25
metaInfo.maxLat +=0.25
metaInfo.minLat -=0.25

 

여기에 이제 다각형에서의 이벤트를 그리는 공식을 달아주면 원하는 이벤트가 달린 기초적인 모습의 기능이 완성됩니다.

잘 되는군요.

 

다각형에 대한 이벤트를 부여하는 방법은 아래 포스팅에서 확인 할 수 있습니다.

* 참조 : lts0606.tistory.com/286

 

이제 좀 더 간단하게 위경도에 따른 대한민국 지도를 표현 할 수 있게 되었습니다.

위 방법을 활용하면 어느 지역이던지 간에 쉽게 캔버스(canvas)를 활용하여 표현 할 수 있을 것 입니다.

동작하는 코드를 보려면 아래 깃허브 주소를 통해 확인하여 주세요.

* 동작 중인 깃허브 주소(Sample 동작 코드)

 

Canvas

 

taeseungryu.github.io

 

 

위 모든 내용이 웹(web)에서 동작하는 캔버스(canvas)로 이루어진 내용 입니다.

 * 플래쉬, 액션스크립트, 유니티 같은 응용 프로그램이 아닙니다~

이상으로 Html 캔버스를 활용한 대한민국 지도를 쉽게 캔버스로 표현하는 방법에 대해서 정리하여 보았습니다.

 

해당 포스팅은 코드를 전부 공개하지 않고 개념만 정리한 내용입니다.

문의사항이나 궁금한 점은 언제든 댓글 또는 메일로 연락주세요~ :)

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글