Skip to content

Instantly share code, notes, and snippets.

@brikeats
Created March 22, 2017 19:27
Show Gist options
  • Save brikeats/52689a72a19f1b85f3942fd6e04652df to your computer and use it in GitHub Desktop.
Save brikeats/52689a72a19f1b85f3942fd6e04652df to your computer and use it in GitHub Desktop.
Create a google maps webpage with polygons and heatmaps from geojson annotations and yield shapefiles
import shapely
html_template_part1 = """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>%s</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%%;
margin: 0;
padding: 0;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: 'Roboto','sans-serif';
line-height: 30px;
padding-left: 10px;
}
#floating-panel {
background-color: #fff;
border: 1px solid #999;
left: 25%%;
padding: 5px;
position: absolute;
top: 10px;
z-index: 5;
}
</style>
</head>
<body>
<div id="floating-panel">
<button onclick="toggleHeatmap()" id="heatmapToggleButton">Show Heatmaps</button>
</div>
<div id="map"></div>
<script>
// This example requires the Visualization library. Include the libraries=visualization
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=visualization">
var polygons = [];
var heatmaps = [];
function initMap() {
var bounds = new google.maps.LatLngBounds();
bounds.extend(new google.maps.LatLng(%.6f, %.6f));
bounds.extend(new google.maps.LatLng(%.6f, %.6f));
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: %.4f, lng: %.4f},
mapTypeId: 'satellite'
});
map.fitBounds(bounds);
map.addListener('zoom_changed', function() {
onZoomChange(map.getZoom());
});
"""
html_template_part2 = """
}
function toggleHeatmap() {
var button = document.getElementById("heatmapToggleButton");
// change label
if (button.innerHTML=="Show Heatmaps") {
button.innerHTML = "Show Polygons";
for (var i=0; i < polygons.length; i++)
polygons[i].setMap(null);
for (var i=0; i < heatmaps.length; i++)
heatmaps[i].setMap(map);
}
else {
button.innerHTML = "Show Heatmaps";
for (var i=0; i < polygons.length; i++)
polygons[i].setMap(map);
for (var i=0; i < heatmaps.length; i++)
heatmaps[i].setMap(null);
}
}
function onZoomChange(zoom){
var button = document.getElementById("heatmapToggleButton");
console.log('new zoom level: '+zoom);
if (button.innerHTML=="Show Polygons") { // when button has "Show Polygons", the heatmap is being displayed
for (var i=0; i < heatmaps.length; i++){
heatmaps[i].radius = Math.pow(2, zoom-16);
console.log('new radius: '+heatmaps[i].radius);
}
}
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDZ6DjC_TDxBNQjkscsdV3ffPW4SCWC7-E&libraries=visualization&callback=initMap">
</script>
</body>
</html>
"""
def points_to_javascript_polygon(points, poly_index=0):
html = 'var coords%i = [\n' % poly_index
for pt_num, pt in enumerate(points):
html += """\t\t{lat: %.6f, lng: %.6f}""" % (pt[1], pt[0])
if pt_num != len(points) - 1:
html += ',\n'
html += '];'
html += """
var polygon%i = new google.maps.Polygon({
paths: coords%i,
strokeColor: '#FF0000',
strokeOpacity: 0.7,
strokeWeight: 0,
fillColor: '#FF0000',
fillOpacity: 0.35
});
polygon%i.setMap(map);
polygons.push(polygon%i);
""" % (poly_index, poly_index, poly_index, poly_index)
return html
def points_to_javascript_heatmap(points, weights, heatmap_index=0):
html = """var heatmap%i = new google.maps.visualization.HeatmapLayer({
data: [""" % heatmap_index
for pt_num, (pt, weight) in enumerate(zip(points, weights)):
html += '\t\t\t{location: new google.maps.LatLng(%.6f, %.6f), weight: %.3f}' % (pt[1], pt[0], weight)
if pt_num != len(points) - 1:
html += ','
html += '\n'
html += """],
radius: 0.5,
opacity: 0.7
});
heatmaps.push(heatmap%i);
""" % heatmap_index
return html
def fill_heatmap_template(yield_data, field_polygons, title=''):
if len(field_polygons) == 1:
field_polygons = shapely.geometry.MultiPolygon([field_polygons])
else:
field_polygons = shapely.geometry.MultiPolygon(field_polygons)
min_lng, min_lat, max_lng, max_lat = field_polygons.bounds
center = np.array([(min_lng + max_lng) / 2, (min_lat + max_lat) / 2])
TR = max_lng, max_lat
BL = min_lng, min_lat
if not title:
title = '(lat, lng) = (%.3f, %.3f)' % (center[1], center[0])
html = html_template_part1 % (title, TR[1], TR[0], BL[1], BL[0], center[1], center[0])
# Add polygons for field boundaries
for poly_num, polygon in enumerate(field_polygons):
html += points_to_javascript_polygon(np.array(polygon.boundary), poly_num)
# Add heatmaps
for num, weighted_pts in enumerate(yield_data):
pts = weighted_pts[:, :2]
weights = weighted_pts[:, 2]
html += points_to_javascript_heatmap(pts, weights, num)
html += html_template_part2
# write the html and open the webpage
html_fn = 'webpage.html'
with open(html_fn, 'wt') as f:
f.write(html)
import geopandas
from shapely.geometry import MultiPoint
field_polygons = []
with open('yield_data/gridded_data_field.json') as f:
polygon = shape(geojson.load(f))
field_polygons.append(polygon)
with open('yield_data/gridded_data_2016_corn_field1.json') as f:
polygon = shape(geojson.load(f))
field_polygons.append(polygon)
# yield_data = []
# gdf = geopandas.read_file('yield_data/gridded_data.shp')
# points = np.asarray(MultiPoint(gdf.geometry))
# yield_data.append(np.hstack([points, np.expand_dims(gdf.dry_yield.values, -1)]))
# gdf = geopandas.read_file('yield_data/gridded_data_2016_corn.shp')
# points = np.asarray(MultiPoint(gdf.geometry))
# yield_data.append(np.hstack([points, np.expand_dims(gdf.dry_yield.values, -1)]))
fill_heatmap_template(yield_data, field_polygons)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment