Geoespacial - Flutter SDK
Nesta página
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.
Tipos de dados geoespaciais
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.
GeoPoint
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 duplolon
: 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.
Círculo geográfico
Um GeoCircle define um círculo na superfície da Terra. Você define um GeoCircle
fornecendo:
Um
GeoPoint
para o centro do círculoUm
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](/pt-br/docs/atlas/device-sdks/static/9e9b060713c414d5d84e33ee50767603/6a29e/geocircles.webp)
GeoBox
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](/pt-br/docs/atlas/device-sdks/static/e652ed3c490f1d68ab1993aa8e5b75f7/96cd5/geoboxes.webp)
Persistir dados geoespaciais
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.
Criar uma classe compatível com GeoJSON
Para criar uma classe que esteja em conformidade com a especificação GeoJSON, você:
Crie um objeto incorporado. Para obter mais informações sobre objetos incorporados, consulte Objetos incorporados.
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. (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); }
Use a classe incorporada
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. ()class _Company { () 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](/pt-br/docs/atlas/device-sdks/static/e2a34c0b13221325b3e2fb2f47aa3c32/20f8c/geopoints.webp)
Executar query de dados geoespaciais
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.](/pt-br/docs/atlas/device-sdks/static/0772d990be80943a5011e513eccbd29b/f0d7d/geocircles-query.webp)
GeoBox
final companiesInLargeBox = realm.query<Company>("location geoWithin \$0", [largeBox]); final companiesInSmallBox = realm.query<Company>("location geoWithin \$0", [smallBox]);
![Consultando um exemplo do GeoBox.](/pt-br/docs/atlas/device-sdks/static/397984610ac368234fc01ef0cb10bb4f/30f62/geoboxes-query.webp)