Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
422 changes: 422 additions & 0 deletions examples/ImageOverlay.ipynb

Large diffs are not rendered by default.

Binary file added examples/Mercator_projection_SW.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/Mercator_projection_SW.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions folium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Popup, TileLayer)

from folium.features import (ClickForMarker, ColorScale, CustomIcon, DivIcon,
GeoJson, ImageOverlay, LatLngPopup,
GeoJson, LatLngPopup,
MarkerCluster, MultiPolyLine, PolyLine, Vega,
RegularPolygonMarker, TopoJson, WmsTileLayer)

Expand All @@ -30,7 +30,6 @@
'DivIcon',
'GeoJson',
'GeoJsonStyle',
'ImageOverlay',
'LatLngPopup',
'MarkerCluster',
'MultiPolyLine',
Expand Down
80 changes: 7 additions & 73 deletions folium/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,22 @@
text_type, binary_type)

from .element import Element, Figure, JavascriptLink, CssLink, MacroElement
from .map import TileLayer, Icon, Marker, Popup
from .map import Layer, Icon, Marker, Popup


class WmsTileLayer(TileLayer):
class WmsTileLayer(Layer):
def __init__(self, url, name=None,
format=None, layers=None, transparent=True,
attr=None, overlay=True):
attr=None, overlay=True, control=True):
"""
TODO docstring here

"""
super(TileLayer, self).__init__()
super(WmsTileLayer, self).__init__(overlay=overlay, control=control)
self._name = 'WmsTileLayer'
self.tile_name = name if name is not None else 'WmsTileLayer_'+self._id
self.url = url
self.format = format
self.layers = layers
self.overlay = overlay
self.transparent = transparent
self.attr = attr

Expand All @@ -49,7 +47,6 @@ def __init__(self, url, name=None,
{% endmacro %}
""") # noqa


class RegularPolygonMarker(Marker):
def __init__(self, location, color='black', opacity=1, weight=2,
fill_color='blue', fill_opacity=1,
Expand Down Expand Up @@ -336,16 +333,16 @@ def render(self, **kwargs):
name='d3')


class MarkerCluster(MacroElement):
class MarkerCluster(Layer):
"""Adds a MarkerCluster layer on the map."""
def __init__(self):
def __init__(self, overlay=True, control=True):
"""Creates a MarkerCluster element to append into a map with
Map.add_children.

Parameters
----------
"""
super(MarkerCluster, self).__init__()
super(MarkerCluster, self).__init__(overlay=overlay, control=control)
self._name = 'MarkerCluster'
self._template = Template(u"""
{% macro script(this, kwargs) %}
Expand Down Expand Up @@ -608,69 +605,6 @@ def __init__(self, locations, color=None, weight=None,
{% endmacro %}
""") # noqa


class ImageOverlay(MacroElement):
def __init__(self, image, bounds, opacity=1., attr=None,
origin='upper', colormap=None, mercator_project=False):
"""
Used to load and display a single image over specific bounds of
the map, implements ILayer interface.

Parameters
----------
image: string, file or array-like object
The data you want to draw on the map.
* If string, it will be written directly in the output file.
* If file, it's content will be converted as embedded in the
output file.
* If array-like, it will be converted to PNG base64 string
and embedded in the output.
bounds: list
Image bounds on the map in the form [[lat_min, lon_min],
[lat_max, lon_max]]
opacity: float, default Leaflet's default (1.0)
attr: string, default Leaflet's default ("")
origin : ['upper' | 'lower'], optional, default 'upper'
Place the [0,0] index of the array in the upper left or
lower left corner of the axes.
colormap : callable, used only for `mono` image.
Function of the form [x -> (r,g,b)] or [x -> (r,g,b,a)]
for transforming a mono image into RGB.
It must output iterables of length 3 or 4,
with values between 0 and 1.
Hint : you can use colormaps from `matplotlib.cm`.
mercator_project : bool, default False.
Used only for array-like image. Transforms the data to
project (longitude, latitude) coordinates to the
Mercator projection.

"""
super(ImageOverlay, self).__init__()
self._name = 'ImageOverlay'

self.url = image_to_url(image, origin=origin,
mercator_project=mercator_project,
bounds=bounds)

self.bounds = json.loads(json.dumps(bounds))
options = {
'opacity': opacity,
'attribution': attr,
}
self.options = json.dumps({key: val for key, val
in options.items() if val},
sort_keys=True)
self._template = Template(u"""
{% macro script(this, kwargs) %}
var {{this.get_name()}} = L.imageOverlay(
'{{ this.url }}',
{{ this.bounds }},
{{ this.options }}
).addTo({{this._parent.get_name()}});
{% endmacro %}
""")


class CustomIcon(Icon):
def __init__(self, icon_image, icon_size=None, icon_anchor=None,
shadow_image=None, shadow_size=None, shadow_anchor=None,
Expand Down
10 changes: 7 additions & 3 deletions folium/folium.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
from .features import (WmsTileLayer, RegularPolygonMarker, Vega, GeoJson,
CircleMarker, LatLngPopup,
ClickForMarker, ColorScale, TopoJson, PolyLine,
MultiPolyLine, ImageOverlay)
from .utilities import color_brewer, write_png

MultiPolyLine)
from .utilities import color_brewer

def initialize_notebook():
"""Initialize the IPython notebook display elements."""
Expand Down Expand Up @@ -686,6 +685,11 @@ def image_overlay(self, data, opacity=0.25, min_lat=-90.0, max_lat=90.0,
... min_lon=2.25214, max_lon=2.44731)

"""
warnings.warn('This method is deprecated. Please use `Map.add_children('
'folium.plugins.ImageOverlay(...))` instead.')
from .plugins import ImageOverlay
from .utilities import write_png

if filename:
image = write_png(data, origin=origin, colormap=colormap)
open(filename, 'wb').write(image)
Expand Down
57 changes: 39 additions & 18 deletions folium/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,43 @@ def add_tile_layer(self, tiles='OpenStreetMap', name=None,
detect_retina=detect_retina)
self.add_children(tile_layer, name=tile_layer.tile_name)

class Layer(MacroElement):
"""An abstract class for everything that is a Layer on the map.
It will be used to define whether an object will be included in LayerControls.
"""
def __init__(self, name=None, overlay=False, control=True):
"""Creates a Layer instance.

class TileLayer(MacroElement):
Parameters
----------
name : string, default None
The name of the Layer, as it will appear in LayerControls
overlay : bool, default False
Whether the layer is optional (overlay) or compulsory.
control : bool, default True
Whether the Layer will be included in LayerControls
"""
super(Layer, self).__init__()
self.layer_name = name if name is not None else self.get_name()
self.overlay = overlay
self.control = control

class TileLayer(Layer):
def __init__(self, tiles='OpenStreetMap', name=None,
min_zoom=1, max_zoom=18, attr=None, API_key=None,
overlay=False, detect_retina=False):
overlay=False, control=True, detect_retina=False):
"""TODO docstring here
Parameters
----------
"""
super(TileLayer, self).__init__()
self._name = 'TileLayer'
self.tile_name = (name if name is not None else
''.join(tiles.lower().strip().split()))
super(TileLayer, self).__init__(name=self.tile_name, overlay=overlay, control=control)
self._name = 'TileLayer'

self.min_zoom = min_zoom
self.max_zoom = max_zoom

self.overlay = overlay
self.detect_retina = detect_retina

self.tiles = ''.join(tiles.lower().strip().split())
Expand Down Expand Up @@ -225,8 +244,8 @@ def __init__(self, tiles='OpenStreetMap', name=None,
""")


class FeatureGroup(TileLayer):
def __init__(self, name=None, overlay=True):
class FeatureGroup(Layer):
def __init__(self, name=None, overlay=True, control=True):
"""
Create a FeatureGroup layer ; you can put things in it and handle them
as a single layer. For example, you can add a LayerControl to
Expand All @@ -242,13 +261,11 @@ def __init__(self, name=None, overlay=True):
Whether your layer will be an overlay (ticked with a check box in
LayerControls) or a base layer (ticked with a radio button).
"""
super(TileLayer, self).__init__()
super(FeatureGroup, self).__init__(overlay=overlay, control=control)
self._name = 'FeatureGroup'

self.tile_name = name if name is not None else self.get_name()

self.overlay = overlay

self._template = Template(u"""
{% macro script(this, kwargs) %}
var {{this.get_name()}} = L.featureGroup(
Expand Down Expand Up @@ -286,18 +303,22 @@ def __init__(self):

def render(self, **kwargs):
"""TODO : docstring here."""
# We select all Layers for which (control and not overlay).
self.base_layers = OrderedDict(
[(val.tile_name, val.get_name()) for key, val in
self._parent._children.items() if
isinstance(val, TileLayer) and not hasattr(val, 'overlay')])
[(val.layer_name, val.get_name()) for key, val in
self._parent._children.items() if isinstance(val, Layer)
and (not hasattr(val, 'overlay') or not val.overlay)
and (not hasattr(val, 'control') or val.control)
])
# We select all Layers for which (control and overlay).
self.overlays = OrderedDict(
[(val.tile_name, val.get_name()) for key, val in
self._parent._children.items() if
isinstance(val, TileLayer) and hasattr(val, 'overlay')])

[(val.layer_name, val.get_name()) for key, val in
self._parent._children.items() if isinstance(val, Layer)
and (hasattr(val, 'overlay') and val.overlay)
and (not hasattr(val, 'control') or val.control)
])
super(LayerControl, self).render()


class Icon(MacroElement):
def __init__(self, color='blue', icon_color='white', icon='info-sign',
angle=0, prefix='glyphicon'):
Expand Down
5 changes: 4 additions & 1 deletion folium/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
from .boat_marker import BoatMarker
from .timestamped_geo_json import TimestampedGeoJson
from .heat_map import HeatMap
from .image_overlay import ImageOverlay

__all__ = ['MarkerCluster',
'ScrollZoomToggler',
'Terminator',
'BoatMarker',
'TimestampedGeoJson',
'HeatMap']
'HeatMap',
'ImageOverlay',
]
Loading