- view.fit() 사용하여 특정 영역으로 부드럽게 이동하기 -


지도의 특정 영역으로 이동하는 방법은 찾아보면 되게 많은데


여러 방법중에 부드럽게 애니메이션을 사용하여 움직이는 방법에 대해 알아보자.


*다른 게시글에 지도 띄운 소스를 기반으로 작성함으로 그부분은 생략한다.


view 에서 fit()이라는 함수를 제공해주는데 이 함수에 애니메이션을 추가할 수 있다.


fit은 center와 zoom을 동시에 이동시켜주기에


간단하지만 굉장히 유용하다

물론 지금까지 많이 사용 안해본 내 입장에서만이다.


일단 extent를 알고 있다고 가정하에 예제를 통해 진행해보자.


▷일반적인 사용방법 (이동)


map.getView().fit(extent1);
// extent1 : [12962380.601052666, 4004207.209473483, 15290958.230732275, 4982601.171523739]
// extent2 : [14087955.176897664, 4463567.034718425, 14386612.803451654, 4589053.432430186]



이런식으로 그저 이동하는데 사용 가능하며 여기서 추가적으로


애니메이션을 삽입하여 부드럽게 이동할 수 있다.


▷애니메이션 추가한 이동


map.getView().fit(extent2,{
  duration : 500
});
// extent1 : [12962380.601052666, 4004207.209473483, 15290958.230732275, 4982601.171523739]
// extent2 : [14087955.176897664, 4463567.034718425, 14386612.803451654, 4589053.432430186]



이런식으로 두번재 매개변수에 duration을 추가해주면


아주 부드럽게 이동한다.


반응형


- 현재 지도 map 의 extent 가져오기 -


현재 보고있는 map 화면의 영역(extent) 를 가져오자


일단 지도를 띄우기 위해 코드를 작성한다.



<!doctype html>
<html lang="ko">
  <head>
    <link rel="stylesheet" 
href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css">
    <style>
      #map {
        height800px;
        width100%;
      }
    </style>
    <script 
src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js">
</script>
    <title>OpenLayers-vworld</title>
  </head>
  <body>
    <h2>OpenLayers_MAP</h2>
    <div id="map" ></div>
  </body>
    <script type="text/javascript">
     
     //기본지도
     var baseMap = new ol.layer.Tile({
            source: new ol.source.XYZ({
                 //Vworld Tile 변경
                 url: 'http://xdworld.vworld.kr:8080/2d/Base/202002/{z}/{x}/{y}.png'
             })
          });

     var map = new ol.Map({
        target : 'map',
        layers: [baseMap],
        view: new ol.View({
                center: [14126669.415892474493404.190498611],
                zoom: 7,
                minZoom: 7,
                maxZoom: 19
            })
      });

    </script>
</html>


그러면 이제 앞에 작성해왔던 게시글 처럼 기본적인 지도가 화면에 출력된다.


아래가 지도 화면이다.



여기서 이제 현재 보고 있는 영역(extent)를 뽑아보자.


명령어로 딱 한줄만 쓰면된다.


map.getView.calculateExtent()


이다.



map.getView().calculateExtent()
// [12962380.601052666, 4004207.209473483, 15290958.230732275, 4982601.171523739]



https://openlayers.org/en/latest/apidoc/module-ol_View-View.html


ol apidoc 에서 확인 가능한 하다 (문서 양이 많으니 calculateExtent로 찾아보자.)


반응형


- WMS CQL filter 사용하기 -


geoserver에서 wms 를 가져올때 필터 조건을 사용하여


조건에 맞는 부분만 가져오는 방법에 대해 알아보자.


그냥 기존에 가져와서 사용하던 방식에서


params부분에 "CQL_FILTER"를 추가해서 넣어주기만 하면 된다.

(윗부분은 항상 동일하니 script부분만 정리한다.)


var sig = new ol.layer.Tile({
title : 'SIG',
source : new ol.source.TileWMS({
url : 'http://192.168.200.200:8080/geoserver/mine/wms',
params:{
'VERSION': '1.1.0',
'LAYERS' : 'mine:SIG',
'BBOX':[746110.2515145557,1458754.0441563274,1387947.6818815223,2068443.9546290115],
'SRS' : 'EPSG:5179',
'FORMAT': 'image/png',
},
serverType : 'geoserver'
})
});

위에 보여주는 것은 cql_filter를 적용하지 않고 예시로 시군구단위의 지도를 띄운것이다.


이제 여기서 filter를 적용시켜보자.


var sig = new ol.layer.Tile({
title : 'SIG',
source : new ol.source.TileWMS({
url : 'http://192.168.200.200:8080/geoserver/mine/wms',
params:{
'VERSION': '1.1.0',
'LAYERS' : 'mine:SIG',
'BBOX':[746110.2515145557,1458754.0441563274,1387947.6818815223,2068443.9546290115],
'SRS' : 'EPSG:5179',
'FORMAT': 'image/png',
'CQL_FILTER' : 'SIG_CD IN (43750,43770,43130,43150,43800,43760,43745,43114,43113,43112,43111,43720,43730,43740)'
},
serverType : 'geoserver'
})
});

필터를 적용하여 충북지역만 뽑아봤다.


CQL_FILTER를 보면 알겠지만 해당 wms가 가지고있는 

속성정보에서 filter를 적용시키는것을 잊지말자.


반응형


- x,y 좌표계 변경하기 from EPSG:4326 to EPSG:3857 -


API 기능을 통해 x,y 좌표를 받아왔는데


이 좌표를 사용하여 지도를 움직이고자 하는데 좌표계가 맞지않아 바꿔야 하는 상황이다.


이번 역시 결과적으로 매우 간단한 코드가 나와서 다행이다.


var center = ol.proj.transform([lon,lat],'EPSG:4326','EPSG:3857')
map.getView().setCenter(center);


변환 자체는 ol.proj.transform 한줄이면 끝나고


그걸 사용하여 openlayers의 지도를 이동해주는 코드이다.


변경 전/후를 비교해보면 다음과 같다.



같은 방식으로 다른 x,y 좌표계 역시도 변경할 수 있을것으로 보인다.


반응형
  1. 익명 2021.09.12 21:03

    비밀댓글입니다

    • 2021.09.13 20:20

      비밀댓글입니다


- OpenLayers import GeoJSON -


앞서 정리한 글에서 geoJson export를 해봤는데

여기서 export한 geojson 즉 json파일을 import해보도록하자

(파일로 추출은 안해봤지만 했다는 가정하에 파일을 읽어보도록한다.)


testGeo2.json


geojson으로 추출한 정보가 들어있는 이 .json파일을 가지고 해볼것이다.


<!doctype html>
<html lang="ko">
<head>
<!-- OpenLayers -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>

<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<style>
#map {height: 800px; width: 100%;}
</style>
<title>OpenLayers-vworld</title>
</head>
<body>
<h2>OpenLayers_MAP</h2>
<div id="map" ></div>
<select id="type">
<option value="Point">Point</option>
<option value="LineString">LineString</option>
<option value="Polygon">Polygon</option>
<option value="Circle">Circle</option>
<option value="None" selected>None</option>
</select>
<button type="button" class="exportBtn" ><span>getGeoJSON</span></button>
<button type="button" onclick="importJson()"><span>setGeoJSON</span></button>
</body>
<script type="text/javascript">

//기본지도
var vwBaseLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://xdworld.vworld.kr:8080/2d/Base/202002/{z}/{x}/{y}.png'
})
});

var map = new ol.Map({
target : 'map',
layers: [vwBaseLayer],
view: new ol.View({
center: [14126669.41589247, 4493404.190498611],
zoom: 7,
minZoom: 7,
maxZoom: 19
})
});

var typeSelect = document.getElementById('type');
var draw;
typeSelect.onchange = function () {
map.removeInteraction(draw);
addInteraction();
};

// Add over interaction that draw hull in a layer
var source = new ol.source.Vector({ wrapX: false });
var vector = new ol.layer.Vector({
title : 'vector',
source: source, });

map.addLayer(vector); //vector layer add

function addInteraction() {
var value = typeSelect.value;
if (value !== 'None') {
draw = new ol.interaction.Draw({
source: source,
type: value
});
map.addInteraction(draw);
}
}

//GeoJson export
$(".exportBtn").click(function(){
var newfeatures = [];
var projection = ol.proj.get('EPSG:3857'); // from 3857
vector.getSource().forEachFeature(function(feature) {
var clone = feature.clone();
clone.setId(feature.getId()); // clone does not set the id
clone.getGeometry().transform(projection, 'EPSG:4326'); // to EPSG:4326
newfeatures.push(clone);
});
var json = new ol.format.GeoJSON().writeFeatures(newfeatures);
console.log(json);
});

var vector2;
function importJson(){
// Earthquake layer
var vectorSource = new ol.source.Vector({
url: '../testGeo2.json',
projection: 'EPSG:4326',
format: new ol.format.GeoJSON(),
});

vector2 = new ol.layer.Vector({
source: vectorSource
});

map.addLayer(vector2);
}
</script>
</html>


importJson() 메소드를 통해서 json 파일을 읽어보려한다.

읽는방법 자체는 간단하다 ol.source.Vector 에서 url 과 format을 설정해주고


vector layer를 생성한 후 maplayer에 넣어주면 된다.


그러면 아래와 같이 json에 저장되어있는 데이터를 읽어서

지도에 표시가된다.




읽는 방법은 간단하나 vector layer를 하나만 계속 쓰고 싶은데


이것역시 아직 해보질 않아서 여기까지만 정리해둔다.


반응형
  1. 익명 2021.09.07 10:35

    비밀댓글입니다

    • 2021.09.07 20:33

      비밀댓글입니다


- 도형으로 그린 피처 정보 GeoJSON으로 추출하기 -


직접 그린 도형들을 geojson 형태로 추출하여 저장해야 하는 경우가 생길수 있다.


geojson은 간단하게 json 에서 위치정보를 가진것을 geojson이라 생각하고 넘어가자


다행히 json형태로 정보를 추출하는건


openlayers - extension 에


예제가 존재하기 때문에 보고 가져다 사용하면 된다.


https://viglino.github.io/ol-ext/examples/bar/map.control.editionbar.html


<!doctype html>
<html lang="ko">
<head>
<!-- OpenLayers -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>

<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<style>
#map {height: 800px;width: 100%;}
</style>
<title>OpenLayers-vworld</title>
</head>
<body>
<h2>OpenLayers_MAP</h2>
<div id="map" ></div>
<select id="type">
<option value="Point">Point</option>
<option value="LineString">LineString</option>
<option value="Polygon">Polygon</option>
<option value="Circle">Circle</option>
<option value="None" selected>None</option>
</select>
<button type="button" class="exportBtn" ><span>getGeoJSON</span></button>
</body>
<script type="text/javascript">

//기본지도
var vwBaseLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://xdworld.vworld.kr:8080/2d/Base/202002/{z}/{x}/{y}.png'
})
});

var map = new ol.Map({
target : 'map',
layers: [vwBaseLayer],
view: new ol.View({
center: [14126669.41589247, 4493404.190498611],
zoom: 7,
minZoom: 7,
maxZoom: 19
})
});

var typeSelect = document.getElementById('type');
var draw;
typeSelect.onchange = function () {
map.removeInteraction(draw);
addInteraction();
};

// Add over interaction that draw hull in a layer
var source = new ol.source.Vector({ wrapX: false });
var vector = new ol.layer.Vector({
title : 'vector',
source: source, });

map.addLayer(vector); //vector layer add

function addInteraction() {
var value = typeSelect.value;
if (value !== 'None') {
draw = new ol.interaction.Draw({
source: source,
type: value
});
map.addInteraction(draw);
}
}

//GeoJson export
$(".exportBtn").click(function(){
var json = new ol.format.GeoJSON().writeFeatures(vector.getSource().getFeatures());
console.log(json);
});
</script>
</html>

이 앞에서 그리기 관련 게시글을 작성했던 소스와 별반 차이는 없지만


마지막에 new ol.format.GeoJson()... 이 한줄이 

GeoJSON으로 vector 레이어에 그려진 피쳐들을 추출하는 코드이다.


아래 그림을 통해 결과를 보도록 하자.



콘솔에 찍히도록 해놨는데 찍힌것을 보니 폴리곤 1개, 라인스트링 1개, 포인트4개

이렇게 전부 좌표정보와 함께 추출된것을 확인이 가능하다.


여기서 하나 의문이 생길수 있는게 왜 circle은 없는가? 이다.


전 게시글에서 언급했지만 circle을 일반적으로 그리면 반경으로 그리기 때문에

geoJson이나 kml을 통해 추출이 불가능하다.


그래서 polygon 형태로 최대한 원에 가깝게 그려줘야 추출이 가능하다.

(이부분은 속성정보 추출과 함께 추후 정리할 예정이다.)


이제 저 결과를 보면 좌표계가 우리가 원하는 좌표계로 바꿔줘야하는데


그럴경우 소스코드를 조금 손봐야한다.


//GeoJson export
$(".exportBtn").click(function(){
var newfeatures = [];
var projection = ol.proj.get('EPSG:3857'); // from 3857
vector.getSource().forEachFeature(function(feature) {
var clone = feature.clone();
clone.setId(feature.getId()); // clone does not set the id
clone.getGeometry().transform(projection, 'EPSG:4326'); // to EPSG:4326
newfeatures.push(clone);
});
var json = new ol.format.GeoJSON().writeFeatures(newfeatures);
console.log(json);
});


clone을 이용하여 복제한 다음에 3857에서 4326으로 변경하여

배열에 담아둔뒤 담아둔 정보들을 GeoJSON으로 변경하는 과정이다.


그러면 다음과같이 우리가 잘 알고있는 좌표계로 변경된다.

(소스코드 변경때문에 도형을 다시 그렸기때문에 좌표가 다르다.)



geojson export 는 이런식으로 진행되며


추출은 했지만 실제로 파일로 만드는 부분은 해보지 않아서


나중에 하게 되면 정리할 예정이다.


반응형