Se você usa QGIS faz tempo e tá começando a sofrer com shapefile travando, GeoPackage corrompendo, projeto demorando pra abrir e múltiplas pessoas tentando editar o mesmo dado, eu tenho uma notícia boa. O problema não é seu computador. É que você passou do ponto onde arquivo dá conta. Você precisa de banco de dados espacial. E o melhor banco de dados espacial do mercado é gratuito, open source e se chama PostGIS.
Neste tutorial você vai sair do zero e chegar no seu primeiro JOIN espacial funcionando em menos de uma hora. Eu vou te mostrar como instalar PostgreSQL e PostGIS, como conectar o QGIS, como subir seu primeiro shapefile, como rodar a primeira query, como fazer um JOIN espacial entre duas camadas e como criar índice pra tudo voar. Cada seção tem código pronto pra copiar. Vamos.
O que é PostGIS e por que parar de usar shapefile
PostgreSQL é um banco de dados relacional, igual MySQL ou SQL Server, mas open source e mais sério. PostGIS é uma extensão que ensina o PostgreSQL a entender geometria. Com PostGIS você guarda ponto, linha e polígono dentro do banco e roda análise espacial direto em SQL.
Por que isso é melhor que shapefile? Vou listar os motivos que aparecem na vida real:
- Shapefile tem limite de 2 GB. Quando seu dado passa disso, você tá perdido. PostGIS aguenta tabela com bilhões de linha.
- Shapefile é três ou quatro arquivos. Perdeu o .prj, era. PostGIS é uma tabela só, dentro de um banco que faz backup automático.
- Shapefile é mono-usuário. Duas pessoas editando o mesmo .shp ao mesmo tempo é receita pra corrupção. PostGIS é multi-usuário desde o primeiro dia.
- Shapefile não faz JOIN bem. Você abre tabela em Excel pra cruzar dado. Em PostGIS é uma linha de SQL.
- PostGIS conversa com Power BI, Python, R, Tableau, Metabase, Superset, Looker e qualquer ferramenta que fale SQL. Shapefile não conversa com nada disso direito.
Por que isso importa pra você: se você quer trabalhar em empresa séria de GIS, você vai usar PostGIS. Não tem fintech, agtech ou consultoria grande rodando análise espacial em shapefile.
Instalando PostgreSQL e PostGIS
Tem três caminhos. Escolhe o seu.
Windows. Baixa o instalador do PostgreSQL no site oficial (postgresql.org). Roda o instalador, define senha do usuário postgres (anota essa senha, você vai usar), aceita porta padrão 5432. Na última tela o instalador abre o Stack Builder. Ali você seleciona “Spatial Extensions” e instala o PostGIS. Pronto, banco e extensão prontos.
Linux (Ubuntu/Debian).
sudo apt update
sudo apt install postgresql postgresql-contrib postgis
sudo systemctl enable postgresql
sudo systemctl start postgresql
Habilitando a extensão. Independente de qual caminho você escolheu, depois de instalar você precisa rodar uma vez no banco:
CREATE EXTENSION IF NOT EXISTS postgis;
SELECT PostGIS_Version();
Se a segunda linha retornar algo tipo 3.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1, parabéns, você tá com PostGIS funcionando.
Conectando o QGIS no PostGIS
QGIS tem um cliente PostGIS embutido que se chama DB Manager (no menu Banco de Dados). Mas a forma mais rápida é o painel Browser.
- Abre QGIS, vai no painel Browser à esquerda.
- Clica direito em PostgreSQL e escolhe Nova conexão.
- Preenche: Nome (qualquer apelido), Host (
localhostse for local), Porta (5432), Banco (meugisou o que você nomeou), Usuário, Senha. - Marca “Salvar usuário” e “Salvar senha” pra não digitar toda hora.
- Clica em Testar conexão. Se der “Conexão bem-sucedida”, você tá dentro.
Pronto, agora qualquer tabela espacial que você criar no banco aparece direto no Browser do QGIS, e você arrasta pra dentro do mapa igual arrasta um shapefile.
Por que isso importa pra você: PostGIS não substitui o QGIS, ele turbina o QGIS. Você ganha o melhor dos dois mundos: SQL no banco, mapa no QGIS.
Importando seu primeiro shapefile pro PostGIS
Tem três formas. Vou te mostrar a mais simples primeiro.
Pelo QGIS (mais fácil).
- Abre o shapefile no QGIS.
- Clica direito na camada, Exportar, Salvar feições como.
- Em Formato escolhe PostgreSQL SQL dump ou usa o DB Manager, Importar camada.
- Seleciona a conexão que você criou, define o nome da tabela (sem espaço, sem acento, em minúscula), confirma o SRID e manda.
Pelo terminal (mais rápido em massa).
shp2pgsql -I -s 4326 municipios.shp public.municipios | psql -U gis -d meugis
Tradução: -I cria índice espacial, -s 4326 define SRID (sistema de coordenadas) como WGS84, e o pipe joga o SQL gerado direto pro banco.
A partir de CSV com lat/lon. Se você tem um CSV com colunas latitude e longitude, sobe primeiro como tabela comum e depois cria a coluna geométrica:
CREATE TABLE escolas (
id SERIAL PRIMARY KEY,
nome TEXT,
latitude DOUBLE PRECISION,
longitude DOUBLE PRECISION
);
\COPY escolas(nome, latitude, longitude)
FROM '/caminho/escolas.csv' DELIMITER ',' CSV HEADER;
ALTER TABLE escolas ADD COLUMN geom geometry(Point, 4326);
UPDATE escolas
SET geom = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326);
Atenção pra ordem: ST_MakePoint recebe (longitude, latitude), não o contrário. Esse é o erro mais comum de quem tá começando.
Tipos espaciais: GEOMETRY vs GEOGRAPHY
PostGIS tem dois tipos principais pra guardar dado espacial. A diferença muda muito o resultado de cálculo.
GEOMETRY trata o mundo como plano cartesiano. Se você projeta os dados num SRID métrico (tipo SIRGAS 2000 / UTM 23S, que é EPSG:31983), distância e área saem em metros e quadrados. Rápido, padrão da indústria, recomendado pra 95% dos casos.
GEOGRAPHY trata o mundo como esfera (na verdade elipsoide). Distância sempre em metros, sem precisar reprojetar. Mais preciso pra distâncias continentais, mas mais lento e suporta menos funções.
Regra prática que eu uso: trabalha com GEOMETRY em SRID métrico local (UTM da sua região no Brasil) sempre que possível. Reserva GEOGRAPHY pra quando você precisa medir distância entre Manaus e Porto Alegre sem se preocupar com projeção.
Sistemas de coordenadas em PostGIS (SRID e ST_Transform)
Todo dado espacial em PostGIS tem um SRID, que é o número que identifica o sistema de referência. WGS84 (lat/lon) é 4326. SIRGAS 2000 / UTM 23S é 31983. Web Mercator é 3857.
Pra reprojetar uma camada, você usa ST_Transform:
SELECT id, nome, ST_Transform(geom, 31983) AS geom_utm
FROM municipios;
Se você quer guardar a versão reprojetada como uma nova coluna ou tabela:
CREATE TABLE municipios_utm AS
SELECT id, nome, ST_Transform(geom, 31983)::geometry(MultiPolygon, 31983) AS geom
FROM municipios;
CREATE INDEX ON municipios_utm USING GIST (geom);
Atenção: pra reprojetar funcionar, o SRID original do dado precisa estar declarado. Se sua tabela veio sem SRID definido (você vê SRID 0 quando consulta), você seta primeiro:
SELECT UpdateGeometrySRID('municipios', 'geom', 4326);
Por que isso importa pra você: 80% dos erros estranhos em PostGIS são SRID errado ou ausente. Sempre confere o SRID antes de calcular qualquer coisa.
Sua primeira query: ST_Area, ST_Length, ST_Distance
Agora começa a parte legal. Calcular área, comprimento e distância em SQL puro.
Área de cada município, em km²:
SELECT
nome,
ST_Area(ST_Transform(geom, 31983)) / 1000000 AS area_km2
FROM municipios
ORDER BY area_km2 DESC
LIMIT 10;
Comprimento de cada rodovia, em km:
SELECT
nome,
ST_Length(ST_Transform(geom, 31983)) / 1000 AS comprimento_km
FROM rodovias
ORDER BY comprimento_km DESC;
Distância entre cada escola e o hospital mais próximo:
SELECT
e.nome AS escola,
h.nome AS hospital_mais_proximo,
ST_Distance(
ST_Transform(e.geom, 31983),
ST_Transform(h.geom, 31983)
) AS distancia_metros
FROM escolas e
CROSS JOIN LATERAL (
SELECT nome, geom
FROM hospitais
ORDER BY e.geom <-> hospitais.geom
LIMIT 1
) h;
O operador <-> é o KNN (K-Nearest Neighbors) do PostGIS. Ele usa o índice espacial pra achar o vizinho mais próximo de forma rapidíssima, mesmo em tabela com milhões de linhas.
Spatial JOIN: ST_Intersects, ST_Within, ST_Contains
Esse é o coração do PostGIS. Cruzar duas camadas pela posição geográfica delas.
Quantas escolas tem dentro de cada município:
SELECT
m.nome AS municipio,
COUNT(e.id) AS total_escolas
FROM municipios m
LEFT JOIN escolas e
ON ST_Intersects(m.geom, e.geom)
GROUP BY m.nome
ORDER BY total_escolas DESC;
Listar todos os pontos de COVID que caem dentro do bairro Botafogo:
SELECT c.*
FROM casos_covid c
JOIN bairros b ON ST_Within(c.geom, b.geom)
WHERE b.nome = 'Botafogo';
Quais polígonos de propriedade rural contém alguma nascente:
SELECT DISTINCT p.id_propriedade, p.proprietario
FROM propriedades p
JOIN nascentes n ON ST_Contains(p.geom, n.geom);
A diferença entre as três funções:
ST_Intersects(A, B): A e B se tocam de alguma forma (cruzam, encostam, contém).ST_Within(A, B): A está completamente dentro de B.ST_Contains(A, B): A contém B totalmente (espelho do Within).
Pra contagem rápida e maioria dos casos, ST_Intersects resolve. Use ST_Within e ST_Contains quando você precisa de inclusão estrita.
Por que isso importa pra você: spatial join em QGIS demora minutos com dado grande. Em PostGIS bem indexado, demora segundo. É a diferença entre entregar análise no mesmo dia e entregar na semana seguinte.
Como dar o próximo passo
O que você acabou de fazer já te coloca acima da maioria dos profissionais de GIS no Brasil. A maior parte ainda tá presa em shapefile. Mas existe uma diferença grande entre rodar uma query PostGIS e dominar PostGIS de verdade: tuning de query pesada, índice composto, raster em PostGIS, modelagem de banco espacial pra projeto sério.
Foi exatamente pra cobrir esse caminho que eu construí o curso PostgreSQL e PostGIS para Produção de Mapas. São 12 aulas com 3 horas de conteúdo direto ao ponto, do zero ao banco espacial profissional, com exercício prático em cada módulo.
Conhecer o curso (PostgreSQL e PostGIS)
E se eu quiser ir além de PostGIS?
Se você quer construir a trilha completa (Python, dashboard, sensoriamento, automação), dá uma olhada no Clube do GIS Premium, que dá acesso a todos os cursos.
Perguntas frequentes
Preciso saber programar pra aprender PostGIS?
Não precisa. Você precisa aprender SQL, que é uma linguagem declarativa bem mais simples que Python ou Java. Em uma semana você já escreve query útil. PostGIS adiciona umas funções espaciais em cima do SQL, e você aprende elas no uso.
PostGIS substitui o QGIS?
Não, eles trabalham juntos. O QGIS continua sendo a melhor ferramenta de visualização e edição. O PostGIS é onde o dado mora e onde a análise pesada acontece. Você ganha os dois mundos.
Dá pra usar PostGIS de graça em projeto comercial?
Dá. PostgreSQL e PostGIS são open source com licença permissiva (PostgreSQL License e GPL). Pode usar em produto pago, em empresa privada, em projeto público, sem royalty.
Qual a diferença entre PostGIS e SpatiaLite?
SpatiaLite é a extensão espacial do SQLite, banco em arquivo único, ótimo pra projeto pessoal e mobile. PostGIS é a extensão espacial do PostgreSQL, banco cliente-servidor, ótimo pra time, multi-usuário e dado grande. Os dois têm SQL parecido, mas pra ambiente profissional o padrão é PostGIS.
Quanto dado o PostGIS aguenta?
Aguenta tabela com bilhões de linha sem suar. Empresas como Uber, Foursquare e várias agtechs brasileiras rodam PostGIS em produção com terabytes de dado espacial. Bem indexado, ele entrega query em segundos mesmo nesse volume.