source: extensions/rv_gmaps/trunk/template/data_loader.js @ 12706

Last change on this file since 12706 was 12706, checked in by rvelices, 12 years ago

rv_gmaps use places autocomplete + added new markers + better algo for displaying markers

  • Property svn:eol-style set to LF
File size: 6.0 KB
Line 
1function PwgDataLoader( map, opts )
2{
3        this._map = map;
4        this.options = jQuery.fn.extend(
5                {
6                        reload_data_timeout: 200,
7                        rectangle_of_confusion: new google.maps.Size(16,32)
8                }
9                , opts || {} );
10        this.options.rectangle_of_confusion = new google.maps.Size( this.options.rectangle_of_confusion.width, this.options.rectangle_of_confusion.height );
11        if (this.options.rectangle_of_confusion.width<16) this.options.rectangle_of_confusion.width=16;
12        if (this.options.rectangle_of_confusion.height<16) this.options.rectangle_of_confusion.height=16;
13}
14
15
16// returns the number of digits (between 0 and 6) to round a lat/lon so that it does not vary by more than factor*pow(-exp)
17getLatLonDigits = function(d, factor, exp)
18{
19        if (d<0) return getLatLonDigits(-d,factor,exp);
20        var digits = Math.ceil( exp - Math.log(d*factor)/Math.LN10 );
21        return digits<0 ? 0 : (digits>6 ? 6 : digits);
22}
23
24Math.roundN = function(d, digits) { var c = Math.pow(10,digits); return Math.round(d*c)/c; }
25
26
27PwgDataLoader.prototype =  {
28
29
30_urlMapData: null,
31_timerReloadData: null,
32_dataLoading: false,
33
34_previousLoadDataReq : {box: null, zoom:0, resultBounds:null},
35
36start: function(urlMapData)
37{
38        this._urlMapData = urlMapData;
39        google.maps.event.bind( this._map, "movestart", this, this.clearTimerReloadData );
40        google.maps.event.bind( this._map, "idle", this, this._onIdle );
41        //this._loadData();
42},
43
44terminate: function()
45{
46        this.clearTimerReloadData();
47        this._map = null;
48},
49
50clearTimerReloadData : function()
51{
52        if (this._timerReloadData)
53        {
54                clearTimeout( this._timerReloadData );
55                this._timerReloadData = null;
56                return true;
57        }
58        return false;
59},
60
61_onIdle: function()
62{
63        this.clearTimerReloadData();
64        this._timerReloadData = setTimeout(  pwgBind(this, this._onTimeoutLoadData), this.options.reload_data_timeout );
65},
66
67
68_onTimeoutLoadData: function ()
69{
70        if (this._dataLoading) return; // still in progress
71        this.clearTimerReloadData();
72        this._loadData();
73},
74
75_loadData: function()
76{
77        var bounds = new google.maps.LatLngBounds( this._map.getBounds().getSouthWest(), this._map.getBounds().getNorthEast() );
78       
79        //BEGIN BUG in maps api as of v3.7 - when map wraps horizontally more than 360 deg - the getBounds is wrong
80        var isOver = false;
81        if (bounds.getSouthWest().lng() < bounds.getNorthEast().lng())
82        {
83                if ( this._map.getCenter().lng()<bounds.getSouthWest().lng() || this._map.getCenter().lng()>bounds.getNorthEast().lng() )
84                {
85                        isOver = true;
86                }
87        }
88        else if ( this._map.getCenter().lng()>bounds.getNorthEast().lng() && this._map.getCenter().lng()<bounds.getSouthWest().lng() )
89        {
90                isOver = true;
91        }
92        if (!isOver)
93        {//very emprical tests
94                if (this._map.getDiv().offsetWidth / this._map.getDiv().offsetHeight > 1.3
95                                && this._map.getZoom()<3
96                                && bounds.getSouthWest().lat() < -50
97                                && bounds.getNorthEast().lat() > 50)
98                {
99                        isOver = true;
100                }
101        }
102       
103        if (isOver)
104                bounds = new google.maps.LatLngBounds( new google.maps.LatLng(this._map.getBounds().getSouthWest().lat(),-179.9), new google.maps.LatLng(this._map.getBounds().getNorthEast().lat(), 179.9) );
105        //END bug
106       
107       
108        var latRange = bounds.toSpan().lat();
109        var latPrec = latRange * this.options.rectangle_of_confusion.height / this._map.getDiv().offsetHeight;
110
111        var lonRange = bounds.toSpan().lng();
112        var lonPrec = ( lonRange>=0 ? lonRange : 360-lonRange )* this.options.rectangle_of_confusion.width / this._map.getDiv().offsetWidth;
113
114        if ( this._previousLoadDataReq.box!=null )
115        { // not the first time
116                if ( this._previousLoadDataReq.box.contains( bounds.getNorthEast() )
117                                        && this._previousLoadDataReq.box.contains( bounds.getSouthWest() ))
118                {
119                        if ( this._previousLoadDataReq.resultBounds == null )
120                                return; // no images here
121                        if ( this._map.getZoom() <= this._previousLoadDataReq.zoom )
122                                return;
123                }
124        }
125
126        var nd=0, sd=0, ed=0, wd=0;
127        /*if ( !bounds.isFullLat() )*/
128        {
129                nd = latRange*0.12;
130                sd = latRange*0.04;
131        }
132        /*if ( !bounds.isFullLng() )*/
133        {
134                ed = lonRange*0.09;
135                wd = lonRange*0.07;
136        }
137        var digits = Math.max( getLatLonDigits(latRange,4,2), getLatLonDigits(lonRange,4,2) );
138        var box = new google.maps.LatLngBounds( bounds.getSouthWest(), bounds.getNorthEast() );
139        box.extend( new google.maps.LatLng( Math.roundN(bounds.getSouthWest().lat()-sd,digits), Math.roundN( bounds.getSouthWest().lng()-wd,digits ) ) );
140        box.extend( new google.maps.LatLng( Math.roundN(bounds.getNorthEast().lat()+nd,digits), Math.roundN( bounds.getNorthEast().lng()+ed,digits) ) );
141
142        var url = this._urlMapData;
143        url += "&box=" + box.getSouthWest().toUrlValue(5) + "," + box.getNorthEast().toUrlValue(5);
144        url += "&lap=" +  Math.roundN( latPrec, getLatLonDigits(latPrec,1,1) ).toString();
145        url += "&lop=" +  Math.roundN( lonPrec, getLatLonDigits(lonPrec,1,1) ).toString();
146
147        if (document.is_debug) {
148                glog("sd="+sd+" wd="+wd+" nd="+nd+" ed="+ed);
149                glog( url );
150        }
151
152        this._previousLoadDataReq.box = box;
153        this._previousLoadDataReq.zoom = this._map.getZoom();
154        this._previousLoadDataReq.resultBounds = null;
155        this._dataLoading = true;
156
157        try {
158                google.maps.event.trigger( this, "dataloading" );
159                jQuery.ajax( {
160                        url: url,
161                        success: pwgBind(this, this._onAjaxSuccess),
162                        error: pwgBind(this, this._onAjaxError),
163                        });
164        }
165        catch (e) {
166                this._dataLoading = false;
167                this._previousLoadDataReq.box=null;
168                google.maps.event.trigger( this, "dataloadfailed", 600, e );
169        }
170},
171
172_onAjaxSuccess: function(data, textStatus, xhr)
173{
174        var resp;
175        try
176        {
177                eval('resp = ' + data);
178                if (resp.nb_items == undefined)
179                        throw new Error( "DATA DECODING ERROR" );
180                this._previousLoadDataReq.resultBounds = resp.bounds;
181                if (document.is_debug && resp.debug) glog( resp.debug );
182                google.maps.event.trigger( this, "dataloaded", resp );
183        }
184        catch (e)       {
185                this._previousLoadDataReq.box=null;
186                google.maps.event.trigger( this, "dataloadfailed", responseCode, e );
187                var s = e.message;
188                s += '\n' + data.substr(0,1000);
189                alert( s );
190        }
191        finally {
192                this._dataLoading = false;
193        }
194},
195
196_onAjaxError: function(xhr, textStatus, exc)
197{
198        try {
199                google.maps.event.trigger( this, "dataloadfailed", textStatus + xhr.status, exc );
200        }
201        catch (e) {
202        }
203        finally {
204                this._dataLoading = false;
205        }
206},
207
208}
Note: See TracBrowser for help on using the repository browser.