[OpenLayers3] 히트맵(HeatMap)

ol3에서 포인트 데이터를 받아 포인트 데이터가 많이 모여 있는 곳을 효과적으로 시각화 해주는 히트맵에 대한 예를 살펴 보겠습니다. 먼저 히트맵에 대해 구현하고조 하는 결과를 아래의 웹 페이지에서 먼저 확인해 봅시다.

위의 실행 결과는 지진이 발생하 지점을 히트맵으로 표시하는 것인데요. 지진 발생이 밀집된 곳은 빨간색으로 표시됨으로써 지진 발생 빈도가 많은 지점을 시각적으로 빠르고 효과적으로 판단할 수 있습니다. 히트맵 결과를 얻기 위해서는 포인트 데이터뿐만 아니라 반경 크기(Radius Size)나 블러링 크기(Blur Size) 값이 필요합니다. 각각의 포인트 지점에서 주어진 반경 크기 안에 포함되는 다른 포인트를 찾아 히트맵의 결과에 반영함으로 반경 크기가 클수록 더 많은 포인트가 그 결과에 반영됨으로써 빨간색의 결과가 더 많이 표시됩니다. 그리고 블러링 크기가 클수록 색상으로 더 흐리게 표시하게 됩니다.

자, 이제 위의 웹페이지에 대한 코드를 살펴볼텐데요. 먼저 필요한 외부 CSS와 스크립트를 포함합니다.




OpenLayers3에 대한 CSS와 js 파일 및 jQuery에 대한 js 파일이 포함되었습니다. 다음은 UI에 대한 코드입니다.

지도가 표시될 div 요소가 있는데, id가 map으로 지정되어 있구요. 히트맵을 위한 입력값을 위한 input 요소가 2개가 있으며 각각에 대한 id를 radius와 blur로 지정되어 있습니다. 이 input 요소는 앞서 설명드렸듯이 각각 검색 반경 크기와 블러링 크기값으로 사용됩니다. 이제 UI에 영혼을 불어 넣을 스크립트를 살펴보겠습니다.

먼저 jQuery의 ready 이벤트를 아래처럼 준비해 둡니다.


위의 …. 부분에 코드를 추가할 것인데요. jQuery의 ready 이벤트는 웹페이지에 대한 모든 준비가 끝났을때 호출됩니다.

먼저 히트맵 표시를 위한 검색반경 및 블러링 크기값을 UI로 부터 얻기 위한 객체를 미리 정의합니다.

var blur = $('#blur');
var radius = $('#radius');

히트맵도 레이어의 종류 중 하나인데요. 다음처럼 히트맵을 위한 레이어 변수를 정의합니다.

var vector = new ol.layer.Heatmap({
    source: new ol.source.Vector({
        url: 'https://openlayers.org/en/v3.19.1/examples/data/kml/2012_Earthquakes_Mag5.kml',
        format: new ol.format.KML({
            extractStyles: false
        })
    }),
    blur: parseInt(blur.val(), 10),
    radius: parseInt(radius.val(), 10),                
    weight: function (feature) {
        var magnitude = parseFloat(feature.get('magnitude'));
        return magnitude - 5;
    }
});

히트맵을 위해 포인트 데이터를 입력 받아야 하는데요. 이를 위해 데이터 소스가 필요합니다. 2번 코드에 ol.source.Vector 클래스로 데이터 소스 객체를 생성하는데.. 실제 데이터 경로를 3번 코드에서 url 문자열로 지정하고 있고, 이 url에서 받는 리소스의 형식은 4번 코드를 통해 지정합니다. 그리고 히트맵의 블러링 크기와 검색 반경의 크기 지정을 위해 각각 8번과 9번에서 지정하고 있습니다. 또한 옵션으로 가중치값을 10번 코드에서 지정하고 있는데요. 함수 형태로 각 포인트에 대한 가중치 값을 계산할 수 있는 함수를 지정할 수 있는데, 가중치의 값이 범위가 0~1 이므로 이 함수 역시 0~1 사이의 값으로 떨어지도록 반환해야 합니다. 위의 코드는 포인트에 대한 속성값 중 maginitude 값을 얻어 이 값에 5를 뺀값으로 하고 있습니다. kml 데이터를 보면 모든 포인트의 magnitude 값은 5~6 사이의 소수값이므로 5를 빼면 0~1사이의 값이 됩니다.

다음은 히트맵 밑에 표시될 배경맵으로 Stamen 서비스 중 toner 레이어에 대한 객체 정의입니다.

var raster = new ol.layer.Tile({
    source: new ol.source.Stamen({
        layer: 'toner'
    })
});

이제 히트맵에 대한 레이어와 배경맵에 대한 레이어 객체가 준비되었으므로, 지도 객체를 생성하고 이 두개의 레이어를 추가해 히트맵과 배경맵을 원하는 div에 표시합니다. 아래의 코드를 통해서 말입니다.

var map = new ol.Map({
    layers: [raster, vector],
    target: 'map',
    view: new ol.View({
        center: [13527858.897415451, 1822818.8878542576],
        zoom: 3
    })
});

2번 코드가 앞서 정의해둔 2개의 레이어 객체에 대한 추가이고, 3번은 지도를 표시할 div의 id이며, 4번은 처음 지도가 표시될 좌표와 줌 레벨값입니다.

이제 마지막으로 검색 반경과 블러링 크기를 설정할 수 있는 input UI에 대해 change 이벤트를 지정해서 사용자가 설정값을 변경하면 바로 지도에 반영될 수 있도록 합니다.

radius.on('change', function () {
    vector.setRadius(parseInt(radius.val(), 10));
});

blur.on('change', function () {
    vector.setBlur(parseInt(blur.val(), 10));
});

아래는 위에서 설명한 전체 코드에 대한 다운로드입니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다