Usando funções de dados GeoJSON

A especificação GeoJson define a estrutura e o conteúdo de objetos JSON que supostamente representam formas geográficas na terra (chamadas geometrias). De acordo com a especificação GeoJson, para que um objeto JSON seja um objeto de geometria, ele deve ter dois campos chamados tipo e coordenadas, em que o valor do campo de tipo especifica o tipo de geometria e o valor das coordenadas deve ser um array cujos elementos definem a forma geométrica.

Todos os tipos de geometrias são especificados em termos de um conjunto de posições. No entanto, para cordas de linha e polígonos, a forma geométrica real é formada pelas linhas que conectam suas posições. A especificação GeoJson define uma linha entre dois pontos como a linha reta que conecta os pontos no sistema de coordenadas cartesianas (plano) cujos eixos horizontais e verticais são a longitude e a latitude, respectivamente.

Existem várias funções incorporadas que interpretam objetos JSON como geometrias e permitem pesquisar as linhas que contêm geometrias que satisfazem determinadas condições.

Para seguir os exemplos, crie uma tabela na console do OCI usando o Modo de Entrada DDL Avançada. A instrução DDL é fornecida a seguir.

CREATE TABLE IF NOT EXISTS PointsOfInterest (
    id INTEGER, poi JSON,
PRIMARY KEY(id));

Consulte Criando Tabela Singleton: Modo de Entrada DDL Avançada para obter etapas para criar uma tabela com uma instrução DDL.

Para carregar dados na tabela criada na console do OCI, clique no nome da tabela. Os detalhes da tabela são exibidos. Clique em Fazer Upload de Dados. Clique em selecionar arquivo para upload e forneça o arquivo JSON a ser submetido a upload. Você pode fazer download do arquivo DDL e JSON para os dados GeoJSON aqui

geo_interno

Determina geometrias dentro de uma geometria GeoJSON delimitadora.

boolean geo_inside(any*, any*)

A função determina se a geometria apontada pelo primeiro parâmetro está completamente contida dentro do polígono apontado pelo segundo parâmetro.

Se algum dos dois parâmetros não retornar um único objeto de geometria válido, e se ele puder ser detectado no tempo de compilação, a função gerará um erro.

O comportamento do runtime é o seguinte:

Observação: O interior de um polígono são todos os pontos na área do polígono, exceto os pontos no anel linear que definem o limite do polígono.

Exemplo:Procure parques naturais no norte da Califórnia.

SELECT t.poi.name AS park_name,
t.poi.address.street AS park_location
FROM PointsOfInterest t
WHERE t.poi.kind = "nature park"
AND geo_inside(t.poi.location,
              { "type" : "polygon",
                "coordinates": [[
                  [-
120.1135253906249, 36.99816565700228],
                  [-119.0972900390625, 37.391981943533544],
                  [-119.2840576171875, 37.97451499202459],
                  [-120.2069091796874, 38.035112420612975],
                  [-122.3822021484375, 37.74031329210266],
                  [-122.2283935546875, 37.15156050223665],
                  [-121.5362548828124, 36.85325222344018],
                  [-120.1135253906249, 36.99816565700228]
                ]]
             });

Explicação:

Resultado:

{"park_name":"portola redwoods state park",
"park_location":"15000 Skyline Blvd"}

geo_interseção

Determina geometrias que se cruzam com uma geometria GeoJSON.

boolean geo_intersect(any*, any*)

O primeiro e o segundo parâmetros any* podem ser qualquer objeto geométrico.

A função determina se duas geometrias que são especificadas como parâmetros têm pontos em comum. Se algum dos dois parâmetros não retornar um único objeto de geometria válido, e se ele puder ser detectado no tempo de compilação, a função gerará um erro.

O comportamento do runtime é o seguinte:

Se ambos os parâmetros retornarem um único objeto de geometria cada, a função retornará verdadeiro se as 2 geometrias tiverem pontos em comum; caso contrário, falso.

Exemplo:A Texas está considerando regulamentar o acesso ao abastecimento de água subterrânea. Um aquífero é uma camada subterrânea de rocha permeável à água, fraturas rochosas ou materiais não consolidados. O governo quer impor novos regulamentos para locais que estão muito perto de um aquífero.

As coordenadas do aquífero já foram mapeadas. Você quer saber todos os condados do estado do Texas que se cruzam com esse aquífero para que você possa notificar o governo do condado para cada condado afetado para participar das negociações para os novos regulamentos.

SELECT t.poi.county AS County_needs_regulation,
t.poi.contact AS Contact_phone
FROM PointsOfInterest t WHERE
geo_intersect(
    t.poi.location,
    {

     "type" : "polygon",
      "coordinates": [
          [
            [-97.668457031249, 29.34387539941801],
            [-95.207519531258, 29.19053283229458],
            [-92.900390625653, 30.37287518811801],
            [-94.636230468752, 32.21280106801518],
            [-97.778320312522, 32.45415593941475],
            [-99.799804687541, 31.18460913574325],
            [-97.668457031249, 29.34387539941801]
          ]
        ]
    }
);

Explicação:

Resultado:

{"County_needs_regulation":"Tarrant","Contact_phone":"469 745 5687"}
{"County_needs_regulation":"Kinga","Contact_phone":"469 384 7612"}

geo_distância

Determina a distância entre dois objetos geoespaciais.

double geo_distance(any*, any*)

O primeiro e o segundo parâmetros any* podem ser qualquer objeto geométrico.

A função retorna a distância geodésica entre as duas geometrias de entrada. A distância retornada é o mínimo entre as distâncias de qualquer par de pontos onde o primeiro ponto pertence à primeira geometria e o segundo ponto à segunda geometria. Entre dois desses pontos, sua distância é o comprimento da linha geodésica que conecta os pontos.

Visão Geral da Linha Geodética

Uma linha geodésica entre 2 pontos é a linha mais curta que pode ser traçada entre os 2 pontos na superfície elipsoidal da terra. Para uma definição simplificada, mas mais ilustrativa, suponha por um momento que a superfície da Terra é uma esfera. Então, a linha geodésica entre dois pontos na terra é o arco menor entre os dois pontos no grande círculo correspondente aos pontos, ou seja, o círculo que é formado pela interseção da esfera e o plano definido pelo centro da terra e os dois pontos.

A figura a seguir mostra a diferença entre as linhas geodésicas e retas entre Los Angeles e Londres.

Segue-se a descrição de geodetic-vs-straight-line.jpg

Descrição da ilustração geodetic-vs-straight-line.jpg

Se algum dos dois parâmetros não retornar um único objeto de geometria válido, e se ele puder ser detectado no tempo de compilação, a função gerará um erro.

O comportamento do runtime é o seguinte:

Caso contrário, a função retorna a distância geodésica em metros entre as 2 geometrias de entrada.

Observação: os resultados são classificados em ordem crescente por distância (exibindo a distância mais curta primeiro).

Exemplo:Até onde fica o restaurante mais próximo do local fornecido?

SELECT
t.poi.name AS restaurant_name,
t.poi.address.street AS street_name,
geo_distance(
    t.poi.location,
    {
       "type" : "point",
       "coordinates": [-
121.94034576416016,37.2812239247177]
    }
) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "restaurant" ;

Explicação:

Resultado:

{"restaurant_name":"Coach Sports Bar & Grill","street_name":"80 Edward St","distance_in_meters":799.2645323337218}
{"restaurant_name":"Ricos Taco","street_name":"80 East Boulevard St","distance_in_meters":976.5361117138553}
{"restaurant_name":"Effie's Restaurant and Bar","street_name":"80 Woodeard St","distance_in_meters":2891.0508307646282}

A distância entre a localização atual e o restaurante mais próximo é de 799 metros.

geo_dentro_distância

Determina objetos geoespaciais próximos de um ponto.

boolean geo_within_distance(any*, any*,double)

O primeiro e o segundo parâmetros any* podem ser qualquer objeto geométrico.

A função determina se a primeira geometria está a uma distância de N metros da segunda geometria.

Se algum dos dois parâmetros não retornar um único objeto de geometria válido, e se ele puder ser detectado no tempo de compilação, a função gerará um erro.

O comportamento do runtime é o seguinte:

Finalmente, se ambos os parâmetros retornarem um único objeto de geometria cada, ele retornará verdadeiro se a primeira geometria estiver a uma distância de N metros da segunda geometria, onde N é o número retornado pelo terceiro parâmetro; caso contrário, falso. A distância entre 2 geometrias é definida como o mínimo entre as distâncias de qualquer par de pontos onde o primeiro ponto pertence à primeira geometria e o segundo ponto à segunda geometria. Se N for um número negativo, ele será definido como 0.

Exemplo:Há uma prefeitura nos próximos 5 km? Qual é a distância?

SELECT t.poi.address.street AS city_hall_address,
geo_distance(
    t.poi.location,
    {
        "type" : "point",
        "coordinates" : [-120.653828125,38.85682013474361]
    }

) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "city hall" AND
geo_within_distance(
    t.poi.location,
    {
        "type" : "point",
        "coordinates" : [-120.653828125,38.85682013474361]
    },
    5000
);

Explicação:

Resultado:

{"city_hall_address":"70 North 1st street","distance_in_meters":1736.0144040331768}

A prefeitura fica a 1736 m(1,73 km) da localização atual.

geo_near

Determina objetos geoespaciais próximos de um ponto.

boolean geo_near(any*, any*, double)

O primeiro e o segundo parâmetros any* podem ser qualquer objeto geométrico.

A função determina se a primeira geometria está a uma distância de N metros da segunda geometria.

Se algum dos dois parâmetros não retornar um único objeto de geometria válido, e se ele puder ser detectado no tempo de compilação, a função gerará um erro.

O comportamento do runtime é o seguinte:

Finalmente, se ambos os dois primeiros parâmetros retornarem um único objeto de geometria cada, ele retornará verdadeiro se a primeira geometria estiver a uma distância de N metros da segunda geometria, onde N é o número retornado pelo terceiro parâmetro; caso contrário, falso.

Observação: geo_near é convertido internamente em geo_within_distance mais uma ordem (implícita) pela distância entre as duas geometrias. No entanto, se a consulta já tiver um order-by (explícito), nenhuma ordenação por distância será executada. A função geo_near só pode aparecer na cláusula WHERE, onde deve ser um predicado de nível superior, ou seja, não aninhado em um operador OR ou NOT.

Exemplo 1:Existe um hospital a 3 km do local indicado?

SELECT
t.poi.name AS hospital_name,
t.poi.address.street AS hospital_address
FROM PointsOfInterest t
WHERE t.poi.kind = "hospital"
AND
geo_near(
    t.poi.location,
    {"type" : "point",
     "coordinates" : [-122.03493933105469,37.32949164059004]
    },
    3000
);

Explicação:

Resultado:

{"hospital_name":"St. Marthas hospital","hospital_address":"18000 West Blvd"}
{"hospital_name":"Memorial hospital","hospital_address":"10500 South St"}

Exemplo 2: Qual é a distância de um posto de gasolina na próxima milha do local fornecido?

SELECT
t.poi.address.street AS gas_station_address,
geo_distance(
    t.poi.location,
    {
        "type" : "point",
        "coordinates" : [-121.90768646240233,37.292081740702365]
    }
) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "gas station" AND
geo_near(
    t.poi.location,
    {
        "type" : "point",
        "coordinates" : [-121.90768646240233,37.292081740702365]
    },
    1600
);

Explicação:

Resultado:

{"gas_station_address":"33 North Avenue","distance_in_meters":886.7004173859665}

A distância real para o posto de gasolina mais próximo dentro da próxima milha é de 886m.

geo_is_geometria

Valida um objeto geoespacial.

boolean geo_is_geometry(any*)

O parâmetro any* pode ser qualquer objeto geométrico.

A função determina se a entrada fornecida é um objeto de geometria válido.

Exemplo: determine se o local que aponta para o salão da cidade é um objeto geométrico válido.

SELECT geo_is_geometry(t.poi.location) AS city_hall
FROM PointsOfInterest t
WHERE t.poi.kind = "city hall"

Explicação: use a função geo_is_geometry para determinar se um determinado local é ou não um objeto geométrico válido.

Resultado:

{ "city_hall" : true}

Tópicos Relacionados