4

I'm trying to load a directory of JSON files into QGIS 3.x

They all have the same prefix of 'land'. My code to target all the files starts with:

# 1. import glob library
import glob 

# 2. Targets files with prefix
layers = glob.glob('V:/GIS - Files/3. Data/Agriculture/land*.json')

Each json file contains a line and polygon sub-set of data. I'm trying to load both geometry types separately. Is there a way of doing this?

Geometry types for each JSON file:

2
+50

Using a plugin:

You can load JSON files from a directory structure, applying a prefix filter, using the Load Them All plugin v3.2.0.

Load Them All will recognize sublayers into each JSON file and load them properly.

Look at the docs to see some screencasts and details.


Using PyQGIS:

With the following script you can load your JSON layers and sublayers to QGIS (the script is extracted from Load Them All):

import os
import glob

json_paths = glob.glob('/path/to/jsons/dir/land*.json')
layer_paths = list()  # List of layer paths to load

for json_path in json_paths:
  layer = QgsVectorLayer(json_path, "", "ogr")

  if layer.isValid():
      # Do we have sublayers?
      if len(layer.dataProvider().subLayers()) > 1:
          sublayers = dict()

          for sublayer in layer.dataProvider().subLayers():
              # Sample: 
              # ['0!!::!!my_layer!!::!!12!!::!!LineString!!::!!geometryProperty']
              parts = sublayer.split("!!::!!")  # 1: name, 3: geometry type
              # Sublayers might share layer name, 
              # we need to get geometry types just in case
              if parts[1] in sublayers:
                  sublayers[parts[1]].append(parts[3])
              else:
                  sublayers[parts[1]] = [parts[3]]

          # Let's create layer paths for sublayers
          for sublayer_name,sublayer_geometries in sublayers.items():
              if len(sublayer_geometries) > 1:
                  for sublayer_geometry in sublayer_geometries:
                      layer_paths.append(
                          "{}|layername={}|geometrytype={}".format(json_path, 
                                                               sublayer_name, 
                                                               sublayer_geometry))
              else:
                  layer_paths.append("{}|layername={}".format(json_path, 
                                                              sublayer_name))
      else:
          layer_paths.append(json_path)  # Load JSON as normal OGR layer

# Finally, load all layers!
layers = list()
for layer_path in layer_paths:
    layers.append(QgsVectorLayer(layer_path, os.path.basename(layer_path), "ogr"))

QgsProject.instance().addMapLayers(layers)

As you can see, sublayers will load with very long names. For reference, you can see here how Load Them All gets short names for sublayers.

| improve this answer | |
  • The question is about PyQGIS. – inc42 Apr 3 at 21:27
  • @inc42, check again. – Germán Carrillo Apr 4 at 11:46
  • 1
    Thanks @GermánCarrillo. Very kind of you to tackle this! – James B Apr 5 at 11:27
0

I believe the following should help you in your logic. Essentially you can do some nice if and for combinations here. Essentially you want to grab all the JSON files with the 'land' prefix - you have done this. Now for geometry type separation.

If it were me, I would add logic which grabs all these files, checks their type and imports all the lines and starts over, grabs all these files, checks their type and imports all the polygons. The following code from here should help you:

if layer.wkbType()==QGis.WKBPoint:
    print 'Layer is a point layer'

if layer.wkbType()==QGis.WKBLineString:
    print 'Layer is a line layer'

if layer.wkbType()==QGis.WKBPolygon:
    print 'Layer is a polygon layer'

if layer.wkbType()==QGis.WKBMultiPolygon:

I may not be understanding the import part. If you provide data I could get something more specific but I assume this should help. If not just comment and I can revise as best I can. Hope this helps

| improve this answer | |
-1

Can you just select all and drag and drop them into QGIS map window?

They will reside in the list at the current cursor this is how i import my geojson files

| improve this answer | |
  • Afraid not, the window prompt appears for every layer so I need to click OK n times. – James B Mar 31 at 15:50
  • The question is about PyQGIS. – inc42 Apr 3 at 21:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.