|
26 | 26 | from .element import Element, Figure, JavascriptLink, CssLink, Div, MacroElement |
27 | 27 | from .map import Map, TileLayer, Icon, Marker, Popup, FitBounds |
28 | 28 | from .features import WmsTileLayer, RegularPolygonMarker, Vega, GeoJson, GeoJsonStyle, MarkerCluster, DivIcon,\ |
29 | | - CircleMarker, LatLngPopup, ClickForMarker, ColorScale, TopoJson, PolyLine, MultiPolyLine |
30 | | -from .utilities import color_brewer |
| 29 | + CircleMarker, LatLngPopup, ClickForMarker, ColorScale, TopoJson, PolyLine, MultiPolyLine, ImageOverlay |
| 30 | +from .utilities import color_brewer, write_png |
31 | 31 | #import sys |
32 | 32 | #import base64 |
33 | 33 |
|
@@ -907,96 +907,80 @@ def geo_json(self, geo_path=None, geo_str=None, data_out='data.json', |
907 | 907 | self.add_children(geo_json) |
908 | 908 | self.add_children(color_scale) |
909 | 909 |
|
910 | | -# @iter_obj('image_overlay') |
911 | | -# def image_overlay(self, data, opacity=0.25, min_lat=-90.0, max_lat=90.0, |
912 | | -# min_lon=-180.0, max_lon=180.0, image_name=None, |
913 | | -# filename=None): |
914 | | -# """ |
915 | | -# Simple image overlay of raster data from a numpy array. This is a |
916 | | -# lightweight way to overlay geospatial data on top of a map. If your |
917 | | -# data is high res, consider implementing a WMS server and adding a WMS |
918 | | -# layer. |
919 | | -# |
920 | | -# This function works by generating a PNG file from a numpy array. If |
921 | | -# you do not specify a filename, it will embed the image inline. |
922 | | -# Otherwise, it saves the file in the current directory, and then adds |
923 | | -# it as an image overlay layer in leaflet.js. By default, the image is |
924 | | -# placed and stretched using bounds that cover the entire globe. |
925 | | -# |
926 | | -# Parameters |
927 | | -# ---------- |
928 | | -# data: numpy array OR url string, required. |
929 | | -# if numpy array, must be a image format, |
930 | | -# i.e., NxM (mono), NxMx3 (rgb), or NxMx4 (rgba) |
931 | | -# if url, must be a valid url to a image (local or external) |
932 | | -# opacity: float, default 0.25 |
933 | | -# Image layer opacity in range 0 (transparent) to 1 (opaque) |
934 | | -# min_lat: float, default -90.0 |
935 | | -# max_lat: float, default 90.0 |
936 | | -# min_lon: float, default -180.0 |
937 | | -# max_lon: float, default 180.0 |
938 | | -# image_name: string, default None |
939 | | -# The name of the layer object in leaflet.js |
940 | | -# filename: string, default None |
941 | | -# Optional file name of output.png for image overlay. |
942 | | -# Use `None` for inline PNG. |
943 | | -# |
944 | | -# Output |
945 | | -# ------ |
946 | | -# Image overlay data layer in obj.template_vars |
947 | | -# |
948 | | -# Examples |
949 | | -# ------- |
950 | | -# # assumes a map object `m` has been created |
951 | | -# >>> import numpy as np |
952 | | -# >>> data = np.random.random((100,100)) |
953 | | -# |
954 | | -# # to make a rgba from a specific matplotlib colormap: |
955 | | -# >>> import matplotlib.cm as cm |
956 | | -# >>> cmapper = cm.cm.ColorMapper('jet') |
957 | | -# >>> data2 = cmapper.to_rgba(np.random.random((100,100))) |
958 | | -# >>> # Place the data over all of the globe (will be pretty pixelated!) |
959 | | -# >>> m.image_overlay(data) |
960 | | -# >>> # Put it only over a single city (Paris). |
961 | | -# >>> m.image_overlay(data, min_lat=48.80418, max_lat=48.90970, |
962 | | -# ... min_lon=2.25214, max_lon=2.44731) |
963 | | -# |
964 | | -# """ |
965 | | -# |
966 | | -# if isinstance(data, str): |
967 | | -# filename = data |
968 | | -# else: |
969 | | -# try: |
970 | | -# png_str = utilities.write_png(data) |
971 | | -# except Exception as e: |
972 | | -# raise e |
973 | | -# |
974 | | -# if filename is not None: |
975 | | -# with open(filename, 'wb') as fd: |
976 | | -# fd.write(png_str) |
977 | | -# else: |
978 | | -# png = "data:image/png;base64,{}".format |
979 | | -# filename = png(base64.b64encode(png_str).decode('utf-8')) |
980 | | -# |
981 | | -# if image_name not in self.added_layers: |
982 | | -# if image_name is None: |
983 | | -# image_name = "Image_Overlay" |
984 | | -# else: |
985 | | -# image_name = image_name.replace(" ", "_") |
986 | | -# image_url = filename |
987 | | -# image_bounds = [[min_lat, min_lon], [max_lat, max_lon]] |
988 | | -# image_opacity = opacity |
989 | | -# |
990 | | -# image_temp = self.env.get_template('image_layer.js') |
991 | | -# |
992 | | -# image = image_temp.render({'image_name': image_name, |
993 | | -# 'image_url': image_url, |
994 | | -# 'image_bounds': image_bounds, |
995 | | -# 'image_opacity': image_opacity}) |
996 | | -# |
997 | | -# self.template_vars['image_layers'].append(image) |
998 | | -# self.added_layers.append(image_name) |
999 | | -# |
| 910 | + def image_overlay(self, data, opacity=0.25, min_lat=-90.0, max_lat=90.0, |
| 911 | + min_lon=-180.0, max_lon=180.0, origin='upper', colormap=None, |
| 912 | + image_name=None, filename=None, mercator_project=False): |
| 913 | + """ |
| 914 | + Simple image overlay of raster data from a numpy array. This is a |
| 915 | + lightweight way to overlay geospatial data on top of a map. If your |
| 916 | + data is high res, consider implementing a WMS server and adding a WMS |
| 917 | + layer. |
| 918 | +
|
| 919 | + This function works by generating a PNG file from a numpy array. If |
| 920 | + you do not specify a filename, it will embed the image inline. |
| 921 | + Otherwise, it saves the file in the current directory, and then adds |
| 922 | + it as an image overlay layer in leaflet.js. By default, the image is |
| 923 | + placed and stretched using bounds that cover the entire globe. |
| 924 | +
|
| 925 | + Parameters |
| 926 | + ---------- |
| 927 | + data: numpy array OR url string, required. |
| 928 | + if numpy array, must be a image format, |
| 929 | + i.e., NxM (mono), NxMx3 (rgb), or NxMx4 (rgba) |
| 930 | + if url, must be a valid url to a image (local or external) |
| 931 | + opacity: float, default 0.25 |
| 932 | + Image layer opacity in range 0 (transparent) to 1 (opaque) |
| 933 | + min_lat: float, default -90.0 |
| 934 | + max_lat: float, default 90.0 |
| 935 | + min_lon: float, default -180.0 |
| 936 | + max_lon: float, default 180.0 |
| 937 | + image_name: string, default None |
| 938 | + The name of the layer object in leaflet.js |
| 939 | + filename: string, default None |
| 940 | + Optional file name of output.png for image overlay. |
| 941 | + Use `None` for inline PNG. |
| 942 | + origin : ['upper' | 'lower'], optional, default 'upper' |
| 943 | + Place the [0,0] index of the array in the upper left or lower left |
| 944 | + corner of the axes. |
| 945 | +
|
| 946 | + colormap : callable, used only for `mono` image. |
| 947 | + Function of the form [x -> (r,g,b)] or [x -> (r,g,b,a)] |
| 948 | + for transforming a mono image into RGB. |
| 949 | + It must output iterables of length 3 or 4, with values between 0. and 1. |
| 950 | + Hint : you can use colormaps from `matplotlib.cm`. |
| 951 | +
|
| 952 | + mercator_project : bool, default False, used only for array-like image. |
| 953 | + Transforms the data to project (longitude,latitude) coordinates to the Mercator projection. |
| 954 | + Output |
| 955 | + ------ |
| 956 | + Image overlay data layer in obj.template_vars |
| 957 | +
|
| 958 | + Examples |
| 959 | + ------- |
| 960 | + # assumes a map object `m` has been created |
| 961 | + >>> import numpy as np |
| 962 | + >>> data = np.random.random((100,100)) |
| 963 | +
|
| 964 | + # to make a rgba from a specific matplotlib colormap: |
| 965 | + >>> import matplotlib.cm as cm |
| 966 | + >>> cmapper = cm.cm.ColorMapper('jet') |
| 967 | + >>> data2 = cmapper.to_rgba(np.random.random((100,100))) |
| 968 | + >>> # Place the data over all of the globe (will be pretty pixelated!) |
| 969 | + >>> m.image_overlay(data) |
| 970 | + >>> # Put it only over a single city (Paris). |
| 971 | + >>> m.image_overlay(data, min_lat=48.80418, max_lat=48.90970, |
| 972 | + ... min_lon=2.25214, max_lon=2.44731) |
| 973 | +
|
| 974 | + """ |
| 975 | + if filename: |
| 976 | + image = write_png(data, origin=origin, colormap=colormap) |
| 977 | + open(filename,'wb').write(image) |
| 978 | + data = filename |
| 979 | + |
| 980 | + self.add_children(ImageOverlay(data, [[min_lat, min_lon],[max_lat,max_lon]], |
| 981 | + opacity=opacity, origin=origin, colormap=colormap, |
| 982 | + mercator_project=mercator_project)) |
| 983 | + |
1000 | 984 | # def _build_map(self, html_templ=None, templ_type='string'): |
1001 | 985 | # self._auto_bounds() |
1002 | 986 | # """Build HTML/JS/CSS from Templates given current map type.""" |
|
0 commit comments