<jupyter_start><jupyter_text>Mapping Epicollect points in Hillside Woods Our goal is to display the user's current location, using a phone GPS point, simultaneously alongside EpiCollect5 data for the project (https://five.epicollect.net/project/hillside-woods-restoration-project).  We can do this using a Python package to collect data using the EpiCollect5 API, using the `folium` mapping tool (which wraps leaflet.js), and using the LocateControl functionality in leaflet.js (code here: https://github.com/python-visualization/folium/blob/master/folium/plugins/locate_control.py)  installs (run these in terminal)<jupyter_code># pip install pyepicollect
# conda install folium -c conda-forge<jupyter_output><empty_output><jupyter_text>imports<jupyter_code># package for getting EpiCollect data
import pyepicollect as pyep
# package for mapping
import folium
# tool for adding current location
from folium.plugins import LocateControl
# linear algebraic tools
import numpy as np<jupyter_output><empty_output><jupyter_text>1) Access and format EpiCollect5 data using `pyepicollect`<jupyter_code># load entries -- set the per_page value high so that we get em all
entries = pyep.api.get_entries('hillside-woods-restoration-project',per_page=10000)
# save list of lats
lats = [i['5_Location']['latitude'] for i in entries['data']['entries']]

# save list of lons
lons = [i['5_Location']['longitude'] for i in entries['data']['entries']]
# zip em together
lat_lon_pairs = [list(i) for i in zip(lats,lons)]

# look at the first several:
lat_lon_pairs[:10]<jupyter_output><empty_output><jupyter_text>2) Define a map with `folium`  Map:  Start by defining map parameters:<jupyter_code># give the map a general starting location (middle of hillside woods)
starting_location = [40.997895, -73.867473]

# give the map a starting zoom
zoom_start = 16

# give the map a maximum zoom -- higher number allows farther zoom, but makes things slower...
max_zoom = 22

# maybe giving a min_zoom will speed up rendering?
min_zoom = 0<jupyter_output><empty_output><jupyter_text>Now define the map and locator:<jupyter_code># define a simple map
m = folium.Map(starting_location,
               zoom_start=zoom_start, 
               max_zoom=max_zoom,
               min_zoom=min_zoom)

# turn on the gps locator
LocateControl(strings={"title": "See your current location"}).add_to(m);<jupyter_output><empty_output><jupyter_text>Grid:  Add gridline spacings that we want, covering the whole area:<jupyter_code># here are broad boundaries
gridlons = [-74.5,-73.5]
gridlats = [40.5,50.5]
# extract linear points between these. 
# This controls spacing...
hlines_bigbounds = np.array([[[i,gridlons[0]],[i,gridlons[1]]] for i in np.linspace(gridlats[0],gridlats[1],10001)])
vlines_bigbounds = np.array([[[gridlats[0],i],[gridlats[1],i]] for i in np.linspace(gridlons[0],gridlons[1],1001)])<jupyter_output><empty_output><jupyter_text>Exclude gridlines that are far from Hillside:<jupyter_code># fit boundaries tightly around Hillside
boundlats = [40.993,41.004]
boundlons = [-73.878,-73.857]
# exclude far-away horizontal lines
hlines = hlines_bigbounds[np.logical_and(hlines_bigbounds[:,0,0] >= boundlats[0], hlines_bigbounds[:,0,0] <= boundlats[1])]
hlines[:,0,1] = boundlons[0]
hlines[:,1,1] = boundlons[1]
# exclude far-away vertical lines
vlines = vlines_bigbounds[np.logical_and(vlines_bigbounds[:,0,1] >= boundlons[0], vlines_bigbounds[:,0,1] <= boundlons[1])]
vlines[:,0,0] = boundlats[0]
vlines[:,1,0] = boundlats[1]
# save all lines for grid
lines = np.vstack([hlines,vlines])<jupyter_output><empty_output><jupyter_text>Add grid to map -- each gridline is plotted separately:<jupyter_code># loop through gridlines, adding each one
for line in lines:
    pl=folium.PolyLine(locations=line,weight=1)
    m.add_child(pl)<jupyter_output><empty_output><jupyter_text>EpiCollect:  Finally, add the EpiCollect data to the map:<jupyter_code># add the EpiCollect data points
# for now, the popup just says that they are points
# later, we could add the EpiCollect information for each point
for i in range(len(lat_lon_pairs)):
    folium.Marker(
        lat_lon_pairs[i],
        popup='epicollect data point'
    ).add_to(m)<jupyter_output><empty_output><jupyter_text>3) Display the map: * You can zoom in or out, and drag around the map.  * You can click the location toggle in the upper-left corner to show your gps location.* You can click on the EpiCollect points in Hillside Woods to show information about them (although they're currently informationless!)<jupyter_code>m<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1099236641221374, 'fraction_numerical': 0.023991275899672846, 'mean_word_length': 5.927492447129909, 'pattern_counts': {'":': 1, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '493718', 'license': 'MIT', 'n_tokens_mistral': 1584, 'n_tokens_neox': 1530, 'n_words': 442, 'path': 'notebooks/simple_mapping_demo.ipynb', 'repo_name': 'pmckenz1/hillside_mapping', 'size': '4585'}