Ticket #14284: 14284_patch.diff

File 14284_patch.diff, 20.2 KB (added by ericpalakovichcarr, 9 years ago)

First draft of patch to update from google maps v2 to v3. No testing performed for code.

  • django/contrib/gis/templates/gis/google/google-map.js

     
    11{% load l10n %}
    22{% autoescape off %}
    33{% localize off %}
    4 {% block vars %}var geodjango = {};{% for icon in icons %}
    5 var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
    6 {% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %}
    7 {% if icon.shadow %}{{ icon.varname }}.shadow = "{{ icon.shadow }}";{% endif %} {% if icon.shadowsize %}{{ icon.varname }}.shadowSize = new GSize({{ icon.shadowsize.0 }}, {{ icon.shadowsize.1 }});{% endif %}
    8 {% 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 %}
    9 {% if icon.infowindowanchor %}{{ icon.varname }}.infoWindowAnchor = new GPoint({{ icon.infowindowanchor.0 }}, {{ icon.infowindowanchor.1 }});{% endif %}{% endfor %}
     4{% block vars %}var geodjango = {};
    105{% endblock vars %}{% block functions %}
    116{% block load %}{{ js_module }}.{{ dom_id }}_load = function(){
    12   if (GBrowserIsCompatible()) {
    13     {{ js_module }}.{{ dom_id }} = new GMap2(document.getElementById("{{ dom_id }}"));
    14     {{ js_module }}.{{ dom_id }}.setCenter(new GLatLng({{ center.1 }}, {{ center.0 }}), {{ zoom }});
    15     {% block controls %}{{ js_module }}.{{ dom_id }}.setUIToDefault();{% endblock %}
    16     {% if calc_zoom %}var bounds = new GLatLngBounds(); var tmp_bounds = new GLatLngBounds();{% endif %}
    17     {% for kml_url in kml_urls %}{{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }} = new GGeoXml("{{ kml_url }}");
    18     {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }});{% endfor %}
    19     {% for polygon in polygons %}{{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }} = new {{ polygon }};
    20     {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }});
    21     {% for event in polygon.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_poly{{ forloop.parentloop.counter }}, {{ event }});{% endfor %}
    22     {% 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 %}
    23     {% for polyline in polylines %}{{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }} = new {{ polyline }};
    24     {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }});
    25     {% for event in polyline.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_polyline{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
    26     {% 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 %}
    27     {% for marker in markers %}{{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }} = new {{ marker }};
    28     {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }});
    29     {% for event in marker.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_marker{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
    30     {% if calc_zoom %}bounds.extend({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }}.getLatLng()); {% endif %}{% endfor %}
    31     {% if calc_zoom %}{{ js_module }}.{{ dom_id }}.setCenter(bounds.getCenter(), {{ js_module }}.{{ dom_id }}.getBoundsZoomLevel(bounds));{% endif %}
    32     {% block load_extra %}{% endblock %}
    33   }else {
    34     alert("Sorry, the Google Maps API is not compatible with this browser.");
    35   }
     7  {{ js_module }}.{{ dom_id }} = new google.maps.Map(document.getElementById("{{ dom_id }}"));
     8  {{ js_module }}.{{ dom_id }}.setCenter(new google.maps.LatLng({{ center.1 }}, {{ center.0 }}));
     9  {{ js_module }}.{{ dom_id }}.setZoom({{ zoom }});
     10  {% block controls %}{% endblock %}
     11  {% if calc_zoom %}var bounds = new google.maps.LatLngBounds(); var i; var j;{% endif %}
     12  {% for kml_url in kml_urls %}{{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }} = new google.maps.KmlLayer("{{ kml_url }}");
     13  {{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }}.setMap({{ js_module }}.{{ dom_id }});{% endfor %}
     14  {% for polygon in polygons %}{{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }} = new {{ polygon }};
     15  {{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }}.setMap({{ js_module }}.{{ dom_id }});
     16  {% for event in polygon.events %}google.event.addListener({{ js_module }}.{{ dom_id }}_poly{{ forloop.parentloop.counter }}, {{ event }});{% endfor %}
     17  {% if calc_zoom %}paths={{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }}.getPaths(); for(i=0; i<paths.length(); i++){ for(j=0; j<paths[i].length(); j++){ bounds.extend(paths[i][j]); }}{% endif %}{% endfor %} 
     18  {% for polyline in polylines %}{{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }} = new {{ polyline }};
     19  {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }});
     20  {% for event in polyline.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_polyline{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
     21  {% if calc_zoom %}path={{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }}.getPath(); for(i=0; i<path.length(); i++){ bounds.extend(path[i]); }{% endif %}{% endfor %}
     22  {% for marker in markers %}{{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }} = new {{ marker }};
     23  {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }});
     24  {% for event in marker.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_marker{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
     25  {% if calc_zoom %}bounds.extend({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }}.getPosition());{% endif %}{% endfor %}
     26  {% if calc_zoom %}{{ js_module }}.{{ dom_id }}.fitBounds(bounds);{% endif %}
     27  {% block load_extra %}{% endblock %}
    3628}
    3729{% endblock load %}{% endblock functions %}{% endlocalize %}{% endautoescape %}
  • django/contrib/gis/maps/google/gmap.py

     
    88
    99# The default Google Maps URL (for the API javascript)
    1010# TODO: Internationalize for Japan, UK, etc.
    11 GOOGLE_MAPS_URL='http://maps.google.com/maps?file=api&amp;v=%s&amp;key='
     11GOOGLE_MAPS_URL='http://maps.google.com/maps/api/js?sensor=%s'
    1212
    1313class GoogleMap(object):
    1414    "A class for generating Google Maps JavaScript."
    1515
    1616    # String constants
    17     onunload = mark_safe('onunload="GUnload()"') # Cleans up after Google Maps
     17    onunload = mark_safe('') # NOTE: Used to call GUnload, but google maps v3 doesn't need it so now blank
    1818    vml_css  = mark_safe('v\:* {behavior:url(#default#VML);}') # CSS for IE VML
    1919    xmlns    = mark_safe('xmlns:v="urn:schemas-microsoft-com:vml"') # XML Namespace (for IE VML).
    2020
    21     def __init__(self, key=None, api_url=None, version=None,
    22                  center=None, zoom=None, dom_id='map',
     21    def __init__(self, api_url=None, center=None, zoom=None, dom_id='map',
    2322                 kml_urls=[], polylines=None, polygons=None, markers=None,
     23                 using_sensor=False,
    2424                 template='gis/google/google-map.js',
    2525                 js_module='geodjango',
    2626                 extra_context={}):
    2727
    28         # The Google Maps API Key defined in the settings will be used
    29         # if not passed in as a parameter.  The use of an API key is
    30         # _required_.
    31         if not key:
    32             try:
    33                 self.key = settings.GOOGLE_MAPS_API_KEY
    34             except AttributeError:
    35                 raise GoogleMapException('Google Maps API Key not found (try adding GOOGLE_MAPS_API_KEY to your settings).')
    36         else:
    37             self.key = key
    38 
    39         # Getting the Google Maps API version, defaults to using the latest ("2.x"),
    40         # this is not necessarily the most stable.
    41         if not version:
    42             self.version = getattr(settings, 'GOOGLE_MAPS_API_VERSION', '2.x')
    43         else:
    44             self.version = version
    45 
    4628        # Can specify the API URL in the `api_url` keyword.
    4729        if not api_url:
    48             self.api_url = mark_safe(getattr(settings, 'GOOGLE_MAPS_URL', GOOGLE_MAPS_URL) % self.version)
     30            sensor_value = 'false' # maps v3 needs to know if the device rendering the page has a gps sensor
     31            if using_sensor: sensor_value = 'true'
     32            self.api_url = mark_safe(getattr(settings, 'GOOGLE_MAPS_URL', GOOGLE_MAPS_URL) % sensor_value)
    4933        else:
    5034            self.api_url = api_url
    5135
     
    118102    @property
    119103    def api_script(self):
    120104        "Returns the <script> tag for the Google Maps API javascript."
    121         return mark_safe('<script src="%s%s" type="text/javascript"></script>' % (self.api_url, self.key))
     105        return mark_safe('<script src="%s" type="text/javascript"></script>' % self.api_url)
    122106
    123107    @property
    124108    def js(self):
  • django/contrib/gis/maps/google/overlays.py

     
    33
    44class GEvent(object):
    55    """
    6     A Python wrapper for the Google GEvent object.
     6    A Python wrapper for wiring map events using the
     7    google.maps.event.addListener() function.
    78
    89    Events can be attached to any object derived from GOverlayBase with the
    910    add_event() call.
    1011
    1112    For more information please see the Google Maps API Reference:
    12      http://code.google.com/apis/maps/documentation/reference.html#GEvent
     13     http://code.google.com/apis/maps/documentation/javascript/reference.html#event
    1314
    1415    Example:
    1516
     
    5455        self.events = []
    5556
    5657    def latlng_from_coords(self, coords):
    57         "Generates a JavaScript array of GLatLng objects for the given coordinates."
    58         return '[%s]' % ','.join(['new GLatLng(%s,%s)' % (y, x) for x, y in coords])
     58        "Generates a JavaScript array of google.maps.LatLng objects for the given coordinates."
     59        return '[%s]' % ','.join(['new google.maps.LatLng(%s,%s)' % (y, x) for x, y in coords])
    5960
    6061    def add_event(self, event):
    61         "Attaches a GEvent to the overlay object."
     62        "Causes the event to be applied to the overlay object"
    6263        self.events.append(event)
    6364
    6465    def __unicode__(self):
     
    6768
    6869class GPolygon(GOverlayBase):
    6970    """
    70     A Python wrapper for the Google GPolygon object.  For more information
     71    A Python wrapper for the google.maps.Polygon object.  For more information
    7172    please see the Google Maps API Reference:
    72      http://code.google.com/apis/maps/documentation/reference.html#GPolygon
     73     http://code.google.com/apis/maps/documentation/javascript/reference.html#Polygon
    7374    """
    7475    def __init__(self, poly,
    7576                 stroke_color='#0000ff', stroke_weight=2, stroke_opacity=1,
    7677                 fill_color='#0000ff', fill_opacity=0.4):
    7778        """
    78         The GPolygon object initializes on a GEOS Polygon or a parameter that
    79         may be instantiated into GEOS Polygon.  Please note that this will not
    80         depict a Polygon's internal rings.
     79        The GPolygon object initializes on a GEOS Polygon or a
     80        parameter that may be instantiated into GEOS Polygon.  Please note
     81        that this will not depict a Polygon's internal rings.
    8182
    8283        Keyword Options:
    8384
     
    119120
    120121    @property
    121122    def js_params(self):
    122         return '%s, "%s", %s, %s, "%s", %s' % (self.points, self.stroke_color, self.stroke_weight, self.stroke_opacity,
    123                                                self.fill_color, self.fill_opacity)
     123        result = []
     124        result.append('paths: %s' % self.points)
     125        if self.stroke_color: result.append('strokeColor: "%s"' % self.stroke_color)
     126        if self.stroke_weight: result.append('strokeWeight: "%s"' % self.stroke_weight)
     127        if self.stroke_opacity: result.append('strokeOpacity: "%s"' % self.stroke_opacity)
     128        if self.fill_color: result.append('fillColor: "%s"' % self.fill_color)
     129        if self.fill_opacity: result.append('fillOpactiy: "%s"' % self.fill_opacity)
     130        return '{%s}' % ','.join(result)
    124131
    125132class GPolyline(GOverlayBase):
    126133    """
    127     A Python wrapper for the Google GPolyline object.  For more information
     134    A Python wrapper for the google.maps.Polyline object.  For more information
    128135    please see the Google Maps API Reference:
    129      http://code.google.com/apis/maps/documentation/reference.html#GPolyline
     136     http://code.google.com/apis/maps/documentation/javascript/reference.html#Polyline
    130137    """
    131138    def __init__(self, geom, color='#0000ff', weight=2, opacity=1):
    132139        """
     
    163170
    164171    @property
    165172    def js_params(self):
    166         return '%s, "%s", %s, %s' % (self.latlngs, self.color, self.weight, self.opacity)
     173        result = []
     174        result.append('path: %s' % self.latlngs)
     175        if self.color: result.append('strokeColor: "%s"' % self.color)
     176        if self.weight: result.append('strokeWeight: "%s"' % self.weight)
     177        if self.opacity: result.append('strokeOpacity: "%s"' % self.opacity)
     178        return '{%s}' % ','.join(result)
    167179
    168180
    169 class GIcon(object):
     181class GImage(object):
    170182    """
    171     Creates a GIcon object to pass into a Gmarker object.
     183    Creates a GImage object to pass into a Gmarker object for the icon
     184    and shadow arguments.  The arguments are used to create a MarkerImage
     185    class in the javascript:
    172186
    173     The keyword arguments map to instance attributes of the same name. These,
    174     in turn, correspond to a subset of the attributes of the official GIcon
    175     javascript object:
     187    http://code.google.com/apis/maps/documentation/javascript/reference.html#MarkerImage
    176188
    177     http://code.google.com/apis/maps/documentation/reference.html#GIcon
    178 
    179     Because a Google map often uses several different icons, a name field has
    180     been added to the required arguments.
    181 
    182189    Required Arguments:
    183         varname:
    184             A string which will become the basis for the js variable name of
    185             the marker, for this reason, your code should assign a unique
    186             name for each GIcon you instantiate, otherwise there will be
    187             name space collisions in your javascript.
     190       
     191        url:
     192            The url of the image to be used as the icon on the map
    188193
    189194    Keyword Options:
    190         image:
    191             The url of the image to be used as the icon on the map defaults
    192             to 'G_DEFAULT_ICON'
    193195
    194         iconsize:
     196        size:
    195197            a tuple representing the pixel size of the foreground (not the
    196198            shadow) image of the icon, in the format: (width, height) ex.:
    197199
    198             GIcon('fast_food',
    199                   image="/media/icon/star.png",
     200            GIcon("/media/icon/star.png",
    200201                  iconsize=(15,10))
    201202
    202203            Would indicate your custom icon was 15px wide and 10px height.
    203 
    204         shadow:
    205             the url of the image of the icon's shadow
    206 
    207         shadowsize:
    208             a tuple representing the pixel size of the shadow image, format is
    209             the same as ``iconsize``
    210 
    211         iconanchor:
     204           
     205        origin:
     206            a tuple representing the pixel coordinate of the upper left corner
     207            of the icon.  Used in conjuction with the size option to specify
     208            the sprite/subset of an image.  In the format: (x,y) ex.:
     209           
     210            3rd_marker = GIcon("/media/icon/12_markers.png",
     211                               size=(15,10),
     212                               origin=(30,0))
     213                               
     214            Would indicate the image where it's upper left corner is at (30,0)
     215            and its lower right corner is (45,10).
     216           
     217        anchor:
    212218            a tuple representing the pixel coordinate relative to the top left
    213219            corner of the icon image at which this icon is anchored to the map.
    214220            In (x, y) format.  x increases to the right in the Google Maps
    215221            coordinate system and y increases downwards in the Google Maps
    216222            coordinate system.)
    217223
    218         infowindowanchor:
    219             The pixel coordinate relative to the top left corner of the icon
    220             image at which the info window is anchored to this icon.
    221 
    222224    """
    223     def __init__(self, varname, image=None, iconsize=None,
    224                  shadow=None, shadowsize=None, iconanchor=None,
    225                  infowindowanchor=None):
    226         self.varname = varname
    227         self.image = image
    228         self.iconsize = iconsize
    229         self.shadow = shadow
    230         self.shadowsize = shadowsize
    231         self.iconanchor = iconanchor
    232         self.infowindowanchor = infowindowanchor
     225    def __init__(self, url, size=None, origin=None, anchor=None):
     226        self.url = url
     227        self.size = size
     228        self.origin = origin
     229        self.anchor = anchor
    233230
    234     def __cmp__(self, other):
    235         return cmp(self.varname, other.varname)
    236    
    237     def __hash__(self):
    238         # XOR with hash of GIcon type so that hash('varname') won't
    239         # equal hash(GIcon('varname')).
    240         return hash(self.__class__) ^ hash(self.varname)
     231    def _to_param(self):
     232        args = "(%s" % self.url
     233        if self.size:
     234            args += ", new google.maps.Size(%s)" % self.size
     235            if self.origin:
     236                args += ", new google.maps.Point(%s)" % self.origin
     237                if self.anchor:
     238                    args += ", new google.maps.Point(%s)" % self.anchor
     239        args += ")"
     240        return "new google.maps.MarkerImage(%s)" % args
    241241
    242242class GMarker(GOverlayBase):
    243243    """
    244244    A Python wrapper for the Google GMarker object.  For more information
    245245    please see the Google Maps API Reference:
    246      http://code.google.com/apis/maps/documentation/reference.html#GMarker
     246     http://code.google.com/apis/maps/documentation/javascript/reference.html#Marker
    247247
    248248    Example:
    249249
     
    258258          return render_to_response('mytemplate.html',
    259259                 {'google' : GoogleMap(markers=[marker])})
    260260    """
    261     def __init__(self, geom, title=None, draggable=False, icon=None):
     261    def __init__(self, geom, title=None, draggable=False, icon=None, shadow=None):
    262262        """
    263263        The GMarker object may initialize on GEOS Points or a parameter
    264         that may be instantiated into a GEOS point.  Keyword options map to
    265         GMarkerOptions -- so far only the title option is supported.
     264        that may be instantiated into a GEOS point.
    266265
    267266        Keyword Options:
    268267         title:
     
    270269
    271270         draggable:
    272271           Draggable option for GMarker, disabled by default.
     272           
     273         icon:
     274           Sets the GIcon used to display the marker on the map.
     275           If not set google maps will use the default marker icon.
     276           
     277         shadow:
     278           Sets the GIcon used to display the shadow of the marker on the map.
    273279        """
    274280        # If a GEOS geometry isn't passed in, try to construct one.
    275281        if isinstance(geom, basestring): geom = fromstr(geom)
     
    284290        self.title = title
    285291        self.draggable = draggable
    286292        self.icon = icon
     293        self.shadow = shadow
    287294        super(GMarker, self).__init__()
    288295
    289296    def latlng_from_coords(self, coords):
    290         return 'new GLatLng(%s,%s)' %(coords[1], coords[0])
     297        return 'new google.maps.LatLng(%s,%s)' %(coords[1], coords[0])
    291298
    292     def options(self):
     299    @property
     300    def js_params(self):
    293301        result = []
     302        result.append('position: %s' % self.latlng)
    294303        if self.title: result.append('title: "%s"' % self.title)
    295         if self.icon: result.append('icon: %s' % self.icon.varname)
     304        if self.icon: result.append('icon: %s' % self.icon._to_param())
     305        if self.shadow: result.append('shadow: %s' % self.shadow_to_param())
    296306        if self.draggable: result.append('draggable: true')
    297307        return '{%s}' % ','.join(result)
    298 
    299     @property
    300     def js_params(self):
    301         return '%s, %s' % (self.latlng, self.options())
Back to Top