/src/wt/src/Wt/WGoogleMap.C
Line | Count | Source |
1 | | // This may look like C code, but it's really -*- C++ -*- |
2 | | /* |
3 | | * Copyright (C) 2008 Emweb bv, Herent, Belgium. |
4 | | * |
5 | | * See the LICENSE file for terms of use. |
6 | | * |
7 | | * Contributed by: Richard Ulrich. |
8 | | */ |
9 | | |
10 | | #include <Wt/WGoogleMap.h> |
11 | | #include <Wt/WApplication.h> |
12 | | #include <Wt/WContainerWidget.h> |
13 | | |
14 | | #include "web/WebUtils.h" |
15 | | |
16 | | #include <string> |
17 | | #include <utility> |
18 | | #include <iostream> |
19 | | #include <cmath> |
20 | | |
21 | | #ifndef M_PI |
22 | | #define M_PI 3.14159265358979323846 |
23 | | #endif |
24 | | |
25 | | namespace { |
26 | | // if there is no google api key configured, use the one for |
27 | | // http://localhost:8080/ |
28 | | static const std::string localhost_key |
29 | | = "ABQIAAAAWqrN5o4-ISwj0Up_depYvhTwM0brOpm-" |
30 | | "All5BF6PoaKBxRWWERS-S9gPtCri-B6BZeXV8KpT4F80DQ"; |
31 | | |
32 | | void write(std::stringstream& os, const Wt::WGoogleMap::Coordinate &c) |
33 | 0 | { |
34 | 0 | char b1[35]; |
35 | 0 | char b2[35]; |
36 | 0 | os << "new google.maps.LatLng(" |
37 | 0 | << Wt::Utils::round_js_str(c.latitude(), 15, b1) |
38 | 0 | << "," << Wt::Utils::round_js_str(c.longitude(), 15, b2) << ")"; |
39 | 0 | } |
40 | | } |
41 | | |
42 | | namespace Wt { |
43 | | |
44 | | WGoogleMap::Coordinate::Coordinate() |
45 | 0 | : lat_(0), lon_(0) |
46 | 0 | { } |
47 | | |
48 | | WGoogleMap::Coordinate::Coordinate(double lat, double lon) |
49 | 0 | { |
50 | 0 | setLatitude(lat); |
51 | 0 | setLongitude(lon); |
52 | 0 | } |
53 | | |
54 | | #ifndef WT_TARGET_JAVA |
55 | | WGoogleMap::Coordinate::Coordinate(const std::pair<double, double>& lat_long) |
56 | 0 | { |
57 | 0 | setLatitude(lat_long.first); |
58 | 0 | setLongitude(lat_long.second); |
59 | 0 | } |
60 | | #endif |
61 | | |
62 | | void WGoogleMap::Coordinate::setLatitude(double latitude) |
63 | 0 | { |
64 | 0 | if (latitude < -90.0 || latitude > 90.0) |
65 | 0 | throw std::out_of_range("invalid latitude: " |
66 | 0 | + std::to_string(latitude)); |
67 | | |
68 | 0 | lat_ = latitude; |
69 | 0 | } |
70 | | |
71 | | void WGoogleMap::Coordinate::setLongitude(double longitude) |
72 | 0 | { |
73 | 0 | if (longitude < -180.0 || longitude > 180.0) |
74 | 0 | throw std::out_of_range("invalid longitude: " |
75 | 0 | + std::to_string(longitude)); |
76 | | |
77 | 0 | lon_ = longitude; |
78 | 0 | } |
79 | | |
80 | | double WGoogleMap::Coordinate::distanceTo(const Coordinate &rhs) const |
81 | 0 | { |
82 | 0 | const double lat1 = lat_ * M_PI / 180.0; |
83 | 0 | const double lat2 = rhs.latitude() * M_PI / 180.0; |
84 | 0 | const double deltaLong = (rhs.longitude() - lon_) * M_PI / 180.0; |
85 | 0 | const double angle = std::sin(lat1) * std::sin(lat2) |
86 | 0 | + std::cos(lat1) * std::cos(lat2) * std::cos(deltaLong); |
87 | 0 | const double earthRadius = 6371.0; // km |
88 | 0 | const double dist = earthRadius * std::acos(angle); |
89 | |
|
90 | 0 | return dist; |
91 | 0 | } |
92 | | |
93 | | #ifndef WT_TARGET_JAVA |
94 | | std::pair<double, double> WGoogleMap::Coordinate::operator ()() const |
95 | 0 | { |
96 | 0 | return std::make_pair(lat_, lon_); |
97 | 0 | } |
98 | | |
99 | | std::istream& operator>> (std::istream& i, WGoogleMap::Coordinate& c) |
100 | 0 | { |
101 | 0 | double lat, lon; |
102 | 0 | i >> lat >> std::ws >> lon; |
103 | 0 | c.setLatitude(lat); |
104 | 0 | c.setLongitude(lon); |
105 | |
|
106 | 0 | return i; |
107 | 0 | } |
108 | | #endif |
109 | | |
110 | | // example javascript code from : |
111 | | // http://code.google.com/apis/maps/documentation/ |
112 | | |
113 | | WGoogleMap::WGoogleMap(GoogleMapsVersion version) |
114 | 0 | : clicked_(this, "click"), |
115 | 0 | doubleClicked_(this, "dblclick"), |
116 | 0 | mouseMoved_(nullptr), |
117 | 0 | apiVersion_(version) |
118 | 0 | { |
119 | 0 | setImplementation(std::unique_ptr<WWidget>(new WContainerWidget())); |
120 | |
|
121 | 0 | WApplication *app = WApplication::instance(); |
122 | 0 | googlekey_ = localhost_key; |
123 | 0 | WApplication::readConfigurationProperty("google_api_key", googlekey_); |
124 | | |
125 | | // init the google javascript api |
126 | 0 | const std::string gmuri = "//www.google.com/jsapi?key=" + googlekey_; |
127 | 0 | app->require(gmuri, "google"); |
128 | 0 | } |
129 | | |
130 | | WGoogleMap::~WGoogleMap() |
131 | 0 | { |
132 | 0 | delete mouseMoved_; |
133 | 0 | } |
134 | | |
135 | | void WGoogleMap::streamJSListener(const JSignal<Coordinate> &signal, |
136 | | std::string signalName, |
137 | | Wt::WStringStream &strm) |
138 | 0 | { |
139 | 0 | strm << |
140 | 0 | """google.maps.event.addListener(map, \"" << signalName << "\", " |
141 | 0 | "" "function(event) {" |
142 | 0 | "" "if (event && event.latLng) {" |
143 | 0 | #ifndef WT_TARGET_JAVA |
144 | 0 | << signal.createCall({"event.latLng.lat() +' '+ event.latLng.lng()"}) |
145 | | #else |
146 | | << signal.createCall("event.latLng.lat() +' '+ event.latLng.lng()") |
147 | | #endif |
148 | 0 | << ";" |
149 | 0 | "" "}" |
150 | 0 | """});"; |
151 | 0 | } |
152 | | |
153 | | JSignal<WGoogleMap::Coordinate>& WGoogleMap::mouseMoved() |
154 | 0 | { |
155 | 0 | if (!mouseMoved_) |
156 | 0 | mouseMoved_ = new JSignal<Coordinate>(this, "mousemove"); |
157 | |
|
158 | 0 | return *mouseMoved_; |
159 | 0 | } |
160 | | |
161 | | void WGoogleMap::render(WFlags<RenderFlag> flags) |
162 | 0 | { |
163 | 0 | if (flags.test(RenderFlag::Full)) { |
164 | 0 | WApplication *app = WApplication::instance(); |
165 | |
|
166 | 0 | std::string initFunction = |
167 | 0 | app->javaScriptClass() + ".init_google_maps_" + id(); |
168 | | |
169 | | // initialize the map |
170 | 0 | WStringStream strm; |
171 | 0 | strm << |
172 | 0 | "{ " << initFunction << " = function() {" |
173 | 0 | """var self = " << jsRef() << ";" |
174 | 0 | """if (!self) { " |
175 | 0 | "" "setTimeout(" << initFunction << ", 0);" |
176 | 0 | "" "return;" |
177 | 0 | "}"; |
178 | |
|
179 | 0 | strm << |
180 | 0 | "var latlng = new google.maps.LatLng(47.01887777, 8.651888);" |
181 | 0 | "var myOptions = {" |
182 | 0 | "" "zoom: 13," |
183 | 0 | "" "center: latlng," |
184 | 0 | "" "mapTypeId: google.maps.MapTypeId.ROADMAP" |
185 | 0 | "};" |
186 | 0 | "var map = new google.maps.Map(self, myOptions);" |
187 | 0 | "map.overlays = [];" |
188 | 0 | "map.infowindows = [];"; |
189 | 0 | setJavaScriptMember(WT_RESIZE_JS, |
190 | 0 | "function(self, w, h) {" |
191 | 0 | """if (w >= 0) " |
192 | 0 | "" "self.style.width=w + 'px';" |
193 | 0 | """if (h >= 0) " |
194 | 0 | "" "self.style.height=h + 'px';" |
195 | 0 | """if (self.map)" |
196 | 0 | """ google.maps.event.trigger(self.map, 'resize');" |
197 | 0 | "}"); |
198 | 0 | strm << "self.map = map;"; |
199 | | |
200 | | // eventhandling |
201 | 0 | streamJSListener(clicked_, "click", strm); |
202 | 0 | streamJSListener(doubleClicked_, "dblclick", strm); |
203 | 0 | if (mouseMoved_) |
204 | 0 | streamJSListener(*mouseMoved_, "mousemove", strm); |
205 | | |
206 | | // additional things |
207 | 0 | for (unsigned int i = 0; i < additions_.size(); i++) |
208 | 0 | strm << additions_[i]; |
209 | |
|
210 | 0 | strm << "setTimeout(function(){ delete " << initFunction << ";}, 0)};" |
211 | 0 | << app->javaScriptClass() << "._p_.loadGoogleMaps('" |
212 | 0 | << '3' |
213 | 0 | << "'," << Wt::WWebWidget::jsStringLiteral(googlekey_) |
214 | 0 | << "," << initFunction << ");" |
215 | 0 | << "}"; // private scope |
216 | |
|
217 | 0 | additions_.clear(); |
218 | |
|
219 | 0 | app->doJavaScript(strm.str(), true); |
220 | 0 | } |
221 | |
|
222 | 0 | WCompositeWidget::render(flags); |
223 | 0 | } |
224 | | |
225 | | void WGoogleMap::clearOverlays() |
226 | 0 | { |
227 | 0 | std::stringstream strm; |
228 | 0 | strm |
229 | 0 | << "var mapLocal = " << jsRef() + ".map, i;\n" |
230 | 0 | << "if (mapLocal.overlays) {\n" |
231 | 0 | << """for (i in mapLocal.overlays) {\n" |
232 | 0 | << """mapLocal.overlays[i].setMap(null);\n" |
233 | 0 | << "}\n" |
234 | 0 | << "mapLocal.overlays.length = 0;\n" |
235 | 0 | << "}\n" |
236 | 0 | << "if (mapLocal.infowindows) {\n" |
237 | 0 | << """for (i in mapLocal.infowindows) {\n" |
238 | 0 | << "" "mapLocal.infowindows[i].close();\n" |
239 | 0 | << "" "}\n" |
240 | 0 | << """mapLocal.infowindows.length = 0;\n" |
241 | 0 | << "}\n"; |
242 | |
|
243 | 0 | doGmJavaScript(strm.str()); |
244 | 0 | } |
245 | | |
246 | | void WGoogleMap::doGmJavaScript(const std::string& jscode) |
247 | 0 | { |
248 | 0 | if (isRendered()) |
249 | 0 | doJavaScript(jscode); |
250 | 0 | else |
251 | 0 | additions_.push_back(jscode); |
252 | 0 | } |
253 | | |
254 | | void WGoogleMap::addMarker(const Coordinate& pos) |
255 | 0 | { |
256 | 0 | std::stringstream strm; |
257 | 0 | strm << "var position = "; |
258 | 0 | write(strm, pos); |
259 | 0 | strm << ";" |
260 | 0 | << "var marker = new google.maps.Marker({" |
261 | 0 | << "position: position," |
262 | 0 | << "map: " << jsRef() << ".map" |
263 | 0 | << "});" |
264 | 0 | << jsRef() << ".map.overlays.push(marker);"; |
265 | |
|
266 | 0 | doGmJavaScript(strm.str()); |
267 | 0 | } |
268 | | |
269 | | void WGoogleMap::addIconMarker(const Coordinate &pos, |
270 | | const std::string& iconURL) |
271 | 0 | { |
272 | 0 | std::stringstream strm; |
273 | |
|
274 | 0 | strm << "var position = "; |
275 | 0 | write(strm, pos); |
276 | 0 | strm << ";" |
277 | 0 | << "var marker = new google.maps.Marker({" |
278 | 0 | << "position: position," |
279 | 0 | << "icon: \"" << iconURL << "\"," |
280 | 0 | << "map: " << jsRef() << ".map" |
281 | 0 | << "});" |
282 | |
|
283 | 0 | << jsRef() << ".map.overlays.push(marker);"; |
284 | |
|
285 | 0 | doGmJavaScript(strm.str()); |
286 | 0 | } |
287 | | |
288 | | void WGoogleMap::addCircle(const Coordinate& center, double radius, |
289 | | const WColor& strokeColor, int strokeWidth, |
290 | | const WColor& fillColor) |
291 | 0 | { |
292 | 0 | std::stringstream strm; |
293 | |
|
294 | 0 | double strokeOpacity = strokeColor.alpha() / 255.0; |
295 | 0 | double fillOpacity = fillColor.alpha() / 255.0; |
296 | |
|
297 | 0 | strm << "var mapLocal = " << jsRef() + ".map;" |
298 | 0 | << "var latLng = "; |
299 | 0 | write(strm, center); |
300 | 0 | strm << ";" |
301 | 0 | << "var circle = new google.maps.Circle( " |
302 | 0 | "{ " |
303 | 0 | " map: mapLocal, " |
304 | 0 | " radius: " << radius << ", " |
305 | 0 | " center: latLng ," |
306 | 0 | " fillOpacity: \"" << fillOpacity << "\"," |
307 | 0 | " fillColor: \"" << fillColor.cssText(false) << "\"," |
308 | 0 | " strokeWeight: " << strokeWidth << "," |
309 | 0 | " strokeColor:\"" << strokeColor.cssText(false) << "\"," |
310 | 0 | " strokeOpacity: " << strokeOpacity << |
311 | 0 | "} " |
312 | 0 | ");" |
313 | 0 | << jsRef() << ".map.overlays.push(circle);"; |
314 | |
|
315 | 0 | doGmJavaScript(strm.str()); |
316 | 0 | } |
317 | | |
318 | | void WGoogleMap::addPolyline(const std::vector<Coordinate>& points, |
319 | | const WColor& color, int width, double opacity) |
320 | 0 | { |
321 | 0 | if (opacity == 1.0) |
322 | 0 | opacity = color.alpha() / 255.0; |
323 | | |
324 | | // opacity has to be between 0.0 and 1.0 |
325 | 0 | opacity = std::max(std::min(opacity, 1.0), 0.0); |
326 | |
|
327 | 0 | std::stringstream strm; |
328 | 0 | strm << "var waypoints = [];"; |
329 | 0 | for (size_t i = 0; i < points.size(); ++i) { |
330 | 0 | strm << "waypoints[" << i << "] = "; |
331 | 0 | write(strm, points[i]); |
332 | 0 | strm << ";"; |
333 | 0 | } |
334 | |
|
335 | 0 | strm << |
336 | 0 | "var poly = new google.maps.Polyline({" |
337 | 0 | "path: waypoints," |
338 | 0 | "strokeColor: \"" << color.cssText(false) << "\"," << |
339 | 0 | "strokeOpacity: " << opacity << "," << |
340 | 0 | "strokeWeight: " << width << |
341 | 0 | "});" << |
342 | 0 | "poly.setMap(" << jsRef() << ".map);" << |
343 | 0 | jsRef() << ".map.overlays.push(poly);"; |
344 | |
|
345 | 0 | doGmJavaScript(strm.str()); |
346 | 0 | } |
347 | | |
348 | | void WGoogleMap::openInfoWindow(const Coordinate& pos, |
349 | | const WString& myHtml) |
350 | 0 | { |
351 | 0 | std::stringstream strm; |
352 | 0 | strm << "var pos = "; |
353 | 0 | write(strm, pos); |
354 | 0 | strm << ";"; |
355 | |
|
356 | 0 | strm << "var infowindow = new google.maps.InfoWindow({" |
357 | 0 | "content: " << WWebWidget::jsStringLiteral(myHtml) << "," << |
358 | 0 | "position: pos" |
359 | 0 | "});" |
360 | 0 | "infowindow.open(" << jsRef() << ".map);" << |
361 | 0 | jsRef() << ".map.infowindows.push(infowindow);"; |
362 | |
|
363 | 0 | doGmJavaScript(strm.str()); |
364 | 0 | } |
365 | | |
366 | | void WGoogleMap::setCenter(const Coordinate& center) |
367 | 0 | { |
368 | 0 | std::stringstream strm; |
369 | 0 | strm << jsRef() << ".map.setCenter("; |
370 | 0 | write(strm, center); |
371 | 0 | strm << ");"; |
372 | 0 | doGmJavaScript(strm.str()); |
373 | 0 | } |
374 | | |
375 | | void WGoogleMap::setCenter(const Coordinate& center, int zoom) |
376 | 0 | { |
377 | 0 | std::stringstream strm; |
378 | 0 | strm << jsRef() << ".map.setCenter("; |
379 | 0 | write(strm, center); |
380 | 0 | strm << "); " |
381 | 0 | << jsRef() << ".map.setZoom(" << zoom << ");"; |
382 | |
|
383 | 0 | doGmJavaScript(strm.str()); |
384 | 0 | } |
385 | | |
386 | | void WGoogleMap::panTo(const Coordinate& center) |
387 | 0 | { |
388 | 0 | std::stringstream strm; |
389 | 0 | strm << jsRef() << ".map.panTo("; |
390 | 0 | write (strm, center); |
391 | 0 | strm << ");"; |
392 | |
|
393 | 0 | doGmJavaScript(strm.str()); |
394 | 0 | } |
395 | | |
396 | | void WGoogleMap::setZoom(int level) |
397 | 0 | { |
398 | 0 | doGmJavaScript(jsRef() + ".map.setZoom(" + std::to_string(level) + ");"); |
399 | 0 | } |
400 | | |
401 | | void WGoogleMap::zoomIn() |
402 | 0 | { |
403 | 0 | std::stringstream strm; |
404 | 0 | strm |
405 | 0 | << "var zoom = " << jsRef() << ".map.getZoom();" |
406 | 0 | << jsRef() << ".map.setZoom(zoom + 1);"; |
407 | 0 | doGmJavaScript(strm.str()); |
408 | 0 | } |
409 | | |
410 | | void WGoogleMap::zoomOut() |
411 | 0 | { |
412 | 0 | std::stringstream strm; |
413 | 0 | strm |
414 | 0 | << "var zoom = " << jsRef() << ".map.getZoom();" |
415 | 0 | << jsRef() << ".map.setZoom(zoom - 1);"; |
416 | 0 | doGmJavaScript(strm.str()); |
417 | 0 | } |
418 | | |
419 | | void WGoogleMap::savePosition() |
420 | 0 | { |
421 | 0 | std::stringstream strm; |
422 | 0 | strm |
423 | 0 | << jsRef() << ".map.savedZoom = " << jsRef() << ".map.getZoom();" |
424 | 0 | << jsRef() << ".map.savedPosition = " << jsRef() << ".map.getCenter();"; |
425 | 0 | doGmJavaScript(strm.str()); |
426 | 0 | } |
427 | | |
428 | | void WGoogleMap::returnToSavedPosition() |
429 | 0 | { |
430 | 0 | std::stringstream strm; |
431 | 0 | strm |
432 | 0 | << jsRef() << ".map.setZoom(" << jsRef() << ".map.savedZoom);" |
433 | 0 | << jsRef() << ".map.setCenter(" << jsRef() << ".map.savedPosition);"; |
434 | 0 | doGmJavaScript(strm.str()); |
435 | 0 | } |
436 | | |
437 | | void WGoogleMap::setMapOption(const std::string &option, |
438 | | const std::string &value) |
439 | 0 | { |
440 | 0 | std::stringstream strm; |
441 | 0 | strm |
442 | 0 | << "var option = {" |
443 | 0 | << option << " :" << value |
444 | 0 | << "};" |
445 | 0 | << jsRef() << ".map.setOptions(option);"; |
446 | |
|
447 | 0 | doGmJavaScript(strm.str()); |
448 | 0 | } |
449 | | |
450 | | void WGoogleMap::enableDragging() |
451 | 0 | { |
452 | 0 | setMapOption("draggable", "true"); |
453 | 0 | } |
454 | | |
455 | | void WGoogleMap::disableDragging() |
456 | 0 | { |
457 | 0 | setMapOption("draggable", "false"); |
458 | 0 | } |
459 | | |
460 | | void WGoogleMap::enableDoubleClickZoom() |
461 | 0 | { |
462 | 0 | setMapOption("disableDoubleClickZoom", "false"); |
463 | 0 | } |
464 | | |
465 | | void WGoogleMap::disableDoubleClickZoom() |
466 | 0 | { |
467 | 0 | setMapOption("disableDoubleClickZoom", "true"); |
468 | 0 | } |
469 | | |
470 | | void WGoogleMap::enableGoogleBar() |
471 | 0 | { |
472 | 0 | throw std::logic_error("WGoogleMap::enableGoogleBar is not supported " |
473 | 0 | "in the Google Maps API v3."); |
474 | 0 | } |
475 | | |
476 | | void WGoogleMap::disableGoogleBar() |
477 | 0 | { |
478 | 0 | throw std::logic_error("WGoogleMap::disableGoogleBar is not supported " |
479 | 0 | "in the Google Maps API v3."); |
480 | 0 | } |
481 | | |
482 | | void WGoogleMap::enableScrollWheelZoom() |
483 | 0 | { |
484 | 0 | setMapOption("scrollwheel", "true"); |
485 | 0 | } |
486 | | |
487 | | void WGoogleMap::disableScrollWheelZoom() |
488 | 0 | { |
489 | 0 | setMapOption("scrollwheel", "false"); |
490 | 0 | } |
491 | | |
492 | | #ifndef WT_TARGET_JAVA |
493 | | void WGoogleMap::zoomWindow(const std::pair<Coordinate, Coordinate>& bbox) |
494 | 0 | { |
495 | 0 | zoomWindow(bbox.first, bbox.second); |
496 | 0 | } |
497 | | #endif |
498 | | |
499 | | void WGoogleMap::zoomWindow(const Coordinate& topLeft, |
500 | | const Coordinate& rightBottom) |
501 | 0 | { |
502 | 0 | const Coordinate center |
503 | 0 | ((topLeft.latitude() + rightBottom.latitude()) / 2.0, |
504 | 0 | (topLeft.longitude() + rightBottom.longitude()) / 2.0); |
505 | |
|
506 | 0 | Coordinate topLeftC = |
507 | 0 | Coordinate(std::min(topLeft.latitude(), rightBottom.latitude()), |
508 | 0 | std::min(topLeft.longitude(), rightBottom.longitude())); |
509 | 0 | Coordinate rightBottomC = |
510 | 0 | Coordinate(std::max(topLeft.latitude(), rightBottom.latitude()), |
511 | 0 | std::max(topLeft.longitude(), rightBottom.longitude())); |
512 | 0 | std::stringstream strm; |
513 | 0 | strm << "var bbox = new google.maps.LatLngBounds("; |
514 | 0 | write(strm, topLeftC); |
515 | 0 | strm << ", "; |
516 | 0 | write(strm, rightBottomC); |
517 | 0 | strm << ");"; |
518 | |
|
519 | 0 | strm |
520 | 0 | << jsRef() << ".map.fitBounds(bbox);"; |
521 | |
|
522 | 0 | doGmJavaScript(strm.str()); |
523 | 0 | } |
524 | | |
525 | | void WGoogleMap::setMapTypeControl(MapTypeControl type) |
526 | 0 | { |
527 | 0 | std::stringstream strm; |
528 | |
|
529 | 0 | std::string control; |
530 | 0 | switch (type) { |
531 | 0 | case MapTypeControl::Default: |
532 | 0 | control = "DEFAULT"; |
533 | 0 | break; |
534 | 0 | case MapTypeControl::Menu: |
535 | 0 | control = "DROPDOWN_MENU"; |
536 | 0 | break; |
537 | 0 | case MapTypeControl::HorizontalBar: |
538 | 0 | control = "HORIZONTAL_BAR"; |
539 | 0 | break; |
540 | 0 | case MapTypeControl::Hierarchical: |
541 | 0 | throw std::logic_error("WGoogleMap::setMapTypeControl: " |
542 | 0 | "HierarchicalControl is not supported when using " |
543 | 0 | "Google Maps API v3."); |
544 | 0 | default: |
545 | 0 | control = ""; |
546 | 0 | } |
547 | | |
548 | 0 | strm |
549 | 0 | << "var options = {" |
550 | 0 | << """disableDefaultUI: " << (control == "" ? "true" : "false") << "," |
551 | 0 | << "" "mapTypeControlOptions: {"; |
552 | |
|
553 | 0 | if (control != "") |
554 | 0 | strm << "style: google.maps.MapTypeControlStyle." << control; |
555 | |
|
556 | 0 | strm |
557 | 0 | << """}" |
558 | 0 | << "};" |
559 | 0 | << jsRef() << ".map.setOptions(options);"; |
560 | |
|
561 | 0 | doGmJavaScript(strm.str()); |
562 | 0 | } |
563 | | |
564 | | } |