-
Ponto (POINT);
-
Linha (LINESTRING);
-
Polígono (POLYGON);
-
Multi* (MULTIPOINT,MULTILINESTRING,MULTIPOLYGON,etc);
-
Outros tipos
-
Topology (TOPOGEOM);
-
Raster (RASTER);
-
PolyhedralSurface (POLYHEDRALSURFACE,POLYHEDRALSURFACECEM);
-
CircularString (CIRCULARSTRING);
-
-
A dimensionalidade de uma geometria é o número de informações que podemos derivar da mesma;
-
Pontos são zero dimensionais (não possuem volume, área ou perímetro);
-
Linhas são unidimensionais (possuem comprimento);
-
Polígonos ou áreas são bidimensionais (possuem perímetro e área);
-
Esta noção de dimensionalidade é importante quando falarmos de relações espaciais;
-
Possui a dimensionalidade 0;
-
Construtores comuns:
SELECT ST_AsText(ST_MakePoint(0,0));
SELECT ST_AsEWKT(ST_MakePoint(0,0,0));
SELECT ST_AsEWKT(ST_MakePoint(0,0,0,0));
SELECT ST_GeomFromText('POINT(0 0)',4326);
Fonte: http://en.wikipedia.org/wiki/Well-known_text
-
Possui dimensionalidade 1 (comprimento);
-
Construtores comuns:
SELECT ST_AsText(
ST_MakeLine(ST_MakePoint(0,0),
ST_MakePoint(1,1)));
SELECT ST_AsText(
ST_MakeLine(ARRAY[
ST_MakePoint(0,0),
ST_MakePoint(1,1),
ST_MakePoint(2,0)
]));
SELECT ST_AsText(
ST_GeomFromText('LINESTRING(0 0,1 1,2 0)'));
Fonte: http://en.wikipedia.org/wiki/Well-known_text
-
Possui dimensionalidade 2 (comprimento e área);
-
Construtores comuns:
-- polígono, utilizando MakeLine e MakePoint
SELECT ST_AsText(
ST_MakePolygon(
ST_MakeLine(ARRAY[
ST_MakePoint(0,0),
ST_MakePoint(0,1),
ST_MakePoint(1,1),
ST_MakePoint(1,0),
ST_MakePoint(0,0)])
));
-- polígono, utilizando GeomFromText
SELECT ST_AsText(
ST_MakePolygon(
ST_GeomFromText('LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)')));
-- polígono como buracos
SELECT ST_AsText(
ST_MakePolygon(
ST_GeomFromText('LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)'),
ARRAY[
ST_GeomFromText('LINESTRING(0.5 0.5, 0.5 0.6, 0.6 0.6, 0.6 0.5, 0.5 0.5)')]));
Fonte: http://en.wikipedia.org/wiki/Well-known_text
SELECT ST_AsText(ST_GeomFromText('MULTIPOINT(0 0, 1 1, 2 2, 3 3)'));
Fonte: http://en.wikipedia.org/wiki/Well-known_text
SELECT ST_AsText(ST_GeomFromText('MULTILINESTRING((0 0, 1 1, 2 2, 3 3),(2 1, 3 4, 5 1))'));
Fonte: http://en.wikipedia.org/wiki/Well-known_text
SELECT ST_AsText(
ST_GeomFromText('MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0),(6 6,6 7,7 7,7 6,6 6)))'))
Fonte: http://en.wikipedia.org/wiki/Well-known_text
-
É um tipo de representação simples da geometria de um objeto;
-
BBOX = Bounding Box = Envelope = Mínimo Retângulo Envolvente (existem várias terminologias por aí);
-
Armazena as coordenadas mínimas e máximas de cada geometria;
SELECT Box2D(ST_GeomFromText('LINESTRING(0 0,1 1)'));
-- "BOX(0 0,1 1)"
-
Toda geometria possui uma BBOX;
-
A BBOX de um ponto é o próprio ponto;
SELECT Box2D(ST_GeomFromText('POINT(0 0)'));
-- "BOX(0 0,0 0)"
-
São utilizadas por índices para filtrar e resolver relacionamentos geoespaciais - é muito mais fácil testar se um ponto está dentro de uma BBOX do que testar se o ponto está dentro de um polígono complexo;
-
Agiliza a vida :D;
-
O que são sistemas de referência?
-
Formas de representar a superfície de um objeto ("meio") esférico em um plano;
-
Sistema de coordenadas + Datum + Projeção;
-
-
Sistemas de coordenadas
-
Geográficos;
-
Projectados;
-
-
São definidos numa superfície "esférica";
-
Utiliza medidas angulares para determinar a posição de algo na "esfera";
-
Utilizamos os termos latitude e longitude para localizar a posição;
-
Latitude refere-se ao ângulo entre o equador e um paralelo;
-
Longitude refere-se ao ângulo entre o meridiano central (geralmente Greenwhich) e um meridiano;
Fonte: ESRI (Understanding Map Projections)
-
Na Cartografia convenciou-se nomear as coordendas geográficas como latitude,longitude;
-
Nem sempre será assim em todos os pacotes de softwares.
-
latitude = y
-
longitude = x
-
Este sistema de coordenadas não mantém as distâncias. Ou seja, o valor de 1 grau de latitude no equador é diferente de 1 grau de latitude no paralelo 40N;
-
É determinada por uma esfera ou um elipsóide;
-
A forma da Terra assemelha-se mais a um elipsóide, mas muitos cálculos são executados como se ela fosse uma esfera (mapas de pequenas escala, ou seja 1:5.000.000 ou menor);
-
Escalas maiores (menor que 1:1.000.000) requerem o uso do elipsóide;
Fonte: ESRI (Understanding Map Projections)
-
Uma esfera é baseada num círculo (possui e semieixo maior = semieixo menor);
-
Um elipsóide é baseado numa elipse (valores diferentes dos semieixos maior e menor);
-
Cada região da crosta terrestre ajusta-se bem a um determinado elipsóide;
-
O elipsóide aproxima a forma da Terra;
-
O datum (plural: data) é responsável por posicionar o elipsóide, relativo ao centro da Terra;
-
Podemos ter várias medições (coordenadas) para uma mesma posição, de acordo com o datum escolhido;
Fonte: ESRI (Understanding Map Projections)
-
São sistemas definidos numa superfície plana;
-
São sempre baseados num sistema geográfico;
-
Portanto, são baseados numa esfera ou elipsóide;
-
As coordenadas são dadas por posições x,y, como num gráfico na matemática;
-
Origem: x = 0, y = 0;
-
Operação comumente chamada de projecção;
-
Projecção altera as propriedades espaciais;
-
Imagine uma quadrícula em cima de uma laranja. Corte a casca da laranja e abra a mesma, até ela ficar plana. Os quadradinhos continuam quadradinhos?
Fonte: ESRI (Understanding Map Projections)
- Projecção significa distorção!;
Fonte: ESRI (Understanding Map Projections)
-
Projecções diferentes significam distorções distintas;
-
Projecções conformes mantém a forma;
-
Projecções equidistantes mantém a distância;
-
Projecções azimutais mantém os ângulos;
-
Projecções equivalentes mantém a área;
- Cilíndricas (UTM);
Fonte: ESRI (Understanding Map Projections)
- Planas
Fonte: ESRI (Understanding Map Projections)
- Outros tipos
Fonte: ESRI (Understanding Map Projections)
-
Depende. Varia muito;
-
Qual é a área da aplicação (cartográfica, não computacional)?
-
Quanto menor a área, mais fácil se torna lidar com os dados num sistema projectado;
-
Quanto maior a área, maiores são as distorções exibidas, portanto, um sistema geográfico é melhor;
-
Existem exceções as duas "regras" acima;
-
-
Lembra-se da tabela spatial_ref_sys?
-
Insira um registro com as informações do seu sistema nesta tabela e está pronto;
-
Onde encontro estas informações?
-
Os dados já devem ter um sistema de referência. Não é possível converter um dado geoespacial com sistema de referência
nulo
para outro sistema; -
Utilize a função
ST_Transform
;
SELECT ST_AsText(ST_Transform(ST_GeomFromText('POINT(-47.9 -15.70)',4326),31983));
-- "POINT(189151.648254912 8262118.43615328)"
- Caso a tabela
spatial_ref_sys
não possua o SRID que desejado a conversão falhará!
SELECT ST_AsText(ST_Transform(ST_GeomFromText('POINT(-47.9 -15.70)',4674),1));
-- ERRO: GetProj4StringSPI: Cannot find SRID (1) in spatial_ref_sys
-
Tipo geoespacial mais comum;
-
Amplo suporte de outros softwares;
-
Faz todos os cálculos no plano (mesmo quando se trata de sistemas de referência geográficos);
-
O caminho mais curto entre dois pontos é uma reta;
-
Menos funcionalidade disponível (os cálculos são bem mais complexos);
-
Trabalha no elipsóide;
-
O caminho mais curto entre dois pontos é um grande arco;
-
Só suporta o sistema de referência WGS84 (SRID 4326);
-
Tipos geométricos suportados: POINT,LINESTRING,POLYGON, e MULTIs dos tipos especificados anteriormente;
-
Unidade padrão de pesquisa: metros;
-
Este tipo é mais preciso para ser utilizado quando grandes distâncias estão envolvidas;
-
Calcular a distância entre duas cidades muito distantes é quando este tipo realmente faz a diferença:
-- distância entre seattle e Reykjavik usando geography
SELECT ST_Distance('POINT(-122.33 47.606)'::geography, 'POINT(-21.96 64.15)':: geography);
-- distância entre seattle e Reykjavik, usando geometry
SELECT ST_Distance('POINT(-122.33 47.606)'::geometry, 'POINT(-21.96 64.15)':: geometry);
- Para fazer o mesmo cálculo com o tipo GEOMETRY, seria necessário primeiro converter os dados do sistema de um sistema de referência geográfico para um sistema projetado, para depois calcular a distância em metros (no caso, o PostGIS sempre usa as unidades especificadas no sistema de referência);
-
Índices são que o fazem as bases de dados serem rápidas;
-
Sem índices seria necessário ler toda a tabela de cada vez que fossemos procurar algo;
-
O PostGIS usa o índice GiST (Generalized Search Trees) para os tipos geoespaciais;
-
Suporta formas genéricas de indexação;
-
Funciona excepcionalmente bem com estructuras de dados irregulares;
-
O índice divide os dados em diversas categorias, "dados à esquerda de", "dentro de", etc.
-
Pode indexar valores nulos;
-
O índice do PostGIS ainda embrulha uma implementação de R-Tree, utilizando as BBOX de cada geometria para otimizar muitas buscas;
-
À medida que as tabelas crescem, um índice é um excelente recursos para se ganhar velocidade;
-
Funciona em todos os tipos geométricos;
-
Sempre coleta as estatísticas da tabela após a criação do índice;
CREATE INDEX indice_teste_sede_municipios ON sede_municipal USING GIST(geometria);
VACUUM ANALYZE sede_municipal;
-
PostGIS é PostgreSQL;
-
Tudo o que está disponível no PostgreSQL, está disponível no PostGIS;
-
Suporta queries complexas, agregações, clausúlas where, order by, joins etc;
-
Orders by geoespaciais não são suportados;
SELECT * FROM municipios WHERE ST_Intersects(the_geom,ST_GeomFromText('POLYGON((-48.188 -16.023,-48.188 -15.525,-47.451 -15.525,-47.451 -16.023,-48.188 -16.023))',4326));
-- "Lago Norte"
-- "Riacho Fundo"
-- "Lago Sul"
-- "Cruzeiro"
-- "Guará"
-- "Brazlandia"
-- "Taguatinga"
-- "Sobradinho"
-- "Nucleo Bandeirante"
-- "Santa Maria"
-- "Gama"
-- "Paranoa"
-- "Candangolandia"
-- "Recanto das Emas"
-- "Ceilandia"
-- "Brazilia"
-- "São Sebastião"
SELECT * FROM municipios where ST_Area(geometria::GEOGRAPHY) > 1000 * 1000
-- "Itajaí"
-- "Ji-Paraná"
-- "Mimoso de Goiás"
-- "Parari"
-- "General Maynard"
-- "Amapá"
-- "Ribeirão dos índios"
-- "Cuité de Mamanguape"
-- "Alfredo Vasconcelos"
-- "Porto Vitória"
-- "Manaquiri"
-- "Presidente Médici"
-- "urea"
-- "Vale do Anari"
-- "Itapipoca"
-- "Santarém Novo"
- Este exemplo é mais complexo :D;
-- o operador && significa 'overlaps' para a BBOX!
SELECT SUM(ST_Length(ST_Transform(the_geom,4326)::GEOGRAPHY))/1000 as km FROM hidrografia WHERE ST_Transform(the_geom,4326) ~ ST_GeomFromText('POLYGON((-48.188 -16.023,-48.188 -15.525,-47.451 -15.525,-47.451 -16.023,-48.188 -16.023))',4326);
-
O PostGIS dá ao utilisador diversos operadores que otimizam a execução das funções;
-
Estes operadores tentam sempre utilizar o índice GiST nas suas comparações. Fique atento às queries que constrói, geralmente dá para usar este operador.
-
CUIDADO! Estes operadores agilizam muito as queries, mas eles fazem comparações entre BBOX de geometrias e não a comparação entre as geometrias em si!
-
=
- retorna verdadeiro se a BBOX de A = BBOX de B;
SELECT ST_GeomFromText('LINESTRING(0 0,1 1)') = ST_GeomFromText('LINESTRING(1 1,0 0)');
-- true
&<
- retorna verdadeiro se a BBOX de A sobrepõe ou está a esquerda da BBOX de B;
-- dê-me tudo o que esteja a oeste ou sobreponha a alguma coisa
SELECT ST_GeomFromText('LINESTRING(0 0,-1 -1)') &< ST_GeomFromText('LINESTRING(1 1,0 0)');
-- true
&>
- retorna verdadeiro se a BBOX de A se sobrepõe ou está a direita da BBOX de B;
-- dê-me tudo o que esteja a leste ou sobreponha a alguma coisa
SELECT ST_GeomFromText('LINESTRING(0 0,-1 -1)') &> ST_GeomFromText('LINESTRING(1 1,0 0)');
-- false
SELECT ST_GeomFromText('LINESTRING(0 0,1 1)') &> ST_GeomFromText('LINESTRING(-1 -1,0 0)');
-- true
<<
- retorna verdadeiro se a BBOX de A está estritamente à esquerda da BBOX de B;
-- dê-me tudo o que esteja a oeste de alguma coisa
-- realmente, a BBOX de A é (-2 -2,-1 -1) e a BBOX de B é (0 0,1 1);
SELECT ST_GeomFromText('LINESTRING(-2 -2,-1 -1)') << ST_GeomFromText('LINESTRING(1 1,0 0)');
-- true
-- É pá! neste caso ela não está estritamente à esquerda do B. Elas tocam-se.
SELECT ST_GeomFromText('LINESTRING(0 0,-1 -1)') &< ST_GeomFromText('LINESTRING(1 1,0 0)');
-- false
>>
- retorna verdadeiro se a BBOX de A está estritamente à direita da BBOX de B;
SELECT ST_GeomFromText('LINESTRING(1 1,0 0)') >> ST_GeomFromText('LINESTRING(-2 -2,-1 -1)') ;
-- true
&<|
- retorna verdadeiro se a BBOX de A sobrepõe ou está abaixo da BBOX de B;
SELECT ST_GeomFromText('LINESTRING(0 0,1 1)') &<| ST_GeomFromText('LINESTRING(2 2,3 3)');
-- TRUE
<<|
- retorna verdadeiro se a BBOX de A está estritamente abaixo da BBOX de B;
SELECT ST_GeomFromText('LINESTRING(0 0,1 1)') <<| ST_GeomFromText('LINESTRING(2 2,3 3)');
-- TRUE
|&>
- retorna verdadeiro se a BBOX de A está sobreposta ou acima da BBOX de B;
SELECT ST_GeomFromText('LINESTRING(2 2,3 3)') |&>ST_GeomFromText('LINESTRING(0 0,1 1)');
-- TRUE
|>>
- retorna verdadeiro se a BBOX de A está estritamente acima da BBOX de B;
SELECT ST_GeomFromText('LINESTRING(2 2,3 3)') |>> ST_GeomFromText('LINESTRING(0 0,1 1)');
-- TRUE
~=
- retorna verdadeiro se as geometrias A e B são exatamente iguais;
SELECT ST_GeomFromText('LINESTRING(0 0,1 1)') ~= ST_GeomFromText('LINESTRING(0 0,1 1)');
-- true
SELECT ST_GeomFromText('LINESTRING(0 0,1 1)') ~= ST_GeomFromText('LINESTRING(1 1,0 0)');
-- true
@
- retorna verdadeiro se a BBOX de A está completamente contida na BBOX de B;
SELECT ST_GeomFromText('LINESTRING(0 0,1 1)') @ ST_GeomFromText('LINESTRING(-10 -10,10 10)');
-- true
SELECT ST_GeomFromText('LINESTRING(-10 -10,10 10)') @ ST_GeomFromText('LINESTRING(0 0,1 1)') ;
-- false
~
- retorna verdadeiro se a BBOX de A contém completamente a BBOX de B;
SELECT ST_GeomFromText('LINESTRING(-10 -10,10 10)') ~ ST_GeomFromText('LINESTRING(0 0,1 1)') ;
-- true
&&
- retorna verdadeiro se a BBOX de A sobrepõe a BBOX de B - este é um operador muito útil!;
SELECT ST_GeomFromText('LINESTRING(-10 -10,10 10)') && ST_GeomFromText('LINESTRING(9 9,12 12)');
- AddGeometryColumn;
- DropGeometryColumn;
- DropGeometryTable;
- PostGIS_Full_Version;
- Populate_Geometry_Columns;
- UpdateGeometrySRID;
- ST_GeomFromText;
- ST_MakePoint;
- ST_MakeLine;
- ST_MakePolygon;
- ST_MakeBox2D;
- ST_GeogFromText;