Skip to content

Commit

Permalink
improve test coverage (#159)
Browse files Browse the repository at this point in the history
  • Loading branch information
atmorling authored May 21, 2024
1 parent cc4fb51 commit 4b5d2fb
Show file tree
Hide file tree
Showing 10 changed files with 314 additions and 20 deletions.
27 changes: 13 additions & 14 deletions ecoscope/mapping/map.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import base64
import os
import tempfile
import time
import typing
import urllib
Expand Down Expand Up @@ -306,19 +305,19 @@ def to_png(self, outfile, sleep_time=5, **kwargs):
fully loaded but can also be decreased in most cases.
"""

with tempfile.NamedTemporaryFile(mode="w", suffix=".html") as tmp:
super().to_html(tmp.name, **kwargs)
chrome_options = selenium.webdriver.chrome.options.Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
driver = selenium.webdriver.Chrome(options=chrome_options)
if self.px_width and self.px_height:
driver.set_window_size(width=self.px_width, height=self.px_height)
driver.get(f"file://{os.path.abspath(tmp.name)}")
time.sleep(sleep_time)
driver.save_screenshot(outfile)
tempfile = "tmp_to_png.html"
super().to_html(tempfile, **kwargs)
chrome_options = selenium.webdriver.chrome.options.Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
driver = selenium.webdriver.Chrome(options=chrome_options)
if self.px_width and self.px_height:
driver.set_window_size(width=self.px_width, height=self.px_height)
driver.get(f"file://{os.path.abspath(tempfile)}")
time.sleep(sleep_time)
driver.save_screenshot(outfile)
os.remove(tempfile)

def add_ee_layer(self, ee_object, visualization_params, name) -> None:
"""
Expand Down
2 changes: 1 addition & 1 deletion ecoscope/plotting/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def nsd(relocations):
relocations = relocations.to_crs(relocations.estimate_utm_crs())

times = relocations["fixtime"]
distances = relocations.distance(relocations.geometry[0]) ** 2
distances = relocations.distance(relocations.geometry.iat[0]) ** 2

fig = go.FigureWidget()

Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
- jupyterlab
- geopandas<=0.14.2
- beautifulsoup4
- ipywidgets
- pip:
- kaleido
- pre-commit>=3
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"folium",
"geopandas<=0.14.2",
"igraph",
"ipywidgets",
"kaleido",
"mapclassify",
"matplotlib",
Expand Down
30 changes: 30 additions & 0 deletions tests/test_astronomy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pyproj
from ecoscope.analysis import astronomy


def test_to_EarthLocation(movebank_relocations):
geometry = movebank_relocations["geometry"]
test_point = geometry.iloc[0]

transformed = astronomy.to_EarthLocation(geometry)

assert len(geometry) == len(transformed)

transform = pyproj.Transformer.from_proj(
proj_from="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs",
proj_to="+proj=geocent +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
)

# Check the projected values in the returned EarthLocation are what we expect
test_val = transform.transform(xx=test_point.x, yy=test_point.y, zz=0)
assert test_val[0] == transformed[0].x.value
assert test_val[1] == transformed[0].y.value
assert test_val[2] == transformed[0].z.value


def test_is_night(movebank_relocations):
subset = movebank_relocations.iloc[12:15].copy()

subset["is_night"] = astronomy.is_night(subset.geometry, subset.fixtime)

assert subset["is_night"].values.tolist() == [True, True, False]
63 changes: 63 additions & 0 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,66 @@ def test_daynight_ratio(movebank_relocations):
),
expected,
)


def test_edf_filter(movebank_relocations):
movebank_relocations["junk_status"] = True

empty = movebank_relocations.remove_filtered()
assert len(empty) == 0

reset = movebank_relocations.reset_filter().remove_filtered()
assert len(reset) > 0


def test_relocs_from_gdf_with_warnings():
df = pd.read_feather("tests/sample_data/vector/movebank_data.feather")
geometry = gpd.points_from_xy(df.pop("location-long"), df.pop("location-lat"))

gdf = gpd.GeoDataFrame(df, geometry=geometry)

with pytest.warns(UserWarning, match="CRS was not set"):
ecoscope.base.Relocations.from_gdf(gdf, time_col="timestamp")

gdf = gpd.GeoDataFrame(df, geometry=geometry, crs=4326)
gdf["timestamp"] = pd.to_datetime(gdf["timestamp"])

with pytest.warns(UserWarning, match="timestamp is not timezone aware"):
ecoscope.base.Relocations.from_gdf(gdf, time_col="timestamp")

gdf["timestamp"] = "1/1/2000"

with pytest.warns(UserWarning, match="timestamp is not of type datetime64"):
ecoscope.base.Relocations.from_gdf(gdf, time_col="timestamp")


def test_apply_traj_filter(movebank_relocations):
trajectory = ecoscope.base.Trajectory.from_relocations(movebank_relocations)

min_length = 0.2
max_length = 6000
min_time = 100
max_time = 300000
min_speed = 0.1
max_speed = 5

traj_seg_filter = ecoscope.base.TrajSegFilter(
min_length_meters=min_length,
max_length_meters=max_length,
min_time_secs=min_time,
max_time_secs=max_time,
min_speed_kmhr=min_speed,
max_speed_kmhr=max_speed,
)

filtered = trajectory.apply_traj_filter(traj_seg_filter)
filtered.remove_filtered(inplace=True)

assert filtered["dist_meters"].min() >= min_length
assert filtered["dist_meters"].max() <= max_length

assert filtered["timespan_seconds"].min() >= min_time
assert filtered["timespan_seconds"].max() <= max_time

assert filtered["speed_kmhr"].min() >= min_speed
assert filtered["speed_kmhr"].max() <= max_speed
21 changes: 17 additions & 4 deletions tests/test_ecomap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
GeoTIFFElement,
PrintControl,
)
import os
import ee
import geopandas
import pytest
Expand Down Expand Up @@ -35,6 +36,18 @@ def test_repr_html():
assert m._parent.width == 800 and m._parent.height == 600


def test_static_map():
m = EcoMap(width=800, height=600, static=True)
assert len(m._children) == 2


def test_to_png():
output_path = "tests/outputs/ecomap.png"
m = EcoMap(width=800, height=600)
m.to_png(output_path)
assert os.path.exists(output_path)


def test_add_legend():
m = EcoMap()
# Test that we can assign hex colors with or without #
Expand Down Expand Up @@ -157,11 +170,11 @@ def test_add_print_control():
@pytest.mark.parametrize(
"file, geom_type",
[
("tests/sample_data/vector/maec_4zones_UTM36S.gpkg", "tests/sample_data/vector/observations.geojson"),
("polygon", "point"),
("tests/sample_data/vector/maec_4zones_UTM36S.gpkg", "polygon"),
("tests/sample_data/vector/observations.geojson", "point"),
],
)
def add_datashader_gdf(file, geom_type):
def test_add_datashader_gdf(file, geom_type):
m = EcoMap()
gdf = geopandas.GeoDataFrame.from_file(file)
m.add_datashader_gdf(gdf, geom_type, zoom=False)
Expand All @@ -170,7 +183,7 @@ def add_datashader_gdf(file, geom_type):
assert "L.imageOverlay(" in m._repr_html_()


def add_datashader_gdf_with_zoom():
def test_add_datashader_gdf_with_zoom():
m = EcoMap()
gdf = geopandas.GeoDataFrame.from_file("tests/sample_data/vector/maec_4zones_UTM36S.gpkg")
m.add_datashader_gdf(gdf, "polygon", zoom=True)
Expand Down
47 changes: 47 additions & 0 deletions tests/test_ecoplot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import numpy as np
from ecoscope.plotting.plot import EcoPlotData, ecoplot, mcp, nsd, speed
from ecoscope.base import Trajectory


def test_ecoplot(movebank_relocations):
traj = Trajectory.from_relocations(movebank_relocations)
epd = EcoPlotData(traj.groupby("groupby_col"), "segment_start", "speed_kmhr", line=dict(color="blue"))
figure = ecoplot([epd], "EcoPlot")

habiba = traj.loc[traj["groupby_col"] == "Habiba"]
salif = traj.loc[traj["groupby_col"] == "Salif Keita"]

assert len(figure.data) == 2

assert figure.data[0].name == "Habiba"
assert np.equal(figure.data[0].x, habiba["segment_start"].array).all()
assert np.equal(figure.data[0].y, habiba["speed_kmhr"].array).all()

assert figure.data[1].name == "Salif Keita"
assert np.equal(figure.data[1].x, salif["segment_start"].array).all()
assert np.equal(figure.data[1].y, salif["speed_kmhr"].array).all()


def test_mcp(movebank_relocations):
figure = mcp(movebank_relocations)

assert len(figure.data) == 1
assert movebank_relocations["fixtime"].iat[0] == figure.data[0].x[0]
assert movebank_relocations["fixtime"].iat[-1] == figure.data[0].x[-1]


def test_nsd(movebank_relocations):
figure = nsd(movebank_relocations)

assert len(figure.data) == 1
assert len(figure.data[0].x) == len(movebank_relocations)
assert len(figure.data[0].y) == len(movebank_relocations)


def test_speed(movebank_relocations):
traj = Trajectory.from_relocations(movebank_relocations)
figure = speed(traj)

assert len(figure.data) == 1
len(figure.data[0].x) == len(traj) * 4
len(figure.data[0].y) == len(traj) * 4
20 changes: 20 additions & 0 deletions tests/test_proiximity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pytest
from ecoscope.analysis.proximity import SpatialFeature, Proximity, ProximityProfile
from ecoscope.base import Trajectory


@pytest.mark.skipif(not pytest.earthranger, reason="No connection to EarthRanger")
def test_proximity(er_io):
er_features = er_io.get_spatial_features_group(spatial_features_group_id="15698426-7e0f-41df-9bc3-495d87e2e097")

prox_profile = ProximityProfile([])

for row in er_features.iterrows():
prox_profile.spatial_features.append(SpatialFeature(row[1]["name"], row[1]["pk"], row[1]["geometry"]))

relocations = er_io.get_subjectgroup_observations(group_name=er_io.GROUP_NAME)
trajectory = Trajectory.from_relocations(relocations)

proximity_events = Proximity.calculate_proximity(proximity_profile=prox_profile, trajectory=trajectory)

assert len(proximity_events["spatialfeature_id"].unique()) == len(prox_profile.spatial_features)
Loading

0 comments on commit 4b5d2fb

Please sign in to comment.