Outdated version of the documentation. Find the latest one here.

16.5. geometria de construção

Nesta seção, vamos nos aprofundar um pouco mais em como as geometrias simples são construídas com SQL. Na realidade, você provavelmente irá usar um GIS como QGIS para criar geometrias complexas, utilizando suas ferramentas de digitalização; no entanto, compreender como elas são formuladas pode ser útil para escrever consultas e entender como o banco de dados é montado.

O objetivo desta lição: entender melhor como criar entidades espaciais diretamente no PostgreSQL/PostGIS.

16.5.1. Criando linhas

Voltando ao nosso banco de dados address, vamos deixar a nossa tabela streets igual às outras; ou seja, tendo uma restrição na geometria, um índice e uma entrada na tabela geometry_columns.

16.5.2. Try Yourself moderate

  • Modifique a tabela streets para que ela tenha uma coluna geometria do tipo ST_LineString.

  • Não se esqueça de fazer a atualização correspondente na tabela geometry_columns!

  • Crie também uma restrição para evitar que quaisquer geometrias diferentes de LINESTRINGS ou nulo sejam inseridas.

  • Crie um índice espacial para a nova coluna do tipo geometry.

Verifique seus resultados

Agora vamos inserir uma linha em nossa tabela ‘streets’. Neste caso, vamos atualizar um registro existente em ‘streets’:

update streets set the_geom = 'SRID=4326;LINESTRING(20 -33, 21 -34, 24 -33)'
where streets.id=2;

Dê uma olhada nos resultados no QGIS. (Você pode precisar clicar com o botão direito sobre a camada street no painel ‘Camadas’, e escolher a opção ‘Zoom para a camada’.)

Agora, crie mais alguns registros em ‘streets’ - alguns pelo QGIS e alguns pela linha de comando.

16.5.3. Criando poligonos

A criação de polígonos é muito fácil. Uma coisa a se lembrar é que, por definição, polígonos têm pelo menos quatro vértices, sendo o último e o primeiro vértices na mesma localização:

insert into cities (name, the_geom)
values ('Tokyo', 'SRID=4326;POLYGON((10 -10, 5 -32, 30 -27, 10 -10))');

Nota

Um polígono requer colchetes duplos em torno de sua lista de coordenadas; isto serve para permitir que você adicione polígonos complexos com múltiplas áreas não conectadas. Por exemplo:

insert into cities (name, the_geom)
values ('Tokyo Outer Wards', 'SRID=4326;POLYGON((20 10, 20 20, 35 20, 20 10),
      (-10 -30, -5 0, -15 -15, -10 -30))');

Se você seguir esse passo, você poderá verificar o que ele faz carregando o DataSet ‘cities’ no QGIS, abrindo a sua tabela de atributos, e selecionando o novo registro. Note como os dois novos polígonos comportam-se como um único polígono.

16.5.4. Exercício: Ligando Cidades a Pessoas

Para este execício você deve fazer o seguinte:

  • Delete todos os dados da tabela ‘people’.

  • Adicione uma coluna de chave estrangeira na tabela ‘people’ que referencie a chave primária da tabela ‘cities’.

  • Use QGIS para capturar algumas cidades.

  • Use SQL para inserir alguns registros novos de pessoas, garantindo que cada um tenha uma rua e uma cidade associados aos mesmos.

Seu esquema atualizado de ‘people’ deve estar parecido com isso:

\d people

Table "public.people"
   Column   |         Type          |                      Modifiers
 -----------+-----------------------+--------------------------------------------
  id        | integer               | not null
            |                       | default nextval('people_id_seq'::regclass)
  name      | character varying(50) |
  house_no  | integer               | not null
  street_id | integer               | not null
  phone_no  | character varying     |
  the_geom  | geometry              |
  city_id   | integer               | not null
Indexes:
  "people_pkey" PRIMARY KEY, btree (id)
  "people_name_idx" btree (name)
Check constraints:
  "people_geom_point_chk" CHECK (st_geometrytype(the_geom) =
                       'ST_Point'::text OR the_geom IS NULL)
Foreign-key constraints:
  "people_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cities(id)
  "people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)

Verifique seus resultados

16.5.5. Verificando nosso esquema

Por enquanto, nosso esquema deve estar parecendo com isso:

../../../_images/final_schema.png

16.5.6. Try Yourself hard

Crie limites de cidade computando o menor polígono que contenha todos os endereços para aquela cidade e crie um buffer em torno dessa área.

16.5.7. Acessando Subobjetos

Com as funções do modelo SFS, você tem uma grande variedade de opções para acessar subobjetos de Geometrias SFS. Quando você quiser selecionar o primeiro vértice de cada polígono na tabela myPolygonTable, você terá que fazer dessa maneira:

  • Transformando o limite do polígono em uma linha:

    select st_boundary(geometry) from myPolygonTable;
  • Selecionando o primeiro vértice da linha resultante:

    select st_startpoint(myGeometry)
    from (
        select st_boundary(geometry) as myGeometry
        from myPolygonTable) as foo;

16.5.8. Processamento de dados

O PostGIS suporta todas as funções conformes do padrão OGC SFS/MM. Todas essas funções começam com ST_.

16.5.9. Recortando

Para recortar uma parte de seus dados você pode usar a função ST_INTERSECT(). Para evitar geometrias vazias, utilize:

where not st_isempty(st_intersection(a.the_geom, b.the_geom))
../../../_images/qgis_001.png
select st_intersection(a.the_geom, b.the_geom), b.*
from clip as a, road_lines as b
where not st_isempty(st_intersection(st_setsrid(a.the_geom,32734),
  b.the_geom));
../../../_images/qgis_002.png

16.5.10. Construindo Geometrias a partir de outras Geometrias

A partir de uma determinada tabela de pontos, você quer gerar uma linha. A ordem dos pontos é definida pelo id. Outro método de ordenação poderia ser o horário, como quando você captura pontos em um caminho com um receptor GPS.

../../../_images/qgis_006.png

Para criar uma linha a partir de uma nova camada do tipo ponto chamada ‘points’, você pode executar o seguinte comando:

select ST_LineFromMultiPoint(st_collect(the_geom)), 1 as id
from (
  select the_geom
  from points
  order by id
) as foo;

Para ver como isso funciona sem criar uma nova camada, você também pode executar esse comando sobre a camada ‘people’, embora, naturalmente, fizesse pouco sentido fazer isso no mundo real.

../../../_images/qgis_007.png

16.5.11. Limpeza de Geometria

Você pode conseguir mais informações sobre este tópico nesse blog: <http://linfiniti.com/?s=cleangeometry>`_.

16.5.12. As diferenças entre as tabelas

Para detectar diferenças entre duas tabelas com a mesma estrutura, você pode usar a palavra-chave do PostgreSQL EXCEPT:

select * from table_a
except
select * from table_b;

Como resultado, você terá todos os registros de table_a que não estão presentes em table_b.

16.5.13. Tablespaces

Você pode definir onde o Postgres deverá armazenar seus dados no disco criando tablespaces:

CREATE TABLESPACE homespace LOCATION '/home/pg';

Quando você cria um banco de dados, você pode especificar qual tablespace usar. Por exemplo:

createdb --tablespace=homespace t4a

16.5.14. In Conclusion

Você aprendeu como criar geometrias mais complexas usando declarações do PostGIS. Tenha em mente que isso é principalmente para melhorar o seu conhecimento tácito ao trabalhar com bancos de dados geo-capacitados através de uma interface GIS. Você normalmente não precisará entrar com essas declarações manualmente, mas ter uma ideia geral de sua estrutura irá ajudá-lo quando for usar um SIG, especialmente se você encontrar erros que de outra forma podem parecer enigmáticos.