지리 공간적 - Flutter SDK
이 페이지의 내용
버전 1.6.0에 추가 되었습니다.
지리 공간적 데이터 또는 '지리 데이터'는 지구 표면의 점과 기하학적 객체를 지정합니다. 지리 데이터 유형을 사용하면 특정 점이 도형 내에 포함되어 있는지 확인하는 쿼리를 만들 수 있습니다. 예를 들어 지정된 지점에서 15 km 이내에 있는 모든 커피숍을 찾을 수 있습니다.
Flutter SDK v1.6.1 이상에서는 Atlas Device Sync에서 지리 공간적 데이터에 대한 지원이 추가되었습니다. 이를 통해 동기화된 데이터베이스에서 지리 공간적 쿼리를 구독할 수 있습니다. 이전 버전의 SDK에서 지리 공간적 쿼리를 구독하려고 하면 보상 쓰기와 함께 서버 오류가 발생합니다. 동기화 구독 관리에 대한 자세한 내용은 동기화 구독 관리 - Flutter SDK를 참조하세요.
Device Sync 를 사용하여 지리 공간적 데이터를 쿼리하는 방법에 대한 자세한 내용은 App Services 문서에서 지리 공간적 데이터를 참조하세요.
지리 공간적 데이터 유형
Flutter SDK는 다음 데이터 유형을 사용하여 지리 공간적 쿼리를 지원합니다.
GeoPoint
GeoCircle
GeoBox
SDK는 이러한 지리 공간적 데이터 유형을 제공하여 지리 공간적 데이터 쿼리를 간소화합니다. 이러한 데이터 유형을 직접 유지할 수 는 없습니다 .
지리 공간적 데이터를 유지하는 방법에 대한 자세한 내용은 이 페이지의 지리 공간적 데이터 유지 섹션을 참조하세요.
GeoPoint
GeoPoint 지구 표면의 특정 위치 를 정의합니다. 모든 지리 공간적 데이터 유형은 를 GeoPoints
사용하여 위치 를 정의합니다.
GeoPoint
은(는) 두 가지 필수 속성을 가진 객체입니다.
lat
: 이중 값lon
: 이중 값
GeoPoint는 다른 도형 GeoCircle 및 GeoBox의 빌딩 블록으로만 사용됩니다. 이러한 도형과 GeoPoint 유형은 지속성이 아닌 쿼리에 사용됩니다.
지리 공간적 데이터를 데이터베이스에 저장하려면 지리 공간적 데이터 유지를 참조하세요 .
GeoCircle
GeoCircle 지구 표면에 원을 정의합니다. 다음을 제공하여 GeoCircle
를 정의합니다.
원의 중심에 대한
GeoPoint
원의 거리(반지름)에 대한
GeoDistance
반경 거리는 측정 단위로 라디안을 사용하며, SDK에서는 더블로 구현됩니다. SDK는 다른 측정 단위에서 GeoDistance
를 생성할 수 있는 편리한 메서드를 제공합니다.
다음 코드는 원을 만드는 두 가지 예를 보여줍니다.
final smallCircle = GeoCircle(GeoPoint(lon: -121.9, lat: 47.3), 0.25.degrees); final largeCircleCenter = GeoPoint(lon: -122.6, lat: 47.8); // The SDK provides convenience methods to convert measurements to radians. final radiusFromKm = GeoDistance.fromKilometers(44.4); final largeCircle = GeoCircle(largeCircleCenter, radiusFromKm);
GeoBox
GeoBox 지구 표면의 직사각형을 정의합니다. 왼쪽 하단(남서) 모서리와 오른쪽 상단(북동쪽) 모서리를 지정하여 사각형을 정의합니다.
다음 예에서는 2 상자를 만듭니다.
final largeBox = GeoBox( GeoPoint(lon: -122.7, lat: 47.3), GeoPoint(lon: -122.1, lat: 48.1)); final smallBoxSouthWest = GeoPoint(lon: -122.4, lat: 47.5); final smallBoxNorthEast = GeoPoint(lon: -121.8, lat: 47.9); final smallBox = GeoBox(smallBoxSouthWest, smallBoxNorthEast);
지리 공간적 데이터 유지
중요
지리 공간적 데이터 유형을 지속할 수 없음
현재는 지리 공간적 데이터만 유지할 수 있습니다. 지리 공간적 데이터 유형은 직접 유지할 수 없습니다 . 예를 들어 GeoBox
유형의 속성은 선언할 수 없습니다.
이러한 유형은 지리공간 쿼리의 인수로만 사용할 수 있습니다.
지리 공간적 데이터를 유지하려면 GeoJSON 사양 을 준수해야 합니다. .
GeoJSON 호환 클래스 만들기
GeoJSON 사양을 준수하는 클래스를 만들려면 다음을 수행합니다.
포함된 객체를 만듭니다. 포함된 객체에 대한 자세한 내용은 포함된 객체를 참조하세요 .
최소한 GeoJSON 사양에 필요한 두 개의 필드를 추가합니다.
스키마의 '좌표'(대소문자 구분) 속성에 매핑되는
double[]
유형의 필드입니다.'type' 속성에 매핑되는
string
유형의 필드입니다. 이 필드의 값은 'Point'여야 합니다.
다음 예제에서는 지리 공간적 데이터를 유지하는 데 사용되는 MyGeoPoint
이라는 포함된 클래스를 보여줍니다.
// To store geospatial data, create an embedded object with this structure. // Name it whatever is most convenient for your application. (ObjectType.embeddedObject)class _MyGeoPoint { // These two properties are required to persist geo data. final String type = 'Point'; final List<double> coordinates = const []; // You can optionally implement convenience methods to simplify // creating and working with geospatial data. double get lon => coordinates[0]; set lon(double value) => coordinates[0] = value; double get lat => coordinates[1]; set lat(double value) => coordinates[1] = value; GeoPoint toGeoPoint() => GeoPoint(lon: lon, lat: lat); }
임베디드 클래스 사용
그런 다음 다음 예제와 같이 데이터 모델에서 사용자 지정 MyGeoPoint
클래스를 사용합니다.
// Use the GeoJSON-compatible class as a property in your model. ()class _Company { () late ObjectId id; _MyGeoPoint? location; }
다른 모델과 마찬가지로 클래스의 인스턴스를 데이터베이스에 추가합니다.
final realm = Realm(Configuration.local([MyGeoPoint.schema, Company.schema])); realm.write(() { realm.addAll([ Company( firstCompanyID, location: MyGeoPoint(coordinates: [-122.35, 47.68]), ), Company( secondCompanyID, location: MyGeoPoint(coordinates: [-121.85, 47.9]), ) ]); });
다음 이미지는 이러한 두 회사 객체를 생성한 결과를 보여줍니다.
지리 공간적 데이터 쿼리
지리 공간적 데이터를 쿼리하려면 geoWithin
연산자를 RQL 과 함께 사용할 수 있습니다. geoWithin
연산자는 쿼리하려는 점을 정의하는 포함된 객체의 '좌표' 속성과 지리 공간적 도형 중 하나를 사용하여 해당 점이 도형 내에 포함되어 있는지 확인합니다.
참고
지리 공간적 데이터를 쿼리하는 형식은 지리 데이터 리전의 형태에 관계없이 동일합니다.
다음 예제에서는 다양한 셰이프를 쿼리하여 셰이프 내의 회사 목록을 반환하는 방법을 보여 줍니다.
GeoCircle
final companiesInSmallCircle = realm.query<Company>("location geoWithin \$0", [smallCircle]); final companiesInLargeCircle = realm.query<Company>("location geoWithin \$0", [largeCircle]);
GeoBox
final companiesInLargeBox = realm.query<Company>("location geoWithin \$0", [largeBox]); final companiesInSmallBox = realm.query<Company>("location geoWithin \$0", [smallBox]);