GeoJSON muito volumoso - o que fazer?


19

Estou usando o leaflet.js para permitir que os usuários da web selecionem uma região. Regiões válidas são estados dos EUA, providências canadenses e países do mundo (exceto EUA e Canadá). Eu mesmo construí um shapefile usando o Qgis e o salvei como geojson. Simplifiquei as geometrias o máximo que pude.

O shapefile resultante é de 400kb, mas o geojson tem mais de um megabyte. Isso é maior do que eu gostaria. Preciso reduzir a sobrecarga da rede envolvida na transferência dessas informações.

Qual é a maneira certa de fazer isso? As opções que posso imaginar são:

  1. Sirva o arquivo geojson compactado com gzip, descompacte no cliente.
  2. Analise o shapefile no cliente para geojson
  3. Gere minhas próprias peças do shapefile e sirva as

Se alguém pudesse me dizer qual é a melhor opção (ou nenhuma das opções acima), eu apreciaria!


Observo que você disse que tentou simplificar a geometria, mas tentou usar um algoritmo de simplificação GIS e verificar os resultados? Também pode ajudar a olhar para qual parte do JSON está ocupando mais espaço.
BradHards

1
Certifique-se de que o GeoJSON não seja bem impresso, a remoção de todo o espaço em branco desnecessário ajudará a diminuir o arquivo - não necessariamente por uma quantidade enorme, mas tudo ajuda!
CHenderson

Respostas:


13

Antes de seguir caminhos mais trabalhosos, a opção mais simples é reduzir a geometria. Quais são os seus conjuntos de dados de origem? Como você os simplificou? Quanto isso reduziu o tamanho do arquivo geojson?

Se você está confiante de que fez tudo o que foi possível acima, o menor resultado pendente de suas opções é

  1. Sirva o arquivo geojson compactado com gzip, descompacte no cliente.

Todos os navegadores modernos fazem a descompactação dos dados compactados automaticamente, por isso é apenas um caso de configuração do servidor da Web para compactar os dados antes de enviá-los. Normalmente, isso é relativamente simples, com muito material disponível para Apache , IIS ou Nginx

Minha dica seria tentar primeiro, testar e, se o tamanho da latência / resposta / dados não for aceitável, vá para outras opções. Também gostaria de tentar otimizar prematuramente, procuraria determinar por que você precisa reduzir o tamanho dos dados e, depois de ter razões (e números) difíceis para fazê-lo, implementar iterativamente as alterações e testar novamente para ver o que ganhos que você está recebendo.


13

O Mapshaper.org é uma ferramenta on-line gratuita e útil que permite fazer upload de um arquivo geojson, exibi-lo como um mapa e escolher um dos três alogrítimos de simplificação nos quais você pode ajustar a força com um controle deslizante.

Ele atualiza o mapa e destaca em vermelho todos os lugares onde há perda de integridade, como uma sobreposição entre duas regiões. Há um botão 'consertar' que normalmente (mas nem sempre) corrige esses problemas.

Você pode encontrar um nível de simplificação aceitável e exportar o arquivo geojson recém-simplificado.

Obviamente, isso depende do nível de detalhe necessário, mas os resultados podem ser impressionantes. Por exemplo, aqui está o mapa da Escócia a partir de um arquivo geojson de 40mb:

insira a descrição da imagem aqui

Um aplicativo de 99% reduz para um arquivo de 441 kb, sem sobreposições e perda de detalhes invisíveis nesse nível de zoom:

insira a descrição da imagem aqui

Um aplicativo de 99,95% (até 29kb) mostra que tipo de simplificação de caminho está sendo aplicada (e ainda consegue evitar sobreposições e é perfeitamente adequado para usos como cloropletos em nível nacional):

insira a descrição da imagem aqui


Eu uso essa ferramenta o tempo todo. É excelente!
Mike Furlender #

1
Você é um salva-vidas!!
Khizar 29/04

6

Gostaria de saber se você poderia fazer uso da compactação encontrada nesta resposta que fala sobre compactar o GeoJSON com topojson .

Não sei se o Leaflet ainda será capaz de ler o GeoJSON - algo a tentar =)

Mais sobre o topojson: https://github.com/mbostock/topojson/


Leaflet.GeoJSON faz não dados arco de análise, pelo que esta abordagem não vai funcionar
smcphill

O folheto não pode ser nativo, mas você pode usar o topojson no lado do cliente para fazê-lo, exemplo do topojson no folheto , embora esse exemplo use o d3 para renderizá-lo.
Calvin

1
Eu tinha um arquivo geoJson de 27mb. Foi para mapshaper.org e, após simplificar (1,0%) e exportar o topojson, tornou-se 122kb. Depois disso, adicionei o código do topoJson Leaflet de github.com/shramov/leaflet-plugins/blob/master/layer/vector/… ao meu aplicativo e fiz o seguinte: novo L.TOPOJSON ("myExported.topojson"). ToGeoJson ().
StackUnder

3

Concordo com o @ Kelso acima em simplificar sua geometria.

Se você não tem acesso ao seu servidor para desinflar os dados com o gzip facilmente, pode dar uma olhada na biblioteca MessagePack para serializar seu geoJSON em dados binários (acredito que seja uma implementação da especificação BSON usada por coisas como MongoDB para armazenar dados, mas posso estar errado) . Existem bibliotecas em Python e javascript (entre outras) que você pode usar para serializar / desserializar os dados.


2
O MessagePack não está relacionado ao BSON (na verdade é melhor em muitos casos, de acordo com stackoverflow.com/questions/6355497/… . Informações mais interessantes sobre o messagepack e especificamente o geojson podem ser encontradas em nelsonslog.wordpress.com/2012/06/22/checking -fora-msgpack .
Kelso

Obrigado por @Kelso - atualizou a resposta. E bom artigo também!
Om_henners

1

Eu sugeriria apenas criar sua própria matriz processual de objetos do Leaflet Polygon. Eu concordo que o GeoJSON seja muito grande. Os nomes das chaves do objeto são muito descritivos, mas talvez desnecessariamente longos também. Eu faço esse tipo de coisa:

objects = [];
objects.push( new L.polygon([[1,1],[1,2],[3,4]],options );
objects.push( new L.polygon([[4,7],[8,27],[35,66]],options );
objects.push( new L.polygon([[3,5],[56,24],[13,49]],options );
objects.push( new L.polygon([[13,7],[7,68],[23,9]],options );
layerGroup = L.layerGroup(objects).addTo(map);

É simples. É muito mais leve que o GeoJSON assim:

{ "type": "FeatureCollection",
  "features": [
    { "type": "Feature",
      "geometry": {"type": "Polygon",
      "coordinates": [1,1],[1,2],[3,4]},
      },

    //etc...

E repita para cada polígono ... ugh ... muito inchado. Adiciona muitos bytes ao seu JS. Como eu disse, os nomes das chaves são bons e descritivos ... mas são longos e adicionam muitos tchaus desnecessários ao seu JS.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.