fix
[roojs1] / Roo / bootstrap / LocationPicker.js
1 /*
2  * - LGPL
3  *
4  * Location Picker
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.LocationPicker
10  * @extends Roo.bootstrap.Component
11  * Bootstrap LocationPicker class
12  * @cfg {Number} latitude Position when init default 0
13  * @cfg {Number} longitude Position when init default 0
14  * @cfg {Number} zoom default 15
15  * @cfg {String} mapTypeId default google.maps.MapTypeId.ROADMAP
16  * @cfg {Boolean} mapTypeControl default false
17  * @cfg {Boolean} disableDoubleClickZoom default false
18  * @cfg {Boolean} scrollwheel default true
19  * @cfg {Boolean} streetViewControl default false
20  * @cfg {Number} radius default 0
21  * @cfg {String} locationName
22  * @cfg {Boolean} draggable default true
23  * @cfg {Boolean} enableAutocomplete default false
24  * @cfg {Boolean} enableReverseGeocode default true
25  * @cfg {String} markerTitle
26  * 
27  * @constructor
28  * Create a new LocationPicker
29  * @param {Object} config The config object
30  */
31
32
33 Roo.bootstrap.LocationPicker = function(config){
34     
35     Roo.bootstrap.LocationPicker.superclass.constructor.call(this, config);
36     
37     this.addEvents({
38         /**
39          * @event initial
40          * Fires when the picker initialized.
41          * @param {Roo.bootstrap.LocationPicker} this
42          * @param {Google Location} location
43          */
44         initial : true,
45         /**
46          * @event positionchanged
47          * Fires when the picker position changed.
48          * @param {Roo.bootstrap.LocationPicker} this
49          * @param {Google Location} location
50          */
51         positionchanged : true,
52         /**
53          * @event resize
54          * Fires when the map resize.
55          * @param {Roo.bootstrap.LocationPicker} this
56          */
57         resize : true,
58         /**
59          * @event show
60          * Fires when the map show.
61          * @param {Roo.bootstrap.LocationPicker} this
62          */
63         show : true,
64         /**
65          * @event hide
66          * Fires when the map hide.
67          * @param {Roo.bootstrap.LocationPicker} this
68          */
69         hide : true,
70         /**
71          * @event mapClick
72          * Fires when click the map.
73          * @param {Roo.bootstrap.LocationPicker} this
74          * @param {Map event} e
75          */
76         mapClick : true,
77         /**
78          * @event mapRightClick
79          * Fires when right click the map.
80          * @param {Roo.bootstrap.LocationPicker} this
81          * @param {Map event} e
82          */
83         mapRightClick : true,
84         /**
85          * @event markerClick
86          * Fires when click the marker.
87          * @param {Roo.bootstrap.LocationPicker} this
88          * @param {Map event} e
89          */
90         markerClick : true,
91         /**
92          * @event markerRightClick
93          * Fires when right click the marker.
94          * @param {Roo.bootstrap.LocationPicker} this
95          * @param {Map event} e
96          */
97         markerRightClick : true,
98         /**
99          * @event OverlayViewDraw
100          * Fires when OverlayView Draw
101          * @param {Roo.bootstrap.LocationPicker} this
102          */
103         OverlayViewDraw : true,
104         /**
105          * @event OverlayViewOnAdd
106          * Fires when OverlayView Draw
107          * @param {Roo.bootstrap.LocationPicker} this
108          */
109         OverlayViewOnAdd : true,
110         /**
111          * @event OverlayViewOnRemove
112          * Fires when OverlayView Draw
113          * @param {Roo.bootstrap.LocationPicker} this
114          */
115         OverlayViewOnRemove : true,
116         /**
117          * @event OverlayViewShow
118          * Fires when OverlayView Draw
119          * @param {Roo.bootstrap.LocationPicker} this
120          * @param {Pixel} cpx
121          */
122         OverlayViewShow : true,
123         /**
124          * @event OverlayViewHide
125          * Fires when OverlayView Draw
126          * @param {Roo.bootstrap.LocationPicker} this
127          */
128         OverlayViewHide : true
129     });
130         
131 };
132
133 Roo.extend(Roo.bootstrap.LocationPicker, Roo.bootstrap.Component,  {
134     
135     gMapContext: false,
136     
137     latitude: 0,
138     longitude: 0,
139     zoom: 15,
140     mapTypeId: false,
141     mapTypeControl: false,
142     disableDoubleClickZoom: false,
143     scrollwheel: true,
144     streetViewControl: false,
145     radius: 0,
146     locationName: '',
147     draggable: true,
148     enableAutocomplete: false,
149     enableReverseGeocode: true,
150     markerTitle: '',
151     
152     getAutoCreate: function()
153     {
154
155         var cfg = {
156             tag: 'div',
157             cls: 'roo-location-picker'
158         };
159         
160         return cfg
161     },
162     
163     initEvents: function(ct, position)
164     {       
165         if(!this.el.getWidth() || this.isApplied()){
166             return;
167         }
168         
169         this.el.setVisibilityMode(Roo.Element.DISPLAY);
170         
171         this.initial();
172     },
173     
174     initial: function()
175     {
176         if(!this.mapTypeId){
177             this.mapTypeId = google.maps.MapTypeId.ROADMAP;
178         }
179         
180         this.gMapContext = this.GMapContext();
181         
182         this.initOverlayView();
183         
184         this.OverlayView = new Roo.bootstrap.LocationPicker.OverlayView(this.gMapContext.map);
185         
186         var _this = this;
187                 
188         google.maps.event.addListener(this.gMapContext.marker, "dragend", function(event) {
189             _this.setPosition(_this.gMapContext.marker.position);
190         });
191         
192         google.maps.event.addListener(this.gMapContext.map, 'click', function(event){
193             _this.fireEvent('mapClick', this, event);
194             
195         });
196
197         google.maps.event.addListener(this.gMapContext.map, 'rightclick', function(event){
198             _this.fireEvent('mapRightClick', this, event);
199             
200         });
201         
202         google.maps.event.addListener(this.gMapContext.marker, 'click', function(event){
203             _this.fireEvent('markerClick', this, event);
204             
205         });
206
207         google.maps.event.addListener(this.gMapContext.marker, 'rightclick', function(event){
208             _this.fireEvent('markerRightClick', this, event);
209             
210         });
211         
212         this.setPosition(this.gMapContext.location);
213         
214         this.fireEvent('initial', this, this.gMapContext.location);
215     },
216     
217     initOverlayView: function()
218     {
219         var _this = this;
220         
221         Roo.bootstrap.LocationPicker.OverlayView.prototype = Roo.apply(new google.maps.OverlayView(), {
222             
223             draw: function()
224             {
225                 _this.fireEvent('OverlayViewDraw', _this);
226             },
227             
228             onAdd: function()
229             {
230                 _this.fireEvent('OverlayViewOnAdd', _this);
231             },
232             
233             onRemove: function()
234             {
235                 _this.fireEvent('OverlayViewOnRemove', _this);
236             },
237             
238             show: function(cpx)
239             {
240                 _this.fireEvent('OverlayViewShow', _this, cpx);
241             },
242             
243             hide: function()
244             {
245                 _this.fireEvent('OverlayViewHide', _this);
246             }
247             
248         });
249     },
250     
251     fromLatLngToContainerPixel: function(event)
252     {
253         return this.OverlayView.getProjection().fromLatLngToContainerPixel(event.latLng);
254     },
255     
256     isApplied: function() 
257     {
258         return this.getGmapContext() == false ? false : true;
259     },
260     
261     getGmapContext: function() 
262     {
263         return this.gMapContext
264     },
265     
266     GMapContext: function() 
267     {
268         var position = new google.maps.LatLng(this.latitude, this.longitude);
269         
270         var _map = new google.maps.Map(this.el.dom, {
271             center: position,
272             zoom: this.zoom,
273             mapTypeId: this.mapTypeId,
274             mapTypeControl: this.mapTypeControl,
275             disableDoubleClickZoom: this.disableDoubleClickZoom,
276             scrollwheel: this.scrollwheel,
277             streetViewControl: this.streetViewControl,
278             locationName: this.locationName,
279             draggable: this.draggable,
280             enableAutocomplete: this.enableAutocomplete,
281             enableReverseGeocode: this.enableReverseGeocode
282         });
283         
284         var _marker = new google.maps.Marker({
285             position: position,
286             map: _map,
287             title: this.markerTitle,
288             draggable: this.draggable
289         });
290         
291         return {
292             map: _map,
293             marker: _marker,
294             circle: null,
295             location: position,
296             radius: this.radius,
297             locationName: this.locationName,
298             addressComponents: {
299                 formatted_address: null,
300                 addressLine1: null,
301                 addressLine2: null,
302                 streetName: null,
303                 streetNumber: null,
304                 city: null,
305                 district: null,
306                 state: null,
307                 stateOrProvince: null
308             },
309             settings: this,
310             domContainer: this.el.dom,
311             geodecoder: new google.maps.Geocoder()
312         };
313     },
314     
315     drawCircle: function(center, radius, options) 
316     {
317         if (this.gMapContext.circle != null) {
318             this.gMapContext.circle.setMap(null);
319         }
320         if (radius > 0) {
321             radius *= 1;
322             options = Roo.apply({}, options, {
323                 strokeColor: "#0000FF",
324                 strokeOpacity: .35,
325                 strokeWeight: 2,
326                 fillColor: "#0000FF",
327                 fillOpacity: .2
328             });
329             
330             options.map = this.gMapContext.map;
331             options.radius = radius;
332             options.center = center;
333             this.gMapContext.circle = new google.maps.Circle(options);
334             return this.gMapContext.circle;
335         }
336         
337         return null;
338     },
339     
340     setPosition: function(location) 
341     {
342         this.gMapContext.location = location;
343         this.gMapContext.marker.setPosition(location);
344         this.gMapContext.map.panTo(location);
345         this.drawCircle(location, this.gMapContext.radius, {});
346         
347         var _this = this;
348         
349         if (this.gMapContext.settings.enableReverseGeocode) {
350             this.gMapContext.geodecoder.geocode({
351                 latLng: this.gMapContext.location
352             }, function(results, status) {
353                 
354                 if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
355                     _this.gMapContext.locationName = results[0].formatted_address;
356                     _this.gMapContext.addressComponents = _this.address_component_from_google_geocode(results[0].address_components);
357                     
358                     _this.fireEvent('positionchanged', this, location);
359                 }
360             });
361             
362             return;
363         }
364         
365         this.fireEvent('positionchanged', this, location);
366     },
367     
368     resize: function()
369     {
370         google.maps.event.trigger(this.gMapContext.map, "resize");
371         
372         this.gMapContext.map.setCenter(this.gMapContext.marker.position);
373         
374         this.fireEvent('resize', this);
375     },
376     
377     setPositionByLatLng: function(latitude, longitude)
378     {
379         this.setPosition(new google.maps.LatLng(latitude, longitude));
380     },
381     
382     getCurrentPosition: function() 
383     {
384         return {
385             latitude: this.gMapContext.location.lat(),
386             longitude: this.gMapContext.location.lng()
387         };
388     },
389     
390     getAddressName: function() 
391     {
392         return this.gMapContext.locationName;
393     },
394     
395     getAddressComponents: function() 
396     {
397         return this.gMapContext.addressComponents;
398     },
399     
400     address_component_from_google_geocode: function(address_components) 
401     {
402         var result = {};
403         
404         for (var i = 0; i < address_components.length; i++) {
405             var component = address_components[i];
406             if (component.types.indexOf("postal_code") >= 0) {
407                 result.postalCode = component.short_name;
408             } else if (component.types.indexOf("street_number") >= 0) {
409                 result.streetNumber = component.short_name;
410             } else if (component.types.indexOf("route") >= 0) {
411                 result.streetName = component.short_name;
412             } else if (component.types.indexOf("neighborhood") >= 0) {
413                 result.city = component.short_name;
414             } else if (component.types.indexOf("locality") >= 0) {
415                 result.city = component.short_name;
416             } else if (component.types.indexOf("sublocality") >= 0) {
417                 result.district = component.short_name;
418             } else if (component.types.indexOf("administrative_area_level_1") >= 0) {
419                 result.stateOrProvince = component.short_name;
420             } else if (component.types.indexOf("country") >= 0) {
421                 result.country = component.short_name;
422             }
423         }
424         
425         result.addressLine1 = [ result.streetNumber, result.streetName ].join(" ").trim();
426         result.addressLine2 = "";
427         return result;
428     },
429     
430     setZoomLevel: function(zoom)
431     {
432         this.gMapContext.map.setZoom(zoom);
433     },
434     
435     show: function()
436     {
437         if(!this.el){
438             return;
439         }
440         
441         this.el.show();
442         
443         this.resize();
444         
445         this.fireEvent('show', this);
446     },
447     
448     hide: function()
449     {
450         if(!this.el){
451             return;
452         }
453         
454         this.el.hide();
455         
456         this.fireEvent('hide', this);
457     }
458     
459 });
460
461 Roo.apply(Roo.bootstrap.LocationPicker, {
462     
463     OverlayView : function(map, options)
464     {
465         options = options || {};
466         
467         this.setMap(map);
468     }
469     
470     
471 });