Skip to content

Instantly share code, notes, and snippets.

@highfestiva
Last active October 24, 2022 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save highfestiva/7b73fe06879e753099dd1efe871cde43 to your computer and use it in GitHub Desktop.
Save highfestiva/7b73fe06879e753099dd1efe871cde43 to your computer and use it in GitHub Desktop.
Streamlit parsing and plotting of geo-coordinates
'''
# 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