My objective is to convert a google earth engine featureCollection into a geopandas geodataframe.

Earth engine can handle geoJSON whereas geopandas prefers shapely.

The geometry (geoJSON) of the first feature in my featureCollection is:


as you can see, there is a geodesic (boolean) parameter in the geoJSON.

I use shapely.geometry.shape() to convert the geoJSON to a shapely geometry that geopandas can handle. However I am not sure if the geodesic parameter is captured correctly. The shapely documentation doesn't mention this. [EDIT: the main page does] How can I make sure the geodesic parameter is handled correctly?

Here is my full function:

def fcToGdf(fc):
    """converts a featurecollection to a (geo)Pandas GeoDataFrame or a pandas DataFrame. WARNING: Geometries are non-geodesic. Geodesic not yet supported. work in progress

        fc (ee.FeatureCollection) : the earth engine feature collection to convert. Size is limited to memory (geopandas limitation)
        crs (dictionary, optional) : the coordinate reference system in geopandas format. Defaults to {'init' :'epsg:4326'}

        gdf (geoPandas.GeoDataFrame or pandas.DataFrame) : the corresponding (geo)dataframe. 

    crs = {'init' :'epsg:4326'}

    features = fc.getInfo()['features']
    dictarr = []

    for f in features:
        attr = f['properties']
        attr['geometry'] = f['geometry']  

    gdf = gpd.GeoDataFrame(dictarr)
    gdf['geometry2'] = map(lambda s: shapely.geometry.shape(s), gdf.geometry)
    gdf.crs = crs
    return gdf

shapely only handles geometry in the Cartesian plane. The project is explicit about that. You have surely seen that there is no spatial reference system properties for shapely Geometries. With that, I think you can absolve shapely from the requirement of maintaining geodesic properties.

edit: the following original paragraph is incorrect

geopandas should be correctly handling the geodesic properties, namely the arc/line connecting two adjacent vertices of a polygon geometry should fall on a great circle. Whereas shapely only handles Cartesian geometry, geopandas has good capabilities to handle spatial reference systems (including geodetic coordinate systems) through its use of pyproj.


Looking into the GeoJSON spec RFC 7946, there are explicit instructions that state:

A line between two positions is a straight Cartesian line, the shortest line between those two points in the coordinate reference system (see Section 4).

In other words, every point on a line that does not cross the antimeridian between a point (lon0, lat0) and (lon1, lat1) can be calculated as

F(lon, lat) = (lon0 + (lon1 - lon0) * t, lat0 + (lat1 - lat0) * t)

with t being a real number greater than or equal to 0 and smaller than or equal to 1. Note that this line may markedly differ from the geodesic path along the curved surface of the reference ellipsoid.

So with this it is fairly clear that GeoJSON uses for its geometry calculations an unrolled and warped geodetic spherical grid (now treated as a flat cartesian grid). This means, explicitly, that when handling modern GeoJSON, you should not expect geodetic geometry except for the equator and any lines of longitude.

To understand Google Earth Engine's (GEE) geodesic field within the geometry definition look at section 6.1 of the spec, which refers to foreign member extension. In short, GEE's geodesic field is permitted but acceptance and use of that member should not be expected across many different implementations and applications. I think you are seeing that here.

None of this is to say that geopandas needs to follow the GeoJSON spec in any way except for probably for the export gdf.to_json(). I noticed in your comment when you plot the geodataframe you are probably using the default representation, which is is the unrolled and warped (lon,lat) grid.

I think my answer should be unmarked as accepted to promote someone providing a better solution to actually finding how to use geodesic/great-circle geometries in python, geopandas, ...

  • this is helpful. In my function I set the crs in geopandas to crs = {'init' :'epsg:4326'}. Since this is a GCS, the geometries should be implemented correctly. thanks again – RutgerH Jan 4 '18 at 11:17
  • If I use gdf.to_json() the geodesic parameter is lost. Also when I use gdf.plot(), I see a planar geometry instead of a geodesic one. – RutgerH Jan 4 '18 at 12:03

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.