Processamento de Dados Vetoriais¶
As operações sobre dados vetoriais são comumente conhecidas como operações de geoprocessamento. Neste capítulo veremos as mais comuns: geração de faixas de distância (buffer), sobreposição de polígonos (intersecção, união e diferença), cálculo de áreas e centroides e geração de amostras aleatórias.
Antes de começar, é importante perceber que algumas operações são aplicadas a uma feição (ee.Feature) e outras a uma coleção (ee.FeatureCollection):

Operações como .buffer(), .centroid(), .area() e .intersection() são definidas para uma feição. Para aplicá-las a todas as feições de uma coleção, usamos o .map() — o segundo passo do padrão filter–map–reduce que vimos no Capítulo 3.
Dados usados neste capítulo
Baixe e envie aos seus assets (ver Capítulo 5):
- polos_madeireiros_mma.zip — polos madeireiros da Amazônia (Ministério do Meio Ambiente), 74 pontos, atributo
UF4com a sigla da UF; - terras_indigenas.zip — terras indígenas (FUNAI, 2010), atributos
NOME_TI23(nome) eUF10(UF). Versão com geometria simplificada, preparada para fins didáticos.
Lembre-se de substituir projects/ee-sergiocosta/assets/... pelo identificador dos seus assets.
⭕ Geração de faixas de distância (buffer)¶
A operação de buffer identifica zonas de proximidade ao redor de entidades geográficas — pontos, linhas ou polígonos (LONGLEY, 2005). Autoridades municipais podem usá-la para definir zonas de restrição em torno de rios, reservatórios ou áreas de preservação; no planejamento de transportes, para identificar as áreas a uma certa distância de estações de metrô ou paradas de ônibus.
Para realizá-la, escolhemos a entidade de interesse e a distância desejada, geralmente em metros. Suponha que queremos investigar a relação entre o desmatamento e a proximidade de polos madeireiros. O método .buffer() é aplicado a uma feição e retorna uma nova feição. Para aplicá-lo a toda a coleção, encapsulamos a operação em uma função e usamos o .map():

var fbuffer = function (feat) {
return feat.buffer(50000); // 50 km
};
var bufferPolos = polosMadeireiros.map(fbuffer);
O código completo, restrito aos polos do Pará:
var fbuffer = function (feat) {
return feat.buffer(50000);
};
var polosMadeireiros =
ee.FeatureCollection('projects/ee-sergiocosta/assets/polos_madeireiros_mma');
var bufferPolos = polosMadeireiros
.filter(ee.Filter.eq('UF4', 'PA')) // filter
.map(fbuffer); // map
Map.addLayer(bufferPolos, {}, 'Buffer de 50 km');
Map.centerObject(bufferPolos, 6);

🔀 Sobreposição de polígonos¶
A sobreposição de polígonos é uma operação fundamental nos SIGs, essencial para o planejamento urbano, a gestão de recursos naturais, a análise de riscos e muitas outras aplicações. As três operações principais são a intersecção, a união e a diferença.
| Operação | Notação | Resultado |
|---|---|---|
| Intersecção | A ∩ B | apenas a área comum a A e B |
| União | A ∪ B | toda a área de A e de B |
| Diferença | A − B | a área de A que não está em B |
Intersecção¶
A intersecção identifica as regiões de sobreposição entre duas ou mais geometrias — as áreas em que diferentes conjuntos de dados têm algo em comum. Na pesquisa sobre conflitos territoriais, por exemplo, ela identifica onde as jurisdições de várias entidades se sobrepõem. Continuando o exemplo anterior, vamos identificar as áreas de terras indígenas que estão dentro das faixas de 50 km dos polos madeireiros — algo essencial para avaliar o impacto potencial dessas atividades.
Exemplo 1 — intersecção com uma única terra indígena. Selecionamos a TI Parakanã (uma feição, obtida com .first()) e aplicamos a cada buffer uma função que retorna a intersecção com ela:
var polosMadeireiros =
ee.FeatureCollection('projects/ee-sergiocosta/assets/polos_madeireiros_mma');
var tis = ee.FeatureCollection('projects/ee-sergiocosta/assets/terras_indigenas');
var tiParakana = tis
.filter(ee.Filter.eq('NOME_TI23', 'Parakana'))
.first();
var fbuffer = function (feat) {
return feat.buffer(50000);
};
var fintersecaoParakana = function (feat) {
return feat.intersection(tiParakana);
};
var intersecao = polosMadeireiros
.filter(ee.Filter.eq('UF4', 'PA'))
.map(fbuffer)
.map(fintersecaoParakana);
Map.addLayer(intersecao, {}, 'Intersecção com a TI Parakanã');
Map.centerObject(intersecao, 9);

Observe que não foi preciso guardar o resultado do buffer em uma variável: os dois .map() foram encadeados.
Exemplo 2 — intersecção com todas as terras indígenas do Pará. Agora a função aplicada a cada buffer precisa calcular a intersecção com cada terra indígena — ou seja, precisamos de um .map() dentro de outro:
var intersecaoTIs = function (feat) {
return tisPA.map(function (tiFeat) {
return feat.intersection(tiFeat);
});
};
Executando esse código e imprimindo o resultado, nada aparece no mapa. No Console, descobrimos o motivo: o resultado é uma coleção de coleções — para cada buffer, uma coleção de intersecções.

A operação .flatten() transforma uma coleção de coleções em uma única coleção:

O código completo:
var polosMadeireiros =
ee.FeatureCollection('projects/ee-sergiocosta/assets/polos_madeireiros_mma');
var tisPA = ee.FeatureCollection('projects/ee-sergiocosta/assets/terras_indigenas')
.filter(ee.Filter.eq('UF10', 'PA'));
var fbuffer = function (feat) {
return feat.buffer(50000);
};
var intersecaoTIs = function (feat) {
return tisPA.map(function (tiFeat) {
return feat.intersection(tiFeat);
});
};
var intersecao = polosMadeireiros
.filter(ee.Filter.eq('UF4', 'PA'))
.map(fbuffer)
.map(intersecaoTIs)
.flatten();
print(intersecao);
Map.addLayer(intersecao, {color: 'FF0000'}, 'TIs a menos de 50 km de polos');
Map.centerObject(intersecao, 6);

Agora o Console mostra uma coleção de feições, e não mais uma coleção de coleções.
Intersecções vazias
Quando um buffer não toca uma terra indígena, a intersecção resulta em uma geometria vazia — que também entra na coleção. Para descartá-las, filtre pela área: acrescente ao final da cadeia .map(function (f) { return f.set('area', f.area(1)); }).filter(ee.Filter.gt('area', 0)).
União¶
A união combina polígonos, gerando um novo polígono que abrange toda a área dos polígonos originais. Ela é usada para consolidar informações de diversas fontes ou para criar um polígono contínuo a partir de várias unidades menores — na gestão de recursos naturais, várias áreas de vegetação podem resultar em um único polígono de habitat. Um uso muito comum é delimitar uma área de estudo a partir de vários municípios. O código a seguir une quatro municípios do centro do Maranhão:
var filtro = ee.Filter.or(
ee.Filter.eq('NM_MUN', 'Barra do Corda'),
ee.Filter.eq('NM_MUN', 'Grajaú'),
ee.Filter.eq('NM_MUN', 'Jenipapo dos Vieiras'),
ee.Filter.eq('NM_MUN', 'Fernando Falcão')
);
var areaEstudo = ee.FeatureCollection(
'projects/ee-sergiocosta/assets/MA_Municipios_2022')
.filter(filtro)
.union();
print(areaEstudo);
Map.addLayer(areaEstudo, {}, 'Área de estudo');
Map.centerObject(areaEstudo, 8);

O filtro ee.Filter.or seleciona os municípios que satisfazem qualquer das condições. O mesmo resultado seria obtido com ee.Filter.inList('NM_MUN', ['Barra do Corda', 'Grajaú', 'Jenipapo dos Vieiras', 'Fernando Falcão']). O método .union() da coleção retorna uma nova coleção com uma única feição, cuja geometria é a união de todas.
Diferença¶
A diferença subtrai um polígono de outro, eliminando uma área específica de um polígono maior — por exemplo, remover uma área construída de uma zona de conservação ambiental. Suponha que, durante a análise, decidimos excluir o município de Grajaú da área de estudo:
var municipios = ee.FeatureCollection('projects/ee-sergiocosta/assets/MA_Municipios_2022');
var areaEstudo = municipios
.filter(ee.Filter.inList('NM_MUN',
['Barra do Corda', 'Grajaú', 'Jenipapo dos Vieiras', 'Fernando Falcão']))
.union();
var grajau = municipios
.filter(ee.Filter.eq('NM_MUN', 'Grajaú'))
.first();
var calcularDiferenca = function (feature) {
return feature.difference(grajau);
};
var resultadoDiferenca = areaEstudo.map(calcularDiferenca);
Map.addLayer(areaEstudo, {color: '999999'}, 'Área de estudo inicial');
Map.addLayer(resultadoDiferenca, {color: 'FF0000'}, 'Diferença');
Map.centerObject(resultadoDiferenca, 8);
Como areaEstudo é uma coleção (com uma feição), usamos novamente o .map() para aplicar a operação.
📏 Área e centroides¶
Cálculo de área¶
O método .area() retorna a área de uma geometria em metros quadrados, calculada sobre o elipsoide — ou seja, sem as distorções de uma projeção. Para calcular a área de todos os municípios e guardá-la como um novo atributo, usamos .map() e .set():
var municipios = ee.FeatureCollection('projects/ee-sergiocosta/assets/MA_Municipios_2022');
var comArea = municipios.map(function (feature) {
var areaKm2 = feature.geometry().area(1).divide(1e6); // m² → km²
return feature.set('area_calc_km2', areaKm2);
});
print(comArea.limit(5)); // compare area_calc_km2 com o atributo AREA_KM2 do IBGE
O argumento 1 é o erro máximo tolerado (em metros) no cálculo.
Cálculo de centroides¶
Outra operação muito comum é o cálculo do ponto central — o centro de massa — de uma geometria, o centroide. Ele é usado para posicionar rótulos em mapas temáticos, em análises de redes, de densidade e muitas outras. Aplicado a uma feição, o método .centroid() retorna uma nova feição, com o centroide como geometria e os mesmos atributos da original:
var municipios = ee.FeatureCollection('projects/ee-sergiocosta/assets/MA_Municipios_2022');
var calcularCentroide = function (feature) {
return feature.centroid(1);
};
// aplica a função a cada feição da coleção
var centroides = municipios.map(calcularCentroide);
print(centroides.limit(5));
Map.addLayer(municipios, {}, 'Municípios');
Map.addLayer(centroides, {color: 'FF0000'}, 'Centroides');
Map.centerObject(municipios, 6);

E se eu calcular o centroide da geometria?
feature.geometry().centroid() retorna apenas uma geometria, sem atributos. Para manter os atributos nesse caso, crie uma nova feição: ee.Feature(feature.geometry().centroid(1), feature.toDictionary()). Usar diretamente feature.centroid() é mais simples.
🎲 Geração de dados amostrais¶
A geração de amostras aleatórias é uma etapa fundamental em muitas aplicações de sensoriamento remoto e análise espacial: avaliar a qualidade de uma classificação de imagem, treinar algoritmos de aprendizado de máquina ou conduzir análises estatísticas. O método ee.FeatureCollection.randomPoints recebe a região de interesse e o número de pontos desejado e retorna uma coleção de pontos. No exemplo a seguir, criamos 100 pontos na área de estudo:
var areaEstudo = ee.FeatureCollection(
'projects/ee-sergiocosta/assets/MA_Municipios_2022')
.filter(ee.Filter.inList('NM_MUN',
['Barra do Corda', 'Grajaú', 'Jenipapo dos Vieiras', 'Fernando Falcão']))
.union();
var numeroDePontos = 100;
var amostras = ee.FeatureCollection.randomPoints({
region: areaEstudo.geometry(),
points: numeroDePontos,
seed: 42 // semente: garante que os mesmos pontos sejam gerados a cada execução
});
Map.centerObject(areaEstudo, 8);
Map.addLayer(areaEstudo, {}, 'Área de estudo');
Map.addLayer(amostras, {color: 'red'}, 'Amostras');

Reprodutibilidade
O parâmetro seed torna o sorteio reprodutível: com a mesma semente, os mesmos pontos são gerados. Isso é importante em trabalhos científicos, para que outras pessoas possam repetir a análise.
📝 Síntese¶
| Operação | Aplicada a | Método no GEE |
|---|---|---|
| Faixa de distância | feição | feature.buffer(distância) |
| Intersecção | feição | feature.intersection(outra) |
| União | coleção | colecao.union() |
| Diferença | feição | feature.difference(outra) |
| Área | geometria | geometry.area(erroMax) |
| Centroide | feição | feature.centroid(erroMax) |
| Amostras aleatórias | região | ee.FeatureCollection.randomPoints(...) |
| Achatar coleções | coleção de coleções | colecao.flatten() |
Para aplicar uma operação de feição a toda uma coleção, use .map().
✏️ Exercícios¶
- Gere buffers de 10 km em torno das sedes dos polos madeireiros do Maranhão (
UF4 = 'MA'). Quantos polos existem no estado? - Calcule a área (em km²) de cada terra indígena do Maranhão e liste as três maiores (dica:
.sort('area', false).limit(3)). - Construa a área de estudo formada pelos municípios da Ilha do Maranhão (São Luís, São José de Ribamar, Paço do Lumiar e Raposa) e gere 50 amostras aleatórias com semente 2024.
- Modifique o Exemplo 2 da intersecção para calcular, em cada feição resultante, a área em km², e remova as intersecções vazias.
- Explique por que o resultado do Exemplo 2 era uma coleção de coleções e o que o
.flatten()faz.