Ticket #9955: google-maps.patch

File google-maps.patch, 13.2 KB (added by aromano, 6 years ago)

Google Maps patch - multiple map instance support

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

     
    1 {% autoescape off %}{% block vars %}var map;{% endblock %}
     1{% autoescape off %}{% block vars %}var maps;{% endblock %}
    22{% block functions %}{% endblock %}
    33{% block load %}function {{ load_func }}(){
     4  maps = new Array();
     5
     6  {% for map in maps %}//initializing map {{ map.id }}
    47  if (GBrowserIsCompatible()) {
    5     map = new GMap2(document.getElementById("{{ dom_id }}"));
    6     map.setCenter(new GLatLng({{ center.1 }}, {{ center.0 }}), {{ zoom }});
    7     {% block controls %}map.addControl(new GSmallMapControl());
    8     map.addControl(new GMapTypeControl());{% endblock %}
    9     {% if calc_zoom %}var bounds = new GLatLngBounds(); var tmp_bounds = new GLatLngBounds();{% endif %}
    10     {% for kml_url in kml_urls %}var kml{{ forloop.counter }} = new GGeoXml("{{ kml_url }}");
    11     map.addOverlay(kml{{ forloop.counter }});{% endfor %}
     8    maps[{{map.id}}] = new GMap2(document.getElementById("{{ map.dom_id }}"));
     9    maps[{{map.id}}].setCenter(new GLatLng({{ map.center.1 }}, {{ map.center.0 }}), {{ map.zoom }});
     10    {% block controls %}maps[{{map.id}}].addControl(new GSmallMapControl());
     11    maps[{{map.id}}].addControl(new GMapTypeControl());{% endblock %}
     12    {% if map.calc_zoom %}var bounds = new GLatLngBounds(); var tmp_bounds = new GLatLngBounds();{% endif %}
     13    {% for kml_url in map.kml_urls %}var kml{{ forloop.counter }} = new GGeoXml("{{ kml_url }}");
     14    maps[{{map.id}}].addOverlay(kml{{ forloop.counter }});{% endfor %}
    1215
    13     {% for polygon in polygons %}var poly{{ forloop.counter }} = new {{ polygon }};
    14     map.addOverlay(poly{{ forloop.counter }});
    15     {% for event in polygon.events %}GEvent.addListener(poly{{ forloop.parentloop.counter }}, {{ event }});{% endfor %}
    16     {% if calc_zoom %}tmp_bounds = poly{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %}
     16    {% for polygon in map.polygons %}var poly{{ forloop.counter }} = new {{ polygon }};
     17    maps[{{map.id}}].addOverlay(poly{{ forloop.counter }});
     18    {% for event in map.polygon.events %}GEvent.addListener(poly{{ forloop.parentloop.counter }}, {{ event }});{% endfor %}
     19    {% if map.calc_zoom %}tmp_bounds = poly{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %}
    1720
    18     {% for polyline in polylines %}var polyline{{ forloop.counter }} = new {{ polyline }};
    19     map.addOverlay(polyline{{ forloop.counter }});
    20     {% for event in polyline.events %}GEvent.addListener(polyline{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
    21     {% if calc_zoom %}tmp_bounds = polyline{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %}
     21    {% for polyline in map.polylines %}var polyline{{ forloop.counter }} = new {{ polyline }};
     22    maps[{{map.id}}].addOverlay(polyline{{ forloop.counter }});
     23    {% for event in map.polyline.events %}GEvent.addListener(polyline{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
     24    {% if map.calc_zoom %}tmp_bounds = polyline{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %}
    2225   
    23     {% for marker in markers %}var marker{{ forloop.counter }} = new {{ marker }};
    24     map.addOverlay(marker{{ forloop.counter }});
    25     {% for event in marker.events %}GEvent.addListener(marker{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
    26     {% if calc_zoom %}bounds.extend(marker{{ forloop.counter }}.getLatLng()); {% endif %}{% endfor %}
     26    {% for marker in map.markers %}var marker{{ forloop.counter }} = new {{ marker }};
     27    maps[{{map.id}}].addOverlay(marker{{ forloop.counter }});
     28    {% for event in map.marker.events %}GEvent.addListener(marker{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %}
     29    {% if map.calc_zoom %}bounds.extend(marker{{ forloop.counter }}.getLatLng()); {% endif %}{% endfor %}
    2730
    28     {% if calc_zoom %}map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));{% endif %}
     31    {% if map.calc_zoom %}maps[{{map.id}}].setCenter(bounds.getCenter(), maps[{{map.id}}].getBoundsZoomLevel(bounds));{% endif %}
    2932    {% block load_extra %}{% endblock %}
     33
    3034  }else {
    3135    alert("Sorry, the Google Maps API is not compatible with this browser.");
     36  }{% endfor %}
    3237  }
     38
     39// getIcon function - used to return a personalized GMarker
     40function gmap_getIcon(path,width,height) {
     41  var gicon = new GIcon(G_DEFAULT_ICON, path);
     42  if(height != undefined && width != undefined) { gicon.iconSize = new GSize(width,height); }
     43  return gicon;
    3344}
    3445{% endblock %}{% endautoescape %}
  • django/contrib/gis/maps/google/__init__.py

     
    5656   * GOOGLE_MAPS_URL (optional): Must have a substitution ('%s') for the API
    5757      version.
    5858"""
    59 from django.contrib.gis.maps.google.gmap import GoogleMap
     59from django.contrib.gis.maps.google.gmap import GoogleMap, GoogleMapSet
    6060from django.contrib.gis.maps.google.overlays import GEvent, GMarker, GPolygon, GPolyline
    6161from django.contrib.gis.maps.google.zoom import GoogleZoom
  • django/contrib/gis/maps/google/gmap.py

     
    1111GOOGLE_MAPS_URL='http://maps.google.com/maps?file=api&v=%s&key='
    1212
    1313class GoogleMap(object):
    14     "A class for generating Google Maps JavaScript."
     14    "A class for generating a single Google Maps JavaScript instance."
    1515
    1616    # String constants
    17     onunload = mark_safe('onunload="GUnload()"') # Cleans up after Google Maps
    18     vml_css  = mark_safe('v\:* {behavior:url(#default#VML);}') # CSS for IE VML
    19     xmlns    = mark_safe('xmlns:v="urn:schemas-microsoft-com:vml"') # XML Namespace (for IE VML).
    20 
    21     def __init__(self, key=None, api_url=None, version=None,
    22                  center=None, zoom=None, dom_id='map', load_func='gmap_load',
     17    def __init__(self,
     18                 center=None, zoom=None, dom_id='map',
    2319                 kml_urls=[], polygons=[], polylines=[], markers=[],
    24                  template='gis/google/js/google-map.js',
    2520                 extra_context={}):
    2621
    27         # The Google Maps API Key defined in the settings will be used
    28         #  if not passed in as a parameter.  The use of an API key is
    29         #  _required_.
    30         if not key:
    31             try:
    32                 self.key = settings.GOOGLE_MAPS_API_KEY
    33             except AttributeError:
    34                 raise GoogleMapException('Google Maps API Key not found (try adding GOOGLE_MAPS_API_KEY to your settings).')
    35         else:
    36             self.key = key
    37        
    38         # Getting the Google Maps API version, defaults to using the latest ("2.x"),
    39         #  this is not necessarily the most stable.
    40         if not version:
    41             self.version = getattr(settings, 'GOOGLE_MAPS_API_VERSION', '2.x')
    42         else:
    43             self.version = version
    44 
    45         # Can specify the API URL in the `api_url` keyword.
    46         if not api_url:
    47             self.api_url = mark_safe(getattr(settings, 'GOOGLE_MAPS_URL', GOOGLE_MAPS_URL) % self.version)
    48         else:
    49             self.api_url = api_url
    50 
    51         # Setting the DOM id of the map, the load function, the JavaScript
    52         # template, and the KML URLs array.
     22        # Setting the DOM id of the map and the KML URLs array.
    5323        self.dom_id = dom_id
    54         self.load_func = load_func
    55         self.template = template
    5624        self.kml_urls = kml_urls
    5725       
    5826        # Does the user want any GMarker, GPolygon, and/or GPolyline overlays?
     
    9462        self.center = center
    9563
    9664        # Setting the parameters for the javascript template.
    97         params = {'calc_zoom' : self.calc_zoom,
     65        self.params = {'calc_zoom' : self.calc_zoom,
    9866                  'center' : self.center,
    9967                  'dom_id' : self.dom_id,
    10068                  'kml_urls' : self.kml_urls,
    101                   'load_func' : self.load_func,
    10269                  'zoom' : self.zoom,
    10370                  'polygons' : self.polygons,
    10471                  'polylines' : self.polylines,
    10572                  'markers' : self.markers,
    10673                  }
    107         params.update(extra_context)
     74        self.params.update(extra_context)
     75
     76class GoogleMapSet(object):
     77    onunload = mark_safe('onunload="GUnload()"') # Cleans up after Google Maps
     78    vml_css  = mark_safe('v\:* {behavior:url(#default#VML);}') # CSS for IE VML
     79    xmlns    = mark_safe('xmlns:v="urn:schemas-microsoft-com:vml"') # XML Namespace (for IE VML).
     80
     81    def __init__(self, maps, key=None, api_url=None, version=None,
     82                 load_func='gmap_load',template='gis/google/js/google-map.js'):
     83        # The Google Maps API Key defined in the settings will be used
     84        #  if not passed in as a parameter.  The use of an API key is
     85        #  _required_.
     86        if not key:
     87            try:
     88                self.key = settings.GOOGLE_MAPS_API_KEY
     89            except AttributeError:
     90                raise GoogleMapException('Google Maps API Key not found (try adding GOOGLE_MAPS_API_KEY to your settings).')
     91        else:
     92            self.key = key
     93       
     94        # Getting the Google Maps API version, defaults to using the latest ("2.x"),
     95        #  this is not necessarily the most stable.
     96        if not version:
     97            self.version = getattr(settings, 'GOOGLE_MAPS_API_VERSION', '2.x')
     98        else:
     99            self.version = version
     100
     101        # Can specify the API URL in the `api_url` keyword.
     102        if not api_url:
     103            self.api_url = mark_safe(getattr(settings, 'GOOGLE_MAPS_URL', GOOGLE_MAPS_URL) % self.version)
     104        else:
     105            self.api_url = api_url
     106
     107        params = {'maps'     : [g.params for g in maps],
     108                  'load_func': load_func}
     109
     110        # keep sure dom ids are unique, if they are not they must be regenerated
     111        dom_ids = {}
     112        dom_ids_unique = True
     113        dom_counter = 0
     114        for g in params['maps']:
     115            g['id'] = dom_counter
     116            dom_counter = dom_counter+1
     117
     118            if(not dom_ids.has_key(g['dom_id'])): dom_ids[g['dom_id']] = 1
     119            else: dom_ids_unique = False
     120
     121        if(not dom_ids_unique):
     122            dom_counter = 1
     123            for g in params['maps']:
     124                g['dom_id'] = 'map_%d' % dom_counter
     125                dom_counter = dom_counter + 1
     126               
     127        self.template = template
     128       
    108129        self.js = render_to_string(self.template, params)
     130        self.maps = params['maps']
    109131
    110132    @property
    111133    def body(self):
     
    136158    def xhtml(self):
    137159        "Returns XHTML information needed for IE VML overlays."
    138160        return mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" %s>' % self.xmlns)
     161
  • django/contrib/gis/maps/google/overlays.py

     
    184184          return render_to_response('mytemplate.html',
    185185                 {'google' : GoogleMap(markers=[marker])})
    186186    """
    187     def __init__(self, geom, title=None):
     187    def __init__(self, geom, title=None, icon=None):
    188188        """
    189189        The GMarker object may initialize on GEOS Points or a parameter
    190190        that may be instantiated into a GEOS point.  Keyword options map to
     
    193193        Keyword Options:
    194194         title:
    195195           Title option for GMarker, will be displayed as a tooltip.
     196         icon:
     197           Icon option(s) for GMarker ({path, width, height} or just "path" as a string)
    196198        """
    197199        # If a GEOS geometry isn't passed in, try to construct one.
    198200        if isinstance(geom, basestring): geom = fromstr(geom)
     
    205207        self.envelope = geom.envelope
    206208        # TODO: Add support for more GMarkerOptions
    207209        self.title = title
     210        if(isinstance(icon, basestring)): icon = {'path': icon}
     211        self.icon = icon
    208212        super(GMarker, self).__init__()
    209213
    210214    def latlng_from_coords(self, coords):
     
    213217    def options(self):
    214218        result = []
    215219        if self.title: result.append('title: "%s"' % self.title)
     220        if self.icon: result.append('icon: %s' % self.getIcon())
    216221        return '{%s}' % ','.join(result)
    217222
     223    def getIcon(self):
     224        params = []
     225        params.append("""'%s'""" % self.icon['path']);
     226        if (self.icon.has_key('width') and self.icon.has_key('height')):
     227                params.append(self.icon['width']);
     228                params.append(self.icon['height']);
     229
     230        s = """gmap_getIcon(%s)""" % ",".join(params);
     231        return s
     232
    218233    @property
    219234    def js_params(self):
    220235        return '%s, %s' % (self.latlng, self.options())
     236
Back to Top