Skip to content

Commit 005be58

Browse files
authored
Merge pull request mvexel#125 from KaartGroup/date_query
Add date parameter to query builder
2 parents 279432c + 39a3e87 commit 005be58

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ response = api.get('node["name"="Salt Lake City"]')
5454

5555
`response` will be a dictionary representing the
5656
JSON output you would get [from the Overpass API
57-
directly](https://overpass-api.de/output_formats.html#json).
57+
directly](https://overpass-api.de/output_formats.html#json).
5858

5959
**Note that the Overpass query passed to `get()` should not contain any `out` or other meta statements.** See `verbosity` below for how to control the output.
6060

@@ -96,7 +96,12 @@ response = api.get('node["name"="Salt Lake City"]', responseformat="xml")
9696

9797
We will construct a valid Overpass QL query from the parameters you set by default. This means you don't have to include 'meta' statements like `[out:json]`, `[timeout:60]`, `[out body]`, etcetera. You just supply the meat of the query, the part that actually tells Overpass what to query for. If for whatever reason you want to override this and supply a full, valid Overpass QL query, you can set `build` to `False` to make the API not do any pre-processing.
9898

99-
### Pre-cooked Queries: `MapQuery`, `WayQuery`
99+
#### `date`
100+
101+
You can query the data as it was on a given date. You can give either a standard ISO date alone (YYYY-MM-DD) or a full overpass date and time (YYYY-MM-DDTHH:MM:SSZ, i.e. 2020-04-28T00:00:00Z).
102+
You can also directly pass a `date` or `datetime` object from the `datetime` library.
103+
104+
### Pre-cooked Queries: `MapQuery`, `WayQuery`
100105

101106
In addition to just sending your query and parse the result, `overpass`
102107
provides shortcuts for often used map queries. To use them, just pass

overpass/api.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import csv
99
import geojson
1010
import logging
11+
from datetime import datetime
1112
from shapely.geometry import Polygon, Point
1213
from io import StringIO
1314
from .errors import (
@@ -42,8 +43,8 @@ class API(object):
4243
_debug = False
4344
_proxies = None
4445

45-
_QUERY_TEMPLATE = "[out:{out}];{query}out {verbosity};"
46-
_GEOJSON_QUERY_TEMPLATE = "[out:json];{query}out {verbosity};"
46+
_QUERY_TEMPLATE = "[out:{out}]{date};{query}out {verbosity};"
47+
_GEOJSON_QUERY_TEMPLATE = "[out:json]{date};{query}out {verbosity};"
4748

4849
def __init__(self, *args, **kwargs):
4950
self.endpoint = kwargs.get("endpoint", self._endpoint)
@@ -70,7 +71,7 @@ def __init__(self, *args, **kwargs):
7071
requests_log.setLevel(logging.DEBUG)
7172
requests_log.propagate = True
7273

73-
def get(self, query, responseformat="geojson", verbosity="body", build=True):
74+
def get(self, query, responseformat="geojson", verbosity="body", build=True, date=''):
7475
"""Pass in an Overpass query in Overpass QL.
7576
7677
:param query: the Overpass QL query to send to the endpoint
@@ -81,11 +82,19 @@ def get(self, query, responseformat="geojson", verbosity="body", build=True):
8182
"body geom qt"
8283
:param build: boolean to indicate whether to build the overpass query from a template (True)
8384
or allow the programmer to specify full query manually (False)
85+
:param date: a date with an optional time. Example: 2020-04-27 or 2020-04-27T00:00:00Z
8486
"""
87+
if date and isinstance(date, str):
88+
# If date is given and is not already a datetime, attempt to parse from string
89+
try:
90+
date = datetime.fromisoformat(date)
91+
except ValueError:
92+
# The 'Z' in a standard overpass date will throw fromisoformat() off
93+
date = datetime.strptime(date, '%Y-%m-%dT%H:%M:%SZ')
8594
# Construct full Overpass query
8695
if build:
8796
full_query = self._construct_ql_query(
88-
query, responseformat=responseformat, verbosity=verbosity
97+
query, responseformat=responseformat, verbosity=verbosity, date=date
8998
)
9099
else:
91100
full_query = query
@@ -137,18 +146,22 @@ def search(self, feature_type, regex=False):
137146
Get = get
138147
Search = search
139148

140-
def _construct_ql_query(self, userquery, responseformat, verbosity):
149+
def _construct_ql_query(self, userquery, responseformat, verbosity, date):
141150
raw_query = str(userquery).rstrip()
142151
if not raw_query.endswith(";"):
143152
raw_query += ";"
144153

154+
if date:
155+
date = f'[date:"{date.strftime("%Y-%m-%dT%H:%M:%SZ")}"]'
156+
145157
if responseformat == "geojson":
146158
template = self._GEOJSON_QUERY_TEMPLATE
147-
complete_query = template.format(query=raw_query, verbosity=verbosity)
159+
complete_query = template.format(
160+
query=raw_query, verbosity=verbosity, date=date)
148161
else:
149162
template = self._QUERY_TEMPLATE
150163
complete_query = template.format(
151-
query=raw_query, out=responseformat, verbosity=verbosity
164+
query=raw_query, out=responseformat, verbosity=verbosity, date=date
152165
)
153166

154167
if self.debug:

0 commit comments

Comments
 (0)