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.

Now let’s insert a linestring into our streets table. In this case we will update an existing street record:

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

Criar polígonos é igualmente fácil. Uma coisa a lembrar é que, por definição, os polígonos têm pelo menos quatro vértices, com o último e o primeiro co-localizados:

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 de pessoas atualizado deve se parecer 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)

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:

  • Transform the polygon boundary to a linestring:

    select st_boundary(geometry) from myPolygonTable;
    
  • Select the first vertex point of the resultant linestring:

    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 subparte dos seus dados, você pode usar a função ST_INTERSECT (). Para evitar geometrias vazias, use:

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 linestring a partir de uma nova camada de pontos 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

You can get more information for this topic in this blog entry.

16.5.12. As diferenças entre as tabelas

Para detectar a diferença 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 deve armazenar seus dados no disco criando espaços de tabela:

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.