Skip to content

Commit

Permalink
gdal2tiles.py: add Leaflet template (patch by jnth, OSGeo/gdal#71)
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.osgeo.org/gdal/trunk/gdal@30962 f0d54148-0727-0410-94bb-9a71ac55c965
  • Loading branch information
rouault committed Oct 11, 2015
1 parent c4b4b03 commit 66f0271
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 3 deletions.
4 changes: 2 additions & 2 deletions apps/gdal_utilities.dox
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,7 @@ gdal2tiles.py [-p profile] [-r resampling] [-s srs] [-z zoom]

This utility generates a directory with small tiles and metadata, following
the OSGeo Tile Map Service Specification. Simple web pages with viewers based on
Google Maps and OpenLayers are generated as well - so anybody can comfortably
Google Maps, OpenLayers and Leaflet are generated as well - so anybody can comfortably
explore your maps on-line and you do not need to install or configure any
special software (like MapServer) and the map displays very fast in the
web browser. You only need to upload the generated directory onto a web server.
Expand Down Expand Up @@ -1541,7 +1541,7 @@ Options for generated Google Earth SuperOverlay metadata
Options for generated HTML viewers a la Google Maps
<dl>
<dt> <b>-w</b> <i>WEBVIEWER</i>, --webviewer=<i>WEBVIEWER</i>:</dt>
<dd>Web viewer to generate (all,google,openlayers,none) - default 'all'.</dd>
<dd>Web viewer to generate (all,google,openlayers,leaflet,none) - default 'all'.</dd>
<dt> <b>-t</b> <i>TITLE</i>, --title=<i>TITLE</i>:</dt>
<dd>Title of the map.</dd>
<dt> <b>-c</b> <i>COPYRIGHT</i>, --copyright=<i>COPYRIGHT</i>:</dt>
Expand Down
142 changes: 141 additions & 1 deletion swig/python/scripts/gdal2tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

resampling_list = ('average','near','bilinear','cubic','cubicspline','lanczos','antialias')
profile_list = ('mercator','geodetic','raster') #,'zoomify')
webviewer_list = ('all','google','openlayers','none')
webviewer_list = ('all','google','openlayers','leaflet','none')

# =============================================================================
# =============================================================================
Expand Down Expand Up @@ -1093,6 +1093,13 @@ def generate_metadata(self):
f.write( self.generate_openlayers() )
f.close()

# Generate leaflet.html
if self.options.webviewer in ('all','leaflet'):
if not self.options.resume or not os.path.exists(os.path.join(self.output, 'leaflet.html')):
f = open(os.path.join(self.output, 'leaflet.html'), 'w')
f.write( self.generate_leaflet() )
f.close()

elif self.options.profile == 'geodetic':

west, south = self.ominx, self.ominy
Expand Down Expand Up @@ -1939,6 +1946,139 @@ def generate_googlemaps(self):
return s


# -------------------------------------------------------------------------
def generate_leaflet(self):
"""
Template for leaflet.html implementing overlay of tiles for 'mercator' profile.
It returns filled string. Expected variables:
title, north, south, east, west, minzoom, maxzoom, tilesize, tileformat, publishurl
"""

args = {}
args['title'] = self.options.title.replace('"', '\\"')
args['htmltitle'] = self.options.title
args['south'], args['west'], args['north'], args['east'] = self.swne
args['centerlon'] = (args['north'] + args['south']) / 2.
args['centerlat'] = (args['west'] + args['east']) / 2.
args['minzoom'] = self.tminz
args['maxzoom'] = self.tmaxz
args['beginzoom'] = self.tmaxz
args['tilesize'] = self.tilesize # not used
args['tileformat'] = self.tileext
args['publishurl'] = self.options.url # not used
args['copyright'] = self.options.copyright.replace('"', '\\"')

s = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<title>%(htmltitle)s</title>
<!-- Leaflet -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.js"></script>
<style>
body { margin:0; padding:0; }
body, table, tr, td, th, div, h1, h2, input { font-family: "Calibri", "Trebuchet MS", "Ubuntu", Serif; font-size: 11pt; }
#map { position:absolute; top:0; bottom:0; width:100%%; } /* full size */
.ctl {
padding: 2px 10px 2px 10px;
background: white;
background: rgba(255,255,255,0.9);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
text-align: right;
}
.title {
font-size: 18pt;
font-weight: bold;
}
.src {
font-size: 10pt;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
/* **** Leaflet **** */
// Base layers
// .. OpenStreetMap
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'});
// .. CartoDB Positron
var cartodb = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>'});
// .. OSM Toner
var toner = L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png', {attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.'});
// .. White background
var white = L.tileLayer("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEX///+nxBvIAAAAH0lEQVQYGe3BAQ0AAADCIPunfg43YAAAAAAAAAAA5wIhAAAB9aK9BAAAAABJRU5ErkJggg==");
// Overlay layers (TMS)
var lyr = L.tileLayer('./{z}/{x}/{y}.%(tileformat)s', {tms: true, opacity: 0.7, attribution: "%(copyright)s"});
// Map
var map = L.map('map', {
center: [%(centerlon)s, %(centerlat)s],
zoom: %(beginzoom)s,
minZoom: %(minzoom)s,
maxZoom: %(maxzoom)s,
layers: [osm]
});
var basemaps = {"OpenStreetMap": osm, "CartoDB Positron": cartodb, "Stamen Toner": toner, "Without background": white}
var overlaymaps = {"Layer": lyr}
// Title
var title = L.control();
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl title');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = "%(title)s";
};
title.addTo(map);
// Note
var src = 'Generated by <a href="http://www.klokan.cz/projects/gdal2tiles/">GDAL2Tiles</a>, Copyright &copy; 2008 <a href="http://www.klokan.cz/">Klokan Petr Pridal</a>, <a href="http://www.gdal.org/">GDAL</a> &amp; <a href="http://www.osgeo.org/">OSGeo</a> <a href="http://code.google.com/soc/">GSoC</a>';
var title = L.control({position: 'bottomleft'});
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl src');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = src;
};
title.addTo(map);
// Add base layers
L.control.layers(basemaps, overlaymaps, {collapsed: false}).addTo(map);
// Fit to overlayer bounds (SW and NE points with (lat, lon))
map.fitBounds([[%(south)s, %(east)s], [%(north)s, %(west)s]]);
</script>
</body>
</html>
""" % args

return s


# -------------------------------------------------------------------------
def generate_openlayers( self ):
"""
Expand Down

0 comments on commit 66f0271

Please sign in to comment.