티스토리 뷰

행정구역을 폴리곤(Polygon)으로 구분해보자(with 카카오 맵 or 다음 맵)


다음 부동산 처럼 행정구역을 구분해서 지역 별로 길찾기를 구현하고 싶었다.

다음 맵 API에 들어가보니 '다각형 이벤트 등록하기2'에 비슷한 느낌으로 샘플코드가 있었지만 폴리곤을 만들기 위한 좌표들이 없었다...

언제나 그렇듯 구글링 하다보니 http://ssmlim.tistory.com/16?category=566348 여기에 자세히 나와있어서, 좌표들을 geojson 파일로 만들 수 있었다.

그 다음부턴 그냥 JSON 파일만 받아와서 다음 맵 API에 있는 샘플코드에 좌표들을 넣기만 하면 되었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<script>
 
//행정구역 구분
$.getJSON("resources/json/seoul_gson.geojson"function(geojson) {
 
    var data = geojson.features;
    var coordinates = [];    //좌표 저장할 배열
    var name = '';            //행정 구 이름
 
    $.each(data, function(index, val) {
 
        coordinates = val.geometry.coordinates;
        name = val.properties.SIG_KOR_NM;
        
        displayArea(coordinates, name);
 
    })
})
 
 
var polygons=[];                //function 안 쪽에 지역변수로 넣으니깐 폴리곤 하나 생성할 때마다 배열이 비어서 클릭했을 때 전체를 못 없애줌.  그래서 전역변수로 만듦.
    
//행정구역 폴리곤
function displayArea(coordinates, name) {
 
    var path = [];            //폴리곤 그려줄 path
    var points = [];        //중심좌표 구하기 위한 지역구 좌표들
    
    $.each(coordinates[0], function(index, coordinate) {        //console.log(coordinates)를 확인해보면 보면 [0]번째에 배열이 주로 저장이 됨.  그래서 [0]번째 배열에서 꺼내줌.
        var point = new Object(); 
        point.x = coordinate[1];
        point.y = coordinate[0];
        points.push(point);
        path.push(new daum.maps.LatLng(coordinate[1], coordinate[0]));            //new daum.maps.LatLng가 없으면 인식을 못해서 path 배열에 추가
    })
    
    // 다각형을 생성합니다 
    var polygon = new daum.maps.Polygon({
        map : map, // 다각형을 표시할 지도 객체
        path : path,
        strokeWeight : 2,
        strokeColor : '#004c80',
        strokeOpacity : 0.8,
        fillColor : '#fff',
        fillOpacity : 0.7
    });
    
    polygons.push(polygon);            //폴리곤 제거하기 위한 배열
 
    // 다각형에 mouseover 이벤트를 등록하고 이벤트가 발생하면 폴리곤의 채움색을 변경합니다 
    // 지역명을 표시하는 커스텀오버레이를 지도위에 표시합니다
    daum.maps.event.addListener(polygon, 'mouseover'function(mouseEvent) {
        polygon.setOptions({
            fillColor : '#09f'
        });
 
        customOverlay.setContent('<div class="area">' + name + '</div>');
 
        customOverlay.setPosition(mouseEvent.latLng);
        customOverlay.setMap(map);
    });
 
    // 다각형에 mousemove 이벤트를 등록하고 이벤트가 발생하면 커스텀 오버레이의 위치를 변경합니다 
    daum.maps.event.addListener(polygon, 'mousemove'function(mouseEvent) {
 
        customOverlay.setPosition(mouseEvent.latLng);
    });
 
    // 다각형에 mouseout 이벤트를 등록하고 이벤트가 발생하면 폴리곤의 채움색을 원래색으로 변경합니다
    // 커스텀 오버레이를 지도에서 제거합니다 
    daum.maps.event.addListener(polygon, 'mouseout'function() {
        polygon.setOptions({
            fillColor : '#fff'
        });
        customOverlay.setMap(null);
    });
 
    // 다각형에 click 이벤트를 등록하고 이벤트가 발생하면 해당 지역 확대을 확대합니다.
    daum.maps.event.addListener(polygon, 'click'function() {
        
        // 현재 지도 레벨에서 2레벨 확대한 레벨
        var level = map.getLevel()-2;
        
        // 지도를 클릭된 폴리곤의 중앙 위치를 기준으로 확대합니다
        map.setLevel(level, {anchor: centroid(points), animate: {
            duration: 350            //확대 애니메이션 시간
        }});            
 
        deletePolygon(polygons);                    //폴리곤 제거      
    });
}
</sciprt>
cs



폴리곤(Polygon) 클릭 확대 이벤트를 구현해보자 (with 카카오 맵 or 다음 맵)

만들어진 폴리곤(Polygon)을 클릭하면 해당 지역만 보여주도록 확대시키면서, 행정구역 경계선과 채움색을 사라지게 하고 싶었다.

샘플 코드의  'click'이 있는 리스너에 구현하려 했지만, 폴리곤의 중심좌표가 있어야만 했다.

폴리곤의 중심좌표를 구하려면 centroid 알고리즘을 활용하라는 글을 보고 냅다 써먹어 봤다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//centroid 알고리즘 (폴리곤 중심좌표 구하기 위함)
function centroid (points) {
    var i, j, len, p1, p2, f, area, x, y;
 
    area = x = y = 0;
 
    for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
            p1 = points[i];
            p2 = points[j];
 
            f = p1.y * p2.x - p2.y * p1.x;
            x += (p1.x + p2.x) * f;
            y += (p1.y + p2.y) * f;
            area += f * 3;
    }
    return new daum.maps.LatLng(x / area, y / area);
}
 
cs


폴리곤을 없애는 건 예전에 사용한 적 있는 setMap(null)을 활용해서 어렵지 않게 지울 수 있었다. 

1
2
3
4
5
6
7
8
//지도 위 표시되고 있는 폴리곤 제거
function deletePolygon(polygons) {
    for (var i = 0; i < polygons.length; i++) {
        polygons[i].setMap(null);
    }
    polygons = [];
}
 
cs


결과물


댓글