Skip to content

Commit 85a3958

Browse files
committed
Merge pull request #119 from themiurgo/fit_bounds
Introduce fit_bounds method
2 parents ecc3ae5 + cb0aff7 commit 85a3958

File tree

8 files changed

+351
-275
lines changed

8 files changed

+351
-275
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
0.1.5
22
~~~~~
3+
- `fit_bounds` method. (themiurgo)
34
- GeoJSON popup. (ocefpaf 7aad5e0)
45
- Added cartodb positron and dark_matter tiles (ocefpaf d4daee7)
56
- Forcing HTTPS when available. (ocefpaf c69ac89)

folium/folium.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,50 @@ def click_for_marker(self, popup=None):
610610
click_str = click_temp.render({'popup': popup_txt})
611611
self.template_vars.update({'click_pop': click_str})
612612

613+
def fit_bounds(self, bounds, padding_top_left=None,
614+
padding_bottom_right=None, padding=None, max_zoom=None):
615+
"""Fit the map to contain a bounding box with the maximum zoom level possible.
616+
617+
Parameters
618+
----------
619+
bounds: list of (latitude, longitude) points
620+
Bounding box specified as two points [southwest, northeast]
621+
padding_top_left: (x, y) point, default None
622+
Padding in the top left corner. Useful if some elements in
623+
the corner, such as controls, might obscure objects you're zooming
624+
to.
625+
padding_bottom_right: (x, y) point, default None
626+
Padding in the bottom right corner.
627+
padding: (x, y) point, default None
628+
Equivalent to setting both top left and bottom right padding to
629+
the same value.
630+
max_zoom: int, default None
631+
Maximum zoom to be used.
632+
633+
Example
634+
-------
635+
>>> map.fit_bounds([[52.193636, -2.221575], [52.636878, -1.139759]])
636+
637+
"""
638+
options = {
639+
'paddingTopLeft': padding_top_left,
640+
'paddingBottomRight': padding_bottom_right,
641+
'padding': padding,
642+
'maxZoom': max_zoom,
643+
}
644+
fit_bounds_options = {}
645+
for key, opt in options.items():
646+
if opt:
647+
fit_bounds_options[key] = opt
648+
fit_bounds = self.env.get_template('fit_bounds.js')
649+
fit_bounds_str = fit_bounds.render({
650+
'bounds': json.dumps(bounds),
651+
'fit_bounds_options': json.dumps(fit_bounds_options),
652+
})
653+
654+
self.template_vars.update({'fit_bounds': fit_bounds_str})
655+
656+
613657
def _popup_render(self, popup=None, mk_name=None, count=None,
614658
popup_on=True, width=300):
615659
"""Popup renderer: either text or Vincent/Vega.

folium/templates/fit_bounds.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
map.fitBounds({{ bounds }},
2+
{{ fit_bounds_options }}
3+
);

folium/templates/fol_template.html

Lines changed: 153 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,153 @@
1-
<!DOCTYPE html>
2-
<head>
3-
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
4-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css" />
5-
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script>
6-
7-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
8-
9-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
10-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
11-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
12-
13-
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
14-
15-
<link rel="stylesheet" href="https://rawgit.com/lvoogdt/Leaflet.awesome-markers/2.0/develop/dist/leaflet.awesome-markers.css">
16-
<script src="https://rawgithub.com/lvoogdt/Leaflet.awesome-markers/2.0/develop/dist/leaflet.awesome-markers.js"></script>
17-
18-
19-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.Default.css">
20-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.css">
21-
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster-src.js"></script>
22-
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster.js"></script>
23-
24-
<link rel="stylesheet" href="https://birdage.github.io/Leaflet.awesome-markers/dist/leaflet.awesome.rotate.css">
25-
26-
{{ dvf_js }}
27-
{{ d3 }}
28-
{{ vega }}
29-
{{ jquery }}
30-
31-
<style>
32-
33-
html, body {
34-
width: 100%;
35-
height: 100%;
36-
margin: 0;
37-
padding: 0;
38-
}
39-
40-
#map {
41-
position:absolute;
42-
top:0;
43-
bottom:0;
44-
right:0;
45-
left:0;
46-
}
47-
48-
</style>
49-
</head>
50-
51-
<body>
52-
53-
<div class="folium-map" id="{{ map_id }}" {{ size }}></div>
54-
55-
<script>
56-
57-
{{ vega_parse }}
58-
59-
var base_tile = L.tileLayer('{{ Tiles }}', {
60-
maxZoom: {{ max_zoom }},
61-
minZoom: {{ min_zoom }},
62-
attribution: '{{ attr }}'
63-
});
64-
65-
var baseLayer = {
66-
"Base Layer": base_tile
67-
};
68-
69-
/*
70-
addition of the wms layers
71-
*/
72-
73-
{% for wms in wms_layers %}
74-
{{ wms }}
75-
{% endfor %}
76-
77-
/*
78-
addition of the tile layers
79-
*/
80-
{% for tile in tile_layers %}
81-
{{ tile }}
82-
{% endfor %}
83-
84-
/*
85-
list of layers to be added
86-
*/
87-
var layer_list = {
88-
{% for data_string in data_layers %}
89-
{{ data_string }}
90-
{% endfor %}
91-
};
92-
93-
/*
94-
Bounding box.
95-
*/
96-
var southWest = L.latLng({{ min_lat }}, {{ min_lon }}),
97-
northEast = L.latLng({{ max_lat }}, {{ max_lon }}),
98-
bounds = L.latLngBounds(southWest, northEast);
99-
100-
/*
101-
Creates the map and adds the selected layers
102-
*/
103-
var map = L.map('{{ map_id }}', {
104-
center:[{{ lat }}, {{ lon }}],
105-
zoom: {{ zoom_level }},
106-
maxBounds: bounds,
107-
layers: [base_tile]
108-
});
109-
110-
L.control.layers(baseLayer, layer_list).addTo(map);
111-
112-
//cluster group
113-
var clusteredmarkers = L.markerClusterGroup();
114-
//section for adding clustered markers
115-
{% for icon, mark, popup, add_mark in cluster_markers %}
116-
{{ icon }}
117-
{{ mark }}
118-
{{ popup }}
119-
{{ add_mark }}
120-
{% endfor %}
121-
//add the clustered markers to the group anyway
122-
map.addLayer(clusteredmarkers);
123-
124-
{% for icon, mark, popup, add_mark in custom_markers %}
125-
{{ icon }}
126-
{{ mark }}
127-
{{ popup }}
128-
{{ add_mark }}
129-
{% endfor %}
130-
131-
{% for mark, popup, add_mark in markers %}
132-
{{ mark }}
133-
{{ popup }}
134-
{{ add_mark }}
135-
{% endfor %}
136-
137-
{% for line, add_line in lines %}
138-
{{ line }}
139-
{{ add_line }}
140-
{% endfor %}
141-
142-
{% for multiline, add_multiline in multilines %}
143-
{{ multiline }}
144-
{{ add_multiline }}
145-
{% endfor %}
146-
147-
{{ lat_lng_pop }}
148-
149-
{{ click_pop }}
150-
151-
</script>
152-
153-
</body>
1+
<!DOCTYPE html>
2+
<head>
3+
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
4+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css" />
5+
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script>
6+
7+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
8+
9+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
10+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
11+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
12+
13+
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
14+
15+
<link rel="stylesheet" href="https://rawgit.com/lvoogdt/Leaflet.awesome-markers/2.0/develop/dist/leaflet.awesome-markers.css">
16+
<script src="https://rawgithub.com/lvoogdt/Leaflet.awesome-markers/2.0/develop/dist/leaflet.awesome-markers.js"></script>
17+
18+
19+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.Default.css">
20+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.css">
21+
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster-src.js"></script>
22+
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster.js"></script>
23+
24+
<link rel="stylesheet" href="https://birdage.github.io/Leaflet.awesome-markers/dist/leaflet.awesome.rotate.css">
25+
26+
{{ dvf_js }}
27+
{{ d3 }}
28+
{{ vega }}
29+
{{ jquery }}
30+
31+
<style>
32+
33+
html, body {
34+
width: 100%;
35+
height: 100%;
36+
margin: 0;
37+
padding: 0;
38+
}
39+
40+
#map {
41+
position:absolute;
42+
top:0;
43+
bottom:0;
44+
right:0;
45+
left:0;
46+
}
47+
48+
</style>
49+
</head>
50+
51+
<body>
52+
53+
<div class="folium-map" id="{{ map_id }}" {{ size }}></div>
54+
55+
<script>
56+
57+
{{ vega_parse }}
58+
59+
var base_tile = L.tileLayer('{{ Tiles }}', {
60+
maxZoom: {{ max_zoom }},
61+
minZoom: {{ min_zoom }},
62+
attribution: '{{ attr }}'
63+
});
64+
65+
var baseLayer = {
66+
"Base Layer": base_tile
67+
};
68+
69+
/*
70+
addition of the wms layers
71+
*/
72+
73+
{% for wms in wms_layers %}
74+
{{ wms }}
75+
{% endfor %}
76+
77+
/*
78+
addition of the tile layers
79+
*/
80+
{% for tile in tile_layers %}
81+
{{ tile }}
82+
{% endfor %}
83+
84+
/*
85+
list of layers to be added
86+
*/
87+
var layer_list = {
88+
{% for data_string in data_layers %}
89+
{{ data_string }}
90+
{% endfor %}
91+
};
92+
93+
/*
94+
Bounding box.
95+
*/
96+
var southWest = L.latLng({{ min_lat }}, {{ min_lon }}),
97+
northEast = L.latLng({{ max_lat }}, {{ max_lon }}),
98+
bounds = L.latLngBounds(southWest, northEast);
99+
100+
/*
101+
Creates the map and adds the selected layers
102+
*/
103+
var map = L.map('{{ map_id }}', {
104+
center:[{{ lat }}, {{ lon }}],
105+
zoom: {{ zoom_level }},
106+
maxBounds: bounds,
107+
layers: [base_tile]
108+
});
109+
110+
L.control.layers(baseLayer, layer_list).addTo(map);
111+
112+
//cluster group
113+
var clusteredmarkers = L.markerClusterGroup();
114+
//section for adding clustered markers
115+
{% for icon, mark, popup, add_mark in cluster_markers %}
116+
{{ icon }}
117+
{{ mark }}
118+
{{ popup }}
119+
{{ add_mark }}
120+
{% endfor %}
121+
//add the clustered markers to the group anyway
122+
map.addLayer(clusteredmarkers);
123+
124+
{% for icon, mark, popup, add_mark in custom_markers %}
125+
{{ icon }}
126+
{{ mark }}
127+
{{ popup }}
128+
{{ add_mark }}
129+
{% endfor %}
130+
131+
{% for mark, popup, add_mark in markers %}
132+
{{ mark }}
133+
{{ popup }}
134+
{{ add_mark }}
135+
{% endfor %}
136+
137+
{% for line, add_line in lines %}
138+
{{ line }}
139+
{{ add_line }}
140+
{% endfor %}
141+
142+
{% for multiline, add_multiline in multilines %}
143+
{{ multiline }}
144+
{{ add_multiline }}
145+
{% endfor %}
146+
147+
{{ lat_lng_pop }}
148+
149+
{{ click_pop }}
150+
151+
</script>
152+
153+
</body>

0 commit comments

Comments
 (0)