I am unable to read a TopoJSON / JSON file in GeoPandas. The issue is that it's a JSON file with keys that are "probably" not standard.

I tried to use the from_features() method but it gives the error: KeyError: 'geometry'

Getting the GeoDataFrame is fine, but it doesn't have the geometry column as one would like.

File Source

File's data structure -

state:  "GA"
stateName:  "Georgia"
voteData:   […]
    type:   "Topology"
    arcs:   […]
    transform:  {…}
            type:   "GeometryCollection"
            geometries: […]
        stateOutline:   {…}
countySummaryStats: {…}

What I tried:

import geopandas as gpd
import pandas as pd
import requests
uri = "https://static01.nyt.com/newsgraphics/2020/10/29/election-early-battlegrounds/030056173a56b8c767e453b62d8cee320984b92d/GA.json"
r = requests.get(uri)
data = r.json()['topojson']['objects']['counties']['geometries']

When trying gpd.GeoDataFrame().from_features(r.json()['topojson']['objects']['counties']) I get the error -

TypeError: string indices must be integers

Ideally I'd like to have voteData's fields corresponding to geometries.

Any suggestion how to read this file?

  • Can't provide a solution right now but maybe this helps you going: This is indeed a TopoJSON file, not GeoJSON. They both use JSON as general format but have a completely different structure. GeoPandas does not support TopoJSON github.com/geopandas/geopandas/issues/610. Nov 6 '20 at 13:13
  • GeoPandas can read valid TopoJSON via geopandas.read_file('file.json'). It does not support writing. Nov 6 '20 at 13:40
  • Reading itself is the issue here, perhaps because although the file contains TopoJSON data, but it has it in a different format.... problem is that I am very new to GIS so I am not quite familiar with everything yet. Maybe I am wrong and it is indeed a proper TopoJSON, but then the read_file method is not able to parse it properly.
    – jar
    Nov 6 '20 at 13:46

The file is not a TopoJSON file. It's just a JSON file containing topojson section. Use the following script.

import geopandas as gpd
import pandas as pd
import json

# read json file
with open('GA.json') as json_file:
    json_data = json.load(json_file)

vote_df = pd.DataFrame(json_data["voteData"])
topo = dict(json_data["topojson"])

# write topojson section to file
with open('topo.json', 'w') as f:
    json.dump(topo, f)

# read as GeoDataFrame
gdf = gpd.GeoDataFrame.from_file('topo.json')
gdf.rename(columns={'NAME': 'county'}, inplace=True)

# add other attributes to gdf
gdf = gdf.merge(vote_df, on='county')

# OUT:
#      id  ST  GEOID   county STATEFP                          geometry   fips  postal  ....  senate_leading_display        lon        lat 
# 0  None  GA  13001  Appling      13  POLYGON ((-82.43134 31.96647,...   13001     GA  ....              Perdue +56 -82.289024  31.761233 
# 1  None  GA  13007    Baker      13  POLYGON ((-84.63750 31.43408,...   13007     GA  ....               Ossoff +9 -84.448526  31.327343 
# ....
# ....
# [159 rows x 67 columns]


enter image description here

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.