diff --git a/gmplot/gmplot.py b/gmplot/gmplot.py index 3968cfe..534625f 100644 --- a/gmplot/gmplot.py +++ b/gmplot/gmplot.py @@ -1,22 +1,9 @@ -from __future__ import absolute_import - -import json import math -import os import requests -import warnings - -from collections import namedtuple - -from gmplot.color_dicts import mpl_color_map, html_color_codes -from gmplot.google_maps_templates import SYMBOLS, CIRCLE - - -Symbol = namedtuple('Symbol', ['symbol', 'lat', 'long', 'size']) - +import json +import os -class InvalidSymbolError(Exception): - pass +from .color_dicts import mpl_color_map, html_color_codes def safe_iter(var): @@ -36,13 +23,10 @@ def __init__(self, center_lat, center_lng, zoom, apikey=''): self.paths = [] self.shapes = [] self.points = [] - self.circles = [] - self.symbols = [] self.heatmap_points = [] - self.ground_overlays = [] self.radpoints = [] self.gridsetting = None - self.coloricon = os.path.join(os.path.dirname(__file__), 'markers/%s.png') + self.coloricon = 'file:///' + os.path.dirname(__file__).replace('\\', '/') + '/markers/%s.png' self.color_dict = mpl_color_map self.html_color_codes = html_color_codes @@ -62,14 +46,15 @@ def geocode(self, location_string): def grid(self, slat, elat, latin, slng, elng, lngin): self.gridsetting = [slat, elat, latin, slng, elng, lngin] - def marker(self, lat, lng, color='#FF0000', c=None, title="no implementation"): + def marker(self, lat, lng, color='#FF0000', c=None, title="no implementation", label="", infoDict=None): + assert(infoDict is None or type(infoDict) == dict) if c: color = c color = self.color_dict.get(color, color) color = self.html_color_codes.get(color, color) - self.points.append((lat, lng, color[1:], title)) + self.points.append((lat, lng, color[1:], title, label, infoDict)) - def scatter(self, lats, lngs, color=None, size=None, marker=True, c=None, s=None, symbol='o', **kwargs): + def scatter(self, lats, lngs, color=None, size=None, marker=True, c=None, s=None, **kwargs): color = color or c size = size or s or 40 kwargs["color"] = color @@ -79,15 +64,7 @@ def scatter(self, lats, lngs, color=None, size=None, marker=True, c=None, s=None if marker: self.marker(lat, lng, settings['color']) else: - self._add_symbol(Symbol(symbol, lat, lng, size), **settings) - - def _add_symbol(self, symbol, color=None, c=None, **kwargs): - color = color or c - kwargs.setdefault('face_alpha', 0.5) - kwargs.setdefault('face_color', "#000000") - kwargs.setdefault("color", color) - settings = self._process_kwargs(kwargs) - self.symbols.append((symbol, settings)) + self.circle(lat, lng, size, **settings) def circle(self, lat, lng, radius, color=None, c=None, **kwargs): color = color or c @@ -95,35 +72,36 @@ def circle(self, lat, lng, radius, color=None, c=None, **kwargs): kwargs.setdefault('face_color', "#000000") kwargs.setdefault("color", color) settings = self._process_kwargs(kwargs) - self.circles.append(((lat, lng, radius), settings)) + path = self.get_cycle(lat, lng, radius) + self.shapes.append((path, settings)) def _process_kwargs(self, kwargs): settings = dict() settings["edge_color"] = kwargs.get("color", None) or \ - kwargs.get("edge_color", None) or \ - kwargs.get("ec", None) or \ - "#000000" + kwargs.get("edge_color", None) or \ + kwargs.get("ec", None) or \ + "#000000" settings["edge_alpha"] = kwargs.get("alpha", None) or \ - kwargs.get("edge_alpha", None) or \ - kwargs.get("ea", None) or \ - 1.0 + kwargs.get("edge_alpha", None) or \ + kwargs.get("ea", None) or \ + 1.0 settings["edge_width"] = kwargs.get("edge_width", None) or \ - kwargs.get("ew", None) or \ - 1.0 + kwargs.get("ew", None) or \ + 1.0 settings["face_alpha"] = kwargs.get("alpha", None) or \ - kwargs.get("face_alpha", None) or \ - kwargs.get("fa", None) or \ - 0.3 + kwargs.get("face_alpha", None) or \ + kwargs.get("fa", None) or \ + 0.3 settings["face_color"] = kwargs.get("color", None) or \ - kwargs.get("face_color", None) or \ - kwargs.get("fc", None) or \ - "#000000" + kwargs.get("face_color", None) or \ + kwargs.get("fc", None) or \ + "#000000" settings["color"] = kwargs.get("color", None) or \ - kwargs.get("c", None) or \ - settings["edge_color"] or \ - settings["face_color"] + kwargs.get("c", None) or \ + settings["edge_color"] or \ + settings["face_color"] # Need to replace "plum" with "#DDA0DD" and "c" with "#00FFFF" (cyan). for key, color in settings.items(): @@ -133,6 +111,7 @@ def _process_kwargs(self, kwargs): settings[key] = color settings["closed"] = kwargs.get("closed", None) + return settings def plot(self, lats, lngs, color=None, c=None, **kwargs): @@ -142,24 +121,19 @@ def plot(self, lats, lngs, color=None, c=None, **kwargs): path = zip(lats, lngs) self.paths.append((path, settings)) - def heatmap(self, lats, lngs, threshold=10, radius=10, gradient=None, opacity=0.6, maxIntensity=1, dissipating=True): + def heatmap(self, lats, lngs, threshold=10, radius=10, gradient=None, opacity=0.6, dissipating=True): """ :param lats: list of latitudes :param lngs: list of longitudes - :param maxIntensity:(int) max frequency to use when plotting. Default (None) uses max value on map domain. :param threshold: :param radius: The hardest param. Example (string): :return: """ settings = {} - # Try to give anyone using threshold a heads up. - if threshold != 10: - warnings.warn("The 'threshold' kwarg is deprecated, replaced in favor of maxIntensity.") settings['threshold'] = threshold settings['radius'] = radius settings['gradient'] = gradient settings['opacity'] = opacity - settings['maxIntensity'] = maxIntensity settings['dissipating'] = dissipating settings = self._process_heatmap_kwargs(settings) @@ -172,7 +146,6 @@ def _process_heatmap_kwargs(self, settings_dict): settings_string = '' settings_string += "heatmap.set('threshold', %d);\n" % settings_dict['threshold'] settings_string += "heatmap.set('radius', %d);\n" % settings_dict['radius'] - settings_string += "heatmap.set('maxIntensity', %d);\n" % settings_dict['maxIntensity'] settings_string += "heatmap.set('opacity', %f);\n" % settings_dict['opacity'] dissipation_string = 'true' if settings_dict['dissipating'] else 'false' @@ -190,34 +163,6 @@ def _process_heatmap_kwargs(self, settings_dict): return settings_string - def ground_overlay(self, url, bounds_dict): - ''' - :param url: Url of image to overlay - :param bounds_dict: dict of the form {'north': , 'south': , 'west': , 'east': } - setting the image container - :return: None - Example use: - import gmplot - gmap = gmplot.GoogleMapPlotter(37.766956, -122.438481, 13) - bounds_dict = {'north':37.832285, 'south': 37.637336, 'west': -122.520364, 'east': -122.346922} - gmap.ground_overlay('http://explore.museumca.org/creeks/images/TopoSFCreeks.jpg', bounds_dict) - gmap.draw("my_map.html") - Google Maps API documentation - https://developers.google.com/maps/documentation/javascript/groundoverlays#introduction - ''' - - bounds_string = self._process_ground_overlay_image_bounds(bounds_dict) - self.ground_overlays.append((url, bounds_string)) - - def _process_ground_overlay_image_bounds(self, bounds_dict): - bounds_string = 'var imageBounds = {' - bounds_string += "north: %.4f,\n" % bounds_dict['north'] - bounds_string += "south: %.4f,\n" % bounds_dict['south'] - bounds_string += "east: %.4f,\n" % bounds_dict['east'] - bounds_string += "west: %.4f};\n" % bounds_dict['west'] - - return bounds_string - def polygon(self, lats, lngs, color=None, c=None, **kwargs): color = color or c kwargs.setdefault("color", color) @@ -225,10 +170,9 @@ def polygon(self, lats, lngs, color=None, c=None, **kwargs): shape = zip(lats, lngs) self.shapes.append((shape, settings)) + # create the html file which include one google map and all points and + # paths def draw(self, htmlfile): - """Create the html file which include one google map and all points and paths. If - no string is provided, return the raw html. - """ f = open(htmlfile, 'w') f.write('\n') f.write('
\n') @@ -236,22 +180,19 @@ def draw(self, htmlfile): '\n') f.write( '\n') - f.write('{key}: {val}
' for key, val in infoDict.items()]) + f.write('\t\tvar infowindow%d = new google.maps.InfoWindow({\n' % i) + f.write(f'\t\tcontent: \'{contentString}\'\n') + f.write('\t\t});\n') + f.write('\t\tmarker%d.addListener(\'click\', function() {\n' % i) + f.write('\t\tinfowindow%d.open(map, marker%d);\n' % (i, i)) + f.write('\t\t});\n') + f.write('\n') def write_polyline(self, f, path, settings): clickable = False @@ -398,7 +337,7 @@ def write_polygon(self, f, path, settings): strokeOpacity = settings.get('edge_alpha') strokeWeight = settings.get('edge_width') fillColor = settings.get('face_color') or settings.get('color') - fillOpacity= settings.get('face_alpha') + fillOpacity = settings.get('face_alpha') f.write('var coords = [\n') for coordinate in path: f.write('new google.maps.LatLng(%f, %f),\n' % @@ -437,16 +376,6 @@ def write_heatmap(self, f): f.write('heatmap.setMap(map);' + '\n') f.write(settings_string) - def write_ground_overlay(self, f): - - for url, bounds_string in self.ground_overlays: - f.write(bounds_string) - f.write('var groundOverlay;' + '\n') - f.write('groundOverlay = new google.maps.GroundOverlay(' + '\n') - f.write('\n') - f.write("'" + url + "'," + '\n') - f.write('imageBounds);' + '\n') - f.write('groundOverlay.setMap(map);' + '\n') if __name__ == "__main__": @@ -461,18 +390,18 @@ def write_ground_overlay(self, f): mymap.marker(lat, lng, "red") mymap.circle(37.429, -122.145, 100, "#FF0000", ew=2) path = [(37.429, 37.428, 37.427, 37.427, 37.427), - (-122.145, -122.145, -122.145, -122.146, -122.146)] - path2 = [[i+.01 for i in path[0]], [i+.02 for i in path[1]]] - path3 = [(37.433302 , 37.431257 , 37.427644 , 37.430303), (-122.14488, -122.133121, -122.137799, -122.148743)] + (-122.145, -122.145, -122.145, -122.146, -122.146)] + path2 = [[i + .01 for i in path[0]], [i + .02 for i in path[1]]] + path3 = [(37.433302, 37.431257, 37.427644, 37.430303), (-122.14488, -122.133121, -122.137799, -122.148743)] path4 = [(37.423074, 37.422700, 37.422410, 37.422188, 37.422274, 37.422495, 37.422962, 37.423552, 37.424387, 37.425920, 37.425937), - (-122.150288, -122.149794, -122.148936, -122.148142, -122.146747, -122.14561, -122.144773, -122.143936, -122.142992, -122.147863, -122.145953)] + (-122.150288, -122.149794, -122.148936, -122.148142, -122.146747, -122.14561, -122.144773, -122.143936, -122.142992, -122.147863, -122.145953)] mymap.plot(path[0], path[1], "plum", edge_width=10) mymap.plot(path2[0], path2[1], "red") mymap.polygon(path3[0], path3[1], edge_color="cyan", edge_width=5, face_color="blue", face_alpha=0.1) mymap.heatmap(path4[0], path4[1], threshold=10, radius=40) - mymap.heatmap(path3[0], path3[1], threshold=10, radius=40, dissipating=False, gradient=[(30,30,30,0), (30,30,30,1), (50, 50, 50, 1)]) + mymap.heatmap(path3[0], path3[1], threshold=10, radius=40, dissipating=False, gradient=[(30, 30, 30, 0), (30, 30, 30, 1), (50, 50, 50, 1)]) mymap.scatter(path4[0], path4[1], c='r', marker=True) - mymap.scatter(path4[0], path4[1], s=90, marker=False, alpha=0.9, symbol='x', c='red', edge_width=4) + mymap.scatter(path4[0], path4[1], s=90, marker=False, alpha=0.1) # Get more points with: # http://www.findlatitudeandlongitude.com/click-lat-lng-list/ scatter_path = ([37.424435, 37.424417, 37.424417, 37.424554, 37.424775, 37.425099, 37.425235, 37.425082, 37.424656, 37.423957, 37.422952, 37.421759, 37.420447, 37.419135, 37.417822, 37.417209],