def test_image_overlay(self): """Test image overlay.""" from numpy.random import random from folium.utilities import write_png import base64 data = random((100, 100)) png_str = write_png(data) with open('data.png', 'wb') as f: f.write(png_str) png = "data:image/png;base64,{}".format inline_image_url = png(base64.b64encode(png_str).decode('utf-8')) image_tpl = self.env.get_template('image_layer.js') image_name = 'Image_Overlay' image_opacity = 0.25 image_url = 'data.png' min_lon, max_lon, min_lat, max_lat = -90.0, 90.0, -180.0, 180.0 image_bounds = [[min_lon, min_lat], [max_lon, max_lat]] image_rendered = image_tpl.render({'image_name': image_name, 'image_url': image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity}) self.map.image_overlay(data, filename=image_url) assert image_rendered in self.map.template_vars['image_layers'] image_rendered = image_tpl.render({'image_name': image_name, 'image_url': inline_image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity}) self.map.image_overlay(data) assert image_rendered in self.map.template_vars['image_layers']
def test_image_overlay(self): """Test image overlay.""" # from numpy.random import random from folium.utilities import write_png # import base64 data = [[[1, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0]], [[1, 1, 0, 0.5], [0, 0, 1, 1], [0, 0, 1, 1]]] min_lon, max_lon, min_lat, max_lat = -90.0, 90.0, -180.0, 180.0 self.setup() image_url = "data.png" self.map.image_overlay(data, filename=image_url) out = self.map._parent.render() imageoverlay = [val for key, val in self.map._children.items() if isinstance(val, ImageOverlay)][0] png_str = write_png(data) # with open('data.png', 'wb') as f: # f.write(png_str) png = "data:image/png;base64,{}".format inline_image_url = png(base64.b64encode(png_str).decode("utf-8")) image_tpl = self.env.get_template("image_layer.js") image_name = "Image_Overlay" image_opacity = 0.25 image_bounds = [[min_lon, min_lat], [max_lon, max_lat]] image_rendered = image_tpl.render( { "image_name": image_name, "this": imageoverlay, "image_url": image_url, "image_bounds": image_bounds, "image_opacity": image_opacity, } ) assert "".join(image_rendered.split()) in "".join(out.split()) self.setup() self.map.image_overlay(data, mercator_project=True) out = self.map._parent.render() imageoverlay = [val for key, val in self.map._children.items() if isinstance(val, ImageOverlay)][0] image_rendered = image_tpl.render( { "image_name": image_name, "this": imageoverlay, "image_url": inline_image_url, "image_bounds": image_bounds, "image_opacity": image_opacity, } ) assert "".join(image_rendered.split()) in "".join(out.split()) bounds = self.map.get_bounds() assert bounds == [[-90.0, -180.0], [90.0, 180.0]], bounds
def test_image_overlay(self): """Test image overlay.""" # from numpy.random import random from folium.utilities import write_png # import base64 data = [[[1, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0]], [[1, 1, 0, 0.5], [0, 0, 1, 1], [0, 0, 1, 1]]] min_lon, max_lon, min_lat, max_lat = -90.0, 90.0, -180.0, 180.0 self.setup() image_url = 'data.png' self.map.image_overlay(data, filename=image_url) out = self.map._parent.render() imageoverlay = [ val for key, val in self.map._children.items() if isinstance(val, ImageOverlay) ][0] png_str = write_png(data) # with open('data.png', 'wb') as f: # f.write(png_str) png = "data:image/png;base64,{}".format inline_image_url = png(base64.b64encode(png_str).decode('utf-8')) image_tpl = self.env.get_template('image_layer.js') image_name = 'Image_Overlay' image_opacity = 0.25 image_bounds = [[min_lon, min_lat], [max_lon, max_lat]] image_rendered = image_tpl.render({ 'image_name': image_name, 'this': imageoverlay, 'image_url': image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity }) assert ''.join(image_rendered.split()) in ''.join(out.split()) self.setup() self.map.image_overlay(data) out = self.map._parent.render() imageoverlay = [ val for key, val in self.map._children.items() if isinstance(val, ImageOverlay) ][0] image_rendered = image_tpl.render({ 'image_name': image_name, 'this': imageoverlay, 'image_url': inline_image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity }) assert ''.join(image_rendered.split()) in ''.join(out.split())
def test_image_overlay(self): """Test image overlay.""" # from numpy.random import random from folium.utilities import write_png # import base64 data = [[[1, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0]], [[1, 1, 0, 0.5], [0, 0, 1, 1], [0, 0, 1, 1]]] min_lon, max_lon, min_lat, max_lat = -90.0, 90.0, -180.0, 180.0 self.setup() image_url = 'data.png' self.map.image_overlay(data, filename=image_url) out = self.map._parent.render() imageoverlay = [val for key, val in self.map._children.items() if isinstance(val, ImageOverlay)][0] png_str = write_png(data) # with open('data.png', 'wb') as f: # f.write(png_str) png = "data:image/png;base64,{}".format inline_image_url = png(base64.b64encode(png_str).decode('utf-8')) image_tpl = self.env.get_template('image_layer.js') image_name = 'Image_Overlay' image_opacity = 0.25 image_bounds = [[min_lon, min_lat], [max_lon, max_lat]] image_rendered = image_tpl.render({'image_name': image_name, 'this': imageoverlay, 'image_url': image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity}) assert ''.join(image_rendered.split()) in ''.join(out.split()) self.setup() self.map.image_overlay(data) out = self.map._parent.render() imageoverlay = [val for key, val in self.map._children.items() if isinstance(val, ImageOverlay)][0] image_rendered = image_tpl.render({'image_name': image_name, 'this': imageoverlay, 'image_url': inline_image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity}) assert ''.join(image_rendered.split()) in ''.join(out.split())
def test_image_overlay(self): """Test image overlay.""" from numpy.random import random from folium.utilities import write_png import base64 data = random((100, 100)) png_str = write_png(data) with open('data.png', 'wb') as f: f.write(png_str) png = "data:image/png;base64,{}".format inline_image_url = png(base64.b64encode(png_str).decode('utf-8')) image_tpl = self.env.get_template('image_layer.js') image_name = 'Image_Overlay' image_opacity = 0.25 image_url = 'data.png' min_lon, max_lon, min_lat, max_lat = -90.0, 90.0, -180.0, 180.0 image_bounds = [[min_lon, min_lat], [max_lon, max_lat]] image_rendered = image_tpl.render({ 'image_name': image_name, 'image_url': image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity }) self.map.image_overlay(data, filename=image_url) assert image_rendered in self.map.template_vars['image_layers'] image_rendered = image_tpl.render({ 'image_name': image_name, 'image_url': inline_image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity }) self.map.image_overlay(data) assert image_rendered in self.map.template_vars['image_layers']
def image_overlay(self, data, opacity=0.25, min_lat=-90.0, max_lat=90.0, min_lon=-180.0, max_lon=180.0, image_name=None, filename=None): """Simple image overlay of raster data from a numpy array. This is a lightweight way to overlay geospatial data on top of a map. If your data is high res, consider implementing a WMS server and adding a WMS layer. This function works by generating a PNG file from a numpy array. If you do not specifiy a filename, it will embed the image inline. Otherwise, it saves the file in the current directory, and then adds it as an image overlay layer in leaflet.js. By default, the image is placed and stretched using bounds that cover the entire globe. Parameters ---------- data: numpy array OR url string, required. if numpy array, must be a image format, i.e., NxM (mono), NxMx3 (rgb), or NxMx4 (rgba) if url, must be a valid url to a image (local or external) opacity: float, default 0.25 Image layer opacity in range 0 (completely transparent) to 1 (opaque) min_lat: float, default -90.0 max_lat: float, default 90.0 min_lon: float, default -180.0 max_lon: float, default 180.0 image_name: string, default None The name of the layer object in leaflet.js filename: string, default None Optional file name of output.png for image overlay. If None, we use a inline PNG. Output ------ Image overlay data layer in obj.template_vars Examples ------- # assumes a map object `m` has been created >>> import numpy as np >>> data = np.random.random((100,100)) # to make a rgba from a specific matplotlib colormap: >>> import matplotlib.cm as cm >>> cmapper = cm.cm.ColorMapper('jet') >>> data2 = cmapper.to_rgba(np.random.random((100,100))) # place the data over all of the globe (will be pretty pixelated!) >>> m.image_overlay(data) # put it only over a single city (Paris) >>> m.image_overlay(data, min_lat=48.80418, max_lat=48.90970, min_lon=2.25214, max_lon=2.44731) """ if isinstance(data, str): filename = data else: try: png_str = utilities.write_png(data) except Exception as e: raise e if filename is not None: with open(filename, 'wb') as fd: fd.write(png_str) else: filename = "data:image/png;base64,"+base64.b64encode(png_str).decode('utf-8') if image_name not in self.added_layers: if image_name is None: image_name = "Image_Overlay" else: image_name = image_name.replace(" ", "_") image_url = filename image_bounds = [[min_lat, min_lon], [max_lat, max_lon]] image_opacity = opacity image_temp = self.env.get_template('image_layer.js') image = image_temp.render({'image_name': image_name, 'image_url': image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity}) self.template_vars['image_layers'].append(image) self.added_layers.append(image_name)
def image_overlay(self, data, image_opacity=1, min_lat=-90.0, max_lat=90.0, min_lon=-180.0, max_lon=180.0, image_name=None, filename=None): """ Simple image overlay of raster `data` from an image or a NumPy array. This is a lightweight way to overlay geospatial data on top of a map. The default lon, lat corners are the whole globe. Adjust it to your image. If `data` is is a NumPy array a PNG file will be created for you. If you do not specify a filename the image will be embedded inline. NOTE: The image must be projected as Web Mercator (https://en.wikipedia.org/wiki/Web_Mercator). See the examples below for re-projection. Parameters ---------- data: NumPy array OR image. The NumPy array can NxM (mono), NxMx3 (RGB), or NxMx4 (RGBA) image_opacity: float, default 1 Image layer image_opacity in range 0 (transparent) to 1 (opaque) min_lat: float (default: -90) max_lat: float (default: 90) min_lon: float (default: -180) max_lon: float (default" 180) image_name: string, default None The name of the layer object in leaflet.js filename: string or None, default None Optional file name of output.png for image overlay. If None, we use a inline PNG. Output ------ Image overlay data layer in obj.template_vars Examples ------- >>> import numpy as np >>> import matplotlib >>> def sample_data(shape=(73, 145)): ... nlats, nlons = shape ... lats = np.linspace(-np.pi / 2, np.pi / 2, nlats) ... lons = np.linspace(0, 2 * np.pi, nlons) ... lons, lats = np.meshgrid(lons, lats) ... wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons) ... mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2) ... lats = np.rad2deg(lats) ... lons = np.rad2deg(lons) ... data = wave + mean ... return lons, lats, data >>> # Lets create some data, >>> lon, lat, data = sample_data(shape=(73, 145)) >>> lon -= 180 >>> # and color it. >>> cm = matplotlib.cm.get_cmap('cubehelix') >>> normed_data = (data - data.min()) / (data.max() - data.min()) >>> colored_data = cm(normed_data) >>> # First no projection (wrong). >>> map = folium.Map(location=[lat.mean(), lon.mean()], zoom_start=1) >>> map.image_overlay(colored_data, ... min_lat=lat.min(), max_lat=lat.max(), ... min_lon=lon.min(), max_lon=lon.max(), ... image_opacity=0.25) >>> # Now lets project the data as to Web Mercator (correct). >>> map = folium.Map(location=[lat.mean(), lon.mean()], zoom_start=1) >>> project = geodetic_to_mercator(colored_data) >>> map.image_overlay(projected, ... min_lat=lat.min(), max_lat=lat.max(), ... min_lon=lon.min(), max_lon=lon.max(), ... image_opacity=0.25) """ if isinstance(data, str): filename = data else: try: png_str = utilities.write_png(data) except Exception as e: raise e if filename is not None: with open(filename, 'wb') as fd: fd.write(png_str) else: png = "data:image/png;base64,{}".format filename = png(base64.b64encode(png_str).decode('utf-8')) if image_name not in self.added_layers: if image_name is None: # FIXME: This will fails with multiple overlays! image_name = "Image_Overlay" else: # FIXME: We should write a more robust `name_normalizer()`. image_name = image_name.replace(" ", "_") image_url = filename image_bounds = [[min_lat, min_lon], [max_lat, max_lon]] image_templ = self.env.get_template('image_layer.js') image = image_templ.render({'image_name': image_name, 'image_url': image_url, 'image_bounds': image_bounds, 'image_opacity': image_opacity}) self.template_vars['image_layers'].append(image)