- OpenLayers를 여행하는 개발자를 위한 안내서 - 25. WebGL로 초대용량 데이터 표시하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 24. Heat Map 표현하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 23. Cluster Map 표현하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 22. WFS Transaction으로 데이터 삭제하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 21. WFS Transaction으로 데이터 수정하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 20. WFS Transaction으로 데이터 추가하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 19. WMS에 팝업 붙이기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 18. WFS에 팝업 붙이기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 17. WFS 객체에 상호작용 추가하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 16. WMS GetImage를 사용하여 지도에 이미지 표시하기
👀 OpenLayers를 여행하는 개발자를 위한 안내서 - 15. WFS GetFeature를 사용하여 지도에 객체 표시하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 14. 지도에 사용자의 위치 표시하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 13. 브라우저에서 사용자 위치정보 수집하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 12. 맵의 유용한 정보 표시하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 11. VWorld 맵 만들기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 10. Open Street Map(OSM) 맵 만들기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 9. 데이터 필터링하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 8. 공간정보 데이터를 주문하는 법. OGC
- OpenLayers를 여행하는 개발자를 위한 안내서 - 7. 공간정보 데이터를 관리하는 법. GeoServer
- OpenLayers를 여행하는 개발자를 위한 안내서 - 6. 공간정보의 DB화
- OpenLayers를 여행하는 개발자를 위한 안내서 - 5. OpenLayers
- OpenLayers를 여행하는 개발자를 위한 안내서 - 4. QGIS 체험하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 3. 좌표계
- OpenLayers를 여행하는 개발자를 위한 안내서 - 2. GIS랑 인사하기
- OpenLayers를 여행하는 개발자를 위한 안내서 - 1. 머릿말
Table of Contents
WFS 🔗
지금까지는 온전히 OpenLayers만의 기능이였다면, 이 장부터 슬슬 GeoServer와의 연동을 다루게 된다.
그 중 첫 번째로 다룰 기능은, WFS다. GeoServer에서 WFS는 지정한 요소의 정보를 GeoJSON의 형태로 반환해준다. 이 정보를 적절히 활용하여 지도에 표시할 수 있다.
이러한 기능을 통해 직접 관리하거나 가공한 데이터를 지도에 표시할 수 있다.
WFS를 활용하여 지도에 표시하기 🔗
WFS를 표시하기 위해, 총 5개 객체가 필요하다. 각각 WFS의 결과인 GeoJSON을 담을 VectorSource
, VectorSource
를 활용하여 지도를 렌더링하는 VectorLayer
, 나머지 View
와 Map
객체가 그것이다. 추가로 Style
객체의 표현 방식을 기술할 수 있다.
이 5가지 요소를 구현하는 방법을 차례로 설명하여, 최종적으로 WFS를 활용한 지도를 만든다.
1. GetFeature URL 구성하기 🔗
GeoServer를 통해 데이터를 구축했으므로, GeoServer가 해당 레이어의 WFS 요청을 처리할 수 있다. WFS 호출 URL을 구성해보자.
WFS 중에서도, 속성정보를 제공하는 GetFeature
를 사용한다. GetFeature
의 요청방법은 아래와 같다.
TXT
0 | GET https://example.com/geoserver/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=test:building&srsName=EPSG:3857&outputFormat=application/json&bbox=14168809.936013725,4366042.924151548,14170735.193663657,4367768.7289308,EPSG:3857 |
Parameter | Example | Require | Description |
---|---|---|---|
service | WFS (고정) | Y | 서비스명 |
version | 2.0.0 (기본), 1.1.0, 1.0.0 | Y | 버전 |
request | GetFeature (고정) | Y | 요청명 |
typename | repo_name:layer_name | Y | 레이어명 (다수는 쉼표로 구분) |
srsName | EPSG:4326 | 기준 좌표계 (비울 경우 레이어의 기본 좌표계로 표시) | |
outputFormat | application/vnd.ogc.se_xml (기본) | 응답 형식 | |
exceptions | application/vnd.ogc.se_xml (기본) | 예외 응답 형식 | |
propertyName | 전체 컬럼 | 응답에 포함할 컬럼명 (다수의 경우 쉼표로 구분) | |
bbox | ,EPSG:0000 | 제한할 범위 | |
featureID | {id} | Feature ID |
본인이 구성한 레이어의 정보에 맞게 URL을 구성하자.
2. VectorSource 생성하기 🔗
OpenLayers의 VectorSource
객체는 입력받은 GeoJSON을 직접 해석할 수 있다. 덕분에 잘 구성된 GeoJSON이라면, 별도의 설정이나 매핑과정 없이 간편하게 적용이 가능하다.
위에서 생성한 WFS URL을 토대로 VectorSource
를 생성한다.
TYPESCRIPT
0 | import { Vector as VectorSource } from 'ol/source'; |
1 | import { GeoJSON } from 'ol/format'; |
2 | import { bbox } from 'ol/loadingstrategy'; |
3 | |
4 | const wfs = new VectorSource({ |
5 | format: new GeoJSON(), |
6 | url: (extent) => `https://example.com/geoserver/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=test:building&srsName=EPSG%3A3857&outputFormat=application%2Fjson&exceptions=application%2Fjson&bbox=${extent[0]}%2C${extent[1]}%2C${extent[2]}%2C${extent[3]}%2CEPSG%3A3857`, |
7 | strategy: bbox |
8 | }); |
VectorSource
에 대한 전체 정보는 공식 문서에서 확인할 수 있다.
원래 Vector
지만, 좀 더 명확한 표현을 위해 VectorSource
로 명칭을 변경했다.
VectorSource
는 JSON 형태로 원하는 옵션을 설정할 수 있는데, 위 설정은 가장 기초적인 설정값을 입력한 것이다.
Name | Type | Default | Description |
---|---|---|---|
attributions | ol/source/Source-AttributionLike | undefined |
기여 문구 (지도 우측 하단) | |
features | Array<ol/Feature-Feature> | ol/Collection-Collection<ol/Feature-Feature> | undefined |
Feature 배열 |
|
format | ol/format/Feature-FeatureFormat | undefined |
URL 데이터 로더가 데이터를 인식하기 위해 사용하는 포맷. url 을 설정했을 경우 필수 |
|
loader | ol/featureloader-FeatureLoader | undefined |
로더 메서드. 지정하지 않을 경우 기본 로더가 사용됨.features load end 및 features load error 이벤트는 성공 및 실패 콜백을 사용하는 경우에만 발생 |
|
overlaps | boolean |
true |
중첩된 지오메트리에 대한 처리 방식.false 일 경우, 렌더러가 지오메트리의 경계 및 채우기 작업을 최적화함 |
strategy | ol/source/Vector-LoadingStrategy | undefined |
데이터 렌더링 전략. 기본적으로 ol/loadingstrategy.all를 사용하며, 이는 모든 Feature 를 한 번에 로드함 |
|
url | string | ol/featureloader-FeatureUrlFunction | undefined |
데이터 URL | |
useSpatialIndex | boolean |
true |
공간 인덱스 사용 여부. 피쳐의 변경이 잦거나 수가 적을 경우, false 로 두면 속도가 향상된다. |
wrapX | boolean |
true |
수직 감싸기 여부 |
url
에 할당된 URL에 접근하면, 조건에 맞는 GeoJSON을 반환해준다. VectorSource
의 format
이 GeoJSON이므로, 데이터 해석이 가능하다.
현재 바라보는 지도의 영역을 기준으로 로딩하므로, 지도의 영역에 해당하는 데이터를 호출하기 용이하다.
그 외 사용할 수 있는 옵션과 메서드의 종류는 ol/source/Vector-VectorSource에서 확인하자.
2-1. WFS URL 직관적으로 생성하기 🔗
TYPESCRIPT
0 | const url = `https://example.com/geoserver/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=test:building&srsName=EPSG%3A3857&outputFormat=application%2Fjson&exceptions=application%2Fjson&bbox=${extent[0]}%2C${extent[1]}%2C${extent[2]}%2C${extent[3]}%2CEPSG%3A3857` |
URL이 위와 같이 구성될 경우, URL의 구성 결과를 확인하기 용이하지만 각 데이터가 한 눈에 들어오지는 않는다. 이런 형태는 오타같은 작은 실수를 놓치기 쉽고, URL을 직접 구성하는 것 또한 피곤하다.
이를 해결하기 위해, JSON 형태로 데이터를 전달받아, 이를 URL Query 형태로 바꿔주는 메서드를 생성했다.
TYPESCRIPT
0 | /** |
1 | * URL 빌더 메서드 |
2 | * |
3 | * @param {string} host: 호스트 |
4 | * @param {{ [ key: string ]: string | number | boolean | undefined }} query: 쿼리 파라미터 |
5 | * |
6 | * @returns {string} URL |
7 | */ |
8 | export function urlBuilder(host: string, query: { [ key: string ]: string | number | boolean | undefined }) |
9 | { |
10 | const param = Object.entries(query).map(([ key, value ]) => value ? `${key}=${encodeURIComponent(value)}` : '').join('&'); |
11 | |
12 | return `${host}?${param}`; |
13 | } |
14 | |
15 | // https://example.com/geoserver/wfs?name=steve&age=18&actived=true |
16 | urlBuilder('https://example.com/geoserver/wfs', { |
17 | name: 'steve', |
18 | age: 18, |
19 | actived: true |
20 | }); |
host
: 쿼리를 사용할 대상 URLhttps://example.com/test?query=1
에서?
앞의 주소 부분
query
: JSON 객체
위 메서드를 사용하면, WFS의 url
부분을 아래와 같이 변경할 수 있다.
TYPESCRIPT
0 | const url = (extent) => `https://example.com/geoserver/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=test:building&srsName=EPSG%3A3857&outputFormat=application%2Fjson&exceptions=application%2Fjson&bbox=${extent[0]}%2C${extent[1]}%2C${extent[2]}%2C${extent[3]}%2CEPSG%3A3857`; |
1 | |
2 | const advanced = (extent) => urlBuilder('https://example.com/geoserver/wfs', { |
3 | service: 'WFS', |
4 | version: '2.0.0', |
5 | request: 'GetFeature', |
6 | typename: 'test:building', |
7 | srsName: 'EPSG:3857', |
8 | outputFormat: 'application/json', |
9 | exceptions: 'application/json', |
10 | bbox: `${extent.join(',')},EPSG:3857` |
11 | }); |
url
과 advanced
를 비교하면, advanced
쪽이 훨씬 직관적임을 확인할 수 있다.
3. VectorLayer 생성하기 🔗
OpenLayers의 VectorLayer
객체는 VectorSource
객체를 통해 지도를 렌더링한다. 벡터 지도는 단순 그림이 아니라, JS 상에서 일종의 DOM의 형태로 렌더링되기 때문에, 브라우저 상에서 인식이 가능한 실체화된 객체다.
TYPESCRIPT
0 | import { Vector as VectorLayer } from 'ol/layer'; |
1 | |
2 | const wfsLayer = new VectorLayer({ |
3 | source: wfs, |
4 | minZoom: 15, |
5 | zIndex: 5, |
6 | properties: { name: 'wfs' } |
7 | }); |
Name | Type | Default | Description |
---|---|---|---|
className | string |
ol-layer |
클래스명 |
opacity | number |
1 |
투명도 (0 ~ 1) |
visible | boolean |
true |
표시 여부 |
extent | ol/extent-Extent | undefined |
레이어의 렌더링 범위. 해당 범위를 넘어가면 데이터를 표시하지 않음 | |
zIndex | number | undefined |
우선 순위 (높을수록 위에 표시) | |
minResolution | number | undefined |
최소 표시 해상도 | |
maxResolution | number | undefined |
최대 표시 해상도 | |
minZoom | number | undefined |
최소 표시 줌 레벨 | |
maxZoom | number | undefined |
최대 표시 줌 레벨 | |
renderOrder | ol/render-OrderFunction | undefined |
Feature 의 렌더링 순서 정렬 |
|
renderBuffer | number |
100 | 현재 영역의 버퍼 크기 버퍼가 100일 경우, 현재 영역에서 100만큼 더 넓은 영역의 Feature 를 렌더링 |
source | (ol/source/Vector-VectorSource | ol/source/VectorTile-VectorTile) | undefined |
레이어의 소스 | |
map | ol/PluggableMap-PluggableMap | undefined |
지정한 Map 객체에서 해당 레이어를 오버레이로 사용 |
|
declutter | boolean |
false |
지도의 이미지, 텍스트의 분해 미사용 여부 |
style | ol/style/Style-StyleLike | null | undefined |
레이어 스타일. null 일 경우 고유 스타일을 가진 Feature 만 렌더링됨기본 스타일은 ol/style/Style-Style 참조 |
|
background | ol/layer/Base-BackgroundColor | undefined |
레이어의 배경색. 지정하지 않을 경우 투명 | |
updateWhileAnimating | boolean |
false |
true 일 경우, 애니메이션 과정에서 Feature 배치가 재생성됨. Feature 가 많을 경우 성능이 저하될 우려가 있음false 일 경우, 애니메이션이 끝나고 배치가 재생성됨 |
updateWhileInteracting | boolean |
true |
true 일 경우, 상호작용 과정에서 Feature 배치가 재생성됨. updateWhileAnimating 옵션과 비슷함 |
properties | object | undefined |
임의 속성. get() , set() 으로 조작 가능 |
VectorLayer
에 대한 전체 정보는 ol/layer/Vector-VectorLayer에서 확인할 수 있다.
4. View 만들기 🔗
지도의 뷰잉 정보를 선언할 View 객체를 생성한다.
TYPESCRIPT
0 | import View from 'ol/View'; |
1 | import proj4 from 'proj4'; |
2 | |
3 | const view = new View({ |
4 | projection: 'EPSG:3857', |
5 | center: proj4('EPSG:4326', 'EPSG:3857', [ 127.28923267492068, 36.48024986578043 ]), |
6 | zoom: 17 |
7 | }); |
Name | Type | Default | Description |
---|---|---|---|
center | ol/coordinate-Coordinate | undefined |
지도의 중심 | |
constrainRotation | boolean | number |
true |
회전 구속 여부. 숫자일 경우 회전 가능 갯수를 의미 (0일 경우, 90, 180, 270, 360) |
enableRotation | boolean |
true |
회전 가능 여부 |
extent | ol/extent-Extent | undefined |
지도의 뷰잉 범위. 지정된 범위 밖을 벗어날 수 없음 | |
constrainOnlyCenter | boolean |
false |
true 일 경우 extent 제한이 View 중심에만 적용되며, 전체 extent에 적용되지 않음 |
smoothExtentConstraint | boolean |
true |
View가 extent 범위를 약간 벗어날 수 있는지 여부 |
maxResolution | number | undefined |
최대 뷰잉 해상도. 지정 해상도 이상 확대 불가능. | |
minResolution | number | undefined |
최소 뷰잉 해상도. 지정 해상도 이상 축소 불가능. | |
maxZoom | number |
28 |
최대 뷰잉 줌 레벨. 지정 줌 레벨 이상 확대 불가능. |
minZoom | number |
0 |
최소 뷰잉 줌 레벨. 지정 줌 레벨 이상 축소 불가능. |
multiWorld | boolean |
false |
다중 월드 사용 여부 |
constrainResolution | boolean |
false |
줌 레벨 정수만 허용 여부 |
smoothResolutionConstraint | boolean |
true |
느슨한 확대/축소 규칙 사용 여부 |
showFullExtent | boolean |
false |
전체 구성된 extent 표시 여부 |
projection | ol/proj-ProjectionLike | EPSG:3857 |
좌표계 |
resolution | number | undefined |
초기 해상도 | |
resolutions | Array<number> | undefined |
사용 가능한 해상도 목록 (내림차순) max/minResolution , max/minZoom , zoomFactor 옵션이 무시됨 |
|
rotation | number |
0 |
기본 회전값 |
zoom | number | undefined |
기본 줌 레벨 | |
zoomFactor | number |
2 |
줌 배율 |
padding | Array<number> |
[ 0, 0, 0, 0 ] |
패딩 |
4-1. 좌표 변환하기 🔗
[ 127.28923267492068, 36.48024986578043 ]
는 세종시청의 경위도(EPSG:4326) 좌표다. 하지만 이 문서에서 다루는 좌표는 Google 좌표계(EPSG:3857)이다. 좌표체계가 다르므로 이에 맞춰 변환이 필요하다.
proj4
를 활용하면 좌표변환을 쉽게 구현할 수 있다.
TYPESCRIPT
0 | import proj4 from 'proj4'; |
1 | |
2 | // 경위도 좌표를 EPSG:5179로 변환 |
3 | const xy: number[] = proj4('EPSG:4326', 'EPSG:5179', [ 127.28923267492068, 36.48024986578043 ]); |
위 코드는 세종시청 EPSG:4326 경위도 좌표를 EPSG:5179로 변환하는 코드다. 이와 같은 방식으로 기존의 좌표계를 다른 좌표계로 변환할 수 있다.
5. Style 정의하기 🔗
지도에 객체를 표시할 때, 원하는 모양으로 객체가 렌더링되게끔 지정할 수 있다.
공간정보 데이터 형식에 따라 기술되는 형태가 조금씩 다르다.
Layer
객체에 지정하여 레이어에 포함된 모든 객체에 일괄로 적용하거나, Feature
마다 스타일을 지정할 수도 있다.
TYPESCRIPT
0 | // 벡터 레이어 객체 |
1 | const wfsLayer = new VectorLayer({ |
2 | source: wfs, |
3 | // 스타일 지정 가능 |
4 | style: {}, |
5 | minZoom: 15, |
6 | zIndex: 5, |
7 | properties: { name: 'wfs' } |
8 | }); |
VectorLayer
의 경우 옵션에서 스타일 객체를 할당할 수 있다. Object
형태로 바로 적용하거나, (feature) => {}
와 같이 콜백 메서드 형태로 사용할 수도 있다.
Object
형태와 다르게 콜백 메서드 형태를 사용하면, Feature
의 데이터를 토대로 스타일을 가변적으로 작성할 수 있다. 마커에 각 Feature
의 이름 혹은 주소를 표시한다던가, 값별로 스타일을 나눠 표시할 수 있다.
단, 스타일 분기 처리의 경우, filter
옵션을 활용하여 해당되는 Feature
만 간추리는 것이 더 쉽고 빠르다.
Point
데이터의 경우, 기본적으로 아래와 같이 작성할 수 있다.
TYPESCRIPT
0 | import { Feature } from 'ol'; |
1 | import Geometry from 'ol/geom/Geometry'; |
2 | import RenderFeature from 'ol/render/Feature'; |
3 | import Circle from 'ol/style/Circle'; |
4 | import Fill from 'ol/style/Fill'; |
5 | import Stroke from 'ol/style/Stroke'; |
6 | import Style from 'ol/style/Style'; |
7 | import Text from 'ol/style/Text'; |
8 | |
9 | /** |
10 | * 스타일 반환 메서드 |
11 | * |
12 | * @param {RenderFeature | Feature<Geometry>} feature: Feature |
13 | * |
14 | * @returns {Style} 스타일 |
15 | */ |
16 | function getStyle(feature: RenderFeature | Feature<Geometry>) |
17 | { |
18 | return new Style({ |
19 | image: new Circle({ |
20 | stroke: new Stroke({ |
21 | color: 'rgba(3, 102, 53, 1)', |
22 | width: 2 |
23 | }), |
24 | fill: new Fill({ |
25 | color: 'rgba(3, 102, 53, 0.6)' |
26 | }), |
27 | radius: 20 |
28 | }), |
29 | text: new Text({ |
30 | font: '0.8rem sans-serif', |
31 | fill: new Fill({ color: 'white' }), |
32 | stroke: new Stroke({ |
33 | color: 'rgba(0, 0, 0, 1)', |
34 | width: 4 |
35 | }), |
36 | text: feature.get('address') |
37 | }) |
38 | }); |
39 | } |
image
: 포인트 스타일stroke
: 포인트 테두리fill
: 포인트 배경색radius
: 반지름
text
: 텍스트 스타일font
: 텍스트 폰트stroke
: 텍스트 테두리fill
: 텍스트 색text
: 텍스트 값
getStyle
메서드는 Feature
를 인자로 받아 스타일을 반환한다. Layer
옵션에서 style: (feature) => getStyle(feature)
와 같이 사용할 수 있다.
TYPESCRIPT
0 | import { Feature } from 'ol'; |
1 | import Geometry from 'ol/geom/Geometry'; |
2 | import RenderFeature from 'ol/render/Feature'; |
3 | import { Icon } from 'ol/style'; |
4 | import Fill from 'ol/style/Fill'; |
5 | import Stroke from 'ol/style/Stroke'; |
6 | import Style from 'ol/style/Style'; |
7 | import Text from 'ol/style/Text'; |
8 | |
9 | /** |
10 | * 스타일 반환 메서드 |
11 | * |
12 | * @param {RenderFeature | Feature<Geometry>} feature: Feature |
13 | * |
14 | * @returns {Style} 스타일 |
15 | */ |
16 | function getStyle(feature: RenderFeature | Feature<Geometry>) |
17 | { |
18 | return new Style({ |
19 | image: new Icon({ |
20 | src: 'https://t1.daumcdn.net/cfile/tistory/99857F4F5E738F472F', |
21 | scale: 0.05 |
22 | }), |
23 | text: new Text({ |
24 | font: '0.8rem sans-serif', |
25 | fill: new Fill({ color: 'white' }), |
26 | stroke: new Stroke({ |
27 | color: 'rgba(0, 0, 0, 1)', |
28 | width: 4 |
29 | }), |
30 | text: feature.get('address') |
31 | }) |
32 | }); |
33 | } |
반대로 Icon
객체를 활용하여 단색이 아닌 외부 이미지를 활용할 수도 있다.
Polygon
데이터는 아래와 같이 기술한다.
TYPESCRIPT
0 | import { Feature } from 'ol'; |
1 | import Geometry from 'ol/geom/Geometry'; |
2 | import RenderFeature from 'ol/render/Feature'; |
3 | import Fill from 'ol/style/Fill'; |
4 | import Stroke from 'ol/style/Stroke'; |
5 | import Style from 'ol/style/Style'; |
6 | import Text from 'ol/style/Text'; |
7 | |
8 | /** |
9 | * 스타일 반환 메서드 |
10 | * |
11 | * @param {RenderFeature | Feature<Geometry>} feature: Feature |
12 | * |
13 | * @returns {Style} 스타일 |
14 | */ |
15 | function getStyle(feature: RenderFeature | Feature<Geometry>) |
16 | { |
17 | return new Style({ |
18 | stroke: new Stroke({ |
19 | color: 'rgba(100, 149, 237, 1)', |
20 | width: 2 |
21 | }), |
22 | fill: new Fill({ |
23 | color: 'rgba(100, 149, 237, 0.6)' |
24 | }), |
25 | text: new Text({ |
26 | font: '0.8rem sans-serif', |
27 | fill: new Fill({ color: 'white' }), |
28 | stroke: new Stroke({ |
29 | color: 'rgba(0, 0, 0, 1)', |
30 | width: 4 |
31 | }), |
32 | text: feature.get('address') |
33 | }) |
34 | }); |
35 | } |
image
옵션이 제외되고, stroke
와 fill
옵션을 사용하여 도형의 스타일을 구성할 수 있다.
6. Map 만들기 🔗
모든 정보를 종합하여 지도를 만드는 Map 객체를 생성한다.
TYPESCRIPT
0 | import Map from 'ol/Map'; |
1 | import { Vector as VectorSource } from 'ol/source'; |
2 | import { GeoJSON } from 'ol/format'; |
3 | import { bbox } from 'ol/loadingstrategy'; |
4 | import { Vector as VectorLayer } from 'ol/layer'; |
5 | import View from 'ol/View'; |
6 | import proj4 from 'proj4'; |
7 | import { Feature } from 'ol'; |
8 | import Geometry from 'ol/geom/Geometry'; |
9 | import RenderFeature from 'ol/render/Feature'; |
10 | import Fill from 'ol/style/Fill'; |
11 | import Stroke from 'ol/style/Stroke'; |
12 | import Style from 'ol/style/Style'; |
13 | import Text from 'ol/style/Text'; |
14 | |
15 | // WFS 벡터 소스 |
16 | const wfs = new VectorSource({ |
17 | format: new GeoJSON(), |
18 | url: (extent) => urlBuilder('https://example.com/geoserver/wfs', { |
19 | service: 'WFS', |
20 | version: '2.0.0', |
21 | request: 'GetFeature', |
22 | typename: 'TEST:buld_sejong', |
23 | srsName: 'EPSG:3857', |
24 | outputFormat: 'application/json', |
25 | exceptions: 'application/json', |
26 | bbox: `${extent.join(',')},EPSG:3857` |
27 | }), |
28 | strategy: bbox |
29 | }); |
30 | |
31 | // 벡터 레이어 객체 |
32 | const wfsLayer = new VectorLayer({ |
33 | source: wfs, |
34 | style: feature => new Style({ |
35 | stroke: new Stroke({ |
36 | color: 'rgba(100, 149, 237, 1)', |
37 | width: 2 |
38 | }), |
39 | fill: new Fill({ |
40 | color: 'rgba(100, 149, 237, 0.6)' |
41 | }), |
42 | text: new Text({ |
43 | font: '0.8rem sans-serif', |
44 | fill: new Fill({ color: 'white' }), |
45 | stroke: new Stroke({ |
46 | color: 'rgba(0, 0, 0, 1)', |
47 | width: 4 |
48 | }), |
49 | text: feature.get('address') |
50 | }) |
51 | }), |
52 | minZoom: 15, |
53 | zIndex: 5, |
54 | properties: { name: 'wfs' } |
55 | }); |
56 | |
57 | // 뷰 객체 |
58 | const view = new View({ |
59 | projection: 'EPSG:3857', |
60 | center: proj4('EPSG:4326', 'EPSG:3857', [ 127.28923267492068, 36.48024986578043 ]), |
61 | zoom: 17 |
62 | }); |
63 | |
64 | // 맵 객체 |
65 | const map = new Map({ |
66 | layers: [ vworldBaseLayer, vworldHybridLayer, wfsLayer ], |
67 | target: 'map', |
68 | view: view |
69 | }); |
Name | Type | Default | Description |
---|---|---|---|
controls | ol/Collection-Collection<ol/control/Control-Control> | Array<ol/control/Control-Control> | undefined |
ol/control/defaults | 지도 컨트롤 객체 |
pixelRatio | number |
window.devicePixelRatio |
기기 픽셀 비율 |
interactions | ol/Collection-Collection<ol/interaction/Interaction-Interaction> | Array<ol/interaction/Interaction-Interaction> | undefined |
||
keyboardEventTarget | HTMLElement | Document | string | undefined |
키보드 이벤트 대상 요소 | |
layers | Array<ol/layer/Base-BaseLayer> | ol/Collection-Collection<ol/layer/Base-BaseLayer> | ol/layer/Group-LayerGroup | undefined |
레이어 목록. 배열 뒤에 있을 수록 우선순위가 높아짐 | |
maxTilesLoading | number |
16 |
동시 로드 가능한 최대 타일 수 |
moveTolerance | number |
1 |
지도 이동 이벤트로 인식하기 위해 마우스가 움직여야할 최소 픽셀 |
overlays | ol/Collection-Collection<ol/Overlay-Overlay> | Array<ol/Overlay-Overlay> | undefined |
지도 오버레이 객체 | |
target | HTMLElement | string | undefined |
지도를 표시할 DOM 혹은 DOM 아이디 | |
view | ol/View-View | Promise<ol/View-View> | undefined |
지도 뷰 객체 |
Map
객체에 지금까지 선언한 객체들을 할당한다. target
에 지정된 DOM에 선언된 지도가 표시된다.
target: map
은 아이디가 map
인 DOM에 지도를 표시한다는 뜻이다. 꼭 아이디가 아니더라도 HTMLElement
를 할당할 수도 있다.
WFS로 호출한 데이터가 기술한 스타일대로 출력되는 것을 확인할 수 있다.
예제 확인하기 🔗
OpenLayers6 Sandbox - WFS에서 이를 구현한 예제를 확인할 수 있다.
GeoServer를 통해 공간정보 데이터를 호출하여, OpenLayers가 지도에 렌더링하는 걸 확인할 수 있다.
📆 작성일
2022-05-14 Sat 17:48:50
📚 카테고리
🏷️ 태그