반응형

저번 포스팅에서 좌표가 포함된 csv 파일을 읽어 포인트 레이어로 추가했었다.

 

데이터가 10개 정도여서 보기에 큰 불편함은 없었다. 하지만 포인트가 수천 개에서 수만 개라면 어떻게 처리해야 할까?

 

수천 개의 포인트의 지도에 그린다면 빼곡히 포인트만 보이고 배경지도는 가려질 수 있다.

 

그래서 어느 특정 레벨에서는 그룹핑된 포인트의 수를 보여주고 레벨이 커질수록 포인트 객체를 보여주는 cluster에 대해 알아보도록 하겠다.

 

저번 포스팅에 썼던 예제를 계속해서 활용해서 진행해보려고 한다. 단위 기능만 구현하다 보니 실제 수천 개의 객체에 대해 테스트해보지는 않았겠지만 사용법만 숙지하면 별 탈 없이 활용할 수 있을 것이다.

 

<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css" type="text/css">
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>openlayers - dev-jhs</title>
  </head>
  <body>
    <h2>오픈 레이어스 브이월드 마우스 클릭 포인트 벡터레이어 생성 에제</h2>
    <div id="map" class="map" style="width:100%;height:80%;"></div>
		<span id="textupdate"><span>
    <script>
    //브이월드 타일레이어 url 설정s
    var source =new ol.source.XYZ({
                    url: 'http://xdworld.vworld.kr:8080/2d/Base/201802/{z}/{x}/{y}.png'
                });
		
    //타일레이어 생성하기
    var viewLayer = new ol.layer.Tile({
                        source:source
                    });
    
    //위치는 우리나라 중앙쯤(?)
    var view = new ol.View({
                  center:[14248656.389982047, 4331624.063626864],
                  zoom:12,
               });

    var mapView = new ol.Map({
                      target:"map", // 지도를 생성할 element 객체의 id 값,
                      layers:[viewLayer], //생성한 레이어 추가,
                      view:view,	//view 설정
                  });
   
    $.ajax({
        url:'./lib/csvTest.csv',
        type:'get',
        dataType:'text',
        success:function(data){
            var records = data.split("\n");

            var lonIndx=0;
            var latIndx=0;
       
            //경위도 인덱스 찾기
            for(var i=0;i<records.length;i++){
                var parse = records[i].split(",");

                for(var j=0;j<parse.length;j++){
                    if(parse[j]=="경도"){
                        lonIndx=j;
                    }

                    if(parse[j]=="위도"){
                        latIndx=j;
                    }
                }
            }
      
            var lonArr=[];
            var latArr=[];
            var pointFeatureArr = []; 
            
            //포인트 객체 생성하기
            for(var i=1;i<records.length;i++){
                var record = records[i].split(",");
                var lon= record[lonIndx];
                var lat = record[latIndx];
         
                //경위도 좌표를 EPSG:3857로 변경하기
                var point4326 = [lon,lat];
                var point3857 = ol.proj.transform(point4326,"EPSG:4326","EPSG:3857");
                var point = new ol.geom.Point(point3857);
        
                //point label 및 스타일 지정하기
                var pointFeature = new ol.Feature(point);
        
                pointFeatureArr.push(pointFeature);
            }

            var pointSourceLayer = new ol.source.Vector({
                                        features:pointFeatureArr
                                   });

            var clusterSource =new ol.source.Cluster({
                                   distance:30,
                                   source:pointSourceLayer
                               });
      
            var styleCache={};
            var clusterLayer = new ol.layer.Vector({
                                   source:clusterSource,
                                   zIndex:99999,
                                   style: function(feature) {
                                       var clusterFea = feature.get('features');
                                       var size = feature.get('features').length;
                                       var style = styleCache[size];

                                       if (!style) {
                                           if(size.toString() == "1"){//포인트 갯수가 하나일 때 스타일 지정
                                               style= new ol.style.Style({
                                                   image: new ol.style.Circle({
                                                       radius: 8,
                                                       fill: new ol.style.Fill({color: 'blue'}),
                                                   }),
                                                   text:new ol.style.Text({
                                                       text:record[0],
                                                       offsetY:12
                                                   })  
                                              });
                                       }else{
                                            style = new ol.style.Style({//cluster style 지정
                                                image: new ol.style.Circle({
                                                    radius: 22,
                                                    stroke: new ol.style.Stroke({
                                                        color: '#fff'
                                                    }),
                                                    fill: new ol.style.Fill({
                                                        color: 'rgba(144,202,75,1)'
                                                    })
                                                }),
                                                text: new ol.style.Text({
                                                    text: size.toString(),
                                                    fill: new ol.style.Fill({
                                                        color: '#fff'
                                                    }),
                                                    scale:1.5
                                                })
                                            });
                                            
                                            styleCache[size] = style;
                                          }

                                     }
                                    return style;
                                }
                          });
 
      mapView.addLayer(clusterLayer);
      mapView.getView().setCenter([14309209.0797486,4278704.08358673])
     }
   })
    </script>
  </body>
</html>

 

전체 소스는 아래 링크를 참조하면 된다.

plnkr.co/edit/N1IOhDgNHeAnAREH

 

Plunker - Csv to point openlayers

Plunker is loading… Get your fork on.

plnkr.co

 

반응형

+ Recent posts