diff --git a/.gitignore b/.gitignore index a456f4aef4..3d2579d726 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .DS_Store +.idea/ .pytest_cache/ +.vscode/ **/__pycache__/ *.py[cod] dist/ @@ -11,4 +13,4 @@ eggs/ pip-log.txt docs/_build/ Pipfile.lock -venv/ \ No newline at end of file +venv/ diff --git a/overpass/api.py b/overpass/api.py index 0536c75dca..5dfee7c389 100644 --- a/overpass/api.py +++ b/overpass/api.py @@ -7,8 +7,10 @@ import json import logging import re -from datetime import datetime +from datetime import datetime, timezone from io import StringIO +from math import ceil +from typing import Optional import geojson import requests @@ -204,6 +206,34 @@ def slots_running(self) -> tuple: """ return self._api_status()["running_slots"] + @property + def slot_available_datetime(self) -> Optional[datetime]: + """ + :returns: None if a slot is available now (no wait needed) or a datetime representing when the next slot will become available + """ + if self.slots_available: + return None + return min(self.slots_running + self.slots_waiting) + + @property + def slot_available_countdown(self) -> int: + """ + :returns: 0 if a slot is available now, or an int of seconds until the next slot is free + """ + try: + return max( + ceil( + ( + self.slot_available_datetime - + datetime.now(timezone.utc) + ).total_seconds() + ), + 0 + ) + except TypeError: + # Can't subtract from None, which means slot is available now + return 0 + def search(self, feature_type, regex=False): """Search for something.""" raise NotImplementedError() diff --git a/setup.py b/setup.py index 034b967e0e..a0622434b3 100644 --- a/setup.py +++ b/setup.py @@ -20,5 +20,5 @@ "Topic :: Utilities", ], install_requires=["requests>=2.3.0", "geojson>=1.0.9", "shapely>=1.6.4"], - extras_require={"test": ["pytest"]}, + extras_require={"test": ["pytest", "requests-mock[fixture]"]}, ) diff --git a/tests/example_mapquery.json b/tests/example_mapquery.json new file mode 100644 index 0000000000..856f9aff16 --- /dev/null +++ b/tests/example_mapquery.json @@ -0,0 +1,1897 @@ +{ + "version": 0.6, + "generator": "Overpass API 0.7.58.5 b0c4acbb", + "osm3s": { + "timestamp_osm_base": "2022-07-26T00:41:24Z", + "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." + }, + "elements": [ + { "type": "node", "id": 31792138, "lat": 37.8603296, "lon": -122.3154486 }, + { "type": "node", "id": 31793704, "lat": 37.8687352, "lon": -122.3148768 }, + { "type": "node", "id": 31802087, "lat": 37.8659262, "lon": -122.3179189 }, + { "type": "node", "id": 31806467, "lat": 37.8677652, "lon": -122.3131913 }, + { "type": "node", "id": 31810191, "lat": 37.8652103, "lon": -122.3118958 }, + { "type": "node", "id": 31811936, "lat": 37.8590371, "lon": -122.3158983 }, + { "type": "node", "id": 31814789, "lat": 37.8629153, "lon": -122.3139303 }, + { "type": "node", "id": 31824950, "lat": 37.8680027, "lon": -122.3183041 }, + { "type": "node", "id": 31826578, "lat": 37.8670585, "lon": -122.3181089 }, + { "type": "node", "id": 31828392, "lat": 37.8626366, "lon": -122.3174381 }, + { "type": "node", "id": 31828867, "lat": 37.8597419, "lon": -122.3154655 }, + { "type": "node", "id": 31828873, "lat": 37.8689908, "lon": -122.3150035 }, + { "type": "node", "id": 31831699, "lat": 37.8678702, "lon": -122.3136748 }, + { "type": "node", "id": 31832346, "lat": 37.8641477, "lon": -122.3163995 }, + { "type": "node", "id": 31833063, "lat": 37.8623879, "lon": -122.3153091 }, + { "type": "node", "id": 31833974, "lat": 37.8589635, "lon": -122.3161911 }, + { "type": "node", "id": 31834262, "lat": 37.866116, "lon": -122.3180648 }, + { "type": "node", "id": 31834997, "lat": 37.8627551, "lon": -122.317567 }, + { "type": "node", "id": 31836398, "lat": 37.8663038, "lon": -122.3172694 }, + { "type": "node", "id": 31840870, "lat": 37.8673521, "lon": -122.3183488 }, + { "type": "node", "id": 31841306, "lat": 37.8593413, "lon": -122.3164732 }, + { "type": "node", "id": 31843733, "lat": 37.8690284, "lon": -122.3150803 }, + { "type": "node", "id": 31844309, "lat": 37.8594687, "lon": -122.3156099 }, + { "type": "node", "id": 31846142, "lat": 37.8642832, "lon": -122.316657 }, + { "type": "node", "id": 31846355, "lat": 37.8680104, "lon": -122.3145684 }, + { "type": "node", "id": 31846473, "lat": 37.8615776, "lon": -122.3158456 }, + { "type": "node", "id": 31848189, "lat": 37.8629719, "lon": -122.3176871 }, + { "type": "node", "id": 31849187, "lat": 37.8638766, "lon": -122.3177471 }, + { "type": "node", "id": 31849796, "lat": 37.867038, "lon": -122.3126608 }, + { "type": "node", "id": 31850341, "lat": 37.8640935, "lon": -122.3159017 }, + { "type": "node", "id": 31854283, "lat": 37.8672524, "lon": -122.3181678 }, + { "type": "node", "id": 31858211, "lat": 37.8690384, "lon": -122.3151593 }, + { "type": "node", "id": 31860126, "lat": 37.8591479, "lon": -122.3155097 }, + { "type": "node", "id": 31860299, "lat": 37.8650996, "lon": -122.3178502 }, + { "type": "node", "id": 31860925, "lat": 37.8610671, "lon": -122.3156187 }, + { "type": "node", "id": 31861027, "lat": 37.8681359, "lon": -122.3146521 }, + { "type": "node", "id": 31861250, "lat": 37.864788, "lon": -122.3123932 }, + { "type": "node", "id": 31864065, "lat": 37.8633684, "lon": -122.3177127 }, + { "type": "node", "id": 31864568, "lat": 37.8676054, "lon": -122.3129339 }, + { "type": "node", "id": 31869347, "lat": 37.8684666, "lon": -122.3179197 }, + { "type": "node", "id": 53021415, "lat": 37.8630906, "lon": -122.3172578 }, + { "type": "node", "id": 53091722, "lat": 37.8657458, "lon": -122.3177788 }, + { "type": "node", "id": 53091724, "lat": 37.8634904, "lon": -122.3173866 }, + { "type": "node", "id": 87337461, "lat": 37.8680555, "lon": -122.3185432 }, + { "type": "node", "id": 87353882, "lat": 37.8682285, "lon": -122.3181615 }, + { "type": "node", "id": 87353897, "lat": 37.8678626, "lon": -122.3183499 }, + { + "type": "node", + "id": 87362461, + "lat": 37.8685848, + "lon": -122.317574, + "tags": { "leisure": "slipway" } + }, + { + "type": "node", + "id": 87362495, + "lat": 37.8671444, + "lon": -122.3183266, + "tags": { "highway": "turning_circle" } + }, + { "type": "node", "id": 87362500, "lat": 37.8672888, "lon": -122.318441 }, + { "type": "node", "id": 87362504, "lat": 37.8681506, "lon": -122.3183595 }, + { "type": "node", "id": 87362512, "lat": 37.8683531, "lon": -122.3181867 }, + { "type": "node", "id": 87362517, "lat": 37.8685038, "lon": -122.3180262 }, + { "type": "node", "id": 87362524, "lat": 37.8685976, "lon": -122.3178336 }, + { "type": "node", "id": 87362533, "lat": 37.8686506, "lon": -122.3178006 }, + { "type": "node", "id": 87362540, "lat": 37.8688101, "lon": -122.3169443 }, + { "type": "node", "id": 87362547, "lat": 37.8689112, "lon": -122.3163791 }, + { "type": "node", "id": 87362555, "lat": 37.8690125, "lon": -122.3158432 }, + { "type": "node", "id": 87362561, "lat": 37.8691409, "lon": -122.3151262 }, + { "type": "node", "id": 87362565, "lat": 37.8690817, "lon": -122.3149651 }, + { "type": "node", "id": 87362570, "lat": 37.8690213, "lon": -122.3149032 }, + { "type": "node", "id": 87362576, "lat": 37.8685277, "lon": -122.3147209 }, + { "type": "node", "id": 87362586, "lat": 37.8681437, "lon": -122.3145713 }, + { "type": "node", "id": 87362591, "lat": 37.8680832, "lon": -122.3144774 }, + { "type": "node", "id": 87362597, "lat": 37.8680658, "lon": -122.3142632 }, + { "type": "node", "id": 87362604, "lat": 37.8680198, "lon": -122.3139961 }, + { "type": "node", "id": 87362610, "lat": 37.8679531, "lon": -122.3136948 }, + { "type": "node", "id": 87362614, "lat": 37.8678765, "lon": -122.3133392 }, + { "type": "node", "id": 87362623, "lat": 37.867758, "lon": -122.3129614 }, + { "type": "node", "id": 87362650, "lat": 37.8686906, "lon": -122.3175981 }, + { "type": "node", "id": 255822137, "lat": 37.8659125, "lon": -122.3173224 }, + { "type": "node", "id": 255822153, "lat": 37.8644402, "lon": -122.316507 }, + { "type": "node", "id": 255822154, "lat": 37.8653973, "lon": -122.3168895 }, + { "type": "node", "id": 255822164, "lat": 37.8645023, "lon": -122.3137573 }, + { "type": "node", "id": 255822174, "lat": 37.8645971, "lon": -122.3133939 }, + { "type": "node", "id": 255822190, "lat": 37.8646739, "lon": -122.3130811 }, + { "type": "node", "id": 255822207, "lat": 37.8663056, "lon": -122.3154688 }, + { "type": "node", "id": 255822219, "lat": 37.8662269, "lon": -122.3158459 }, + { "type": "node", "id": 255822229, "lat": 37.8661931, "lon": -122.3160048 }, + { "type": "node", "id": 255822241, "lat": 37.8671128, "lon": -122.3157947 }, + { "type": "node", "id": 255822242, "lat": 37.8661474, "lon": -122.3162232 }, + { "type": "node", "id": 255822252, "lat": 37.8665073, "lon": -122.3165912 }, + { "type": "node", "id": 255822253, "lat": 37.8660983, "lon": -122.3164605 }, + { "type": "node", "id": 255822259, "lat": 37.8656823, "lon": -122.3164437 }, + { "type": "node", "id": 255822260, "lat": 37.8660747, "lon": -122.31657 }, + { "type": "node", "id": 255822269, "lat": 37.8664216, "lon": -122.3169915 }, + { "type": "node", "id": 255822270, "lat": 37.8660158, "lon": -122.316865 }, + { "type": "node", "id": 255822332, "lat": 37.8656126, "lon": -122.316846 }, + { "type": "node", "id": 255822333, "lat": 37.8659945, "lon": -122.3169707 }, + { "type": "node", "id": 255822356, "lat": 37.8642648, "lon": -122.3148783 }, + { "type": "node", "id": 255822384, "lat": 37.8641138, "lon": -122.3156528 }, + { "type": "node", "id": 255822443, "lat": 37.8672769, "lon": -122.3127792 }, + { "type": "node", "id": 255822463, "lat": 37.8688855, "lon": -122.3160554 }, + { "type": "node", "id": 255822501, "lat": 37.8687228, "lon": -122.3169214 }, + { "type": "node", "id": 255822544, "lat": 37.8664699, "lon": -122.3123589 }, + { "type": "node", "id": 300459906, "lat": 37.7718397, "lon": -122.3859658 }, + { "type": "node", "id": 302034041, "lat": 37.7718795, "lon": -122.3860022 }, + { "type": "node", "id": 310159601, "lat": 37.8683604, "lon": -122.3180513 }, + { "type": "node", "id": 310159602, "lat": 37.8672729, "lon": -122.3182736 }, + { "type": "node", "id": 310159604, "lat": 37.8671701, "lon": -122.3181039 }, + { "type": "node", "id": 310159619, "lat": 37.868535, "lon": -122.3177687 }, + { "type": "node", "id": 310159621, "lat": 37.8689342, "lon": -122.3149556 }, + { "type": "node", "id": 310159623, "lat": 37.8680118, "lon": -122.3143214 }, + { "type": "node", "id": 310159625, "lat": 37.8679931, "lon": -122.3141941 }, + { "type": "node", "id": 310159627, "lat": 37.8676769, "lon": -122.3130098 }, + { "type": "node", "id": 310163208, "lat": 37.8662142, "lon": -122.3178935 }, + { "type": "node", "id": 310163209, "lat": 37.8661391, "lon": -122.3172084 }, + { "type": "node", "id": 310163210, "lat": 37.8661098, "lon": -122.3173181 }, + { "type": "node", "id": 310163211, "lat": 37.8650027, "lon": -122.312514 }, + { "type": "node", "id": 310163212, "lat": 37.8650273, "lon": -122.3118068 }, + { "type": "node", "id": 310163213, "lat": 37.8651532, "lon": -122.3116541 }, + { "type": "node", "id": 310163214, "lat": 37.8652208, "lon": -122.311627 }, + { "type": "node", "id": 310163215, "lat": 37.8653313, "lon": -122.3116228 }, + { "type": "node", "id": 310163216, "lat": 37.865428, "lon": -122.3116988 }, + { "type": "node", "id": 310163217, "lat": 37.8656188, "lon": -122.3118722 }, + { "type": "node", "id": 310163218, "lat": 37.8628281, "lon": -122.3143657 }, + { "type": "node", "id": 310163219, "lat": 37.8626442, "lon": -122.314893 }, + { "type": "node", "id": 310163220, "lat": 37.8624873, "lon": -122.3151641 }, + { "type": "node", "id": 310163221, "lat": 37.861744, "lon": -122.3157361 }, + { "type": "node", "id": 310163222, "lat": 37.8621697, "lon": -122.3154542 }, + { "type": "node", "id": 310163223, "lat": 37.8614198, "lon": -122.3158511 }, + { "type": "node", "id": 310163224, "lat": 37.8612359, "lon": -122.3157498 }, + { "type": "node", "id": 310163225, "lat": 37.8607086, "lon": -122.3155035 }, + { "type": "node", "id": 310163226, "lat": 37.8596333, "lon": -122.3155417 }, + { "type": "node", "id": 310163227, "lat": 37.8590193, "lon": -122.3158018 }, + { "type": "node", "id": 310163228, "lat": 37.8590471, "lon": -122.3160065 }, + { "type": "node", "id": 310163229, "lat": 37.8591997, "lon": -122.3161036 }, + { "type": "node", "id": 310163230, "lat": 37.8592136, "lon": -122.3162493 }, + { "type": "node", "id": 310163231, "lat": 37.8591962, "lon": -122.316395 }, + { "type": "node", "id": 310163232, "lat": 37.8590332, "lon": -122.3163603 }, + { "type": "node", "id": 310163233, "lat": 37.8589461, "lon": -122.316308 }, + { "type": "node", "id": 310163234, "lat": 37.8589313, "lon": -122.3162398 }, + { "type": "node", "id": 310163235, "lat": 37.8660143, "lon": -122.3180562 }, + { "type": "node", "id": 310163264, "lat": 37.8659553, "lon": -122.3171795 }, + { "type": "node", "id": 310163265, "lat": 37.8661338, "lon": -122.3172287 }, + { "type": "node", "id": 310163266, "lat": 37.8650176, "lon": -122.3169671 }, + { "type": "node", "id": 310163267, "lat": 37.8650641, "lon": -122.3167615 }, + { "type": "node", "id": 310163442, "lat": 37.8679799, "lon": -122.3137924 }, + { "type": "node", "id": 310163446, "lat": 37.8684599, "lon": -122.3146952 }, + { "type": "node", "id": 310163448, "lat": 37.8656584, "lon": -122.311833 }, + { "type": "node", "id": 310163449, "lat": 37.8655916, "lon": -122.3117418 }, + { "type": "node", "id": 310163450, "lat": 37.8655003, "lon": -122.311606 }, + { "type": "node", "id": 310163451, "lat": 37.865398, "lon": -122.3114725 }, + { "type": "node", "id": 310163452, "lat": 37.8653186, "lon": -122.3114394 }, + { "type": "node", "id": 310163453, "lat": 37.8652021, "lon": -122.3113985 }, + { "type": "node", "id": 310163454, "lat": 37.865123, "lon": -122.3113796 }, + { "type": "node", "id": 310163455, "lat": 37.8649517, "lon": -122.3113894 }, + { "type": "node", "id": 310163456, "lat": 37.8648338, "lon": -122.311479 }, + { "type": "node", "id": 310163457, "lat": 37.8648702, "lon": -122.3115642 }, + { "type": "node", "id": 310163458, "lat": 37.8649267, "lon": -122.3116868 }, + { "type": "node", "id": 310163460, "lat": 37.8649838, "lon": -122.311822 }, + { "type": "node", "id": 310163461, "lat": 37.8649795, "lon": -122.3119844 }, + { "type": "node", "id": 310163462, "lat": 37.8648297, "lon": -122.3123894 }, + { "type": "node", "id": 310163463, "lat": 37.8647894, "lon": -122.312374 }, + { "type": "node", "id": 310163464, "lat": 37.8640912, "lon": -122.3156102 }, + { "type": "node", "id": 310163465, "lat": 37.8640348, "lon": -122.315983 }, + { "type": "node", "id": 310163466, "lat": 37.8640416, "lon": -122.3162929 }, + { "type": "node", "id": 310163467, "lat": 37.864082, "lon": -122.316489 }, + { "type": "node", "id": 310163468, "lat": 37.8641607, "lon": -122.3166386 }, + { "type": "node", "id": 310163469, "lat": 37.8643182, "lon": -122.316753 }, + { "type": "node", "id": 310163470, "lat": 37.8658225, "lon": -122.3173661 }, + { "type": "node", "id": 310163471, "lat": 37.8659298, "lon": -122.3174295 }, + { "type": "node", "id": 310163505, "lat": 37.8640829, "lon": -122.3156443 }, + { "type": "node", "id": 310163506, "lat": 37.8642374, "lon": -122.3148685 }, + { "type": "node", "id": 310163507, "lat": 37.8646052, "lon": -122.3130598 }, + { "type": "node", "id": 310163510, "lat": 37.8644372, "lon": -122.3176469 }, + { "type": "node", "id": 361211065, "lat": 37.8638105, "lon": -122.3174637 }, + { "type": "node", "id": 361211106, "lat": 37.8633075, "lon": -122.3173437 }, + { "type": "node", "id": 361213673, "lat": 37.8624875, "lon": -122.3173351 }, + { "type": "node", "id": 361213704, "lat": 37.8628467, "lon": -122.3176441 }, + { "type": "node", "id": 361213896, "lat": 37.8646423, "lon": -122.3176956 }, + { "type": "node", "id": 361214298, "lat": 37.8658823, "lon": -122.3174982 }, + { "type": "node", "id": 361214299, "lat": 37.8658418, "lon": -122.3175372 }, + { "type": "node", "id": 361214331, "lat": 37.8659298, "lon": -122.3175153 }, + { "type": "node", "id": 361214333, "lat": 37.8659764, "lon": -122.3175746 }, + { "type": "node", "id": 361214334, "lat": 37.8659732, "lon": -122.317675 }, + { "type": "node", "id": 361214336, "lat": 37.865933, "lon": -122.3177785 }, + { "type": "node", "id": 361214340, "lat": 37.8658876, "lon": -122.3178022 }, + { "type": "node", "id": 361214342, "lat": 37.8658013, "lon": -122.317786 }, + { "type": "node", "id": 361221167, "lat": 37.8659805, "lon": -122.3179704 }, + { "type": "node", "id": 813905691, "lat": 37.8686651, "lon": -122.3177302 }, + { + "type": "node", + "id": 813905694, + "lat": 37.8685517, + "lon": -122.3177004, + "tags": { "leisure": "slipway" } + }, + { "type": "node", "id": 813905730, "lat": 37.8689712, "lon": -122.3160789 }, + { "type": "node", "id": 813905746, "lat": 37.8684402, "lon": -122.3147926 }, + { "type": "node", "id": 813905749, "lat": 37.8679001, "lon": -122.3138109 }, + { + "type": "node", + "id": 813905835, + "lat": 37.8683015, + "lon": -122.3181005, + "tags": { "leisure": "slipway" } + }, + { + "type": "node", + "id": 1326065120, + "lat": 37.8652598, + "lon": -122.3117191 + }, + { + "type": "node", + "id": 1326065122, + "lat": 37.8683365, + "lon": -122.3179847 + }, + { + "type": "node", + "id": 1326065123, + "lat": 37.8663568, + "lon": -122.3172581 + }, + { + "type": "node", + "id": 1326065124, + "lat": 37.8661467, + "lon": -122.3172412 + }, + { "type": "node", "id": 1326065125, "lat": 37.8663187, "lon": -122.317297 }, + { "type": "node", "id": 1326065128, "lat": 37.864381, "lon": -122.31659 }, + { + "type": "node", + "id": 1326065133, + "lat": 37.8685312, + "lon": -122.3174536 + }, + { + "type": "node", + "id": 1326065134, + "lat": 37.8660917, + "lon": -122.3176674 + }, + { + "type": "node", + "id": 1326065135, + "lat": 37.8661364, + "lon": -122.3171881 + }, + { + "type": "node", + "id": 1326065138, + "lat": 37.8679469, + "lon": -122.3182771 + }, + { + "type": "node", + "id": 1326065143, + "lat": 37.8677224, + "lon": -122.3131567 + }, + { + "type": "node", + "id": 1326065144, + "lat": 37.8662279, + "lon": -122.3177361 + }, + { "type": "node", "id": 1326065145, "lat": 37.868004, "lon": -122.3146722 }, + { + "type": "node", + "id": 1326065146, + "lat": 37.8689569, + "lon": -122.3150745 + }, + { + "type": "node", + "id": 1326065150, + "lat": 37.8658993, + "lon": -122.3171962 + }, + { "type": "node", "id": 1326065153, "lat": 37.865012, "lon": -122.3125425 }, + { + "type": "node", + "id": 1326065154, + "lat": 37.8641523, + "lon": -122.3159355 + }, + { + "type": "node", + "id": 1326065155, + "lat": 37.8648723, + "lon": -122.3125211 + }, + { + "type": "node", + "id": 1326065157, + "lat": 37.8663101, + "lon": -122.3177192 + }, + { + "type": "node", + "id": 1659965167, + "lat": 37.8628913, + "lon": -122.3141046 + }, + { + "type": "node", + "id": 1659965200, + "lat": 37.8682558, + "lon": -122.3181386 + }, + { + "type": "node", + "id": 2132971257, + "lat": 37.8625701, + "lon": -122.3151014 + }, + { + "type": "node", + "id": 2334582460, + "lat": 37.7974915, + "lon": -122.3947156 + }, + { + "type": "node", + "id": 2334582461, + "lat": 37.7975909, + "lon": -122.3945439 + }, + { + "type": "node", + "id": 2334582463, + "lat": 37.7978045, + "lon": -122.3942085 + }, + { + "type": "node", + "id": 2334582464, + "lat": 37.7978381, + "lon": -122.3942397 + }, + { "type": "node", "id": 2334582466, "lat": 37.7976504, "lon": -122.394599 }, + { + "type": "node", + "id": 2334582467, + "lat": 37.7975509, + "lon": -122.3947707 + }, + { "type": "node", "id": 2345064491, "lat": 37.8672058, "lon": -122.318407 }, + { "type": "node", "id": 2345064497, "lat": 37.867426, "lon": -122.318349 }, + { + "type": "node", + "id": 2345064505, + "lat": 37.8683211, + "lon": -122.3180841 + }, + { + "type": "node", + "id": 2419414566, + "lat": 37.8645517, + "lon": -122.3132989 + }, + { + "type": "node", + "id": 2862795703, + "lat": 37.8657205, + "lon": -122.3176981 + }, + { + "type": "node", + "id": 2862795704, + "lat": 37.8649074, + "lon": -122.3176042 + }, + { + "type": "node", + "id": 2862795705, + "lat": 37.8650344, + "lon": -122.3170785 + }, + { + "type": "node", + "id": 2862795706, + "lat": 37.8658497, + "lon": -122.3174004 + }, + { + "type": "node", + "id": 4069974843, + "lat": 37.8643977, + "lon": -122.3176353 + }, + { + "type": "node", + "id": 4069974844, + "lat": 37.8638632, + "lon": -122.3174791 + }, + { "type": "node", "id": 4070023574, "lat": 37.864903, "lon": -122.317715 }, + { + "type": "node", + "id": 4070023575, + "lat": 37.8650523, + "lon": -122.3171575 + }, + { + "type": "node", + "id": 4070023576, + "lat": 37.8658448, + "lon": -122.3174552 + }, + { + "type": "node", + "id": 4070023577, + "lat": 37.8658071, + "lon": -122.3176232 + }, + { + "type": "node", + "id": 4070023578, + "lat": 37.8650031, + "lon": -122.3173412 + }, + { + "type": "node", + "id": 4622849715, + "lat": 37.8642462, + "lon": -122.3148248 + }, + { + "type": "node", + "id": 4644000624, + "lat": 37.797602, + "lon": -122.3946825, + "tags": { + "amenity": "ferry_terminal", + "cargo": "passengers", + "ferry": "yes", + "name": "San Francisco Pier 1\u00bd", + "network": "Tideline", + "operator": "Tideline", + "public_transport": "stop_position", + "wheelchair": "yes" + } + }, + { "type": "node", "id": 4644000625, "lat": 37.797641, "lon": -122.3947031 }, + { + "type": "node", + "id": 4644000626, + "lat": 37.7976855, + "lon": -122.3947047 + }, + { + "type": "node", + "id": 4644000627, + "lat": 37.7977464, + "lon": -122.3946579 + }, + { "type": "node", "id": 4644000628, "lat": 37.7985164, "lon": -122.393348 }, + { + "type": "node", + "id": 4644000629, + "lat": 37.7993449, + "lon": -122.3924447 + }, + { "type": "node", "id": 4644000635, "lat": 37.821379, "lon": -122.3950402 }, + { + "type": "node", + "id": 4644000636, + "lat": 37.8401805, + "lon": -122.3842311 + }, + { + "type": "node", + "id": 4644000637, + "lat": 37.8412093, + "lon": -122.3831527 + }, + { + "type": "node", + "id": 4644000638, + "lat": 37.8525222, + "lon": -122.3644724 + }, + { "type": "node", "id": 4644000639, "lat": 37.86446, "lon": -122.3137433 }, + { + "type": "node", + "id": 4644000640, + "lat": 37.8650387, + "lon": -122.314062, + "tags": { + "amenity": "ferry_terminal", + "cargo": "passengers", + "ferry": "yes", + "name": "Berkeley Marina K-Dock", + "network": "Tideline", + "operator": "Tideline", + "public_transport": "stop_position", + "website": "https://tidelinetickets.com/berkeley-sf-commute/berkeley-sf-booking/" + } + }, + { + "type": "node", + "id": 4644000641, + "lat": 37.8651283, + "lon": -122.3139716 + }, + { + "type": "node", + "id": 4644000642, + "lat": 37.8651711, + "lon": -122.3138839 + }, + { + "type": "node", + "id": 4644000643, + "lat": 37.8653227, + "lon": -122.3138395 + }, + { + "type": "node", + "id": 4644000646, + "lat": 37.8660228, + "lon": -122.3140616 + }, + { + "type": "node", + "id": 4644000647, + "lat": 37.8662546, + "lon": -122.3141704 + }, + { + "type": "node", + "id": 4644000648, + "lat": 37.8666081, + "lon": -122.3180346 + }, + { + "type": "node", + "id": 4644000649, + "lat": 37.8667015, + "lon": -122.3188557 + }, + { + "type": "node", + "id": 4644000650, + "lat": 37.8668869, + "lon": -122.3147801 + }, + { + "type": "node", + "id": 4644000651, + "lat": 37.8670758, + "lon": -122.3150778 + }, + { + "type": "node", + "id": 4644000652, + "lat": 37.8671326, + "lon": -122.3195821 + }, + { + "type": "node", + "id": 4644000653, + "lat": 37.8671528, + "lon": -122.3154503 + }, + { + "type": "node", + "id": 4644000654, + "lat": 37.8672046, + "lon": -122.3204678 + }, + { + "type": "node", + "id": 4644000655, + "lat": 37.8672309, + "lon": -122.3198634 + }, + { + "type": "node", + "id": 4807137371, + "lat": 37.8655124, + "lon": -122.3171284, + "tags": { "access": "customers", "amenity": "toilets" } + }, + { + "type": "node", + "id": 4807137372, + "lat": 37.865805, + "lon": -122.3178375, + "tags": { "amenity": "bench", "backrest": "yes" } + }, + { + "type": "node", + "id": 5136682547, + "lat": 37.8685963, + "lon": -122.3175278 + }, + { + "type": "node", + "id": 5136682550, + "lat": 37.8686982, + "lon": -122.3175567 + }, + { + "type": "node", + "id": 5136682552, + "lat": 37.8673362, + "lon": -122.3182427 + }, + { + "type": "node", + "id": 5136682553, + "lat": 37.8672795, + "lon": -122.3181332 + }, + { + "type": "node", + "id": 5136682554, + "lat": 37.8671864, + "lon": -122.3180388 + }, + { + "type": "node", + "id": 5136682555, + "lat": 37.8670854, + "lon": -122.3180516 + }, + { + "type": "node", + "id": 5136682556, + "lat": 37.8669998, + "lon": -122.3181052 + }, + { "type": "node", "id": 5136682557, "lat": 37.866939, "lon": -122.3182316 }, + { + "type": "node", + "id": 5136682558, + "lat": 37.8662084, + "lon": -122.3180119 + }, + { + "type": "node", + "id": 5560981043, + "lat": 37.8643025, + "lon": -122.3145538 + }, + { + "type": "node", + "id": 6443979376, + "lat": 37.8215266, + "lon": -122.3950818 + }, + { + "type": "node", + "id": 6443979377, + "lat": 37.8217214, + "lon": -122.3950684 + }, + { + "type": "node", + "id": 6443979378, + "lat": 37.8219327, + "lon": -122.3949953 + }, + { + "type": "node", + "id": 6443979513, + "lat": 37.8055864, + "lon": -122.3888578 + }, + { + "type": "node", + "id": 6443979803, + "lat": 37.8052892, + "lon": -122.3887808 + }, + { "type": "node", "id": 6443979804, "lat": 37.8049723, "lon": -122.388788 }, + { + "type": "node", + "id": 6446343427, + "lat": 37.8046563, + "lon": -122.3888934 + }, + { + "type": "node", + "id": 6479662111, + "lat": 37.7926331, + "lon": -122.3844472 + }, + { + "type": "node", + "id": 6479662112, + "lat": 37.7890321, + "lon": -122.3820587 + }, + { + "type": "node", + "id": 6479662113, + "lat": 37.7890284, + "lon": -122.3821507 + }, + { + "type": "node", + "id": 6479662114, + "lat": 37.7900306, + "lon": -122.3824533 + }, + { + "type": "node", + "id": 6479662115, + "lat": 37.7909989, + "lon": -122.3829659 + }, + { + "type": "node", + "id": 6479662116, + "lat": 37.7917887, + "lon": -122.3835947 + }, + { + "type": "node", + "id": 6479662117, + "lat": 37.7982529, + "lon": -122.3911746 + }, + { + "type": "node", + "id": 6479662118, + "lat": 37.7984571, + "lon": -122.3915492 + }, + { + "type": "node", + "id": 6479662119, + "lat": 37.7986096, + "lon": -122.3919831 + }, + { + "type": "node", + "id": 6479662120, + "lat": 37.7986551, + "lon": -122.3924666 + }, + { + "type": "node", + "id": 6479662121, + "lat": 37.7986156, + "lon": -122.3928934 + }, + { + "type": "node", + "id": 6479662122, + "lat": 37.7984761, + "lon": -122.3933091 + }, + { + "type": "node", + "id": 6479662123, + "lat": 37.7977246, + "lon": -122.3946364 + }, + { + "type": "node", + "id": 6479662124, + "lat": 37.7977033, + "lon": -122.3946626 + }, + { + "type": "node", + "id": 6479662125, + "lat": 37.7976758, + "lon": -122.3946759 + }, + { + "type": "node", + "id": 6479662126, + "lat": 37.7976418, + "lon": -122.3946807 + }, + { + "type": "node", + "id": 6479662127, + "lat": 37.7977199, + "lon": -122.3946887 + }, + { + "type": "node", + "id": 6479662128, + "lat": 37.7988907, + "lon": -122.3928546 + }, + { + "type": "node", + "id": 6479662129, + "lat": 37.7916822, + "lon": -122.3826629 + }, + { + "type": "node", + "id": 6479662130, + "lat": 37.7904757, + "lon": -122.3823247 + }, + { + "type": "node", + "id": 6479662131, + "lat": 37.8228351, + "lon": -122.3943865 + }, + { + "type": "node", + "id": 6479662132, + "lat": 37.8056914, + "lon": -122.3883788 + }, + { + "type": "node", + "id": 6479662133, + "lat": 37.8215107, + "lon": -122.3946077 + }, + { + "type": "node", + "id": 6479662134, + "lat": 37.8219988, + "lon": -122.3946537 + }, + { "type": "node", "id": 6479662135, "lat": 37.8224221, "lon": -122.394557 }, + { "type": "node", "id": 6479662136, "lat": 37.840151, "lon": -122.3841719 }, + { + "type": "node", + "id": 6479662137, + "lat": 37.8411696, + "lon": -122.3831043 + }, + { + "type": "node", + "id": 6479662138, + "lat": 37.8524745, + "lon": -122.3644372 + }, + { + "type": "node", + "id": 6479662139, + "lat": 37.8671522, + "lon": -122.3204466 + }, + { + "type": "node", + "id": 6479662140, + "lat": 37.8671994, + "lon": -122.3201785 + }, + { + "type": "node", + "id": 6479662141, + "lat": 37.8671772, + "lon": -122.3198811 + }, + { + "type": "node", + "id": 6479662142, + "lat": 37.8670851, + "lon": -122.3196174 + }, + { + "type": "node", + "id": 6479662143, + "lat": 37.8666543, + "lon": -122.3188916 + }, + { + "type": "node", + "id": 6479662144, + "lat": 37.8665504, + "lon": -122.3186088 + }, + { + "type": "node", + "id": 6479662145, + "lat": 37.8665187, + "lon": -122.3182878 + }, + { + "type": "node", + "id": 6479662146, + "lat": 37.8665546, + "lon": -122.3180193 + }, + { + "type": "node", + "id": 6479662147, + "lat": 37.8670592, + "lon": -122.3157801 + }, + { "type": "node", "id": 6479662148, "lat": 37.867097, "lon": -122.3154542 }, + { + "type": "node", + "id": 6479662149, + "lat": 37.8670257, + "lon": -122.3151097 + }, + { + "type": "node", + "id": 6479662150, + "lat": 37.8668484, + "lon": -122.3148302 + }, + { + "type": "node", + "id": 6479662713, + "lat": 37.8662279, + "lon": -122.3142319 + }, + { + "type": "node", + "id": 6479662714, + "lat": 37.8660066, + "lon": -122.3141279 + }, + { + "type": "node", + "id": 6479662715, + "lat": 37.8653146, + "lon": -122.3138742 + }, + { "type": "node", "id": 6479662716, "lat": 37.865256, "lon": -122.3138793 }, + { + "type": "node", + "id": 6479662717, + "lat": 37.8651901, + "lon": -122.3139146 + }, + { "type": "node", "id": 6479662718, "lat": 37.865153, "lon": -122.3139793 }, + { + "type": "node", + "id": 6479662719, + "lat": 37.8666037, + "lon": -122.3185894 + }, + { "type": "node", "id": 6479662720, "lat": 37.866574, "lon": -122.3182893 }, + { + "type": "node", + "id": 6479662721, + "lat": 37.8652473, + "lon": -122.3138346 + }, + { + "type": "node", + "id": 6479662722, + "lat": 37.8672548, + "lon": -122.3201828 + }, + { "type": "node", "id": 6479662723, "lat": 37.7725213, "lon": -122.385152 }, + { + "type": "node", + "id": 6479662724, + "lat": 37.7725407, + "lon": -122.3853709 + }, + { + "type": "node", + "id": 6479662725, + "lat": 37.7725098, + "lon": -122.3855876 + }, + { + "type": "node", + "id": 6479662726, + "lat": 37.7724311, + "lon": -122.3857841 + }, + { + "type": "node", + "id": 6479662727, + "lat": 37.7723113, + "lon": -122.3859439 + }, + { + "type": "node", + "id": 6479662728, + "lat": 37.7721603, + "lon": -122.3860537 + }, + { + "type": "node", + "id": 6479662729, + "lat": 37.7719898, + "lon": -122.3860907 + }, + { + "type": "node", + "id": 6479662730, + "lat": 37.7724546, + "lon": -122.3849535 + }, + { + "type": "node", + "id": 6479662731, + "lat": 37.7722027, + "lon": -122.3800506 + }, + { + "type": "node", + "id": 6479662732, + "lat": 37.7718708, + "lon": -122.3801944 + }, + { + "type": "node", + "id": 6479662733, + "lat": 37.7715808, + "lon": -122.3804443 + }, + { + "type": "node", + "id": 6479662734, + "lat": 37.7713535, + "lon": -122.3807823 + }, + { + "type": "node", + "id": 6479662735, + "lat": 37.7712049, + "lon": -122.3811844 + }, + { + "type": "node", + "id": 6479662736, + "lat": 37.7711459, + "lon": -122.3816219 + }, + { + "type": "node", + "id": 6479662737, + "lat": 37.7711805, + "lon": -122.3820636 + }, + { + "type": "node", + "id": 6479662738, + "lat": 37.7725455, + "lon": -122.3800237 + }, + { + "type": "node", + "id": 6479662739, + "lat": 37.7713036, + "lon": -122.3824693 + }, + { + "type": "node", + "id": 6479662740, + "lat": 37.7713548, + "lon": -122.3824444 + }, + { + "type": "node", + "id": 6479662741, + "lat": 37.7725489, + "lon": -122.3800929 + }, + { + "type": "node", + "id": 6479662742, + "lat": 37.7722135, + "lon": -122.3801192 + }, + { + "type": "node", + "id": 6479662743, + "lat": 37.7718955, + "lon": -122.3802569 + }, + { + "type": "node", + "id": 6479662744, + "lat": 37.7716177, + "lon": -122.3804963 + }, + { + "type": "node", + "id": 6479662745, + "lat": 37.7713999, + "lon": -122.3808201 + }, + { + "type": "node", + "id": 6479662746, + "lat": 37.7712577, + "lon": -122.3812053 + }, + { + "type": "node", + "id": 6479662747, + "lat": 37.7712011, + "lon": -122.3816244 + }, + { + "type": "node", + "id": 6479662748, + "lat": 37.7712342, + "lon": -122.3820475 + }, + { + "type": "node", + "id": 6479662749, + "lat": 37.7724319, + "lon": -122.3849656 + }, + { "type": "node", "id": 6479662750, "lat": 37.7724972, "lon": -122.38516 }, + { + "type": "node", + "id": 6479662751, + "lat": 37.7725158, + "lon": -122.3853698 + }, + { + "type": "node", + "id": 6479662752, + "lat": 37.7724861, + "lon": -122.3855776 + }, + { "type": "node", "id": 6479662753, "lat": 37.7724107, "lon": -122.385766 }, + { + "type": "node", + "id": 6479662754, + "lat": 37.7722959, + "lon": -122.3859192 + }, + { + "type": "node", + "id": 6479662755, + "lat": 37.7721511, + "lon": -122.3860244 + }, + { + "type": "node", + "id": 6479662756, + "lat": 37.7719887, + "lon": -122.3860728 + }, + { + "type": "node", + "id": 6479662757, + "lat": 37.7718729, + "lon": -122.3860138, + "tags": { + "amenity": "ferry_terminal", + "cargo": "passengers", + "ferry": "yes", + "name": "San Francisco Pier 52", + "network": "Tideline", + "operator": "Tideline", + "public_transport": "stop_position" + } + }, + { + "type": "node", + "id": 6743277066, + "lat": 37.8659203, + "lon": -122.3174354, + "tags": { "emergency": "fire_hydrant" } + }, + { + "type": "node", + "id": 6743283024, + "lat": 37.866079, + "lon": -122.3179817, + "tags": { "tourism": "viewpoint" } + }, + { + "type": "node", + "id": 6743286401, + "lat": 37.8658684, + "lon": -122.3173395, + "tags": { "amenity": "waste_disposal" } + }, + { + "type": "node", + "id": 6932307313, + "lat": 37.7976172, + "lon": -122.3945683 + }, + { + "type": "node", + "id": 6932307314, + "lat": 37.7976253, + "lon": -122.3945543 + }, + { + "type": "node", + "id": 6932307315, + "lat": 37.7976283, + "lon": -122.3945785 + }, + { + "type": "node", + "id": 6932307316, + "lat": 37.7976363, + "lon": -122.3945645 + }, + { + "type": "node", + "id": 6932307317, + "lat": 37.7976116, + "lon": -122.3945415 + }, + { + "type": "node", + "id": 6932307318, + "lat": 37.7976452, + "lon": -122.3945727 + }, + { + "type": "node", + "id": 6932454004, + "lat": 37.8650104, + "lon": -122.3141754 + }, + { "type": "node", "id": 6932454005, "lat": 37.8650519, "lon": -122.313999 }, + { "type": "node", "id": 6932454006, "lat": 37.8650152, "lon": -122.314177 }, + { + "type": "node", + "id": 6932454007, + "lat": 37.8650413, + "lon": -122.3139955 + }, + { + "type": "node", + "id": 6932454008, + "lat": 37.8650046, + "lon": -122.3141735 + }, + { + "type": "node", + "id": 6932454013, + "lat": 37.8645052, + "lon": -122.3137434 + }, + { + "type": "node", + "id": 6932454020, + "lat": 37.8644969, + "lon": -122.3137837 + }, + { + "type": "node", + "id": 6932454023, + "lat": 37.7716572, + "lon": -122.3862851 + }, + { "type": "node", "id": 6932454024, "lat": 37.771697, "lon": -122.3863215 }, + { + "type": "node", + "id": 7285768929, + "lat": 37.7975107, + "lon": -122.3947334 + }, + { + "type": "node", + "id": 7285768930, + "lat": 37.7716771, + "lon": -122.3863033 + }, + { + "type": "node", + "id": 8929006168, + "lat": 37.8661077, + "lon": -122.3174341 + }, + { + "type": "node", + "id": 8929006169, + "lat": 37.8661175, + "lon": -122.3174373 + }, + { + "type": "node", + "id": 8929006170, + "lat": 37.8660971, + "lon": -122.3175384 + }, + { + "type": "node", + "id": 8929006171, + "lat": 37.8661165, + "lon": -122.3175447 + }, + { "type": "node", "id": 8929006172, "lat": 37.8661675, "lon": -122.317692 }, + { "type": "node", "id": 8929006173, "lat": 37.8661629, "lon": -122.317715 }, + { + "type": "node", + "id": 8929006174, + "lat": 37.8662568, + "lon": -122.3175933 + }, + { "type": "node", "id": 8929006175, "lat": 37.866248, "lon": -122.3175904 }, + { + "type": "node", + "id": 8929006176, + "lat": 37.8662724, + "lon": -122.3174698 + }, + { + "type": "node", + "id": 8929006177, + "lat": 37.8662831, + "lon": -122.3174732 + }, + { "type": "node", "id": 9063656316, "lat": 37.8640294, "lon": -122.316138 }, + { "type": "node", "id": 9063682136, "lat": 37.865951, "lon": -122.3177451 }, + { + "type": "node", + "id": 9063682137, + "lat": 37.8659897, + "lon": -122.3177976 + }, + { + "type": "node", + "id": 9063682138, + "lat": 37.8661209, + "lon": -122.3179321 + }, + { + "type": "node", + "id": 9063682139, + "lat": 37.8660997, + "lon": -122.3179072 + }, + { + "type": "node", + "id": 9063682140, + "lat": 37.8660708, + "lon": -122.3179085 + }, + { + "type": "node", + "id": 9063682141, + "lat": 37.8660512, + "lon": -122.3179353 + }, + { + "type": "node", + "id": 9063682142, + "lat": 37.8660523, + "lon": -122.3179719 + }, + { + "type": "node", + "id": 9063682143, + "lat": 37.8660734, + "lon": -122.3179968 + }, + { + "type": "node", + "id": 9063682144, + "lat": 37.8661023, + "lon": -122.3179954 + }, + { + "type": "node", + "id": 9063682145, + "lat": 37.8661219, + "lon": -122.3179686 + }, + { + "type": "node", + "id": 9063682221, + "lat": 37.8682211, + "lon": -122.3146192 + }, + { + "type": "node", + "id": 9063682222, + "lat": 37.8681063, + "lon": -122.3145417 + }, + { + "type": "node", + "id": 9063682223, + "lat": 37.8687556, + "lon": -122.3147956 + }, + { + "type": "node", + "id": 9063682224, + "lat": 37.8691171, + "lon": -122.3150416 + }, + { + "type": "node", + "id": 9063682247, + "lat": 37.8659424, + "lon": -122.3171758 + }, + { + "type": "node", + "id": 9063682248, + "lat": 37.8642253, + "lon": -122.3167073 + }, + { + "type": "node", + "id": 9063682249, + "lat": 37.8649997, + "lon": -122.3170397 + }, + { + "type": "node", + "id": 9063682267, + "lat": 37.8664941, + "lon": -122.3122821 + }, + { + "type": "node", + "id": 9063682268, + "lat": 37.8672969, + "lon": -122.3127136 + }, + { + "type": "node", + "id": 9063682274, + "lat": 37.7975376, + "lon": -122.3947584 + }, + { + "type": "way", + "id": 6353187, + "nodes": [ + 361214298, 361214331, 361214333, 361214334, 9063682136, 361214336, + 361214340, 361214342, 53091722 + ], + "tags": { + "addr:city": "Berkeley", + "highway": "residential", + "name": "Seawall Drive", + "oneway": "yes", + "tiger:cfcc": "A41", + "tiger:county": "Alameda, CA", + "tiger:name_base": "Seawall", + "tiger:name_type": "Dr", + "tiger:reviewed": "no" + } + }, + { + "type": "way", + "id": 10322307, + "nodes": [ + 87362495, 2345064491, 87362500, 87337461, 87362504, 87362512, 87362517, + 87362524, 87362533, 813905691, 87362650, 5136682550, 87362540, 87362547, + 813905730, 87362555, 87362561, 9063682224, 87362565, 87362570, + 9063682223, 87362576, 310163446, 9063682221, 87362586, 9063682222, + 87362591, 87362597, 87362604, 310163442, 87362610, 87362614, 87362623, + 9063682268, 9063682267, 310163448, 310163449, 310163450, 310163451, + 310163452, 310163453, 310163454, 310163455, 310163456, 310163457, + 310163458, 310163460, 310163461, 310163462, 310163463, 310163507, + 2419414566, 4644000639, 5560981043, 4622849715, 310163506, 310163464, + 310163505, 310163465, 9063656316, 310163466, 310163467, 310163468, + 9063682248, 310163469, 9063682249, 310163470, 310163471, 361214331 + ], + "tags": { "addr:city": "Berkeley", "highway": "footway" } + }, + { + "type": "way", + "id": 23617830, + "nodes": [ + 255822207, 255822219, 255822229, 255822242, 255822253, 255822260, + 255822270, 255822333, 310163264, 9063682247, 255822137 + ], + "tags": { + "addr:city": "Berkeley", + "man_made": "pier", + "name": "O-Dock", + "ref": "O" + } + }, + { + "type": "way", + "id": 23617832, + "nodes": [255822153, 310163267, 255822154], + "tags": { + "addr:city": "Berkeley", + "man_made": "pier", + "name": "N-Dock", + "ref": "N" + } + }, + { + "type": "way", + "id": 23617840, + "nodes": [255822252, 255822253], + "tags": { "man_made": "pier", "name": "O-Dock", "ref": "O" } + }, + { + "type": "way", + "id": 23617841, + "nodes": [255822259, 255822260], + "tags": { + "addr:city": "Berkeley", + "man_made": "pier", + "name": "O-Dock", + "ref": "O" + } + }, + { + "type": "way", + "id": 23617842, + "nodes": [255822269, 255822270], + "tags": { + "addr:city": "Berkeley", + "man_made": "pier", + "name": "O-Dock", + "ref": "O" + } + }, + { + "type": "way", + "id": 23617849, + "nodes": [255822332, 255822333], + "tags": { + "addr:city": "Berkeley", + "man_made": "pier", + "name": "O-Dock", + "ref": "O" + } + }, + { + "type": "way", + "id": 27369597, + "nodes": [ + 6932454023, 300459906, 302034041, 6479662757, 6932454024, 7285768930, + 6932454023 + ], + "tags": { + "area": "yes", + "ferry": "yes", + "floating": "yes", + "man_made": "pier", + "name": "San Francisco Pier 52", + "network": "Tideline", + "public_transport": "platform" + } + }, + { + "type": "way", + "id": 28239155, + "nodes": [310163264, 310163265], + "tags": { + "addr:city": "Berkeley", + "floating": "yes", + "man_made": "pier", + "name": "Berkeley Yacht Club Guest Dock" + } + }, + { + "type": "way", + "id": 117767449, + "nodes": [ + 1326065134, 8929006171, 8929006170, 8929006169, 8929006168, 1326065124, + 1326065125, 8929006177, 8929006176, 8929006175, 8929006174, 1326065144, + 8929006173, 8929006172, 1326065134 + ], + "tags": { + "addr:city": "Berkeley", + "addr:housenumber": "1", + "addr:postcode": "94710", + "addr:state": "CA", + "addr:street": "Seawall Drive", + "amenity": "public_building", + "building": "yes", + "name": "Berkeley Yacht Club" + } + }, + { + "type": "way", + "id": 117767451, + "nodes": [ + 1326065157, 5136682558, 5136682557, 5136682556, 5136682555, 5136682554, + 5136682553, 5136682552, 1326065138, 1326065122, 1326065133, 1326065146, + 1326065145, 1326065143, 1326065120, 1326065153, 1326065155, 1326065154, + 1326065128, 1326065150, 1326065135, 1326065123, 1326065157 + ], + "tags": { + "addr:city": "Berkeley", + "addr:housenumber": "201", + "addr:street": "University Avenue", + "leisure": "marina", + "name": "Berkeley Marina", + "operator": "City of Berkeley", + "power_supply": "yes", + "sanitary_dump_station": "yes" + } + }, + { + "type": "way", + "id": 153288129, + "nodes": [ + 31826578, 310159604, 31854283, 310159602, 31840870, 2345064497, + 87353897, 31824950, 87353882, 1659965200, 813905835, 2345064505, + 310159601, 31869347, 310159619, 813905694, 87362461, 5136682547, + 255822501, 255822463, 31858211, 31843733, 31828873, 310159621, 31793704, + 813905746, 31861027, 31846355, 310159623, 310159625, 813905749, + 31831699, 31806467, 310159627, 31864568, 255822443, 31849796, 255822544, + 310163217, 310163216, 310163215, 310163214, 310163213, 310163212, + 31810191, 310163211, 31861250, 255822190, 255822174, 6932454013, + 255822164, 6932454020, 255822356, 255822384, 31850341, 31832346, + 31846142, 310163266, 255822137, 310163210, 310163265, 310163209, + 31836398, 310163208, 31834262, 310163235, 361221167, 31802087, 31860299, + 31849187, 31864065, 31848189, 361213704, 31834997, 31828392, 361213673, + 31841306, 310163231, 310163232, 310163233, 310163234, 31833974, + 310163230, 310163229, 310163228, 31811936, 310163227, 31860126, + 31844309, 310163226, 31828867, 31792138, 310163225, 31860925, 310163224, + 310163223, 31846473, 310163221, 310163222, 31833063, 310163220, + 2132971257, 310163219, 310163218, 1659965167, 31814789 + ], + "tags": { + "addr:city": "Berkeley", + "natural": "coastline", + "source": "PGS" + } + }, + { + "type": "way", + "id": 195430725, + "nodes": [ + 53021415, 361211106, 53091724, 361211065, 4069974844, 4069974843, + 310163510, 361213896, 4070023574, 53091722, 4070023577, 361214299, + 361214298 + ], + "tags": { + "addr:city": "Berkeley", + "highway": "residential", + "name": "Seawall Drive", + "tiger:cfcc": "A41", + "tiger:county": "Alameda, CA", + "tiger:name_base": "Seawall", + "tiger:name_type": "Dr", + "tiger:reviewed": "no" + } + }, + { + "type": "way", + "id": 224658487, + "nodes": [ + 6932307316, 6932307315, 2334582466, 4644000624, 2334582467, 9063682274, + 7285768929, 2334582460, 2334582461, 6932307313, 6932307314, 6932307317, + 2334582463, 2334582464, 6932307318, 6932307316 + ], + "tags": { + "area": "yes", + "ferry": "yes", + "floating": "yes", + "man_made": "pier", + "name": "San Francisco Pier 1\u00bd", + "network": "Tideline", + "public_transport": "platform" + } + }, + { + "type": "way", + "id": 282352311, + "nodes": [2862795703, 2862795704, 2862795705, 2862795706, 2862795703], + "tags": { "amenity": "parking", "parking": "surface" } + }, + { + "type": "way", + "id": 404731101, + "nodes": [4070023577, 4070023578], + "tags": { + "highway": "service", + "oneway": "yes", + "service": "parking_aisle" + } + }, + { + "type": "way", + "id": 404731102, + "nodes": [4070023578, 4070023575, 4070023576, 361214298], + "tags": { + "highway": "service", + "oneway": "yes", + "service": "parking_aisle" + } + }, + { + "type": "way", + "id": 470184134, + "nodes": [ + 4644000640, 4644000641, 4644000642, 6479662721, 4644000643, 4644000646, + 4644000647, 4644000650, 4644000651, 4644000653, 255822241, 4644000648, + 6479662720, 6479662719, 4644000649, 4644000652, 4644000655, 6479662722, + 4644000654, 4644000638, 4644000637, 4644000636, 6443979378, 6443979377, + 6443979376, 4644000635, 6443979513, 6443979803, 6443979804, 6446343427, + 4644000629, 6479662128, 4644000628, 4644000627, 6479662127, 4644000626, + 4644000625, 4644000624 + ], + "tags": { + "bicycle": "yes", + "disused:route": "ferry", + "duration": "00:20:00", + "fee": "yes", + "foot": "yes", + "name": "Berkeley - San Francisco Pier 1\u00bd", + "network": "Tideline", + "note": "suspended due to pandemic", + "opening_hours": "Mo-Fr 06:30-09:20, 16:00-18:50", + "operator": "Tideline", + "payment:cash": "no", + "payment:clipper": "no", + "payment:prepaid_ticket": "yes", + "vehicle": "no", + "website": "https://tidelinetickets.com/commuter-shuttle/berkeley/" + } + }, + { + "type": "way", + "id": 690605722, + "nodes": [ + 6479662757, 6479662729, 6479662728, 6479662727, 6479662726, 6479662725, + 6479662724, 6479662723, 6479662730, 6479662740, 6479662748, 6479662747, + 6479662746, 6479662745, 6479662744, 6479662743, 6479662742, 6479662741, + 6479662113, 6479662114, 6479662115, 6479662116, 6479662111, 6479662117, + 6479662118, 6479662119, 6479662120, 6479662121, 6479662122, 6479662123, + 6479662124, 6479662125, 6479662126, 4644000624 + ], + "tags": { + "bicycle": "yes", + "disused:route": "ferry", + "fee": "yes", + "foot": "yes", + "name": "San Francisco Pier 1\u00bd - San Francisco Pier 52", + "network": "Tideline", + "note": "suspended due to pandemic", + "opening_hours": "Mo-Fr 06:30-09:20, 16:00-18:50", + "operator": "Tideline", + "payment:cash": "no", + "payment:clipper": "no", + "payment:prepaid_ticket": "yes", + "vehicle": "no", + "website": "https://tidelinetickets.com/commuter-shuttle/berkeley/" + } + }, + { + "type": "way", + "id": 690605723, + "nodes": [ + 6479662757, 6479662756, 6479662755, 6479662754, 6479662753, 6479662752, + 6479662751, 6479662750, 6479662749, 6479662739, 6479662737, 6479662736, + 6479662735, 6479662734, 6479662733, 6479662732, 6479662731, 6479662738, + 6479662112, 6479662130, 6479662129, 6479662132, 6479662133, 6479662134, + 6479662135, 6479662131, 6479662136, 6479662137, 6479662138, 6479662139, + 6479662140, 6479662141, 6479662142, 6479662143, 6479662144, 6479662145, + 6479662146, 6479662147, 6479662148, 6479662149, 6479662150, 6479662713, + 6479662714, 6479662715, 6479662716, 6479662717, 6479662718, 4644000640 + ], + "tags": { + "bicycle": "yes", + "disused:route": "ferry", + "duration": "00:30", + "fee": "yes", + "foot": "yes", + "name": "Berkeley - San Francisco Pier 52", + "network": "Tideline", + "note": "suspended due to pandemic", + "opening_hours": "Mo-Fr 06:30-09:20, 16:00-18:50", + "operator": "Tideline", + "payment:cash": "no", + "payment:clipper": "no", + "payment:prepaid_ticket": "yes", + "vehicle": "no", + "website": "https://www.tidelinetickets.com/commute" + } + }, + { + "type": "way", + "id": 740454500, + "nodes": [ + 6932454008, 6932454004, 6932454006, 4644000640, 6932454005, 6932454007, + 6932454008 + ], + "tags": { + "area": "yes", + "ferry": "yes", + "man_made": "pier", + "name": "Berkeley Marina K-Dock", + "network": "Tideline", + "public_transport": "platform" + } + }, + { + "type": "way", + "id": 979766517, + "nodes": [9063682140, 9063682137, 9063682136], + "tags": { "highway": "footway" } + }, + { + "type": "way", + "id": 979766518, + "nodes": [ + 9063682145, 9063682144, 9063682143, 9063682142, 9063682141, 9063682140, + 9063682139, 9063682138, 9063682145 + ], + "tags": { "highway": "footway" } + }, + { + "type": "relation", + "id": 9596727, + "members": [ + { "type": "node", "ref": 4644000640, "role": "stop" }, + { "type": "way", "ref": 740454500, "role": "platform" }, + { "type": "node", "ref": 6479662757, "role": "stop" }, + { "type": "way", "ref": 27369597, "role": "platform" }, + { "type": "node", "ref": 4644000624, "role": "stop" }, + { "type": "way", "ref": 224658487, "role": "platform" }, + { "type": "node", "ref": 4644000640, "role": "stop" }, + { "type": "way", "ref": 740454500, "role": "platform" }, + { "type": "way", "ref": 690605723, "role": "" }, + { "type": "way", "ref": 690605722, "role": "" }, + { "type": "way", "ref": 470184134, "role": "" } + ], + "tags": { + "bicycle": "yes", + "disused:route": "ferry", + "fee": "yes", + "foot": "yes", + "from": "Berkeley Marina K-Dock", + "name": "Tideline: Berkeley => San Francisco => Berkeley (evenings)", + "network": "Tideline", + "note": "suspended due to pandemic", + "opening_hours": "Mo-Fr 16:00-18:50", + "operator": "Tideline", + "payment:cash": "no", + "payment:clipper": "no", + "payment:prepaid_ticket": "yes", + "public_transport:version": "2", + "roundtrip": "yes", + "to": "Berkeley Marina K-Dock", + "type": "route", + "vehicle": "no", + "via": "San Francisco Pier 52;San Francisco Pier 1\u00bd" + } + }, + { + "type": "relation", + "id": 9596728, + "members": [ + { "type": "node", "ref": 4644000640, "role": "stop" }, + { "type": "way", "ref": 740454500, "role": "platform" }, + { "type": "node", "ref": 4644000624, "role": "stop" }, + { "type": "way", "ref": 224658487, "role": "platform" }, + { "type": "node", "ref": 6479662757, "role": "stop" }, + { "type": "way", "ref": 27369597, "role": "platform" }, + { "type": "node", "ref": 4644000640, "role": "stop" }, + { "type": "way", "ref": 740454500, "role": "platform" }, + { "type": "way", "ref": 470184134, "role": "" }, + { "type": "way", "ref": 690605722, "role": "" }, + { "type": "way", "ref": 690605723, "role": "" } + ], + "tags": { + "bicycle": "yes", + "disused:route": "ferry", + "fee": "yes", + "foot": "yes", + "from": "Berkeley Marina K-Dock", + "name": "Tideline: Berkeley => San Francisco => Berkeley (mornings)", + "network": "Tideline", + "note": "suspended due to pandemic", + "opening_hours": "Mo-Fr 06:30-09:20", + "operator": "Tideline", + "payment:cash": "no", + "payment:clipper": "no", + "payment:prepaid_ticket": "yes", + "public_transport:version": "2", + "roundtrip": "yes", + "to": "Berkeley Marina K-Dock", + "type": "route", + "vehicle": "no", + "via": "San Francisco Pier 1\u00bd;San Francisco Pier 52" + } + } + ] +} diff --git a/tests/example_singlenode.json b/tests/example_singlenode.json new file mode 100644 index 0000000000..d770c3034d --- /dev/null +++ b/tests/example_singlenode.json @@ -0,0 +1,1178 @@ +{ + "version": 0.6, + "generator": "Overpass API 0.7.58.5 b0c4acbb", + "osm3s": { + "timestamp_osm_base": "2022-07-26T00:41:24Z", + "timestamp_areas_base": "2022-07-20T10:48:09Z", + "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." + }, + "elements": [ + { + "type": "node", + "id": 830609255, + "lat": -15.7526149, + "lon": -47.8900512, + "tags": { + "amenity": "cafe", + "name": "Caf\u00e9 Sincera", + "smoking": "no" + } + }, + { + "type": "node", + "id": 1532856975, + "lat": -15.7600089, + "lon": -47.8791123, + "tags": { + "addr:street": "CLN 408", + "amenity": "cafe", + "name": "Senhoritas" + } + }, + { + "type": "node", + "id": 2691239509, + "lat": -15.8268, + "lon": -47.90628, + "tags": { + "addr:place": "Asa Sul", + "addr:street": "Cls 410", + "amenity": "cafe", + "cuisine": "pizza", + "name": "Gentil" + } + }, + { + "type": "node", + "id": 3051977281, + "lat": -15.7567262, + "lon": -47.8913837, + "tags": { + "amenity": "cafe", + "internet_access": "no", + "name": "Amor \u00e0 Torta", + "opening_hours": "Mo-Fr 07:30-19:30; Sa 08:00-18:00", + "wheelchair": "yes" + } + }, + { + "type": "node", + "id": 3089963930, + "lat": -15.786985, + "lon": -47.886423, + "tags": { "amenity": "cafe", "name": "Cafezinho Express" } + }, + { + "type": "node", + "id": 3093838425, + "lat": -15.7770943, + "lon": -47.878313, + "tags": { + "addr:street": "CLN 204", + "amenity": "cafe", + "name": "Candy House", + "wheelchair": "yes" + } + }, + { + "type": "node", + "id": 3093842234, + "lat": -15.7575012, + "lon": -47.8825355, + "tags": { + "amenity": "cafe", + "brand": "Fran's Caf\u00e9", + "brand:wikidata": "Q62075645", + "cuisine": "coffee_shop", + "internet_access": "wlan", + "internet_access:fee": "no", + "name": "Fran's Caf\u00e9", + "opening_hours": "24/7", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 3095008557, + "lat": -15.7665684, + "lon": -47.8779077, + "tags": { "addr:street": "CLN 406", "amenity": "cafe", "name": "Sebinho" } + }, + { + "type": "node", + "id": 3139274344, + "lat": -15.8145074, + "lon": -47.8388265, + "tags": { "amenity": "cafe" } + }, + { + "type": "node", + "id": 3161293041, + "lat": -15.7749509, + "lon": -47.8908733, + "tags": { "amenity": "cafe", "name": "Caf\u00e9 Cobog\u00f3" } + }, + { + "type": "node", + "id": 3190786485, + "lat": -15.7461875, + "lon": -47.892084, + "tags": { "amenity": "cafe", "name": "Moebius Caf\u00e9" } + }, + { + "type": "node", + "id": 3192140335, + "lat": -15.7661003, + "lon": -47.877285, + "tags": { + "addr:street": "CLN 407", + "amenity": "cafe", + "name": "Cafezinho" + } + }, + { + "type": "node", + "id": 3200216679, + "lat": -15.7470931, + "lon": -47.8836644, + "tags": { + "addr:street": "CLN 413", + "amenity": "cafe", + "internet_access": "wlan", + "level": "0", + "name": "Clandestino", + "opening_hours": "Mo 09:00-21:00; We-Sa 09:00-21:00; Su 09:00-15:00", + "outdoor_seating": "yes", + "smoking": "no", + "website": "http://www.cafeclandestino.com.br" + } + }, + { + "type": "node", + "id": 3211680213, + "lat": -15.74597, + "lon": -47.8913941, + "tags": { "amenity": "cafe", "name": "Genaro - jazz burger caf\u00e9" } + }, + { + "type": "node", + "id": 3222516874, + "lat": -15.7806286, + "lon": -47.8860998, + "tags": { + "addr:place": "CLN 303", + "amenity": "cafe", + "internet_access": "wlan", + "internet_access:fee": "no", + "name": "Caramella", + "opening_hours": "Mo-Su 07:30-21:00", + "smoking": "no", + "website": "http://www.caramellaconfeitaria.com.br/", + "wheelchair": "yes" + } + }, + { + "type": "node", + "id": 3222516875, + "lat": -15.7805371, + "lon": -47.8847823, + "tags": { + "addr:place": "CLN 303", + "amenity": "cafe", + "internet_access": "wlan", + "name": "Martinica Caf\u00e9", + "opening_hours": "Mo-Fr 11:00-01:00; Sa 17:00-01:00; Su 18:00-01:00", + "phone": "+55 61 33262357" + } + }, + { + "type": "node", + "id": 3223614838, + "lat": -15.7451711, + "lon": -47.8870925, + "tags": { "amenity": "cafe", "name": "Torteria di Lorenza" } + }, + { + "type": "node", + "id": 3230418026, + "lat": -15.7832184, + "lon": -47.8829046, + "tags": { + "addr:city": "Bras\u00edlia", + "addr:housenumber": "Loja 56", + "addr:postcode": "70722-520", + "addr:street": "CLN 102 Bloco B", + "addr:suburb": "Asa Norte", + "amenity": "cafe", + "internet_access": "wlan", + "name": "Objeto Encontrado", + "opening_hours": "Mo-Sa 12:00-23:00", + "phone": "+55 61 3081-8383", + "smoking": "no", + "website": "https://www.objetoencontrado.com.br/" + } + }, + { + "type": "node", + "id": 3231952883, + "lat": -15.7770016, + "lon": -47.8827129, + "tags": { + "amenity": "cafe", + "cuisine": "french", + "name": "Daniel Briand", + "opening_hours": "Tu-Fr 09:00-22:00; Sa 09:30-22:00; Su 08:00-22:00", + "phone": "+55 61 33261135", + "website": "https://www.cafedanielbriand.com/" + } + }, + { + "type": "node", + "id": 3324092861, + "lat": -15.756386, + "lon": -47.8903219, + "tags": { + "amenity": "cafe", + "internet_access": "wlan", + "name": "D'Vilella", + "wheelchair": "yes" + } + }, + { + "type": "node", + "id": 3334254945, + "lat": -15.7454249, + "lon": -47.8874166, + "tags": { + "amenity": "cafe", + "diet:vegan": "only", + "name": "Canelle Confeitaria", + "opening_hours": "Tu-Sa 10:00-22:00;Su 12:00-20:00", + "phone": "+55 61 30372422" + } + }, + { + "type": "node", + "id": 3334254946, + "lat": -15.7403494, + "lon": -47.8929929, + "tags": { + "amenity": "cafe", + "name": "Florisa Caf\u00e9", + "opening_hours": "Mo-Sa 08:00-21:00", + "phone": "+55 61 32028882" + } + }, + { + "type": "node", + "id": 3358345330, + "lat": -15.7833159, + "lon": -47.8785943, + "tags": { + "addr:city": "Brasilia", + "addr:street": "CLN 202 Bloco A", + "addr:suburb": "Asa Norte", + "amenity": "cafe", + "internet_access": "wlan", + "name": "Caf\u00e9 Cristina Colina da Pedra", + "opening_hours": "Su 12:00-19:00; Mo-Sa 08:00-19:00" + } + }, + { + "type": "node", + "id": 3362305606, + "lat": -15.7804074, + "lon": -47.8851897, + "tags": { + "amenity": "cafe", + "diet:gluten_free": "yes", + "diet:vegan": "yes", + "name": "Bioon Caf\u00e9" + } + }, + { + "type": "node", + "id": 3362308337, + "lat": -15.7809705, + "lon": -47.8862323, + "tags": { + "amenity": "cafe", + "cuisine": "arab", + "name": "Caf\u00e9 com Caf\u00e9" + } + }, + { + "type": "node", + "id": 3364780124, + "lat": -15.8278397, + "lon": -47.9225416, + "tags": { "amenity": "cafe", "name": "Dylan Cafe Bakery" } + }, + { + "type": "node", + "id": 3451223465, + "lat": -15.7530174, + "lon": -47.889783, + "tags": { + "addr:street": "CLN 111", + "amenity": "cafe", + "cuisine": "coffee_shop", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Concreto Coffee Crew", + "opening_hours": "Mo-Sa 13:00-20:00", + "outdoor_seating": "yes", + "website": "https://www.instagram.com/concretocoffee/" + } + }, + { + "type": "node", + "id": 3451247095, + "lat": -15.75974, + "lon": -47.8805597, + "tags": { "amenity": "cafe", "name": "Vincent Ch\u00e1s e Caf\u00e9s" } + }, + { + "type": "node", + "id": 3525964203, + "lat": -15.7649188, + "lon": -47.8701905, + "tags": { + "amenity": "cafe", + "name": "Caf\u00e9 das Letras", + "wheelchair": "yes" + } + }, + { + "type": "node", + "id": 3634570440, + "lat": -15.8044722, + "lon": -47.8852709, + "tags": { "amenity": "cafe", "name": "Rappot" } + }, + { + "type": "node", + "id": 3634570442, + "lat": -15.80452, + "lon": -47.8851878, + "tags": { "amenity": "cafe", "name": "Caf\u00e9 do Ponto" } + }, + { + "type": "node", + "id": 3634570451, + "lat": -15.8048503, + "lon": -47.8846875, + "tags": { + "amenity": "cafe", + "name": "Cristina Caf\u00e9s", + "website": "http://cafecristina.com.br" + } + }, + { + "type": "node", + "id": 3645307602, + "lat": -15.7626851, + "lon": -47.8896497, + "tags": { + "amenity": "cafe", + "name": "Caf\u00e9 Bem Casado", + "opening_hours": "Mo-Sa 09:00-19:30", + "website": "http://cafebemcasado.com.br" + } + }, + { + "type": "node", + "id": 3768730374, + "lat": -15.7831717, + "lon": -47.8834145, + "tags": { "amenity": "cafe", "name": "Rosa's Caf\u00e9" } + }, + { + "type": "node", + "id": 3900700774, + "lat": -15.7608557, + "lon": -47.8916129, + "tags": { "amenity": "cafe", "name": "Gr\u00e3o Sabor" } + }, + { + "type": "node", + "id": 3958863453, + "lat": -15.7877449, + "lon": -47.8826614, + "tags": { "amenity": "cafe", "name": "Art Caf\u00e9" } + }, + { + "type": "node", + "id": 3958863455, + "lat": -15.7871193, + "lon": -47.8828056, + "tags": { + "amenity": "cafe", + "name": "Tomilla Caf\u00e9", + "wheelchair": "yes" + } + }, + { + "type": "node", + "id": 3971324159, + "lat": -15.7873255, + "lon": -47.8828911, + "tags": { "amenity": "cafe", "name": "Especiarias de Minas" } + }, + { + "type": "node", + "id": 3971325069, + "lat": -15.783933, + "lon": -47.8848583, + "tags": { + "amenity": "cafe", + "brand": "Fran's Caf\u00e9", + "brand:wikidata": "Q62075645", + "cuisine": "coffee_shop", + "name": "Fran's Caf\u00e9", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 3973507957, + "lat": -15.7812333, + "lon": -47.8881001, + "tags": { "amenity": "cafe", "name": "C\u00f3pia com Caf\u00e9" } + }, + { + "type": "node", + "id": 4081269529, + "lat": -15.773612, + "lon": -47.876547, + "tags": { + "addr:city": "Bras\u00edlia", + "addr:street": "CLN 404", + "addr:suburb": "Asa Norte", + "amenity": "cafe", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Los Baristas", + "opening_hours": "Mo-Fr 12:00-20:00; Sa 10:00-19:00", + "outdoor_seating": "yes", + "smoking": "no", + "website": "https://www.losbaristas.com/" + } + }, + { + "type": "node", + "id": 4081269533, + "lat": -15.790137, + "lon": -47.8849886, + "tags": { "amenity": "cafe", "name": "Chateau Brasil" } + }, + { + "type": "node", + "id": 4119072799, + "lat": -15.7470135, + "lon": -47.8835617, + "tags": { + "amenity": "cafe", + "level": "1", + "name": "Quintal f/508", + "opening_hours": "Mo-Fr 15:30-20:30; Sa 09:00-12:00", + "outdoor_seating": "no", + "phone": "+55 61 33473985;+55 61 91400303", + "website": "https://f508.com.br/quintal/" + } + }, + { + "type": "node", + "id": 4156321058, + "lat": -15.7770087, + "lon": -47.8840073, + "tags": { + "amenity": "cafe", + "name": "Chico Mineiro Confeitaria e Caf\u00e9" + } + }, + { + "type": "node", + "id": 4187993132, + "lat": -15.7746238, + "lon": -47.8856309, + "tags": { + "amenity": "cafe", + "name": "Caf\u00e9 Sarah Kubitscheck", + "opening_hours": "Mo-Fr 09:00-20:00; Sa 08:00-17:00", + "phone": "+55 61 39637373" + } + }, + { + "type": "node", + "id": 4207805094, + "lat": -15.763683, + "lon": -47.881545, + "tags": { "amenity": "cafe", "name": "Caf\u00e9 da V\u00f3 Maria" } + }, + { + "type": "node", + "id": 4330783337, + "lat": -15.8192743, + "lon": -47.8998423, + "tags": { "amenity": "cafe", "name": "Magrelas Caf\u00e9" } + }, + { + "type": "node", + "id": 4433154149, + "lat": -15.8097643, + "lon": -47.9078076, + "tags": { "amenity": "cafe", "cuisine": "french", "name": "Le Jardin" } + }, + { + "type": "node", + "id": 4471601993, + "lat": -15.8307026, + "lon": -47.9242343, + "tags": { + "amenity": "cafe", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Ernesto Caf\u00e9s Especiais", + "name:pt": "Ernesto Caf\u00e9s Especiais", + "opening_hours": "Mo-Su 07:00-22:00", + "outdoor_seating": "yes", + "smoking": "no" + } + }, + { + "type": "node", + "id": 4558361197, + "lat": -15.7355928, + "lon": -47.8972574, + "tags": { + "amenity": "cafe", + "name": "Rei do Mate", + "name:pt": "Rei do Mate" + } + }, + { + "type": "node", + "id": 4558399090, + "lat": -15.7390367, + "lon": -47.8892686, + "tags": { + "amenity": "cafe", + "name": "Croissanterie caf\u00e9 | bistr\u00f4" + } + }, + { + "type": "node", + "id": 4585501235, + "lat": -15.786565, + "lon": -47.8888328, + "tags": { + "amenity": "cafe", + "brand": "Fran's Caf\u00e9", + "brand:wikidata": "Q62075645", + "cuisine": "coffee_shop", + "name": "Fran's Caf\u00e9", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 4585501236, + "lat": -15.7866114, + "lon": -47.8890018, + "tags": { "amenity": "cafe", "name": "Martinica" } + }, + { + "type": "node", + "id": 4585529781, + "lat": -15.7871869, + "lon": -47.8840682, + "tags": { "amenity": "cafe", "level": "1", "name": "Grande Caf\u00e9" } + }, + { + "type": "node", + "id": 4591337312, + "lat": -15.7501975, + "lon": -47.8933428, + "tags": { "amenity": "cafe", "name": "Rei do P\u00e3o de Queijo" } + }, + { + "type": "node", + "id": 4591337315, + "lat": -15.7499358, + "lon": -47.8931995, + "tags": { "amenity": "cafe", "name": "Iaga Arte Caf\u00e9" } + }, + { + "type": "node", + "id": 4608731433, + "lat": -15.7868298, + "lon": -47.88463, + "tags": { "amenity": "cafe", "level": "0", "name": "Cr\u00e9pe de Paris" } + }, + { + "type": "node", + "id": 4693815344, + "lat": -15.7334022, + "lon": -47.8996803, + "tags": { "amenity": "cafe", "name": "Kopenhagen" } + }, + { + "type": "node", + "id": 4825889842, + "lat": -15.7337708, + "lon": -47.8987679, + "tags": { + "amenity": "cafe", + "level": "0", + "name": "Casa do P\u00e3o de Queijo" + } + }, + { + "type": "node", + "id": 4897810422, + "lat": -15.759575, + "lon": -47.8785977, + "tags": { + "amenity": "cafe", + "cuisine": "arab", + "name": "Snob", + "name:pt": "Snob" + } + }, + { + "type": "node", + "id": 4908113823, + "lat": -15.7526495, + "lon": -47.8891559, + "tags": { "amenity": "cafe", "cuisine": "chocolate", "name": "Lugano" } + }, + { + "type": "node", + "id": 4908141129, + "lat": -15.7906235, + "lon": -47.8831845, + "tags": { "amenity": "cafe", "level": "2", "name": "Gaudi Caf\u00e9" } + }, + { + "type": "node", + "id": 4957238257, + "lat": -15.7591758, + "lon": -47.8877238, + "tags": { + "amenity": "cafe", + "cuisine": "nordestina", + "name": "Caf\u00e9 e um Ch\u00earo", + "opening_hours": "Mo-Sa 07:00-22:00", + "website": "http://www.cafeeumchero.com.br" + } + }, + { + "type": "node", + "id": 5029115521, + "lat": -15.780834, + "lon": -47.889139, + "tags": { + "amenity": "cafe", + "name": "Oficina Caf\u00e9", + "name:pt": "Oficina Caf\u00e9" + } + }, + { + "type": "node", + "id": 5087302622, + "lat": -15.7452496, + "lon": -47.8866603, + "tags": { + "amenity": "cafe", + "level": "-1", + "name": "Labbora Caf\u00e9s Especiais", + "opening_hours": "Mo-Fr 10:00-19:00" + } + }, + { + "type": "node", + "id": 5087302722, + "lat": -15.7446725, + "lon": -47.8870871, + "tags": { + "amenity": "cafe", + "cuisine": "hungarian", + "name": "Duna Casa H\u00fangara", + "name:pt": "Duna Casa H\u00fangara" + } + }, + { + "type": "node", + "id": 5124575930, + "lat": -15.7962238, + "lon": -47.8927946, + "tags": { + "amenity": "cafe", + "internet_access": "wlan", + "name": "Caf\u00e9 Civit\u00e1", + "name:pt": "Caf\u00e9 Civit\u00e1" + } + }, + { + "type": "node", + "id": 5125114322, + "lat": -15.7953783, + "lon": -47.8924834, + "tags": { + "amenity": "cafe", + "brand": "Fran's Caf\u00e9", + "brand:wikidata": "Q62075645", + "cuisine": "coffee_shop", + "name": "Fran's Caf\u00e9", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 5135659820, + "lat": -15.7686257, + "lon": -47.8743398, + "tags": { "amenity": "cafe" } + }, + { + "type": "node", + "id": 5225539396, + "lat": -15.8028809, + "lon": -47.8931241, + "tags": { "amenity": "cafe", "name": "Nosso Quadrado" } + }, + { + "type": "node", + "id": 5230076441, + "lat": -15.8103402, + "lon": -47.9100841, + "tags": { + "amenity": "cafe", + "brand": "Fran's Caf\u00e9", + "brand:wikidata": "Q62075645", + "cuisine": "coffee_shop", + "name": "Fran's Caf\u00e9", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 5299457845, + "lat": -15.8195535, + "lon": -47.9121922, + "tags": { "amenity": "cafe", "name": "Uai Bezinha!" } + }, + { + "type": "node", + "id": 5353491828, + "lat": -15.8184198, + "lon": -47.8749357, + "tags": { "amenity": "cafe", "name": "Gr\u00e3o Espresso" } + }, + { + "type": "node", + "id": 5366399095, + "lat": -15.7514698, + "lon": -47.8846808, + "tags": { + "amenity": "cafe", + "internet_access": "wlan", + "name": "Garden Caf\u00e9", + "opening_hours": "Mo-Fr 08:30-20:00; Sa 10:00-18:00" + } + }, + { + "type": "node", + "id": 5381047922, + "lat": -15.8136655, + "lon": -47.9130762, + "tags": { "amenity": "cafe", "name": "Da Vici Cafeteria" } + }, + { + "type": "node", + "id": 5416977721, + "lat": -15.7902403, + "lon": -47.8846678, + "tags": { + "addr:street": "SHN Quadra 1", + "amenity": "cafe", + "name": "Melbourne Caf\u00e9 & Co.", + "opening_hours": "Mo-Fr 08:15-17:30", + "outdoor_seating": "yes", + "website": "http://www.olamelbourne.com.br/" + } + }, + { + "type": "node", + "id": 5436122015, + "lat": -15.8273745, + "lon": -47.9187069, + "tags": { + "addr:city": "Bras\u00edlia", + "addr:housenumber": "Loja 07", + "addr:street": "CLS 114 Bloco B", + "amenity": "cafe", + "internet_access": "wlan", + "internet_access:fee": "no", + "name": "Belini Caf\u00e9", + "opening_hours": "Mo-Sa 08:00-23:00; Su 08:00-22:00", + "outdoor_seating": "yes", + "payment:cash": "yes", + "payment:credit_cards": "yes", + "smoking": "no", + "website": "https://pt-br.facebook.com/pg/belinicafe/about/?ref=page_internal" + } + }, + { + "type": "node", + "id": 5470850733, + "lat": -15.7526191, + "lon": -47.8900604, + "tags": { "amenity": "cafe", "name": "Sincera" } + }, + { + "type": "node", + "id": 5650571821, + "lat": -15.8263217, + "lon": -47.906648, + "tags": { + "addr:housenumber": "Bloco A Loja 13", + "addr:street": "SQS 410", + "amenity": "cafe", + "cuisine": "cake;coffee_shop", + "email": "contato@cioccolateria.com.br", + "internet_access": "wlan", + "name": "Cioccolateria Doceria e Caf\u00e9", + "opening_hours": "Mo-Fr 10:00-19:00; Sa 09:00-17:00", + "phone": "+55 61 3242 6399", + "website": "http://www.cioccolateria.com.br" + } + }, + { + "type": "node", + "id": 5766574433, + "lat": -15.7775553, + "lon": -47.8826493, + "tags": { + "addr:city": "Bras\u00edlia", + "addr:street": "CLN 103/104", + "amenity": "cafe", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Quanto", + "opening_hours": "Mo-Fr 11:00-21:00, Sa 09:00-21:00", + "outdoor_seating": "yes", + "smoking": "no" + } + }, + { + "type": "node", + "id": 5856741812, + "lat": -15.7398592, + "lon": -47.8994946, + "tags": { + "addr:street": "CLRN 716", + "amenity": "cafe", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Antonieta", + "outdoor_seating": "yes", + "shop": "tea", + "smoking": "no", + "website": "https://www.instagram.com/antonietacafe" + } + }, + { + "type": "node", + "id": 5856750259, + "lat": -15.7398134, + "lon": -47.89356, + "tags": { + "addr:city": "Bras\u00edlia", + "addr:housenumber": "Loja 46", + "addr:street": "SCLN 116 Bloco B", + "addr:suburb": "Plano Piloto", + "amenity": "cafe", + "name": "Salve Caf\u00e9 Maravilha", + "opening_hours": "Mo-Fr 14:00-20:30; Sa 14:300-20:30; Su 09:30-12:30", + "payment:cash": "yes", + "payment:credit_cards": "yes", + "payment:debit_cards": "yes", + "website": "https://www.facebook.com/salvecafemaravilha/" + } + }, + { + "type": "node", + "id": 6005691723, + "lat": -15.7645578, + "lon": -47.8852493, + "tags": { + "addr:street": "CLN 107/108", + "amenity": "cafe", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Ernesto Caf\u00e9s Especiais", + "opening_hours": "Mo-Su 07:00-22:00", + "outdoor_seating": "yes", + "smoking": "no" + } + }, + { + "type": "node", + "id": 6207544093, + "lat": -15.7712064, + "lon": -47.8712547, + "tags": { + "amenity": "cafe", + "cuisine": "sandwiches", + "internet_access": "no", + "internet_access:fee": "no", + "name": "Caf\u00e9 da Fiocruz", + "outdoor_seating": "no", + "smoking": "no", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 6456239248, + "lat": -15.8148373, + "lon": -47.9071188, + "tags": { "amenity": "cafe", "name": "Maria Aur\u00e9lia" } + }, + { + "type": "node", + "id": 6456386661, + "lat": -15.8151596, + "lon": -47.8938988, + "tags": { + "amenity": "cafe", + "brand": "Fran's Caf\u00e9", + "brand:wikidata": "Q62075645", + "cuisine": "coffee_shop", + "name": "Fran's Caf\u00e9", + "outdoor_seating": "yes", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 6591961959, + "lat": -15.7808206, + "lon": -47.8900077, + "tags": { "amenity": "cafe", "name": "Sterna Caf\u00e9" } + }, + { + "type": "node", + "id": 6632677485, + "lat": -15.7708562, + "lon": -47.8845249, + "tags": { + "addr:postcode": "70742-530", + "addr:street": "SQN 106 Bloco A", + "amenity": "cafe", + "name": "QualyCream", + "opening_hours": "Mo-Fr 08:00-18:00; Sa 09:00-13:00", + "phone": "+55 61 3033 1010", + "website": "http://qualycream.com.br" + } + }, + { + "type": "node", + "id": 7705116886, + "lat": -15.8256478, + "lon": -47.9289296, + "tags": { "amenity": "cafe" } + }, + { + "type": "node", + "id": 7705116908, + "lat": -15.8268004, + "lon": -47.9294188, + "tags": { "amenity": "cafe" } + }, + { + "type": "node", + "id": 7949383205, + "lat": -15.7518287, + "lon": -47.8975325, + "tags": { + "addr:city": "Bras\u00edlia", + "addr:street": "SCRN 712/713, bloco E", + "amenity": "cafe", + "name": "Amarelinha" + } + }, + { + "type": "node", + "id": 8223909098, + "lat": -15.7406194, + "lon": -47.8992532, + "tags": { + "addr:street": "CLRN 716", + "amenity": "cafe", + "cuisine": "coffee_shop;regional", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Marilda Caf\u00e9", + "opening_hours": "Tu-Fr 12:00-20:00; Sa-Su 09:00-20:00", + "outdoor_seating": "yes", + "payment:cash": "yes", + "payment:credit_cards": "yes", + "phone": "+55 61 2194 7902", + "website": "https://www.instagram.com/marilda_cafe" + } + }, + { + "type": "node", + "id": 8435477631, + "lat": -15.8152087, + "lon": -47.902979, + "tags": { + "addr:housenumber": "Bloco D Loja x", + "addr:street": "CLS 108", + "amenity": "cafe", + "name": "Lugano" + } + }, + { + "type": "node", + "id": 9106354157, + "lat": -15.8015199, + "lon": -47.896786, + "tags": { + "addr:city": "distrito federal", + "addr:housenumber": "36", + "addr:postcode": "70331710", + "addr:street": "SHIGS Quadra 703, bloco J;SHIGS Quadra 703, Bloco J", + "addr:suburb": "asa sul", + "amenity": "cafe", + "cuisine": "cake;cafetaria", + "name": "Rafaela Brand\u00e3o Doceria;Senhorita Brigadeiro" + } + }, + { + "type": "node", + "id": 9223636892, + "lat": -15.7728741, + "lon": -47.8760889, + "tags": { + "addr:street": "CLN 405", + "amenity": "cafe", + "cuisine": "coffee_shop;regional", + "name": "Maytrea Caf\u00e9 do Cerrado", + "opening_hours": "Tu-Fr 14:00-19:00; Sa 11:00-15:00", + "outdoor_seating": "yes", + "website": "https://www.instagram.com/maytreacerrado/" + } + }, + { + "type": "node", + "id": 9223668163, + "lat": -15.7598622, + "lon": -47.8802586, + "tags": { + "addr:street": "CLN 409", + "amenity": "cafe", + "cuisine": "coffee_shop", + "name": "The Coffee", + "opening_hours": "Mo-Fr 07:30-20:00; sa-su 08:00-20:00", + "outdoor_seating": "yes", + "website": "https://www.thecoffee.jp/" + } + }, + { + "type": "node", + "id": 9321058495, + "lat": -15.7634914, + "lon": -47.8926958, + "tags": { + "addr:street": "CRN 708/709 G", + "amenity": "cafe", + "cuisine": "coffee_shop", + "internet_access": "yes", + "internet_access:fee": "no", + "name": "Aha", + "opening_hours": "We-Su 11:00-18:00", + "website": "https://www.ahacafes.com.br/" + } + }, + { + "type": "node", + "id": 9364462024, + "lat": -15.7611957, + "lon": -47.8926411, + "tags": { "amenity": "cafe", "name": "Civita" } + }, + { + "type": "node", + "id": 9559046117, + "lat": -15.8066905, + "lon": -47.893681, + "tags": { + "amenity": "cafe", + "name": "Duckbill Cookies & Coffee", + "survey:date": "2022-03-06" + } + }, + { + "type": "node", + "id": 9559046118, + "lat": -15.8069382, + "lon": -47.8933825, + "tags": { + "amenity": "cafe", + "name": "Caf\u00e9 da Mata", + "survey:date": "2022-03-06" + } + }, + { + "type": "node", + "id": 9563487746, + "lat": -15.7950461, + "lon": -47.8924062, + "tags": { + "amenity": "cafe", + "brand": "Starbucks", + "brand:wikidata": "Q37158", + "brand:wikipedia": "en:Starbucks", + "cuisine": "coffee_shop", + "name": "Starbucks", + "official_name": "Starbucks Coffee", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 9577464680, + "lat": -15.79097, + "lon": -47.8829693, + "tags": { + "amenity": "cafe", + "brand": "Starbucks", + "brand:wikidata": "Q37158", + "brand:wikipedia": "en:Starbucks", + "cuisine": "coffee_shop", + "name": "Starbucks", + "official_name": "Starbucks Coffee", + "takeaway": "yes" + } + }, + { + "type": "node", + "id": 9858565892, + "lat": -15.7373599, + "lon": -47.8951192, + "tags": { + "addr:street": "SCLN 116 Bloco I", + "air_conditioning": "no", + "amenity": "cafe", + "cuisine": "regional", + "level": "0", + "name": "Ponto Do Caf\u00e9 116", + "outdoor_seating": "yes" + } + } + ] +} diff --git a/tests/test_api.py b/tests/test_api.py index d3603a1606..95c9c09122 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -8,6 +8,7 @@ from datetime import datetime, timezone from distutils.util import strtobool from pathlib import Path +from typing import Tuple, Union import geojson import overpass @@ -23,18 +24,34 @@ def test_initialize_api(): @pytest.mark.parametrize( - "query,length", + "query,length,response", [ - (overpass.MapQuery(37.86517, -122.31851, 37.86687, -122.31635), 1), - ("node(area:3602758138)[amenity=cafe]", 1) + ( + overpass.MapQuery(37.86517, -122.31851, 37.86687, -122.31635), + 1, + Path("tests/example_mapquery.json") + ), + ( + "node(area:3602758138)[amenity=cafe]", + 1, + Path("tests/example_singlenode.json") + ) ] ) def test_geojson( - query, - length + query: Union[overpass.MapQuery, str], + length: int, + response: Path, + requests_mock ): api = overpass.API(debug=True) + with response.open() as fp: + mock_response = json.load(fp) + requests_mock.post( + "//overpass-api.de/api/interpreter", json=mock_response + ) + osm_geo = api.get(query) assert len(osm_geo["features"]) > length @@ -90,19 +107,19 @@ def test_geojson_live(): "response,slots_available,slots_running,slots_waiting", [ ( - "tests/overpass_status/no_slots_waiting_six_lines.txt", + Path("tests/overpass_status/no_slots_waiting_six_lines.txt"), 2, (), () ), ( - "tests/overpass_status/no_slots_waiting.txt", + Path("tests/overpass_status/no_slots_waiting.txt"), 2, (), () ), ( - "tests/overpass_status/one_slot_running.txt", + Path("tests/overpass_status/one_slot_running.txt"), 1, ( datetime( @@ -118,7 +135,7 @@ def test_geojson_live(): () ), ( - "tests/overpass_status/one_slot_waiting.txt", + Path("tests/overpass_status/one_slot_waiting.txt"), 1, (), ( @@ -134,7 +151,7 @@ def test_geojson_live(): ) ), ( - "tests/overpass_status/two_slots_waiting.txt", + Path("tests/overpass_status/two_slots_waiting.txt"), 0, (), ( @@ -160,9 +177,8 @@ def test_geojson_live(): ), ] ) -def test_api_status(response, slots_available, slots_running, slots_waiting, requests_mock): - with open(response) as fp: - mock_response = fp.read() +def test_api_status(response: Path, slots_available: int, slots_running: Tuple[datetime], slots_waiting: Tuple[datetime], requests_mock): + mock_response = response.read_text() requests_mock.get("https://overpass-api.de/api/status", text=mock_response) api = overpass.API(debug=True) @@ -181,3 +197,8 @@ def test_api_status(response, slots_available, slots_running, slots_waiting, req assert isinstance(api.slots_waiting, tuple) assert api.slots_waiting == slots_waiting + + assert isinstance(api.slot_available_countdown, int) + assert api.slot_available_countdown >= 0 + + assert api.slot_available_datetime is None or isinstance(api.slot_available_datetime, datetime)