Mark Joshwel
a9e26c8916
i hate GIS - geocoders now have to return a bounding box - new SHAREABLE_TEXT_LOCALITY constant, also exposed - _generate_text now does double duty for locality and sharetext generation
727 lines
26 KiB
Plaintext
727 lines
26 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# surplus 2.x.y playground notebook\n",
|
|
"\n",
|
|
"wrangling with environments for devbox users using codium/vs code:\n",
|
|
"\n",
|
|
"```text\n",
|
|
"$ devbox shell # enter devbox env\n",
|
|
"(surplus-py3.11) (devbox) $ exit # leave poetry env\n",
|
|
"(devbox) $ codium . # open ide\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"OUTPUT_LINE_X_KEYS: Final[tuple[str, ...]] = (\"region\",\"county\",\"state\",\"state_district\",\"country\",\"continent\",)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# converting nominatim keys to OUTPUT_LINE_X_KEYS format\n",
|
|
"\n",
|
|
"keys = \"\"\"\n",
|
|
"region, county, state, state_district, country, continent\n",
|
|
"\"\"\"\n",
|
|
"\n",
|
|
"split_keys = [f'\"{key.strip()}\"' for key in keys.strip().split(\",\")]\n",
|
|
"\n",
|
|
"print(f\"OUTPUT_LINE_X_KEYS: Final[tuple[str, ...]] = ({','.join(split_keys)},)\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from surplus import PlusCodeQuery, LocalCodeQuery, LatlongQuery, StringQuery\n",
|
|
"from surplus import Latlong, Result\n",
|
|
"from surplus import SurplusDefaultGeocoding\n",
|
|
"\n",
|
|
"geocoding = SurplusDefaultGeocoding()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Generic Result NamedTuple"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"True\tNone \t3\n",
|
|
"False\tZeroDivisionError('division by zero') \tdivision by zero (ZeroDivisionError)\n"
|
|
]
|
|
},
|
|
{
|
|
"ename": "ZeroDivisionError",
|
|
"evalue": "division by zero",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m/home/m/works/surplus/playground.ipynb Cell 5\u001b[0m in \u001b[0;36m<cell line: 0>\u001b[0;34m()\u001b[0m\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=7'>8</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m{:<40}\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m{}\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mformat(\u001b[39mbool\u001b[39m(nom_result), \u001b[39mrepr\u001b[39m(nom_result\u001b[39m.\u001b[39merror), nom_result\u001b[39m.\u001b[39mget()))\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=8'>9</a>\u001b[0m \u001b[39mprint\u001b[39m(\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=9'>10</a>\u001b[0m \u001b[39m\"\u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m{:<40}\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m{}\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mformat(\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=10'>11</a>\u001b[0m \u001b[39mbool\u001b[39m(exc_result), \u001b[39mrepr\u001b[39m(exc_result\u001b[39m.\u001b[39merror), exc_result\u001b[39m.\u001b[39mcry(string\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m)\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=11'>12</a>\u001b[0m )\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=12'>13</a>\u001b[0m )\n\u001b[0;32m---> <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=13'>14</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m{:<40}\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m{}\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mformat(\u001b[39mbool\u001b[39m(exc_result), \u001b[39mrepr\u001b[39m(exc_result\u001b[39m.\u001b[39merror), exc_result\u001b[39m.\u001b[39;49mget()))\n",
|
|
"File \u001b[0;32m~/works/surplus/surplus/surplus.py:270\u001b[0m, in \u001b[0;36mResult.get\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 268\u001b[0m \u001b[39m\"\"\"method that returns self.value if Result is non-erroneous else raises error\"\"\"\u001b[39;00m\n\u001b[1;32m 269\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39merror, \u001b[39mBaseException\u001b[39;00m):\n\u001b[0;32m--> 270\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39merror\n\u001b[1;32m 271\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mvalue\n",
|
|
"\u001b[1;32m/home/m/works/surplus/playground.ipynb Cell 5\u001b[0m in \u001b[0;36m<cell line: 0>\u001b[0;34m()\u001b[0m\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=0'>1</a>\u001b[0m nom_result \u001b[39m=\u001b[39m Result[\u001b[39mint\u001b[39m](\u001b[39m3\u001b[39m)\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=2'>3</a>\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m----> <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=3'>4</a>\u001b[0m \u001b[39m1\u001b[39;49m \u001b[39m/\u001b[39;49m \u001b[39m0\u001b[39;49m\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=4'>5</a>\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m \u001b[39mas\u001b[39;00m exc:\n\u001b[1;32m <a href='vscode-notebook-cell://wsl%2Balpine/home/m/works/surplus/playground.ipynb#X26sdnNjb2RlLXJlbW90ZQ%3D%3D?line=5'>6</a>\u001b[0m exc_result \u001b[39m=\u001b[39m Result[\u001b[39mint\u001b[39m](\u001b[39m-\u001b[39m\u001b[39m1\u001b[39m, error\u001b[39m=\u001b[39mexc)\n",
|
|
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"nom_result = Result[int](3)\n",
|
|
"\n",
|
|
"try:\n",
|
|
" 1 / 0\n",
|
|
"except Exception as exc:\n",
|
|
" exc_result = Result[int](-1, error=exc)\n",
|
|
"\n",
|
|
"print(\"{}\\t{:<40}\\t{}\".format(bool(nom_result), repr(nom_result.error), nom_result.get()))\n",
|
|
"print(\n",
|
|
" \"{}\\t{:<40}\\t{}\".format(\n",
|
|
" bool(exc_result), repr(exc_result.error), exc_result.cry(string=True)\n",
|
|
" )\n",
|
|
")\n",
|
|
"print(\"{}\\t{:<40}\\t{}\".format(bool(exc_result), repr(exc_result.error), exc_result.get()))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Query Types"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Result(value=Latlong(latitude=1.3336875, longitude=103.7746875), error=None)"
|
|
]
|
|
},
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"PlusCodeQuery(code=\"6PH58QMF+FV\").to_lat_long_coord(geocoder=geocoding.geocoder)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Result(value=Latlong(latitude=1.3336875, longitude=103.7746875), error=None)"
|
|
]
|
|
},
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"plus_code = LocalCodeQuery(code=\"8QMF+FV\", locality=\"Singapore\").to_full_plus_code(\n",
|
|
" geocoder=geocoding.geocoder\n",
|
|
")\n",
|
|
"\n",
|
|
"PlusCodeQuery(code=plus_code.get()).to_lat_long_coord(geocoder=geocoding.geocoder)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Result(value=Latlong(latitude=1.3336875, longitude=103.7746875), error=None)"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"LocalCodeQuery(code=\"8QMF+FV\", locality=\"Singapore\").to_lat_long_coord(\n",
|
|
" geocoder=geocoding.geocoder\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Result(value=Latlong(latitude=1.33318835, longitude=103.77461234638255), error=None)"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"LatlongQuery(\n",
|
|
" latlong=Latlong(latitude=1.33318835, longitude=103.77461234638255)\n",
|
|
").to_lat_long_coord(geocoder=geocoding.geocoder)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Result(value=Latlong(latitude=1.33318835, longitude=103.77461234638255), error=None)"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"StringQuery(query=\"Ngee Ann Polytechnic\").to_lat_long_coord(geocoder=geocoding.geocoder)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## return dictionary of `reverser` function\n",
|
|
"\n",
|
|
"all the necessary keys (see `SHAREABLE_TEXT_LINE_*` constants) should be at the top-level of the dictionary.\n",
|
|
"these keys will be casted into strings for safety guarantee when shareable text lines are being generated.\n",
|
|
"\n",
|
|
"while not necessary, consider keeping the original response dict under the \"raw\" key.\n",
|
|
"helps with debugging using `-d/--debug`!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"reverser_return = {\n",
|
|
" \"amenity\": \"Ngee Ann Polytechnic\",\n",
|
|
" \"house_number\": \"535\",\n",
|
|
" \"road\": \"Clementi Road\",\n",
|
|
" \"suburb\": \"Bukit Timah\",\n",
|
|
" \"city\": \"Singapore\",\n",
|
|
" \"county\": \"Northwest\",\n",
|
|
" \"ISO3166-2-lvl6\": \"SG-03\",\n",
|
|
" \"postcode\": \"599489\",\n",
|
|
" \"country\": \"Singapore\",\n",
|
|
" \"country_code\": \"sg\",\n",
|
|
" \"raw\": {\n",
|
|
" \"place_id\": 297946059,\n",
|
|
" \"licence\": \"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright\",\n",
|
|
" \"osm_type\": \"relation\",\n",
|
|
" \"osm_id\": 2535118,\n",
|
|
" \"lat\": \"1.33318835\",\n",
|
|
" \"lon\": \"103.77461234638255\",\n",
|
|
" \"class\": \"amenity\",\n",
|
|
" \"type\": \"university\",\n",
|
|
" \"place_rank\": 30,\n",
|
|
" \"importance\": 0.34662169301918117,\n",
|
|
" \"addresstype\": \"amenity\",\n",
|
|
" \"name\": \"Ngee Ann Polytechnic\",\n",
|
|
" \"display_name\": \"Ngee Ann Polytechnic, 535, Clementi Road, Bukit Timah, Singapore, Northwest, 599489, Singapore\",\n",
|
|
" \"address\": {\n",
|
|
" \"amenity\": \"Ngee Ann Polytechnic\",\n",
|
|
" \"house_number\": \"535\",\n",
|
|
" \"road\": \"Clementi Road\",\n",
|
|
" \"suburb\": \"Bukit Timah\",\n",
|
|
" \"city\": \"Singapore\",\n",
|
|
" \"county\": \"Northwest\",\n",
|
|
" \"ISO3166-2-lvl6\": \"SG-03\",\n",
|
|
" \"postcode\": \"599489\",\n",
|
|
" \"country\": \"Singapore\",\n",
|
|
" \"country_code\": \"sg\",\n",
|
|
" },\n",
|
|
" \"boundingbox\": [\"1.3289692\", \"1.3372184\", \"103.7701481\", \"103.7783945\"],\n",
|
|
" },\n",
|
|
" \"latitude\": 1.33318835,\n",
|
|
" \"longitude\": 103.77461234638255,\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"{'ISO3166-2-lvl6': 'SG-03',\n",
|
|
" 'amenity': 'Ngee Ann Polytechnic',\n",
|
|
" 'city': 'Singapore',\n",
|
|
" 'country': 'Singapore',\n",
|
|
" 'country_code': 'sg',\n",
|
|
" 'county': 'Northwest',\n",
|
|
" 'house_number': '535',\n",
|
|
" 'latitude': 1.33318835,\n",
|
|
" 'longitude': 103.77461234638255,\n",
|
|
" 'neighbourhood': 'Ewart Park',\n",
|
|
" 'postcode': '599489',\n",
|
|
" 'raw': {'address': {'ISO3166-2-lvl6': 'SG-03',\n",
|
|
" 'amenity': 'Ngee Ann Polytechnic',\n",
|
|
" 'city': 'Singapore',\n",
|
|
" 'country': 'Singapore',\n",
|
|
" 'country_code': 'sg',\n",
|
|
" 'county': 'Northwest',\n",
|
|
" 'house_number': '535',\n",
|
|
" 'neighbourhood': 'Ewart Park',\n",
|
|
" 'postcode': '599489',\n",
|
|
" 'road': 'Clementi Road',\n",
|
|
" 'suburb': 'Bukit Timah'},\n",
|
|
" 'addresstype': 'amenity',\n",
|
|
" 'boundingbox': ['1.3289692',\n",
|
|
" '1.3372184',\n",
|
|
" '103.7701481',\n",
|
|
" '103.7783945'],\n",
|
|
" 'class': 'amenity',\n",
|
|
" 'display_name': 'Ngee Ann Polytechnic, 535, Clementi Road, Ewart '\n",
|
|
" 'Park, Bukit Timah, Singapore, Northwest, 599489, '\n",
|
|
" 'Singapore',\n",
|
|
" 'importance': 0.34662169301918117,\n",
|
|
" 'lat': '1.33318835',\n",
|
|
" 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '\n",
|
|
" 'http://osm.org/copyright',\n",
|
|
" 'lon': '103.77461234638255',\n",
|
|
" 'name': 'Ngee Ann Polytechnic',\n",
|
|
" 'osm_id': 2535118,\n",
|
|
" 'osm_type': 'relation',\n",
|
|
" 'place_id': 250910125,\n",
|
|
" 'place_rank': 30,\n",
|
|
" 'type': 'university'},\n",
|
|
" 'road': 'Clementi Road',\n",
|
|
" 'suburb': 'Bukit Timah'}\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import pprint\n",
|
|
"\n",
|
|
"latlong = LocalCodeQuery(code=\"8QMF+FV\", locality=\"Singapore\").to_lat_long_coord(\n",
|
|
" geocoder=geocoding.geocoder\n",
|
|
")\n",
|
|
"if not latlong:\n",
|
|
" latlong.cry()\n",
|
|
"\n",
|
|
"else:\n",
|
|
" location = geocoding.reverser(latlong.get())\n",
|
|
" pprint.pprint(location)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 2.1.0: adventures in of shortening global/full Plus Codes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### testing rate-limited and cached default geocoding functions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"test_geocoding = SurplusDefaultGeocoding(user_agent=\"surplus/playground\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1\n",
|
|
"2\n",
|
|
"3\n",
|
|
"4\n",
|
|
"5\n",
|
|
"\n",
|
|
"1\n",
|
|
"2\n",
|
|
"3\n",
|
|
"4\n",
|
|
"5\n",
|
|
"\n",
|
|
"3.1107698050s\t->\t0.0000886890s\t\t(-3.1106811160002508s)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from timeit import timeit\n",
|
|
"\n",
|
|
"\n",
|
|
"test_stmt = \"\"\"\\\n",
|
|
"print(1)\n",
|
|
"test_geocoding.geocoder(\"Wisma Atria\") # instant\n",
|
|
"print(2)\n",
|
|
"test_geocoding.geocoder(\"Temasek Polytechnic\") # after 1 second\n",
|
|
"print(3)\n",
|
|
"location = test_geocoding.geocoder(\"Ngee Ann Polytechnic\") # after 1 second\n",
|
|
"print(4)\n",
|
|
"test_geocoding.reverser(f\"{location.latitude}, {location.longitude}\") # instant\n",
|
|
"print(5)\n",
|
|
"test_geocoding.reverser(f\"{location.latitude}, {location.longitude}\") # instant (cached)\n",
|
|
"print()\n",
|
|
"\"\"\"\n",
|
|
"\n",
|
|
"time_cold_call = timeit(test_stmt, globals=globals(), number=1) # expecting 3-4 seconds\n",
|
|
"time_2nd_call = timeit(test_stmt, globals=globals(), number=1) # should be instant\n",
|
|
"\n",
|
|
"print(\n",
|
|
" f\"{time_cold_call:.10f}s\\t->\\t{time_2nd_call:.10f}s\\t\\t({time_2nd_call - time_cold_call}s)\"\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### reversing the query latlong and using the address information to form a locality"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"level = 13"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"St Lucia, St Lucia, Queensland, Australia\n",
|
|
"Austin, Travis County, Texas, United States\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"(\n",
|
|
" au_response := geocoding.reverser(\n",
|
|
" (\n",
|
|
" au_target := (\n",
|
|
" LocalCodeQuery(\n",
|
|
" \"G227+XF\", \"St Lucia, Queensland, Australia\"\n",
|
|
" ).to_lat_long_coord(geocoding.geocoder)\n",
|
|
" )\n",
|
|
" ).get(),\n",
|
|
" level=level,\n",
|
|
" )\n",
|
|
")\n",
|
|
"\n",
|
|
"au_locality = f\"{au_response['suburb']}, {au_response['city_district']}, {au_response['state']}, {au_response['country']}\"\n",
|
|
"print(au_locality)\n",
|
|
"\n",
|
|
"(\n",
|
|
" us_response := geocoding.reverser(\n",
|
|
" (\n",
|
|
" us_target := (\n",
|
|
" LocalCodeQuery(\"77Q4+7X\", \"Austin, Texas, USA\").to_lat_long_coord(\n",
|
|
" geocoding.geocoder\n",
|
|
" )\n",
|
|
" )\n",
|
|
" ).get(),\n",
|
|
" level=level,\n",
|
|
" )\n",
|
|
")\n",
|
|
"\n",
|
|
"us_locality = f\"{us_response['city']}, {us_response['county']}, {us_response['state']}, {us_response['country']}\"\n",
|
|
"print(us_locality)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### getting boundary boxes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"{'addresstype': 'suburb',\n",
|
|
" 'boundingbox': ['-27.5187362', '-27.4787362', '152.9881642', '153.0281642'],\n",
|
|
" 'class': 'place',\n",
|
|
" 'display_name': 'St Lucia, Brisbane City, Queensland, 4072, Australia',\n",
|
|
" 'importance': 0.27501,\n",
|
|
" 'lat': '-27.4987362',\n",
|
|
" 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '\n",
|
|
" 'http://osm.org/copyright',\n",
|
|
" 'lon': '153.0081642',\n",
|
|
" 'name': 'St Lucia',\n",
|
|
" 'osm_id': 88800268,\n",
|
|
" 'osm_type': 'node',\n",
|
|
" 'place_id': 54477898,\n",
|
|
" 'place_rank': 19,\n",
|
|
" 'type': 'suburb'}\n",
|
|
"\n",
|
|
"Latlong(latitude=-27.4987362, longitude=153.0081642, bounding_box=[-27.5187362, -27.4787362, 152.9881642, 153.0281642])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from geopy.geocoders import Nominatim\n",
|
|
"from pprint import pprint\n",
|
|
"\n",
|
|
"target_query: Result[Latlong] = au_target\n",
|
|
"target_locality: str = au_locality\n",
|
|
"\n",
|
|
"raw_geocoding = Nominatim(user_agent=\"surplus/playground\")\n",
|
|
"latlong = raw_geocoding.geocode(target_locality)\n",
|
|
"pprint(latlong.raw)\n",
|
|
"print()\n",
|
|
"\n",
|
|
"# done: now implmented in surplus as surplus.Latlong.bounding_box\n",
|
|
"locality_latlong = geocoding.geocoder(target_locality)\n",
|
|
"pprint(locality_latlong)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[-27.5187362, -27.4787362, 152.9881642, 153.0281642]\n",
|
|
"(True, True, True, True)\n",
|
|
"(True, True, True, True)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# based on <https://github.com/google/open-location-code/wiki/Guidance-for-shortening-codes>\n",
|
|
"\n",
|
|
"target_latlong = target_query.get()\n",
|
|
"if locality_latlong.bounding_box is None:\n",
|
|
" ... # raise some error\n",
|
|
"\n",
|
|
"print(locality_latlong.bounding_box)\n",
|
|
"check1 = (\n",
|
|
" # The center point of the feature is within 0.4 degrees latitude and 0.4 degrees longitude\n",
|
|
" (\n",
|
|
" (target_latlong.latitude - 0.4)\n",
|
|
" <= locality_latlong.latitude\n",
|
|
" <= (target_latlong.latitude + 0.4)\n",
|
|
" ),\n",
|
|
" (\n",
|
|
" (target_latlong.longitude - 0.4)\n",
|
|
" <= locality_latlong.longitude\n",
|
|
" <= (target_latlong.longitude + 0.4)\n",
|
|
" ),\n",
|
|
" # The bounding box of the feature is less than 0.8 degrees high and wide.\n",
|
|
" abs(locality_latlong.bounding_box[0] - locality_latlong.bounding_box[1]) < 0.8,\n",
|
|
" abs(locality_latlong.bounding_box[2] - locality_latlong.bounding_box[3]) < 0.8,\n",
|
|
")\n",
|
|
"\n",
|
|
"\n",
|
|
"check2 = (\n",
|
|
" # The center point of the feature is within 0.4 degrees latitude and 0.4 degrees longitude\n",
|
|
" (\n",
|
|
" (target_latlong.latitude - 8)\n",
|
|
" <= locality_latlong.latitude\n",
|
|
" <= (target_latlong.latitude + 8)\n",
|
|
" ),\n",
|
|
" (\n",
|
|
" (target_latlong.longitude - 8)\n",
|
|
" <= locality_latlong.longitude\n",
|
|
" <= (target_latlong.longitude + 8)\n",
|
|
" ),\n",
|
|
" # The bounding box of the feature is less than 0.8 degrees high and wide.\n",
|
|
" abs(locality_latlong.bounding_box[0] - locality_latlong.bounding_box[1]) < 16,\n",
|
|
" abs(locality_latlong.bounding_box[2] - locality_latlong.bounding_box[3]) < 16,\n",
|
|
")\n",
|
|
"\n",
|
|
"print(check1)\n",
|
|
"print(check2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"G227+XF St Lucia, St Lucia, Queensland, Australia\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from pluscodes import encode\n",
|
|
"\n",
|
|
"target_plus_code = encode(\n",
|
|
" lat=target_latlong.latitude, lon=target_latlong.longitude, code_length=10\n",
|
|
")\n",
|
|
"portion_plus_code = \"\"\n",
|
|
"\n",
|
|
"if check1:\n",
|
|
" portion_plus_code = target_plus_code[4:]\n",
|
|
" print(portion_plus_code, target_locality)\n",
|
|
"\n",
|
|
"elif check2:\n",
|
|
" portion_plus_code = target_plus_code[2:]\n",
|
|
" print(portion_plus_code, target_locality)\n",
|
|
"\n",
|
|
"else:\n",
|
|
" print(\n",
|
|
" \"info: could not determine a suitable geographical feature to use as locality for shortening.\"\n",
|
|
" )\n",
|
|
" print(plus_code)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## machine fingerprinting attempt\n",
|
|
"\n",
|
|
"because of nominatim's acceptable usage policy \n",
|
|
"<https://operations.osmfoundation.org/policies/nominatim/>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from hashlib import shake_256 as _hashlib_shake_256\n",
|
|
"from platform import platform as _platform_platform\n",
|
|
"from socket import gethostname as _socket_gethostname\n",
|
|
"from uuid import getnode as _uuid_getnode\n",
|
|
"from surplus import VERSION, VERSION_SUFFIX\n",
|
|
"\n",
|
|
"\n",
|
|
"def generate_fingerprinted_user_agent() -> Result[str]:\n",
|
|
" \"\"\"\n",
|
|
" function that attempts to return a unique user agent string.\n",
|
|
"\n",
|
|
" returns Result[str]\n",
|
|
" this result will always have a valid value as erroneous results will have a\n",
|
|
" resulting value of 'surplus/<version>/generic-user'\n",
|
|
" valid results will have a value of 'surplus/<version>/<fingerprint>', where\n",
|
|
" fingerprint is a 12 character hexadecimal string\n",
|
|
" \"\"\"\n",
|
|
" version: str = \".\".join([str(v) for v in VERSION]) + VERSION_SUFFIX\n",
|
|
"\n",
|
|
" try:\n",
|
|
" system_info: str = _platform_platform()\n",
|
|
" hostname: str = _socket_gethostname()\n",
|
|
" mac_address: str = \":\".join(\n",
|
|
" [\n",
|
|
" \"{:02x}\".format((_uuid_getnode() >> elements) & 0xFF)\n",
|
|
" for elements in range(0, 2 * 6, 2)\n",
|
|
" ][::-1]\n",
|
|
" )\n",
|
|
" unique_info: str = f\"{version}-{system_info}-{hostname}-{mac_address}\"\n",
|
|
"\n",
|
|
" print(f\"{version=}\")\n",
|
|
" print(f\"{system_info=}\")\n",
|
|
" print(f\"{hostname=}\")\n",
|
|
" print(f\"{mac_address=}\")\n",
|
|
"\n",
|
|
" except Exception as exc:\n",
|
|
" return Result[str](f\"surplus/{version} (generic-user)\", error=exc)\n",
|
|
"\n",
|
|
" fingerprint: str = _hashlib_shake_256(unique_info.encode()).hexdigest(5)\n",
|
|
"\n",
|
|
" return Result[str](f\"surplus/{version} ({fingerprint})\")"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.11.1"
|
|
},
|
|
"orig_nbformat": 4
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|