jquery-gmap3-rails 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/jquery/gmap3/rails/version.rb +2 -2
- data/vendor/assets/javascripts/gmap3.js +2511 -2222
- data/vendor/assets/javascripts/gmap3.min.js +10 -39
- metadata +19 -8
@@ -1,2222 +1,2511 @@
|
|
1
|
-
|
2
|
-
* GMAP3 Plugin for JQuery
|
3
|
-
* Version :
|
4
|
-
* Date :
|
5
|
-
* Licence : GPL v3 : http://www.gnu.org/licenses/gpl.html
|
6
|
-
* Author : DEMONTE Jean-Baptiste
|
7
|
-
* Contact : jbdemonte@gmail.com
|
8
|
-
* Web site : http://gmap3.net
|
9
|
-
*
|
10
|
-
* Copyright (c) 2010-
|
11
|
-
* All rights reserved.
|
12
|
-
*
|
13
|
-
* Redistribution and use in source and binary forms, with or without
|
14
|
-
* modification, are permitted provided that the following conditions are met:
|
15
|
-
*
|
16
|
-
* - Redistributions of source code must retain the above copyright
|
17
|
-
* notice, this list of conditions and the following disclaimer.
|
18
|
-
* - Redistributions in binary form must reproduce the above
|
19
|
-
* copyright notice, this list of conditions and the following
|
20
|
-
* disclaimer in the documentation and/or other materials provided
|
21
|
-
* with the distribution.
|
22
|
-
* - Neither the name of the author nor the names of its contributors
|
23
|
-
* may be used to endorse or promote products derived from this
|
24
|
-
* software without specific prior written permission.
|
25
|
-
*
|
26
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
27
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
28
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
30
|
-
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
31
|
-
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
32
|
-
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
33
|
-
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
34
|
-
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
-
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
36
|
-
* POSSIBILITY OF SUCH DAMAGE.
|
37
|
-
*/
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
}
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
if (
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
}
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
this.
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
}
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
}
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
return
|
595
|
-
}
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
}
|
646
|
-
}
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
}
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
}
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
//
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
)
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
if (
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
*
|
1201
|
-
**/
|
1202
|
-
this.
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
}
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
}
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
}
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
}
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
}
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
if (
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
}
|
1665
|
-
}
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
}
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
if (!
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
}
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
}
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
var
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
);
|
2003
|
-
} else {
|
2004
|
-
|
2005
|
-
}
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
}
|
2020
|
-
}
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2049
|
-
}
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
2147
|
-
}
|
2148
|
-
|
2149
|
-
|
2150
|
-
if (
|
2151
|
-
|
2152
|
-
|
2153
|
-
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2203
|
-
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
1
|
+
/*!
|
2
|
+
* GMAP3 Plugin for JQuery
|
3
|
+
* Version : 5.1.1
|
4
|
+
* Date : 2013-05-25
|
5
|
+
* Licence : GPL v3 : http://www.gnu.org/licenses/gpl.html
|
6
|
+
* Author : DEMONTE Jean-Baptiste
|
7
|
+
* Contact : jbdemonte@gmail.com
|
8
|
+
* Web site : http://gmap3.net
|
9
|
+
*
|
10
|
+
* Copyright (c) 2010-2012 Jean-Baptiste DEMONTE
|
11
|
+
* All rights reserved.
|
12
|
+
*
|
13
|
+
* Redistribution and use in source and binary forms, with or without
|
14
|
+
* modification, are permitted provided that the following conditions are met:
|
15
|
+
*
|
16
|
+
* - Redistributions of source code must retain the above copyright
|
17
|
+
* notice, this list of conditions and the following disclaimer.
|
18
|
+
* - Redistributions in binary form must reproduce the above
|
19
|
+
* copyright notice, this list of conditions and the following
|
20
|
+
* disclaimer in the documentation and/or other materials provided
|
21
|
+
* with the distribution.
|
22
|
+
* - Neither the name of the author nor the names of its contributors
|
23
|
+
* may be used to endorse or promote products derived from this
|
24
|
+
* software without specific prior written permission.
|
25
|
+
*
|
26
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
27
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
28
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
30
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
31
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
32
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
33
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
34
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
36
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
*/
|
38
|
+
;(function ($, undef) {
|
39
|
+
|
40
|
+
/***************************************************************************/
|
41
|
+
/* GMAP3 DEFAULTS */
|
42
|
+
/***************************************************************************/
|
43
|
+
// defaults are defined later in the code to pass the rails asset pipeline and
|
44
|
+
//jasmine while google library is not loaded
|
45
|
+
var defaults, gId = 0;
|
46
|
+
|
47
|
+
function initDefaults() {
|
48
|
+
if (!defaults) {
|
49
|
+
defaults = {
|
50
|
+
verbose: false,
|
51
|
+
queryLimit: {
|
52
|
+
attempt: 5,
|
53
|
+
delay: 250, // setTimeout(..., delay + random);
|
54
|
+
random: 250
|
55
|
+
},
|
56
|
+
classes: {
|
57
|
+
Map : google.maps.Map,
|
58
|
+
Marker : google.maps.Marker,
|
59
|
+
InfoWindow : google.maps.InfoWindow,
|
60
|
+
Circle : google.maps.Circle,
|
61
|
+
Rectangle : google.maps.Rectangle,
|
62
|
+
OverlayView : google.maps.OverlayView,
|
63
|
+
StreetViewPanorama: google.maps.StreetViewPanorama,
|
64
|
+
KmlLayer : google.maps.KmlLayer,
|
65
|
+
TrafficLayer : google.maps.TrafficLayer,
|
66
|
+
BicyclingLayer : google.maps.BicyclingLayer,
|
67
|
+
GroundOverlay : google.maps.GroundOverlay,
|
68
|
+
StyledMapType : google.maps.StyledMapType,
|
69
|
+
ImageMapType : google.maps.ImageMapType
|
70
|
+
},
|
71
|
+
map: {
|
72
|
+
mapTypeId : google.maps.MapTypeId.ROADMAP,
|
73
|
+
center: [46.578498, 2.457275],
|
74
|
+
zoom: 2
|
75
|
+
},
|
76
|
+
overlay: {
|
77
|
+
pane: "floatPane",
|
78
|
+
content: "",
|
79
|
+
offset: {
|
80
|
+
x: 0,
|
81
|
+
y: 0
|
82
|
+
}
|
83
|
+
},
|
84
|
+
geoloc: {
|
85
|
+
getCurrentPosition: {
|
86
|
+
maximumAge: 60000,
|
87
|
+
timeout: 5000
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
function globalId(id, simulate){
|
95
|
+
return id !== undef ? id : "gmap3_" + (simulate ? gId + 1 : ++gId);
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Return true if current version of Google Maps is equal or above to these in parameter
|
100
|
+
* @param version {string} Minimal version required
|
101
|
+
* @return {Boolean}
|
102
|
+
*/
|
103
|
+
function googleVersionMin(version) {
|
104
|
+
var toInt = function(v){return parseInt(v, 10);},
|
105
|
+
// extract the google map version
|
106
|
+
gmVersion = google.maps.version.split(".").map(toInt),
|
107
|
+
i;
|
108
|
+
version = version.split(".").map(toInt);
|
109
|
+
for(i = 0; i < version.length; i++) {
|
110
|
+
if (gmVersion.hasOwnProperty(i)) {
|
111
|
+
if (gmVersion[i] < version[i]) {
|
112
|
+
return false;
|
113
|
+
}
|
114
|
+
} else {
|
115
|
+
return false;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
return true;
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* attach events from a container to a sender
|
123
|
+
* todo[
|
124
|
+
* events => { eventName => function, }
|
125
|
+
* onces => { eventName => function, }
|
126
|
+
* data => mixed data
|
127
|
+
* ]
|
128
|
+
**/
|
129
|
+
function attachEvents($container, args, sender, id, senders){
|
130
|
+
if (args.todo.events || args.todo.onces) {
|
131
|
+
var context = {
|
132
|
+
id: id,
|
133
|
+
data: args.todo.data,
|
134
|
+
tag: args.todo.tag
|
135
|
+
};
|
136
|
+
if (args.todo.events){
|
137
|
+
$.each(args.todo.events, function(name, f){
|
138
|
+
var that = $container, fn = f;
|
139
|
+
if ($.isArray(f)) {
|
140
|
+
that = f[0];
|
141
|
+
fn = f[1]
|
142
|
+
}
|
143
|
+
google.maps.event.addListener(sender, name, function(event) {
|
144
|
+
fn.apply(that, [senders ? senders : sender, event, context]);
|
145
|
+
});
|
146
|
+
});
|
147
|
+
}
|
148
|
+
if (args.todo.onces){
|
149
|
+
$.each(args.todo.onces, function(name, f){
|
150
|
+
var that = $container, fn = f;
|
151
|
+
if ($.isArray(f)) {
|
152
|
+
that = f[0];
|
153
|
+
fn = f[1]
|
154
|
+
}
|
155
|
+
google.maps.event.addListenerOnce(sender, name, function(event) {
|
156
|
+
fn.apply(that, [senders ? senders : sender, event, context]);
|
157
|
+
});
|
158
|
+
});
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
/***************************************************************************/
|
164
|
+
/* STACK */
|
165
|
+
/***************************************************************************/
|
166
|
+
|
167
|
+
function Stack (){
|
168
|
+
var st = [];
|
169
|
+
this.empty = function (){
|
170
|
+
return !st.length;
|
171
|
+
};
|
172
|
+
this.add = function(v){
|
173
|
+
st.push(v);
|
174
|
+
};
|
175
|
+
this.get = function (){
|
176
|
+
return st.length ? st[0] : false;
|
177
|
+
};
|
178
|
+
this.ack = function (){
|
179
|
+
st.shift();
|
180
|
+
};
|
181
|
+
}
|
182
|
+
|
183
|
+
/***************************************************************************/
|
184
|
+
/* TASK */
|
185
|
+
/***************************************************************************/
|
186
|
+
|
187
|
+
function Task(ctx, onEnd, todo){
|
188
|
+
var session = {},
|
189
|
+
that = this,
|
190
|
+
current,
|
191
|
+
resolve = {
|
192
|
+
latLng:{ // function => bool (=> address = latLng)
|
193
|
+
map:false,
|
194
|
+
marker:false,
|
195
|
+
infowindow:false,
|
196
|
+
circle:false,
|
197
|
+
overlay: false,
|
198
|
+
getlatlng: false,
|
199
|
+
getmaxzoom: false,
|
200
|
+
getelevation: false,
|
201
|
+
streetviewpanorama: false,
|
202
|
+
getaddress: true
|
203
|
+
},
|
204
|
+
geoloc:{
|
205
|
+
getgeoloc: true
|
206
|
+
}
|
207
|
+
};
|
208
|
+
|
209
|
+
if (typeof todo === "string"){
|
210
|
+
todo = unify(todo);
|
211
|
+
}
|
212
|
+
|
213
|
+
function unify(todo){
|
214
|
+
var result = {};
|
215
|
+
result[todo] = {};
|
216
|
+
return result;
|
217
|
+
}
|
218
|
+
|
219
|
+
function next(){
|
220
|
+
var k;
|
221
|
+
for(k in todo){
|
222
|
+
if (k in session){ // already run
|
223
|
+
continue;
|
224
|
+
}
|
225
|
+
return k;
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
this.run = function (){
|
230
|
+
var k, opts;
|
231
|
+
while(k = next()){
|
232
|
+
if (typeof ctx[k] === "function"){
|
233
|
+
current = k;
|
234
|
+
opts = $.extend(true, {}, defaults[k] || {}, todo[k].options || {});
|
235
|
+
if (k in resolve.latLng){
|
236
|
+
if (todo[k].values){
|
237
|
+
resolveAllLatLng(todo[k].values, ctx, ctx[k], {todo:todo[k], opts:opts, session:session});
|
238
|
+
} else {
|
239
|
+
resolveLatLng(ctx, ctx[k], resolve.latLng[k], {todo:todo[k], opts:opts, session:session});
|
240
|
+
}
|
241
|
+
} else if (k in resolve.geoloc){
|
242
|
+
geoloc(ctx, ctx[k], {todo:todo[k], opts:opts, session:session});
|
243
|
+
} else {
|
244
|
+
ctx[k].apply(ctx, [{todo:todo[k], opts:opts, session:session}]);
|
245
|
+
}
|
246
|
+
return; // wait until ack
|
247
|
+
} else {
|
248
|
+
session[k] = null;
|
249
|
+
}
|
250
|
+
}
|
251
|
+
onEnd.apply(ctx, [todo, session]);
|
252
|
+
};
|
253
|
+
|
254
|
+
this.ack = function(result){
|
255
|
+
session[current] = result;
|
256
|
+
that.run.apply(that, []);
|
257
|
+
};
|
258
|
+
}
|
259
|
+
|
260
|
+
function getKeys(obj){
|
261
|
+
var k, keys = [];
|
262
|
+
for(k in obj){
|
263
|
+
keys.push(k);
|
264
|
+
}
|
265
|
+
return keys;
|
266
|
+
}
|
267
|
+
|
268
|
+
function tuple(args, value){
|
269
|
+
var todo = {};
|
270
|
+
|
271
|
+
// "copy" the common data
|
272
|
+
if (args.todo){
|
273
|
+
for(var k in args.todo){
|
274
|
+
if ((k !== "options") && (k !== "values")){
|
275
|
+
todo[k] = args.todo[k];
|
276
|
+
}
|
277
|
+
}
|
278
|
+
}
|
279
|
+
// "copy" some specific keys from value first else args.todo
|
280
|
+
var i, keys = ["data", "tag", "id", "events", "onces"];
|
281
|
+
for(i=0; i<keys.length; i++){
|
282
|
+
copyKey(todo, keys[i], value, args.todo);
|
283
|
+
}
|
284
|
+
|
285
|
+
// create an extended options
|
286
|
+
todo.options = $.extend({}, args.opts || {}, value.options || {});
|
287
|
+
|
288
|
+
return todo;
|
289
|
+
}
|
290
|
+
|
291
|
+
/**
|
292
|
+
* copy a key content
|
293
|
+
**/
|
294
|
+
function copyKey(target, key){
|
295
|
+
for(var i=2; i<arguments.length; i++){
|
296
|
+
if (key in arguments[i]){
|
297
|
+
target[key] = arguments[i][key];
|
298
|
+
return;
|
299
|
+
}
|
300
|
+
}
|
301
|
+
}
|
302
|
+
|
303
|
+
/***************************************************************************/
|
304
|
+
/* GEOCODERCACHE */
|
305
|
+
/***************************************************************************/
|
306
|
+
|
307
|
+
function GeocoderCache(){
|
308
|
+
var cache = [];
|
309
|
+
|
310
|
+
this.get = function(request){
|
311
|
+
if (cache.length){
|
312
|
+
var i, j, k, item, eq,
|
313
|
+
keys = getKeys(request);
|
314
|
+
for(i=0; i<cache.length; i++){
|
315
|
+
item = cache[i];
|
316
|
+
eq = keys.length == item.keys.length;
|
317
|
+
for(j=0; (j<keys.length) && eq; j++){
|
318
|
+
k = keys[j];
|
319
|
+
eq = k in item.request;
|
320
|
+
if (eq){
|
321
|
+
if ((typeof request[k] === "object") && ("equals" in request[k]) && (typeof request[k] === "function")){
|
322
|
+
eq = request[k].equals(item.request[k]);
|
323
|
+
} else{
|
324
|
+
eq = request[k] === item.request[k];
|
325
|
+
}
|
326
|
+
}
|
327
|
+
}
|
328
|
+
if (eq){
|
329
|
+
return item.results;
|
330
|
+
}
|
331
|
+
}
|
332
|
+
}
|
333
|
+
};
|
334
|
+
|
335
|
+
this.store = function(request, results){
|
336
|
+
cache.push({request:request, keys:getKeys(request), results:results});
|
337
|
+
};
|
338
|
+
}
|
339
|
+
|
340
|
+
/***************************************************************************/
|
341
|
+
/* OVERLAYVIEW */
|
342
|
+
/***************************************************************************/
|
343
|
+
function OverlayView(map, opts, latLng, $div) {
|
344
|
+
var that = this, listeners = [];
|
345
|
+
|
346
|
+
defaults.classes.OverlayView.call(this);
|
347
|
+
this.setMap(map);
|
348
|
+
|
349
|
+
this.onAdd = function() {
|
350
|
+
var panes = this.getPanes();
|
351
|
+
if (opts.pane in panes) {
|
352
|
+
$(panes[opts.pane]).append($div);
|
353
|
+
}
|
354
|
+
$.each("dblclick click mouseover mousemove mouseout mouseup mousedown".split(" "), function(i, name){
|
355
|
+
listeners.push(
|
356
|
+
google.maps.event.addDomListener($div[0], name, function(e) {
|
357
|
+
$.Event(e).stopPropagation();
|
358
|
+
google.maps.event.trigger(that, name, [e]);
|
359
|
+
that.draw();
|
360
|
+
})
|
361
|
+
);
|
362
|
+
});
|
363
|
+
listeners.push(
|
364
|
+
google.maps.event.addDomListener($div[0], "contextmenu", function(e) {
|
365
|
+
$.Event(e).stopPropagation();
|
366
|
+
google.maps.event.trigger(that, "rightclick", [e]);
|
367
|
+
that.draw();
|
368
|
+
})
|
369
|
+
);
|
370
|
+
};
|
371
|
+
this.getPosition = function(){
|
372
|
+
return latLng;
|
373
|
+
};
|
374
|
+
this.draw = function() {
|
375
|
+
var ps = this.getProjection().fromLatLngToDivPixel(latLng);
|
376
|
+
$div
|
377
|
+
.css("left", (ps.x+opts.offset.x) + "px")
|
378
|
+
.css("top" , (ps.y+opts.offset.y) + "px");
|
379
|
+
};
|
380
|
+
this.onRemove = function() {
|
381
|
+
for (var i = 0; i < listeners.length; i++) {
|
382
|
+
google.maps.event.removeListener(listeners[i]);
|
383
|
+
}
|
384
|
+
$div.remove();
|
385
|
+
};
|
386
|
+
this.hide = function() {
|
387
|
+
$div.hide();
|
388
|
+
};
|
389
|
+
this.show = function() {
|
390
|
+
$div.show();
|
391
|
+
};
|
392
|
+
this.toggle = function() {
|
393
|
+
if ($div) {
|
394
|
+
if ($div.is(":visible")){
|
395
|
+
this.show();
|
396
|
+
} else {
|
397
|
+
this.hide();
|
398
|
+
}
|
399
|
+
}
|
400
|
+
};
|
401
|
+
this.toggleDOM = function() {
|
402
|
+
if (this.getMap()) {
|
403
|
+
this.setMap(null);
|
404
|
+
} else {
|
405
|
+
this.setMap(map);
|
406
|
+
}
|
407
|
+
};
|
408
|
+
this.getDOMElement = function() {
|
409
|
+
return $div[0];
|
410
|
+
};
|
411
|
+
}
|
412
|
+
|
413
|
+
/***************************************************************************/
|
414
|
+
/* CLUSTERING */
|
415
|
+
/***************************************************************************/
|
416
|
+
|
417
|
+
/**
|
418
|
+
* Usefull to get a projection
|
419
|
+
* => done in a function, to let dead-code analyser works without google library loaded
|
420
|
+
**/
|
421
|
+
function newEmptyOverlay(map, radius){
|
422
|
+
function Overlay(){
|
423
|
+
this.onAdd = function(){};
|
424
|
+
this.onRemove = function(){};
|
425
|
+
this.draw = function(){};
|
426
|
+
return defaults.classes.OverlayView.apply(this, []);
|
427
|
+
}
|
428
|
+
Overlay.prototype = defaults.classes.OverlayView.prototype;
|
429
|
+
var obj = new Overlay();
|
430
|
+
obj.setMap(map);
|
431
|
+
return obj;
|
432
|
+
}
|
433
|
+
|
434
|
+
/**
|
435
|
+
* Class InternalClusterer
|
436
|
+
* This class manage clusters thanks to "todo" objects
|
437
|
+
*
|
438
|
+
* Note:
|
439
|
+
* Individuals marker are created on the fly thanks to the todo objects, they are
|
440
|
+
* first set to null to keep the indexes synchronised with the todo list
|
441
|
+
* This is the "display" function, set by the gmap3 object, which uses theses data
|
442
|
+
* to create markers when clusters are not required
|
443
|
+
* To remove a marker, the objects are deleted and set not null in arrays
|
444
|
+
* markers[key]
|
445
|
+
* = null : marker exist but has not been displayed yet
|
446
|
+
* = false : marker has been removed
|
447
|
+
**/
|
448
|
+
function InternalClusterer($container, map, raw){
|
449
|
+
var updating = false,
|
450
|
+
updated = false,
|
451
|
+
redrawing = false,
|
452
|
+
ready = false,
|
453
|
+
enabled = true,
|
454
|
+
that = this,
|
455
|
+
events = [],
|
456
|
+
store = {}, // combin of index (id1-id2-...) => object
|
457
|
+
ids = {}, // unique id => index
|
458
|
+
idxs = {}, // index => unique id
|
459
|
+
markers = [], // index => marker
|
460
|
+
todos = [], // index => todo or null if removed
|
461
|
+
values = [], // index => value
|
462
|
+
overlay = newEmptyOverlay(map, raw.radius),
|
463
|
+
timer, projection,
|
464
|
+
ffilter, fdisplay, ferror; // callback function
|
465
|
+
|
466
|
+
main();
|
467
|
+
|
468
|
+
function prepareMarker(index) {
|
469
|
+
if (!markers[index]) {
|
470
|
+
delete todos[index].options.map;
|
471
|
+
markers[index] = new defaults.classes.Marker(todos[index].options);
|
472
|
+
attachEvents($container, {todo: todos[index]}, markers[index], todos[index].id);
|
473
|
+
}
|
474
|
+
}
|
475
|
+
|
476
|
+
/**
|
477
|
+
* return a marker by its id, null if not yet displayed and false if no exist or removed
|
478
|
+
**/
|
479
|
+
this.getById = function(id){
|
480
|
+
if (id in ids) {
|
481
|
+
prepareMarker(ids[id]);
|
482
|
+
return markers[ids[id]];
|
483
|
+
}
|
484
|
+
return false;
|
485
|
+
};
|
486
|
+
|
487
|
+
/**
|
488
|
+
* remove one object from the store
|
489
|
+
**/
|
490
|
+
this.rm = function (id) {
|
491
|
+
var index = ids[id];
|
492
|
+
if (markers[index]){ // can be null
|
493
|
+
markers[index].setMap(null);
|
494
|
+
}
|
495
|
+
delete markers[index];
|
496
|
+
markers[index] = false;
|
497
|
+
|
498
|
+
delete todos[index];
|
499
|
+
todos[index] = false;
|
500
|
+
|
501
|
+
delete values[index];
|
502
|
+
values[index] = false;
|
503
|
+
|
504
|
+
delete ids[id];
|
505
|
+
delete idxs[index];
|
506
|
+
updated = true;
|
507
|
+
};
|
508
|
+
|
509
|
+
/**
|
510
|
+
* remove a marker by its id
|
511
|
+
**/
|
512
|
+
this.clearById = function(id){
|
513
|
+
if (id in ids){
|
514
|
+
this.rm(id);
|
515
|
+
return true;
|
516
|
+
}
|
517
|
+
};
|
518
|
+
|
519
|
+
/**
|
520
|
+
* remove objects from the store
|
521
|
+
**/
|
522
|
+
this.clear = function(last, first, tag){
|
523
|
+
var start, stop, step, index, i,
|
524
|
+
list = [],
|
525
|
+
check = ftag(tag);
|
526
|
+
if (last) {
|
527
|
+
start = todos.length - 1;
|
528
|
+
stop = -1;
|
529
|
+
step = -1;
|
530
|
+
} else {
|
531
|
+
start = 0;
|
532
|
+
stop = todos.length;
|
533
|
+
step = 1;
|
534
|
+
}
|
535
|
+
for (index = start; index != stop; index += step) {
|
536
|
+
if (todos[index]) {
|
537
|
+
if (!check || check(todos[index].tag)){
|
538
|
+
list.push(idxs[index]);
|
539
|
+
if (first || last) {
|
540
|
+
break;
|
541
|
+
}
|
542
|
+
}
|
543
|
+
}
|
544
|
+
}
|
545
|
+
for (i = 0; i < list.length; i++) {
|
546
|
+
this.rm(list[i]);
|
547
|
+
}
|
548
|
+
};
|
549
|
+
|
550
|
+
// add a "marker todo" to the cluster
|
551
|
+
this.add = function(todo, value){
|
552
|
+
todo.id = globalId(todo.id);
|
553
|
+
this.clearById(todo.id);
|
554
|
+
ids[todo.id] = markers.length;
|
555
|
+
idxs[markers.length] = todo.id;
|
556
|
+
markers.push(null); // null = marker not yet created / displayed
|
557
|
+
todos.push(todo);
|
558
|
+
values.push(value);
|
559
|
+
updated = true;
|
560
|
+
};
|
561
|
+
|
562
|
+
// add a real marker to the cluster
|
563
|
+
this.addMarker = function(marker, todo){
|
564
|
+
todo = todo || {};
|
565
|
+
todo.id = globalId(todo.id);
|
566
|
+
this.clearById(todo.id);
|
567
|
+
if (!todo.options){
|
568
|
+
todo.options = {};
|
569
|
+
}
|
570
|
+
todo.options.position = marker.getPosition();
|
571
|
+
attachEvents($container, {todo:todo}, marker, todo.id);
|
572
|
+
ids[todo.id] = markers.length;
|
573
|
+
idxs[markers.length] = todo.id;
|
574
|
+
markers.push(marker);
|
575
|
+
todos.push(todo);
|
576
|
+
values.push(todo.data || {});
|
577
|
+
updated = true;
|
578
|
+
};
|
579
|
+
|
580
|
+
// return a "marker todo" by its index
|
581
|
+
this.todo = function(index){
|
582
|
+
return todos[index];
|
583
|
+
};
|
584
|
+
|
585
|
+
// return a "marker value" by its index
|
586
|
+
this.value = function(index){
|
587
|
+
return values[index];
|
588
|
+
};
|
589
|
+
|
590
|
+
// return a marker by its index
|
591
|
+
this.marker = function(index){
|
592
|
+
if (index in markers) {
|
593
|
+
prepareMarker(index);
|
594
|
+
return markers[index];
|
595
|
+
}
|
596
|
+
return false;
|
597
|
+
};
|
598
|
+
|
599
|
+
// return a marker by its index
|
600
|
+
this.markerIsSet = function(index){
|
601
|
+
return Boolean(markers[index]);
|
602
|
+
};
|
603
|
+
|
604
|
+
// store a new marker instead if the default "false"
|
605
|
+
this.setMarker = function(index, marker){
|
606
|
+
markers[index] = marker;
|
607
|
+
};
|
608
|
+
|
609
|
+
// link the visible overlay to the logical data (to hide overlays later)
|
610
|
+
this.store = function(cluster, obj, shadow){
|
611
|
+
store[cluster.ref] = {obj:obj, shadow:shadow};
|
612
|
+
};
|
613
|
+
|
614
|
+
// free all objects
|
615
|
+
this.free = function(){
|
616
|
+
for(var i = 0; i < events.length; i++){
|
617
|
+
google.maps.event.removeListener(events[i]);
|
618
|
+
}
|
619
|
+
events = [];
|
620
|
+
|
621
|
+
$.each(store, function(key){
|
622
|
+
flush(key);
|
623
|
+
});
|
624
|
+
store = {};
|
625
|
+
|
626
|
+
$.each(todos, function(i){
|
627
|
+
todos[i] = null;
|
628
|
+
});
|
629
|
+
todos = [];
|
630
|
+
|
631
|
+
$.each(markers, function(i){
|
632
|
+
if (markers[i]){ // false = removed
|
633
|
+
markers[i].setMap(null);
|
634
|
+
delete markers[i];
|
635
|
+
}
|
636
|
+
});
|
637
|
+
markers = [];
|
638
|
+
|
639
|
+
$.each(values, function(i){
|
640
|
+
delete values[i];
|
641
|
+
});
|
642
|
+
values = [];
|
643
|
+
|
644
|
+
ids = {};
|
645
|
+
idxs = {};
|
646
|
+
};
|
647
|
+
|
648
|
+
// link the display function
|
649
|
+
this.filter = function(f){
|
650
|
+
ffilter = f;
|
651
|
+
redraw();
|
652
|
+
};
|
653
|
+
|
654
|
+
// enable/disable the clustering feature
|
655
|
+
this.enable = function(value){
|
656
|
+
if (enabled != value){
|
657
|
+
enabled = value;
|
658
|
+
redraw();
|
659
|
+
}
|
660
|
+
};
|
661
|
+
|
662
|
+
// link the display function
|
663
|
+
this.display = function(f){
|
664
|
+
fdisplay = f;
|
665
|
+
};
|
666
|
+
|
667
|
+
// link the errorfunction
|
668
|
+
this.error = function(f){
|
669
|
+
ferror = f;
|
670
|
+
};
|
671
|
+
|
672
|
+
// lock the redraw
|
673
|
+
this.beginUpdate = function(){
|
674
|
+
updating = true;
|
675
|
+
};
|
676
|
+
|
677
|
+
// unlock the redraw
|
678
|
+
this.endUpdate = function(){
|
679
|
+
updating = false;
|
680
|
+
if (updated){
|
681
|
+
redraw();
|
682
|
+
}
|
683
|
+
};
|
684
|
+
|
685
|
+
// extends current bounds with internal markers
|
686
|
+
this.autofit = function(bounds){
|
687
|
+
for(var i=0; i<todos.length; i++){
|
688
|
+
if (todos[i]){
|
689
|
+
bounds.extend(todos[i].options.position);
|
690
|
+
}
|
691
|
+
}
|
692
|
+
};
|
693
|
+
|
694
|
+
// bind events
|
695
|
+
function main(){
|
696
|
+
projection = overlay.getProjection();
|
697
|
+
if (!projection){
|
698
|
+
setTimeout(function(){
|
699
|
+
main.apply(that, []);
|
700
|
+
},
|
701
|
+
25);
|
702
|
+
return;
|
703
|
+
}
|
704
|
+
ready = true;
|
705
|
+
events.push(google.maps.event.addListener(map, "zoom_changed", function(){delayRedraw();}));
|
706
|
+
events.push(google.maps.event.addListener(map, "bounds_changed", function(){delayRedraw();}));
|
707
|
+
redraw();
|
708
|
+
}
|
709
|
+
|
710
|
+
// flush overlays
|
711
|
+
function flush(key){
|
712
|
+
if (typeof store[key] === "object"){ // is overlay
|
713
|
+
if (typeof(store[key].obj.setMap) === "function") {
|
714
|
+
store[key].obj.setMap(null);
|
715
|
+
}
|
716
|
+
if (typeof(store[key].obj.remove) === "function") {
|
717
|
+
store[key].obj.remove();
|
718
|
+
}
|
719
|
+
if (typeof(store[key].shadow.remove) === "function") {
|
720
|
+
store[key].obj.remove();
|
721
|
+
}
|
722
|
+
if (typeof(store[key].shadow.setMap) === "function") {
|
723
|
+
store[key].shadow.setMap(null);
|
724
|
+
}
|
725
|
+
delete store[key].obj;
|
726
|
+
delete store[key].shadow;
|
727
|
+
} else if (markers[key]){ // marker not removed
|
728
|
+
markers[key].setMap(null);
|
729
|
+
// don't remove the marker object, it may be displayed later
|
730
|
+
}
|
731
|
+
delete store[key];
|
732
|
+
}
|
733
|
+
|
734
|
+
/**
|
735
|
+
* return the distance between 2 latLng couple into meters
|
736
|
+
* Params :
|
737
|
+
* Lat1, Lng1, Lat2, Lng2
|
738
|
+
* LatLng1, Lat2, Lng2
|
739
|
+
* Lat1, Lng1, LatLng2
|
740
|
+
* LatLng1, LatLng2
|
741
|
+
**/
|
742
|
+
function distanceInMeter(){
|
743
|
+
var lat1, lat2, lng1, lng2, e, f, g, h;
|
744
|
+
if (arguments[0] instanceof google.maps.LatLng){
|
745
|
+
lat1 = arguments[0].lat();
|
746
|
+
lng1 = arguments[0].lng();
|
747
|
+
if (arguments[1] instanceof google.maps.LatLng){
|
748
|
+
lat2 = arguments[1].lat();
|
749
|
+
lng2 = arguments[1].lng();
|
750
|
+
} else {
|
751
|
+
lat2 = arguments[1];
|
752
|
+
lng2 = arguments[2];
|
753
|
+
}
|
754
|
+
} else {
|
755
|
+
lat1 = arguments[0];
|
756
|
+
lng1 = arguments[1];
|
757
|
+
if (arguments[2] instanceof google.maps.LatLng){
|
758
|
+
lat2 = arguments[2].lat();
|
759
|
+
lng2 = arguments[2].lng();
|
760
|
+
} else {
|
761
|
+
lat2 = arguments[2];
|
762
|
+
lng2 = arguments[3];
|
763
|
+
}
|
764
|
+
}
|
765
|
+
e = Math.PI*lat1/180;
|
766
|
+
f = Math.PI*lng1/180;
|
767
|
+
g = Math.PI*lat2/180;
|
768
|
+
h = Math.PI*lng2/180;
|
769
|
+
return 1000*6371 * Math.acos(Math.min(Math.cos(e)*Math.cos(g)*Math.cos(f)*Math.cos(h)+Math.cos(e)*Math.sin(f)*Math.cos(g)*Math.sin(h)+Math.sin(e)*Math.sin(g),1));
|
770
|
+
}
|
771
|
+
|
772
|
+
// extend the visible bounds
|
773
|
+
function extendsMapBounds(){
|
774
|
+
var radius = distanceInMeter(map.getCenter(), map.getBounds().getNorthEast()),
|
775
|
+
circle = new google.maps.Circle({
|
776
|
+
center: map.getCenter(),
|
777
|
+
radius: 1.25 * radius // + 25%
|
778
|
+
});
|
779
|
+
return circle.getBounds();
|
780
|
+
}
|
781
|
+
|
782
|
+
// return an object where keys are store keys
|
783
|
+
function getStoreKeys(){
|
784
|
+
var keys = {}, k;
|
785
|
+
for(k in store){
|
786
|
+
keys[k] = true;
|
787
|
+
}
|
788
|
+
return keys;
|
789
|
+
}
|
790
|
+
|
791
|
+
// async the delay function
|
792
|
+
function delayRedraw(){
|
793
|
+
clearTimeout(timer);
|
794
|
+
timer = setTimeout(function(){
|
795
|
+
redraw();
|
796
|
+
},
|
797
|
+
25);
|
798
|
+
}
|
799
|
+
|
800
|
+
// generate bounds extended by radius
|
801
|
+
function extendsBounds(latLng) {
|
802
|
+
var p = projection.fromLatLngToDivPixel(latLng),
|
803
|
+
ne = projection.fromDivPixelToLatLng(new google.maps.Point(p.x+raw.radius, p.y-raw.radius)),
|
804
|
+
sw = projection.fromDivPixelToLatLng(new google.maps.Point(p.x-raw.radius, p.y+raw.radius));
|
805
|
+
return new google.maps.LatLngBounds(sw, ne);
|
806
|
+
}
|
807
|
+
|
808
|
+
// run the clustering process and call the display function
|
809
|
+
function redraw(){
|
810
|
+
if (updating || redrawing || !ready){
|
811
|
+
return;
|
812
|
+
}
|
813
|
+
|
814
|
+
var keys = [], used = {},
|
815
|
+
zoom = map.getZoom(),
|
816
|
+
forceDisabled = ("maxZoom" in raw) && (zoom > raw.maxZoom),
|
817
|
+
previousKeys = getStoreKeys(),
|
818
|
+
i, j, k, indexes, check = false, bounds, cluster, position, previous, lat, lng, loop;
|
819
|
+
|
820
|
+
// reset flag
|
821
|
+
updated = false;
|
822
|
+
|
823
|
+
if (zoom > 3){
|
824
|
+
// extend the bounds of the visible map to manage clusters near the boundaries
|
825
|
+
bounds = extendsMapBounds();
|
826
|
+
|
827
|
+
// check contain only if boundaries are valid
|
828
|
+
check = bounds.getSouthWest().lng() < bounds.getNorthEast().lng();
|
829
|
+
}
|
830
|
+
|
831
|
+
// calculate positions of "visibles" markers (in extended bounds)
|
832
|
+
for(i=0; i<todos.length; i++){
|
833
|
+
if (todos[i] && (!check || bounds.contains(todos[i].options.position)) && (!ffilter || ffilter(values[i]))){
|
834
|
+
keys.push(i);
|
835
|
+
}
|
836
|
+
}
|
837
|
+
|
838
|
+
// for each "visible" marker, search its neighbors to create a cluster
|
839
|
+
// we can't do a classical "for" loop, because, analysis can bypass a marker while focusing on cluster
|
840
|
+
while(1){
|
841
|
+
i=0;
|
842
|
+
while(used[i] && (i<keys.length)){ // look for the next marker not used
|
843
|
+
i++;
|
844
|
+
}
|
845
|
+
if (i == keys.length){
|
846
|
+
break;
|
847
|
+
}
|
848
|
+
|
849
|
+
indexes = [];
|
850
|
+
|
851
|
+
if (enabled && !forceDisabled){
|
852
|
+
loop = 10;
|
853
|
+
do{
|
854
|
+
previous = indexes;
|
855
|
+
indexes = [];
|
856
|
+
loop--;
|
857
|
+
|
858
|
+
if (previous.length){
|
859
|
+
position = bounds.getCenter()
|
860
|
+
} else {
|
861
|
+
position = todos[ keys[i] ].options.position;
|
862
|
+
}
|
863
|
+
bounds = extendsBounds(position);
|
864
|
+
|
865
|
+
for(j=i; j<keys.length; j++){
|
866
|
+
if (used[j]){
|
867
|
+
continue;
|
868
|
+
}
|
869
|
+
if (bounds.contains(todos[ keys[j] ].options.position)){
|
870
|
+
indexes.push(j);
|
871
|
+
}
|
872
|
+
}
|
873
|
+
} while( (previous.length < indexes.length) && (indexes.length > 1) && loop);
|
874
|
+
} else {
|
875
|
+
for(j=i; j<keys.length; j++){
|
876
|
+
if (used[j]){
|
877
|
+
continue;
|
878
|
+
}
|
879
|
+
indexes.push(j);
|
880
|
+
break;
|
881
|
+
}
|
882
|
+
}
|
883
|
+
|
884
|
+
cluster = {indexes:[], ref:[]};
|
885
|
+
lat = lng = 0;
|
886
|
+
for(k=0; k<indexes.length; k++){
|
887
|
+
used[ indexes[k] ] = true;
|
888
|
+
cluster.indexes.push(keys[indexes[k]]);
|
889
|
+
cluster.ref.push(keys[indexes[k]]);
|
890
|
+
lat += todos[ keys[indexes[k]] ].options.position.lat();
|
891
|
+
lng += todos[ keys[indexes[k]] ].options.position.lng();
|
892
|
+
}
|
893
|
+
lat /= indexes.length;
|
894
|
+
lng /= indexes.length;
|
895
|
+
cluster.latLng = new google.maps.LatLng(lat, lng);
|
896
|
+
|
897
|
+
cluster.ref = cluster.ref.join("-");
|
898
|
+
|
899
|
+
if (cluster.ref in previousKeys){ // cluster doesn't change
|
900
|
+
delete previousKeys[cluster.ref]; // remove this entry, these still in this array will be removed
|
901
|
+
} else { // cluster is new
|
902
|
+
if (indexes.length === 1){ // alone markers are not stored, so need to keep the key (else, will be displayed every time and marker will blink)
|
903
|
+
store[cluster.ref] = true;
|
904
|
+
}
|
905
|
+
fdisplay(cluster);
|
906
|
+
}
|
907
|
+
}
|
908
|
+
|
909
|
+
// flush the previous overlays which are not still used
|
910
|
+
$.each(previousKeys, function(key){
|
911
|
+
flush(key);
|
912
|
+
});
|
913
|
+
redrawing = false;
|
914
|
+
}
|
915
|
+
}
|
916
|
+
|
917
|
+
/**
|
918
|
+
* Class Clusterer
|
919
|
+
* a facade with limited method for external use
|
920
|
+
**/
|
921
|
+
function Clusterer(id, internalClusterer){
|
922
|
+
this.id = function(){
|
923
|
+
return id;
|
924
|
+
};
|
925
|
+
this.filter = function(f){
|
926
|
+
internalClusterer.filter(f);
|
927
|
+
};
|
928
|
+
this.enable = function(){
|
929
|
+
internalClusterer.enable(true);
|
930
|
+
};
|
931
|
+
this.disable = function(){
|
932
|
+
internalClusterer.enable(false);
|
933
|
+
};
|
934
|
+
this.add = function(marker, todo, lock){
|
935
|
+
if (!lock) {
|
936
|
+
internalClusterer.beginUpdate();
|
937
|
+
}
|
938
|
+
internalClusterer.addMarker(marker, todo);
|
939
|
+
if (!lock) {
|
940
|
+
internalClusterer.endUpdate();
|
941
|
+
}
|
942
|
+
};
|
943
|
+
this.getById = function(id){
|
944
|
+
return internalClusterer.getById(id);
|
945
|
+
};
|
946
|
+
this.clearById = function(id, lock){
|
947
|
+
var result;
|
948
|
+
if (!lock) {
|
949
|
+
internalClusterer.beginUpdate();
|
950
|
+
}
|
951
|
+
result = internalClusterer.clearById(id);
|
952
|
+
if (!lock) {
|
953
|
+
internalClusterer.endUpdate();
|
954
|
+
}
|
955
|
+
return result;
|
956
|
+
};
|
957
|
+
this.clear = function(last, first, tag, lock){
|
958
|
+
if (!lock) {
|
959
|
+
internalClusterer.beginUpdate();
|
960
|
+
}
|
961
|
+
internalClusterer.clear(last, first, tag);
|
962
|
+
if (!lock) {
|
963
|
+
internalClusterer.endUpdate();
|
964
|
+
}
|
965
|
+
};
|
966
|
+
}
|
967
|
+
/***************************************************************************/
|
968
|
+
/* STORE */
|
969
|
+
/***************************************************************************/
|
970
|
+
|
971
|
+
function Store(){
|
972
|
+
var store = {}, // name => [id, ...]
|
973
|
+
objects = {}; // id => object
|
974
|
+
|
975
|
+
function normalize(res) {
|
976
|
+
return {
|
977
|
+
id: res.id,
|
978
|
+
name: res.name,
|
979
|
+
object:res.obj,
|
980
|
+
tag:res.tag,
|
981
|
+
data:res.data
|
982
|
+
};
|
983
|
+
}
|
984
|
+
|
985
|
+
/**
|
986
|
+
* add a mixed to the store
|
987
|
+
**/
|
988
|
+
this.add = function(args, name, obj, sub){
|
989
|
+
var todo = args.todo || {},
|
990
|
+
id = globalId(todo.id);
|
991
|
+
if (!store[name]){
|
992
|
+
store[name] = [];
|
993
|
+
}
|
994
|
+
if (id in objects){ // object already exists: remove it
|
995
|
+
this.clearById(id);
|
996
|
+
}
|
997
|
+
objects[id] = {obj:obj, sub:sub, name:name, id:id, tag:todo.tag, data:todo.data};
|
998
|
+
store[name].push(id);
|
999
|
+
return id;
|
1000
|
+
};
|
1001
|
+
|
1002
|
+
/**
|
1003
|
+
* return a stored object by its id
|
1004
|
+
**/
|
1005
|
+
this.getById = function(id, sub, full){
|
1006
|
+
if (id in objects){
|
1007
|
+
if (sub) {
|
1008
|
+
return objects[id].sub
|
1009
|
+
} else if (full) {
|
1010
|
+
return normalize(objects[id]);
|
1011
|
+
}
|
1012
|
+
return objects[id].obj;
|
1013
|
+
|
1014
|
+
}
|
1015
|
+
return false;
|
1016
|
+
};
|
1017
|
+
|
1018
|
+
/**
|
1019
|
+
* return a stored value
|
1020
|
+
**/
|
1021
|
+
this.get = function(name, last, tag, full){
|
1022
|
+
var n, id, check = ftag(tag);
|
1023
|
+
if (!store[name] || !store[name].length){
|
1024
|
+
return null;
|
1025
|
+
}
|
1026
|
+
n = store[name].length;
|
1027
|
+
while(n){
|
1028
|
+
n--;
|
1029
|
+
id = store[name][last ? n : store[name].length - n - 1];
|
1030
|
+
if (id && objects[id]){
|
1031
|
+
if (check && !check(objects[id].tag)){
|
1032
|
+
continue;
|
1033
|
+
}
|
1034
|
+
return full ? normalize(objects[id]) : objects[id].obj;
|
1035
|
+
}
|
1036
|
+
}
|
1037
|
+
return null;
|
1038
|
+
};
|
1039
|
+
|
1040
|
+
/**
|
1041
|
+
* return all stored values
|
1042
|
+
**/
|
1043
|
+
this.all = function(name, tag, full){
|
1044
|
+
var result = [],
|
1045
|
+
check = ftag(tag),
|
1046
|
+
find = function(n){
|
1047
|
+
var i, id;
|
1048
|
+
for(i=0; i<store[n].length; i++){
|
1049
|
+
id = store[n][i];
|
1050
|
+
if (id && objects[id]){
|
1051
|
+
if (check && !check(objects[id].tag)){
|
1052
|
+
continue;
|
1053
|
+
}
|
1054
|
+
result.push(full ? normalize(objects[id]) : objects[id].obj);
|
1055
|
+
}
|
1056
|
+
}
|
1057
|
+
};
|
1058
|
+
if (name in store){
|
1059
|
+
find(name);
|
1060
|
+
} else if (name === undef){ // internal use only
|
1061
|
+
for(name in store){
|
1062
|
+
find(name);
|
1063
|
+
}
|
1064
|
+
}
|
1065
|
+
return result;
|
1066
|
+
};
|
1067
|
+
|
1068
|
+
/**
|
1069
|
+
* hide and remove an object
|
1070
|
+
**/
|
1071
|
+
function rm(obj){
|
1072
|
+
// Google maps element
|
1073
|
+
if (typeof(obj.setMap) === "function") {
|
1074
|
+
obj.setMap(null);
|
1075
|
+
}
|
1076
|
+
// jQuery
|
1077
|
+
if (typeof(obj.remove) === "function") {
|
1078
|
+
obj.remove();
|
1079
|
+
}
|
1080
|
+
// internal (cluster)
|
1081
|
+
if (typeof(obj.free) === "function") {
|
1082
|
+
obj.free();
|
1083
|
+
}
|
1084
|
+
obj = null;
|
1085
|
+
}
|
1086
|
+
|
1087
|
+
/**
|
1088
|
+
* remove one object from the store
|
1089
|
+
**/
|
1090
|
+
this.rm = function(name, check, pop){
|
1091
|
+
var idx, id;
|
1092
|
+
if (!store[name]) {
|
1093
|
+
return false;
|
1094
|
+
}
|
1095
|
+
if (check){
|
1096
|
+
if (pop){
|
1097
|
+
for(idx = store[name].length - 1; idx >= 0; idx--){
|
1098
|
+
id = store[name][idx];
|
1099
|
+
if ( check(objects[id].tag) ){
|
1100
|
+
break;
|
1101
|
+
}
|
1102
|
+
}
|
1103
|
+
} else {
|
1104
|
+
for(idx = 0; idx < store[name].length; idx++){
|
1105
|
+
id = store[name][idx];
|
1106
|
+
if (check(objects[id].tag)){
|
1107
|
+
break;
|
1108
|
+
}
|
1109
|
+
}
|
1110
|
+
}
|
1111
|
+
} else {
|
1112
|
+
idx = pop ? store[name].length - 1 : 0;
|
1113
|
+
}
|
1114
|
+
if ( !(idx in store[name]) ) {
|
1115
|
+
return false;
|
1116
|
+
}
|
1117
|
+
return this.clearById(store[name][idx], idx);
|
1118
|
+
};
|
1119
|
+
|
1120
|
+
/**
|
1121
|
+
* remove object from the store by its id
|
1122
|
+
**/
|
1123
|
+
this.clearById = function(id, idx){
|
1124
|
+
if (id in objects){
|
1125
|
+
var i, name = objects[id].name;
|
1126
|
+
for(i=0; idx === undef && i<store[name].length; i++){
|
1127
|
+
if (id === store[name][i]){
|
1128
|
+
idx = i;
|
1129
|
+
}
|
1130
|
+
}
|
1131
|
+
rm(objects[id].obj);
|
1132
|
+
if(objects[id].sub){
|
1133
|
+
rm(objects[id].sub);
|
1134
|
+
}
|
1135
|
+
delete objects[id];
|
1136
|
+
store[name].splice(idx, 1);
|
1137
|
+
return true;
|
1138
|
+
}
|
1139
|
+
return false;
|
1140
|
+
};
|
1141
|
+
|
1142
|
+
/**
|
1143
|
+
* return an object from a container object in the store by its id
|
1144
|
+
* ! for now, only cluster manage this feature
|
1145
|
+
**/
|
1146
|
+
this.objGetById = function(id){
|
1147
|
+
var result;
|
1148
|
+
if (store["clusterer"]) {
|
1149
|
+
for(var idx in store["clusterer"]){
|
1150
|
+
if ((result = objects[store["clusterer"][idx]].obj.getById(id)) !== false){
|
1151
|
+
return result;
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
}
|
1155
|
+
return false;
|
1156
|
+
};
|
1157
|
+
|
1158
|
+
/**
|
1159
|
+
* remove object from a container object in the store by its id
|
1160
|
+
* ! for now, only cluster manage this feature
|
1161
|
+
**/
|
1162
|
+
this.objClearById = function(id){
|
1163
|
+
if (store["clusterer"]) {
|
1164
|
+
for(var idx in store["clusterer"]){
|
1165
|
+
if (objects[store["clusterer"][idx]].obj.clearById(id)){
|
1166
|
+
return true;
|
1167
|
+
}
|
1168
|
+
}
|
1169
|
+
}
|
1170
|
+
return null;
|
1171
|
+
};
|
1172
|
+
|
1173
|
+
/**
|
1174
|
+
* remove objects from the store
|
1175
|
+
**/
|
1176
|
+
this.clear = function(list, last, first, tag){
|
1177
|
+
var k, i, name, check = ftag(tag);
|
1178
|
+
if (!list || !list.length){
|
1179
|
+
list = [];
|
1180
|
+
for(k in store){
|
1181
|
+
list.push(k);
|
1182
|
+
}
|
1183
|
+
} else {
|
1184
|
+
list = array(list);
|
1185
|
+
}
|
1186
|
+
for(i=0; i<list.length; i++){
|
1187
|
+
name = list[i];
|
1188
|
+
if (last){
|
1189
|
+
this.rm(name, check, true);
|
1190
|
+
} else if (first){
|
1191
|
+
this.rm(name, check, false);
|
1192
|
+
} else { // all
|
1193
|
+
while(this.rm(name, check, false));
|
1194
|
+
}
|
1195
|
+
}
|
1196
|
+
};
|
1197
|
+
|
1198
|
+
/**
|
1199
|
+
* remove object from a container object in the store by its tags
|
1200
|
+
* ! for now, only cluster manage this feature
|
1201
|
+
**/
|
1202
|
+
this.objClear = function(list, last, first, tag){
|
1203
|
+
if (store["clusterer"] && ($.inArray("marker", list) >= 0 || !list.length)) {
|
1204
|
+
for(var idx in store["clusterer"]){
|
1205
|
+
objects[store["clusterer"][idx]].obj.clear(last, first, tag);
|
1206
|
+
}
|
1207
|
+
}
|
1208
|
+
};
|
1209
|
+
}
|
1210
|
+
|
1211
|
+
/***************************************************************************/
|
1212
|
+
/* GMAP3 GLOBALS */
|
1213
|
+
/***************************************************************************/
|
1214
|
+
|
1215
|
+
var services = {},
|
1216
|
+
geocoderCache = new GeocoderCache();
|
1217
|
+
|
1218
|
+
//-----------------------------------------------------------------------//
|
1219
|
+
// Service tools
|
1220
|
+
//-----------------------------------------------------------------------//
|
1221
|
+
|
1222
|
+
function geocoder(){
|
1223
|
+
if (!services.geocoder) {
|
1224
|
+
services.geocoder = new google.maps.Geocoder();
|
1225
|
+
}
|
1226
|
+
return services.geocoder;
|
1227
|
+
}
|
1228
|
+
|
1229
|
+
function directionsService(){
|
1230
|
+
if (!services.directionsService) {
|
1231
|
+
services.directionsService = new google.maps.DirectionsService();
|
1232
|
+
}
|
1233
|
+
return services.directionsService;
|
1234
|
+
}
|
1235
|
+
|
1236
|
+
function elevationService(){
|
1237
|
+
if (!services.elevationService) {
|
1238
|
+
services.elevationService = new google.maps.ElevationService();
|
1239
|
+
}
|
1240
|
+
return services.elevationService;
|
1241
|
+
}
|
1242
|
+
|
1243
|
+
function maxZoomService(){
|
1244
|
+
if (!services.maxZoomService) {
|
1245
|
+
services.maxZoomService = new google.maps.MaxZoomService();
|
1246
|
+
}
|
1247
|
+
return services.maxZoomService;
|
1248
|
+
}
|
1249
|
+
|
1250
|
+
function distanceMatrixService(){
|
1251
|
+
if (!services.distanceMatrixService) {
|
1252
|
+
services.distanceMatrixService = new google.maps.DistanceMatrixService();
|
1253
|
+
}
|
1254
|
+
return services.distanceMatrixService;
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
//-----------------------------------------------------------------------//
|
1258
|
+
// Unit tools
|
1259
|
+
//-----------------------------------------------------------------------//
|
1260
|
+
|
1261
|
+
function error(){
|
1262
|
+
if (defaults.verbose){
|
1263
|
+
var i, err = [];
|
1264
|
+
if (window.console && (typeof console.error === "function") ){
|
1265
|
+
for(i=0; i<arguments.length; i++){
|
1266
|
+
err.push(arguments[i]);
|
1267
|
+
}
|
1268
|
+
console.error.apply(console, err);
|
1269
|
+
} else {
|
1270
|
+
err = "";
|
1271
|
+
for(i=0; i<arguments.length; i++){
|
1272
|
+
err += arguments[i].toString() + " " ;
|
1273
|
+
}
|
1274
|
+
alert(err);
|
1275
|
+
}
|
1276
|
+
}
|
1277
|
+
}
|
1278
|
+
|
1279
|
+
/**
|
1280
|
+
* return true if mixed is usable as number
|
1281
|
+
**/
|
1282
|
+
function numeric(mixed){
|
1283
|
+
return (typeof(mixed) === "number" || typeof(mixed) === "string") && mixed !== "" && !isNaN(mixed);
|
1284
|
+
}
|
1285
|
+
|
1286
|
+
/**
|
1287
|
+
* convert data to array
|
1288
|
+
**/
|
1289
|
+
function array(mixed){
|
1290
|
+
var k, a = [];
|
1291
|
+
if (mixed !== undef){
|
1292
|
+
if (typeof(mixed) === "object"){
|
1293
|
+
if (typeof(mixed.length) === "number") {
|
1294
|
+
a = mixed;
|
1295
|
+
} else {
|
1296
|
+
for(k in mixed) {
|
1297
|
+
a.push(mixed[k]);
|
1298
|
+
}
|
1299
|
+
}
|
1300
|
+
} else{
|
1301
|
+
a.push(mixed);
|
1302
|
+
}
|
1303
|
+
}
|
1304
|
+
return a;
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
/**
|
1308
|
+
* create a function to check a tag
|
1309
|
+
*/
|
1310
|
+
function ftag(tag){
|
1311
|
+
if (tag){
|
1312
|
+
if (typeof tag === "function"){
|
1313
|
+
return tag;
|
1314
|
+
}
|
1315
|
+
tag = array(tag);
|
1316
|
+
return function(val){
|
1317
|
+
if (val === undef){
|
1318
|
+
return false;
|
1319
|
+
}
|
1320
|
+
if (typeof val === "object"){
|
1321
|
+
for(var i=0; i<val.length; i++){
|
1322
|
+
if($.inArray(val[i], tag) >= 0){
|
1323
|
+
return true;
|
1324
|
+
}
|
1325
|
+
}
|
1326
|
+
return false;
|
1327
|
+
}
|
1328
|
+
return $.inArray(val, tag) >= 0;
|
1329
|
+
}
|
1330
|
+
}
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
/**
|
1334
|
+
* convert mixed [ lat, lng ] objet to google.maps.LatLng
|
1335
|
+
**/
|
1336
|
+
function toLatLng (mixed, emptyReturnMixed, noFlat){
|
1337
|
+
var empty = emptyReturnMixed ? mixed : null;
|
1338
|
+
if (!mixed || (typeof mixed === "string")){
|
1339
|
+
return empty;
|
1340
|
+
}
|
1341
|
+
// defined latLng
|
1342
|
+
if (mixed.latLng) {
|
1343
|
+
return toLatLng(mixed.latLng);
|
1344
|
+
}
|
1345
|
+
// google.maps.LatLng object
|
1346
|
+
if (mixed instanceof google.maps.LatLng) {
|
1347
|
+
return mixed;
|
1348
|
+
}
|
1349
|
+
// {lat:X, lng:Y} object
|
1350
|
+
else if ( numeric(mixed.lat) ) {
|
1351
|
+
return new google.maps.LatLng(mixed.lat, mixed.lng);
|
1352
|
+
}
|
1353
|
+
// [X, Y] object
|
1354
|
+
else if ( !noFlat && $.isArray(mixed)){
|
1355
|
+
if ( !numeric(mixed[0]) || !numeric(mixed[1]) ) {
|
1356
|
+
return empty;
|
1357
|
+
}
|
1358
|
+
return new google.maps.LatLng(mixed[0], mixed[1]);
|
1359
|
+
}
|
1360
|
+
return empty;
|
1361
|
+
}
|
1362
|
+
|
1363
|
+
/**
|
1364
|
+
* convert mixed [ sw, ne ] object by google.maps.LatLngBounds
|
1365
|
+
**/
|
1366
|
+
function toLatLngBounds(mixed){
|
1367
|
+
var ne, sw;
|
1368
|
+
if (!mixed || mixed instanceof google.maps.LatLngBounds) {
|
1369
|
+
return mixed || null;
|
1370
|
+
}
|
1371
|
+
if ($.isArray(mixed)){
|
1372
|
+
if (mixed.length == 2){
|
1373
|
+
ne = toLatLng(mixed[0]);
|
1374
|
+
sw = toLatLng(mixed[1]);
|
1375
|
+
} else if (mixed.length == 4){
|
1376
|
+
ne = toLatLng([mixed[0], mixed[1]]);
|
1377
|
+
sw = toLatLng([mixed[2], mixed[3]]);
|
1378
|
+
}
|
1379
|
+
} else {
|
1380
|
+
if ( ("ne" in mixed) && ("sw" in mixed) ){
|
1381
|
+
ne = toLatLng(mixed.ne);
|
1382
|
+
sw = toLatLng(mixed.sw);
|
1383
|
+
} else if ( ("n" in mixed) && ("e" in mixed) && ("s" in mixed) && ("w" in mixed) ){
|
1384
|
+
ne = toLatLng([mixed.n, mixed.e]);
|
1385
|
+
sw = toLatLng([mixed.s, mixed.w]);
|
1386
|
+
}
|
1387
|
+
}
|
1388
|
+
if (ne && sw){
|
1389
|
+
return new google.maps.LatLngBounds(sw, ne);
|
1390
|
+
}
|
1391
|
+
return null;
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
/**
|
1395
|
+
* resolveLatLng
|
1396
|
+
**/
|
1397
|
+
function resolveLatLng(ctx, method, runLatLng, args, attempt){
|
1398
|
+
var latLng = runLatLng ? toLatLng(args.todo, false, true) : false,
|
1399
|
+
conf = latLng ? {latLng:latLng} : (args.todo.address ? (typeof(args.todo.address) === "string" ? {address:args.todo.address} : args.todo.address) : false),
|
1400
|
+
cache = conf ? geocoderCache.get(conf) : false,
|
1401
|
+
that = this;
|
1402
|
+
if (conf){
|
1403
|
+
attempt = attempt || 0; // convert undefined to int
|
1404
|
+
if (cache){
|
1405
|
+
args.latLng = cache.results[0].geometry.location;
|
1406
|
+
args.results = cache.results;
|
1407
|
+
args.status = cache.status;
|
1408
|
+
method.apply(ctx, [args]);
|
1409
|
+
} else {
|
1410
|
+
if (conf.location){
|
1411
|
+
conf.location = toLatLng(conf.location);
|
1412
|
+
}
|
1413
|
+
if (conf.bounds){
|
1414
|
+
conf.bounds = toLatLngBounds(conf.bounds);
|
1415
|
+
}
|
1416
|
+
geocoder().geocode(
|
1417
|
+
conf,
|
1418
|
+
function(results, status) {
|
1419
|
+
if (status === google.maps.GeocoderStatus.OK){
|
1420
|
+
geocoderCache.store(conf, {results:results, status:status});
|
1421
|
+
args.latLng = results[0].geometry.location;
|
1422
|
+
args.results = results;
|
1423
|
+
args.status = status;
|
1424
|
+
method.apply(ctx, [args]);
|
1425
|
+
} else if ( (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) && (attempt < defaults.queryLimit.attempt) ){
|
1426
|
+
setTimeout(
|
1427
|
+
function(){
|
1428
|
+
resolveLatLng.apply(that, [ctx, method, runLatLng, args, attempt+1]);
|
1429
|
+
},
|
1430
|
+
defaults.queryLimit.delay + Math.floor(Math.random() * defaults.queryLimit.random)
|
1431
|
+
);
|
1432
|
+
} else {
|
1433
|
+
error("geocode failed", status, conf);
|
1434
|
+
args.latLng = args.results = false;
|
1435
|
+
args.status = status;
|
1436
|
+
method.apply(ctx, [args]);
|
1437
|
+
}
|
1438
|
+
}
|
1439
|
+
);
|
1440
|
+
}
|
1441
|
+
} else {
|
1442
|
+
args.latLng = toLatLng(args.todo, false, true);
|
1443
|
+
method.apply(ctx, [args]);
|
1444
|
+
}
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
function resolveAllLatLng(list, ctx, method, args){
|
1448
|
+
var that = this, i = -1;
|
1449
|
+
|
1450
|
+
function resolve(){
|
1451
|
+
// look for next address to resolve
|
1452
|
+
do{
|
1453
|
+
i++;
|
1454
|
+
}while( (i < list.length) && !("address" in list[i]) );
|
1455
|
+
|
1456
|
+
// no address found, so run method
|
1457
|
+
if (i >= list.length){
|
1458
|
+
method.apply(ctx, [args]);
|
1459
|
+
return;
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
resolveLatLng(
|
1463
|
+
that,
|
1464
|
+
function(args){
|
1465
|
+
delete args.todo;
|
1466
|
+
$.extend(list[i], args);
|
1467
|
+
resolve.apply(that, []); // resolve next (using apply avoid too much recursion)
|
1468
|
+
},
|
1469
|
+
true,
|
1470
|
+
{todo:list[i]}
|
1471
|
+
);
|
1472
|
+
}
|
1473
|
+
resolve();
|
1474
|
+
}
|
1475
|
+
|
1476
|
+
/**
|
1477
|
+
* geolocalise the user and return a LatLng
|
1478
|
+
**/
|
1479
|
+
function geoloc(ctx, method, args){
|
1480
|
+
var is_echo = false; // sometime, a kind of echo appear, this trick will notice once the first call is run to ignore the next one
|
1481
|
+
if (navigator && navigator.geolocation){
|
1482
|
+
navigator.geolocation.getCurrentPosition(
|
1483
|
+
function(pos) {
|
1484
|
+
if (is_echo){
|
1485
|
+
return;
|
1486
|
+
}
|
1487
|
+
is_echo = true;
|
1488
|
+
args.latLng = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude);
|
1489
|
+
method.apply(ctx, [args]);
|
1490
|
+
},
|
1491
|
+
function() {
|
1492
|
+
if (is_echo){
|
1493
|
+
return;
|
1494
|
+
}
|
1495
|
+
is_echo = true;
|
1496
|
+
args.latLng = false;
|
1497
|
+
method.apply(ctx, [args]);
|
1498
|
+
},
|
1499
|
+
args.opts.getCurrentPosition
|
1500
|
+
);
|
1501
|
+
} else {
|
1502
|
+
args.latLng = false;
|
1503
|
+
method.apply(ctx, [args]);
|
1504
|
+
}
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
/***************************************************************************/
|
1508
|
+
/* GMAP3 */
|
1509
|
+
/***************************************************************************/
|
1510
|
+
|
1511
|
+
function Gmap3($this){
|
1512
|
+
var that = this,
|
1513
|
+
stack = new Stack(),
|
1514
|
+
store = new Store(),
|
1515
|
+
map = null,
|
1516
|
+
task;
|
1517
|
+
|
1518
|
+
//-----------------------------------------------------------------------//
|
1519
|
+
// Stack tools
|
1520
|
+
//-----------------------------------------------------------------------//
|
1521
|
+
|
1522
|
+
/**
|
1523
|
+
* store actions to execute in a stack manager
|
1524
|
+
**/
|
1525
|
+
this._plan = function(list){
|
1526
|
+
for(var k = 0; k < list.length; k++) {
|
1527
|
+
stack.add(new Task(that, end, list[k]));
|
1528
|
+
}
|
1529
|
+
run();
|
1530
|
+
};
|
1531
|
+
|
1532
|
+
/**
|
1533
|
+
* if not running, start next action in stack
|
1534
|
+
**/
|
1535
|
+
function run(){
|
1536
|
+
if (!task && (task = stack.get())){
|
1537
|
+
task.run();
|
1538
|
+
}
|
1539
|
+
}
|
1540
|
+
|
1541
|
+
/**
|
1542
|
+
* called when action in finished, to acknoledge the current in stack and start next one
|
1543
|
+
**/
|
1544
|
+
function end(){
|
1545
|
+
task = null;
|
1546
|
+
stack.ack();
|
1547
|
+
run.call(that); // restart to high level scope
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
//-----------------------------------------------------------------------//
|
1551
|
+
// Tools
|
1552
|
+
//-----------------------------------------------------------------------//
|
1553
|
+
|
1554
|
+
/**
|
1555
|
+
* execute callback functions
|
1556
|
+
**/
|
1557
|
+
function callback(args){
|
1558
|
+
if (args.todo.callback) {
|
1559
|
+
var params = Array.prototype.slice.call(arguments, 1);
|
1560
|
+
if (typeof args.todo.callback === "function") {
|
1561
|
+
args.todo.callback.apply($this, params);
|
1562
|
+
} else if ($.isArray(args.todo.callback)) {
|
1563
|
+
if (typeof args.todo.callback[1] === "function") {
|
1564
|
+
args.todo.callback[1].apply(args.todo.callback[0], params);
|
1565
|
+
}
|
1566
|
+
}
|
1567
|
+
}
|
1568
|
+
}
|
1569
|
+
|
1570
|
+
/**
|
1571
|
+
* execute ending functions
|
1572
|
+
**/
|
1573
|
+
function manageEnd(args, obj, id){
|
1574
|
+
if (id){
|
1575
|
+
attachEvents($this, args, obj, id);
|
1576
|
+
}
|
1577
|
+
callback(args, obj);
|
1578
|
+
task.ack(obj);
|
1579
|
+
}
|
1580
|
+
|
1581
|
+
/**
|
1582
|
+
* initialize the map if not yet initialized
|
1583
|
+
**/
|
1584
|
+
function newMap(latLng, args){
|
1585
|
+
args = args || {};
|
1586
|
+
if (map) {
|
1587
|
+
if (args.todo && args.todo.options){
|
1588
|
+
if (args.todo.options.center) {
|
1589
|
+
args.todo.options.center = toLatLng(args.todo.options.center);
|
1590
|
+
}
|
1591
|
+
map.setOptions(args.todo.options);
|
1592
|
+
}
|
1593
|
+
} else {
|
1594
|
+
var opts = args.opts || $.extend(true, {}, defaults.map, args.todo && args.todo.options ? args.todo.options : {});
|
1595
|
+
opts.center = latLng || toLatLng(opts.center);
|
1596
|
+
map = new defaults.classes.Map($this.get(0), opts);
|
1597
|
+
}
|
1598
|
+
}
|
1599
|
+
|
1600
|
+
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
1601
|
+
=> function with latLng resolution
|
1602
|
+
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
1603
|
+
|
1604
|
+
/**
|
1605
|
+
* Initialize google.maps.Map object
|
1606
|
+
**/
|
1607
|
+
this.map = function(args){
|
1608
|
+
newMap(args.latLng, args);
|
1609
|
+
attachEvents($this, args, map);
|
1610
|
+
manageEnd(args, map);
|
1611
|
+
};
|
1612
|
+
|
1613
|
+
/**
|
1614
|
+
* destroy an existing instance
|
1615
|
+
**/
|
1616
|
+
this.destroy = function(args){
|
1617
|
+
store.clear();
|
1618
|
+
$this.empty();
|
1619
|
+
if (map){
|
1620
|
+
map = null;
|
1621
|
+
}
|
1622
|
+
manageEnd(args, true);
|
1623
|
+
};
|
1624
|
+
|
1625
|
+
/**
|
1626
|
+
* add an infowindow
|
1627
|
+
**/
|
1628
|
+
this.infowindow = function(args){
|
1629
|
+
var objs = [], multiple = "values" in args.todo;
|
1630
|
+
if (!multiple){
|
1631
|
+
if (args.latLng) {
|
1632
|
+
args.opts.position = args.latLng;
|
1633
|
+
}
|
1634
|
+
args.todo.values = [{options:args.opts}];
|
1635
|
+
}
|
1636
|
+
$.each(args.todo.values, function(i, value){
|
1637
|
+
var id, obj, todo = tuple(args, value);
|
1638
|
+
todo.options.position = todo.options.position ? toLatLng(todo.options.position) : toLatLng(value.latLng);
|
1639
|
+
if (!map){
|
1640
|
+
newMap(todo.options.position);
|
1641
|
+
}
|
1642
|
+
obj = new defaults.classes.InfoWindow(todo.options);
|
1643
|
+
if (obj && ((todo.open === undef) || todo.open)){
|
1644
|
+
if (multiple){
|
1645
|
+
obj.open(map, todo.anchor ? todo.anchor : undef);
|
1646
|
+
} else {
|
1647
|
+
obj.open(map, todo.anchor ? todo.anchor : (args.latLng ? undef : (args.session.marker ? args.session.marker : undef)));
|
1648
|
+
}
|
1649
|
+
}
|
1650
|
+
objs.push(obj);
|
1651
|
+
id = store.add({todo:todo}, "infowindow", obj);
|
1652
|
+
attachEvents($this, {todo:todo}, obj, id);
|
1653
|
+
});
|
1654
|
+
manageEnd(args, multiple ? objs : objs[0]);
|
1655
|
+
};
|
1656
|
+
|
1657
|
+
/**
|
1658
|
+
* add a circle
|
1659
|
+
**/
|
1660
|
+
this.circle = function(args){
|
1661
|
+
var objs = [], multiple = "values" in args.todo;
|
1662
|
+
if (!multiple){
|
1663
|
+
args.opts.center = args.latLng || toLatLng(args.opts.center);
|
1664
|
+
args.todo.values = [{options:args.opts}];
|
1665
|
+
}
|
1666
|
+
if (!args.todo.values.length){
|
1667
|
+
manageEnd(args, false);
|
1668
|
+
return;
|
1669
|
+
}
|
1670
|
+
$.each(args.todo.values, function(i, value){
|
1671
|
+
var id, obj, todo = tuple(args, value);
|
1672
|
+
todo.options.center = todo.options.center ? toLatLng(todo.options.center) : toLatLng(value);
|
1673
|
+
if (!map){
|
1674
|
+
newMap(todo.options.center);
|
1675
|
+
}
|
1676
|
+
todo.options.map = map;
|
1677
|
+
obj = new defaults.classes.Circle(todo.options);
|
1678
|
+
objs.push(obj);
|
1679
|
+
id = store.add({todo:todo}, "circle", obj);
|
1680
|
+
attachEvents($this, {todo:todo}, obj, id);
|
1681
|
+
});
|
1682
|
+
manageEnd(args, multiple ? objs : objs[0]);
|
1683
|
+
};
|
1684
|
+
|
1685
|
+
/**
|
1686
|
+
* add an overlay
|
1687
|
+
**/
|
1688
|
+
this.overlay = function(args, internal){
|
1689
|
+
var objs = [], multiple = "values" in args.todo;
|
1690
|
+
if (!multiple){
|
1691
|
+
args.todo.values = [{latLng: args.latLng, options: args.opts}];
|
1692
|
+
}
|
1693
|
+
if (!args.todo.values.length){
|
1694
|
+
manageEnd(args, false);
|
1695
|
+
return;
|
1696
|
+
}
|
1697
|
+
if (!OverlayView.__initialised) {
|
1698
|
+
OverlayView.prototype = new defaults.classes.OverlayView();
|
1699
|
+
OverlayView.__initialised = true;
|
1700
|
+
}
|
1701
|
+
$.each(args.todo.values, function(i, value){
|
1702
|
+
var id, obj, todo = tuple(args, value),
|
1703
|
+
$div = $(document.createElement("div")).css({
|
1704
|
+
border: "none",
|
1705
|
+
borderWidth: "0px",
|
1706
|
+
position: "absolute"
|
1707
|
+
});
|
1708
|
+
$div.append(todo.options.content);
|
1709
|
+
obj = new OverlayView(map, todo.options, toLatLng(todo) || toLatLng(value), $div);
|
1710
|
+
objs.push(obj);
|
1711
|
+
$div = null; // memory leak
|
1712
|
+
if (!internal){
|
1713
|
+
id = store.add(args, "overlay", obj);
|
1714
|
+
attachEvents($this, {todo:todo}, obj, id);
|
1715
|
+
}
|
1716
|
+
});
|
1717
|
+
if (internal){
|
1718
|
+
return objs[0];
|
1719
|
+
}
|
1720
|
+
manageEnd(args, multiple ? objs : objs[0]);
|
1721
|
+
};
|
1722
|
+
|
1723
|
+
/**
|
1724
|
+
* returns address structure from latlng
|
1725
|
+
**/
|
1726
|
+
this.getaddress = function(args){
|
1727
|
+
callback(args, args.results, args.status);
|
1728
|
+
task.ack();
|
1729
|
+
};
|
1730
|
+
|
1731
|
+
/**
|
1732
|
+
* returns latlng from an address
|
1733
|
+
**/
|
1734
|
+
this.getlatlng = function(args){
|
1735
|
+
callback(args, args.results, args.status);
|
1736
|
+
task.ack();
|
1737
|
+
};
|
1738
|
+
|
1739
|
+
/**
|
1740
|
+
* return the max zoom of a location
|
1741
|
+
**/
|
1742
|
+
this.getmaxzoom = function(args){
|
1743
|
+
maxZoomService().getMaxZoomAtLatLng(
|
1744
|
+
args.latLng,
|
1745
|
+
function(result) {
|
1746
|
+
callback(args, result.status === google.maps.MaxZoomStatus.OK ? result.zoom : false, status);
|
1747
|
+
task.ack();
|
1748
|
+
}
|
1749
|
+
);
|
1750
|
+
};
|
1751
|
+
|
1752
|
+
/**
|
1753
|
+
* return the elevation of a location
|
1754
|
+
**/
|
1755
|
+
this.getelevation = function(args){
|
1756
|
+
var i, locations = [],
|
1757
|
+
f = function(results, status){
|
1758
|
+
callback(args, status === google.maps.ElevationStatus.OK ? results : false, status);
|
1759
|
+
task.ack();
|
1760
|
+
};
|
1761
|
+
|
1762
|
+
if (args.latLng){
|
1763
|
+
locations.push(args.latLng);
|
1764
|
+
} else {
|
1765
|
+
locations = array(args.todo.locations || []);
|
1766
|
+
for(i=0; i<locations.length; i++){
|
1767
|
+
locations[i] = toLatLng(locations[i]);
|
1768
|
+
}
|
1769
|
+
}
|
1770
|
+
if (locations.length){
|
1771
|
+
elevationService().getElevationForLocations({locations:locations}, f);
|
1772
|
+
} else {
|
1773
|
+
if (args.todo.path && args.todo.path.length){
|
1774
|
+
for(i=0; i<args.todo.path.length; i++){
|
1775
|
+
locations.push(toLatLng(args.todo.path[i]));
|
1776
|
+
}
|
1777
|
+
}
|
1778
|
+
if (locations.length){
|
1779
|
+
elevationService().getElevationAlongPath({path:locations, samples:args.todo.samples}, f);
|
1780
|
+
} else {
|
1781
|
+
task.ack();
|
1782
|
+
}
|
1783
|
+
}
|
1784
|
+
};
|
1785
|
+
|
1786
|
+
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
1787
|
+
=> function without latLng resolution
|
1788
|
+
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
1789
|
+
|
1790
|
+
/**
|
1791
|
+
* define defaults values
|
1792
|
+
**/
|
1793
|
+
this.defaults = function(args){
|
1794
|
+
$.each(args.todo, function(name, value){
|
1795
|
+
if (typeof defaults[name] === "object"){
|
1796
|
+
defaults[name] = $.extend({}, defaults[name], value);
|
1797
|
+
} else {
|
1798
|
+
defaults[name] = value;
|
1799
|
+
}
|
1800
|
+
});
|
1801
|
+
task.ack(true);
|
1802
|
+
};
|
1803
|
+
|
1804
|
+
/**
|
1805
|
+
* add a rectangle
|
1806
|
+
**/
|
1807
|
+
this.rectangle = function(args){
|
1808
|
+
var objs = [], multiple = "values" in args.todo;
|
1809
|
+
if (!multiple){
|
1810
|
+
args.todo.values = [{options:args.opts}];
|
1811
|
+
}
|
1812
|
+
if (!args.todo.values.length){
|
1813
|
+
manageEnd(args, false);
|
1814
|
+
return;
|
1815
|
+
}
|
1816
|
+
$.each(args.todo.values, function(i, value){
|
1817
|
+
var id, obj, todo = tuple(args, value);
|
1818
|
+
todo.options.bounds = todo.options.bounds ? toLatLngBounds(todo.options.bounds) : toLatLngBounds(value);
|
1819
|
+
if (!map){
|
1820
|
+
newMap(todo.options.bounds.getCenter());
|
1821
|
+
}
|
1822
|
+
todo.options.map = map;
|
1823
|
+
|
1824
|
+
obj = new defaults.classes.Rectangle(todo.options);
|
1825
|
+
objs.push(obj);
|
1826
|
+
id = store.add({todo:todo}, "rectangle", obj);
|
1827
|
+
attachEvents($this, {todo:todo}, obj, id);
|
1828
|
+
});
|
1829
|
+
manageEnd(args, multiple ? objs : objs[0]);
|
1830
|
+
};
|
1831
|
+
|
1832
|
+
/**
|
1833
|
+
* add a polygone / polyline
|
1834
|
+
**/
|
1835
|
+
function poly(args, poly, path){
|
1836
|
+
var objs = [], multiple = "values" in args.todo;
|
1837
|
+
if (!multiple){
|
1838
|
+
args.todo.values = [{options:args.opts}];
|
1839
|
+
}
|
1840
|
+
if (!args.todo.values.length){
|
1841
|
+
manageEnd(args, false);
|
1842
|
+
return;
|
1843
|
+
}
|
1844
|
+
newMap();
|
1845
|
+
$.each(args.todo.values, function(_, value){
|
1846
|
+
var id, i, j, obj, todo = tuple(args, value);
|
1847
|
+
if (todo.options[path]){
|
1848
|
+
if (todo.options[path][0][0] && $.isArray(todo.options[path][0][0])){
|
1849
|
+
for(i=0; i<todo.options[path].length; i++){
|
1850
|
+
for(j=0; j<todo.options[path][i].length; j++){
|
1851
|
+
todo.options[path][i][j] = toLatLng(todo.options[path][i][j]);
|
1852
|
+
}
|
1853
|
+
}
|
1854
|
+
} else {
|
1855
|
+
for(i=0; i<todo.options[path].length; i++){
|
1856
|
+
todo.options[path][i] = toLatLng(todo.options[path][i]);
|
1857
|
+
}
|
1858
|
+
}
|
1859
|
+
}
|
1860
|
+
todo.options.map = map;
|
1861
|
+
obj = new google.maps[poly](todo.options);
|
1862
|
+
objs.push(obj);
|
1863
|
+
id = store.add({todo:todo}, poly.toLowerCase(), obj);
|
1864
|
+
attachEvents($this, {todo:todo}, obj, id);
|
1865
|
+
});
|
1866
|
+
manageEnd(args, multiple ? objs : objs[0]);
|
1867
|
+
}
|
1868
|
+
|
1869
|
+
this.polyline = function(args){
|
1870
|
+
poly(args, "Polyline", "path");
|
1871
|
+
};
|
1872
|
+
|
1873
|
+
this.polygon = function(args){
|
1874
|
+
poly(args, "Polygon", "paths");
|
1875
|
+
};
|
1876
|
+
|
1877
|
+
/**
|
1878
|
+
* add a traffic layer
|
1879
|
+
**/
|
1880
|
+
this.trafficlayer = function(args){
|
1881
|
+
newMap();
|
1882
|
+
var obj = store.get("trafficlayer");
|
1883
|
+
if (!obj){
|
1884
|
+
obj = new defaults.classes.TrafficLayer();
|
1885
|
+
obj.setMap(map);
|
1886
|
+
store.add(args, "trafficlayer", obj);
|
1887
|
+
}
|
1888
|
+
manageEnd(args, obj);
|
1889
|
+
};
|
1890
|
+
|
1891
|
+
/**
|
1892
|
+
* add a bicycling layer
|
1893
|
+
**/
|
1894
|
+
this.bicyclinglayer = function(args){
|
1895
|
+
newMap();
|
1896
|
+
var obj = store.get("bicyclinglayer");
|
1897
|
+
if (!obj){
|
1898
|
+
obj = new defaults.classes.BicyclingLayer();
|
1899
|
+
obj.setMap(map);
|
1900
|
+
store.add(args, "bicyclinglayer", obj);
|
1901
|
+
}
|
1902
|
+
manageEnd(args, obj);
|
1903
|
+
};
|
1904
|
+
|
1905
|
+
/**
|
1906
|
+
* add a ground overlay
|
1907
|
+
**/
|
1908
|
+
this.groundoverlay = function(args){
|
1909
|
+
args.opts.bounds = toLatLngBounds(args.opts.bounds);
|
1910
|
+
if (args.opts.bounds){
|
1911
|
+
newMap(args.opts.bounds.getCenter());
|
1912
|
+
}
|
1913
|
+
var id, obj = new defaults.classes.GroundOverlay(args.opts.url, args.opts.bounds, args.opts.opts);
|
1914
|
+
obj.setMap(map);
|
1915
|
+
id = store.add(args, "groundoverlay", obj);
|
1916
|
+
manageEnd(args, obj, id);
|
1917
|
+
};
|
1918
|
+
|
1919
|
+
/**
|
1920
|
+
* set a streetview
|
1921
|
+
**/
|
1922
|
+
this.streetviewpanorama = function(args){
|
1923
|
+
if (!args.opts.opts){
|
1924
|
+
args.opts.opts = {};
|
1925
|
+
}
|
1926
|
+
if (args.latLng){
|
1927
|
+
args.opts.opts.position = args.latLng;
|
1928
|
+
} else if (args.opts.opts.position){
|
1929
|
+
args.opts.opts.position = toLatLng(args.opts.opts.position);
|
1930
|
+
}
|
1931
|
+
if (args.todo.divId){
|
1932
|
+
args.opts.container = document.getElementById(args.todo.divId)
|
1933
|
+
} else if (args.opts.container){
|
1934
|
+
args.opts.container = $(args.opts.container).get(0);
|
1935
|
+
}
|
1936
|
+
var id, obj = new defaults.classes.StreetViewPanorama(args.opts.container, args.opts.opts);
|
1937
|
+
if (obj){
|
1938
|
+
map.setStreetView(obj);
|
1939
|
+
}
|
1940
|
+
id = store.add(args, "streetviewpanorama", obj);
|
1941
|
+
manageEnd(args, obj, id);
|
1942
|
+
};
|
1943
|
+
|
1944
|
+
this.kmllayer = function(args){
|
1945
|
+
var objs = [], multiple = "values" in args.todo;
|
1946
|
+
if (!multiple){
|
1947
|
+
args.todo.values = [{options:args.opts}];
|
1948
|
+
}
|
1949
|
+
if (!args.todo.values.length){
|
1950
|
+
manageEnd(args, false);
|
1951
|
+
return;
|
1952
|
+
}
|
1953
|
+
$.each(args.todo.values, function(i, value){
|
1954
|
+
var id, obj, options, todo = tuple(args, value);
|
1955
|
+
if (!map){
|
1956
|
+
newMap();
|
1957
|
+
}
|
1958
|
+
options = todo.options;
|
1959
|
+
// compatibility 5.0-
|
1960
|
+
if (todo.options.opts) {
|
1961
|
+
options = todo.options.opts;
|
1962
|
+
if (todo.options.url) {
|
1963
|
+
options.url = todo.options.url;
|
1964
|
+
}
|
1965
|
+
}
|
1966
|
+
// -- end --
|
1967
|
+
options.map = map;
|
1968
|
+
if (googleVersionMin("3.10")) {
|
1969
|
+
obj = new defaults.classes.KmlLayer(options);
|
1970
|
+
} else {
|
1971
|
+
obj = new defaults.classes.KmlLayer(options.url, options);
|
1972
|
+
}
|
1973
|
+
objs.push(obj);
|
1974
|
+
id = store.add({todo:todo}, "kmllayer", obj);
|
1975
|
+
attachEvents($this, {todo:todo}, obj, id);
|
1976
|
+
});
|
1977
|
+
manageEnd(args, multiple ? objs : objs[0]);
|
1978
|
+
};
|
1979
|
+
|
1980
|
+
/**
|
1981
|
+
* add a fix panel
|
1982
|
+
**/
|
1983
|
+
this.panel = function(args){
|
1984
|
+
newMap();
|
1985
|
+
var id, x= 0, y=0, $content,
|
1986
|
+
$div = $(document.createElement("div"));
|
1987
|
+
|
1988
|
+
$div.css({
|
1989
|
+
position: "absolute",
|
1990
|
+
zIndex: 1000,
|
1991
|
+
visibility: "hidden"
|
1992
|
+
});
|
1993
|
+
|
1994
|
+
if (args.opts.content){
|
1995
|
+
$content = $(args.opts.content);
|
1996
|
+
$div.append($content);
|
1997
|
+
$this.first().prepend($div);
|
1998
|
+
|
1999
|
+
if (args.opts.left !== undef){
|
2000
|
+
x = args.opts.left;
|
2001
|
+
} else if (args.opts.right !== undef){
|
2002
|
+
x = $this.width() - $content.width() - args.opts.right;
|
2003
|
+
} else if (args.opts.center){
|
2004
|
+
x = ($this.width() - $content.width()) / 2;
|
2005
|
+
}
|
2006
|
+
|
2007
|
+
if (args.opts.top !== undef){
|
2008
|
+
y = args.opts.top;
|
2009
|
+
} else if (args.opts.bottom !== undef){
|
2010
|
+
y = $this.height() - $content.height() - args.opts.bottom;
|
2011
|
+
} else if (args.opts.middle){
|
2012
|
+
y = ($this.height() - $content.height()) / 2
|
2013
|
+
}
|
2014
|
+
|
2015
|
+
$div.css({
|
2016
|
+
top: y,
|
2017
|
+
left: x,
|
2018
|
+
visibility: "visible"
|
2019
|
+
});
|
2020
|
+
}
|
2021
|
+
|
2022
|
+
id = store.add(args, "panel", $div);
|
2023
|
+
manageEnd(args, $div, id);
|
2024
|
+
$div = null; // memory leak
|
2025
|
+
};
|
2026
|
+
|
2027
|
+
/**
|
2028
|
+
* Create an InternalClusterer object
|
2029
|
+
**/
|
2030
|
+
function createClusterer(raw){
|
2031
|
+
var internalClusterer = new InternalClusterer($this, map, raw),
|
2032
|
+
todo = {},
|
2033
|
+
styles = {},
|
2034
|
+
thresholds = [],
|
2035
|
+
isInt = /^[0-9]+$/,
|
2036
|
+
calculator,
|
2037
|
+
k;
|
2038
|
+
|
2039
|
+
for(k in raw){
|
2040
|
+
if (isInt.test(k)){
|
2041
|
+
thresholds.push(1*k); // cast to int
|
2042
|
+
styles[k] = raw[k];
|
2043
|
+
styles[k].width = styles[k].width || 0;
|
2044
|
+
styles[k].height = styles[k].height || 0;
|
2045
|
+
} else {
|
2046
|
+
todo[k] = raw[k];
|
2047
|
+
}
|
2048
|
+
}
|
2049
|
+
thresholds.sort(function (a, b) { return a > b});
|
2050
|
+
|
2051
|
+
// external calculator
|
2052
|
+
if (todo.calculator){
|
2053
|
+
calculator = function(indexes){
|
2054
|
+
var data = [];
|
2055
|
+
$.each(indexes, function(i, index){
|
2056
|
+
data.push(internalClusterer.value(index));
|
2057
|
+
});
|
2058
|
+
return todo.calculator.apply($this, [data]);
|
2059
|
+
};
|
2060
|
+
} else {
|
2061
|
+
calculator = function(indexes){
|
2062
|
+
return indexes.length;
|
2063
|
+
};
|
2064
|
+
}
|
2065
|
+
|
2066
|
+
// set error function
|
2067
|
+
internalClusterer.error(function(){
|
2068
|
+
error.apply(that, arguments);
|
2069
|
+
});
|
2070
|
+
|
2071
|
+
// set display function
|
2072
|
+
internalClusterer.display(function(cluster){
|
2073
|
+
var i, style, atodo, obj, offset,
|
2074
|
+
cnt = calculator(cluster.indexes);
|
2075
|
+
|
2076
|
+
// look for the style to use
|
2077
|
+
if (raw.force || cnt > 1) {
|
2078
|
+
for(i = 0; i < thresholds.length; i++) {
|
2079
|
+
if (thresholds[i] <= cnt) {
|
2080
|
+
style = styles[thresholds[i]];
|
2081
|
+
}
|
2082
|
+
}
|
2083
|
+
}
|
2084
|
+
|
2085
|
+
if (style){
|
2086
|
+
offset = style.offset || [-style.width/2, -style.height/2];
|
2087
|
+
// create a custom overlay command
|
2088
|
+
// nb: 2 extends are faster that a deeper extend
|
2089
|
+
atodo = $.extend({}, todo);
|
2090
|
+
atodo.options = $.extend({
|
2091
|
+
pane: "overlayLayer",
|
2092
|
+
content:style.content ? style.content.replace("CLUSTER_COUNT", cnt) : "",
|
2093
|
+
offset:{
|
2094
|
+
x: ("x" in offset ? offset.x : offset[0]) || 0,
|
2095
|
+
y: ("y" in offset ? offset.y : offset[1]) || 0
|
2096
|
+
}
|
2097
|
+
},
|
2098
|
+
todo.options || {});
|
2099
|
+
|
2100
|
+
obj = that.overlay({todo:atodo, opts:atodo.options, latLng:toLatLng(cluster)}, true);
|
2101
|
+
|
2102
|
+
atodo.options.pane = "floatShadow";
|
2103
|
+
atodo.options.content = $(document.createElement("div")).width(style.width+"px").height(style.height+"px").css({cursor:"pointer"});
|
2104
|
+
shadow = that.overlay({todo:atodo, opts:atodo.options, latLng:toLatLng(cluster)}, true);
|
2105
|
+
|
2106
|
+
// store data to the clusterer
|
2107
|
+
todo.data = {
|
2108
|
+
latLng: toLatLng(cluster),
|
2109
|
+
markers:[]
|
2110
|
+
};
|
2111
|
+
$.each(cluster.indexes, function(i, index){
|
2112
|
+
todo.data.markers.push(internalClusterer.value(index));
|
2113
|
+
if (internalClusterer.markerIsSet(index)){
|
2114
|
+
internalClusterer.marker(index).setMap(null);
|
2115
|
+
}
|
2116
|
+
});
|
2117
|
+
attachEvents($this, {todo:todo}, shadow, undef, {main:obj, shadow:shadow});
|
2118
|
+
internalClusterer.store(cluster, obj, shadow);
|
2119
|
+
} else {
|
2120
|
+
$.each(cluster.indexes, function(i, index){
|
2121
|
+
internalClusterer.marker(index).setMap(map);
|
2122
|
+
});
|
2123
|
+
}
|
2124
|
+
});
|
2125
|
+
|
2126
|
+
return internalClusterer;
|
2127
|
+
}
|
2128
|
+
/**
|
2129
|
+
* add a marker
|
2130
|
+
**/
|
2131
|
+
this.marker = function(args){
|
2132
|
+
var multiple = "values" in args.todo,
|
2133
|
+
init = !map;
|
2134
|
+
if (!multiple){
|
2135
|
+
args.opts.position = args.latLng || toLatLng(args.opts.position);
|
2136
|
+
args.todo.values = [{options:args.opts}];
|
2137
|
+
}
|
2138
|
+
if (!args.todo.values.length){
|
2139
|
+
manageEnd(args, false);
|
2140
|
+
return;
|
2141
|
+
}
|
2142
|
+
if (init){
|
2143
|
+
newMap();
|
2144
|
+
}
|
2145
|
+
|
2146
|
+
if (args.todo.cluster && !map.getBounds()){ // map not initialised => bounds not available : wait for map if clustering feature is required
|
2147
|
+
google.maps.event.addListenerOnce(map, "bounds_changed", function() { that.marker.apply(that, [args]); });
|
2148
|
+
return;
|
2149
|
+
}
|
2150
|
+
if (args.todo.cluster){
|
2151
|
+
var clusterer, internalClusterer;
|
2152
|
+
if (args.todo.cluster instanceof Clusterer){
|
2153
|
+
clusterer = args.todo.cluster;
|
2154
|
+
internalClusterer = store.getById(clusterer.id(), true);
|
2155
|
+
} else {
|
2156
|
+
internalClusterer = createClusterer(args.todo.cluster);
|
2157
|
+
clusterer = new Clusterer(globalId(args.todo.id, true), internalClusterer);
|
2158
|
+
store.add(args, "clusterer", clusterer, internalClusterer);
|
2159
|
+
}
|
2160
|
+
internalClusterer.beginUpdate();
|
2161
|
+
|
2162
|
+
$.each(args.todo.values, function(i, value){
|
2163
|
+
var todo = tuple(args, value);
|
2164
|
+
todo.options.position = todo.options.position ? toLatLng(todo.options.position) : toLatLng(value);
|
2165
|
+
todo.options.map = map;
|
2166
|
+
if (init){
|
2167
|
+
map.setCenter(todo.options.position);
|
2168
|
+
init = false;
|
2169
|
+
}
|
2170
|
+
internalClusterer.add(todo, value);
|
2171
|
+
});
|
2172
|
+
|
2173
|
+
internalClusterer.endUpdate();
|
2174
|
+
manageEnd(args, clusterer);
|
2175
|
+
|
2176
|
+
} else {
|
2177
|
+
var objs = [];
|
2178
|
+
$.each(args.todo.values, function(i, value){
|
2179
|
+
var id, obj, todo = tuple(args, value);
|
2180
|
+
todo.options.position = todo.options.position ? toLatLng(todo.options.position) : toLatLng(value);
|
2181
|
+
todo.options.map = map;
|
2182
|
+
if (init){
|
2183
|
+
map.setCenter(todo.options.position);
|
2184
|
+
init = false;
|
2185
|
+
}
|
2186
|
+
obj = new defaults.classes.Marker(todo.options);
|
2187
|
+
objs.push(obj);
|
2188
|
+
id = store.add({todo:todo}, "marker", obj);
|
2189
|
+
attachEvents($this, {todo:todo}, obj, id);
|
2190
|
+
});
|
2191
|
+
manageEnd(args, multiple ? objs : objs[0]);
|
2192
|
+
}
|
2193
|
+
};
|
2194
|
+
|
2195
|
+
/**
|
2196
|
+
* return a route
|
2197
|
+
**/
|
2198
|
+
this.getroute = function(args){
|
2199
|
+
args.opts.origin = toLatLng(args.opts.origin, true);
|
2200
|
+
args.opts.destination = toLatLng(args.opts.destination, true);
|
2201
|
+
directionsService().route(
|
2202
|
+
args.opts,
|
2203
|
+
function(results, status) {
|
2204
|
+
callback(args, status == google.maps.DirectionsStatus.OK ? results : false, status);
|
2205
|
+
task.ack();
|
2206
|
+
}
|
2207
|
+
);
|
2208
|
+
};
|
2209
|
+
|
2210
|
+
/**
|
2211
|
+
* add a direction renderer
|
2212
|
+
**/
|
2213
|
+
this.directionsrenderer = function(args){
|
2214
|
+
args.opts.map = map;
|
2215
|
+
var id, obj = new google.maps.DirectionsRenderer(args.opts);
|
2216
|
+
if (args.todo.divId){
|
2217
|
+
obj.setPanel(document.getElementById(args.todo.divId));
|
2218
|
+
} else if (args.todo.container){
|
2219
|
+
obj.setPanel($(args.todo.container).get(0));
|
2220
|
+
}
|
2221
|
+
id = store.add(args, "directionsrenderer", obj);
|
2222
|
+
manageEnd(args, obj, id);
|
2223
|
+
};
|
2224
|
+
|
2225
|
+
/**
|
2226
|
+
* returns latLng of the user
|
2227
|
+
**/
|
2228
|
+
this.getgeoloc = function(args){
|
2229
|
+
manageEnd(args, args.latLng);
|
2230
|
+
};
|
2231
|
+
|
2232
|
+
/**
|
2233
|
+
* add a style
|
2234
|
+
**/
|
2235
|
+
this.styledmaptype = function(args){
|
2236
|
+
newMap();
|
2237
|
+
var obj = new defaults.classes.StyledMapType(args.todo.styles, args.opts);
|
2238
|
+
map.mapTypes.set(args.todo.id, obj);
|
2239
|
+
manageEnd(args, obj);
|
2240
|
+
};
|
2241
|
+
|
2242
|
+
/**
|
2243
|
+
* add an imageMapType
|
2244
|
+
**/
|
2245
|
+
this.imagemaptype = function(args){
|
2246
|
+
newMap();
|
2247
|
+
var obj = new defaults.classes.ImageMapType(args.opts);
|
2248
|
+
map.mapTypes.set(args.todo.id, obj);
|
2249
|
+
manageEnd(args, obj);
|
2250
|
+
};
|
2251
|
+
|
2252
|
+
/**
|
2253
|
+
* autofit a map using its overlays (markers, rectangles ...)
|
2254
|
+
**/
|
2255
|
+
this.autofit = function(args){
|
2256
|
+
var bounds = new google.maps.LatLngBounds();
|
2257
|
+
$.each(store.all(), function(i, obj){
|
2258
|
+
if (obj.getPosition){
|
2259
|
+
bounds.extend(obj.getPosition());
|
2260
|
+
} else if (obj.getBounds){
|
2261
|
+
bounds.extend(obj.getBounds().getNorthEast());
|
2262
|
+
bounds.extend(obj.getBounds().getSouthWest());
|
2263
|
+
} else if (obj.getPaths){
|
2264
|
+
obj.getPaths().forEach(function(path){
|
2265
|
+
path.forEach(function(latLng){
|
2266
|
+
bounds.extend(latLng);
|
2267
|
+
});
|
2268
|
+
});
|
2269
|
+
} else if (obj.getPath){
|
2270
|
+
obj.getPath().forEach(function(latLng){
|
2271
|
+
bounds.extend(latLng);""
|
2272
|
+
});
|
2273
|
+
} else if (obj.getCenter){
|
2274
|
+
bounds.extend(obj.getCenter());
|
2275
|
+
} else if (obj instanceof Clusterer){
|
2276
|
+
obj = store.getById(obj.id(), true);
|
2277
|
+
if (obj){
|
2278
|
+
obj.autofit(bounds);
|
2279
|
+
}
|
2280
|
+
}
|
2281
|
+
});
|
2282
|
+
|
2283
|
+
if (!bounds.isEmpty() && (!map.getBounds() || !map.getBounds().equals(bounds))){
|
2284
|
+
if ("maxZoom" in args.todo){
|
2285
|
+
// fitBouds Callback event => detect zoom level and check maxZoom
|
2286
|
+
google.maps.event.addListenerOnce(
|
2287
|
+
map,
|
2288
|
+
"bounds_changed",
|
2289
|
+
function() {
|
2290
|
+
if (this.getZoom() > args.todo.maxZoom){
|
2291
|
+
this.setZoom(args.todo.maxZoom);
|
2292
|
+
}
|
2293
|
+
}
|
2294
|
+
);
|
2295
|
+
}
|
2296
|
+
map.fitBounds(bounds);
|
2297
|
+
}
|
2298
|
+
manageEnd(args, true);
|
2299
|
+
};
|
2300
|
+
|
2301
|
+
/**
|
2302
|
+
* remove objects from a map
|
2303
|
+
**/
|
2304
|
+
this.clear = function(args){
|
2305
|
+
if (typeof args.todo === "string"){
|
2306
|
+
if (store.clearById(args.todo) || store.objClearById(args.todo)){
|
2307
|
+
manageEnd(args, true);
|
2308
|
+
return;
|
2309
|
+
}
|
2310
|
+
args.todo = {name:args.todo};
|
2311
|
+
}
|
2312
|
+
if (args.todo.id){
|
2313
|
+
$.each(array(args.todo.id), function(i, id){
|
2314
|
+
store.clearById(id) || store.objClearById(id);
|
2315
|
+
});
|
2316
|
+
} else {
|
2317
|
+
store.clear(array(args.todo.name), args.todo.last, args.todo.first, args.todo.tag);
|
2318
|
+
store.objClear(array(args.todo.name), args.todo.last, args.todo.first, args.todo.tag);
|
2319
|
+
}
|
2320
|
+
manageEnd(args, true);
|
2321
|
+
};
|
2322
|
+
|
2323
|
+
/**
|
2324
|
+
* run a function on each items selected
|
2325
|
+
**/
|
2326
|
+
this.exec = function(args){
|
2327
|
+
var that = this;
|
2328
|
+
$.each(array(args.todo.func), function(i, func){
|
2329
|
+
$.each(that.get(args.todo, true, args.todo.hasOwnProperty("full") ? args.todo.full : true), function(j, res){
|
2330
|
+
func.call($this, res);
|
2331
|
+
});
|
2332
|
+
});
|
2333
|
+
manageEnd(args, true);
|
2334
|
+
};
|
2335
|
+
|
2336
|
+
/**
|
2337
|
+
* return objects previously created
|
2338
|
+
**/
|
2339
|
+
this.get = function(args, direct, full){
|
2340
|
+
var name, res,
|
2341
|
+
todo = direct ? args : args.todo;
|
2342
|
+
if (!direct) {
|
2343
|
+
full = todo.full;
|
2344
|
+
}
|
2345
|
+
if (typeof todo === "string"){
|
2346
|
+
res = store.getById(todo, false, full) || store.objGetById(todo);
|
2347
|
+
if (res === false){
|
2348
|
+
name = todo;
|
2349
|
+
todo = {};
|
2350
|
+
}
|
2351
|
+
} else {
|
2352
|
+
name = todo.name;
|
2353
|
+
}
|
2354
|
+
if (name === "map"){
|
2355
|
+
res = map;
|
2356
|
+
}
|
2357
|
+
if (!res){
|
2358
|
+
res = [];
|
2359
|
+
if (todo.id){
|
2360
|
+
$.each(array(todo.id), function(i, id) {
|
2361
|
+
res.push(store.getById(id, false, full) || store.objGetById(id));
|
2362
|
+
});
|
2363
|
+
if (!$.isArray(todo.id)) {
|
2364
|
+
res = res[0];
|
2365
|
+
}
|
2366
|
+
} else {
|
2367
|
+
$.each(name ? array(name) : [undef], function(i, aName) {
|
2368
|
+
var result;
|
2369
|
+
if (todo.first){
|
2370
|
+
result = store.get(aName, false, todo.tag, full);
|
2371
|
+
if (result) res.push(result);
|
2372
|
+
} else if (todo.all){
|
2373
|
+
$.each(store.all(aName, todo.tag, full), function(i, result){
|
2374
|
+
res.push(result);
|
2375
|
+
});
|
2376
|
+
} else {
|
2377
|
+
result = store.get(aName, true, todo.tag, full);
|
2378
|
+
if (result) res.push(result);
|
2379
|
+
}
|
2380
|
+
});
|
2381
|
+
if (!todo.all && !$.isArray(name)) {
|
2382
|
+
res = res[0];
|
2383
|
+
}
|
2384
|
+
}
|
2385
|
+
}
|
2386
|
+
res = $.isArray(res) || !todo.all ? res : [res];
|
2387
|
+
if (direct){
|
2388
|
+
return res;
|
2389
|
+
} else {
|
2390
|
+
manageEnd(args, res);
|
2391
|
+
}
|
2392
|
+
};
|
2393
|
+
|
2394
|
+
/**
|
2395
|
+
* return the distance between an origin and a destination
|
2396
|
+
*
|
2397
|
+
**/
|
2398
|
+
this.getdistance = function(args){
|
2399
|
+
var i;
|
2400
|
+
args.opts.origins = array(args.opts.origins);
|
2401
|
+
for(i=0; i<args.opts.origins.length; i++){
|
2402
|
+
args.opts.origins[i] = toLatLng(args.opts.origins[i], true);
|
2403
|
+
}
|
2404
|
+
args.opts.destinations = array(args.opts.destinations);
|
2405
|
+
for(i=0; i<args.opts.destinations.length; i++){
|
2406
|
+
args.opts.destinations[i] = toLatLng(args.opts.destinations[i], true);
|
2407
|
+
}
|
2408
|
+
distanceMatrixService().getDistanceMatrix(
|
2409
|
+
args.opts,
|
2410
|
+
function(results, status) {
|
2411
|
+
callback(args, status === google.maps.DistanceMatrixStatus.OK ? results : false, status);
|
2412
|
+
task.ack();
|
2413
|
+
}
|
2414
|
+
);
|
2415
|
+
};
|
2416
|
+
|
2417
|
+
/**
|
2418
|
+
* trigger events on the map
|
2419
|
+
**/
|
2420
|
+
this.trigger = function(args){
|
2421
|
+
if (typeof args.todo === "string"){
|
2422
|
+
google.maps.event.trigger(map, args.todo);
|
2423
|
+
} else {
|
2424
|
+
var options = [map, args.todo.eventName];
|
2425
|
+
if (args.todo.var_args) {
|
2426
|
+
$.each(args.todo.var_args, function(i, v){
|
2427
|
+
options.push(v);
|
2428
|
+
});
|
2429
|
+
}
|
2430
|
+
google.maps.event.trigger.apply(google.maps.event, options);
|
2431
|
+
}
|
2432
|
+
callback(args);
|
2433
|
+
task.ack();
|
2434
|
+
};
|
2435
|
+
}
|
2436
|
+
|
2437
|
+
/**
|
2438
|
+
* Return true if get is a direct call
|
2439
|
+
* it means :
|
2440
|
+
* - get is the only key
|
2441
|
+
* - get has no callback
|
2442
|
+
* @param obj {Object} The request to check
|
2443
|
+
* @return {Boolean}
|
2444
|
+
*/
|
2445
|
+
function isDirectGet(obj) {
|
2446
|
+
var k;
|
2447
|
+
if (!typeof obj === "object" || !obj.hasOwnProperty("get")){
|
2448
|
+
return false;
|
2449
|
+
}
|
2450
|
+
for(k in obj) {
|
2451
|
+
if (k !== "get") {
|
2452
|
+
return false;
|
2453
|
+
}
|
2454
|
+
}
|
2455
|
+
return !obj.get.hasOwnProperty("callback");
|
2456
|
+
}
|
2457
|
+
|
2458
|
+
//-----------------------------------------------------------------------//
|
2459
|
+
// jQuery plugin
|
2460
|
+
//-----------------------------------------------------------------------//
|
2461
|
+
|
2462
|
+
$.fn.gmap3 = function(){
|
2463
|
+
var i, list = [], empty = true, results = [];
|
2464
|
+
|
2465
|
+
// init library
|
2466
|
+
initDefaults();
|
2467
|
+
|
2468
|
+
// store all arguments in a todo list
|
2469
|
+
for(i=0; i<arguments.length; i++){
|
2470
|
+
if (arguments[i]){
|
2471
|
+
list.push(arguments[i]);
|
2472
|
+
}
|
2473
|
+
}
|
2474
|
+
|
2475
|
+
// resolve empty call - run init
|
2476
|
+
if (!list.length) {
|
2477
|
+
list.push("map");
|
2478
|
+
}
|
2479
|
+
|
2480
|
+
// loop on each jQuery object
|
2481
|
+
$.each(this, function() {
|
2482
|
+
var $this = $(this), gmap3 = $this.data("gmap3");
|
2483
|
+
empty = false;
|
2484
|
+
if (!gmap3){
|
2485
|
+
gmap3 = new Gmap3($this);
|
2486
|
+
$this.data("gmap3", gmap3);
|
2487
|
+
}
|
2488
|
+
if (list.length === 1 && (list[0] === "get" || isDirectGet(list[0]))){
|
2489
|
+
if (list[0] === "get") {
|
2490
|
+
results.push(gmap3.get("map", true));
|
2491
|
+
} else {
|
2492
|
+
results.push(gmap3.get(list[0].get, true, list[0].get.full));
|
2493
|
+
}
|
2494
|
+
} else {
|
2495
|
+
gmap3._plan(list);
|
2496
|
+
}
|
2497
|
+
});
|
2498
|
+
|
2499
|
+
// return for direct call only
|
2500
|
+
if (results.length){
|
2501
|
+
if (results.length === 1){ // 1 css selector
|
2502
|
+
return results[0];
|
2503
|
+
} else {
|
2504
|
+
return results;
|
2505
|
+
}
|
2506
|
+
}
|
2507
|
+
|
2508
|
+
return this;
|
2509
|
+
}
|
2510
|
+
|
2511
|
+
})(jQuery);
|