Last active
October 24, 2022 14:48
-
-
Save highfestiva/7b73fe06879e753099dd1efe871cde43 to your computer and use it in GitHub Desktop.
Streamlit parsing and plotting of geo-coordinates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
# AutoMap | |
A tool for plotting pretty much anything with geo-coordinates in it. | |
First install Python3 and Streamlit (https://docs.streamlit.io/). Start script by running | |
```bash | |
streamlit run automap.py | |
``` | |
A web page opens. Paste your payload or even plain JSON is fine too. Click the 'Parse' button. | |
If geo-coordinates were found a bunch of buttons will show up. Click any button to see the | |
contents plotted to a map. | |
''' | |
import streamlit as st | |
import base64 | |
import gzip | |
import json | |
import pandas as pd | |
import pydeck as pdk | |
geo_keys = {'latitude':'latitude', 'lat':'latitude', 'longitude':'longitude', 'lng':'longitude'} | |
st.title('AutoMapper') | |
if 'coords' not in st.session_state: | |
st.session_state.coords = {} | |
def unbase64(data): | |
try: return base64.b64decode(data) | |
except: return data | |
def ungzip(data): | |
try: return gzip.decompress(data) | |
except: return data | |
def unjson(data): | |
try: return json.loads(data) | |
except: return data | |
def get_list(store, hierarchy_names, tag): | |
tags = hierarchy_names[:-1] if type(hierarchy_names[-1]) == int else hierarchy_names | |
tags = hierarchy_names[:-2]+hierarchy_names[-1:] if len(hierarchy_names) >= 2 and type(hierarchy_names[-2]) == int else hierarchy_names | |
parent_name = '.'.join([str(t) for t in tags]) | |
if not parent_name in store: | |
store[parent_name] = {'latitude':[], 'longitude':[]} | |
node = store[parent_name] | |
return node[tag] | |
def deep_pluck(store, hierarchy_names, node): | |
'''Converts anything lat/lng into a datastructure like so: | |
{ | |
"waypoint.0.shapes": { | |
"lat": [1.1, 2.2, 3.3], | |
"lng": [4.4, 5.5, 6.6] | |
},... | |
} | |
''' | |
if type(node) == dict: | |
for key,value in node.items(): | |
if type(value) == float and key in geo_keys: | |
l = get_list(store, hierarchy_names, geo_keys[key]) | |
l.append(value) | |
else: | |
deep_pluck(store, hierarchy_names+[key], value) | |
elif type(node) == list: | |
for i,value in enumerate(node): | |
deep_pluck(store, hierarchy_names+[i], value) | |
# ignore strings and ints | |
return store | |
def uncoord(data): | |
return deep_pluck(store={}, hierarchy_names=[], node=data) | |
def join_latlng(data): | |
print(list(data)) | |
print(data) | |
for key in list(data): | |
parent_tag,ending = key.rsplit('.',1) | |
if ending in geo_keys: | |
data[parent_tag] = {'latitude':[], 'longitude': []} | |
data[parent_tag]['latitude'] = data[parent_tag + '.latitude']['latitude'] | |
data[parent_tag]['longitude'] = data[parent_tag + '.longitude']['longitude'] | |
return data | |
def unpack_data(data): | |
data = data.strip() | |
if data[0] not in '[{': | |
data = unbase64(data.strip()) | |
data = ungzip(data) | |
data = unjson(data) | |
data = uncoord(data) | |
data = join_latlng(data) | |
return data | |
def update_buttons(): | |
data = unpack_data(st.session_state.text) | |
st.session_state.coords = data | |
st.session_state.text = '' | |
with st.form(key='input_coord_data'): | |
st.text_area('Paste geocoords', key='text') | |
submit = st.form_submit_button(label='Parse', on_click=update_buttons) | |
for label,coords in st.session_state.coords.items(): | |
if st.button(label): | |
print(coords) | |
df = pd.DataFrame(coords) | |
st.map(df) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment