0

How can I get of the extent of all features within a GeoJSON FeatureCollection with Python 3? One extent for all features, not one per feature.

The Feature collection includes multiple points features and multiple LineStrings features.

0
1

If your FeatureCollection doesn't have a bbox member as described in RFC 7946, you will need to loop over all Features and update a global variable as you go.

The code found in this answer can serve as a starting point for your script.

4
  • Now getting this error: c1 = [x[0] for x in c] TypeError: 'float' object is not subscriptable – Dean Sep 8 '18 at 20:58
  • Not sure about your location, but here it is getting late - maybe for you too... ;-) A point doesn't have an array of coordinates of course. :) For points it is simply: c1 = f["geometry"]["coordinates"][0] and c2 = f["geometry"]["coordinates"][1]. – Stefan Sep 8 '18 at 21:12
  • what about LineString. It's only 4:15pm here – Dean Sep 8 '18 at 21:15
  • See tools.ietf.org/html/rfc7946#appendix-A.2 You will have to find the outermost coordinates. I'm wondering if you aren't better off using node.js to compute bbox for your FeatureCollection: npmjs.com/package/@mapbox/geojson-extent – Stefan Sep 8 '18 at 21:26
0

Here's the way I do this, it doesn't require using ogr or shapely or anything outside of the core json library. This script is set up to crawl geojson with mixed geometries (point, linestring, polygon) but will work on single feature types too. It abstracts all coordinate pairs from their features, sticks them in a list, and then uses python's built-in range() functions to identify the min/max.

You can always subtract/add some arbitrary float to the min/max (respectively) if you want some 'padding' around the lower left/upper right coordinates.

import json

geojson_file = "path/to/file.json"

with open(geojson_file, 'r') as geojson:
    xcoords = []
    ycoords = []
    data = json.load(geojson)
    for f in data['features']:
        geom = f['geometry']
        for coord in geom['coordinates']:
            if type(coord) == float:  # then its a point feature
                xcoords.append(geom['coordinates'][0])
                ycoords.append(geom['coordinates'][1])
            elif type(coord) == list:
                for c in coord:
                    if type(c) == float:  # then its a linestring feature
                        xcoords.append(coord[0])
                        ycoords.append(coord[1])
                    elif type(c) == list:  # then its a polygon feature
                        xcoords.append(c[0])
                        ycoords.append(c[1])
    

Then, assuming you want to make a new poly object, you can just ask the list for the min/max and line it up however you want. I use the following format cause I work mainly with arcpy:

    extent = [
        [min(ycoords), min(xcoords)],
        [max(ycoords), min(xcoords)],
        [max(ycoords), max(xcoords)],
        [min(ycoords), max(xcoords)]
    ]
-1

I found the answer here with @Stefan_Fairphone's help...

The answer is here

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