Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create a featureCollection from a geointerface #381

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions geetools/ee_feature_collection.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Toolbox for the `ee.FeatureCollection` class."""
from __future__ import annotations

from typing import Any

import ee
import geopandas as gpd
from matplotlib import pyplot as plt
Expand Down Expand Up @@ -504,3 +506,51 @@ def plot(
gdf.boundary.plot(ax=ax, color=color)
else:
gdf.plot(column=property, ax=ax, cmap=cmap)

@classmethod
def fromGeoInterface(cls, data: Any) -> ee.FeatureCollection:
"""Create a FeatureCollection from a geo interface.

The ``geo_interface`` is a protocol representing a vector collection as a python GeoJSON-like dictionary structure.
More information is available at https://gist.github.com/sgillies/2217756. Note that the :py:class:`ee.FeatureCollection`
constructor is only supporting data represented in EPSG:4326.

The user can either provide an object that implements the ``__geo_interface__`` method or a dictionary
that respects the protocol described in the link above.

Parameters:
data: The geo_interface to create the FeatureCollection from.
crs: The CRS to use for the FeatureCollection. Default to "EPSG:4326".

Returns:
The created FeatureCollection.

Examples:
code-block:: python

import geetools

data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {"name": "Coors Field"},
"geometry": {
"type": "Point",
"coordinates": [-104.99404, 39.75621]
}
}
]
}

fc = ee.FeatureCollection.geetools.fromGeoInterface(data, crs="EPSG:4326")
"""
# clean the data
if hasattr(data, "__geo_interface__"):
data = data.__geo_interface__
elif not isinstance(data, dict):
raise ValueError("The data must be a geo_interface or a dictionary")

# create the feature collection
return ee.FeatureCollection(data)
30 changes: 30 additions & 0 deletions tests/test_FeatureCollection.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,33 @@ def hydroshed(self):
dataset = "WWF/HydroATLAS/v1/Basins/level04"
region = ee.Geometry.BBox(-80, -60, -20, 20)
return ee.FeatureCollection(dataset).filterBounds(region)


class TestFromGeoInterface:
"""Test the ``fromGeoInterface`` method."""

def test_from_geo_interface(self, gdf, data_regression):
fc = ee.FeatureCollection.geetools.fromGeoInterface(gdf)
data_regression.check(fc.getInfo())

def test_from_geo_interface_from_dict(self, gdf, data_regression):
fc = ee.FeatureCollection.geetools.fromGeoInterface(gdf.__geo_interface__)
data_regression.check(fc.getInfo())

def test_error_from_geo_interface_(self):
with pytest.raises(ValueError):
ee.FeatureCollection.geetools.fromGeoInterface("toto")

@pytest.fixture
def gdf(self):
data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {"name": "Coors Field"},
"geometry": {"type": "Point", "coordinates": [-104.99404, 39.75621]},
}
],
}
return gpd.GeoDataFrame.from_features(data["features"])
14 changes: 14 additions & 0 deletions tests/test_FeatureCollection/test_from_geo_interface.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
columns:
name: String
system:index: String
features:
- geometry:
coordinates:
- -104.99404
- 39.75621
type: Point
id: '0'
properties:
name: Coors Field
type: Feature
type: FeatureCollection
14 changes: 14 additions & 0 deletions tests/test_FeatureCollection/test_from_geo_interface_from_dict.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
columns:
name: String
system:index: String
features:
- geometry:
coordinates:
- -104.99404
- 39.75621
type: Point
id: '0'
properties:
name: Coors Field
type: Feature
type: FeatureCollection