Alternativas a ogr2ogr para cargar archivos GeoJson grandes a PostGIS

24

Tengo un archivo GeoJson de 7GB que me gustaría cargar en una base de datos PostGIS. He intentado usar ogr2ogr pero falla porque el archivo es demasiado grande para que ogr2ogr se cargue en la memoria y luego se procese.

¿Existen otras alternativas para cargar este archivo geojson en PostGIS?

El error ogr2ogr que recibo es:

  

ERROR 2: CPLMalloc (): sin memoria asignando -611145182 bytes. Esta   La aplicación ha solicitado al Runtime que termine en un modo inusual.   camino. Por favor, póngase en contacto con el equipo de soporte de la aplicación para más   información.

    
pregunta RyanDalton 30.10.2011 - 21:16

5 respuestas

10

La muestra que envió muestra que es posible dividir el archivo manualmente usando un editor como notepad ++

1) Para cada fragmento, crea un encabezado:

{"type":"FeatureCollection","features":[

2) Después del encabezado, coloque muchas características:

{"geometry": {"type": "Point", "coordinates": [-103.422819, 20.686477]}, "type": "Feature", "id": "[email protected]", "properties": {"website": "http://www.buongiorno.com", "city": "M\u00e9xico D.F. ", "name": "Buongiorno", "tags": ["mobile", "vas", "community", "social-networking", "connected-devices", "android", "tablets", "smartphones"], "country": "MX", "classifiers": [{"category": "Professional", "type": "Services", "subcategory": "Computer Services"}], "href": "http://api.simplegeo.com/1.0/features/[email protected]", "address": "Le\u00f3n Tolstoi #18 PH Col. Anzures", "owner": "simplegeo", "postcode": "11590"}},

3) Termina el fragmento con:

]}

EDITAR: aquí está el código de Python que dividirá el archivo en partes del tamaño definido (en número de funciones):

import sys

class JsonFile(object):
    def __init__(self,file):
        self.file = open(file, 'r') 
    def split(self,csize):
        header=self.file.readline()
        number=0
        while True:
            output=open("chunk %s.geojson" %(number),'w')
            output.write(header)
            number+=1
            feature=self.file.readline()
            if feature==']}':
                break
            else:
                for i in range(csize):
                    output.write(feature)
                    feature=self.file.readline()
                    if feature==']}':
                        output.write("]}")
                        output.close()
                        sys.exit("Done!")
                output.write("]}")
                output.close()

if __name__=="__main__":
    myfile = JsonFile('places_mx.geojson')
    myfile.split(2000) #size of the chunks.
    
respondido por el Pablo 31.10.2011 - 12:26
19

Desafortunadamente, JSON es, al igual que XML, mal adaptado para el procesamiento de secuencias, por lo que casi todas las implementaciones requieren que todo el conjunto de datos se cargue en la memoria. Si bien esto está bien para conjuntos pequeños en su caso, no hay otra opción que dividir el conjunto de datos en partes más pequeñas y manejables.

Para mejorar la solución de Pablo, aquí hay una que no requiere que realmente abra y cargue el archivo en un editor y lo divida a mano, pero trata de automatizar todo lo posible todo el proceso.

Copie el archivo json en un host Unix (linux, osx) o instale las herramientas cygwin en Windows. Luego, abra un shell y use vim para eliminar la primera y la última fila del archivo:

$ vim places.json

escriba dd para eliminar la primera línea, luego SHIFT-G para mover el final del archivo, escriba dd nuevamente para eliminar el último línea. Ahora escriba : wq para guardar los cambios. Esto debería tomar solo un par de minutos como máximo.

Ahora vamos a aprovechar el poder de Unix para dividir el archivo en partes más manejables. En el tipo de shell:

$ split -l 10000 places.json places-chunks-

Ve a tomar una cerveza. Esto dividirá el archivo en muchos archivos más pequeños, cada uno con 10000 líneas. Puede aumentar el número de líneas, siempre y cuando lo mantenga lo suficientemente pequeño para que ogr2gr pueda administrarlo.

Ahora vamos a pegar cabeza y cola a cada uno de los archivos:

$ echo '{"type":"FeatureCollection","features":[' > head
$ echo ']}' > tail
$ for f in places-chunks-* ; do cat head $f tail > $f.json && rm -f $f ; done

Ve a tomar un snak. Los primeros dos comandos simplemente crean un archivo de encabezado y pie de página con el contenido correcto (solo por conveniencia), mientras que el último agregará encabezado y pie de página a cada uno de los fragmentos que dividimos arriba y eliminará el fragmento sin encabezado / pie de página (para ahorrar espacio ).

En este punto, esperamos que pueda procesar los muchos archivos places-chunks - *. json con ogr2ogr:

$ for f in places-chunks-*.json ; do ogr2ogr -your-options-here $f ; done
    
respondido por el unicoletti 31.10.2011 - 14:07
3

Es posible cargar sus datos con FME Desktop. Es muy fácil.

    
respondido por el user3120 30.10.2011 - 23:10
2

Debe ser sencillo escribir un lector y escritor perezoso en Python que convierta su archivo geojson al formato de archivo de forma mucho más pequeño o directamente a SQL sin hacerlo todo en la memoria. Una vez convertidas, las herramientas nativas de PostGIS pueden importar grandes conjuntos de datos. El soporte geojson en OGR es relativamente nuevo y no hay indicadores para manejar archivos grandes.

Si de alguna manera puedes compartir una parte manejable de tu archivo, puedo ayudarte.

    
respondido por el GeospatialPython.com 31.10.2011 - 02:22
2

Esto ha mejorado en GDAL 2.3.0 enlace ahora es mucho más eficiente en memoria al leer archivos grandes de GeoJSON.

    
respondido por el AndrewHarvey 14.09.2018 - 13:36

Lea otras preguntas en las etiquetas