summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2016-09-15 16:15:02 -0400
committerTim Graham <timograham@gmail.com>2016-09-16 15:21:46 -0400
commit5a51b449360ed2b84c2a54b90127a5faafa6f8f7 (patch)
tree7e0de09523b57ee2657d0c8b69027c214d4e775f
parent727d7ce6cba21363470aaefb2dc5353017531be3 (diff)
Fixed #26697 -- Removed contrib.gis.maps.
-rw-r--r--django/contrib/gis/maps/__init__.py0
-rw-r--r--django/contrib/gis/maps/google/__init__.py69
-rw-r--r--django/contrib/gis/maps/google/gmap.py244
-rw-r--r--django/contrib/gis/maps/google/overlays.py332
-rw-r--r--django/contrib/gis/maps/google/zoom.py166
-rw-r--r--django/contrib/gis/maps/openlayers/__init__.py0
-rw-r--r--django/contrib/gis/templates/gis/google/google-map.html12
-rw-r--r--django/contrib/gis/templates/gis/google/google-map.js37
-rw-r--r--django/contrib/gis/templates/gis/google/google-multi.js8
-rw-r--r--django/contrib/gis/templates/gis/google/google-single.js2
-rw-r--r--docs/releases/1.11.txt4
-rw-r--r--tests/gis_tests/maps/tests.py57
12 files changed, 4 insertions, 927 deletions
diff --git a/django/contrib/gis/maps/__init__.py b/django/contrib/gis/maps/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/django/contrib/gis/maps/__init__.py
+++ /dev/null
diff --git a/django/contrib/gis/maps/google/__init__.py b/django/contrib/gis/maps/google/__init__.py
deleted file mode 100644
index b80e6d30cd..0000000000
--- a/django/contrib/gis/maps/google/__init__.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""
- This module houses the GoogleMap object, used for generating
- the needed javascript to embed Google Maps in a Web page.
-
- Google(R) is a registered trademark of Google, Inc. of Mountain View, California.
-
- Example:
-
- * In the view:
- return render(request, 'template.html', {'google': GoogleMap(key="abcdefg")})
-
- * In the template:
-
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- {{ google.xhtml }}
- <head>
- <title>Google Maps via GeoDjango</title>
- {{ google.style }}
- {{ google.scripts }}
- </head>
- {{ google.body }}
- <div id="{{ google.dom_id }}" style="width:600px;height:400px;"></div>
- </body>
- </html>
-
- Note: If you want to be more explicit in your templates, the following are
- equivalent:
- {{ google.body }} => "<body {{ google.onload }} {{ google.onunload }}>"
- {{ google.xhtml }} => "<html xmlns="http://www.w3.org/1999/xhtml" {{ google.xmlns }}>"
- {{ google.style }} => "<style>{{ google.vml_css }}</style>"
-
- Explanation:
- - The `xhtml` property provides the correct XML namespace needed for
- Google Maps to operate in IE using XHTML. Google Maps on IE uses
- VML to draw polylines. Returns, by default:
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
-
- - The `style` property provides the correct style tag for the CSS
- properties required by Google Maps on IE:
- <style type="text/css">v\:* {behavior:url(#default#VML);}</style>
-
- - The `scripts` property provides the necessary <script> tags for
- including the Google Maps javascript, as well as including the
- generated javascript.
-
- - The `body` property provides the correct attributes for the
- body tag to load the generated javascript. By default, returns:
- <body onload="gmap_load()" onunload="GUnload()">
-
- - The `dom_id` property returns the DOM id for the map. Defaults to "map".
-
- The following attributes may be set or customized in your local settings:
- * GOOGLE_MAPS_API_KEY: String of your Google Maps API key. These are tied
- to a domain. May be obtained from https://developers.google.com/maps/
- * GOOGLE_MAPS_API_VERSION (optional): Defaults to using "2.x"
- * GOOGLE_MAPS_URL (optional): Must have a substitution ('%s') for the API
- version.
-"""
-from django.contrib.gis.maps.google.gmap import GoogleMap, GoogleMapSet
-from django.contrib.gis.maps.google.overlays import (
- GEvent, GIcon, GMarker, GPolygon, GPolyline,
-)
-from django.contrib.gis.maps.google.zoom import GoogleZoom
-
-__all__ = [
- 'GoogleMap', 'GoogleMapSet', 'GEvent', 'GIcon', 'GMarker', 'GPolygon',
- 'GPolyline', 'GoogleZoom',
-]
diff --git a/django/contrib/gis/maps/google/gmap.py b/django/contrib/gis/maps/google/gmap.py
deleted file mode 100644
index d40c3b8218..0000000000
--- a/django/contrib/gis/maps/google/gmap.py
+++ /dev/null
@@ -1,244 +0,0 @@
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.contrib.gis.maps.google.overlays import (
- GMarker, GPolygon, GPolyline,
-)
-from django.template.loader import render_to_string
-from django.utils.html import format_html
-from django.utils.safestring import mark_safe
-from django.utils.six.moves import range
-
-
-class GoogleMapException(Exception):
- pass
-
-
-# The default Google Maps URL (for the API javascript)
-# TODO: Internationalize for Japan, UK, etc.
-GOOGLE_MAPS_URL = 'http://maps.google.com/maps?file=api&v=%s&key='
-
-
-class GoogleMap(object):
- "A class for generating Google Maps JavaScript."
-
- # String constants
- onunload = mark_safe('onunload="GUnload()"') # Cleans up after Google Maps
- vml_css = mark_safe('v\:* {behavior:url(#default#VML);}') # CSS for IE VML
- xmlns = mark_safe('xmlns:v="urn:schemas-microsoft-com:vml"') # XML Namespace (for IE VML).
-
- def __init__(self, key=None, api_url=None, version=None,
- center=None, zoom=None, dom_id='map',
- kml_urls=[], polylines=None, polygons=None, markers=None,
- template='gis/google/google-map.js',
- js_module='geodjango',
- extra_context={}):
-
- # The Google Maps API Key defined in the settings will be used
- # if not passed in as a parameter. The use of an API key is
- # _required_.
- if not key:
- try:
- self.key = settings.GOOGLE_MAPS_API_KEY
- except AttributeError:
- raise GoogleMapException(
- 'Google Maps API Key not found (try adding '
- 'GOOGLE_MAPS_API_KEY to your settings).'
- )
- else:
- self.key = key
-
- # Getting the Google Maps API version, defaults to using the latest ("2.x"),
- # this is not necessarily the most stable.
- if not version:
- self.version = getattr(settings, 'GOOGLE_MAPS_API_VERSION', '2.x')
- else:
- self.version = version
-
- # Can specify the API URL in the `api_url` keyword.
- if not api_url:
- self.api_url = getattr(settings, 'GOOGLE_MAPS_URL', GOOGLE_MAPS_URL) % self.version
- else:
- self.api_url = api_url
-
- # Setting the DOM id of the map, the load function, the JavaScript
- # template, and the KML URLs array.
- self.dom_id = dom_id
- self.extra_context = extra_context
- self.js_module = js_module
- self.template = template
- self.kml_urls = kml_urls
-
- # Does the user want any GMarker, GPolygon, and/or GPolyline overlays?
- overlay_info = [[GMarker, markers, 'markers'],
- [GPolygon, polygons, 'polygons'],
- [GPolyline, polylines, 'polylines']]
-
- for overlay_class, overlay_list, varname in overlay_info:
- setattr(self, varname, [])
- if overlay_list:
- for overlay in overlay_list:
- if isinstance(overlay, overlay_class):
- getattr(self, varname).append(overlay)
- else:
- getattr(self, varname).append(overlay_class(overlay))
-
- # If GMarker, GPolygons, and/or GPolylines are used the zoom will be
- # automatically calculated via the Google Maps API. If both a zoom
- # level and a center coordinate are provided with polygons/polylines,
- # no automatic determination will occur.
- self.calc_zoom = False
- if self.polygons or self.polylines or self.markers:
- if center is None or zoom is None:
- self.calc_zoom = True
-
- # Defaults for the zoom level and center coordinates if the zoom
- # is not automatically calculated.
- if zoom is None:
- zoom = 4
- self.zoom = zoom
- if center is None:
- center = (0, 0)
- self.center = center
-
- def render(self):
- """
- Generates the JavaScript necessary for displaying this Google Map.
- """
- params = {'calc_zoom': self.calc_zoom,
- 'center': self.center,
- 'dom_id': self.dom_id,
- 'js_module': self.js_module,
- 'kml_urls': self.kml_urls,
- 'zoom': self.zoom,
- 'polygons': self.polygons,
- 'polylines': self.polylines,
- 'icons': self.icons,
- 'markers': self.markers,
- }
- params.update(self.extra_context)
- return render_to_string(self.template, params)
-
- @property
- def body(self):
- "Returns HTML body tag for loading and unloading Google Maps javascript."
- return format_html('<body {} {}>', self.onload, self.onunload)
-
- @property
- def onload(self):
- "Returns the `onload` HTML <body> attribute."
- return format_html('onload="{}.{}_load()"', self.js_module, self.dom_id)
-
- @property
- def api_script(self):
- "Returns the <script> tag for the Google Maps API javascript."
- return format_html('<script src="{}{}" type="text/javascript"></script>',
- self.api_url, self.key)
-
- @property
- def js(self):
- "Returns only the generated Google Maps JavaScript (no <script> tags)."
- return self.render()
-
- @property
- def scripts(self):
- "Returns all <script></script> tags required with Google Maps JavaScript."
- return format_html('{}\n <script type="text/javascript">\n//<![CDATA[\n{}//]]>\n </script>',
- self.api_script, mark_safe(self.js))
-
- @property
- def style(self):
- "Returns additional CSS styling needed for Google Maps on IE."
- return format_html('<style type="text/css">{}</style>', self.vml_css)
-
- @property
- def xhtml(self):
- "Returns XHTML information needed for IE VML overlays."
- return format_html('<html xmlns="http://www.w3.org/1999/xhtml" {}>', self.xmlns)
-
- @property
- def icons(self):
- "Returns a sequence of GIcon objects in this map."
- return set(marker.icon for marker in self.markers if marker.icon)
-
-
-class GoogleMapSet(GoogleMap):
-
- def __init__(self, *args, **kwargs):
- """
- A class for generating sets of Google Maps that will be shown on the
- same page together.
-
- Example:
- gmapset = GoogleMapSet( GoogleMap( ... ), GoogleMap( ... ) )
- gmapset = GoogleMapSet( [ gmap1, gmap2] )
- """
- # The `google-multi.js` template is used instead of `google-single.js`
- # by default.
- template = kwargs.pop('template', 'gis/google/google-multi.js')
-
- # This is the template used to generate the GMap load JavaScript for
- # each map in the set.
- self.map_template = kwargs.pop('map_template', 'gis/google/google-single.js')
-
- # Running GoogleMap.__init__(), and resetting the template
- # value with default obtained above.
- super(GoogleMapSet, self).__init__(**kwargs)
- self.template = template
-
- # If a tuple/list passed in as first element of args, then assume
- if isinstance(args[0], (tuple, list)):
- self.maps = args[0]
- else:
- self.maps = args
-
- # Generating DOM ids for each of the maps in the set.
- self.dom_ids = ['map%d' % i for i in range(len(self.maps))]
-
- def load_map_js(self):
- """
- Returns JavaScript containing all of the loading routines for each
- map in this set.
- """
- result = []
- for dom_id, gmap in zip(self.dom_ids, self.maps):
- # Backup copies the GoogleMap DOM id and template attributes.
- # They are overridden on each GoogleMap instance in the set so
- # that only the loading JavaScript (and not the header variables)
- # is used with the generated DOM ids.
- tmp = (gmap.template, gmap.dom_id)
- gmap.template = self.map_template
- gmap.dom_id = dom_id
- result.append(gmap.js)
- # Restoring the backup values.
- gmap.template, gmap.dom_id = tmp
- return mark_safe(''.join(result))
-
- def render(self):
- """
- Generates the JavaScript for the collection of Google Maps in
- this set.
- """
- params = {'js_module': self.js_module,
- 'dom_ids': self.dom_ids,
- 'load_map_js': self.load_map_js(),
- 'icons': self.icons,
- }
- params.update(self.extra_context)
- return render_to_string(self.template, params)
-
- @property
- def onload(self):
- "Returns the `onload` HTML <body> attribute."
- # Overloaded to use the `load` function defined in the
- # `google-multi.js`, which calls the load routines for
- # each one of the individual maps in the set.
- return mark_safe('onload="%s.load()"' % self.js_module)
-
- @property
- def icons(self):
- "Returns a sequence of all icons in each map of the set."
- icons = set()
- for map in self.maps:
- icons |= map.icons
- return icons
diff --git a/django/contrib/gis/maps/google/overlays.py b/django/contrib/gis/maps/google/overlays.py
deleted file mode 100644
index 3a1c9d4219..0000000000
--- a/django/contrib/gis/maps/google/overlays.py
+++ /dev/null
@@ -1,332 +0,0 @@
-from __future__ import unicode_literals
-
-from functools import total_ordering
-
-from django.contrib.gis.geos import (
- LinearRing, LineString, Point, Polygon, fromstr,
-)
-from django.utils import six
-from django.utils.encoding import python_2_unicode_compatible
-from django.utils.html import html_safe
-
-
-@html_safe
-@python_2_unicode_compatible
-class GEvent(object):
- """
- A Python wrapper for the Google GEvent object.
-
- Events can be attached to any object derived from GOverlayBase with the
- add_event() call.
-
- For more information please see the Google Maps API Reference:
- https://developers.google.com/maps/documentation/javascript/reference#event
-
- Example:
-
- from django.shortcuts import render
- from django.contrib.gis.maps.google import GoogleMap, GEvent, GPolyline
-
- def sample_request(request):
- polyline = GPolyline('LINESTRING(101 26, 112 26, 102 31)')
- event = GEvent('click',
- 'function() { location.href = "http://www.google.com"}')
- polyline.add_event(event)
- return render(request, 'mytemplate.html', {
- 'google': GoogleMap(polylines=[polyline]),
- })
- """
-
- def __init__(self, event, action):
- """
- Initializes a GEvent object.
-
- Parameters:
-
- event:
- string for the event, such as 'click'. The event must be a valid
- event for the object in the Google Maps API.
- There is no validation of the event type within Django.
-
- action:
- string containing a Javascript function, such as
- 'function() { location.href = "newurl";}'
- The string must be a valid Javascript function. Again there is no
- validation fo the function within Django.
- """
- self.event = event
- self.action = action
-
- def __str__(self):
- "Returns the parameter part of a GEvent."
- return '"%s", %s' % (self.event, self.action)
-
-
-@html_safe
-@python_2_unicode_compatible
-class GOverlayBase(object):
- def __init__(self):
- self.events = []
-
- def latlng_from_coords(self, coords):
- "Generates a JavaScript array of GLatLng objects for the given coordinates."
- return '[%s]' % ','.join('new GLatLng(%s,%s)' % (y, x) for x, y in coords)
-
- def add_event(self, event):
- "Attaches a GEvent to the overlay object."
- self.events.append(event)
-
- def __str__(self):
- "The string representation is the JavaScript API call."
- return '%s(%s)' % (self.__class__.__name__, self.js_params)
-
-
-class GPolygon(GOverlayBase):
- """
- A Python wrapper for the Google GPolygon object. For more information
- please see the Google Maps API Reference:
- https://developers.google.com/maps/documentation/javascript/reference#Polygon
- """
- def __init__(self, poly,
- stroke_color='#0000ff', stroke_weight=2, stroke_opacity=1,
- fill_color='#0000ff', fill_opacity=0.4):
- """
- The GPolygon object initializes on a GEOS Polygon or a parameter that
- may be instantiated into GEOS Polygon. Please note that this will not
- depict a Polygon's internal rings.
-
- Keyword Options:
-
- stroke_color:
- The color of the polygon outline. Defaults to '#0000ff' (blue).
-
- stroke_weight:
- The width of the polygon outline, in pixels. Defaults to 2.
-
- stroke_opacity:
- The opacity of the polygon outline, between 0 and 1. Defaults to 1.
-
- fill_color:
- The color of the polygon fill. Defaults to '#0000ff' (blue).
-
- fill_opacity:
- The opacity of the polygon fill. Defaults to 0.4.
- """
- if isinstance(poly, six.string_types):
- poly = fromstr(poly)
- if isinstance(poly, (tuple, list)):
- poly = Polygon(poly)
- if not isinstance(poly, Polygon):
- raise TypeError('GPolygon may only initialize on GEOS Polygons.')
-
- # Getting the envelope of the input polygon (used for automatically
- # determining the zoom level).
- self.envelope = poly.envelope
-
- # Translating the coordinates into a JavaScript array of
- # Google `GLatLng` objects.
- self.points = self.latlng_from_coords(poly.shell.coords)
-
- # Stroke settings.
- self.stroke_color, self.stroke_opacity, self.stroke_weight = stroke_color, stroke_opacity, stroke_weight
-
- # Fill settings.
- self.fill_color, self.fill_opacity = fill_color, fill_opacity
-
- super(GPolygon, self).__init__()
-
- @property
- def js_params(self):
- return '%s, "%s", %s, %s, "%s", %s' % (self.points, self.stroke_color, self.stroke_weight, self.stroke_opacity,
- self.fill_color, self.fill_opacity)
-
-
-class GPolyline(GOverlayBase):
- """
- A Python wrapper for the Google GPolyline object. For more information
- please see the Google Maps API Reference:
- https://developers.google.com/maps/documentation/javascript/reference#Polyline
- """
- def __init__(self, geom, color='#0000ff', weight=2, opacity=1):
- """
- The GPolyline object may be initialized on GEOS LineStirng, LinearRing,
- and Polygon objects (internal rings not supported) or a parameter that
- may instantiated into one of the above geometries.
-
- Keyword Options:
-
- color:
- The color to use for the polyline. Defaults to '#0000ff' (blue).
-
- weight:
- The width of the polyline, in pixels. Defaults to 2.
-
- opacity:
- The opacity of the polyline, between 0 and 1. Defaults to 1.
- """
- # If a GEOS geometry isn't passed in, try to construct one.
- if isinstance(geom, six.string_types):
- geom = fromstr(geom)
- if isinstance(geom, (tuple, list)):
- geom = Polygon(geom)
- # Generating the lat/lng coordinate pairs.
- if isinstance(geom, (LineString, LinearRing)):
- self.latlngs = self.latlng_from_coords(geom.coords)
- elif isinstance(geom, Polygon):
- self.latlngs = self.latlng_from_coords(geom.shell.coords)
- else:
- raise TypeError('GPolyline may only initialize on GEOS LineString, LinearRing, and/or Polygon geometries.')
-
- # Getting the envelope for automatic zoom determination.
- self.envelope = geom.envelope
- self.color, self.weight, self.opacity = color, weight, opacity
- super(GPolyline, self).__init__()
-
- @property
- def js_params(self):
- return '%s, "%s", %s, %s' % (self.latlngs, self.color, self.weight, self.opacity)
-
-
-@total_ordering
-class GIcon(object):
- """
- Creates a GIcon object to pass into a Gmarker object.
-
- The keyword arguments map to instance attributes of the same name. These,
- in turn, correspond to a subset of the attributes of the official GIcon
- javascript object:
-
- https://developers.google.com/maps/documentation/javascript/reference#Icon
-
- Because a Google map often uses several different icons, a name field has
- been added to the required arguments.
-
- Required Arguments:
- varname:
- A string which will become the basis for the js variable name of
- the marker, for this reason, your code should assign a unique
- name for each GIcon you instantiate, otherwise there will be
- name space collisions in your javascript.
-
- Keyword Options:
- image:
- The url of the image to be used as the icon on the map defaults
- to 'G_DEFAULT_ICON'
-
- iconsize:
- a tuple representing the pixel size of the foreground (not the
- shadow) image of the icon, in the format: (width, height) ex.:
-
- GIcon('fast_food',
- image="/media/icon/star.png",
- iconsize=(15,10))
-
- Would indicate your custom icon was 15px wide and 10px height.
-
- shadow:
- the url of the image of the icon's shadow
-
- shadowsize:
- a tuple representing the pixel size of the shadow image, format is
- the same as ``iconsize``
-
- iconanchor:
- a tuple representing the pixel coordinate relative to the top left
- corner of the icon image at which this icon is anchored to the map.
- In (x, y) format. x increases to the right in the Google Maps
- coordinate system and y increases downwards in the Google Maps
- coordinate system.)
-
- infowindowanchor:
- The pixel coordinate relative to the top left corner of the icon
- image at which the info window is anchored to this icon.
- """
- def __init__(self, varname, image=None, iconsize=None,
- shadow=None, shadowsize=None, iconanchor=None,
- infowindowanchor=None):
- self.varname = varname
- self.image = image
- self.iconsize = iconsize
- self.shadow = shadow
- self.shadowsize = shadowsize
- self.iconanchor = iconanchor
- self.infowindowanchor = infowindowanchor
-
- def __eq__(self, other):
- return self.varname == other.varname
-
- def __lt__(self, other):
- return self.varname < other.varname
-
- def __hash__(self):
- # XOR with hash of GIcon type so that hash('varname') won't
- # equal hash(GIcon('varname')).
- return hash(self.__class__) ^ hash(self.varname)
-
-
-class GMarker(GOverlayBase):
- """
- A Python wrapper for the Google GMarker object. For more information
- please see the Google Maps API Reference:
- https://developers.google.com/maps/documentation/javascript/reference#Marker
-
- Example:
-
- from django.shortcuts import render
- from django.contrib.gis.maps.google.overlays import GMarker, GEvent
-
- def sample_request(request):
- marker = GMarker('POINT(101 26)')
- event = GEvent('click',
- 'function() { location.href = "http://www.google.com"}')
- marker.add_event(event)
- return render(request, 'mytemplate.html', {
- 'google': GoogleMap(markers=[marker]),
- })
- """
- def __init__(self, geom, title=None, draggable=False, icon=None):
- """
- The GMarker object may initialize on GEOS Points or a parameter
- that may be instantiated into a GEOS point. Keyword options map to
- GMarkerOptions -- so far only the title option is supported.
-
- Keyword Options:
- title:
- Title option for GMarker, will be displayed as a tooltip.
-
- draggable:
- Draggable option for GMarker, disabled by default.
- """
- # If a GEOS geometry isn't passed in, try to construct one.
- if isinstance(geom, six.string_types):
- geom = fromstr(geom)
- if isinstance(geom, (tuple, list)):
- geom = Point(geom)
- if isinstance(geom, Point):
- self.latlng = self.latlng_from_coords(geom.coords)
- else:
- raise TypeError('GMarker may only initialize on GEOS Point geometry.')
- # Getting the envelope for automatic zoom determination.
- self.envelope = geom.envelope
- # TODO: Add support for more GMarkerOptions
- self.title = title
- self.draggable = draggable
- self.icon = icon
- super(GMarker, self).__init__()
-
- def latlng_from_coords(self, coords):
- return 'new GLatLng(%s,%s)' % (coords[1], coords[0])
-
- def options(self):
- result = []
- if self.title:
- result.append('title: "%s"' % self.title)
- if self.icon:
- result.append('icon: %s' % self.icon.varname)
- if self.draggable:
- result.append('draggable: true')
- return '{%s}' % ','.join(result)
-
- @property
- def js_params(self):
- return '%s, %s' % (self.latlng, self.options())
diff --git a/django/contrib/gis/maps/google/zoom.py b/django/contrib/gis/maps/google/zoom.py
deleted file mode 100644
index d169fbd59b..0000000000
--- a/django/contrib/gis/maps/google/zoom.py
+++ /dev/null
@@ -1,166 +0,0 @@
-from __future__ import unicode_literals
-
-from math import atan, exp, log, pi, sin
-
-from django.contrib.gis.geos import GEOSGeometry, LinearRing, Point, Polygon
-from django.contrib.gis.maps.google.gmap import GoogleMapException
-from django.utils.six.moves import range
-
-# Constants used for degree to radian conversion, and vice-versa.
-DTOR = pi / 180.
-RTOD = 180. / pi
-
-
-class GoogleZoom(object):
- """
- GoogleZoom is a utility for performing operations related to the zoom
- levels on Google Maps.
-
- This class is inspired by the OpenStreetMap Mapnik tile generation routine
- `generate_tiles.py`, and the article "How Big Is the World" (Hack #16) in
- "Google Maps Hacks" by Rich Gibson and Schuyler Erle.
-
- `generate_tiles.py` may be found at:
- http://trac.openstreetmap.org/browser/applications/rendering/mapnik/generate_tiles.py
-
- "Google Maps Hacks" may be found at http://safari.oreilly.com/0596101619
- """
-
- def __init__(self, num_zoom=19, tilesize=256):
- "Initializes the Google Zoom object."
- # Google's tilesize is 256x256, square tiles are assumed.
- self._tilesize = tilesize
-
- # The number of zoom levels
- self._nzoom = num_zoom
-
- # Initializing arrays to hold the parameters for each one of the
- # zoom levels.
- self._degpp = [] # Degrees per pixel
- self._radpp = [] # Radians per pixel
- self._npix = [] # 1/2 the number of pixels for a tile at the given zoom level
-
- # Incrementing through the zoom levels and populating the parameter arrays.
- z = tilesize # The number of pixels per zoom level.
- for i in range(num_zoom):
- # Getting the degrees and radians per pixel, and the 1/2 the number of
- # for every zoom level.
- self._degpp.append(z / 360.) # degrees per pixel
- self._radpp.append(z / (2 * pi)) # radians per pixel
- self._npix.append(z / 2) # number of pixels to center of tile
-
- # Multiplying `z` by 2 for the next iteration.
- z *= 2
-
- def __len__(self):
- "Returns the number of zoom levels."
- return self._nzoom
-
- def get_lon_lat(self, lonlat):
- "Unpacks longitude, latitude from GEOS Points and 2-tuples."
- if isinstance(lonlat, Point):
- lon, lat = lonlat.coords
- else:
- lon, lat = lonlat
- return lon, lat
-
- def lonlat_to_pixel(self, lonlat, zoom):
- "Converts a longitude, latitude coordinate pair for the given zoom level."
- # Setting up, unpacking the longitude, latitude values and getting the
- # number of pixels for the given zoom level.
- lon, lat = self.get_lon_lat(lonlat)
- npix = self._npix[zoom]
-
- # Calculating the pixel x coordinate by multiplying the longitude value
- # with the number of degrees/pixel at the given zoom level.
- px_x = round(npix + (lon * self._degpp[zoom]))
-
- # Creating the factor, and ensuring that 1 or -1 is not passed in as the
- # base to the logarithm. Here's why:
- # if fac = -1, we'll get log(0) which is undefined;
- # if fac = 1, our logarithm base will be divided by 0, also undefined.
- fac = min(max(sin(DTOR * lat), -0.9999), 0.9999)
-
- # Calculating the pixel y coordinate.
- px_y = round(npix + (0.5 * log((1 + fac) / (1 - fac)) * (-1.0 * self._radpp[zoom])))
-
- # Returning the pixel x, y to the caller of the function.
- return (px_x, px_y)
-
- def pixel_to_lonlat(self, px, zoom):
- "Converts a pixel to a longitude, latitude pair at the given zoom level."
- if len(px) != 2:
- raise TypeError('Pixel should be a sequence of two elements.')
-
- # Getting the number of pixels for the given zoom level.
- npix = self._npix[zoom]
-
- # Calculating the longitude value, using the degrees per pixel.
- lon = (px[0] - npix) / self._degpp[zoom]
-
- # Calculating the latitude value.
- lat = RTOD * (2 * atan(exp((px[1] - npix) / (-1.0 * self._radpp[zoom]))) - 0.5 * pi)
-
- # Returning the longitude, latitude coordinate pair.
- return (lon, lat)
-
- def tile(self, lonlat, zoom):
- """
- Returns a Polygon corresponding to the region represented by a fictional
- Google Tile for the given longitude/latitude pair and zoom level. This
- tile is used to determine the size of a tile at the given point.
- """
- # The given lonlat is the center of the tile.
- delta = self._tilesize / 2
-
- # Getting the pixel coordinates corresponding to the
- # the longitude/latitude.
- px = self.lonlat_to_pixel(lonlat, zoom)
-
- # Getting the lower-left and upper-right lat/lon coordinates
- # for the bounding box of the tile.
- ll = self.pixel_to_lonlat((px[0] - delta, px[1] - delta), zoom)
- ur = self.pixel_to_lonlat((px[0] + delta, px[1] + delta), zoom)
-
- # Constructing the Polygon, representing the tile and returning.
- return Polygon(LinearRing(ll, (ll[0], ur[1]), ur, (ur[0], ll[1]), ll), srid=4326)
-
- def get_zoom(self, geom):
- "Returns the optimal Zoom level for the given geometry."
- # Checking the input type.
- if not isinstance(geom, GEOSGeometry) or geom.srid != 4326:
- raise TypeError('get_zoom() expects a GEOS Geometry with an SRID of 4326.')
-
- # Getting the envelope for the geometry, and its associated width, height
- # and centroid.
- env = geom.envelope
- env_w, env_h = self.get_width_height(env.extent)
- center = env.centroid
-
- for z in range(self._nzoom):
- # Getting the tile at the zoom level.
- tile_w, tile_h = self.get_width_height(self.tile(center, z).extent)
-
- # When we span more than one tile, this is an approximately good
- # zoom level.
- if (env_w > tile_w) or (env_h > tile_h):
- if z == 0:
- raise GoogleMapException('Geometry width and height should not exceed that of the Earth.')
- return z - 1
-
- # Otherwise, we've zoomed in to the max.
- return self._nzoom - 1
-
- def get_width_height(self, extent):
- """
- Returns the width and height for the given extent.
- """
- # Getting the lower-left, upper-left, and upper-right
- # coordinates from the extent.
- ll = Point(extent[:2])
- ul = Point(extent[0], extent[3])
- ur = Point(extent[2:])
- # Calculating the width and height.
- height = ll.distance(ul)
- width = ul.distance(ur)
- return width, height
diff --git a/django/contrib/gis/maps/openlayers/__init__.py b/django/contrib/gis/maps/openlayers/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/django/contrib/gis/maps/openlayers/__init__.py
+++ /dev/null
diff --git a/django/contrib/gis/templates/gis/google/google-map.html b/django/contrib/gis/templates/gis/google/google-map.html
deleted file mode 100644
index ef80c5b1b1..0000000000
--- a/django/contrib/gis/templates/gis/google/google-map.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% load i18n %}<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" {{ gmap.xmlns }}>
-<head>
- <title>{% block title %}{% trans "Google Maps via GeoDjango" %}{% endblock %}</title>
- {{ gmap.style }}
- {{ gmap.scripts }}
-</head>
-<body {{ gmap.onload }} {{ gmap.onunload }}>
-{% if gmap.dom_ids %}{% for dom_id in gmap.dom_ids %}<div id="{{ dom_id }}" style="width:600px;height:400px;"></div>{% endfor %}
-{% else %}<div id="{{ gmap.dom_id }}" style="width:600px;height:400px;"></div>{% endif %}
-</body>
-</html>
diff --git a/django/contrib/gis/templates/gis/google/google-map.js b/django/contrib/gis/templates/gis/google/google-map.js
deleted file mode 100644
index 5c1c8132b9..0000000000
--- a/django/contrib/gis/templates/gis/google/google-map.js
+++ /dev/null
@@ -1,37 +0,0 @@
-{% load l10n %}
-{% autoescape off %}
-{% localize off %}
-{% block vars %}var geodjango = {};{% for icon in icons %}
-var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
-{% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %}
-{% if icon.shadow %}{{ icon.varname }}.shadow = "{{ icon.shadow }}";{% endif %} {% if icon.shadowsize %}{{ icon.varname }}.shadowSize = new GSize({{ icon.shadowsize.0 }}, {{ icon.shadowsize.1 }});{% endif %}
-{% if icon.iconanchor %}{{ icon.varname }}.iconAnchor = new GPoint({{ icon.iconanchor.0 }}, {{ icon.iconanchor.1 }});{% endif %} {% if icon.iconsize %}{{ icon.varname }}.iconSize = new GSize({{ icon.iconsize.0 }}, {{ icon.iconsize.1 }});{% endif %}
-{% if icon.infowindowanchor %}{{ icon.varname }}.infoWindowAnchor = new GPoint({{ icon.infowindowanchor.0 }}, {{ icon.infowindowanchor.1 }});{% endif %}{% endfor %}
-{% endblock vars %}{% block functions %}
-{% block load %}{{ js_module }}.{{ dom_id }}_load = function(){
- if (GBrowserIsCompatible()) {
- {{ js_module }}.{{ dom_id }} = new GMap2(document.getElementById("{{ dom_id }}"));
- {{ js_module }}.{{ dom_id }}.setCenter(new GLatLng({{ center.1 }}, {{ center.0 }}), {{ zoom }});
- {% block controls %}{{ js_module }}.{{ dom_id }}.setUIToDefault();{% endblock %}
- {% if calc_zoom %}var bounds = new GLatLngBounds(); var tmp_bounds = new GLatLngBounds();{% endif %}
- {% for kml_url in kml_urls %}{{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }} = new GGeoXml("{{ kml_url }}");
- {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }});{% endfor %}
- {% for polygon in polygons %}{{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }} = new {{ polygon }};
- {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }});
- {% for event in polygon.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_poly{{ forloop.parentloop.counter }}, {{ event }});{% endfor %}
- {% if calc_zoom %}tmp_bounds = {{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %}
- {% for polyline in polylines %}{{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }} = new {{ polyline }};
- {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }});
- {% for event in polyline.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_polyline{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
- {% if calc_zoom %}tmp_bounds = {{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %}
- {% for marker in markers %}{{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }} = new {{ marker }};
- {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }});
- {% for event in marker.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_marker{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
- {% if calc_zoom %}bounds.extend({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }}.getLatLng()); {% endif %}{% endfor %}
- {% if calc_zoom %}{{ js_module }}.{{ dom_id }}.setCenter(bounds.getCenter(), {{ js_module }}.{{ dom_id }}.getBoundsZoomLevel(bounds));{% endif %}
- {% block load_extra %}{% endblock %}
- }else {
- alert("Sorry, the Google Maps API is not compatible with this browser.");
- }
-}
-{% endblock load %}{% endblock functions %}{% endlocalize %}{% endautoescape %}
diff --git a/django/contrib/gis/templates/gis/google/google-multi.js b/django/contrib/gis/templates/gis/google/google-multi.js
deleted file mode 100644
index cfcd3ac5d0..0000000000
--- a/django/contrib/gis/templates/gis/google/google-multi.js
+++ /dev/null
@@ -1,8 +0,0 @@
-{% extends "gis/google/google-map.js" %}
-{% block functions %}
-{{ load_map_js }}
-{{ js_module }}.load = function(){
- {% for dom_id in dom_ids %}{{ js_module }}.{{ dom_id }}_load();
- {% endfor %}
-}
-{% endblock %}
diff --git a/django/contrib/gis/templates/gis/google/google-single.js b/django/contrib/gis/templates/gis/google/google-single.js
deleted file mode 100644
index 801ef1256b..0000000000
--- a/django/contrib/gis/templates/gis/google/google-single.js
+++ /dev/null
@@ -1,2 +0,0 @@
-{% extends "gis/google/google-map.js" %}
-{% block vars %}{# No vars here because used within GoogleMapSet #}{% endblock %}
diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt
index 3cd56c515e..af3c5159db 100644
--- a/docs/releases/1.11.txt
+++ b/docs/releases/1.11.txt
@@ -382,6 +382,10 @@ Backwards incompatible changes in 1.11
``contrib.gis`` was first released, :ref:`gdalbuild` is now a required
dependency for GeoDjango. In older versions, it's only required for SQLite.
+* ``contrib.gis.maps`` is removed as it interfaces with a retired version of
+ the Google Maps API and seems to be unmaintained. If you're using it, `let
+ us know <https://code.djangoproject.com/ticket/14284>`_.
+
Database backend API
--------------------
diff --git a/tests/gis_tests/maps/tests.py b/tests/gis_tests/maps/tests.py
deleted file mode 100644
index c62b9e6735..0000000000
--- a/tests/gis_tests/maps/tests.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from unittest import skipUnless
-
-from django.contrib.gis.geos import HAS_GEOS
-from django.test import SimpleTestCase
-from django.test.utils import modify_settings, override_settings
-from django.utils.encoding import force_text
-
-GOOGLE_MAPS_API_KEY = 'XXXX'
-
-
-@skipUnless(HAS_GEOS, 'Geos is required.')
-@modify_settings(
- INSTALLED_APPS={'append': 'django.contrib.gis'},
-)
-class GoogleMapsTest(SimpleTestCase):
-
- @override_settings(GOOGLE_MAPS_API_KEY=GOOGLE_MAPS_API_KEY)
- def test_google_map_scripts(self):
- """
- Testing GoogleMap.scripts() output. See #20773.
- """
- from django.contrib.gis.maps.google.gmap import GoogleMap
-
- google_map = GoogleMap()
- scripts = google_map.scripts
- self.assertIn(GOOGLE_MAPS_API_KEY, scripts)
- self.assertIn("new GMap2", scripts)
-
- @override_settings(GOOGLE_MAPS_API_KEY=GOOGLE_MAPS_API_KEY)
- def test_unicode_in_google_maps(self):
- """
- Test that GoogleMap doesn't crash with non-ASCII content.
- """
- from django.contrib.gis.geos import Point
- from django.contrib.gis.maps.google.gmap import GoogleMap, GMarker
-
- center = Point(6.146805, 46.227574)
- marker = GMarker(center,
- title='En français !')
- google_map = GoogleMap(center=center, zoom=18, markers=[marker])
- self.assertIn("En français", google_map.scripts)
-
- def test_gevent_html_safe(self):
- from django.contrib.gis.maps.google.overlays import GEvent
- event = GEvent('click', 'function() {location.href = "http://www.google.com"}')
- self.assertTrue(hasattr(GEvent, '__html__'))
- self.assertEqual(force_text(event), event.__html__())
-
- def test_goverlay_html_safe(self):
- from django.contrib.gis.maps.google.overlays import GOverlayBase
- overlay = GOverlayBase()
- overlay.js_params = '"foo", "bar"'
- self.assertTrue(hasattr(GOverlayBase, '__html__'))
- self.assertEqual(force_text(overlay), overlay.__html__())