diff options
| author | Tim Graham <timograham@gmail.com> | 2016-09-15 16:15:02 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-09-16 15:21:46 -0400 |
| commit | 5a51b449360ed2b84c2a54b90127a5faafa6f8f7 (patch) | |
| tree | 7e0de09523b57ee2657d0c8b69027c214d4e775f | |
| parent | 727d7ce6cba21363470aaefb2dc5353017531be3 (diff) | |
Fixed #26697 -- Removed contrib.gis.maps.
| -rw-r--r-- | django/contrib/gis/maps/__init__.py | 0 | ||||
| -rw-r--r-- | django/contrib/gis/maps/google/__init__.py | 69 | ||||
| -rw-r--r-- | django/contrib/gis/maps/google/gmap.py | 244 | ||||
| -rw-r--r-- | django/contrib/gis/maps/google/overlays.py | 332 | ||||
| -rw-r--r-- | django/contrib/gis/maps/google/zoom.py | 166 | ||||
| -rw-r--r-- | django/contrib/gis/maps/openlayers/__init__.py | 0 | ||||
| -rw-r--r-- | django/contrib/gis/templates/gis/google/google-map.html | 12 | ||||
| -rw-r--r-- | django/contrib/gis/templates/gis/google/google-map.js | 37 | ||||
| -rw-r--r-- | django/contrib/gis/templates/gis/google/google-multi.js | 8 | ||||
| -rw-r--r-- | django/contrib/gis/templates/gis/google/google-single.js | 2 | ||||
| -rw-r--r-- | docs/releases/1.11.txt | 4 | ||||
| -rw-r--r-- | tests/gis_tests/maps/tests.py | 57 |
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__()) |
