예제 #1
0
파일: marker.py 프로젝트: tirkarthi/gmplot
    def __init__(self, lat, lng, **kwargs):
        '''
        Args:
            lat (float): Latitude of the marker.
            lng (float): Longitude of the marker.

        Optional:

        Args:
            color/c/face_color/fc (str): Marker color. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to red.
            title (str): Hover-over title of the marker.
            label (str): Label displayed on the marker.
            info_window (str): HTML content to be displayed in a pop-up `info window`_.
            draggable (bool): Whether or not the marker is `draggable`_. Defaults to False.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.

        .. _info window: https://developers.google.com/maps/documentation/javascript/infowindows
        .. _draggable: https://developers.google.com/maps/documentation/javascript/markers#draggable
        '''
        color = _get_hex_color(
            _get_value(kwargs, ['color', 'c', 'face_color', 'fc'],
                       'red',
                       pop=True))
        self._marker_icon = _MarkerIcon(color)

        self._info_window = _get_value(kwargs, ['info_window'], pop=True)
        if self._info_window is not None:
            self._marker_info_window = _MarkerInfoWindow(self._info_window)

        precision = _get_value(kwargs, ['precision'], 6, pop=True)
        self._raw_marker = _RawMarker(_format_LatLng(lat, lng, precision),
                                      self._marker_icon.get_name(), **kwargs)
예제 #2
0
파일: plus.py 프로젝트: tirkarthi/gmplot
    def __init__(self, lat, lng, size, **kwargs):
        '''
        Args:
            lat (float): Latitude of the center of the '+'.
            lng (float): Longitude of the center of the '+'.
            size (int): Size of the '+', in meters.

        Optional:

        Args:
            color/c/edge_color/ec (str): Color of the '+''s edge.
                Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/edge_alpha/ea (float): Opacity of the '+''s edge, ranging from 0 to 1. Defaults to 1.0.
            edge_width/ew (int): Width of the '+''s edge, in pixels. Defaults to 1.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
        '''
        kwargs.setdefault('edge_color', _get_hex_color(_get_value(kwargs, ['color', 'c', 'edge_color', 'ec'], 'black')))
        kwargs.setdefault('edge_alpha', _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'], 1.0))
        kwargs.setdefault('edge_width', _get_value(kwargs, ['edge_width', 'ew'], 1))
        kwargs.setdefault('precision', _get_value(kwargs, ['precision'], 6))

        # TODO: The following generates a '+' in Cartesian frame rather than in lat/lng; avoid this.
        delta_lat = (size / 1000.0 / _EARTH_RADIUS_IN_KM) * (180.0 / math.pi)
        delta_lng = delta_lat / math.cos(math.pi * lat / 180.0)

        self._horizontal_stroke = _Polyline([lat, lat], [lng - delta_lng, lng + delta_lng], **kwargs)
        self._vertical_stroke = _Polyline([lat - delta_lat, lat + delta_lat], [lng, lng], **kwargs)
예제 #3
0
    def __init__(self, lats, lngs, **kwargs):
        '''
        Args:
            lats ([float]): Latitudes.
            lngs ([float]): Longitudes.

        Optional:

        Args:
            color/c/edge_color/ec (str): Color of the polyline.
                Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/edge_alpha/ea (float): Opacity of the polyline, ranging from 0 to 1. Defaults to 1.0.
            edge_width/ew (int): Width of the polyline, in pixels. Defaults to 1.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
        '''
        self._color = _get_hex_color(
            _get_value(kwargs, ['color', 'c', 'edge_color', 'ec'], 'black'))
        self._edge_alpha = _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'],
                                      1.0)
        self._edge_width = _get_value(kwargs, ['edge_width', 'ew'], 1)

        precision = _get_value(kwargs, ['precision'], 6)

        self._points = [
            _format_LatLng(lat, lng, precision)
            for lat, lng in zip(lats, lngs)
        ]
예제 #4
0
    def from_geocode(cls, location, **kwargs):
        '''
        Initialize a GoogleMapPlotter object using a location string (instead of a specific lat/lng location).

        Requires `Geocoding API`_.

        Args:
            location (str): Location or address of interest, as a human-readable string.

        Optional:

        Args:
            zoom (int): `Zoom level`_, where 0 is fully zoomed out. Defaults to 13.
            map_type (str): `Map type`_.
            apikey (str): Google Maps `API key`_.
            title (str): Title of the HTML file (as it appears in the browser tab).
            map_styles ([dict]): `Map styles`_. Requires `Maps JavaScript API`_.
            tilt (int): `Tilt`_ of the map upon zooming in.
            scale_control (bool): Whether or not to display the `scale control`_. Defaults to False.
            fit_bounds (dict): Fit the map to contain the given bounds, as a dict of the form
                ``{'north': float, 'south': float, 'east': float, 'west': float}``.
            precision (int): Number of digits after the decimal to round to for the lat/lng center. Defaults to 6.

        Returns:
            :class:`GoogleMapPlotter`

        .. _Geocoding API: https://console.cloud.google.com/marketplace/details/google/geocoding-backend.googleapis.com
        .. _Zoom level: https://developers.google.com/maps/documentation/javascript/tutorial#zoom-levels
        .. _Map type: https://developers.google.com/maps/documentation/javascript/maptypes
        .. _API key: https://developers.google.com/maps/documentation/javascript/get-api-key
        .. _Map styles: https://developers.google.com/maps/documentation/javascript/style-reference
        .. _Maps JavaScript API: https://console.cloud.google.com/marketplace/details/google/maps-backend.googleapis.com
        .. _Tilt: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.tilt
        .. _scale control: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.scaleControl

        Usage::

            import gmplot
            apikey = '' # (your API key here)
            gmap = gmplot.GoogleMapPlotter.from_geocode('Chiyoda City, Tokyo', apikey=apikey)
            gmap.draw("map.html")

        .. image:: GoogleMapPlotter.from_geocode.png
        '''
        zoom = _get_value(kwargs, ['zoom'], 13, pop=True)
        apikey = _get_value(kwargs, ['apikey'], '')
        return cls(*GoogleMapPlotter.geocode(location, apikey=apikey),
                   zoom=zoom,
                   **kwargs)
예제 #5
0
    def heatmap(self, lats, lngs, **kwargs):
        '''
        Plot a heatmap.

        Args:
            lats ([float]): Latitudes.
            lngs ([float]): Longitudes.

        Optional:

        Args:
            radius (int): Radius of influence for each data point, in pixels. Defaults to 10.
            gradient ([(int, int, int, float)]): Color gradient of the heatmap, as a list of `RGBA`_ colors.
                The color order defines the gradient moving towards the center of a point.
            opacity (float): Opacity of the heatmap, ranging from 0 to 1. Defaults to 0.6.
            max_intensity (int): Maximum intensity of the heatmap. Defaults to 1.
            dissipating (bool): True to dissipate the heatmap on zooming, False to disable dissipation. Defaults to True.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
            weights ([float]): List of weights corresponding to each data point. Each point has a weight
                of 1 by default. Specifying a weight of N is equivalent to plotting the same point N times.
        
        .. _RGBA: https://www.w3.org/TR/css-color-3/#rgba-color

        Usage::

            import gmplot
            apikey = '' # (your API key here)
            gmap = gmplot.GoogleMapPlotter(37.766956, -122.448481, 14, apikey=apikey)

            attractions = zip(*[
                (37.769901, -122.498331),
                (37.768645, -122.475328),
                (37.771478, -122.468677),
                (37.769867, -122.466102),
                (37.767187, -122.467496),
                (37.770104, -122.470436)
            ])

            gmap.heatmap(
                *attractions,
                radius=40,
                weights=[5, 1, 1, 1, 3, 1],
                gradient=[(0, 0, 255, 0), (0, 255, 0, 0.9), (255, 0, 0, 1)]
            )

            gmap.draw('map.html')

        .. image:: GoogleMapPlotter.heatmap.png
        '''
        if len(lats) != len(lngs):
            raise ValueError("Number of latitudes and longitudes don't match!")

        weights = _get_value(kwargs, ['weights'])
        if weights is not None and len(weights) != len(lats):
            raise ValueError(
                "`weights`' length doesn't match the number of points!")

        self._drawables.append(_Heatmap(lats, lngs, **kwargs))
예제 #6
0
    def __init__(self, lats, lngs, **kwargs):
        '''
        Args:
            lats ([float]): Latitudes.
            lngs ([float]): Longitudes.

        Optional:

        Args:
            radius (int): Radius of influence for each data point, in pixels. Defaults to 10.
            gradient ([(int, int, int, float)]): Color gradient of the heatmap, as a list of `RGBA`_ colors.
                The color order defines the gradient moving towards the center of a point.
            opacity (float): Opacity of the heatmap, ranging from 0 to 1. Defaults to 0.6.
            max_intensity (int): Maximum intensity of the heatmap. Defaults to 1.
            dissipating (bool): True to dissipate the heatmap on zooming, False to disable dissipation. Defaults to True.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
            weights ([float]): List of weights corresponding to each data point. Each point has a weight
                of 1 by default. Specifying a weight of N is equivalent to plotting the same point N times.
        
        .. _RGBA: https://www.w3.org/TR/css-color-3/#rgba-color
        '''
        self._radius = _get_value(kwargs, ['radius'], 10)
        self._gradient = _get_value(kwargs, ['gradient'], [])
        self._opacity = _get_value(kwargs, ['opacity'], 0.6)
        self._max_intensity = _get_value(kwargs, ['max_intensity'], 1)
        self._dissipating = _get_value(kwargs, ['dissipating'], True)

        precision = _get_value(kwargs, ['precision'], 6)
        weights = _get_value(kwargs, ['weights'],
                             [self._DEFAULT_WEIGHT] * len(lats))

        self._points = [
            self._Point(_format_LatLng(lat, lng, precision), weight)
            for lat, lng, weight in zip(lats, lngs, weights)
        ]
예제 #7
0
    def __init__(self, position, icon, **kwargs):
        '''
        Args:
            position (str): JavaScript code that represents the position of the marker.
            icon (str): JavaScript code that represents the icon.

        Optional:

        Args:
            title (str): Hover-over title of the marker.
            label (str): Label displayed on the marker.
            draggable (bool): Whether or not the marker is draggable. Defaults to False.
        '''
        self._position = position
        self._icon = icon
        self._title = _get_value(kwargs, ['title'])
        self._label = _get_value(kwargs, ['label'])
        self._draggable = _get_value(kwargs, ['draggable'], False)
예제 #8
0
    def __init__(self, lat, lng, text, **kwargs):
        '''
        Args:
            lat (float): Latitude of the text label.
            lng (float): Longitude of the text label.
            text (str): Text to display.

        Optional:

        Args:
            color/c (str): Text color. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
        '''
        precision = _get_value(kwargs, ['precision'], 6)
        self._position = _format_LatLng(lat, lng, precision)
        self._text = text
        self._color = _get_hex_color(
            _get_value(kwargs, ['color', 'c'], 'black'))
        self._icon = _get_embeddable_image(_COLOR_ICON_PATH % 'clear')
예제 #9
0
파일: map.py 프로젝트: tirkarthi/gmplot
    def __init__(self, lat, lng, zoom, **kwargs):
        '''
        Args:
            lat (float): Latitude of the center of the map.
            lng (float): Longitude of the center of the map.
            zoom (int): `Zoom level`_, where 0 is fully zoomed out.

        Optional:

        Args:
            map_type (str): `Map type`_.
            map_styles ([dict]): `Map styles`_. Requires `Maps JavaScript API`_.
            tilt (int): `Tilt`_ of the map upon zooming in.
            scale_control (bool): Whether or not to display the `scale control`_. Defaults to False.
            fit_bounds (dict): Fit the map to contain the given bounds, as a dict of the form
                ``{'north': float, 'south': float, 'east': float, 'west': float}``.
            precision (int): Number of digits after the decimal to round to for the lat/lng center. Defaults to 6.

        .. _Zoom level: https://developers.google.com/maps/documentation/javascript/tutorial#zoom-levels
        .. _Map type: https://developers.google.com/maps/documentation/javascript/maptypes
        .. _Map styles: https://developers.google.com/maps/documentation/javascript/style-reference
        .. _Maps JavaScript API: https://console.cloud.google.com/marketplace/details/google/maps-backend.googleapis.com
        .. _Tilt: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.tilt
        .. _scale control: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.scaleControl
        '''
        precision = _get_value(kwargs, ['precision'], 6)
        self._center = _format_LatLng(lat, lng, precision)
        self._zoom = zoom
        self._map_type = _get_value(kwargs, ['map_type'])
        self._map_styles = _get_value(kwargs, ['map_styles'], [])
        self._tilt = _get_value(kwargs, ['tilt'])
        self._scale_control = _get_value(kwargs, ['scale_control'], False)
        self._fit_bounds = _get_value(kwargs, ['fit_bounds'])
예제 #10
0
파일: circle.py 프로젝트: tirkarthi/gmplot
    def __init__(self, lat, lng, radius, **kwargs):
        '''
        Args:
            lat (float): Latitude of the center of the circle.
            lng (float): Longitude of the center of the circle.
            radius (int): Radius of the circle, in meters.

        Optional:

        Args:
            color/c/edge_color/ec (str): Color of the circle's edge.
                Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/edge_alpha/ea (float): Opacity of the circle's edge, ranging from 0 to 1. Defaults to 1.0.
            edge_width/ew (int): Width of the circle's edge, in pixels. Defaults to 1.
            color/c/face_color/fc (str): Color of the circle's face.
                Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/face_alpha/fa (float): Opacity of the circle's face, ranging from 0 to 1. Defaults to 0.5.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
        '''
        precision = _get_value(kwargs, ['precision'], 6)
        self._center = _format_LatLng(lat, lng, precision)
        self._radius = radius
        self._edge_color = _get_hex_color(_get_value(kwargs, ['color', 'c', 'edge_color', 'ec'], 'black'))
        self._edge_alpha = _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'], 1.0)
        self._edge_width = _get_value(kwargs, ['edge_width', 'ew'], 1)
        self._face_color = _get_hex_color(_get_value(kwargs, ['color', 'c', 'face_color', 'fc'], 'black'))
        self._face_alpha = _get_value(kwargs, ['alpha', 'face_alpha', 'fa'], 0.5)
예제 #11
0
파일: route.py 프로젝트: tirkarthi/gmplot
    def __init__(self, origin, destination, **kwargs):
        '''
        Args:
            origin ((float, float)): Origin, as a latitude/longitude tuple.
            destination ((float, float)): Destination, as a latitude/longitude tuple.

        Optional:

        Args:
            travel_mode (str): Travel mode. Defaults to 'DRIVING'.
            waypoints ([(float, float)]): Waypoints.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
        '''
        precision = _get_value(kwargs, ['precision'], 6)
        self._origin = _format_LatLng(*origin, precision=precision)
        self._destination = _format_LatLng(*destination, precision=precision)
        self._travel_mode = _get_value(kwargs, ['travel_mode'],
                                       'DRIVING').upper()
        self._waypoints = [
            _format_LatLng(*waypoint, precision=precision)
            for waypoint in _get_value(kwargs, ['waypoints'], [])
        ]
예제 #12
0
    def __init__(self, url, bounds, **kwargs):
        '''
        Args:
            url (str): URL of image to overlay.
            bounds (dict): Image bounds, as a dict of the form
                ``{'north': float, 'south': float, 'east': float, 'west': float}``.

        Optional:

        Args:
            opacity (float): Opacity of the overlay, ranging from 0 to 1. Defaults to 1.0.
        '''
        self._url = url
        self._bounds = bounds
        self._opacity = _get_value(kwargs, ['opacity'], 1.0)
예제 #13
0
    def __init__(self, **kwargs):
        '''
        Optional:

        Args:
            color/c (str): Color of the markers to be dropped. Can be hex ('#00FFFF'), named ('cyan'),
                or matplotlib-like ('c'). Defaults to red.
            title (str): Hover-over title of the markers to be dropped.
            label (str): Label displayed on the markers to be dropped.
            draggable (bool): Whether or not the markers to be dropped are draggable. Defaults to False.
        '''
        color = _get_hex_color(
            _get_value(kwargs, ['color', 'c'], 'red', pop=True))
        self._marker_icon = _MarkerIcon(color)
        self._marker = _RawMarker('%s.latLng' % self._EVENT_OBJECT_NAME,
                                  self._marker_icon.get_name(), **kwargs)
예제 #14
0
    def geocode(location, **kwargs):
        '''
        Return the lat/lng coordinates of a location string.

        Requires `Geocoding API`_.

        Args:
            location (str): Location or address of interest, as a human-readable string.

        Optional:

        Args:
            apikey (str): Google Maps `API key`_.

        .. _Geocoding API: https://console.cloud.google.com/marketplace/details/google/geocoding-backend.googleapis.com
        .. _API key: https://developers.google.com/maps/documentation/javascript/get-api-key

        Returns:
            (float, float): Latitude/longitude coordinates of the given location string.

        Usage::

            import gmplot
            apikey = '' # (your API key here)
            location = gmplot.GoogleMapPlotter.geocode('Versailles, France', apikey=apikey)
            print(location)

        .. code-block::

            -> (48.801408, 2.130122)
        '''
        apikey = _get_value(kwargs, ['apikey'], '')
        geocode = requests.get(
            'https://maps.googleapis.com/maps/api/geocode/json?address="%s"&key=%s'
            % (location, apikey))
        geocode = json.loads(geocode.text)
        if geocode.get('error_message', ''):
            raise GoogleAPIError(geocode['error_message'])

        latlng_dict = geocode['results'][0]['geometry']['location']
        return latlng_dict['lat'], latlng_dict['lng']
예제 #15
0
    def __init__(self, shape, lat, lng, size, **kwargs):
        '''
        Args:
            shape (str): Shape of the symbol, as 'o', 'x', or '+'.
            lat (float): Latitude of the center of the symbol.
            lng (float): Longitude of the center of the symbol.
            size (int): Size of the symbol, in meters.

        Optional:

        Args:
            color/c/edge_color/ec (str): Color of the symbol's edge.
                Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/edge_alpha/ea (float): Opacity of the symbol's edge, ranging from 0 to 1. Defaults to 1.0.
            edge_width/ew (int): Width of the symbol's edge, in pixels. Defaults to 1.
            color/c/face_color/fc (str): Color of the symbol's face.
                Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/face_alpha/fa (float): Opacity of the symbol's face, ranging from 0 to 1. Defaults to 0.5.
            precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.
        '''
        kwargs.setdefault(
            'edge_color',
            _get_hex_color(
                _get_value(kwargs, ['color', 'c', 'edge_color', 'ec'],
                           'black')))
        kwargs.setdefault(
            'edge_alpha', _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'],
                                     1.0))
        kwargs.setdefault('edge_width',
                          _get_value(kwargs, ['edge_width', 'ew'], 1))
        kwargs.setdefault(
            'face_color',
            _get_hex_color(
                _get_value(kwargs, ['color', 'c', 'face_color', 'fc'],
                           'black')))
        kwargs.setdefault(
            'face_alpha', _get_value(kwargs, ['alpha', 'face_alpha', 'fa'],
                                     0.5))
        kwargs.setdefault('precision', _get_value(kwargs, ['precision'], 6))

        self._symbol = self._SHAPES[shape](lat, lng, size, **kwargs)
예제 #16
0
    def __init__(self, lat, lng, zoom, **kwargs):
        '''
        Args:
            lat (float): Latitude of the center of the map.
            lng (float): Longitude of the center of the map.
            zoom (int): `Zoom level`_, where 0 is fully zoomed out.

        Optional:

        Args:
            map_type (str): `Map type`_.
            apikey (str): Google Maps `API key`_.
            title (str): Title of the HTML file (as it appears in the browser tab).
            map_styles ([dict]): `Map styles`_. Requires `Maps JavaScript API`_.
            tilt (int): `Tilt`_ of the map upon zooming in.
            scale_control (bool): Whether or not to display the `scale control`_. Defaults to False.
            fit_bounds (dict): Fit the map to contain the given bounds, as a dict of the form
                ``{'north': float, 'south': float, 'east': float, 'west': float}``.
            precision (int): Number of digits after the decimal to round to for the lat/lng center. Defaults to 6.

        .. _Zoom level: https://developers.google.com/maps/documentation/javascript/tutorial#zoom-levels
        .. _Map type: https://developers.google.com/maps/documentation/javascript/maptypes
        .. _API key: https://developers.google.com/maps/documentation/javascript/get-api-key
        .. _Map styles: https://developers.google.com/maps/documentation/javascript/style-reference
        .. _Maps JavaScript API: https://console.cloud.google.com/marketplace/details/google/maps-backend.googleapis.com
        .. _Tilt: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.tilt
        .. _scale control: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.scaleControl

        Usage::

            import gmplot
            apikey = '' # (your API key here)
            gmap = gmplot.GoogleMapPlotter(37.7670, -122.4385, 13, apikey=apikey, map_type='hybrid')
            gmap.draw("map.html")

        .. image:: GoogleMapPlotter.png

        Further customization and `styling`_::

            import gmplot

            apikey = '' # (your API key here)
            bounds = {'north': 37.967, 'south': 37.567, 'east': -122.238, 'west': -122.638}
            map_styles = [
                {
                    'featureType': 'all',
                    'stylers': [
                        {'saturation': -80},
                        {'lightness': 30},
                    ]
                }
            ]

            gmplot.GoogleMapPlotter(
                37.766956, -122.438481, 13,
                apikey=apikey,
                map_styles=map_styles,
                scale_control=True,
                fit_bounds=bounds
            ).draw("map.html")

        .. _styling: https://developers.google.com/maps/documentation/javascript/styling

        .. image:: GoogleMapPlotter_Styled.png
        '''
        self._apikey = _get_value(kwargs, ['apikey'], '', pop=True)
        self._title = _get_value(kwargs, ['title'],
                                 'Google Maps - gmplot',
                                 pop=True)

        self._map = _Map(lat, lng, zoom, **kwargs)
        self._drawables = []
        self._markers = []
        self._marker_dropper = None
예제 #17
0
    def scatter(self, lats, lngs, **kwargs):
        '''
        Plot a collection of points.

        Args:
            lats ([float]): Latitudes.
            lngs ([float]): Longitudes.

        Optional:

        Args:
            marker (bool or [bool]): True to plot points as markers, False to plot them as symbols. Defaults to True.
            title (str or [str]): Hover-over title of each point (markers only).
            label (str or [str]): Label displayed on each point (markers only).
            info_window (str or [str]): HTML content to be displayed in each point's pop-up `info window`_ (markers only).
            draggable (bool): Whether or not each point is `draggable`_ (markers only). Defaults to False.
            symbol (str or [str]): Shape of each point, as 'o', 'x', or '+' (symbols only). Defaults to 'o'.
            size/s (int or [int]): Size of each point, in meters (symbols only). Defaults to 40.
            color/c/edge_color/ec (str or [str]):
                Color of each point's edge (symbols only). Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/edge_alpha/ea (float or [float]):
                Opacity of each point's edge, ranging from 0 to 1 (symbols only). Defaults to 1.0.
            edge_width/ew (int or [int]): Width of each point's edge, in pixels (symbols only). Defaults to 1.
            color/c/face_color/fc (str or [str]):
                Color of each point's face. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black.
            alpha/face_alpha/fa (float or [float]):
                Opacity of each point's face, ranging from 0 to 1 (symbols only). Defaults to 0.3.
            precision (int or [int]): Number of digits after the decimal to round to for lat/lng values. Defaults to 6.

        .. _info window: https://developers.google.com/maps/documentation/javascript/infowindows
        .. _draggable: https://developers.google.com/maps/documentation/javascript/markers#draggable

        Usage::

            import gmplot
            apikey = '' # (your API key here)
            gmap = gmplot.GoogleMapPlotter(37.766956, -122.479481, 15, apikey=apikey)

            attractions = zip(*[
                (37.769901, -122.498331),
                (37.768645, -122.475328),
                (37.771478, -122.468677),
                (37.769867, -122.466102),
                (37.767187, -122.467496),
                (37.770104, -122.470436)
            ])

            gmap.scatter(
                *attractions,
                color=['red', 'orange', 'yellow', 'green', 'blue', 'purple'],
                s=60,
                ew=2,
                marker=[True, True, False, True, False, False],
                symbol=[None, None, 'o', None, 'x', '+'],
                title=['First', 'Second', None, 'Third', None, None],
                label=['A', 'B', 'C', 'D', 'E', 'F']
            )

            gmap.draw('map.html')

        .. image:: GoogleMapPlotter.scatter.png
        '''
        ARG_MAP = {
            'marker': _ArgInfo(['marker'], True),
            'title': _ArgInfo(['title'], None),
            'label': _ArgInfo(['label'], None),
            'info_window': _ArgInfo(['info_window'], None),
            'draggable': _ArgInfo(['draggable'], False),
            'symbol': _ArgInfo(['symbol'], 'o'),
            'size': _ArgInfo(['size', 's'], 40),
            'edge_color': _ArgInfo(['color', 'c', 'edge_color', 'ec'],
                                   'black'),
            'edge_alpha': _ArgInfo(['alpha', 'edge_alpha', 'ea'], 1.0),
            'edge_width': _ArgInfo(['edge_width', 'ew'], 1),
            'face_color': _ArgInfo(['color', 'c', 'face_color', 'fc'],
                                   'black'),
            'face_alpha': _ArgInfo(['alpha', 'face_alpha', 'fa'], 0.3),
            'precision': _ArgInfo(['precision'], 6)
        }
        # This links the draw-related settings to the arguments passed into this function.
        # Note that some settings can be set through more than one argument.
        # If no arguments are passed in for a given setting, its defined default is used.

        if len(lats) != len(lngs):
            raise ValueError("Number of latitudes and longitudes don't match!")

        # For each setting...
        settings = dict()
        for setting_name, arg_info in ARG_MAP.items():

            # ...attempt to set it from kwargs (if the value isn't a list, expand it into one):
            argument_name, value = _get_value(kwargs,
                                              arg_info.arguments,
                                              arg_info.default,
                                              get_key=True)
            settings[setting_name] = value if isinstance(
                value, list) else [value] * len(lats)

            # ...ensure that its length matches the number of points:
            if len(settings[setting_name]) != len(lats):
                raise ValueError(
                    "`%s`'s length doesn't match the number of points!" %
                    argument_name)

        # For each point, plot a marker or symbol with its corresponding settings:
        for i, location in enumerate(zip(lats, lngs)):
            point_settings = {
                setting_name: value[i]
                for (setting_name, value) in settings.items()
            }

            if point_settings.pop('marker'):
                self.marker(*location, **point_settings)
            else:
                shape = point_settings.pop('symbol')
                if not _Symbol.is_valid(shape):
                    raise InvalidSymbolError(
                        "Symbol '%s' is not implemented." % shape)
                self._drawables.append(
                    _Symbol(shape,
                            *location,
                            size=point_settings.pop('size'),
                            **point_settings))