1
|
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
|
2
|
* full list of contributors). Published under the 2-clause BSD license.
|
3
|
* See license.txt in the OpenLayers distribution or repository for the
|
4
|
* full text of the license. */
|
5
|
|
6
|
/**
|
7
|
* @requires OpenLayers/Control.js
|
8
|
*/
|
9
|
|
10
|
/**
|
11
|
* Class: OpenLayers.Control.ScaleLine
|
12
|
* The ScaleLine displays a small line indicator representing the current
|
13
|
* map scale on the map. By default it is drawn in the lower left corner of
|
14
|
* the map.
|
15
|
*
|
16
|
* Inherits from:
|
17
|
* - <OpenLayers.Control>
|
18
|
*
|
19
|
* Is a very close copy of:
|
20
|
* - <OpenLayers.Control.Scale>
|
21
|
*/
|
22
|
OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
|
23
|
|
24
|
/**
|
25
|
* Property: maxWidth
|
26
|
* {Integer} Maximum width of the scale line in pixels. Default is 100.
|
27
|
*/
|
28
|
maxWidth: 100,
|
29
|
|
30
|
/**
|
31
|
* Property: topOutUnits
|
32
|
* {String} Units for zoomed out on top bar. Default is km.
|
33
|
*/
|
34
|
topOutUnits: "km",
|
35
|
|
36
|
/**
|
37
|
* Property: topInUnits
|
38
|
* {String} Units for zoomed in on top bar. Default is m.
|
39
|
*/
|
40
|
topInUnits: "m",
|
41
|
|
42
|
/**
|
43
|
* Property: bottomOutUnits
|
44
|
* {String} Units for zoomed out on bottom bar. Default is mi.
|
45
|
*/
|
46
|
bottomOutUnits: "mi",
|
47
|
|
48
|
/**
|
49
|
* Property: bottomInUnits
|
50
|
* {String} Units for zoomed in on bottom bar. Default is ft.
|
51
|
*/
|
52
|
bottomInUnits: "ft",
|
53
|
|
54
|
/**
|
55
|
* Property: eTop
|
56
|
* {DOMElement}
|
57
|
*/
|
58
|
eTop: null,
|
59
|
|
60
|
/**
|
61
|
* Property: eBottom
|
62
|
* {DOMElement}
|
63
|
*/
|
64
|
eBottom:null,
|
65
|
|
66
|
/**
|
67
|
* APIProperty: geodesic
|
68
|
* {Boolean} Use geodesic measurement. Default is false. The recommended
|
69
|
* setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to
|
70
|
* true, the scale will be calculated based on the horizontal size of the
|
71
|
* pixel in the center of the map viewport.
|
72
|
*/
|
73
|
geodesic: false,
|
74
|
|
75
|
/**
|
76
|
* Constructor: OpenLayers.Control.ScaleLine
|
77
|
* Create a new scale line control.
|
78
|
*
|
79
|
* Parameters:
|
80
|
* options - {Object} An optional object whose properties will be used
|
81
|
* to extend the control.
|
82
|
*/
|
83
|
|
84
|
/**
|
85
|
* Method: draw
|
86
|
*
|
87
|
* Returns:
|
88
|
* {DOMElement}
|
89
|
*/
|
90
|
draw: function() {
|
91
|
OpenLayers.Control.prototype.draw.apply(this, arguments);
|
92
|
if (!this.eTop) {
|
93
|
// stick in the top bar
|
94
|
this.eTop = document.createElement("div");
|
95
|
this.eTop.className = this.displayClass + "Top";
|
96
|
var theLen = this.topInUnits.length;
|
97
|
this.div.appendChild(this.eTop);
|
98
|
if((this.topOutUnits == "") || (this.topInUnits == "")) {
|
99
|
this.eTop.style.visibility = "hidden";
|
100
|
} else {
|
101
|
this.eTop.style.visibility = "visible";
|
102
|
}
|
103
|
|
104
|
// and the bottom bar
|
105
|
this.eBottom = document.createElement("div");
|
106
|
this.eBottom.className = this.displayClass + "Bottom";
|
107
|
this.div.appendChild(this.eBottom);
|
108
|
if((this.bottomOutUnits == "") || (this.bottomInUnits == "")) {
|
109
|
this.eBottom.style.visibility = "hidden";
|
110
|
} else {
|
111
|
this.eBottom.style.visibility = "visible";
|
112
|
}
|
113
|
}
|
114
|
this.map.events.register('moveend', this, this.update);
|
115
|
this.update();
|
116
|
return this.div;
|
117
|
},
|
118
|
|
119
|
/**
|
120
|
* Method: getBarLen
|
121
|
* Given a number, round it down to the nearest 1,2,5 times a power of 10.
|
122
|
* That seems a fairly useful set of number groups to use.
|
123
|
*
|
124
|
* Parameters:
|
125
|
* maxLen - {float} the number we're rounding down from
|
126
|
*
|
127
|
* Returns:
|
128
|
* {Float} the rounded number (less than or equal to maxLen)
|
129
|
*/
|
130
|
getBarLen: function(maxLen) {
|
131
|
// nearest power of 10 lower than maxLen
|
132
|
var digits = parseInt(Math.log(maxLen) / Math.log(10));
|
133
|
var pow10 = Math.pow(10, digits);
|
134
|
|
135
|
// ok, find first character
|
136
|
var firstChar = parseInt(maxLen / pow10);
|
137
|
|
138
|
// right, put it into the correct bracket
|
139
|
var barLen;
|
140
|
if(firstChar > 5) {
|
141
|
barLen = 5;
|
142
|
} else if(firstChar > 2) {
|
143
|
barLen = 2;
|
144
|
} else {
|
145
|
barLen = 1;
|
146
|
}
|
147
|
|
148
|
// scale it up the correct power of 10
|
149
|
return barLen * pow10;
|
150
|
},
|
151
|
|
152
|
/**
|
153
|
* Method: update
|
154
|
* Update the size of the bars, and the labels they contain.
|
155
|
*/
|
156
|
update: function() {
|
157
|
var res = this.map.getResolution();
|
158
|
if (!res) {
|
159
|
return;
|
160
|
}
|
161
|
|
162
|
var curMapUnits = this.map.getUnits();
|
163
|
var inches = OpenLayers.INCHES_PER_UNIT;
|
164
|
|
165
|
// convert maxWidth to map units
|
166
|
var maxSizeData = this.maxWidth * res * inches[curMapUnits];
|
167
|
var geodesicRatio = 1;
|
168
|
if(this.geodesic === true) {
|
169
|
var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w ||
|
170
|
0.000001) * this.maxWidth;
|
171
|
var maxSizeKilometers = maxSizeData / inches["km"];
|
172
|
geodesicRatio = maxSizeGeodesic / maxSizeKilometers;
|
173
|
maxSizeData *= geodesicRatio;
|
174
|
}
|
175
|
|
176
|
// decide whether to use large or small scale units
|
177
|
var topUnits;
|
178
|
var bottomUnits;
|
179
|
if(maxSizeData > 100000) {
|
180
|
topUnits = this.topOutUnits;
|
181
|
bottomUnits = this.bottomOutUnits;
|
182
|
} else {
|
183
|
topUnits = this.topInUnits;
|
184
|
bottomUnits = this.bottomInUnits;
|
185
|
}
|
186
|
|
187
|
// and to map units units
|
188
|
var topMax = maxSizeData / inches[topUnits];
|
189
|
var bottomMax = maxSizeData / inches[bottomUnits];
|
190
|
|
191
|
// now trim this down to useful block length
|
192
|
var topRounded = this.getBarLen(topMax);
|
193
|
var bottomRounded = this.getBarLen(bottomMax);
|
194
|
|
195
|
// and back to display units
|
196
|
topMax = topRounded / inches[curMapUnits] * inches[topUnits];
|
197
|
bottomMax = bottomRounded / inches[curMapUnits] * inches[bottomUnits];
|
198
|
|
199
|
// and to pixel units
|
200
|
var topPx = topMax / res / geodesicRatio;
|
201
|
var bottomPx = bottomMax / res / geodesicRatio;
|
202
|
|
203
|
// now set the pixel widths
|
204
|
// and the values inside them
|
205
|
|
206
|
if (this.eBottom.style.visibility == "visible"){
|
207
|
this.eBottom.style.width = Math.round(bottomPx) + "px";
|
208
|
this.eBottom.innerHTML = bottomRounded + " " + bottomUnits ;
|
209
|
}
|
210
|
|
211
|
if (this.eTop.style.visibility == "visible"){
|
212
|
this.eTop.style.width = Math.round(topPx) + "px";
|
213
|
this.eTop.innerHTML = topRounded + " " + topUnits;
|
214
|
}
|
215
|
|
216
|
},
|
217
|
|
218
|
CLASS_NAME: "OpenLayers.Control.ScaleLine"
|
219
|
});
|
220
|
|