[Pre Onboarding-TIL]공간 데이터베이스

연꽃·2021년 11월 24일
0

Pre Onboarding

목록 보기
11/12

공간 데이터베이스의 필요성

여려가지 서비스에서 위치기반 서비스를 제공한다. 이것이 잘 작동하기 위해서는 먼저 점, 선, 공간(면)과 같은 지도에서 쓰일 수 있는 정보들이 데이터베이스에 잘 담겨 있어야 한다. 또한 이렇게 잘 저장되어 있는 정보를 상황에 맞게 활용할 수 있어야 한다. 그래서 일반적인 데이터를 저장하는 것과 달리 공간에 대한 정보를 저장하기 위해 공간 데이터베이스가 필요하다.

공간 데이터 타입

일반적으로 사용되는 공간 데이터 타입은 아래의 그림과 같은 종류들이 있다.

공간데이터 타입정의sql
Point좌표 공간에서 한 지점의 위치를 표시POINT (5 5)
LineString다수의 Point를 연결해주는 선분LINESTRING (5 5, 20 22, 15 17)
Polygon다수의 선분들이 연결되어 닫혀 있는 상태인 다각형POLYGON ((5 5, 10 30, 20 55, 20 10, 5 5))
Multi-Point다수 개의 Point 집합MULTIPOINT (5 5, 30 20, 33 45)
Multi-LineString다수 개의 LineString 집합MULTILINESTRING ((10 10, 20 20), (20 15, 30 40))
Multi-Polygon다수 개의 Polygon 집합MULTIPOLYGON (((5 5, 10 30, 20 55, 20 10, 5 5)) , (( 40 25, 44 40, 57 35, 25 10, 40 25 )))
GeomCollection모든 공간 데이터들의 집합GEOMETRYCOLLECTION ( POINT (10 10), LINESTRING (20 20, 30 40), POINT (30 15) )

실제 과제에서의 활용

  • 지역의 내부에 사용자가 존재하는지 여부

과제에서는 Polygon으로 저장되어 있는 지역의 데이터가 있었다. 그리고 위도와 경도로 표시된 사용자의 위치정보(Point)를 받아서 지역(데이터로서 Polygon)내부에 있는지 혹은 외부에 있는지 판단이 필요했다. 이를 위해서는 단순히 데이터들로만은 알 수 없고, 이를 판단해줄 공간관계 함수가 필요하다. 이를 구현하기 위해 작성했던 코드는 다음과 같다.

async findAreaByLatAndLng(lat: string, lng: string): Promise<Area> {
    const foundArea = await this.manager.query(` 
    select * from area where ST_Contains(area.area_boundary, ST_GeomFromText('POINT(${parseFloat(
      lat,
    )} ${parseFloat(lng)})'));
    `);
/*
ST_Contains은 공간 관계 함수. 
Polygon타입으로 저장되어 있는 area.area_boundary에 
사용자의 위치가 포함 되어 있는지 여부를 Boolean값으로 리턴한다.
*/

    return foundArea;
  }
  • 지역의 내부에 사용자가 존재하지 않는다면 사용자와 지역의 거리

과제에서 사용자가 지역으로부터 벗어났을 경우, 벌금을 부과해야한다. 그런데 이를 구현하기가 쉽지 않아 Polygon의 중심점으로부터 사용자의 거리를 피타고라스를 써서 구했다. 하지만 과제를 제출 한 후, 이를 계산할 수 있는 공간 관계 함수가 있다는 것을 알게 되었다.

async findDistance(lat: string, lng: string) {
  const distance = await this.manager.query(`select ST_Distance(ST_GeomFromText('POLYGON ((-90 180, 0 180, 0 16.34, -90 180))'),ST_GeomFromText('POINT(0 190)'));
    `);
  /*ST_Distance는 공간 데이터 사입 간의 거리를 구해주는 함수이다.
  Polygon타입과 Point타입 간의 거리를 구해준 것이다.
  */
     return distance
  }

참고
https://sparkdia.tistory.com/25?category=1114027

profile
우물에서 자라나는 중

0개의 댓글