osm-codes / ggeohash Goto Github PK
View Code? Open in Web Editor NEWGeneralized Geohash Algorithms of the OSM.codes
License: Apache License 2.0
Generalized Geohash Algorithms of the OSM.codes
License: Apache License 2.0
Proposta mudou-se para a Wiki, agora é requisito em https://wiki.addressforall.org/doc/osmc:Conven%C3%A7%C3%B5es/Sintaxe_do_OSMcode#Altitude_local_com_rela%C3%A7%C3%A3o_ao_solo
A issue aqui é solicitação para implementar o requisito.
Importante resgatar os itens descartados em outra tabela. Usando
create table optim.consolidated_data_dups AS
SELECT rank() OVER (PARTITION BY afa_id ORDER BY house_number desc,geom) as id_rank, *
from optim.consolidated_data
where afa_id IN (select afa_id from optim.consolidated_data group by afa_id having count(*)>1)
; -- 586
Para remover e inserir, sem risco, usar:
DELETE FROM optim.consolidated_data
WHERE afa_id IN (select distinct afa_id from optim.consolidated_data_dups)
;
INSERT INTO optim.consolidated_data
SELECT id,afa_id,via_type, via_name, house_number, postcode, geom_frontparcel, score, geom
FROM optim.consolidated_data_dups WHERE id_rank=1
;
ALTER TABLE optim.consolidated_data ADD PRIMARY KEY ( afa_id );
Comparar com indexão da geom, ver https://github.com/osm-codes/GGeohash/blob/main/src/step80benchmark-p1.sql
Toda geração de cobertura depende de ST_GeneratePoints()... Mas ela não está mais em uso em nenhum lugar.
No antigo step01def-lib.sql
de CO_new havia a função libgrid_co.gridGeoms_fromGeom(), que gerava coberturas.. Onde foi parar?
A função devolve uma grade b32 no entorno do ponto, garantindo a não-repetição de IDs nessa grade, quando designada apenas pelo primeiro dígito.
A função seria utilizada em tabelas de conversão de nomes, por exemplo o nome de bairro Sousas em BR-SP-Campinas-Sousas~123
precisa ser canonizado para BR-SP-Campinas~$x123
. A tabela de ponto-cobertura, pela unicidade, garante que o dígito 1
será associado a "Q1" e não a "J1".
Na tabela pública de definição de nomes, BR-SP-Campinas-Sousas
está associado ao ponto geo:-22.881100,-46.969733
(= BR+dfb74174da7
= BR-SP-Campinas~Q1GMF7
), relativo ao centro do bairro/distrito. Internamente, todavia, a resolução do nome pode fazer uso de cache, uma array representando o de-para dos 32 possíveis dígitos com respectivos sufixos. É uma mera operação de conversão de strings, não de células de grade.
Fica a dúvida quanto à escala de definição, por exemplo com a regra "mais 2 dígitos" expressaríamos Q1G
como centro, e fica subintendido que é "na escala Q
"... Se o centro for expresso por Q1G1
vai para a "escala Q1
".
De forma análoga a #25 a função gera uma cobertura em torno de um ponto, mas com outro objetivo. Aqui buscamos associar o nome (ex. bairro Sousas) a um prefixo adequado, encaixando o sufixo.
É preciso padronizar o grau de encurtamento... Por outro lado OSMcodes é mais flexível quanto aos tamanhos, devido aos overlays. Em meio rual seria o análogo a criar overlays a partir de nomes. No meio urbano, todavia, é um segundo nível de encurtamento.
Por exemplo em Campinas queremos definir um subnome, BR-SP-Campinas-Taquaral
, para designar região do entorno do parque.
Por exemplo, seria razoável traduzir BR-SP-Campinas-Taquaral~$x
para BR-SP-Campinas~N3$x
. Mas tanto as fronteiras do parque como do bairro vão para além de N3
(ilustração), então nesse caso não temos o que fazer, será simplemente N
... Ainda assim o morador pode julgar razoável denominar o endereço "Taquaral 3RS0" ao invés de "N3RS0".
Fica para a comunidade se prefere usar N
ou N3
como representante/coberura do bairro Taquaral.
O bairro Sousas não seria diferente, todavia Sousas está metade em "Q" e metade em "J", já não caberia esta estratégia.
Tal como no PlusCodes shortening, a forma mais eficiente e "barata" de se implementar uma tabela de nomes, é fornecendo um ponto de referência para determinar o seu entorno.
Issues vinculadas ao tema, podem ser fechadas em detrimento desta issue:
As "coberturas integrais" são aquelas que garantem a indexação do município, mesmo que com baixa redução no geocódigo. Formam um mosaico que cobre integralmente o município.
As "coberturas de sobreposição" (overlays) sobrepõe-se às integrais, para apenas garantir maior redução do geocódigo nas manchas urbanas estáveis de maior densidade populacional. A densidade de endereços ou densidade de vias são alternativas para a inferência relativa à densidade populacional. Tendências de crescimento populacional futuro também ajudar a definir essas áreas.
Ver exemplo na grade BR, osm-codes/BR_new#4
Geocodigos de referência para encurtamento são similares aos pontos de referência definidos em "Guidance for shortening" do OLC. A estratégia é quase a mesma, exceto pelo número variável de dígitos na referência. A implantação requer duas etapas: pre-processamento do CSV com as definições (geocódigo postal e flag indicando se é célula sozinha ou ela mais suas 8 vizinhas), e resolução do nome, análoga a overlay.
Exemplo de encurtamento: a loceliação BR-SP-CAM~3S36WW de 5 metros, poderia ser reduzida a BR-SP-Campinas-Taquaral~6WW
, sendo o Taquaral centralizado em .3S3
e suas 8 células vizinhas.
Exemplo de overlay em Campinas:
As áreas de maior densidade de obras (vias ou edificações) ou de habitantes determinam onde posicionar as células de overlay, que não precisam ser contiguas.
Havia no centro um grande "vazio", com grande potencial de otiminação...
Uma alternativa seria tudo numa grade integral, contendo 28 células de 6 km de lado + 4 células de 32 km de lado. Totalizando exatamente 32 duas células, porém deixando sem reserva.
Resumo das vantagens do overlay:
Todo Geohash é um BBOX WGS84. Experimente conferir a equivaência entre a geometria da célula e a da sua BBOX:
SELECT ST_Envelope( Box2D(ST_GeomFromGeoHash('6gy)) ) = ST_GeomFromGeoHash('6gy')
.
O mesmo vale em SRID diferente de 4326, há um BBOX e sua indexação no SRID apropriado.
A comparação de geometrias por BBOX é muito mais rápida, portanto vale a decomposição do país em grandes geohashes, interiores e de borda, então classifica-los com o flag is_border
para decidir se confere a interseção.
Exemplo de obtenção e comparação de BBOX, SELECT pt && box AND CASE WHEN is_border THEN ST_intersects(pt,box_geom) ELSE true END FROM (SELECT ST_GeomFromGeoHash('bgy2200'), ST_GeomFromGeoHash('bgy'), false ) t(pt,box_geom,is_border), LATERAL BOX2D(box_geom) as box
A cobertura do país (ilustrada abaixo) pode ser otimizada para que mais de 50% da sua área seja coberta por BBOXes interiores, otimizando a busca.
a padronização por Geohash nas coberturas por país não seria necessária (ver opção por QuadTree rigoroso), mas foi eleita por já termos um algoritmo pronto de obtenção das coberturas-Geohash no PostGIS, e o mesmo não ser impactado por acréscimo de novos países.
As células em rosa podem ter ser reduzidas a BBOX ou ter sua geometria simplificada, por serem fronteira apenas com o oceano, onde o ponto do ser considerado do país.
Se o ponto já está garantidamente dentro do país (ex. ponto de endereço), pode-se pular essa etapa. PS: e se o ponto não está garantidamente contido, converter para SRID 4326.
Sejam pt
o ponto, geom
a geometria com flag is_border
indicando se contem complexidade de borda. As geometrias estão na tabela p
das geometrias de jurisdição particioadas, e estão indexadas, portanto dispensam operação box2D.
SELECT country_id, ST_Transform(pt,country_srid) as ptt FROM p WHERE pt && geom AND CASE WHEN is_border THEN ST_Intersects(pt,geom) ELSE true END
. Não deveria retornar mais que uma linha.
Conforme solicitação é de encode postal ou encode científico.
2.1. SE científico, está pronto: SELECT geocodigo_cientifico_do_pais(ptt,country_id)
.
2.2. SE postal, buscar o município pelo ptt
e seu ptt_cell
já obtido por encode de ptt
. Como está na projeção correta, a grade é BBOX.
SELECT jurisdiction_id, geocodigo_postal(ptt_cell,isolabel_ext,geom_prefix) as code FROM municipios WHERE geocode_match(ptt_cell,geom_prefix) AND CASE WHEN is_border THEN ST_Intersects(ptt,geom) ELSE true END ORDER BY prioridade
.
Todos com SRID do país. A ordenação garante a verificação das geometrias de overlay (células menores) primeiro. Como não são esperados overlays dentro de overlays, pode-se usar o booleano is_overlay
como ordenador.
Problemas a decidir por avaliação de performance:
overlay_list
(pares prefixo-codigo) como parâmetro adicional na função geocodigo_postal() geocode_match(ptt_cell,geom_prefix)
seja tão rápido se não for C++. Provavelmente a comparação direta ptt && geom
é mais rápida (!).ST_Intersects(pt,geom)
tem seu complementar que é o país vizinho. A rigor não faz sentido repetir a comparação com a "geometria complementar" (exceto se for um fronteira tríplice)... Enfim, existe oportunidade para otimizar se não complicar.A principio não queremos encode enriquecido, ideal é sempre devolver o geocódigo postal padrão, contendo o nome a abreviação ou nome do município.
... Mas, se depois do encode quiser enriquecer/encurtar o geocódigo com, por exemplo, nome de bairro, há que se submeter à tabela de conversão secundária, baseada nos pontos de referência — vide caso Uruguai onde muitas das geometrias de mancha urbana nomeada serão expandidas em células-container ou célula central e suas vizinhanças.
Outra opção, que talvez degrade a performance quando houverem muitos países e muitso bairros, é incluir tudo como overlay na tabela de municipios, retornando isolabel_ext especial (por exemplo BR-SP-CAM-Taquaral
). Por hora, todavia, é o mais prático (!).
Se for científico é direto. Já geocódigo postal , requer desmenbrar nome e conferir sinônimos. Vejamos o decode postal:
decompor em prefixo_nominal_raiz
, prefixo_extra
e sufixo_grade
.
1.1. Com prefixo_nominal_raiz
ou seu sinônimo obtém-se o município e seu prefixo_grade
. SE além disso tinha prefixo_extra
não nulo (ex. nome de bairro), concatena ao prefixo_grade
o prefixo_extra_grade
.
1.2.
1.3. fazer decode usual do prefixo_grade concatenado ao sufixo_grade, o resultado será geometria da célula no SRID do país.
Aparentemente o SPGIST conforme guia é um índice estilo quadTree enquanto os outros são mais tradicionais. Neste artigo diático também são analisadas as opções.
A representação em base16h é a base16, hexadecimal convencional, grafada por tradição em letras minúsculas. Somente a letra de sufixo especial (superior a "f") é maiúscula.
Ver exemplo em https://ppkrauss.github.io/Sfc4q/ e especificação formal em http://osm.codes/_foundations/art1.pdf
O processo de encode de geouri usa o cache geom_4326
para obter a respectiva célula da cobertura nacional:
ST_Contains(geom_srid4326,ST_SetSRID(ST_MakePoint(latLon[2],latLon[1]),4326))
CREATE TABLE osmc.coverage (
id bigint NOT NULL,
isolabel_ext text, -- used only in de-para, replace with 14bit in id
prefix text, -- used only in de-para, cache
bbox float[], -- used in l0cover and de-para
geom geometry, -- used in l0cover and de-para
geom_srid4326 geometry -- used only in l0cover
);
Em #2 relata-se problemas ao usar ST_Transform.
A figura a seguir evidencia problema no processo de encode no limite entre células da cobertura brasileira, resultando no marcador fora da célula e célula de cobertura cortando uma célula.
Avaliar o impacto de aplicar ST_Transform_resilient
no cache geom_4326
ao gerar a cobertura nacional em, por exemplo, https://github.com/osm-codes/GGeohash/blob/main/src/step04def-ini.sql#L35.
Apesar da cobertura de nível ter uma ordem indiferente, sem compromisso com a curva de preenchimento (Morton ou Hilbert), os algoritmos de cálculo de vinhança podem se tornar mais simples e com menos exceções se for mantida aproximadamente a ordem da curva de preenchimento.
Exemplo do Brasil: abaixo seguindo a ordem dentro do possível.
ao invés da ordem totalmente arbitrária, apesar de "didática" para o leigo entender a ordem do alfabeto utilizado
Lembrete: essa é a orientação (zero em baixo) e ordem recorrente na base16, não temos dúvidas quando ao algoritmo de vizinhança... Na ilustração abaixo as vizinhanças de A0 com prefixo A são válidas, as demais estão comprometidas porque o prefixo arbitrário não permite o algoritmo avaliar recorrentemente. Por exemplo A0F tem A2, A3 e A1 como vizinhos válidos, mas a esquerda e abaixo de A00, 95 e DA estão comprometidos pela escolha arbitrária de ordem na corbertura.
OSMcode postal é um ponto geográfico que coincide com a "testada de lote" do endereço postal. Endereços postais também possuem complenento, e, pode acontecer desse complemento não ser simplesmente a "casa do fundo" ou "andar Tal apartamento tal", mas a localização dentro do condomínio, tal como "rua tal numero tal".
A rigor temos um "endereço dual", com a parte oficial pública correspondendo à localização da portaria, e a "parte privada", indicando uma localização que pode ser bem distante da portaria. Como ainda é uma localização de GPS, é de certa forma compromisso do OSMcodes expressar também esse tipo de endereço.
O caso típico é o "endereço de casa em condomínio horizontal". Todos reclamam que pro Uber não basta saber a portaria do condominio, precisa depois entrar e chegar na casa, do lado de dentro do condomínio. O mesmo vale para o meio rural, tem a porteira da estradinha e depois um longo percurso na trilha até a casa.
Os dois casos principais e exemplos.
O Parque Shopping Sulacap tem uma entrada ampla, caracterizada como seu endereço postal. Mas o ponto de embarque-desembarque, próximo ao toldo do fundo, fica bem longe dali.
Por exemplo o Uber precisa chegar em BR-RJ-RioJaneiro~G04Y9, com erro de 6 metros. Antes, todavia, precisa chegar no endereço real, que é um amplo acesso (encaixa em ~32m) em BR-RJ-RioJaneiro~G0JT. Resumindo: temos um ponto de interesse e o endereço oficial porém apenas do acesso, não chega ainda no local desejado.
Solução: o endereço-duplo para o Uber é BR-RJ-RioJaneiro~G0JT...4Y9
.
PS: a entrada do grande lote condominial fica no endereço de grade mais curto, representa uma grande portaria, G0JT
. A porta da casa mesmo usa um endereço de grade mais longo, G04Y9
, que no final ficou curto, com 3 dígitos.
No exemplo abaixo, apesar de todas as localizações serem próximas, a menos de 500 metros uma da outra, a grade sobre elas apresenta uma "encruzilhada de células-mãe".
Então neste caso, se a porteira se encontra digamos em BR-RJ-Rio~G009 e o endereço final em BR-RJ-Rio~5CPBSX, a forma mais simples de representar é a dual BR-RJ-Rio~G009~5CPBSX
.
Sugere-se a convenção de "dois pontos de localização", usando o "~" duas vezes. Ex. "BR-SP-SPA~2XY3XY~2XY9BLC".
Quando calha de serem na mesma macrocelula, pode usar o ".." seguido de tantos pontos quantos precisar voltar, ex. para reusar "2XY9" pode-se usar "BR-SP-SPA~2XY3XY...BLC", que fica mais facil de memorizar. No caso anterior o reuso seria menor, seriam 4 pontinhos, "BR-SP-SPA~2XY3XY....9BLC".
Sintaxe sem redução: adiciona-se um segundo ~
.
{cidade}~{gridCode_EnderecoOficial}~{gridCode_enderecoInterior}
Sintaxe com redução: adiciona-se ..
para "comer um dígito" ou ...
para comer 2, ou ....
para comer 3. {cidade}~{gridCode_EnderecoOficial}..{oc_ei_sufixo1}
ou {cidade}~{gridCode_EnderecoOficial}...{oc_ei_sufixo2}
ou {cidade}~{gridCode_EnderecoOficial}....{oc_ei_sufixo3}
.
O sufixo1 omite o gridCode_enderecoInterior
exceto o último dígito. O sufixo2 exceto os 2 últimos dígitos. O sufixo3 exceto os 3 últimos dígitos.
O ..
é o símbolo Unix de "voltar um nível hierarquico".
Em ambos os casos funciona mesmo com pontos em diferentes cidades: a cidade que manda é a oficial, de gridCode_EnderecoOficial
.
Por exemplo CREATE TABLE osmc.coverage
seria parte preliminar, e talvez demande tratamento em separado.
Algumas funcções de encode/decode bigint
precisam ser escritas diretamente em C, vide exemplo simples, não precisam de maior expertize. Ver detalhes em C-Language Functions.
Os commits https://github.com/osm-codes/NaturalCodes/commit/2b1493ba3e637ee68aea2f9029a96b9b617f33c1 e https://github.com/osm-codes/NaturalCodes/commit/22dffaa0842e19e975f9a8c030dcf68c01a799f8 fornecem maneira de usar bigint para indexar células, realizar busca por intervalo ao mesmo tempo que armazenam a quantidade de bits usados.
Considerações preliminares:
Impactos da mudança:
Movendo. Juntar (merge) esta issue na #9
Coberturas em overlap: nova implementação, segundo conjunto de geocódigos que formam a cobertura de overlap, se sobreponto à "cobertura natural". Ver exemplo na grade BR, osm-codes/BR_new#4
Geocodigos de referência são sempre compativeis com o mosaico de jurisdições, e em certo sentido o tratamento é analogo ao overlap. Vide "Guidance for shortening" do OLC, a estratégia é quase a mesma.
A api.jurisdiction_coverage vem consumindo muitos bytes e tempo na interface.
o script https://github.com/osm-codes/GGeohash/blob/main/src/step04def-ini.sql
está com dezenas de blocos comentados por /* .. */
, alguns até com falha de sintaxe.
Estes blocos só são necessários no git-branch e muito raramente nas transições de grandes mudanças.
Temos agora a Wiki oficial de documentação para documentar.
Alternativamente podemos usar a https://github.com/osm-codes/GGeohash/wiki para copiar/colar isso tudo temporariamente.
Deveria ser simples e rápido o algoritmo, mas é preciso otimizar para que rode mais rápido no PostgreSQL
Ver questão de performance em https://gis.stackexchange.com/a/441995/7505
Implementações em https://github.com/AddressForAll/pg_pubLib-v1/blob/main/src/pubLib05pgis-geohash.sql#L254
pg_pubLib-v1 foi apagada!
Ver pendências de refatoração e documentação em digital-guard/preserv#125
Exemplo de https://osm.codes/BR-SP-RioClaro
O poligono pode ser coberto por 30 células,
Vantagens: 1. menor área de interseção com outros municípios (otimiza análise de fronteiras?). 2. sem custo adicional da resolução de overlay (? avaliar se representa custo já que seria por prefixo apenas).
Desvantagens: 1. pouca reserva, e 2. eventual desperdício em área rural.
... Mas atualmente (2023-02-15) se encontra coberto por 4 células maiores:
Vantagens do atual: 1. mais reserva; 2. mímina cobertura-base (maior performance no scan geométrico?); 3. overlay cumprindo com o papel esperado (custo ou maior performance por prefixo?).
Desvantagens do atual: maior área de interseção com outros municípios (representa custo na análise de fronteiras?).
Podemos reduzir em fronteiras mínimas:
Vantagem: redução das áreas de interseção.
Desvantagem: descontinuidade (sai do padrão esperado pelo usuário) no número de dígitos da área rural.
Implementar identificadores de vias, lotes e endereços segundo as convenções.
Atualizar as funções em https://github.com/osm-codes/GGeohash/blob/main/src/step04def-ini.sql com as novas colunas da tabela osmc.coverage: status
e is_overlay
.
Need for universal coverage functions on sample list:
Readme remendo a Wiki ou descrevendo o essencial.
Rodar gerador automatico de documentação das funções, e relacionar os diversos arquivos:
Citar:
PS: remover partes já migradas para mediawiki, https://github.com/osm-codes/GGeohash/wiki
Otimizando a "cobertura exata do buffer de ponto" (também denominado offset), com máxima área de interseção, e seu algoritmo com menor custo de CPU... Ver se compensa usar algoritmo de https://www.mdpi.com/2220-9964/9/5/335
Abaixo, sobre imagem de satélite, o resultado de uma cobertura assimétrica de "30 metros de buffer do ponto"
O algoritmo da referência também fornece as células de fronteira do buffer, ou seja, permite aplicar variações do algoritmo, definindo interior, fronteira e exterior, bem como otimização do interior através da resolução agregada
... A dúvida é se a implantação C++ seria de fato muito mais rápida do que usar ST_Buffer(ponto)
, e se o algoritmo continua válido para identificadores baseados em curva de Morton.
Em step02def-libGGeohash.sql otimização de
ggeohash.draw_cell_bycenter, e demais *draw_ usando
ST_MakeEnvelope(float xmin, float ymin, float xmax, float ymax, integer srid=unknown)`.
construir uma versão mais simples e otimizada de ST_Transform_resilient(), especializada em células quadrilateras. Como a informação de SQRT(area) já é dada, não precisa calular. Outro recurso seria criar com mais pontos já em ggeohash.draw_cell_bycenter()
. Ver #2
Pode focar em segmentar só em X ou só em Y devido ao "efeito varal", incluindo um ponto no meio sucessivamente.
Decode colombiano não funciona.
Por exemplo, o decode de https://osm.codes/CO-8758~853M5Z não funciona.
Por outro lado, https://osm.codes/CO-15001~J7M0 funciona.
Por exemplo a Irish grid (SRID 29902) usa UTM e já oferece uma grade de cobertura adequada à base32.
Outros:
Ver osm-codes/gridMap-draftPages#27 e fontes por país, estamos unificando por exemplo BR_new para BR.
Ver diretivas do merge em osm-codes/BR#1
Ver exemplo BR com https://github.com/digital-guard/stableGeo-BR
Ver norma OGC http://www.opengis.net/doc/AS/2D-tiles/1.0#_conformance_class_abstract_test_suite_normative
O primeiro passo talvez seja revisar as documentações de NaturalCodes e Sfc4q, para que já na abstração de origem estejam em conformidade.
Na OSMcodes o padrão DGGS, que hoje além de OGC é também um padrão ISO, foi adaptado com a mudança de apenas um "axioma", a troca de "Global" por "Local", portanto conforme nossa Wiki, DLGS.
... Então, em seguida ao 2D-Tile, o mais trabalhoso será adaptar as nossas funções GGeohash e cia ao padrão exigido pela seção 8.3 do DGGS: https://docs.ogc.org/as/20-040r3/20-040r3.html#toc27
ISSUE LIXO, mudou-se para https://github.com/osm-codes/GGeohash/wiki/Algoritmos-de-cobertura
Ver GGeohash/wiki/Estudos-sobre-o-bug-do-deslocamento
e ver issues já postadas sobre o assunto na Colômbia
A função natcod.vBit_to_hInt() retorna inteiro de 32 bits. Os isolabels do mundo podem ser ordenados conforme iso numérico e em seguida conforme isolabel.
O hInt32 resultante será útil para buscas por país ou por segundo nível. As coberturas de jurisdição também podem ser definidas em tabela usando esse novo ID, tornando o cálculo de geocódigo logístico mais rápido.
No futuro, polígonos como o CEP5 do Brasil também podem ser subdivisões depois do município. Idem polígonos de distritos-IBGE, como uma taxonomia distinta. As tabelas de abreviação e sinônimos também ganham agilidade com o hint32.
Exemplos e estimativas:
Trazer de https://github.com/osm-codes/CO_new/blob/main/src/step01def-lib.sql
e adaptar os locais.
Grades estatísticas oficiais relativas a valores por exemplo de população, requerem conversão para a "nova grade" (ver por exemplo Brasil e Colômbia).
Implementar o "método 1" de https://github.com/osm-codes/GGeohash/wiki/Convers%C3%A3o-de-grades-de-mesma-proje%C3%A7%C3%A3o
A performance do PostGIS é dada por BBOX, então o uso de bbox na estrutura pode não ser a melhor estratégia
Column | Type | Collation | Nullable | Default
---------------+--------------------+-----------+----------+---------
id | bigint | | not null |
isolabel_ext | text | | |
prefix | text | | |
bbox | double precision[] | | |
geom | geometry | | |
geom_srid4326 | geometry | | |
Indexes:
"osm_coverage_geom4326_idx1" gist (geom_srid4326)
"osm_coverage_geom_idx1" gist (geom)
O operador &&
por exemplo já acessa a representação BBOX interna de cada polígono.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.