Uma sobreposição de grade de Plus Codes (Open Location Code) desenhada como tiles SVG em cima do Leaflet, com:
- rótulos centralizados por célula (seguindo o spec do OLC, inclusive
+
e0
de padding); - auto‐fit do tamanho da fonte por célula;
- contorno do texto para legibilidade;
- mapeamento de zoom → comprimento do código (codeLen) de 2 até 15 dígitos;
- alinhamento global em −90/−180 para as linhas da grade (sem “derrapar” entre tiles);
- fallback de
encode()
embutido (compliant com o spec) caso a lib oficial não carregue.
-
Mapa Leaflet (EPSG:3857) com tiles OSM.
-
Overlay de grade com linhas e rótulos no centro de cada célula, sempre compatíveis com o spec OLC:
- Para
codeLen ≤ 8
, o rótulo exibe até o “+” (com padding0
quandocodeLen < 8
). - Para
codeLen ≥ 10
, o rótulo exibe o código completo daquele nível.
- Para
-
Clique no mapa: exibe um Plus Code de 11 dígitos no painel.
-
Centro do mapa: o painel é atualizado após
moveend/zoomend
(11 dígitos).
- Leaflet 1.9.x
- Open Location Code (biblioteca oficial), via 2 CDNs (jsDelivr e unpkg).
Se ambos falharem, entra o fallback spec-compliant embutido (apenas
encode()
).
A função codeLenFromZoom(z)
define o comprimento do código (até 15) por faixas:
Zoom (Z) | codeLen |
---|---|
Z ≥ 30 | 15 |
28 ≤ Z < 30 | 14 |
26 ≤ Z < 28 | 13 |
24 ≤ Z < 26 | 12 |
22 ≤ Z < 24 | 11 |
19 ≤ Z < 22 | 10 |
15 ≤ Z < 19 | 8 |
11 ≤ Z < 15 | 6 |
6 ≤ Z < 11 | 4 |
Z < 6 | 2 |
Isso seleciona o nível de célula; o passo em graus vem de
precisionForCodeLen
.
A função precisionForCodeLen(codeLen)
retorna:
- Para
≤ 10
: latp = lngp ∈ {20, 1, 0.05, 0.0025, 0.000125} (2,4,6,8,10). - Para
≥ 11
: refina latitude ÷5 e longitude ÷4 a cada dígito extra (grid 5×4).
O início dos laços usa alignDown(valor, passo, base)
com base −90 (lat) e −180 (lng).
Isso garante continuidade de linhas/etiquetas nos limites dos tiles.
A camada estende L.GridLayer
e, em cada tile, gera um <svg width="256" height="256">
:
-
Desenha linhas (horizontais/verticais) com
shape-rendering: crispEdges
. -
Para etiquetas:
- Calcula o centro de cada célula no tile.
- Gera o rótulo com
labelForCell(centerLat, centerLng, codeLen)
. - Faz auto‐fit da fonte via heurística de largura ≈
0.6 × fontSize × nChars
. - Aplica contorno (stroke) + preenchimento com opacidade (25%) para ler bem em qualquer fundo.
-
Tenta
OpenLocationCode.encode(lat, lng, len)
. -
Se a lib não estiver disponível, usa o fallback “spec-compliant” embutido:
- 10 dígitos mais significativos:
(lat+90, lng+180) × 8000 → base 20
, intercalando Lat→Lng, do dígito mais significativo ao menos, com+
na posição 8 e0
como padding quandocodeLen < 8
. - Dígitos extras (≥ 11): grid 5×4 com fatores
2.5e7
(lat) e8.192e6
(lng) sobre a fração em graus.
- 10 dígitos mais significativos:
- Opacidade/cores de linhas/rótulos: editar constantes em
drawGrid()
. (Nesta versão, estão fixas: linhas#FF0000
e rótulos#FF6060
a 25%). - Fonte: mude
font-family
do<text>
. - Auto‐fit: ajuste
LABEL.maxFontPx
,minFontPx
,charW
,hPad
,vPad
. - Níveis de zoom: altere os breakpoints em
codeLenFromZoom(z)
conforme sua necessidade. - Precisões: a função
precisionForCodeLen
já segue o spec; só toque se você souber o que está fazendo.
-
Separador
+
: sempre na posição 8. ParacodeLen < 8
, veja se há0
de padding antes do+
. -
Rótulos por nível:
codeLen ≤ 8
: rótulo deve terminar em+
(ex.:7JVW+
para um nível 4/6/8).codeLen ≥ 10
: rótulo completo (pares + grid).
-
Alinhamento entre tiles: ao mover o mapa, as linhas não se desalinham nos limites.
-
Precisões:
- 2 → 20°; 4 → 1°; 6 → 1/20°; 8 → 1/400°; 10 → 1/8000°.
- Extras: lat ÷5, lng ÷4 por dígito (11–15).
-
Interatividade: clique no mapa exibe 11 dígitos; centro do mapa atualiza no painel.
- SVG é leve e nítido (linhas e texto) em qualquer zoom.
- O auto‐fit evita renderizar textos quando a célula é muito pequena (guard rails).
- Em zooms altíssimos (≥ 28), há muitas células por tile; se precisar, adicione throttling no
drawGrid()
ou desative etiquetas acima de certo nível.
- UI de cores/espessura das linhas e opacidade dos rótulos.
- Busca por Plus Code (regex) com
decode()
para voar até a célula. - Implementar no fallback mais métodos do spec:
isValid
,isShort
,isFull
,decode
,shorten
,recoverNearest
. - Exportar a grade visível para SVG/PDF.
- Cluster de etiquetas em níveis intermediários (quando muitas se sobrepõem).
- Navegadores modernos (Chrome, Edge, Firefox, Safari).
- Requer acesso à internet para os tiles OSM e (opcionalmente) para a lib OLC via CDN.
O fallback de
encode()
garante rótulos mesmo offline (com tiles locais).
Tudo está em um único HTML:
<style>
: visual.- Leaflet + tiles OSM.
- OLC (CDN + fallback
encode()
). - L.GridLayer (SVG): gera linhas e rótulos por tile.
- Botão toggle para mostrar/ocultar a grade.
- Leaflet e OpenStreetMap possuem suas próprias licenças/termos.
- Para este arquivo, defina a licença que fizer sentido no seu projeto (ex.: MIT).
Os rótulos somem em certos níveis
→ Isso é intencional pelo auto‐fit: quando a célula é pequena demais, ocultamos o texto para não “sujar” o mapa. Aumente o zoom ou ajuste LABEL.minFontPx
.
Quero as linhas mais finas/grossas
→ Edite stroke-width
das <line>
no drawGrid()
.
Quero cores configuráveis
→ Troque as constantes por inputs
na UI e repinte chamando rebuildGrid()
.
Se quiser, eu também te entrego uma versão com controles de cor/espessura/opacidade na UI e um selector para escolher o codeLen
manualmente (forçando um nível), mantendo o auto‐fit.