Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ / /

Geoespacial - Flutter SDK

Nesta página

  • Tipos de dados geoespaciais
  • GeoPoint
  • Círculo geográfico
  • GeoBox
  • Persistir dados geoespaciais
  • Criar uma classe compatível com GeoJSON
  • Use a classe incorporada
  • Executar query de dados geoespaciais

Novidade na versão 1,6,0.

Os dados geoespaciais, ou "geodata", especificam pontos e objetos geométricos na superfície da Terra. Com os tipos de dados geográficos, você pode criar consultas que verificam se um determinado ponto está contido dentro de uma forma. Por exemplo, você pode encontrar todos os cafés em um raio de 15 km de um ponto especificado.

Flutter SDK v1.6.1 e posterior adiciona suporte para dados geoespaciais no Atlas Device Sync. Isto permite a você assinar queries geoespaciais em um banco de dados sincronizado. Se você tentar se inscrever em uma query geoespacial com uma versão mais antiga do SDK, receberá um erro de servidor com uma gravação compensatória. Para obter mais informações sobre como gerenciar suas assinaturas de sincronização, consulte Gerenciar assinaturas de sincronização - Flutter SDK.

Para mais informações sobre query de dados geoespaciais com o Device Sync, consulte Dados geoespaciais na documentação do App Services.

O Flutter SDK suporta queries geoespaciais utilizando os seguintes tipos de dados:

  • GeoPoint

  • GeoCircle

  • GeoBox

O SDK fornece estes tipos de dados geoespaciais para simplificar a query de dados geoespaciais. Você não pode persistir esses tipos de dados diretamente.

Para obter informações sobre como persistir dados geoespaciais, consulte a seção Persistir dados geoespaciais nesta página.

Um GeoPoint define um local específico na superfície da Terra. Todos os tipos de dados geoespaciais utilizam o GeoPoints para definir sua localização.

Um GeoPoint é um objeto com duas propriedades obrigatórias:

  • lat: um valor duplo

  • lon: um valor duplo

Um GeoPoint é utilizado somente como um bloco de construção das outras formas: GeoCircle e GeoBox. Estas formas e o tipo GeoPoint são usados em queries, não para persistência.

Para salvar dados geoespaciais no banco de dados, consulte Persistir Dados Geoespaciais.

Um GeoCircle define um círculo na superfície da Terra. Você define um GeoCircle fornecendo:

  • Um GeoPoint para o centro do círculo

  • Um GeoDistance para a distância (raio) do círculo

A distância de raio usa radianos como unidade de medida, implementado como um valor duplo no SDK. O SDK fornece métodos de conveniência para criar um GeoDistance a partir de outras unidades de medida:

O seguinte código mostra dois exemplos de criação de um círculo:

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);
Dois círculos geográficos
clique para ampliar

Uma GeoBox define um retângulo na superfície da Terra. Você define o retângulo especificando o canto inferior esquerdo (sudoeste) e o canto superior direito (nordeste).

O exemplo a seguir cria 2 caixas:

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);
2 GeoBoxes
clique para ampliar

Importante

Não é possível persistir tipos de dados geoespaciais

Atualmente, você só pode persistir dados geoespaciais. Os tipos de dados geoespaciais não podem ser persistidos diretamente. Por exemplo, você não pode declarar uma propriedade do tipo GeoBox.

Estes tipos podem ser utilizados somente como argumentos para queries geoespaciais.

Para persistir dados geoespaciais, eles devem estar em conformidade com a especificação GeoJSON.

Para criar uma classe que esteja em conformidade com a especificação GeoJSON, você:

  1. Crie um objeto incorporado. Para obter mais informações sobre objetos incorporados, consulte Objetos incorporados.

  2. No mínimo, adicione os dois campos exigidos pela especificação GeoJSON:

    • Um campo do tipo double[] que mapeia para uma propriedade de "coordenadas" (diferencia maiúsculas de minúsculas) no esquema.

    • Um campo do tipo string que mapeia para uma propriedade "type". O valor deste campo deve ser "Ponto".

O exemplo seguinte mostra uma classe embarcada denominada MyGeoPoint que é utilizada para persistir dados geoespaciais:

// To store geospatial data, create an embedded object with this structure.
// Name it whatever is most convenient for your application.
@RealmModel(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);
}

Em seguida, use a classe MyGeoPoint personalizada em seu modelo de dados, conforme mostrado no exemplo a seguir:

// Use the GeoJSON-compatible class as a property in your model.
@RealmModel()
class _Company {
@PrimaryKey()
late ObjectId id;
_MyGeoPoint? location;
}

Você adiciona instâncias de sua classe ao banco de dados como qualquer outro modelo.

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]),
)
]);
});

A imagem a seguir mostra os resultados da criação desses dois objetos de empresa.

2 GeoPoints
clique para ampliar

Para fazer query de dados geoespaciais, você pode usar o operador geoWithin com RQL. O operador geoWithin pega a propriedade "coordenadas" de um objeto embarcado que define o ponto que estamos consultando e uma das formas geoespaciais para verificar se esse ponto está contido dentro da forma.

Observação

O formato para consultar dados geoespaciais é o mesmo, independentemente da forma da região de dados geoespaciais.

Os exemplos a seguir mostram a consulta a várias formas para retornar uma lista de empresas dentro da forma:

Círculo geográfico

final companiesInSmallCircle =
realm.query<Company>("location geoWithin \$0", [smallCircle]);
final companiesInLargeCircle =
realm.query<Company>("location geoWithin \$0", [largeCircle]);
Consultando um exemplo do GeoCircle.
clique para ampliar

GeoBox

final companiesInLargeBox =
realm.query<Company>("location geoWithin \$0", [largeBox]);
final companiesInSmallBox =
realm.query<Company>("location geoWithin \$0", [smallBox]);
Consultando um exemplo do GeoBox.

Voltar

Atualizar um esquema de objeto de Realm