2. O que é GeoJSON#
2.1 Conceitos Fundamentais#
GeoJSON é um formato aberto de codificação para representar estruturas de dados geográficos, baseado em JSON (JavaScript Object Notation).
2.2 Estrutura Básica#
Um arquivo GeoJSON válido contém obrigatoriamente um objeto FeatureCollection:
Exemplo de estrutura GeoJSON básica:
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4674"
}
},
"metadata": {
"schema_version": "R0",
"ano_programacao": 2026,
"data_geracao": "2025-10-30T14:30:00-03:00"
},
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-47.0653, -23.5489]
},
"properties": {
"id": 1,
"detalhamento_servico": "Exemplo de feature"
}
}
]
}Componentes principais:
| Componente | Descrição |
|---|---|
type | Sempre "FeatureCollection" para a coleção de features. |
crs | Sistema de Referência de Coordenadas (obrigatório para ARTESP). |
metadata | Metadados de controle (específico da ARTESP). |
features | Array contendo as features (geometria + propriedades). |
2.3 Tipos de Geometria#
O GeoJSON suporta os seguintes tipos geométricos:
2.3.1 Point (Ponto)#
Representa uma localização única no espaço.
Exemplo: [-47.0653, -23.5489]
2.3.2 LineString (Linha)#
Representa uma sequência conectada de pontos.
Exemplo de coordenadas: [ [-47.0653, -23.5489], [-47.0663, -23.5499] ]
Estrutura completa:
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-47.0653, -23.5489],
[-47.0663, -23.5499],
[-47.0673, -23.5509]
]
},
"properties": {
"id": "pavimento-001",
"detalhamento_servico": "Recuperação funcional do pavimento"
}
}Cálculo de Distância entre Pontos Consecutivos#
Para garantir a qualidade e precisão de geometrias LineString, é importante controlar a distância máxima entre pontos consecutivos.
Por que isso importa:
- Distâncias muito grandes entre pontos (> 20m) podem resultar em linhas “retas” que não seguem o traçado real da rodovia
- Distâncias muito pequenas (< 5m) geram vértices excessivos e comprometem a performance
- O espaçamento adequado (~20m) garante representação fiel do trajeto com boa eficiência
Fórmula de Haversine (para coordenadas geográficas em graus):
a = sin²(Δlat/2) + cos(lat₁) × cos(lat₂) × sin²(Δlon/2)
c = 2 × atan2(√a, √(1−a))
d = R × cOnde:
- R = 6.371.000 m (raio médio da Terra)
- Δlat = lat₂ - lat₁ (em radianos)
- Δlon = lon₂ - lon₁ (em radianos)
Implementação em Python:
import math
def distancia_haversine(lon1, lat1, lon2, lat2):
"""
Calcula a distância entre dois pontos usando a fórmula de Haversine.
Parâmetros:
lon1, lat1: Coordenadas do primeiro ponto (graus decimais)
lon2, lat2: Coordenadas do segundo ponto (graus decimais)
Retorna:
Distância em metros
"""
R = 6371000 # Raio da Terra em metros
# Converter de graus para radianos
lat1_rad = math.radians(lat1)
lat2_rad = math.radians(lat2)
delta_lat = math.radians(lat2 - lat1)
delta_lon = math.radians(lon2 - lon1)
# Fórmula de Haversine
a = math.sin(delta_lat/2)**2 + \
math.cos(lat1_rad) * math.cos(lat2_rad) * \
math.sin(delta_lon/2)**2
c = 2 * math.asin(math.sqrt(a))
return R * c
# Exemplo de uso
ponto1 = (-47.0653, -23.5489)
ponto2 = (-47.0663, -23.5499)
dist_m = distancia_haversine(ponto1[0], ponto1[1], ponto2[0], ponto2[1])
print(f"Distância: {dist_m:.1f} m")
# Saída: Distância: 136.3 mValidação da Distância Máxima:
def validar_distancias_linestring(coordinates, max_distancia_m=20.0):
"""
Valida se todos os segmentos de uma LineString respeitam a distância máxima.
Parâmetros:
coordinates: Lista de coordenadas [[lon, lat], ...]
max_distancia_m: Distância máxima permitida entre pontos consecutivos (metros)
Default: 20m (recomendado para trechos rodoviários)
Retorna:
(bool, list): (é_válido, lista_de_erros)
"""
erros = []
for i in range(len(coordinates) - 1):
lon1, lat1 = coordinates[i]
lon2, lat2 = coordinates[i + 1]
dist = distancia_haversine(lon1, lat1, lon2, lat2)
if dist > max_distancia_m:
erros.append({
'segmento': f"{i} → {i+1}",
'ponto1': [lon1, lat1],
'ponto2': [lon2, lat2],
'distancia_m': round(dist, 1)
})
return len(erros) == 0, erros
# Exemplo de validação
linestring = [
[-47.0653, -23.5489],
[-47.0655, -23.5491], # Distância ~31m - EXCEDE o limite de 20m
[-47.0800, -23.5600] # Distância ~18km - MUITO ACIMA do limite
]
valido, erros = validar_distancias_linestring(linestring, max_distancia_m=20.0)
if not valido:
print("⚠️ Segmentos com distância excessiva encontrados:")
for erro in erros:
print(f" Segmento {erro['segmento']}: {erro['distancia_m']:.1f} m")📏 Recomendações de Distância:
| Tipo de Geometria | Distância Máxima Recomendada | Observações |
|---|---|---|
| Trechos rodoviários gerais | 20 m | Padrão recomendado - equilíbrio entre precisão e performance |
| Trechos rodoviários retos | 50-100 m | Pode ser relaxado em trechos retilíneos longos |
| Trechos com curvas suaves | 20-30 m | Mantém fidelidade ao traçado |
| Trechos com curvas acentuadas | 10-15 m | Necessário para representar curvas complexas |
| Áreas urbanas/dispositivos | 5-10 m | Maior detalhamento em interseções e alças |
⚠️ Alertas:
- O padrão de 20 metros oferece boa precisão sem gerar vértices excessivos
- Evite vértices excessivos (> 1000 pontos por LineString) para não comprometer performance
- Para trechos muito longos (> 50 km), considere dividir em múltiplas features
- Use ferramentas GIS para simplificar geometrias quando apropriado
- Distâncias inferiores a 5m raramente agregam precisão significativa
2.3.3 Polygon (Polígono)#
Representa uma área fechada.
Exemplo: [ [ [-47.06, -23.54], [-47.07, -23.54], [-47.07, -23.55], [-47.06, -23.55], [-47.06, -23.54] ] ]
2.3.4 MultiPoint (Múltiplos Pontos)#
Representa um conjunto de pontos discretos não conectados entre si.
Uso típico: Localização de múltiplos itens similares distribuídos ao longo de um trecho (sensores, tachões, placas de sinalização).
Exemplo de coordenadas:
[
[-47.0653, -23.5489],
[-47.0663, -23.5499],
[-47.0673, -23.5509]
]Estrutura completa:
{
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": [
[-47.0653, -23.5489],
[-47.0663, -23.5499],
[-47.0673, -23.5509]
]
},
"properties": {
"id": "sensor-001",
"detalhamento_servico": "Instalação de sensores de tráfego"
}
}2.3.5 Diferença entre MultiPoint e LineString#
Embora ambos os tipos usem arrays de coordenadas, possuem diferenças fundamentais:
| Aspecto | MultiPoint | LineString |
|---|---|---|
| Conectividade | Pontos independentes (não conectados) | Pontos conectados sequencialmente |
| Ordem dos pontos | Ordem não implica continuidade espacial | Ordem define o trajeto da linha |
| Interpretação visual | Conjunto de marcadores discretos | Linha contínua |
| Uso típico | Itens múltiplos e discretos | Trechos lineares contínuos |
| Distância entre pontos | Irrelevante | Deve ser calculada (veja abaixo) |
📌 Exemplo Prático:
MultiPoint - Instalação de 5 radares ao longo da SP-280:
- Radar no km 100
- Radar no km 115
- Radar no km 130
- Radar no km 145
- Radar no km 160
→ Não há relação de continuidade entre os radares. São itens independentes.
LineString - Recuperação de pavimento do km 100 ao km 110 da SP-280:
- Ponto inicial: km 100
- Pontos intermediários: km 102, km 104, km 106, km 108
- Ponto final: km 110
→ Há continuidade espacial. O serviço cobre toda a extensão entre os pontos.
⚠️ Regra de Decisão:
- Use MultiPoint quando os itens são discretos e independentes
- Use LineString quando há continuidade espacial entre os pontos