|
1 from django.utils.safestring import mark_safe |
|
2 from django.contrib.gis.geos import fromstr, Point, LineString, LinearRing, Polygon |
|
3 |
|
4 class GEvent(object): |
|
5 """ |
|
6 A Python wrapper for the Google GEvent object. |
|
7 |
|
8 Events can be attached to any object derived from GOverlayBase with the |
|
9 add_event() call. |
|
10 |
|
11 For more information please see the Google Maps API Reference: |
|
12 http://code.google.com/apis/maps/documentation/reference.html#GEvent |
|
13 |
|
14 Example: |
|
15 |
|
16 from django.shortcuts import render_to_response |
|
17 from django.contrib.gis.maps.google import GoogleMap, GEvent, GPolyline |
|
18 |
|
19 def sample_request(request): |
|
20 polyline = GPolyline('LINESTRING(101 26, 112 26, 102 31)') |
|
21 event = GEvent('click', |
|
22 'function() { location.href = "http://www.google.com"}') |
|
23 polyline.add_event(event) |
|
24 return render_to_response('mytemplate.html', |
|
25 {'google' : GoogleMap(polylines=[polyline])}) |
|
26 """ |
|
27 |
|
28 def __init__(self, event, action): |
|
29 """ |
|
30 Initializes a GEvent object. |
|
31 |
|
32 Parameters: |
|
33 |
|
34 event: |
|
35 string for the event, such as 'click'. The event must be a valid |
|
36 event for the object in the Google Maps API. |
|
37 There is no validation of the event type within Django. |
|
38 |
|
39 action: |
|
40 string containing a Javascript function, such as |
|
41 'function() { location.href = "newurl";}' |
|
42 The string must be a valid Javascript function. Again there is no |
|
43 validation fo the function within Django. |
|
44 """ |
|
45 self.event = event |
|
46 self.action = action |
|
47 |
|
48 def __unicode__(self): |
|
49 "Returns the parameter part of a GEvent." |
|
50 return mark_safe('"%s", %s' %(self.event, self.action)) |
|
51 |
|
52 class GOverlayBase(object): |
|
53 def __init__(self): |
|
54 self.events = [] |
|
55 |
|
56 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]) |
|
59 |
|
60 def add_event(self, event): |
|
61 "Attaches a GEvent to the overlay object." |
|
62 self.events.append(event) |
|
63 |
|
64 def __unicode__(self): |
|
65 "The string representation is the JavaScript API call." |
|
66 return mark_safe('%s(%s)' % (self.__class__.__name__, self.js_params)) |
|
67 |
|
68 class GPolygon(GOverlayBase): |
|
69 """ |
|
70 A Python wrapper for the Google GPolygon object. For more information |
|
71 please see the Google Maps API Reference: |
|
72 http://code.google.com/apis/maps/documentation/reference.html#GPolygon |
|
73 """ |
|
74 def __init__(self, poly, |
|
75 stroke_color='#0000ff', stroke_weight=2, stroke_opacity=1, |
|
76 fill_color='#0000ff', fill_opacity=0.4): |
|
77 """ |
|
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. |
|
81 |
|
82 Keyword Options: |
|
83 |
|
84 stroke_color: |
|
85 The color of the polygon outline. Defaults to '#0000ff' (blue). |
|
86 |
|
87 stroke_weight: |
|
88 The width of the polygon outline, in pixels. Defaults to 2. |
|
89 |
|
90 stroke_opacity: |
|
91 The opacity of the polygon outline, between 0 and 1. Defaults to 1. |
|
92 |
|
93 fill_color: |
|
94 The color of the polygon fill. Defaults to '#0000ff' (blue). |
|
95 |
|
96 fill_opacity: |
|
97 The opacity of the polygon fill. Defaults to 0.4. |
|
98 """ |
|
99 if isinstance(poly, basestring): poly = fromstr(poly) |
|
100 if isinstance(poly, (tuple, list)): poly = Polygon(poly) |
|
101 if not isinstance(poly, Polygon): |
|
102 raise TypeError('GPolygon may only initialize on GEOS Polygons.') |
|
103 |
|
104 # Getting the envelope of the input polygon (used for automatically |
|
105 # determining the zoom level). |
|
106 self.envelope = poly.envelope |
|
107 |
|
108 # Translating the coordinates into a JavaScript array of |
|
109 # Google `GLatLng` objects. |
|
110 self.points = self.latlng_from_coords(poly.shell.coords) |
|
111 |
|
112 # Stroke settings. |
|
113 self.stroke_color, self.stroke_opacity, self.stroke_weight = stroke_color, stroke_opacity, stroke_weight |
|
114 |
|
115 # Fill settings. |
|
116 self.fill_color, self.fill_opacity = fill_color, fill_opacity |
|
117 |
|
118 super(GPolygon, self).__init__() |
|
119 |
|
120 @property |
|
121 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) |
|
124 |
|
125 class GPolyline(GOverlayBase): |
|
126 """ |
|
127 A Python wrapper for the Google GPolyline object. For more information |
|
128 please see the Google Maps API Reference: |
|
129 http://code.google.com/apis/maps/documentation/reference.html#GPolyline |
|
130 """ |
|
131 def __init__(self, geom, color='#0000ff', weight=2, opacity=1): |
|
132 """ |
|
133 The GPolyline object may be initialized on GEOS LineStirng, LinearRing, |
|
134 and Polygon objects (internal rings not supported) or a parameter that |
|
135 may instantiated into one of the above geometries. |
|
136 |
|
137 Keyword Options: |
|
138 |
|
139 color: |
|
140 The color to use for the polyline. Defaults to '#0000ff' (blue). |
|
141 |
|
142 weight: |
|
143 The width of the polyline, in pixels. Defaults to 2. |
|
144 |
|
145 opacity: |
|
146 The opacity of the polyline, between 0 and 1. Defaults to 1. |
|
147 """ |
|
148 # If a GEOS geometry isn't passed in, try to contsruct one. |
|
149 if isinstance(geom, basestring): geom = fromstr(geom) |
|
150 if isinstance(geom, (tuple, list)): geom = Polygon(geom) |
|
151 # Generating the lat/lng coordinate pairs. |
|
152 if isinstance(geom, (LineString, LinearRing)): |
|
153 self.latlngs = self.latlng_from_coords(geom.coords) |
|
154 elif isinstance(geom, Polygon): |
|
155 self.latlngs = self.latlng_from_coords(geom.shell.coords) |
|
156 else: |
|
157 raise TypeError('GPolyline may only initialize on GEOS LineString, LinearRing, and/or Polygon geometries.') |
|
158 |
|
159 # Getting the envelope for automatic zoom determination. |
|
160 self.envelope = geom.envelope |
|
161 self.color, self.weight, self.opacity = color, weight, opacity |
|
162 super(GPolyline, self).__init__() |
|
163 |
|
164 @property |
|
165 def js_params(self): |
|
166 return '%s, "%s", %s, %s' % (self.latlngs, self.color, self.weight, self.opacity) |
|
167 |
|
168 class GMarker(GOverlayBase): |
|
169 """ |
|
170 A Python wrapper for the Google GMarker object. For more information |
|
171 please see the Google Maps API Reference: |
|
172 http://code.google.com/apis/maps/documentation/reference.html#GMarker |
|
173 |
|
174 Example: |
|
175 |
|
176 from django.shortcuts import render_to_response |
|
177 from django.contrib.gis.maps.google.overlays import GMarker, GEvent |
|
178 |
|
179 def sample_request(request): |
|
180 marker = GMarker('POINT(101 26)') |
|
181 event = GEvent('click', |
|
182 'function() { location.href = "http://www.google.com"}') |
|
183 marker.add_event(event) |
|
184 return render_to_response('mytemplate.html', |
|
185 {'google' : GoogleMap(markers=[marker])}) |
|
186 """ |
|
187 def __init__(self, geom, title=None): |
|
188 """ |
|
189 The GMarker object may initialize on GEOS Points or a parameter |
|
190 that may be instantiated into a GEOS point. Keyword options map to |
|
191 GMarkerOptions -- so far only the title option is supported. |
|
192 |
|
193 Keyword Options: |
|
194 title: |
|
195 Title option for GMarker, will be displayed as a tooltip. |
|
196 """ |
|
197 # If a GEOS geometry isn't passed in, try to construct one. |
|
198 if isinstance(geom, basestring): geom = fromstr(geom) |
|
199 if isinstance(geom, (tuple, list)): geom = Point(geom) |
|
200 if isinstance(geom, Point): |
|
201 self.latlng = self.latlng_from_coords(geom.coords) |
|
202 else: |
|
203 raise TypeError('GMarker may only initialize on GEOS Point geometry.') |
|
204 # Getting the envelope for automatic zoom determination. |
|
205 self.envelope = geom.envelope |
|
206 # TODO: Add support for more GMarkerOptions |
|
207 self.title = title |
|
208 super(GMarker, self).__init__() |
|
209 |
|
210 def latlng_from_coords(self, coords): |
|
211 return 'new GLatLng(%s,%s)' %(coords[1], coords[0]) |
|
212 |
|
213 def options(self): |
|
214 result = [] |
|
215 if self.title: result.append('title: "%s"' % self.title) |
|
216 return '{%s}' % ','.join(result) |
|
217 |
|
218 @property |
|
219 def js_params(self): |
|
220 return '%s, %s' % (self.latlng, self.options()) |