from IPython.core.display import HTML
with open('creative_commons.txt', 'r') as f:
html = f.read()
name = '2015-07-13-interactive_geo'
html = '''
<small>
<p> This post was written as an IPython notebook.
It is available for <a href='https://ocefpaf.github.com/python4oceanographers/downloads/notebooks/%s.ipynb'>download</a>
or as a static <a href='https://nbviewer.ipython.org/url/ocefpaf.github.com/python4oceanographers/downloads/notebooks/%s.ipynb'>html</a>.</p>
<p></p>
%s''' % (name, name, html)
%matplotlib inline
from matplotlib import style
style.use('ggplot')
import os
from datetime import datetime
title = "Plotting an static image over an interactive map"
hour = datetime.utcnow().strftime('%H:%M')
comments="true"
date = '-'.join(name.split('-')[:3])
slug = '-'.join(name.split('-')[3:])
metadata = dict(title=title,
date=date,
hour=hour,
comments=comments,
slug=slug,
name=name)
markdown = """Title: {title}
date: {date} {hour}
comments: {comments}
slug: {slug}
{{% notebook {name}.ipynb cells[2:] %}}
""".format(**metadata)
content = os.path.abspath(os.path.join(os.getcwd(), os.pardir, os.pardir, '{}.md'.format(name)))
with open('{}'.format(content), 'w') as f:
f.writelines(markdown)
I just read an issue at the folium issue tracker that gave me an idea. How can I hack folium's HTML to quickly test new leaflet features? Well... The answer is simple, inline modification of the HTML ;-)
I want to test the raster plotting feature. First, just to check the image, lets georeference it using cartopy.
%matplotlib inline
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.io import shapereader
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
def make_map(projection=ccrs.PlateCarree()):
fig, ax = plt.subplots(figsize=(9, 13),
subplot_kw=dict(projection=projection))
gl = ax.gridlines(draw_labels=True)
gl.xlabels_top = gl.ylabels_right = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
return fig, ax
min_lon = -(45 + (58 + 32.27/60) / 60) # 45°58'32.27"W
max_lon = -(45 + (57 + 54.54/60) / 60) # 45°57'54.54"W
min_lat = -(23 + (47 + 7.65/60) / 60) # 23°47' 7.65"S
max_lat = -(23 + (46 + 42.25/60) / 60) # 23°46'42.25"S
fig, ax = make_map()
image = plt.imread('data/itaguare_cropped.jpg')
img = ax.imshow(image, origin='upper', alpha=0.75, extent=[min_lon, max_lon, min_lat, max_lat])
That looks about right. Now lets create a folium map instance for this area.
import folium
def inline_map(m):
from folium import Map
from IPython.display import HTML, IFrame
if isinstance(m, Map):
m._build_map()
srcdoc = m.HTML.replace('"', '"')
embed = HTML('<iframe srcdoc="{srcdoc}" '
'style="width: 100%; height: 500px; '
'border: none"></iframe>'.format(srcdoc=srcdoc))
elif isinstance(m, str):
embed = IFrame(m, width=750, height=500)
return embed
width, height = 650, 500
mapa = folium.Map(location=[-47.563861111111109, -91.940780555555563],
min_lon=min_lon, max_lon=max_lon, min_lat=min_lat, max_lat=max_lat,
tiles='Stamen Toner', width=width, height=height, zoom_start=15)
inline_map(mapa)
According to leafletjs manual we need to perform an imageoverlay.
extra = """
var imageUrl = 'https://raw.githubusercontent.com/ocefpaf/python4oceanographers/master/content/downloads/notebooks/data/itaguare_cropped.jpg',
imageBounds = [[-23.785458333333334, -45.975630555555554], [-23.778402777777778, -45.96515]];
L.imageOverlay(imageUrl, imageBounds).addTo(map);
"""
I know that the last line in the HTML file, before the final </script>
, is
map.addLayer(clusteredmarkers);
, so this is how we can modify it in place:
import fileinput
mapa.create_map(path="mapa.html")
add_lines = False
for line in fileinput.input('mapa.html', inplace=True):
if 'map.addLayer(clusteredmarkers);' in line:
add_lines = True
else:
if add_lines:
print(extra)
add_lines = False
print line,
inline_map("mapa.html")
HTML(html)
This post was written as an IPython notebook. It is available for download or as a static html.