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

New endpoints #134

Closed
wants to merge 16 commits into from
Closed
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
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ time = pandas.date_range("2018-01-01", periods=3, freq="M")

## Contribution Guidelines

The easiest way to contribute is to file a comprehensive [issue](https://github.com/GIScience/ohsome-py/issues) with a reproducible example. Pull requests are always welcome, so if you want to contribute to this project, please fork the repository or create a new branch containing your changes.

This package uses [poetry](https://python-poetry.org/) for dependency management.
The easiest way to contribute is to file a comprehensive [issue](https://github.com/GIScience/ohsome-py/issues) with a reproducible example. Pull requests are always welcome, so if you want to contribute to this project, please fork the repository or create a new branch containing your changes. Follow the steps below to make sure that your contributed code follows the code style and does not break any functionality. Create a **pull request to the main/master** branch once it is ready to be merged.

### Install Package

This package uses [poetry](https://python-poetry.org/) for dependency management. To install all packages necessary for testing and development run

`poetry install`

### Install Pre-Commit Hooks
Expand All @@ -147,12 +147,10 @@ This package uses [poetry](https://python-poetry.org/) for dependency management

### Run Tests

**Before pushing your commits**, run python tests
**Before pushing your commits**, run the python unit tests

`poetry run pytest`

Create a **pull request to the main/master** branch once it is ready to be merged.

#### VCR

ohsome-py records responses using [VCR](https://vcrpy.readthedocs.io/en/latest/) via [pytest-recording](https://github.com/kiwicom/pytest-recording) to prevent unnecessary network traffic and computing during testing. If you implement a test or change an existing one, make sure to update the recorded cassettes. In addition, you should delete all cassettes after a certain time (e.g. every 6m or on each new ohsome release) and re-record them. To do that run
Expand Down
28 changes: 27 additions & 1 deletion ohsome/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -740,10 +740,30 @@ def count(self):
class _OhsomeClientContributionsAggregated(_OhsomePostClient):
@property
def density(self):
return _OhsomePostClient(
return _OhsomeClientContributionsAggregatedDensity(
self._base_api_url, self.log, self.log_dir, self._cache + ["density"]
)

@property
def groupByBoundary(self):
return _OhsomePostClient(
self._base_api_url,
self.log,
self.log_dir,
self._cache + ["groupBy", "boundary"],
)


class _OhsomeClientContributionsAggregatedDensity(_OhsomePostClient):
@property
def groupByBoundary(self):
return _OhsomePostClient(
self._base_api_url,
self.log,
self.log_dir,
self._cache + ["groupBy", "boundary"],
)


class _OhsomeClientContributionsLatest(_OhsomePostClient):
"""Subclass of _OhsomePostClient to define endpoints of ohsome API for contribution analyses."""
Expand All @@ -766,6 +786,12 @@ def geometry(self):
self._base_api_url, self.log, self.log_dir, self._cache + ["geometry"]
)

@property
def count(self):
return _OhsomeClientContributionsAggregated(
self._base_api_url, self.log, self.log_dir, self._cache + ["count"]
)


class _OhsomeClientUsers(_OhsomeBaseClient):
"""Subclass of _OhsomePostClient to define endpoints of ohsome API"""
Expand Down
20 changes: 15 additions & 5 deletions ohsome/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,38 @@ def _as_geodataframe(self, multi_index=True):
)

if "@validFrom" in features.columns:
features["@validFrom"] = features["@validFrom"].str.replace("Z", "")
features["@validTo"] = features["@validTo"].str.replace("Z", "")
features["@validFrom"] = pd.to_datetime(
features["@validFrom"], format="%Y-%m-%dT%H:%M:%SZ"
features["@validFrom"], format="ISO8601"
)
features["@validTo"] = pd.to_datetime(
features["@validTo"], format="%Y-%m-%dT%H:%M:%SZ"
features["@validTo"], format="ISO8601"
)
if multi_index:
features = features.set_index(["@osmId", "@validFrom", "@validTo"])
elif "@snapshotTimestamp" in features.columns:
features["@snapshotTimestamp"] = features["@snapshotTimestamp"].str.replace(
"Z", ""
)
features["@snapshotTimestamp"] = pd.to_datetime(
features["@snapshotTimestamp"], format="%Y-%m-%dT%H:%M:%SZ"
features["@snapshotTimestamp"], format="ISO8601"
)
if multi_index:
features = features.set_index(["@osmId", "@snapshotTimestamp"])
elif (
"timestamp" in features.columns and "groupByBoundaryId" in features.columns
):
features["timestamp"] = features["timestamp"].str.replace("Z", "")
features["timestamp"] = pd.to_datetime(
features["timestamp"], format="%Y-%m-%dT%H:%M:%SZ"
features["timestamp"], format="ISO8601"
)
if multi_index:
features = features.set_index(["groupByBoundaryId", "timestamp"])
elif "@timestamp" in features.columns:
features["@timestamp"] = features["@timestamp"].str.replace("Z", "")
features["@timestamp"] = pd.to_datetime(
features["@timestamp"], format="%Y-%m-%dT%H:%M:%SZ"
features["@timestamp"], format="ISO8601"
)
if multi_index:
features = features.set_index(["@timestamp"])
Expand Down Expand Up @@ -173,13 +180,16 @@ def _format_timestamp(self, result_df: DataFrame) -> None:
:return:
"""
if "timestamp" in result_df.columns:
result_df["timestamp"] = result_df["timestamp"].str.replace("Z", "")
result_df["timestamp"] = pd.to_datetime(
result_df["timestamp"], format="ISO8601"
)
else:
result_df["fromTimestamp"] = result_df["fromTimestamp"].str.replace("Z", "")
result_df["fromTimestamp"] = pd.to_datetime(
result_df["fromTimestamp"], format="ISO8601"
)
result_df["toTimestamp"] = result_df["toTimestamp"].str.replace("Z", "")
result_df["toTimestamp"] = pd.to_datetime(
result_df["toTimestamp"], format="ISO8601"
)
1 change: 0 additions & 1 deletion ohsome/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

def test_start_end_time_is_datetime(base_client):
"""Test if the start_ end end_timestamp is in datetime format without timezone."""

assert isinstance(base_client.start_timestamp, dt.datetime)
assert isinstance(base_client.end_timestamp, dt.datetime)
assert base_client.start_timestamp.tzinfo is None
Expand Down
20 changes: 20 additions & 0 deletions ohsome/test/test_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import geopandas as gpd
import pandas as pd
import pytest
import datetime as dt


@pytest.mark.vcr
Expand Down Expand Up @@ -343,6 +344,25 @@ def test_contributions_latest(base_client):
assert len(result) == 1


def test_contributions_count_density_groupbyboundary(base_client):
"""
Test whether the result of contributions.count.density.groupbyboundary.post is converted to a DataFrame
:return:
"""
bboxes = "8.7137,49.4096,8.717,49.4119"
time = "2015-01-01,2016-01-01"
filter = "name=Krautturm and type:way"

client = base_client
response = client.contributions.count.density.groupByBoundary.post(
bboxes=bboxes, time=time, filter=filter
)
result = response.as_dataframe()

assert isinstance(result, pd.DataFrame)
assert len(result) == 1


@pytest.mark.vcr
def test_empty_geodataframe(base_client):
"""
Expand Down
Loading