logo

𝝅번째 알파카의 개발 낙서장

OpenLayers를 여행하는 개발자를 위한 안내서 - 9. 데이터 필터링하기

프로젝트
⏰ 2022-03-14 16:11:19

D O W N

https://user-images.githubusercontent.com/50317129/156607880-c5abad92-1991-4c01-b85f-7153bf89cb64.png
OpenLayers를 여행하는 개발자를 위한 안내서
이 게시글은 OpenLayers를 여행하는 개발자를 위한 안내서 시리즈의 26개 중 9번 째 게시글입니다.
https://user-images.githubusercontent.com/50317129/260317030-e4b8575b-f09e-47f4-ab70-168a817268c6.png

Table of Contents

https://user-images.githubusercontent.com/50317129/260317030-e4b8575b-f09e-47f4-ab70-168a817268c6.png

OGC Filter

WFS나 WMS를 호출할 때, 좀 더 다채로운 필터링이 필요한 경우가 존재할 수 있다. 특정 영역 밖의 객체를 호출한다거나, 특정 영역에 걸치는 데이터만 호출하는 것, 혹은 다양한 조건을 조합하여 데이터를 조회해야 할 수도 있다.

이 때 요긴하게 사용할 수 있는 것이 OGC Filter다. OGC Filter는 XML의 형태를 가지며, 요청에 포함되어 좀 더 다양한 공간정보 데이터의 필터링을 가능케 한다.

OGC Filter의 요청 URL에 filter 파라미터로 값을 지정하여 사용할 수 있다. 또한 Transaction 명령에서도 사용할 수 있다.



이항 비교 연산자

이항 비교 연산자는 아래와 같다.

  • PropertyIsEqualTo: 일치하는 데이터
  • PropertyIsNotEqualTo: 불일치하는 데이터
  • PropertyIsLessThan: 미만인 데이터
  • PropertyIsLessThanOrEqualTo: 이하인 데이터
  • PropertyIsGreaterThan: 초과인 데이터
  • PropertyIsGreaterThanOrEqualTo: 이상인 데이터
NameRequiredvalue
PropertyNameY컬럼명
LiteralY

XML

1
2
3
4
5
6
7
8
9
10
11
<!-- CITY 컬럼이 서울인 데이터만을 필터링 -->
<PropertyIsEqualTo>
	<PropertyName>CITY</PropertyName>
	<Literal>서울</Literal>
</PropertyIsEqualTo>

<!-- AREA 컬럼이 350 이하인 데이터만을 필터링 -->
<PropertyIsLessThanOrEqualTo>
	<PropertyName>AREA</PropertyName>
	<Literal>350</Literal>
</PropertyIsLessThanOrEqualTo>


값 비교 연산자

값 비교 연산자는 아래와 같다.

  • PropertyIsLike: 값을 포함하는 데이터
  • PropertyIsNull: 값이 NULL인 데이터
  • PropertyIsBetween: 값이 지정값 사이인 데이터

연산자별로 양식이 조금씩 다르다.

  • PropertyIsLike
NameRequiredvalue
PropertyNameY컬럼명
LiteralY

PropertyName 태그에서 아래의 3가지 속성을 사용할 수 있다.

  • wildCard: 와일드카드
  • singleChar: 문자열 하나
  • escapeChar: 개행문자

위 속성에 문자열을 할당하면, 해당 문자열은 위와 동일한 의미를 가지게 된다.

속성은 여러개를 동시에 사용할 수도 있다.

XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- CITY 컬럼이 서울이란 단어를 포함한 데이터만을 필터링 -->
<PropertyIsLike>
	<PropertyName>CITY</PropertyName>
	<Literal>서울</Literal>
</PropertyIsLike>

<!-- CITY 컬럼이 서울로 시작하는 3글자 단어를 포함한 데이터만을 필터링 -->
<PropertyIsLike>
	<PropertyName>CITY</PropertyName>
	<Literal singleChar="_">서울_</Literal>
</PropertyIsLike>

<!-- CITY 컬럼이 서로 시작해서 울로 끝나는 단어를 포함한 데이터만을 필터링 -->
<PropertyIsLike>
	<PropertyName>CITY</PropertyName>
	<Literal wildCard="%">서%울</Literal>
</PropertyIsLike>

<!-- CITY 컬럼이 서울로 시작하는 3글자 단어가 개행된 데이터만을 필터링 -->
<PropertyIsLike>
	<PropertyName>CITY</PropertyName>
	<Literal singleChar="_" escapeChar="-">서울_-</Literal>
</PropertyIsLike>

  • PropertyIsNull
NameRequiredvalue
PropertyNameY컬럼명

컬럼값이 NULL인지만 비교하므로, Literal은 필요 없는 게 특징이다.

XML

1
2
3
4
<!-- CITY 컬럼이 NULL인 데이터만을 필터링 -->
<PropertyIsNull>
	<PropertyName>CITY</PropertyName>
</PropertyIsNull>

  • PropertyIsBetween
NameRequiredvalue
PropertyNameY컬럼명
UpperBoundaryY최대
LowerBoundaryY최소
LiteralY값 (Boundary 하위)

XML

1
2
3
4
5
6
7
8
9
10
<!-- COUNT 컬럼이 500 ~ 1000인 데이터만을 필터링 -->
<PropertyIsBetween>
	<PropertyName>COUNT</PropertyName>
	<UpperBoundary>
		<Literal>1000</Literal>
	</UpperBoundary>
	<LowerBoundary>
		<Literal>500</Literal>
	</LowerBoundary>
</PropertyIsBetween>

Boundary 태그 안에 Literal 태그가 들어감을 주의하자.



공간 연산자

좌표, 영역 등의 공간을 기반으로 필터를 구성할 수 있다.

  • Intersects: 해당 공간에 포함되거나 걸치는 데이터
  • Disjoint: 해당 공간에 포함되지 않는 데이터
  • Contains: 해당 공간에 포함되는 데이터
  • Within: 해당 공간 내부의 데이터
  • Touches: 해당 공간에 닿는 데이터
  • Crosses: 해당 공간을 교차하는 데이터
  • Overlaps: 해당 공간에 겹쳐지는 데이터
  • Equlas: 해당 공간과 동일한 데이터

글로 보면 좀 모호할 수 있는데, 이해를 돕기 위해 아래 그림을 보자.

이와 같은 차이가 존재한다.

NameRequiredvalue
PropertyNameY공간정보 컬럼명
gmlY공간정보 XML

공간정보 XML은 이전 장에서 확인할 수 있다.

XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 해당 영역에 포함되거나 걸치는 데이터만을 필터링 -->
<Intersects>
	<PropertyName>GEOM</PropertyName>
	<gml:Polygon srsName="EPSG:0000">
		<gml:outerBoundaryIs>
			<gml:LinearRing>
				<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates>
			</gml:LinearRing>
		</gml:outerBoundaryIs>
	</gml:Polygon>
</Intersects>

<!-- 해당 라인을 교차하는 데이터만을 필터링 -->
<Crosses>
	<PropertyName>GEOM</PropertyName>
	<gml:LineString srsName="EPSG:0000">
		<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4</gml:coordinates>
	</gml:LineString>
</Crosses>

공간 연산의 특성 상, 점 데이터는 활용 가능성이 낮다.



거리 연산자

데이터의 거리를 기반으로 필터를 구성한다.

  • DWithin: 해당 거리 이내의 데이터
  • Beyond: 해당 거리 너머의 데이터
NameRequiredvalue
PropertyNameY공간정보 컬럼명
gmlY공간정보 XML
DistanceY거리

Distance의 속성으로 units를 사용할 수 있으며, 거리의 단위를 표기한다.

XML

1
2
3
4
5
6
7
8
<!-- 해당 점과 100m 이내의 데이터만을 필터링 -->
<DWithin>
	<PropertyName>GEOM</PropertyName>
	<gml:Point srsName="EPSG:0000">
		<gml:coordinates>x,y</gml:coordinates>
	</gml:Point>
	<Distance units="m">100</Distance>
</DWithin>


영역 연산자

데이터의 영역을 기반으로 필터를 구성한다.

  • BBOX: 해당 공간에 포함되거나 걸치는 데이터 (Intersects와 동일)
NameRequiredvalue
PropertyNameY공간정보 컬럼명
LiteralY
gmlY공간정보 XML

XML

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 해당 영역에 포함되거나 걸치는 데이터만을 필터링 -->
<BBOX>
	<PropertyName>GEOM</PropertyName>
	<Literal>
		<gml:Polygon srsName="EPSG:0000">
			<gml:outerBoundaryIs>
				<gml:LinearRing>
					<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates>
				</gml:LinearRing>
			</gml:outerBoundaryIs>
		</gml:Polygon>
	</Literal>
</BBOX>

사실상 공간 연산자의 Intersects와 동일한 결과.



논리 연산자

여러 조건을 결합하여 필터를 구성한다.

  • And: 조건을 모두 충족하는 데이터
  • Or: 조건을 하나 이상 충족하는 데이터
  • Not: 조건을 충족하지 않는 데이터

XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 해당 영역에 포함되거나 걸치면서, AREA가 350 이하인 데이터 -->
<And>
	<BBOX>
		<PropertyName>GEOM</PropertyName>
		<Literal>
			<gml:Polygon srsName="EPSG:0000">
				<gml:outerBoundaryIs>
					<gml:LinearRing>
						<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates>
					</gml:LinearRing>
				</gml:outerBoundaryIs>
			</gml:Polygon>
		</Literal>
	</BBOX>

	<PropertyIsLessThanOrEqualTo>
		<PropertyName>AREA</PropertyName>
		<Literal>350</Literal>
	</PropertyIsLessThanOrEqualTo>
</And>

논리 연산자를 적절히 중첩하여 복잡한 필터를 구성할 수 있다.




CQL Filter

OGC Filter 이외에도 CQL Filter라는 것 또한 존재한다. 잠깐 짚고 넘어가보자.

CQL Filter는 사용자에 따라 OGC Filter 보다 더 쉬울 수 있다. SQL의 형태와 매우 유사하기 때문.

CQL Filter는 요청 URL에 cql_filter 파라미터로 값을 지정하여 사용할 수 있다.


예를 들어, 아래와 같이 사용할 수 있다.

  • PropertyIsLike

TXT

1
CITY LIKE '%서울%'

이를 OGC로 표현하면 아래와 같다.

XML

1
2
3
4
5
<!-- CITY 컬럼이 서울이란 단어를 포함한 데이터만을 필터링 -->
<PropertyIsLike>
	<PropertyName>CITY</PropertyName>
	<Literal>서울</Literal>
</PropertyIsLike>

  • Intersects

TXT

1
INTERSECTS(GEOM, POLYGON((x1 y1, x2 y2, x3 y3, x4 y4, x1 y1)))

이를 OGC로 표현하면 아래와 같다.

XML

1
2
3
4
5
6
7
8
9
10
11
<!-- 해당 영역에 포함되거나 걸치는 데이터만을 필터링 -->
<Intersects>
	<PropertyName>GEOM</PropertyName>
	<gml:Polygon srsName="EPSG:0000">
		<gml:outerBoundaryIs>
			<gml:LinearRing>
				<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates>
			</gml:LinearRing>
		</gml:outerBoundaryIs>
	</gml:Polygon>
</Intersects>

이 처럼 필터가 단순해지기 때문에, URL 필터링 시 활용하기 훨씬 용이하다.




마치며

OGC Filter와 CQL Filter에 대해서 알아봤다.

데이터의 필터링을 구체적으로 수행할 경우, 요긴하게 사용할 것이다.

  • OGC: XML 형태의 필터. WFS Transaction 등, XML 기반 데이터의 필터링에 용이하다.
  • CQL: 텍스트 형태의 필터. WFS, WMS API와 같이 URL에 적용하기 편하다.

OGC, CQL Filter에 더 많은 정보가 필요하다면 각각 아래의 사이트를 확인하자.

🏷️ Related Tag

# GIS
# GeoServer

😍 읽어주셔서 감사합니다!
도움이 되셨다면, 💝공감이나 🗨️댓글을 달아주시는 건 어떤가요?
블로그 운영에 큰 힘이 됩니다!
https://blog.itcode.dev/projects/2022/03/15/gis-guide-for-programmer-9