INFOGEO · Insper
Tema 3 · Unidade teórica 03 · ODS 6 e 11

Quem vive sem esgoto na minha cidade, e em qual quarteirão?

A geografia está num arquivo e o número de domicílios está em outro. Juntar os dois leva trinta segundos no QGIS, e a junção pode falhar sem emitir uma única mensagem, devolvendo um resultado que parece completo e não é.

120 minduração
40 / 45 / 15 / 20teoria / roteiro / exercício / fechamento
São Paulo, SPárea de estudo
27.301 setoresCenso 2022 · IBGE
Antes de começar

Preparação

A leitura de preparação era o dicionário de variáveis dos agregados por setor censitário do Censo 2022. Se você não leu, abra agora e procure só uma coisa: quantas variáveis diferentes descrevem esgotamento sanitário, e por que elas não são uma só.

Crie a pasta InfoGeo/tema03_atributos com as subpastas dados_brutos e dados_tratados, do mesmo jeito dos dois temas anteriores. Salve o projeto vazio como projeto.qgz antes de carregar qualquer coisa. O pacote de dados desta aula está no começo da Parte 2, junto do passo em que ele passa a ser usado.

A pergunta do tema

A prefeitura anuncia que 3,3% dos domicílios de São Paulo não têm esgotamento sanitário adequado. O número saiu de um cruzamento entre a malha de setores e a planilha do Censo, feito por um estagiário competente, sem nenhum erro de fórmula. O número certo é quase 40% maior. Onde está o erro?

Parte 1 · teoria

Modelo vetorial, topologia e banco de dados geográfico

40 min

No tema anterior você mediu um polígono. Neste tema o polígono ganha uma tabela ao lado, e quase tudo o que um SIG faz de útil acontece na fronteira entre os dois: a geometria guarda a posição, a tabela guarda os valores. O que liga as duas é uma chave, quase sempre um campo de texto, e é nessa chave que a análise territorial costuma quebrar primeiro.

Ponto, linha e polígono

O modelo vetorial tem exatamente três primitivas geométricas: ponto, linha e polígono. Um ponto é um par de coordenadas. Uma linha é uma sequência ordenada de pontos. Um polígono é uma linha que fecha sobre si mesma e delimita uma área. Não existe uma quarta primitiva, e nenhum SIG oferece outra: toda camada vetorial que você vai abrir na vida é feita de uma dessas três.

A escolha da primitiva decide, antes de qualquer análise, que perguntas a camada vai conseguir responder. O ponto tem posição e nada mais: serve para contar, para localizar e para medir distância até outra coisa, e não tem área, comprimento nem forma. A linha acrescenta extensão, sentido e conectividade, e por isso é a única primitiva sobre a qual se calcula caminho, montante e jusante. O polígono acrescenta área, perímetro e, principalmente, interior, e é o interior que permite perguntar o que está dentro.

Qual delas usar depende da escala de trabalho, não da natureza da coisa representada. Uma cidade é ponto num mapa de país e polígono numa planta municipal. Um rio é linha na carta regional e polígono na planta da várzea. Não existe representação certa em abstrato, existe representação compatível com a pergunta.

O que não dá para fazer é recuperar depois a informação que a primitiva descartou. Um ponto guardado no lugar de um polígono não tem a área escondida em algum canto do arquivo: a área não foi registrada, e a única saída é voltar à fonte. Por isso a escolha da primitiva é uma decisão de projeto, tomada antes da coleta, e não um detalhe de formato.

Três painéis mostrando a mesma quadra representada por um ponto, por uma linha e por um polígono, com a lista do que cada representação permite e do que ela impede de responder.
Figura 1 A escola representada por um ponto tem coordenada e não tem área. A rede coletora representada por linha tem comprimento e não tem cobertura. O setor representado por polígono tem área e densidade, mas não sabe dizer em que canto dele está o problema. Essa informação foi descartada quando a primitiva foi escolhida, antes de qualquer análise.
Definição

Feição

Uma feição é o par formado por uma geometria e uma linha de tabela. Toda camada vetorial é uma lista de feições com a mesma primitiva e os mesmos campos. Quando você seleciona algo no mapa, seleciona a linha da tabela junto; quando seleciona a linha, o mapa acende. Não existe um sem o outro, e é essa amarração que faz do SIG outra coisa que um programa de desenho.

Topologia e validade geométrica

Topologia é o conjunto das relações espaciais que sobrevivem a deformar o mapa sem rasgar: o que está dentro do quê, o que faz fronteira com o quê, o que está conectado a quê. Imagine o mapa impresso numa folha de borracha, e a folha sendo esticada em várias direções. Distância muda, área muda, ângulo muda, forma muda. O que não muda é a vizinhança. Um lote dentro de um quarteirão continua dentro. Dois terrenos que dividem um muro continuam dividindo. Um trecho de rua que sai de um cruzamento continua saindo dele.

Daí vem a propriedade que interessa na prática: relação topológica não depende de projeção. Trocar o sistema de coordenadas muda todos os números de área e de distância que você calculou no tema anterior, e não muda uma única resposta de "está dentro". É por isso que as operações de sobreposição podem ser definidas uma vez só, sem uma versão para cada projeção, e por isso um erro de topologia é bem mais grave que um erro de projeção: o de projeção você corrige reprojetando, o de topologia está gravado na própria geometria.

Para que essas relações sejam decidíveis, a geometria precisa ser válida. Validade é um conjunto pequeno de regras: o anel externo fecha exatamente no ponto em que começou, nenhum anel cruza a si mesmo, cada anel interno está inteiramente contido no externo, anéis internos não se sobrepõem entre si e não há vértices repetidos em sequência. Uma geometria que viola qualquer dessas regras continua abrindo, continua sendo desenhada na tela e continua ocupando sua linha na tabela. O defeito não aparece no desenho. Aparece na conta.

O motivo é aritmético. A área de um polígono é calculada percorrendo os vértices na ordem em que foram gravados e somando contribuições que têm sinal, e o sinal depende do sentido do percurso. Num anel bem formado o percurso tem um sentido só, e as contribuições se acumulam. Num anel que cruza a si mesmo o percurso se parte em dois laços de sentidos opostos, e as duas parcelas se subtraem em vez de somar. O número sai menor, às vezes muito menor, e nada nele o distingue de um número correto. O mesmo raciocínio vale para interseção, buffer e dissolve, que pressupõem interior e exterior bem definidos: com o anel cruzado, "interior" deixa de ter sentido único, e cada biblioteca resolve o caso à sua maneira.

Três polígonos: um válido com 41,20 hectares, um com autointerseção que devolve 2,57 hectares, e um com anel interno digitado no mesmo sentido do externo, que soma o vazio à área.
Figura 2 O painel do meio é o mesmo quadrilátero da esquerda com dois vértices trocados de ordem. A área despenca de 41,20 para 2,57 hectares porque os dois laços têm sinal oposto e se cancelam. Nada na tela avisa: o polígono continua sendo desenhado.
Pergunta norteadora

Se a autointerseção derruba a área para menos de um décimo do valor correto, por que esse erro sobrevive tanto tempo em bases reais?

Porque ninguém olha a área de um polígono isolado. Olha-se o total de uma camada com milhares de feições, e um valor que deveria ser 41 e vale 2 desaparece no somatório. O erro só aparece quando alguém compara o total com uma fonte independente, e aí ele já foi para dentro de um relatório. Some-se a isso que a geometria inválida não vem, em geral, de quem produziu o dado: vem de uma edição manual, de uma conversão entre formatos ou de uma simplificação automática aplicada depois, e a camada muda de mãos algumas vezes antes de alguém desconfiar.

Todo SIG traz uma ferramenta de verificação de validade, que percorre a camada, separa as feições válidas das inválidas e aponta o vértice em que a regra foi quebrada. Rode isso em toda base que chegar de terceiros, antes de qualquer conta. Leva segundos e é a checagem com melhor relação entre esforço e prejuízo evitado deste curso.

A tabela de atributos é uma relação, não uma planilha

A tabela de atributos parece uma planilha e não se comporta como uma. Numa planilha a unidade é a célula, e a posição carrega significado que só o autor conhece: a primeira linha costuma ser cabeçalho, a última costuma ser total, a coluna pintada de amarelo quer dizer alguma coisa, e duas tabelas independentes convivem na mesma aba separadas por três linhas em branco. Numa relação a unidade é a linha, e a posição não carrega nada.

Dessa diferença saem as regras que o formato impõe. Cada linha corresponde a uma feição e a nada mais. Não existe célula mesclada, nem linha de total no rodapé, nem duas tabelas no mesmo lugar, nem cor como informação. A ordem das linhas não significa nada e pode mudar entre duas aberturas do mesmo arquivo, de modo que nenhuma conta pode depender de uma linha estar acima de outra. Cada coluna tem um tipo declarado, o mesmo para a coluna inteira, e o programa cobra esse tipo em toda operação.

Essa disciplina toda serve para uma coisa: permitir que a tabela seja cruzada com outra por uma chave. Uma planilha com célula mesclada e total no rodapé não pode ser cruzada com nada, porque nela não há resposta para a pergunta mais básica, que é o que conta como uma linha.

Tipo de campoO que aceitaErro típico
Text (string)Qualquer caractere, com comprimento máximoIdentificador guardado como número perde os zeros à esquerda e ganha uma aritmética que não faz sentido nenhum
IntegerInteiro com sinalIdentificador longo estoura o inteiro de 32 bits que formatos antigos, como o Shapefile, ainda impõem
Decimal (real)Número com casas decimaisArquivo gravado com vírgula decimal, importado sem que isso seja declarado, transforma a coluna inteira em texto
DateData com formato declaradoDia e mês invertidos ao importar de fonte em inglês
BooleanVerdadeiro, falso ou nuloConfundir falso com nulo em consulta, e perder as linhas sem informação
Nulo não é zero, e nenhum dos dois é texto vazio. Um registro que vale zero e um registro sobre o qual não há informação são coisas diferentes, e cada operação trata as duas de um jeito: somar ignora o nulo, contar linhas conta a linha do nulo, e comparar um valor com nulo não devolve nem verdadeiro nem falso. Confundir os três é o defeito mais comum de tabela de atributos.

Chave e cardinalidade

Definição

Chave primária

Um campo, ou combinação de campos, cujo valor identifica uma única linha da tabela. Para servir de chave, o campo precisa de três propriedades. Ser único: nenhum valor se repete em duas linhas. Ser obrigatório: nunca vem vazio nem nulo, porque uma linha sem identificador não pode ser cruzada com nada. E ser estável: o mesmo objeto do mundo carrega o mesmo valor de uma edição da base para a seguinte. As duas primeiras propriedades o programa consegue verificar sozinho, contando repetições e nulos. A terceira não é verificável dentro de um arquivo só, e é justamente a que falha.

Quando campo nenhum identifica a linha sozinho, a chave é composta: vale a combinação de dois ou mais campos, e a junção precisa casar todos eles ao mesmo tempo. Uma tabela de indicadores por município e por ano tem chave composta de município e ano, porque o município se repete em cada ano e o ano se repete em cada município. Cruzar essa tabela usando só o código do município encontra várias linhas candidatas para cada município, e o que acontece a partir daí depende de uma opção da ferramenta que quase ninguém lê.

Chave de território costuma ser um código hierárquico, em que a posição do dígito carrega significado. Imagine um identificador de quinze dígitos em que os sete primeiros identificam o município, os dois seguintes uma divisão interna dele, os dois seguintes uma subdivisão dessa divisão, e os quatro últimos numeram a unidade final dentro dela. Um código assim é prático: dá para recuperar o município de qualquer unidade cortando os sete primeiros dígitos, sem precisar de outra tabela, e dá para agrupar por divisão interna cortando os nove primeiros. É também frágil, e pela mesma razão. Duas unidades vizinhas têm códigos parecidíssimos, uma diferença num dígito do meio é indistinguível a olho nu, e o campo inteiro parece um número sem ser um número.

Erro comum

Abrir a tabela num programa de planilha antes de importar. Planilha reconhece coluna de dígitos como número e descarta os zeros à esquerda na hora, sem perguntar nada: um código que começa por zero volta com um dígito a menos e não casa com mais nada. Código muito longo ainda pode ser convertido para notação científica e perder os dígitos finais de vez. Chave é texto, e continua texto do começo ao fim do fluxo de trabalho, mesmo quando todos os seus caracteres são algarismos.

Definida a chave, a pergunta que decide o resto é de cardinalidade: quantas linhas de um lado correspondem a quantas do outro.

CardinalidadeExemploO que acontece na junção
1:1Uma unidade territorial, uma linha de indicadoresA camada de saída tem o mesmo número de feições da entrada. É o caso mais simples e o desta aula.
1:nUma unidade territorial, várias escolas dentro delaOu o programa duplica a geometria da unidade uma vez por escola, ou descarta todas as correspondências menos uma. Quem escolhe é você, numa opção da ferramenta, e as duas saídas têm totais diferentes.
n:1Várias unidades, um mesmo municípioSeguro. O atributo do município se repete em cada unidade, e a contagem de feições não muda.
n:nUnidades territoriais e áreas de risco que se cruzam parcialmenteNão se resolve por junção de atributo, porque não há chave comum. Exige interseção geométrica, que é assunto do tema 5.
A cardinalidade não está escrita em lugar nenhum do arquivo. É uma hipótese sua sobre os dados, declarada na configuração da ferramenta de junção, e a ferramenta obedece à hipótese declarada sem conferir se ela é verdadeira. Declarar 1:1 sobre dados que são 1:n não produz erro: produz descarte silencioso.
Erro comum

Contar feições depois de uma junção 1:n e reportar o resultado como número de unidades territoriais. Numa camada de 5.000 polígonos em que 900 tenham duas escolas cada, a saída passa a ter 5.900 feições, e somar a população dessa camada conta 900 polígonos duas vezes. O total infla, o mapa continua idêntico, porque as geometrias duplicadas são desenhadas exatamente uma sobre a outra, e nada na tela indica o que aconteceu.

Junções que falham sem erro

Aqui está o assunto central da aula. Uma junção por atributo funciona assim: para cada linha da tabela da esquerda, o programa procura na tabela da direita uma linha com o mesmo valor de chave. Se acha, copia as colunas pedidas. Se não acha, preenche essas mesmas colunas com nulo e passa para a linha seguinte. Não achar é um resultado previsto da operação, e não uma falha dela. Por isso não existe mensagem de erro.

Vale entender por que o comportamento é esse, em vez de reclamar dele. A mesma operação atende a dois propósitos legítimos e opostos. Às vezes você cruza duas tabelas que deveriam cobrir exatamente o mesmo conjunto de unidades, e aí um não-casamento é defeito. Às vezes você cruza uma tabela geral com uma lista parcial, para descobrir quais unidades estão na lista, e aí o não-casamento é precisamente a informação que você foi buscar. O programa não tem como distinguir os dois casos, então adota o único comportamento que serve aos dois: preenche com nulo e segue. Quem sabe qual é o caso é você, e a conferência é sua.

O resultado é uma camada que passa em todas as inspeções superficiais. Tem o número correto de feições, porque nenhuma feição foi descartada. Desenha na tela exatamente como a original, porque a geometria não foi tocada. Abre sem aviso, exporta sem aviso e entra num relatório sem aviso. O defeito mora dentro das colunas trazidas, nas linhas em que a chave não casou, e só aparece se alguém for contá-las.

Definição

Taxa de casamento

A fração das linhas da tabela de entrada que encontraram correspondente na outra tabela. Se entram 27 mil linhas e 25 mil casam, a taxa é de 92,6%. É o primeiro número a apurar depois de qualquer junção e o único que autoriza usar o cruzamento. A taxa sozinha, porém, não decide nada: 92,6% pode ser irrelevante ou pode inverter a conclusão, conforme quem sejam as linhas que ficaram de fora. O mesmo indicador reaparece no tema 7, com o nome de taxa de match, quando o assunto for geocodificação de endereços.

As causas de não-casamento são poucas e se repetem em qualquer base. Vale conhecer as cinco, porque o diagnóstico é diferente em cada uma.

CausaComo se produzComo se reconhece
Tipo diferenteUm lado importou a chave como texto e o outro como número inteiro. Os valores aparecem iguais na tela e nenhum casaTaxa de casamento igual a zero é quase sempre isto. Confira o tipo declarado das duas colunas antes de rodar
Espaço em brancoExportação de planilha ou recorte manual deixa um espaço antes ou depois do código. Invisível na tabelaCompare o comprimento do campo dos dois lados. Se um tem um caractere a mais, é espaço
Zero à esquerda perdidoA chave passou por algum programa que a leu como número, e os códigos iniciados por zero voltaram com um dígito a menosSó falham os códigos que começam por zero. As falhas se concentram nos mesmos prefixos, e nunca aparecem fora deles
Caixa e acentoJunção por nome em vez de por código. Maiúscula, minúscula e acento produzem valores diferentes para o mesmo lugarNão deveria acontecer: quando existe código, a junção é por código. Nome serve para ler, não para cruzar
Edições diferentesAs duas tabelas descrevem o mesmo território em versões distintas da mesma base. Unidades criadas, extintas ou subdivididas mudaram de código entre uma e outraConfira a data de publicação das duas fontes antes de cruzar. É a causa mais frequente e a que menos se anuncia
As quatro primeiras causas produzem falha total ou falha concentrada num prefixo, e por isso chamam atenção. A última produz falha parcial, tipicamente entre 3% e 10% das linhas, que é exatamente a faixa em que ninguém desconfia de nada.

Se as linhas que somem fossem sorteadas, a perda seria só de precisão: a média do que restou continuaria estimando a média do todo. Elas quase nunca são sorteadas. Código de unidade territorial muda quando a unidade é subdividida, e a subdivisão acontece onde a população cresceu rápido, que costuma ser a periferia em adensamento. Fora do território, a lógica se repete de outro jeito: endereço que não geocodifica se concentra em ocupação informal, onde o logradouro ainda não entrou na base oficial. O que falha em casar tende a ser sistematicamente diferente do que casou, e quase sempre na direção que embeleza o indicador. Um cruzamento malfeito costuma produzir um retrato mais otimista do que a realidade, e é por isso que ele passa: o número sai bom, e número bom não é conferido.

Pergunta norteadora

Que checagem de trinta segundos teria pegado esse erro?

Contar quantas linhas ficaram com nulo numa das colunas que a junção trouxe. É uma consulta por atributo, e o resultado dela é a taxa de casamento. Se você esperava 1:1 e o resultado não é zero, pare tudo. Cuidado com a leitura fácil, porém: nulo depois de junção tem pelo menos duas causas com significados opostos. Pode ser chave que não casou, o que é defeito, ou pode ser unidade que existe na geometria e legitimamente não tem registro na tabela de dados, o que é informação correta. A contagem sozinha não separa as duas. Para separar, olhe o que as linhas nulas têm em comum: se elas se parecem entre si e diferem do resto da base, é defeito, e é defeito com viés.

Regra de bancada

Toda junção termina com três números anotados: quantas feições entraram, quantas casaram e quantas ficaram nulas. Quando a terceira não for zero, acrescente uma frase dizendo o que as linhas nulas têm em comum. Sem isso, não há como defender o resultado quando alguém o questionar, e alguém sempre questiona quando o número desagrada.

Consulta por atributo: selecionar, filtrar e exportar

Consultar por atributo é fazer uma pergunta sobre os valores da tabela e receber de volta um subconjunto de feições. A pergunta é escrita numa linguagem de expressão parente do SQL: comparação de campo com valor, combinação de condições por E e por OU, teste de nulo, comparação por prefixo, pedaço de um campo de texto. Cada SIG tem sua variante da linguagem, com regras próprias de pontuação para distinguir o nome de um campo de um texto literal. A gramática muda de programa para programa; a lógica por trás é a mesma em todos, e é a lógica que você precisa levar daqui.

O que decide o resultado do trabalho, aliás, não é a expressão. É o que se faz com o subconjunto depois de obtê-lo. Há três destinos possíveis, com consequências bem diferentes, e confundi-los produz erro difícil de rastrear porque o sintoma aparece muitos passos adiante.

OperaçãoO que fazO que você precisa lembrar
SelecionarMarca as feições que atendem à condição. A camada continua inteira, e as feições não marcadas continuam láA marca é volátil: some ao clicar no mapa e não é gravada no arquivo. Ferramentas com a opção "apenas feições selecionadas" respeitam a marca, e as demais a ignoram por completo
FiltrarEsconde do projeto tudo que não atende à condição. A camada passa a se comportar como se as outras feições não existissemFica gravado no projeto e é facílimo de esquecer. Toda estatística, toda junção e toda exportação feita depois enxerga só o subconjunto, e a contagem de feições que aparece na tela é a do subconjunto
ExportarGrava um arquivo novo contendo apenas o subconjuntoDuplica o dado e congela o recorte no momento em que ele foi feito. A partir daí, corrigir a base de origem não corrige a cópia
Selecionar não altera nem a camada nem o arquivo, e não sobrevive à sessão. Filtrar não altera o arquivo, mas altera tudo o que for calculado depois, e sobrevive ao salvamento do projeto. Exportar cria um segundo arquivo, que a partir de então envelhece por conta própria. A escolha entre os três é uma escolha sobre o que você quer que dure.
Erro comum

Testar nulo com os operadores de igualdade e de diferença. Em lógica de banco de dados vigora um sistema de três valores, e qualquer comparação com nulo não devolve nem verdadeiro nem falso: devolve nulo, e a linha fica de fora da seleção. Perguntar quais linhas são diferentes de nulo com o operador de diferença devolve conjunto vazio, sem aviso nenhum. Existe um operador próprio para o teste de nulo, e é o único que funciona. A mesma lógica explica um efeito colateral que pega muita gente: uma condição como "campo maior que 70" também deixa de fora todas as linhas nulas, porque nulo não é maior nem menor que coisa alguma. Se as linhas sem informação precisam aparecer no resultado, elas têm que ser pedidas explicitamente.

Consulta por localização e os predicados topológicos

A outra família de consulta não olha a tabela. Olha a geometria. Você pergunta quais feições de uma camada guardam determinada relação espacial com as feições de outra, e a relação é escolhida dentro de um conjunto pequeno de predicados definidos formalmente.

"Definidos formalmente" é a parte que importa. Na conversa, "estar dentro de um bairro" é uma expressão que ninguém precisa explicar. Na hora de escrever a consulta, ela exige decisões que a linguagem comum nunca precisou tomar. Um lote que fica metade num bairro e metade no outro está dentro de qual? Um terreno cuja divisa coincide com um trecho da divisa do bairro está dentro? Um ponto de coleta caído exatamente sobre a linha divisória está dentro, fora, ou nos dois? A frase em português não responde, e o programa não pode ficar sem resposta. Os predicados topológicos são o vocabulário que resolve isso, e cada um se define pelo que acontece entre o interior, a fronteira e o exterior das duas geometrias.

PredicadoVerdadeiro quandoO que costuma dar errado
intersectsAs duas geometrias têm pelo menos um ponto em comum, seja de interior, seja de fronteiraÉ o mais permissivo dos cinco. Vizinhos que apenas dividem uma divisa satisfazem o predicado e entram no resultado
withinA primeira geometria está inteiramente contida na segunda, sem nenhuma parte no exterior delaÉ o predicado de "está dentro". Sobreposição parcial não conta, e quem trabalha com unidades que atravessam divisas precisa decidir o que fazer com elas
containsA segunda geometria está inteiramente contida na primeiraÉ within lido do outro lado. Trocar a ordem das camadas na janela troca o resultado por completo
touchesAs duas compartilham pontos de fronteira e nenhum ponto de interiorÉ o predicado de "faz divisa com", e exclui quem se sobrepõe. Útil para achar vizinhos, inútil para achar quem está dentro
disjointAs duas não têm ponto algum em comumÉ a negação de intersects, e serve para achar o que ficou de fora de tudo
Os cinco não são independentes: within e contains são a mesma relação lida de dois lados, disjoint é a negação de intersects, e touches é o caso em que intersects só vale por causa da fronteira. Escolher entre eles é declarar o que a sua frase em português queria dizer.
Tabela verdade dos predicados intersects, contains, within, touches e disjoint aplicados a quatro configurações de duas geometrias.
Figura 3 Repare na terceira coluna. Duas quadras que apenas dividem uma calçada devolvem verdadeiro em intersects, porque compartilham pontos de fronteira. É por isso que uma extração por localização com intersects traz vizinhos que você não pediu, e por que within costuma ser o predicado certo quando a pergunta é "está dentro".
Pergunta norteadora

Você quer contar quantas unidades territoriais críticas estão dentro de um distrito. Usa intersects ou within?

Se a camada consultada for de pontos, e nenhum deles cair sobre a divisa, os dois predicados devolvem o mesmo conjunto e a escolha parece indiferente. A diferença explode quando as duas camadas são de polígonos, que é o caso mais comum em análise territorial: todo vizinho que encosta na divisa satisfaz intersects e não satisfaz within. Numa contagem de algumas centenas de unidades, a diferença entre os dois predicados costuma passar de 10%, e o mapa não denuncia nada, porque os polígonos a mais estão colados na borda e parecem fazer parte do conjunto. Escolher o predicado é declarar o que você entende por "estar em", e essa declaração pertence ao relatório tanto quanto o número. No roteiro você vai medir essa diferença em dados reais.

A unidade de análise é uma escolha administrativa

Quase todo indicador territorial é calculado sobre unidades que alguém desenhou antes, por motivos que nada têm a ver com a sua pergunta. Bairro, distrito, área de ponderação, zona de tráfego, área de abrangência de unidade de saúde, setor censitário: cada um desses recortes existe para viabilizar uma rotina administrativa, e chega às suas mãos como se fosse um fato geográfico.

O setor censitário é o exemplo mais usado em análise urbana e o mais mal compreendido. Ele não corresponde a bairro, quarteirão ou comunidade. É a área que um recenseador consegue percorrer no prazo do Censo, dimensionada por número de domicílios e desenhada por conveniência de campo, com divisas apoiadas no que é reconhecível a pé: uma rua, um córrego, um muro, uma linha de trem. O critério é operacional do começo ao fim. Em compensação, o setor é a menor unidade em que o dado censitário é publicado, e por isso vira, por falta de alternativa, a unidade de quase todo estudo urbano com dado de população.

A consequência é direta. A unidade sobre a qual você vai calcular percentual, densidade e média foi desenhada pela logística de uma pesquisa, e não pela geografia do fenômeno que se quer estudar. Rede de esgoto, mancha de inundação, área de influência de uma escola: nenhuma delas tem motivo para respeitar a divisa do setor, e nenhuma respeita. O recorte é uma grade imposta por fora sobre um fenômeno que não tem divisas.

Três linhas mostrando a dispersão do percentual de domicílios sem esgotamento adequado quando os mesmos dados são agregados por setor censitário, por distrito e pelo município inteiro.
Figura 4 Os mesmos domicílios, contados uma vez e agregados em três níveis. Por setor censitário, o percentual de domicílios sem esgotamento adequado percorre toda a faixa possível, de zero a cem: existe setor em que ninguém tem coleta e setor em que todo mundo tem. Por distrito, a amplitude encolhe e os extremos desaparecem. Pelo município, sobra um número só. Cada linha para cima é informação que a agregação apagou, e nenhuma das três está errada.
Definição · primeira aparição

Problema da unidade de área modificável

Resultados estatísticos calculados sobre unidades territoriais dependem de como essas unidades foram desenhadas, e o problema tem duas metades. O efeito de escala: agregar as mesmas observações em unidades maiores muda o resultado, em geral reduzindo a variação entre unidades e aumentando a correlação entre variáveis, o que faz relações fracas parecerem fortes. O efeito de zoneamento: mantendo o número e o tamanho das unidades e mudando só por onde passam as divisas, o resultado muda de novo. Em inglês, modifiable areal unit problem, ou MAUP. Como o desenho das unidades quase nunca é escolha do analista, o problema não se resolve: declara-se. Você vai ver a formalização dos dois efeitos na aula 4 e usá-la de novo na aula 6.

Pergunta norteadora

Se o resultado depende do desenho das unidades, e o desenho é arbitrário, o número serve para alguma coisa?

Serve, com a unidade de agregação declarada ao lado. O percentual do município inteiro, a contagem de unidades acima de um limiar e o valor do pior distrito são três afirmações verdadeiras sobre a mesma cidade, e cada uma responde a uma pergunta diferente: a primeira serve para comparar com outro município, a segunda para dimensionar obra, a terceira para escolher por onde começar. O que não se pode fazer é comparar um número calculado por setor com outro calculado por distrito e chamar a diferença de mudança na realidade. Também não se pode escolher o nível de agregação depois de ver qual deles dá o resultado mais conveniente, embora seja exatamente isso que acontece toda vez que um número é publicado sem dizer sobre que unidade foi calculado.

Escopo de prova · unidade teórica 03

Dado um par de tabelas e uma junção já executada, a prova pode pedir que você diagnostique por que o cruzamento falhou e estime a direção do viés que isso introduz. Pode também pedir a escolha do predicado topológico adequado a um enunciado, ou a identificação do efeito do MAUP em uma conclusão apresentada como se fosse do fenômeno.

Parte 2 · roteiro

Do CSV ao quarteirão, no QGIS

45 min

Os números abaixo são exatos e saem do pacote desta aula. Se o seu QGIS mostrar outra coisa, pare no ponto de conferência mais próximo e descubra qual passo saiu diferente antes de seguir.

Dados desta aulapacote no Blackboard
Dados de IBGE · Setores censitários e agregados do Censo 2022, recorte de São Paulo capital, baixados em 02/08/2026 e disponíveis no Blackboard, na pasta da disciplina. Fonte original: portal.
  • setores_sp_capital_2022.gpkg 27.301 setores censitários do município de São Paulo, polígono, EPSG:4674. Malha oficial do Censo 2022 com 37 campos: código de 15 dígitos, situação urbana ou rural, tipo de setor, distrito, área em km² e as variáveis v0001 a v0007.
    oficial
  • agregados_esgoto_sp_capital_2022.csv 26.889 linhas e treze colunas, recortadas do arquivo oficial de características do domicílio: chave, distrito, total de domicílios, moradores e as oito variáveis V00309 a V00316 de destinação do esgoto. UTF-8, ponto e vírgula, decimal em vírgula, com os X de sigilo preservados.
    oficial
  • agregados_esgoto_sp_ed_anterior.csv Mesmas 26.889 linhas e os mesmos valores, mas 1.200 códigos de setor vêm de uma edição anterior da malha. ISO-8859-1. É a armadilha do passo 3, e você vai usá-la antes do arquivo bom.
  • agregados_domicilio2_sp_capital_2022.csv O arquivo oficial inteiro de onde saiu o extrato: 26.889 linhas e 318 colunas, variáveis V00090 em diante, com esgotamento sanitário, abastecimento de água, banheiro e espécie do domicílio. 45 MB. Revisão de 17/04/2025.
    oficial
  • agregados_domicilio1_sp_capital_2022.csv 26.889 linhas, variáveis V00001 a V00089: espécie e condição de ocupação do domicílio, moradores por faixa. É de onde vêm o total de domicílios e o de moradores usados no extrato.
    oficial
  • agregados_basico_sp_capital_2022.csv 27.301 linhas do agregado básico por setor. Tem uma linha por setor da malha, inclusive os sem domicílio, e serve para conferir a contagem do passo 4. Revisão de 20/05/2026.
    oficial
Pacote oficial, coleta de 02/08/2026, recorte de São Paulo capital. A malha e o arquivo de domicílio 2 são da mesma revisão, a de 17 de abril de 2025, que é justamente o cuidado que o passo 3 ensina. O extrato agregados_esgoto_sp_capital_2022.csv não é dado novo: são treze colunas copiadas do arquivo oficial de 45 MB, sem alterar um valor, para que a importação no QGIS caiba nos 45 minutos de roteiro. O agregados_esgoto_sp_ed_anterior.csv é o único arquivo construído para a aula, e existe para trazer 1.200 códigos de uma edição anterior da malha.
1

Carregar a malha e olhar a tabela antes de tudo

  1. Abra o QGIS e crie um projeto novo. Salve como InfoGeo/tema03_atributos/projeto.qgz.
  2. Vá em Project Properties General e, em Measurements, defina o elipsoide como GRS 1980 e a unidade de área como Hectares. Você aprendeu isso no tema 2 e vai precisar no exercício.
  3. Arraste setores_sp_capital_2022.gpkg para dentro da janela. São 27 MB e a primeira abertura demora alguns segundos.
  4. Clique com o botão direito na camada, escolha Zoom to Layer, e adicione a conexão OpenStreetMap que você cadastrou no tema 1, pelo painel Browser, em XYZ Tiles. Se ela não aparecer, refaça o passo 5 do Encontro 1.
  5. Abra a tabela de atributos com F6 e leia os nomes das colunas. Ordene por AREA_KM2 clicando no cabeçalho.
Janela do QGIS com a camada de setores censitários de São Paulo em rosa sobre o mapa do OpenStreetMap, e a tabela de atributos aberta abaixo, com as colunas fid, CD_SETOR, SITUACAO, CD_SIT, CD_TIPO, AREA_KM2, CD_REGIAO, NM_REGIAO, CD_UF, NM_UF e CD_MUN.
Figura 5 A camada carregada e a tabela aberta lado a lado. A barra de título da tabela confirma Features Total: 27301, e a coluna CD_SETOR mostra o código que vai servir de chave no passo 3. Repare que SITUACAO aparece como Rural nas primeiras linhas, porque a tabela está ordenada por AREA_KM2 decrescente: os maiores setores da capital ficam em Parelheiros e Marsilac, e um deles tem NULL em SITUACAO, defeito do próprio dado do IBGE.
Confira

A camada tem 27.301 feições e 37 campos. O rodapé da tabela mostra 27301 total. Nenhuma coluna diz quantos domicílios têm esgoto: a malha traz geometria, identificação e sete variáveis de contagem de pessoas e domicílios, v0001 a v0007. Os nomes de distrito aparecem com acento correto, porque o GeoPackage é UTF-8 por construção. Ordenado por área, o maior setor tem 41,87 km² e fica em Marsilac, no extremo sul; o menor tem 246 m², na Sé. Os dois valem uma linha de tabela cada.

Os quinze dígitos do CD_SETOR

A chave desta aula é o CD_SETOR, e ela é hierárquica: quinze dígitos em quatro blocos. Os sete primeiros são o código do município no padrão do IBGE, 3550308 para São Paulo. Os dois seguintes identificam o distrito, os dois seguintes o subdistrito, e os quatro últimos numeram o setor dentro dele. Por isso 355030826000002, na Consolação, e 355030830000023, no Grajaú, têm os mesmos sete dígitos iniciais e divergem no oitavo. Guarde a posição dos blocos: no passo 4 a diferença entre um código que casa e um que não casa vai estar no décimo segundo dígito, o primeiro dos quatro que numeram o setor. O campo é texto, e tem que continuar texto: importado como número, ele estoura o inteiro de 32 bits e perde precisão nos dígitos finais.

Leia o campo CD_TIPO antes de confiar na contagem

O IBGE marca em CD_TIPO o que o setor é. O valor 0 é setor comum, 1 é favela e comunidade urbana, 4 é setor de baixo patamar domiciliar, 6 é unidade prisional, 7 é convento, hospital ou instituição de longa permanência. Os 412 setores que não vão casar no passo 5 são quase todos do tipo 4, e isso muda completamente a leitura do nulo.

2

Importar o CSV, resolvendo encoding, separador e decimal

Arquivo de texto de origem pública brasileira quase nunca vem no padrão que o software espera. A planilha que você vai abrir agora usa ponto e vírgula entre campos e vírgula como separador decimal, do mesmo jeito que o IBGE distribui os agregados, e está gravada em Latin-1, a codificação em que boa parte dos órgãos públicos ainda publica.

  1. Vá em Layer Add Layer Add Delimited Text Layer.
  2. Em File name, aponte para agregados_esgoto_sp_ed_anterior.csv. Sim, o da edição anterior. É de propósito.
  3. Deixe primeiro o Encoding em UTF-8 e olhe o quadro de amostra na parte de baixo da janela.
O que você deve estar vendo

Jardim Ângela aparece como Jardim ?ngela ou Jardim �ngela, e Brasilândia, Capão Redondo e quebram do mesmo jeito. O arquivo não está corrompido: você pediu ao QGIS que lesse bytes Latin-1 como se fossem UTF-8. Troque Encoding para ISO-8859-1 e os acentos voltam na hora.

  1. Preencha o resto da janela conforme abaixo.
Data Source Manager · Delimited Text
Layer name
agregados_ed_anterior
Encoding
ISO-8859-1
File format
Custom delimiters · Semicolon
Number of header lines to discard
0
First record has field names
marcado
Detect field types
marcado
Decimal separator is comma
marcado
Geometry definition
No geometry (attribute only table)
  1. Clique Add e depois Close. A tabela entra no painel de camadas com um ícone diferente, sem geometria.
  2. Abra a tabela e confirme os tipos: passe o mouse sobre o cabeçalho de MEDIA_MORADORES e depois sobre o de V00311.
Confira

A tabela tem 26.889 linhas e treze colunas. MEDIA_MORADORES é decimal, com valores em torno de 3,0; se tiver virado texto, você esqueceu de marcar Decimal separator is comma, então remova a camada e importe de novo. Já as oito colunas V00309 a V00316 chegam como texto, e desta vez está certo: elas contêm 13.323 células com a letra X.

O que significa o X

O X é o marcador de sigilo estatístico do IBGE. Aparece onde a contagem é tão pequena que publicá-la permitiria identificar o informante, e nesta tabela ele sempre esconde um valor entre 1 e 8. Somadas, as células suprimidas escondem 14.342 domicílios dos 4.307.309 da cidade, 0,33% do total. Aqui vamos tratar X como zero e declarar isso no relatório. Quem tratar como nulo perde a linha inteira na soma, o que é bem pior.

Por que o tipo importa mais do que parece

Campo numérico importado como texto não dá erro. Ele ordena "1000" antes de "9", faz o Field Calculator recusar a operação, e em alguns caminhos concatena em vez de somar. Todo problema desta família nasce no diálogo de importação e só é percebido três passos depois. É por isso que o passo 6 embrulha cada variável em to_int.

3

A junção que parece ter dado certo

Confira a data das duas edições antes de cruzar

A malha de setores censitários do Censo 2022 foi republicada pelo IBGE em 17 de abril de 2025, com setores subdivididos, criados e extintos em relação à publicação anterior. Planilha de agregados montada antes dessa data traz códigos que não existem mais na malha de hoje, e é esse o caso do agregados_esgoto_sp_ed_anterior.csv que você acabou de importar. A data de publicação está no metadado dos dois lados e leva quinze segundos para conferir, bem menos do que qualquer diagnóstico depois do estrago. Aqui a conferência fica de propósito para o passo seguinte, para você ver o tamanho do prejuízo.

  1. Abra a caixa de ferramentas de processamento com Ctrl+Alt+T.
  2. Procure por Join attributes by field value, cujo identificador é native:joinattributestable.
  3. Preencha assim.
Join attributes by field value
Input layer
setores_sp_capital_2022
Table field
CD_SETOR
Input layer 2
agregados_ed_anterior
Table field 2
CD_SETOR
Layer 2 fields to copy
V00001, V00005, V00309 a V00316
Join type
Take attributes of the first matching feature only (one-to-one)
Discard records which could not be joined
desmarcado
Joined layer
dados_tratados/setores_join_ruim.gpkg
O que a opção Join type está decidindo

Ao escolher Take attributes of the first matching feature only você declarou que a junção é 1:1. A alternativa, Take attributes of all matching features, é a de uma junção 1:n: ela duplica a geometria de entrada uma vez para cada correspondência encontrada. Aqui a primeira opção é a certa, porque existe no máximo uma linha de agregados por setor. Num cruzamento em que o mesmo setor tivesse várias correspondências, a primeira opção descartaria as demais sem avisar e a segunda multiplicaria as feições, e os dois caminhos mudariam o total. A cardinalidade não está escrita no arquivo: quem a declara é você, nessa caixa.

  1. Clique Run. Com 27.301 feições isso leva perto de meio minuto. Leia a janela de log até o fim e depois feche.
Leia o log com atenção

O log informa quantas feições foram unidas e quantas não foram, sem nenhum destaque, entre outras linhas de execução. A camada nova entra no projeto com 27.301 feições, desenha igual à original e não tem nenhuma marca visual de problema. Se você fechar o log sem ler, e a maioria fecha, segue tudo em frente.

Deixe Discard records which could not be joined desmarcado sempre. Marcado, ele apaga as feições que não casaram e a camada de saída passa a ter menos feições, o que remove a única pista visível de que algo deu errado.

4

Medir a taxa de casamento e achar o culpado

Agora a checagem de trinta segundos que muda o resultado da aula.

A sintaxe de expressão do QGIS

A linguagem de expressão do QGIS é própria, parecida com SQL sem ser SQL, e a regra de pontuação é uma só: nome de campo entre aspas duplas, texto literal entre aspas simples. Trocar as duas é o erro de digitação mais comum do curso, e ele aparece ora como campo inexistente, ora como comparação que nunca é verdadeira. Separador decimal dentro da expressão é sempre o ponto, mesmo quando a tabela mostra vírgula. Estas são as formas que você vai usar hoje e nos próximos temas.

"V00001" IS NULL                              -- o que a junção não trouxe
"NM_DIST" = 'Marsilac'                        -- aspas simples para texto
"NM_DIST" IN ('Parelheiros', 'Marsilac')      -- lista de valores
"NM_DIST" LIKE 'Jardim%'                      -- prefixo
"PCT_SEM" > 70                                -- campo criado no passo 6
"PCT_SEM" > 70 AND "V00005" > 1000            -- crítico e populoso
left("CD_SETOR", 9) = '355030855'             -- todos os setores de um distrito
  1. Selecione setores_join_ruim e abra a tabela de atributos.
  2. Clique no ícone de seleção por expressão, ou use Edit Select Select Features by Expression.
  3. Escreva "V00001" IS NULL, a primeira linha do quadro acima, e clique Select Features.
Confira

O rodapé da tabela mostra 1.612 feições selecionadas de 27.301. A taxa de casamento é 25.689 de 27.301, ou 94,10%. Nenhuma mensagem de erro apareceu em momento algum.

Erro comum

Escrever "V00001" != NULL para achar o que casou. Qualquer comparação com nulo devolve nulo, que não é verdadeiro, então a expressão seleciona zero feições e não emite aviso nenhum. A forma correta é "V00001" IS NOT NULL, e ela devolve as 25.689. Pela mesma razão, quando você chegar ao passo 7, "PCT_SEM" > 70 vai deixar de fora as linhas nulas: nulo não é maior nem menor que nada.

Duas tabelas lado a lado com códigos de setor de São Paulo; duas linhas do Grajaú não casam porque o décimo segundo dígito difere. Abaixo, a taxa de casamento de 94,10 por cento e a comparação entre o indicador correto de 4,56 por cento e o enviesado de 3,27 por cento.
Figura 6 As duas tabelas que você acabou de cruzar, com cinco linhas cada. Consolação, Marsilac e Lajeado casam; os dois setores do Grajaú não, porque o décimo segundo dígito mudou entre as duas edições da malha. Não há mensagem de erro em lugar nenhum. O prejuízo não é o dado que falta: os 1.200 setores que não casam têm 38,60% de domicílios sem esgotamento adequado, oito vezes a média da cidade, e o indicador calculado sobre o que sobrou cai de 4,56% para 3,27%.
  1. Com as 1.612 selecionadas, clique no botão que mostra apenas as feições selecionadas e olhe as colunas NM_DIST e v0001, esta última minúscula, que é a população do setor segundo a própria malha.
  2. Volte ao mapa. As 1.612 estão realçadas em amarelo.
Janela do QGIS com a camada resultante da junção. Os setores sem correspondência aparecem preenchidos em laranja, formando uma mancha contínua no extremo sul do município e manchas menores nas bordas norte e leste. No painel de camadas aparecem a camada unida, a tabela da edição anterior e a malha original desligada.
Figura 7 Os setores que não encontraram par na tabela, em laranja. O padrão não é aleatório: a mancha contínua do extremo sul cobre Parelheiros, Marsilac e o entorno da represa, e as manchas menores acompanham as bordas norte e leste. São justamente as áreas de setor grande e população rarefeita, que sofreram redivisão entre as duas edições da malha. Um join que perde 3,27% das feições ao acaso é um problema de digitação; um que perde a periferia inteira muda a conclusão de qualquer indicador social.
Onde os buracos caem

Os nulos não estão espalhados. Grajaú responde por 138, Parelheiros por 117, Marsilac por 40, Brasilândia por 38, Cidade Tiradentes e Jardim Ângela por 36 cada. Nenhum setor da Consolação, de Pinheiros ou do Jardim Paulista. É a periferia inteira e nada do centro expandido. O motivo é o mesmo que gera a falha: setores subdivididos entre uma edição e outra da malha, e a subdivisão acontece onde a população cresceu rápido.

  1. Para ver a chave de perto, compare um código dos dois lados. Abra agregados_ed_anterior e procure por 355030843005915. Depois procure 355030843000915 na malha. São o mesmo setor do Jardim Ângela em duas edições, e diferem no décimo segundo dígito, o primeiro dos quatro que numeram o setor dentro do subdistrito.
  2. Antes de seguir, limpe a seleção e remova setores_join_ruim do projeto.
Guarde este número

Dos 1.612 nulos, 412 vão continuar nulos no passo 5, com o arquivo certo. Os outros 1.200 são a falha de chave. O passo 5 mostra como separar os dois casos, e é essa separação que a prova pode cobrar.

5

Refazer com o arquivo da edição certa

  1. Importe agregados_esgoto_sp_capital_2022.csv com os mesmos parâmetros do passo 2, mudando só o Encoding para UTF-8, que é como o IBGE publica hoje. Nomeie a camada agregados_2022.
  2. Rode native:joinattributestable de novo, trocando Input layer 2 para agregados_2022 e gravando em dados_tratados/setores_esgoto.gpkg.
  3. Repita a seleção por expressão "V00001" IS NULL na camada nova.
Confira

412 feições selecionadas, e não zero. A taxa de casamento é 26.889 de 27.301, ou 98,49%. Antes de comemorar ou de se desesperar, olhe a coluna v0001 da malha nesses 412: soma zero moradores. Some agora as colunas trazidas pelo painel de estatísticas, em View Panels Statistics: V00001 soma 4.307.309 domicílios e V00005 soma 11.394.071 moradores.

Dois nulos com causas opostas

Os 412 que sobraram são setores sem domicílio particular permanente ocupado: 367 deles têm CD_TIPO igual a 4, o código de baixo patamar domiciliar, e o resto é parque, área industrial, presídio ou instituição. O IBGE não publica agregado de domicílio para eles porque não há domicílio a agregar. Esses 412 não mexem em nada no indicador, porque entram com zero no numerador e no denominador. Os 1.200 do passo 4 mexiam, e muito. A contagem de nulos, sozinha, não distingue um caso do outro: é preciso olhar o CD_TIPO e a população dos setores que não casaram.

O que acabou de acontecer com o resultado

Com o arquivo errado, o indicador da cidade sairia em 3,27%. Com o certo, sai em 4,56%. A diferença de 1,29 ponto parece pequena e não é: em termos relativos, o cruzamento errado apagou 28% do problema. Os 1.200 setores perdidos tinham 38,60% de domicílios sem esgotamento adequado, oito vezes a média da cidade, então a falha empurrava o número sempre na mesma direção. Em domicílios, são 60.335 casas sem esgotamento adequado que sumiriam da conta.

6

Construir o indicador com o Field Calculator

O Censo não publica um campo "sem esgoto". Publica oito destinos possíveis para o esgoto do banheiro, e a definição de adequado é uma escolha metodológica que você precisa fazer de forma explícita.

CampoDestinação do esgoto do banheiro ou sanitárioClassificação
V00309Rede geral ou rede pluvialadequado
V00310Fossa séptica ou fossa filtro ligada à redeadequado
V00311Fossa séptica ou fossa filtro não ligada à redeinadequado
V00312Fossa rudimentar ou buracoinadequado
V00313Valainadequado
V00314Rio, lago, córrego ou marinadequado
V00315Outra formainadequado
V00316Não tinham banheiro nem sanitárioinadequado
É a mesma separação que o Plansab e o IBGE usam. Um consultor que quisesse melhorar o número classificaria a fossa séptica não ligada à rede como adequada, e o percentual de São Paulo cairia de 4,56% para 3,76%, porque 34.331 domicílios mudariam de lado. Nenhuma das duas classificações é indefensável; a diferença é que a do Plansab está documentada em norma, e a alternativa precisaria ser declarada com o mesmo cuidado.
  1. Selecione setores_esgoto, entre em modo de edição com Ctrl+E e abra o Field Calculator com Ctrl+I.
  2. Marque Create a new field, nome DOM_TOT, tipo Whole number (integer). As oito colunas chegaram como texto por causa dos X, então cada parcela precisa ser convertida. A conversão vai por try, e o motivo está na caixa logo abaixo.
try(to_int("V00309"),0) + try(to_int("V00310"),0) +
try(to_int("V00311"),0) + try(to_int("V00312"),0) +
try(to_int("V00313"),0) + try(to_int("V00314"),0) +
try(to_int("V00315"),0) + try(to_int("V00316"),0)
Erro comum

Se você escrever apenas to_int("V00309"), o QGIS responde Cannot convert 'X' to int e a expressão inteira falha, porque a coluna tem células com a letra X. É para isso que serve o try: quando a conversão falha, ele devolve o segundo argumento, que aqui é zero, e a soma continua.

Pergunta norteadora

O try resolveu o erro transformando X em zero. Mas X quer dizer zero?

Não. No Censo 2022 o X marca valor suprimido por sigilo estatístico: o IBGE omite a contagem quando ela é pequena o bastante para permitir identificar quem respondeu. Zero é uma afirmação sobre o mundo, X é uma recusa a informar. Neste extrato há 13.323 células com X, distribuídas por 8.998 setores, um terço da cidade. Somadas, escondem 14.342 domicílios, 0,33% do total do município. O roteiro segue tratando X como zero por uma razão declarada, e a caixa ao fim deste passo mede o preço dessa decisão.

  1. Crie DOM_INAD, também inteiro, com as seis últimas parcelas da expressão acima, de V00311 a V00316, cada uma também dentro de try.
  2. Crie PCT_SEM, Decimal number (real), comprimento 10, precisão 2. O if evita a divisão por zero nos setores sem domicílio.
if("DOM_TOT" > 0, "DOM_INAD" / "DOM_TOT" * 100.0, NULL)
  1. Crie também PCT_ADEQ, com if("DOM_TOT" > 0, 100.0 - "DOM_INAD" / "DOM_TOT" * 100.0, NULL).
  2. Salve as edições e desligue o modo de edição.
  3. Aplique uma simbologia graduada: botão direito na camada, Properties, aba Symbology, Graduated, campo PCT_SEM, cinco classes, modo Equal Count (Quantile), Classify. Olhe a legenda antes de olhar o mapa.
Janela do QGIS com o mapa de São Paulo classificado por PCT_SEM. A legenda mostra cinco classes e as quatro primeiras têm o rótulo 0 - 0. O painel de estatísticas informa Q3 igual a zero, IQR igual a zero e 625 valores nulos. O mapa aparece quase todo preto por causa do contorno dos setores, com uma mancha vermelha contínua no extremo sul.
Figura 8 A classificação por quantis colapsou. Quatro das cinco classes saíram com o rótulo 0 - 0, e o painel de estatísticas explica por quê: o terceiro quartil é zero, e o intervalo interquartílico também. O mapa aparece preto porque 27.301 contornos de setor, na escala do município, cobrem o preenchimento.
Erro comum

A legenda com quatro classes 0 - 0 não é defeito do QGIS. Em São Paulo, 21.682 dos 26.676 setores com denominador válido têm PCT_SEM exatamente zero, o que é 81,3% da cidade. Quantil divide a amostra em cinco partes de tamanho igual, e as quatro primeiras cabem inteiras dentro do zero. A cobertura de esgoto da capital é quase universal, e o indicador é o que a estatística chama de distribuição com excesso de zeros: a informação está concentrada nos 4.994 setores que sobram.

  1. Volte a Symbology e troque o modo para Manual. Apague as classes e crie cinco faixas com estes limites: 0 a 0, depois 0 – 5, 5 – 20, 20 – 50 e 50 – 100. A primeira isola quem não tem o problema; as outras quatro repartem os 4.994 setores em que ele existe.
  2. Ainda em Symbology, clique em Change no símbolo e, em Simple fill, mude Stroke style para No pen. Sem isso, o contorno de 27 mil polígonos domina a tela e o mapa lê como preto.
Confira

A legenda agora traz cinco faixas com limites diferentes entre si, e o mapa mostra o branco da primeira classe na maior parte da cidade, com a cor forte concentrada no extremo sul, entre Grajaú, Parelheiros e Marsilac, e manchas menores nas bordas norte e leste. A quantidade de feições por classe aparece ao lado de cada faixa se você marcar a coluna de contagem no menu de contexto da legenda.

Pergunta norteadora

Os limites 0, 5, 20, 50 e 100 vieram de onde?

De lugar nenhum, e é esse o ponto. Foram escolhidos para separar ordens de grandeza, não por norma. Um corte diferente muda a impressão visual sem alterar um único dado, e essa é justamente a discussão do tema 4, que trata dos quatro métodos de classificação e do efeito de cada um sobre a leitura. Por ora vale a regra mínima: sempre que a legenda for construída à mão, o critério vai escrito na peça.

Confira

No painel de estatísticas com o campo PCT_SEM: o mínimo é 0,00%, o máximo é 100,00%, a mediana é 0,00% e há 625 nulos, que são os 412 sem agregado mais 213 setores cujas oito variáveis somam zero. Vinte e um mil seiscentos e oitenta e dois setores estão em zero, e trezentos e oito em 100%, e o maior deles é o 355030811000446, na Brasilândia, com 206 domicílios e 672 moradores. O indicador da cidade não é a média dos setores: é DOM_INAD somado dividido por DOM_TOT somado, que dá 4,56%, ou 195.714 domicílios em 4.292.967.

O preço de tratar X como zero

Vale medir a decisão em vez de confiar nela. Se em vez de zerar o X você descartasse todo setor que tem ao menos uma célula suprimida, sobrariam 17.891 setores no lugar de 26.676, e o percentual da cidade cairia de 4,56% para 2,92%. A diferença é grande demais para vir dos 14.342 domicílios que os X escondem, que são 0,33% do total.

A explicação está em quem some. A supressão não é sorteada: ela atinge o setor onde alguma categoria tem contagem baixa, e categoria com contagem baixa é justamente fossa, vala e ausência de banheiro. Descartar esses setores tira da conta, de forma sistemática, os lugares onde o problema aparece — e devolve um número menor e mais confortável. Zerar o X subestima um pouco; descartar o setor subestima muito, e com viés de direção conhecida. Nas duas hipóteses o relatório precisa dizer qual foi adotada e quantos setores têm supressão.

Erro comum

Reportar a média aritmética de PCT_SEM como percentual da cidade. Isso dá 5,82% aqui, quase um ponto e meio acima do valor correto, porque a média de percentuais trata um setor de 42 domicílios em Anhanguera como igual a um de 474 na Vila Andrade. O percentual da cidade é uma razão de somas, não uma média de razões. Repare que desta vez o erro inflaria o número: o viés da média simples não tem direção fixa, depende de onde estão os setores pequenos.

7

Selecionar os setores críticos e exportar

  1. Com setores_esgoto ativa, abra Edit Select Select Features by Expression.
  2. Use a expressão e clique Select Features.
"PCT_SEM" > 70
Confira

912 feições selecionadas de 27.301. Com a seleção ativa, o painel de estatísticas em modo Selected features only mostra V00005 somando 282.993 pessoas, que é 2,48% dos 11,4 milhões da cidade, e DOM_TOT somando 93.735 domicílios, dos quais 81.515 sem esgotamento adequado. A soma de AREA_KM2332,8 km², ou 21,9% do território municipal.

Dois números que só fazem sentido juntos

2,48% da população em 21,9% da área. Os setores críticos de São Paulo são grandes e vazios porque estão no cinturão de mananciais do extremo sul e nas bordas de mata do norte, onde a densidade é baixa. Um mapa que pintasse só esses polígonos daria a impressão de um problema enorme; um número que citasse só a população daria a impressão de um problema desprezível. Os dois estão certos, e um relatório honesto apresenta os dois lado a lado.

  1. Botão direito na camada, Export Save Selected Features As.
  2. Preencha a janela conforme abaixo.
Save Vector Layer as
Format
GeoPackage
File name
dados_tratados/setores_criticos.gpkg
Layer name
setores_criticos
CRS
EPSG:4674 — SIRGAS 2000
Encoding
UTF-8
Save only selected features
marcado
Add saved file to map
marcado

O corte em 70% é seu, não dos dados. Baixando para 50% a seleção sobe para 1.314 setores e 446.796 pessoas; subindo para 90% cai para 477 setores e 119.358 pessoas. Um secretário municipal com orçamento para trinta obras escolheria outro limiar, e um promotor de justiça montando ação civil pública escolheria um terceiro. Anote qual você usou e por quê, do mesmo jeito que anota o CRS.

8

Quantos setores críticos estão em Parelheiros, e o que "estar em" quer dizer

Agora a consulta por localização, que não olha a tabela. A pergunta parece trivial e não é: a resposta muda conforme o predicado que você escolhe.

  1. Selecione setores_esgoto e faça uma seleção por expressão com "NM_DIST" = 'Parelheiros'. São 455 setores.
  2. Exporte a seleção com Export Save Selected Features As para dados_tratados/parelheiros.gpkg.
  3. Na caixa de ferramentas, rode Dissolve, de identificador native:dissolve, sobre parelheiros sem campo nenhum em Dissolve field(s), gravando em dados_tratados/parelheiros_limite.gpkg. Sai um polígono só, o contorno do distrito.
  4. Procure Extract by location, de identificador native:extractbylocation, e preencha conforme abaixo.
Extract by location
Extract features from
setores_criticos
Where the features are
are within
By comparing to the features from
parelheiros_limite
Extracted
dados_tratados/criticos_parelheiros.gpkg
  1. Rode e leia a contagem de feições da camada de saída.
  2. Rode de novo, trocando apenas Where the features are para intersect, e compare.
Confira

Are within devolve 167 setores. Intersect devolve 190. Os 23 de diferença não estão em Parelheiros: são 13 setores de Marsilac e 10 do Grajaú que encostam na divisa do distrito e, por compartilharem pontos de fronteira, satisfazem intersects. Se o seu relatório disser "190 setores críticos em Parelheiros", ele está errado em 14%, e ninguém vai notar olhando o mapa.

Erro comum

Usar intersect por ser o predicado que aparece primeiro na lista. Ele é o mais permissivo dos cinco e quase sempre devolve mais do que você pediu. Quando a pergunta é "está dentro de", o predicado é are within. Quando é "encosta em", é touch. Escolher errado não produz mensagem de erro: produz um número diferente, que segue adiante sem nenhuma marca de problema.

A conclusão do roteiro

282.993 pessoas em 912 setores, espalhadas por 55 dos 96 distritos

Os 912 setores críticos concentram 2,48% da população da cidade em 21,9% do território, e os 167 que estão dentro de Parelheiros respondem sozinhos por 14.236 domicílios e 43.818 moradores. A pergunta do tema pedia "em qual quarteirão", e o roteiro devolveu 912 polígonos com código de quinze dígitos, distrito e contagem de domicílios. É esse nível de detalhe que transforma uma estatística em ordem de serviço.

Parte 3

Exercício

15 min
Faça sozinho15 minutos · sem consultar o colega

Saneamento ruim pesa diferente conforme a densidade: num setor esvaziado é um problema de cobertura, num setor adensado vira risco sanitário imediato, porque o esgoto a céu aberto convive com muita gente. Os 912 setores críticos do passo 7 são quase todos do primeiro tipo. Vamos procurar o segundo.

  1. Na camada setores_esgoto, crie o campo DENS_DOM, decimal com precisão 4, usando "DOM_TOT" / ("AREA_KM2" * 100). Sai em domicílios por hectare. Se quiser conferir, compare o denominador com $area, que agora devolve hectares porque você definiu o elipsoide no passo 1.
  2. Abra o painel de estatísticas e anote a mediana de DENS_DOM e a mediana de PCT_SEM.
  3. Olhe para a segunda mediana antes de continuar. Ela vai atrapalhar o plano óbvio, e o que você faz a partir daí é metade do exercício.
  4. Selecione por expressão os setores que estão acima da mediana de densidade e que tenham pelo menos um domicílio sem esgotamento adequado.
  5. Com a seleção ativa, leia no painel de estatísticas quantos setores são, quantos moradores vivem neles e que fração isso representa da população da cidade.

Depois responda, em quatro linhas:

  1. Por que a mediana de PCT_SEM não serve como corte, e que outro critério você usaria no lugar?
  2. Que distritos aparecem mais nessa seleção, e por que a combinação densidade alta com saneamento ruim é pior do que cada uma das duas isoladamente?
  3. Compare a lista de distritos desta seleção com a lista dos 912 setores críticos do passo 7. São as mesmas regiões? O que isso diz sobre priorizar obra por percentual?
Entrega Uma captura de tela do painel de estatísticas com a seleção ativa, mais as quatro linhas. Poste no fórum do tema no Blackboard antes do fim da aula.
Gabarito numérico

A mediana de DENS_DOM é 69,2868 domicílios por hectare. A mediana de PCT_SEM é 0,00, e o terceiro quartil também: 21.682 setores, ou 81,3% dos que têm domicílio, não têm nenhuma casa sem esgotamento adequado. Um corte pela mediana degenera em "qualquer valor maior que zero". A expressão "DENS_DOM" > 69.2868 AND "PCT_SEM" > 0 seleciona 2.443 setores, com 453.029 domicílios, 105.403 deles sem esgotamento adequado, e 1.307.270 moradores em 38,2 km², ou 11,47% da população da cidade. Grajaú aparece 180 vezes, Jardim Ângela 127, Cidade Ademar 115, Jardim São Luís 105, Brasilândia 101 e Capão Redondo 96. Trocando a mediana pelo terceiro quartil de densidade, 132,9735 domicílios por hectare, sobram 935 setores e 544.525 moradores, e a lista muda de cara: Cidade Ademar 59, Campo Limpo 57, Vila Andrade 52, Jardim São Luís 50. Use ponto como separador decimal dentro da expressão, mesmo que a tabela mostre vírgula.

Parte 4

Fechamento

20 min
A resposta do tema

4,56% dos domicílios, e não 3,3%. A diferença veio de 1.200 setores que a junção descartou sem avisar, e eram justamente os piores.

O estagiário não errou nenhuma fórmula. Ele cruzou uma malha publicada em abril de 2025 com uma planilha montada antes disso, e 94,10% das linhas casaram. Os 5,9% que faltaram tinham 38,60% de domicílios sem esgotamento adequado, oito vezes a média da cidade: 60.335 casas apagadas da conta. Nenhuma ferramenta reclamou, porque, do ponto de vista do programa, nada de anormal aconteceu.

E a pergunta pedia o quarteirão: são 912 setores, com 282.993 pessoas, espalhados por 55 distritos e concentrados em Parelheiros, Grajaú, Marsilac, Cidade Tiradentes, Jaraguá e Jardim Ângela. Em Marsilac o problema não é de setor, é de distrito inteiro: 86,94% dos domicílios de lá não têm esgotamento sanitário adequado.

O que discutir com a turma

Três perguntas para os últimos minutos.

Discussão

Uma taxa de casamento de 94% é aceitável?

Depende inteiramente de quem sumiu. Se os 5,9% faltantes fossem sorteados entre 27 mil setores, o efeito sobre a média seria desprezível. Aqui eles não foram sorteados: são os piores. Repare que a taxa de 98,49% do arquivo certo, que parece pior do que 100%, não introduz viés nenhum, porque os 412 nulos de lá têm zero domicílio. A taxa sozinha não responde; o que decide é se o que faltou se parece com o que ficou.

Discussão

Classificar fossa séptica não ligada à rede como inadequada é uma escolha técnica ou política?

As duas coisas, e vale reconhecer isso em voz alta. Existe argumento sanitário dos dois lados, e o percentual de São Paulo cai de 4,56% para 3,76% conforme a definição, o que muda 34.331 domicílios de lado. Quem publica o número tem obrigação de declarar a definição junto; quem lê tem obrigação de perguntar por ela.

Discussão

Se o setor censitário foi desenhado para caber na rotina do recenseador, faz sentido usá-lo como unidade de política pública de saneamento?

O que esta aula não resolveu
  • Você contou domicílios sem esgotamento adequado, e não pessoas doentes. A relação entre as duas coisas existe e não é de um para um; medi-la exige dado de saúde que não está aqui.
  • O setor censitário informa quantos domicílios estão em situação inadequada, e não quais. Dentro do setor 355030883000364, na Vila Andrade, com 474 domicílios e 355 sem esgotamento adequado, você não sabe qual rua tem rede e qual não tem. O Censo não desce abaixo do setor, por sigilo estatístico.
  • Os 13.323 X foram tratados como zero, e por baixo deles há até 14.342 domicílios. É pouco na cidade inteira, 0,33%, e pode ser muito num setor específico onde quatro das oito colunas estão suprimidas. Nenhum passo mediu esse efeito setor a setor.
  • Todo indicador aqui usa o domicílio como unidade. Um setor com 474 domicílios e outro com 42 pesam igual quando você olha o mapa, porque a cor não é ponderada por tamanho. Isso é assunto da aula 4.
  • A geometria foi tratada como correta. Nenhum passo rodou Check Validity sobre a malha, e em base oficial vale rodar antes de qualquer coisa.
  • Os 912 setores críticos são grandes e pouco povoados. Nada aqui diz quanto custa levar rede até eles, e a resposta depende de topografia, distância à rede existente e restrição de área de manancial. Isso não é geoprocessamento de atributo; é projeto de engenharia.
Leituras

Para depois da aula

Preparação
Mark Monmonier, How to Lie with Maps, capítulo sobre mapas de dados e classificação. Leitura dirigida de 15 minutos · antes do tema 4
Oficial
IBGE, nota metodológica dos agregados por setores censitários do Censo 2022, com a definição de esgotamento sanitário adequado. ibge.gov.br · Censo 2022 · agregados por setores
Oficial
IBGE, documentação da malha de setores censitários e o registro da republicação de 17 de abril de 2025. ibge.gov.br · geociências · malhas territoriais
Referência
Gilberto Câmara e outros, Introdução à Ciência da Geoinformação, capítulo sobre representação vetorial e bancos de dados geográficos. INPE · disponível em PDF · leitura de apoio
Aplicado
Instituto Trata Brasil, ranking do saneamento nas cem maiores cidades, para comparar a definição de adequado usada lá com a que você usou aqui. tratabrasil.org.br · leia a metodologia, não só o ranking