1

I am trying to use some geojson features to mask a raster using rasterio.

I can get this working using the example code in the masking documentation for rasterio.

I generate some geojson using a subprocess and create a variable with the geojson in it, I then want to loop through the geojson masking the input raster for each feature within the geojson.

I read that rasterio takes a list of geometries as an input but when I turn my geojson into a list object I get the same error AttributeError: 'unicode' object has no attribute 'get'.

Do I need to loop through the geojson and make a list of with an entry for each feature which I can use as the mask?

import json
import os
import subprocess
import rasterio
from rasterio.tools.mask import mask


# args
os.chdir(r'/workingdir/')
in_rst = "test.tif"
aoi_file = 'test_area84.geojson'
zoom_level = 14
bash = 'cat {0} | supermercado burn {1} | mercantile shapes | fio collect'.format(
    aoi_file, zoom_level)

supermercado_output_tiles = ''


def run_command(command):
    p = subprocess.Popen(command,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b'')

for line in run_command(bash):
    supermercado_output_tiles += line

json_tiles = json.loads(supermercado_output_tiles.decode('utf-8'))

json_tiles = list[json_tiles]    


for feature in json_tiles:

    with rasterio.open(in_rst) as src:
        out_image, out_transform = mask(src, feature, crop=True)
        out_meta = src.meta.copy()

    # save the resulting raster
    out_meta.update({"driver": "GTiff",
                     "height": out_image.shape[1],
                     "width": out_image.shape[2],
                     "transform": out_transform})

    with rasterio.open("tmp_images.tif", "w", **out_meta) as dest:
        dest.write(out_image)

** Edit **

I changed the code so now I just pass in a list of polygons

#!/usr/bin/env 

# standard lib imports 
import json, ast
import os
import subprocess
from subprocess import Popen, PIPE

# third party libs
from supermercado import burntiles
import fiona
import rasterio
from rasterio.tools.mask import mask

# variables
path = '/home/pythonProjects/rasterio_test/'
os.chdir(path)
in_rst = "path/to/rst/some.tif"
aoi_file = 'test_area84.geojson'
zoom_level = 14
bash = 'cat {0} | supermercado burn {1} | mercantile shapes | fio collect'.format(aoi_file, zoom_level)

# run the cli and return the output 
def run_command(command):
    rc = subprocess.Popen(command,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    return (rc.stdout.read())

# create some geojson from the cli output 
mercado_output_tiles = run_command(bash)
json_tiles = json.loads(mercado_output_tiles.decode('utf-8'))

# create the geometry for mask 
intersecting = [feature['geometry'] for feature in json_tiles['features']]

print json.dumps(intersecting, indent=4)

# iterate the geoms 
for geoms in intersecting:

    with rasterio.open(in_rst) as src:
        out_image, out_transform = rasterio.mask.mask(src, 
                                                      geoms, 
                                                      crop=True)
        out_meta = src.meta.copy()

    # save the resulting raster
    out_meta.update({"driver": "GTiff",
        "height": out_image.shape[1],
        "width": out_image.shape[2],
    "transform": out_transform})

    with rasterio.open("tmp.tif", "w", **out_meta) as dest:
        dest.write(out_image)

The following is an example of what I get when I dump out what I am passing into the masking loop -

    {
        "type": "Polygon", 
        "coordinates": [
            [
                [
                    -4.8779296875, 
                    56.8129075187002
                ], 
                [
                    -4.8779296875, 
                    56.8249328650072
                ], 
                [
                    -4.85595703125, 
                    56.8249328650072
                ], 
                [
                    -4.85595703125, 
                    56.8129075187002
                ], 
                [
                    -4.8779296875, 
                    56.8129075187002
                ]
            ]
        ]
    }, 
    {
        "type": "Polygon", 
        "coordinates": [
            [
                [
                    -4.85595703125, 
                    56.8129075187002
                ], 
                [
                    -4.85595703125, 
                    56.8249328650072
                ], 
                [
                    -4.833984375, 
                    56.8249328650072
                ], 
                [
                    -4.833984375, 
                    56.8129075187002
                ], 
                [
                    -4.85595703125, 
                    56.8129075187002
                ]
            ]
        ]
    }
]

Is this not what rasterio.mask expects? I still get the same error as before.

  • json_tiles = list[json_tiles] looks wrong to me. Did you mean json_tiles = list[json_tiles]? If json_tiles is already a sequence, you don't need to make a list from it before you iterate. – sgillies May 16 '17 at 11:15

Your Answer

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

Browse other questions tagged or ask your own question.