문서 메뉴
문서 홈
/ /
Atlas Device SDK
/ / /

지리 공간 - React Native SDK

이 페이지의 내용

  • 지리 공간적 데이터 유형
  • GeoPoint
  • GeoCircle
  • GeoBox
  • GeoPolygon
  • 지리 공간적 데이터 유지
  • GeoJSON 호환 클래스 만들기
  • 임베디드 클래스 작성

버전 12.0.0의 새로운 기능.

지리 공간적 데이터 또는 '지리 데이터'는 지구 표면의 점과 기하학적 객체를 지정합니다. 지리 데이터 유형을 사용하면 특정 점이 도형 내에 포함되어 있는지 확인하는 쿼리를 만들 수 있습니다. 예를 들어 지정된 지점에서 15 km 이내에 있는 모든 커피숍을 찾을 수 있습니다.

버전 에서 변경realm@12.3.0: Atlas Device Sync에서 지원되는 지리 공간적 데이터

Realm.js v12.3.0 이상에서는 Atlas Device Sync에서 지리 공간적 데이터에 대한 지원이 추가되었습니다. 이를 통해 동기화 영역에서 지리 공간적 쿼리를 구독할 수 있습니다. 이전 버전의 SDK에서 지리 공간적 쿼리를 구독하려고 하면 보상 쓰기와 함께 서버 오류가 발생합니다. 동기화 구독 관리에 대한 자세한 내용은 지리 공간적 - React Native SDK를 참조하세요.

Device Sync 를 사용하여 지리 공간적 데이터를 쿼리하는 방법에 대한 자세한 내용은 Atlas App Services 문서에서 지리 공간적 데이터를 참조하세요.

SDK는 다음 데이터 유형을 사용하여 지리 공간적 쿼리를 지원합니다.

  • GeoPoint

  • GeoCircle

  • GeoBox

  • GeoPolygon

SDK는 이러한 지리 공간적 데이터 유형을 제공하여 지리 공간적 데이터 쿼리를 간소화합니다. 이러한 데이터 유형을 직접 유지할 수 는 없습니다 .

지리 공간적 데이터를 유지하는 방법에 대한 자세한 내용은 이 페이지의 지리 공간적 데이터 유지 섹션을 참조하세요.

지리 공간적 데이터를 쿼리하려면 geoWithin 연산자를 RQL 과 함께 사용할 수 있습니다. geoWithin 연산자는 쿼리하는 점을 정의하는 내장된 객체의 coordinates 속성과 지리 공간적 도형 중 하나를 사용하여 해당 점이 도형 내에 포함되어 있는지 확인합니다.

참고

지리 공간적 데이터를 쿼리하는 형식은 지리 데이터 리전의 형태에 관계없이 동일합니다.

GeoPoint 는 지구 표면의 특정 위치를 정의합니다. 모든 지리 공간적 데이터 유형은 GeoPoints 를 사용하여 위치를 정의합니다.

GeoPoint 세 가지 유형 중 하나일 수 있습니다.

  • 다음이 포함된 객체입니다.

    • latitude: 숫자 값

    • longitude: 숫자 값

    • altitude: 선택적 숫자 값

  • CanonicalGeoPoint: 점에 대한 GeoJSON 사양을 충족하는 인터페이스

  • GeoPosition: 경도, 위도 및 선택적 고도가 있는 배열

GeoPoint는 다른 도형 GeoCircle, GeoBox 및 GeoPolygon의 빌딩 블록으로만 사용됩니다. 이러한 도형과 GeoPoint 유형은 지속성이 아닌 쿼리에 사용됩니다.

지리 공간적 데이터를 영역에 저장하려면 이 페이지의 지리 공간적 데이터 유지하기를 참조하세요.

GeoCircle 은 지구 표면에 원을 정의합니다. 다음을 제공하여 GeoCircle 를 정의합니다.

  • 원의 중심에 대한 GeoPoint

  • 원의 거리(반지름)에 대한 숫자

반경 거리는 측정 단위로 라디안을 사용합니다. SDK는 킬로미터 또는 마일을 라디안으로 변환하는 kmToRadiansmiToRadians 메서드를 제공합니다.

다음 코드는 원을 만드는 두 가지 예를 보여줍니다.

import React from 'react';
import {View, Text} from 'react-native';
import {GeoCircle, GeoPoint, kmToRadians} from 'realm';
import {useQuery} from '@realm/react';
function Geocircle(): JSX.Element {
// Define a GeoCircle
const smallCircle: GeoCircle = {
center: [-121.9, 47.3],
// The GeoCircle radius is measured in radians.
// This radian distance corresponds with 0.25 degrees.
distance: 0.004363323,
};
// Realm provides `kmToRadians` and `miToRadians`
// to convert these measurements. Import the relevant
// convenience method for your app's needs.
const radiusFromKm = kmToRadians(44.4);
// Define a GeoPoint within a GeoCircle
const largeCircleCenter: GeoPoint = {
longitude: -122.6,
latitude: 47.8,
};
const largeCircle: GeoCircle = {
center: largeCircleCenter,
distance: radiusFromKm,
};
// Query geospatial data
const companiesInSmallCircle = useQuery(
Company,
collection => collection.filtered('location geoWithin $0', smallCircle),
[smallCircle],
);
// Query geospatial data
const companiesInLargeCircle = useQuery(
Company,
collection => collection.filtered('location geoWithin $0', largeCircle),
[largeCircle],
);
return (
<View>
<Text>Small circle: {companiesInSmallCircle.length}</Text>
<Text>Large circle: {companiesInLargeCircle.length}</Text>
</View>
);
}

다음 이미지는 작은 원과 큰 원이라는 두 객체를 생성한 결과를 보여줍니다.

GeoCircles 2개
클릭하여 확대

지리 공간적 데이터에 대한 쿼리는 정의한 모양 내의 Realm 객체를 반환합니다. 위의 예에서 쿼리 결과는 다음과 같습니다.

GeoCircle 쿼리 예시.
클릭하여 확대

GeoBox 는 지구 표면에 사각형을 정의합니다. 왼쪽 하단(남서) 모서리와 오른쪽 상단(북동쪽) 모서리를 지정하여 사각형을 정의합니다. GeoBox는 해당 GeoPolygon과 동일한 방식으로 작동합니다.

다음 예에서는 2 상자를 만듭니다.

import React from 'react';
import {View, Text} from 'react-native';
import {GeoBox, GeoPoint} from 'realm';
import {useQuery} from '@realm/react';
function Geobox(): JSX.Element {
// Define a GeoBox
const largeBox: GeoBox = {
bottomLeft: [-122.7, 47.3],
topRight: [-122.1, 48.1],
};
// Define GeoBox corners
const smallBoxBottomLeft: GeoPoint = {
longitude: -122.4,
latitude: 47.5,
};
const smallBoxTopRight: GeoPoint = {
longitude: -121.8,
latitude: 47.9,
};
const smallBox: GeoBox = {
bottomLeft: smallBoxBottomLeft,
topRight: smallBoxTopRight,
};
// Query geospatial data
const companiesInLargeBox = useQuery(
Company,
collection => collection.filtered('location geoWithin $0', largeBox),
[largeBox],
);
// Query geospatial data
const companiesInSmallBox = useQuery(
Company,
collection => collection.filtered('location geoWithin $0', smallBox),
[smallBox],
);
return (
<View>
<Text>Small box: {companiesInSmallBox.length}</Text>
<Text>Large box: {companiesInLargeBox.length}</Text>
</View>
);
}

다음 이미지는 작은 상자와 큰 상자라는 두 개의 객체를 생성한 결과를 보여줍니다.

2 GeoBox
클릭하여 확대

지리 공간적 데이터에 대한 쿼리는 정의한 모양 내의 Realm 객체를 반환합니다. 위의 예에서 쿼리 결과는 다음과 같습니다.

GeoBox 예제 쿼리.

GeoPolygon 은 지구 표면의 다각형을 정의합니다. 다각형은 닫힌 모양이므로 최소 4 개의 점을 제공해야 합니다(다각형의 모양을 정의하려면 3 점, 모양을 닫으려면 네 번째 점).

중요

다각형의 네 번째 점은 첫 번째 점과 같아야 합니다.

하나 이상의 "홀"을 정의하여 다각형 내의 영역을 제외할 수도 있습니다. 구멍은 경계가 외부 다각형 내에 완전히 들어가는 또 다른 다각형입니다. 다음 예제에서는 3개의 다각형을 생성합니다: 하나는 점이 5개인 기본 다각형, 하나는 단일 구멍이 있는 동일한 다각형, 세 번째는 두 개의 구멍이 있는 동일한 다각형입니다.

import React from 'react';
import {View, Text} from 'react-native';
import {GeoPolygon, GeoPoint} from 'realm';
import {useQuery} from '@realm/react';
function Geopolygon(): JSX.Element {
// Define a basic GeoPolygon
const basicPolygon: GeoPolygon = {
outerRing: [
[-122.8, 48.0],
[-121.8, 48.2],
[-121.6, 47.6],
[-122.0, 47.0],
[-122.6, 47.2],
[-122.8, 48.0],
],
};
// Define a GeoPolygon with one hole
const outerRing: GeoPoint[] = [
[-122.8, 48.0],
[-121.8, 48.2],
[-121.6, 47.6],
[-122.0, 47.0],
[-122.6, 47.2],
[-122.8, 48.0],
];
const hole: GeoPoint[] = [
[-122.6, 47.8],
[-122.2, 47.7],
[-122.6, 47.4],
[-122.5, 47.6],
[-122.6, 47.8],
];
const polygonWithOneHole: GeoPolygon = {
outerRing: outerRing,
holes: [hole],
};
// Add a second hole to the GeoPolygon
const hole2: GeoPoint[] = [
{
longitude: -122.05,
latitude: 47.55,
},
{
longitude: -121.9,
latitude: 47.55,
},
{
longitude: -122.1,
latitude: 47.3,
},
{
longitude: -122.05,
latitude: 47.55,
},
];
const polygonWithTwoHoles: GeoPolygon = {
outerRing: outerRing,
holes: [hole, hole2],
};
// Query geospatial data
const companiesInBasicPolygon = useQuery(
Company,
collection => collection.filtered('location geoWithin $0', basicPolygon),
[basicPolygon],
);
// Query geospatial data
const companiesInPolygonWithTwoHoles = useQuery(
Company,
collection =>
collection.filtered('location geoWithin $0', polygonWithTwoHoles),
[polygonWithTwoHoles],
);
return (
<View>
<Text>Basic polygon: {companiesInBasicPolygon.length}</Text>
<Text>
Polygon with two holes: {companiesInPolygonWithTwoHoles.length}
</Text>
</View>
);
}

다음 이미지는 세 개의 객체, 즉 다각형, 구멍이 하나 있는 다각형 및 구멍이 두 개인 다각형을 만든 결과를 보여 줍니다.

3 GeoPolygons
클릭하여 확대

지리 공간적 데이터에 대한 쿼리는 정의한 모양 내의 Realm 객체를 반환합니다. 위의 예에서 쿼리 결과는 다음과 같습니다.

GeoPolygon 예제 쿼리.
클릭하여 확대

중요

지리 공간적 데이터 유형을 지속할 수 없음

현재는 지리 공간적 데이터만 유지할 수 있습니다. 지리 공간적 데이터 유형은 직접 유지할 수 없습니다 . 예를 들어 GeoBox 유형의 속성은 선언할 수 없습니다.

이러한 유형은 지리공간 쿼리의 인수로만 사용할 수 있습니다.

지리 공간적 데이터를 유지하려면 GeoJSON 사양 을 준수해야 합니다. .

GeoJSON 사양을 준수하는 클래스를 만들려면 다음을 수행합니다.

  1. 포함된 Realm 객체를 만듭니다. 내장된 객체에 대한 자세한 내용은 내장된 객체 - React Native SDK를 참조하세요.

  2. 최소한 GeoJSON 사양에 필요한 두 개의 필드를 추가합니다.

    • 영역 스키마의 '좌표'(대소문자 구분) 속성에 매핑되는 double[] 유형의 필드입니다.

    • 'type' 속성에 매핑되는 string 유형의 필드입니다. 이 필드의 값은 'Point'여야 합니다.

지리 데이터 지속성을 간소화하기 위해 이미 올바른 형태를 가진 CanonicalGeoPoint 를 구현하는 모델을 정의할 수 있습니다. 다음 예제에서는 지리 공간적 데이터를 유지하는 데 사용되는 MyGeoPoint 이라는 이름의 임베디드 클래스를 보여줍니다.

그런 다음 다음 예시와 같이 영역 모델에서 사용자 지정 MyGeoPoint 클래스를 사용합니다. 다른 Realm 모델과 마찬가지로 클래스의 인스턴스를 Realm에 추가합니다. 그러나 이 예제에서는 MyGeoPoint 클래스가 Realm.Object 을(를) 확장하지 않으므로 영역을 열 때 MyGeoPoint.schema 을(를) 지정해야 합니다.

import React from 'react';
import Realm, {ObjectSchema, CanonicalGeoPoint, GeoPosition} from 'realm';
import {RealmProvider} from '@realm/react';
// Implement `CanonicalGeoPoint`
// for convenience when persisting geodata.
class MyGeoPoint implements CanonicalGeoPoint {
coordinates!: GeoPosition;
type = 'Point' as const;
constructor(long: number, lat: number) {
this.coordinates = [long, lat];
}
static schema: ObjectSchema = {
name: 'MyGeoPoint',
embedded: true,
properties: {
type: 'string',
coordinates: 'double[]',
},
};
}
class Company extends Realm.Object<Company> {
_id!: number;
location!: MyGeoPoint;
static schema: ObjectSchema = {
name: 'Company',
properties: {
_id: 'int',
location: 'MyGeoPoint',
},
primaryKey: '_id',
};
}
export const Geospatial = () => {
return (
<View>
{/*
`MyGeoPoint` does not extend `Realm.Object`, so you pass
only the `.schema` when opening the realm.
*/}
<RealmProvider schema={[Company, MyGeoPoint.schema]}>
<WriteGeospatialObjects />
</RealmProvider>
</View>
);
};

RealmProvider 내에서, Realm.Object 을 확장하는 클래스와 임베디드 클래스를 결합하여 지리 공간적 객체를 생성합니다.

import React from 'react';
import {View} from 'react-native';
import {useEffect} from 'react';
import {useRealm, useQuery} from '@realm/react';
function WriteGeospatialObjects(): JSX.Element {
const realm = useRealm();
const companies = useQuery(Company);
useEffect(() => {
if (!companies.length) {
// Add geospatial objects to realm.
writeNewCompany({_id: 6, location: new MyGeoPoint(-122.35, 47.68)});
writeNewCompany({_id: 9, location: new MyGeoPoint(-121.85, 47.9)});
}
}, []);
type CompanyProps = {
_id: number;
location: MyGeoPoint;
};
const writeNewCompany = ({_id, location}: CompanyProps) => {
// Add geospatial object to realm.
realm.write(() => {
realm.create(Company, {
_id,
location,
});
});
};
return (
<View>
<Geocircle />
<Geobox />
<Geopolygon />
</View>
);
}

다음 이미지는 이러한 두 회사 객체를 생성한 결과를 보여줍니다.

2개의 GeoPoint
클릭하여 확대

돌아가기

임베디드 객체

다음

CRUD