17.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.

17.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.

17.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

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.

17.5.3. Criando poligonos

Creating polygons is just as easy. One thing to remember is that by definition, polygons have at least four vertices, with the last and first being co-located:

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.

17.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.

Your updated people schema should look something like this:

\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

17.5.5. Verificando nosso esquema

Por enquanto, nosso esquema deve estar parecendo com isso:

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

17.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.

17.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;
    

17.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_.

17.5.9. Recortando

To clip a subpart of your data you can use the ST_INTERSECT() function. To avoid empty geometries, 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

17.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

To create a linestring from a new point layer called ‘points’, you can run the following command:

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

17.5.11. Limpeza de Geometria

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

17.5.12. As diferenças entre as tabelas

To detect the difference between two tables with the same structure, you can use the PostgreSQL keyword 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.

17.5.13. Tablespaces

You can define where postgres should store its data on disk by creating 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

17.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.