quarta-feira, 6 de junho de 2012

Manipulação de Geometrias via SQL API

Olá Pessoal, vamos falar um pouco sobre manipulação de geometrias por SQL.

Há alguns bancos de dados com extensão espacial que são aderentes aos padrões da OGC (Open GIS Consortium), mais especificamente ao padrão SFS (Simple Feature Specification) que define como armazenar, recuperar e manipular dados geográficos. Este padrão, ainda, especifica algumas funções para manipular os dados.
A função st_astext por exemplo exibe a geometria numa forma textual, st_within é um operador relacional para buscas espaciais, que verifica se uma geometria está contida em outra, e estes são apenas alguns exemplos dentre de uma infinidade de funções.

O SDE disponibiliza grande parte destas funções da SFS para serem usadas pela API SQL. Vou, então, apresentar alguns exemplos de como manipular dados geográficos diretamente no geodatabase, através desta uma API para SQL.

Neste exemplo vamos utilizar um geodatabase em ambiente Oracle e utilizar a API do SDE.

Primeiro temos que configurar a library do SDE para ser usada pelo Oracle. Quando instalamos o SDE, ele cria uma lib no oracle chamada st_shapelib, que aponta para uma lib do SDE chamada st_shapelib.dll (windows) ou libst_shapelib.so (linux/unix). Basta que configuremos o listener e o tnsnames.ora do servidor. Para tal,

-Adicione a seguinte entrada ao arquivo tnsnames.ora:
EXTPROC_CONNECTION_DATA =
  (DESCRIPTION = 
  (ADDRESS_LIST = 
    (ADDRESS = 
     (PROTOCOL = IPC)
      (KEY = extproc)  
     ) 
   ) 
    (CONNECT_DATA = 
     (SID = PLSExtProc) 
      (PRESENTATION = RO) 
     ) 
  )
-Adicione a seguinte entrada ao arquivo listener.ora
(SID_DESC = 
   (SID_NAME = PLSExtProc) 
   (ORACLE_HOME =) 
   (PROGRAM = extproc)
   (ENVS="EXTPROC_DLLS=\st_shapelib.dll;")  
)
Mais informações podem ser obtidas em: Configuring the Oracle listener to access the geodatabase with SQL. Em seguida vamos criar duas FeatureClasses, uma de pontos e outra de polígonos. Vamos adicionar algumas geometrias em cada uma delas e o resultado será algo próximo a figura abaixo:



Vamos começar pelo exemplo mais simples, que é usar a função st_astext citada anteriormente.

A query
SELECT sde.st_astext(shape) FROM pontos WHERE objectid = 2
deverá retornar algo parecido com "POINT ( -143.93847656 66.22540283)" que é a representação textual de um dos pontos.

Vamos agora experimentar buscar todos os pontos que estão contidos no polígono de ID=1.
SELECT * FROM PONTOS A 
 WHERE SDE.ST_CONTAINS(
       (SELECT B.SHAPE FROM POLIGONOS B WHERE B.OBJECTID = 1), A.SHAPE) = 1
Logo vemos que esta query nos retorna 3 registros, ou seja, 3 pontos.

Repare na figura que há um ponto muito próximo do polígono de ID=1, este ponto é também ID=1.
Vamos então calcular a distância que ele está do polígono ID=1.
SELECT SDE.ST_DISTANCE(
       (SELECT SHAPE FROM PONTOS WHERE OBJECTID = 1), 
       (SELECT SHAPE FROM POLIGONOS WHERE OBJECTID = 1)) FROM DUAL
Aqui a distância é 2,703.

Podemos então fazer um buffer no polígono ID=1, com o valor desta distância mais 0.001 e veremos que a query irá retornar também o ponto ID=1.
SELECT * 
  FROM PONTOS A 
 WHERE SDE.ST_CONTAINS(
       (SELECT sde.st_buffer(B.SHAPE, 2.704) 
          FROM POLIGONOS B WHERE B.OBJECTID = 1), A.SHAPE) = 1
Essa query nos retorna 4 registros, ou melhor, os 4 pontos que deveria.

Bom, por hoje é isso. Num futuro próximo exploraremos mais esta API e o que podemos fazer com ela. ;-)

2 comentários:

  1. muito bom....agora vou usar seu site pare indexar o meu no google....kkk
    www.aciex.com.br

    ResponderExcluir