Menu Docs
Página inicial do Docs
/ / /
Kotlin Coroutine

Pesquisar geoespacialmente

Nesta página

  • Visão geral
  • Coordenadas na Terra
  • Posições GeoJSON
  • Tipos de GeoJSON
  • Index
  • Coordenadas em um plano 2D
  • Index
  • Consultas geoespaciais
  • Operadores de Consulta
  • parâmetros de query
  • Exemplos
  • Query por proximidade
  • Query dentro de um intervalo

Neste guia, você pode aprender como pesquisar dados geoespaciais com o MongoDB Kotlin Driver e os diferentes formatos de dados geoespaciais suportados pelo MongoDB.

Dados geoespaciais são dados que representam uma localização geográfica na superfície da Terra. Exemplos de dados geoespaciais incluem:

  • Localizações de cinemas

  • Fronteiras de países

  • Rotas de passeios de bicicleta

  • Áreas de exercícios para cães na cidade de Nova York

Para armazenar e fazer query dos seus dados geoespaciais no MongoDB, utilize GeoJSON. GeoJSON é um formato de dados criado pela Internet Engineering Task Force (IETF).

Aqui está a localização da sede do MongoDB no GeoJSON:

"MongoDB Headquarters" : {
"type": "point",
"coordinates": [-73.986805, 40.7620853]
}

Para obter informações sólidas sobre o GeoJSON,consulte a especificação oficial do IETF .

Uma posição representa um único local na Terra e existe em código como uma array contendo dois ou três valores numéricos:

  • Longitude na primeira posição (obrigatório)

  • Latitude na segunda posição (obrigatório)

  • Elevação na terceira posição (opcional)

Importante

Longitude e depois latitude

A GeoJSON ordena coordenadas como longitude primeiro e latitude segundo. Isto pode ser surpreendente como convenções do sistema de coordenadas geográficas geralmente listam latitude primeiro e longitude segundo. Certifique-se de verificar qual formato qualquer outra ferramenta com a qual você está trabalhando usa. Ferramentas populares como OpenStreetMap e Google Maps listam coordenadas como latitude primeiro e longitude segundo.

O tipo de objeto GeoJSON determina sua forma geométrica. Formas geométricas são compostas por posições.

Aqui estão alguns tipos de GeoJSON comuns e como você pode especificá-los com posições:

  • Point: uma única posição. Isso pode representar a localização de uma construção.

  • LineString: uma matriz de duas ou mais posições, formando assim uma série de segmentos de linha. Isso pode representar a rota da Grande Muralha da China.

  • Polygon: uma array de posições em que a primeira e a última posição são iguais, contendo algum espaço. Isso pode representar o território dentro da Cidade do Vaticano.

Para saber mais sobre as formas que você pode usar no MongoDB, consulte a entrada do manual GeoJSON.

Para query dados armazenados no formato GeoJSON, adicione o campo que contém dados GeoJSON a um índice do 2dsphere . O seguinte trecho cria um índice 2dsphere no campo location.geo utilizando o construtor Indexes :

collection.createIndex((Indexes.geo2dsphere("location.geo")))

Para obter mais informações sobre o construtor Indexes , consulte nosso guia sobre o construtor de índices.

Você pode armazenar dados geoespaciais utilizando coordenadas do x e y em um plano Euclidiano bidimensional. Nos referimos a coordenadas em um plano bidimensional como "legacy coordinate pairs".

Os legacy coordinate pairs têm a seguinte estrutura:

"<field name>" : [ x, y ]

Seu campo deve conter uma array de dois valores em que o primeiro representa o valor do eixo x e o segundo representa o valor do eixo y.

Para query dados armazenados como legacy coordinate pairs, você deve adicionar o campo que contém legacy coordinate pairs a um índice 2d . O seguinte trecho cria um índice 2d no campo coordinates utilizando o construtor Indexes :

collection.createIndex((Indexes.geo2d("coordinates")))

Para obter mais informações sobre o construtor Indexes , consulte nosso guia sobre o construtor de índices.

Para mais informações sobre legacy coordinate pairs, consulte a página manual do servidor MongoDB sobre legacy coordinate pairs.

Dica

Operadores suportados

Os índices esféricos (2dsphere) e planos (2d) suportam alguns, mas não todos, dos mesmos operadores de query. Para uma lista completa de operadores e sua compatibilidade de índice, consulte a entrada manual para queries geoespaciais.

As queries geoespaciais consistem em um operador de query e formas GeoJSON como parâmetros de query.

Para fazer query de seus dados geoespaciais, utilize um dos seguintes operadores de query:

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects requer um índice de 2dsphere

Você pode especificar esses operadores de query no driver MongoDB Kotlin com os métodos utilitários near(), geoWithin(), nearSphere() e geoIntersects() da classe de construtor Filters .

Para mais informações sobre operadores de query geoespacial, consulte a entrada manual para queries geoespaciais.

Para obter mais informações sobre Filters, consulte nosso guia sobre o construtor de filtros.

Para especificar uma forma para utilizar em uma query geoespacial, utilize as classes Position, Point, LineString e Polygon do driver MongoDB Kotlin.

Para obter uma lista completa das formas GeoJSON disponíveis no driver Kotlin do MongoDB, consulte o pacote GeoJSON Documentação da API.

Os exemplos seguintes utilizam o conjunto de dados de amostra do MongoDB Atlas. Você pode aprender como definir seu próprio Atlas cluster de camada grátis e como carregar o conjunto de dados de exemplo em nosso guia de início rápido.

Os exemplos utilizam a coleção do theaters no banco de dados do sample_mflix a partir do conjunto de dados de amostra.

Os exemplos exigem as seguintes importações:

import com.mongodb.client.model.geojson.Point
import com.mongodb.client.model.geojson.Polygon
import com.mongodb.client.model.geojson.Position
import com.mongodb.client.model.Filters.near
import com.mongodb.client.model.Filters.geoWithin
import com.mongodb.client.model.Projections.fields
import com.mongodb.client.model.Projections.include
import com.mongodb.client.model.Projections.excludeId

Os dados são modelados usando a seguinte classe de dados Kotlin:

data class Theater(
val theaterId: Int,
val location: Location
) {
data class Location(
val address: Address,
val geo: Point
) {
data class Address(
val street1: String,
val street2: String? = null,
val city: String,
val state: String,
val zipcode: String
)
}
}

Os resultados são modelados usando a seguinte classe de dados Kotlin:

data class TheaterResults(
val location: Location
) {
data class Location(
val address: Address
) {
data class Address(
val city: String
)
}
}

A collection theaters já contém um índice 2dsphere no campo "${Theater::location.name}.${Theater.Location::geo.name}" .

Para pesquisar e retornar documento do mais próximo para o mais distante de um ponto, use o método de utilidade estática near() da classe de construtor Filters . O método near() constrói uma query com o operador de query $near .

O exemplo a seguir faz uma query para os cinemas entre 10,000 e 5,000 metros do Grande Gramado do Central Parque:

val database = client.getDatabase("sample_mflix")
val collection = database.getCollection<TheaterResults>("theaters")
val centralPark = Point(Position(-73.9667, 40.78))
val query = Filters.near(
"${Theater::location.name}.${Theater.Location::geo.name}", centralPark, 10000.0, 5000.0
)
val projection = Projections.fields(
Projections.include(
"${Theater::location.name}.${Theater.Location::address.name}.${Theater.Location.Address::city.name}"),
Projections.excludeId()
)
val resultsFlow = collection.find(query).projection(projection)
resultsFlow.collect { println(it) }
TheaterResults(location=Location(address=Address(city=Bronx)))
TheaterResults(location=Location(address=Address(city=New York)))
TheaterResults(location=Location(address=Address(city=New York)))
TheaterResults(location=Location(address=Address(city=Long Island City)))
TheaterResults(location=Location(address=Address(city=New York)))
TheaterResults(location=Location(address=Address(city=Secaucus)))
TheaterResults(location=Location(address=Address(city=Jersey City)))
TheaterResults(location=Location(address=Address(city=Elmhurst)))
TheaterResults(location=Location(address=Address(city=Flushing)))
TheaterResults(location=Location(address=Address(city=Flushing)))
TheaterResults(location=Location(address=Address(city=Flushing)))
TheaterResults(location=Location(address=Address(city=Elmhurst)))

Dica

Curiosidade

O MongoDB utiliza o mesmo sistema de referência que os Satélites gps para calcular geometrias sobre a Terra.

Para obter mais informações sobre o operador $near , consulte a documentação de referência de $near.

Para obter mais informações sobre Filters, consulte nosso guia sobre o construtor de filtros.

Para pesquisar dados geoespaciais dentro de uma forma especificada, utilize o método de utilidade estática geoWithin() da classe de construtor Filters . O método geoWithin() constrói uma query com o operador de query $geoWithin .

O exemplo a seguir pesquisar cinemas em uma seção de Long Console.

val longIslandTriangle = Polygon(
listOf(
Position(-72.0, 40.0),
Position(-74.0, 41.0),
Position(-72.0, 39.0),
Position(-72.0, 40.0)
)
)
val projection = Projections.fields(
Projections.include(
"${Theater::location.name}.${Theater.Location::address.name}.${Theater.Location.Address::city.name}"),
Projections.excludeId()
)
val geoWithinComparison = Filters.geoWithin(
"${Theater::location.name}.${Theater.Location::geo.name}", longIslandTriangle
)
val resultsFlow = collection.find<TheaterResults>(geoWithinComparison)
.projection(projection)
resultsFlow.collect { println(it) }
TheaterResults(location=Location(address=Address(city=Baldwin))))
TheaterResults(location=Location(address=Address(city=Levittown)))
TheaterResults(location=Location(address=Address(city=Westbury)))
TheaterResults(location=Location(address=Address(city=Mount Vernon)))
TheaterResults(location=Location(address=Address(city=Massapequa)))

A figura a seguir mostra o polígono definido pela variável longIslandTriangle e os pontos que representam as localizações dos cinemas retornados por nossa query.

A área de Long Console que procuramos cinemas

Para mais informações sobre o operador $geoWithin , consulte a documentação de referência para $geoWithin

Para obter mais informações sobre os operadores que você pode usar em sua query, consulte a página de manual do servidor MongoDB em operadores de query geoespacial

Próximo

MongoDB Kotlin driver