Skip to content

Commit

Permalink
Merge pull request #151 from getcake/heatmap
Browse files Browse the repository at this point in the history
  • Loading branch information
getcake authored Aug 22, 2021
2 parents ade6679 + 1eb4032 commit 6b99292
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 18 deletions.
68 changes: 53 additions & 15 deletions flask_googlemaps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def __init__(
layer="",
map_ids=None,
bicycle_layer=False,
heatmap_data=None,
heatmap_layer=False,
**kwargs
):
# type: (...) -> None
Expand All @@ -68,7 +70,7 @@ def __init__(
self.zoom = zoom
self.maptype = maptype
self.markers = [] # type: List[Any]
self.map_ids = map_ids,
self.map_ids = map_ids
self.build_markers(markers)
self.rectangles = [] # type: List[Any]
self.build_rectangles(rectangles)
Expand Down Expand Up @@ -102,6 +104,9 @@ def __init__(
self.styles = styles
self.layer = layer
self.bicycle_layer = bicycle_layer
self.heatmap_layer = heatmap_layer
self.heatmap_data = []
self.build_heatmap(heatmap_data, heatmap_layer)

def build_markers(self, markers):
# type: (Optional[Union[Dict, List, Tuple]]) -> None
Expand Down Expand Up @@ -149,7 +154,7 @@ def add_marker(self, lat=None, lng=None, **kwargs):

def build_rectangles(self, rectangles):
# type: (Optional[List[Union[List, Tuple, Tuple[Tuple], Dict]]]) -> None
""" Process data to construct rectangles
"""Process data to construct rectangles
This method is built from the assumption that the rectangles parameter
is a list of:
Expand Down Expand Up @@ -227,7 +232,7 @@ def build_rectangle_dict(
fill_opacity=0.3, # type: float
):
# type: (...) -> Dict
""" Set a dictionary with the javascript class Rectangle parameters
"""Set a dictionary with the javascript class Rectangle parameters
This function sets a default drawing configuration if the user just
pass the rectangle bounds, but also allows to set each parameter
Expand Down Expand Up @@ -260,7 +265,7 @@ def build_rectangle_dict(

def add_rectangle(self, north=None, west=None, south=None, east=None, **kwargs):
# type: (Optional[float], Optional[float], Optional[float], Optional[float], **Any) -> None
""" Adds a rectangle dict to the Map.rectangles attribute
"""Adds a rectangle dict to the Map.rectangles attribute
The Google Maps API describes a rectangle using the LatLngBounds
object, which defines the bounds to be drawn. The bounds use the
Expand Down Expand Up @@ -307,7 +312,7 @@ def add_rectangle(self, north=None, west=None, south=None, east=None, **kwargs):

def build_circles(self, circles):
# type: (Optional[List[Union[List, Tuple, Dict]]]) -> None
""" Process data to construct rectangles
"""Process data to construct rectangles
This method is built from the assumption that the circles parameter
is a list of:
Expand Down Expand Up @@ -359,7 +364,7 @@ def build_circle_dict(
clickable=True, # type: bool
):
# type: (...) -> Dict
""" Set a dictionary with the javascript class Circle parameters
"""Set a dictionary with the javascript class Circle parameters
This function sets a default drawing configuration if the user just
pass the rectangle bounds, but also allows to set each parameter
Expand Down Expand Up @@ -394,7 +399,7 @@ def build_circle_dict(

def add_circle(self, center_lat=None, center_lng=None, radius=None, **kwargs):
# type: (Optional[float], Optional[float], Optional[float], **Any) -> None
""" Adds a circle dict to the Map.circles attribute
"""Adds a circle dict to the Map.circles attribute
The circle in a sphere is called "spherical cap" and is defined in the
Google Maps API by at least the center coordinates and its radius, in
Expand Down Expand Up @@ -436,7 +441,7 @@ def add_circle(self, center_lat=None, center_lng=None, radius=None, **kwargs):

def build_polylines(self, polylines):
# type: (Optional[List[Union[List, Tuple, Dict]]]) -> None
""" Process data to construct polylines
"""Process data to construct polylines
This method is built from the assumption that the polylines parameter
is a list of:
Expand Down Expand Up @@ -500,7 +505,7 @@ def build_polyline_dict(
self, path, stroke_color="#FF0000", stroke_opacity=0.8, stroke_weight=2
):
# type: (List[Dict], str, float, int) -> Dict
""" Set a dictionary with the javascript class Polyline parameters
"""Set a dictionary with the javascript class Polyline parameters
This function sets a default drawing configuration if the user just
pass the polyline path, but also allows to set each parameter
Expand Down Expand Up @@ -532,7 +537,7 @@ def build_polyline_dict(

def add_polyline(self, path=None, **kwargs):
# type: (Optional[List[Dict]], **Any) -> None
""" Adds a polyline dict to the Map.polylines attribute
"""Adds a polyline dict to the Map.polylines attribute
The Google Maps API describes a polyline as a "linear overlay of
connected line segments on the map". The linear paths are defined
Expand Down Expand Up @@ -577,7 +582,7 @@ def add_polyline(self, path=None, **kwargs):

def build_polygons(self, polygons):
# type: (Optional[List[Union[List, Tuple, Dict]]]) -> None
""" Process data to construct polygons
"""Process data to construct polygons
This method is built from the assumption that the polygons parameter
is a list of:
Expand Down Expand Up @@ -649,7 +654,7 @@ def build_polygon_dict(
fill_opacity=0.3, # type: float
):
# type: (...) -> Dict
""" Set a dictionary with the javascript class Polygon parameters
"""Set a dictionary with the javascript class Polygon parameters
This function sets a default drawing configuration if the user just
pass the polygon path, but also allows to set each parameter
Expand Down Expand Up @@ -687,7 +692,7 @@ def build_polygon_dict(

def add_polygon(self, path=None, **kwargs):
# type: (Optional[List[Dict]], **Any) -> None
""" Adds a polygon dict to the Map.polygons attribute
"""Adds a polygon dict to the Map.polygons attribute
The Google Maps API describes a polyline as a "linear overlay of
connected line segments on the map" and "form a closed loop and define
Expand Down Expand Up @@ -733,6 +738,37 @@ def add_polygon(self, path=None, **kwargs):

self.polygons.append(kwargs)

def build_heatmap(self, heatmap_data, heatmap_layer):
# type: (list, bool) -> dict
if not heatmap_layer:
return
if heatmap_layer and not heatmap_data:
raise AttributeError("heatmap_later requires 'heatmap_data'")
if not isinstance(heatmap_data, (list)):
raise AttributeError(
"heatmap_data only accepts a list of dicts with keys 'lat' 'lng' and their corresponding values"
)
for hm in heatmap_data:
if isinstance(hm, dict):
self.add_heatmap(**hm)
else:
raise AttributeError(
"elements of list 'heatmap_data' must be a dict of keys 'lat' and 'lng' with their corresponding values"
)

def add_heatmap(self, lat=None, lng=None, **kwargs):
# type: (Optional[float], Optional[float], **Any) -> None
if lat is not None:
kwargs["lat"] = lat
if lng is not None:
kwargs["lng"] = lng
if "lat" not in kwargs or "lng" not in kwargs:
raise AttributeError("heatmap_data requires 'lat' and 'lng' values")
if len(kwargs) > 2:
raise AttributeError("heatmap_data can only contain 'lat' and 'lng' values")

self.heatmap_data.append(kwargs)

def render(self, *args, **kwargs):
# type: (*Any, **Any) -> Text
return render_template(*args, **kwargs)
Expand Down Expand Up @@ -773,10 +809,12 @@ def as_json(self):
def verify_lat_lng_coordinates(self, lat, lng):
if not (90 >= lat >= -90):
raise AttributeError(
"Latitude must be between -90 and 90 degrees inclusive.")
"Latitude must be between -90 and 90 degrees inclusive."
)
if not (180 >= lng >= -180):
raise AttributeError(
"Longitude must be between -180 and 180 degrees inclusive.")
"Longitude must be between -180 and 180 degrees inclusive."
)

return (lat, lng)

Expand Down
30 changes: 27 additions & 3 deletions flask_googlemaps/templates/googlemaps/gmapjs.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
{% if not is_googlemaps_loaded() %} {% if GOOGLEMAPS_KEY %}
{% if not is_googlemaps_loaded() and not gmap.heatmap_layer %} {% if GOOGLEMAPS_KEY %}
<script src="//maps.googleapis.com/maps/api/js?key={{GOOGLEMAPS_KEY}}&map_ids={{gmap.map_ids}}&language={{gmap.language}}&region={{gmap.region}}" type="text/javascript"></script>
{% else %}
<script src="//maps.googleapis.com/maps/api/js?language={{gmap.language}}&region={{gmap.region}}" type="text/javascript"></script>
{% endif %} {{ set_googlemaps_loaded() }} {% endif %} {% if gmap.cluster %}
{% endif %} {{ set_googlemaps_loaded() }} {% endif %}{% if gmap.cluster %}
<script src="//cdnjs.cloudflare.com/ajax/libs/js-marker-clusterer/1.0.0/markerclusterer_compiled.js" type="text/javascript"></script>
{% endif %}
{% endif %}{% if gmap.heatmap_layer %}{% if GOOGLEMAPS_KEY %}
<script src="//maps.googleapis.com/maps/api/js?key={{GOOGLEMAPS_KEY}}&map_ids={{gmap.map_ids}}&language={{gmap.language}}&region={{gmap.region}}&libraries=visualization" type="text/javascript"></script>
{% endif %}{% endif%}


<style type="text/css">
#{{gmap.identifier}} { {{gmap.style}} }
Expand All @@ -13,6 +16,7 @@
<script type="text/javascript">
var {{gmap.varname}} = null;
var {{gmap.varname}}_markers = [];
var {{gmap.varname}}_heatmap_data = [];
var {{gmap.varname}}_rectangles = [];
var {{gmap.varname}}_circles = [];
var {{gmap.varname}}_polygons = [];
Expand Down Expand Up @@ -61,6 +65,21 @@
{% endif %}


// add heatmap layer
{% if gmap.heatmap_layer %}
var heatmapData = [];
var raw_heatmap_data = {{gmap.heatmap_data|tojson|safe}};
for(i=0; i < {{gmap.heatmap_data|length}}; i++) {
pos = new google.maps.LatLng(raw_heatmap_data[i].lat, raw_heatmap_data[i].lng);
heatmapData.push(pos);
}
var heatmap = new google.maps.visualization.HeatmapLayer({
data: heatmapData
});
heatmap.setMap({{gmap.varname}});

{% endif %}

// add gmap markers
var raw_markers = {{gmap.markers|tojson|safe}};
for(i=0; i<{{gmap.markers|length}};i++) {
Expand All @@ -72,6 +91,7 @@
label: raw_markers[i].label ? raw_markers[i].label : null
});


if(raw_markers[i].infobox)
{
google.maps.event.addListener(
Expand All @@ -80,6 +100,7 @@
getInfoCallback({{gmap.varname}}, raw_markers[i].infobox)
);
}

if("{{gmap.report_markerClickpos}}" === "True" )
{
google.maps.event.addListener(
Expand All @@ -89,12 +110,15 @@
);
}
{{gmap.varname}}_markers[i] = tempMarker;

}


{% if gmap.report_clickpos %}
google.maps.event.addListener(
{{gmap.varname}},
'click',

function(event) { clickposCallback('{{gmap.clickpos_uri}}', event.latLng) }
);
{% endif %}
Expand Down

0 comments on commit 6b99292

Please sign in to comment.