1 |
3032
|
perry
|
/*
|
2 |
4307
|
leinfelder
|
Author: Patrice G. Cappelaere (Got library from Geoserver)
|
3 |
3032
|
perry
|
License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
|
4 |
|
|
|
5 |
4307
|
leinfelder
|
$Id: MGRS.js 2546 2007-01-23 12:07:39Z gjvoosten $
|
6 |
3032
|
perry
|
*/
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
function MGRS() {
|
10 |
|
|
/**
|
11 |
|
|
* UTM zones are grouped, and assigned to one of a group of 6
|
12 |
|
|
* sets.
|
13 |
|
|
*/
|
14 |
|
|
var NUM_100K_SETS = 6;
|
15 |
|
|
|
16 |
|
|
/**
|
17 |
|
|
* The column letters (for easting) of the lower left value, per
|
18 |
|
|
* set.
|
19 |
|
|
*/
|
20 |
|
|
var SET_ORIGIN_COLUMN_LETTERS = new Array('A','J','S','A','J','S');
|
21 |
|
|
|
22 |
|
|
/**
|
23 |
|
|
* The row letters (for northing) of the lower left value, per
|
24 |
|
|
* set.
|
25 |
|
|
*/
|
26 |
|
|
var SET_ORIGIN_ROW_LETTERS = new Array('A','F','A','F','A','F');
|
27 |
|
|
|
28 |
|
|
/**
|
29 |
|
|
* The column letters (for easting) of the lower left value, per
|
30 |
|
|
* set,, for Bessel Ellipsoid.
|
31 |
|
|
*/
|
32 |
|
|
var BESSEL_SET_ORIGIN_COLUMN_LETTERS = new Array( 'A', 'J', 'S', 'A', 'J', 'S' );
|
33 |
|
|
|
34 |
|
|
/**
|
35 |
|
|
* The row letters (for northing) of the lower left value, per
|
36 |
|
|
* set, for Bessel Ellipsoid.
|
37 |
|
|
*/
|
38 |
|
|
var BESSEL_SET_ORIGIN_ROW_LETTERS = new Array( 'L', 'R', 'L', 'R', 'L', 'R' );
|
39 |
|
|
var SET_NORTHING_ROLLOVER = 20000000;
|
40 |
|
|
|
41 |
|
|
/**
|
42 |
|
|
* Use 5 digits for northing and easting values, for 1 meter
|
43 |
|
|
* accuracy of coordinate.
|
44 |
|
|
*/
|
45 |
|
|
|
46 |
|
|
var ACCURACY_1_METER = 5;
|
47 |
|
|
|
48 |
|
|
/**
|
49 |
|
|
* Use 4 digits for northing and easting values, for 10 meter
|
50 |
|
|
* accuracy of coordinate.
|
51 |
|
|
*/
|
52 |
|
|
var ACCURACY_10_METER = 4;
|
53 |
|
|
|
54 |
|
|
/**
|
55 |
|
|
* Use 3 digits for northing and easting values, for 100 meter
|
56 |
|
|
* accuracy of coordinate.
|
57 |
|
|
*/
|
58 |
|
|
var ACCURACY_100_METER = 3;
|
59 |
|
|
|
60 |
|
|
/**
|
61 |
|
|
* Use 2 digits for northing and easting values, for 1000 meter
|
62 |
|
|
* accuracy of coordinate.
|
63 |
|
|
*/
|
64 |
|
|
|
65 |
|
|
var ACCURACY_1000_METER = 2;
|
66 |
|
|
/**
|
67 |
|
|
* Use 1 digits for northing and easting values, for 10000 meter
|
68 |
|
|
* accuracy of coordinate.
|
69 |
|
|
*/
|
70 |
|
|
var ACCURACY_10000_METER = 1;
|
71 |
|
|
|
72 |
|
|
/** The set origin column letters to use. */
|
73 |
|
|
var originColumnLetters = SET_ORIGIN_COLUMN_LETTERS;
|
74 |
|
|
|
75 |
|
|
/** The set origin row letters to use. */
|
76 |
|
|
var originRowLetters = SET_ORIGIN_ROW_LETTERS;
|
77 |
|
|
|
78 |
|
|
var A = 65; //AsciiToNum('A');
|
79 |
|
|
var I = 73; //AsciiToNum('I');
|
80 |
|
|
var O = 79; //AsciiToNum('O');
|
81 |
|
|
var V = 86; //AsciiToNum('V');
|
82 |
|
|
var Z = 90; //AsciiToNum('Z');
|
83 |
|
|
|
84 |
|
|
var DEBUG = false;
|
85 |
|
|
|
86 |
|
|
/** The String holding the MGRS coordinate value. */
|
87 |
|
|
var mgrs_;
|
88 |
|
|
var lat_;
|
89 |
|
|
var lon_;
|
90 |
|
|
var radlat_ ;
|
91 |
|
|
var radlon_ ;
|
92 |
|
|
|
93 |
|
|
var northing_;
|
94 |
|
|
var easting_;
|
95 |
|
|
var zone_number_;
|
96 |
|
|
var zone_letter_;
|
97 |
|
|
|
98 |
|
|
/**
|
99 |
|
|
* Conversion of lat/lon to MGRS
|
100 |
|
|
*/
|
101 |
|
|
this.convert = function(latitude, longitude) {
|
102 |
|
|
lat_ = parseFloat(latitude);
|
103 |
|
|
lon_ = parseFloat(longitude);
|
104 |
|
|
radlat_ = degToRad(lat_);
|
105 |
|
|
radlon_ = degToRad(lon_);
|
106 |
|
|
|
107 |
|
|
LLtoUTM();
|
108 |
|
|
return formatMGRS();
|
109 |
|
|
}
|
110 |
|
|
|
111 |
|
|
function degToRad(deg) {
|
112 |
|
|
return (deg * (Math.PI / 180.0));
|
113 |
|
|
}
|
114 |
|
|
|
115 |
|
|
/**
|
116 |
|
|
* Converts a set of Longitude and Latitude co-ordinates to UTM
|
117 |
|
|
* given an ellipsoid
|
118 |
|
|
*
|
119 |
|
|
* @param ellip an ellipsoid definition.
|
120 |
|
|
* @param llpoint the coordinate to be converted
|
121 |
|
|
* @param utmpoint A UTMPoint instance to put the results in. If
|
122 |
|
|
* null, a new UTMPoint will be allocated.
|
123 |
|
|
* @return A UTM class instance containing the value of
|
124 |
|
|
* <code>null</code> if conversion failed. If you pass
|
125 |
|
|
* in a UTMPoint, it will be returned as well if
|
126 |
|
|
* successful.
|
127 |
|
|
*/
|
128 |
|
|
function LLtoUTM() {
|
129 |
|
|
var Lat = lat_;
|
130 |
|
|
var Long = lon_;
|
131 |
|
|
var a = 6378137.0; //ellip.radius;
|
132 |
|
|
var eccSquared = 0.00669438; //ellip.eccsq;
|
133 |
|
|
var k0 = 0.9996;
|
134 |
|
|
var LongOrigin;
|
135 |
|
|
var eccPrimeSquared;
|
136 |
|
|
var N, T, C, A, M;
|
137 |
|
|
var LatRad = radlat_;
|
138 |
|
|
var LongRad = radlon_;
|
139 |
|
|
var LongOriginRad;
|
140 |
|
|
var ZoneNumber;
|
141 |
|
|
// (int)
|
142 |
|
|
ZoneNumber = Math.floor((Long + 180) / 6) + 1;
|
143 |
|
|
|
144 |
|
|
//Make sure the longitude 180.00 is in Zone 60
|
145 |
|
|
if (Long == 180) {
|
146 |
|
|
ZoneNumber = 60;
|
147 |
|
|
}
|
148 |
|
|
|
149 |
|
|
// Special zone for Norway
|
150 |
|
|
if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) {
|
151 |
|
|
ZoneNumber = 32;
|
152 |
|
|
}
|
153 |
|
|
|
154 |
|
|
// Special zones for Svalbard
|
155 |
|
|
if (Lat >= 72.0 && Lat < 84.0) {
|
156 |
|
|
if (Long >= 0.0 && Long < 9.0)
|
157 |
|
|
ZoneNumber = 31;
|
158 |
|
|
else if (Long >= 9.0 && Long < 21.0)
|
159 |
|
|
ZoneNumber = 33;
|
160 |
|
|
else if (Long >= 21.0 && Long < 33.0)
|
161 |
|
|
ZoneNumber = 35;
|
162 |
|
|
else if (Long >= 33.0 && Long < 42.0)
|
163 |
|
|
ZoneNumber = 37;
|
164 |
|
|
}
|
165 |
|
|
|
166 |
|
|
LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin
|
167 |
|
|
// in middle of
|
168 |
|
|
// zone
|
169 |
|
|
LongOriginRad = degToRad(LongOrigin);
|
170 |
|
|
|
171 |
|
|
eccPrimeSquared = (eccSquared) / (1 - eccSquared);
|
172 |
|
|
|
173 |
|
|
N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad));
|
174 |
|
|
T = Math.tan(LatRad) * Math.tan(LatRad);
|
175 |
|
|
C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad);
|
176 |
|
|
A = Math.cos(LatRad) * (LongRad - LongOriginRad);
|
177 |
|
|
|
178 |
|
|
M = a
|
179 |
|
|
* ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5
|
180 |
|
|
* eccSquared * eccSquared * eccSquared / 256)
|
181 |
|
|
* LatRad
|
182 |
|
|
- (3 * eccSquared / 8 + 3 * eccSquared * eccSquared
|
183 |
|
|
/ 32 + 45 * eccSquared * eccSquared
|
184 |
|
|
* eccSquared / 1024)
|
185 |
|
|
* Math.sin(2 * LatRad)
|
186 |
|
|
+ (15 * eccSquared * eccSquared / 256 + 45 * eccSquared
|
187 |
|
|
* eccSquared * eccSquared / 1024)
|
188 |
|
|
* Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared
|
189 |
|
|
* eccSquared / 3072)
|
190 |
|
|
* Math.sin(6 * LatRad));
|
191 |
|
|
|
192 |
|
|
var UTMEasting = (k0
|
193 |
|
|
* N
|
194 |
|
|
* (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T
|
195 |
|
|
+ 72 * C - 58 * eccPrimeSquared)
|
196 |
|
|
* A * A * A * A * A / 120.0) + 500000.0);
|
197 |
|
|
|
198 |
|
|
var UTMNorthing = (k0 * (M + N
|
199 |
|
|
* Math.tan(LatRad)
|
200 |
|
|
* (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A
|
201 |
|
|
/ 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared)
|
202 |
|
|
* A * A * A * A * A * A / 720.0)));
|
203 |
|
|
if (Lat < 0.0) {
|
204 |
|
|
UTMNorthing += 10000000.0; //10000000 meter offset for
|
205 |
|
|
// southern hemisphere
|
206 |
|
|
}
|
207 |
|
|
|
208 |
|
|
northing_ = Math.round(UTMNorthing);
|
209 |
|
|
easting_ = Math.round(UTMEasting);
|
210 |
|
|
zone_number_ = ZoneNumber;
|
211 |
|
|
zone_letter_ = getLetterDesignator(Lat);
|
212 |
|
|
}
|
213 |
|
|
|
214 |
|
|
function getLetterDesignator(lat) {
|
215 |
|
|
//This is here as an error flag to show that the Latitude is
|
216 |
|
|
//outside MGRS limits
|
217 |
|
|
var LetterDesignator = 'Z';
|
218 |
|
|
|
219 |
|
|
if ((84 >= lat) && (lat >= 72))
|
220 |
|
|
LetterDesignator = 'X';
|
221 |
|
|
else if ((72 > lat) && (lat >= 64))
|
222 |
|
|
LetterDesignator = 'W';
|
223 |
|
|
else if ((64 > lat) && (lat >= 56))
|
224 |
|
|
LetterDesignator = 'V';
|
225 |
|
|
else if ((56 > lat) && (lat >= 48))
|
226 |
|
|
LetterDesignator = 'U';
|
227 |
|
|
else if ((48 > lat) && (lat >= 40))
|
228 |
|
|
LetterDesignator = 'T';
|
229 |
|
|
else if ((40 > lat) && (lat >= 32))
|
230 |
|
|
LetterDesignator = 'S';
|
231 |
|
|
else if ((32 > lat) && (lat >= 24))
|
232 |
|
|
LetterDesignator = 'R';
|
233 |
|
|
else if ((24 > lat) && (lat >= 16))
|
234 |
|
|
LetterDesignator = 'Q';
|
235 |
|
|
else if ((16 > lat) && (lat >= 8))
|
236 |
|
|
LetterDesignator = 'P';
|
237 |
|
|
else if ((8 > lat) && (lat >= 0))
|
238 |
|
|
LetterDesignator = 'N';
|
239 |
|
|
else if ((0 > lat) && (lat >= -8))
|
240 |
|
|
LetterDesignator = 'M';
|
241 |
|
|
else if ((-8 > lat) && (lat >= -16))
|
242 |
|
|
LetterDesignator = 'L';
|
243 |
|
|
else if ((-16 > lat) && (lat >= -24))
|
244 |
|
|
LetterDesignator = 'K';
|
245 |
|
|
else if ((-24 > lat) && (lat >= -32))
|
246 |
|
|
LetterDesignator = 'J';
|
247 |
|
|
else if ((-32 > lat) && (lat >= -40))
|
248 |
|
|
LetterDesignator = 'H';
|
249 |
|
|
else if ((-40 > lat) && (lat >= -48))
|
250 |
|
|
LetterDesignator = 'G';
|
251 |
|
|
else if ((-48 > lat) && (lat >= -56))
|
252 |
|
|
LetterDesignator = 'F';
|
253 |
|
|
else if ((-56 > lat) && (lat >= -64))
|
254 |
|
|
LetterDesignator = 'E';
|
255 |
|
|
else if ((-64 > lat) && (lat >= -72))
|
256 |
|
|
LetterDesignator = 'D';
|
257 |
|
|
else if ((-72 > lat) && (lat >= -80))
|
258 |
|
|
LetterDesignator = 'C';
|
259 |
|
|
return LetterDesignator;
|
260 |
|
|
}
|
261 |
|
|
|
262 |
|
|
function formatMGRS() {
|
263 |
|
|
var seasting = "" + easting_;
|
264 |
|
|
var snorthing = ""+ northing_;
|
265 |
|
|
while( snorthing.length > 6 )
|
266 |
|
|
snorthing = snorthing.substr(1,snorthing.length-1);
|
267 |
|
|
|
268 |
|
|
var str= zone_number_ + "" + zone_letter_ +
|
269 |
|
|
get100kID(easting_, northing_, zone_number_) +
|
270 |
|
|
seasting.substr(1,4) + snorthing.substr(1,4);
|
271 |
|
|
|
272 |
|
|
return str;
|
273 |
|
|
}
|
274 |
|
|
|
275 |
|
|
/**
|
276 |
|
|
* Get the two letter 100k designator for a given UTM easting,
|
277 |
|
|
* northing and zone number value.
|
278 |
|
|
*/
|
279 |
|
|
function get100kID( easting, northing, zone_number) {
|
280 |
|
|
var setParm = get100kSetForZone(zone_number);
|
281 |
|
|
var setColumn = Math.floor( easting / 100000);
|
282 |
|
|
var setRow = Math.floor( northing / 100000) % 20;
|
283 |
|
|
//trace("get100kID:"+setParm+" "+setColumn+" "+setRow);
|
284 |
|
|
return getLetter100kID(setColumn, setRow, setParm);
|
285 |
|
|
}
|
286 |
|
|
|
287 |
|
|
/**
|
288 |
|
|
* Given a UTM zone number, figure out the MGRS 100K set it is in.
|
289 |
|
|
*/
|
290 |
|
|
function get100kSetForZone(i) {
|
291 |
|
|
var setParm = i % NUM_100K_SETS;
|
292 |
|
|
if (setParm == 0)
|
293 |
|
|
setParm = NUM_100K_SETS;
|
294 |
|
|
|
295 |
|
|
return setParm;
|
296 |
|
|
}
|
297 |
|
|
|
298 |
|
|
/**
|
299 |
|
|
* Get the two-letter MGRS 100k designator given information
|
300 |
|
|
* translated from the UTM northing, easting and zone number.
|
301 |
|
|
*
|
302 |
|
|
* @param setColumn the column index as it relates to the MGRS
|
303 |
|
|
* 100k set spreadsheet, created from the UTM easting.
|
304 |
|
|
* Values are 1-8.
|
305 |
|
|
* @param setRow the row index as it relates to the MGRS 100k set
|
306 |
|
|
* spreadsheet, created from the UTM northing value. Values
|
307 |
|
|
* are from 0-19.
|
308 |
|
|
* @param setParm the set block, as it relates to the MGRS 100k set
|
309 |
|
|
* spreadsheet, created from the UTM zone. Values are from
|
310 |
|
|
* 1-60.
|
311 |
|
|
* @return two letter MGRS 100k code.
|
312 |
|
|
*/
|
313 |
|
|
|
314 |
|
|
function getLetter100kID( column, row, parm) {
|
315 |
|
|
// colOrigin and rowOrigin are the letters at the origin of the set
|
316 |
|
|
var index = parm-1;
|
317 |
|
|
var colOrigin = AsciiToNum(SET_ORIGIN_COLUMN_LETTERS[index]);
|
318 |
|
|
var rowOrigin = AsciiToNum(SET_ORIGIN_ROW_LETTERS[index]);
|
319 |
|
|
|
320 |
|
|
// colInt and rowInt are the letters to build to return
|
321 |
|
|
var colInt = colOrigin + column - 1;
|
322 |
|
|
var rowInt = rowOrigin + row;
|
323 |
|
|
var rollover = false;
|
324 |
|
|
|
325 |
|
|
if ( colInt > Z ) {
|
326 |
|
|
colInt = colInt - Z + A - 1;
|
327 |
|
|
rollover = true;
|
328 |
|
|
}
|
329 |
|
|
|
330 |
|
|
if (colInt == I || (colOrigin < I && colInt > I)
|
331 |
|
|
|| ((colInt > I || colOrigin < I) && rollover)) {
|
332 |
|
|
colInt++;
|
333 |
|
|
}
|
334 |
|
|
|
335 |
|
|
if (colInt == O || (colOrigin < O && colInt > O)
|
336 |
|
|
|| ((colInt > O || colOrigin < O) && rollover)) {
|
337 |
|
|
colInt++;
|
338 |
|
|
|
339 |
|
|
if (colInt == I) {
|
340 |
|
|
colInt++;
|
341 |
|
|
}
|
342 |
|
|
}
|
343 |
|
|
|
344 |
|
|
if (colInt > Z) {
|
345 |
|
|
colInt = colInt - Z + A - 1;
|
346 |
|
|
}
|
347 |
|
|
|
348 |
|
|
if (rowInt > V) {
|
349 |
|
|
rowInt = rowInt - V + A - 1;
|
350 |
|
|
rollover = true;
|
351 |
|
|
} else {
|
352 |
|
|
rollover = false;
|
353 |
|
|
}
|
354 |
|
|
|
355 |
|
|
if( ((rowInt == I) || ((rowOrigin < I) && (rowInt > I)))
|
356 |
|
|
|| (((rowInt > I)||(rowOrigin < I)) && rollover)) {
|
357 |
|
|
rowInt++;
|
358 |
|
|
}
|
359 |
|
|
|
360 |
|
|
if( ((rowInt == O) || ((rowOrigin < O) && (rowInt > O)))
|
361 |
|
|
|| (((rowInt > O)|| (rowOrigin < O)) && rollover)) {
|
362 |
|
|
rowInt++;
|
363 |
|
|
|
364 |
|
|
if (rowInt == I) {
|
365 |
|
|
rowInt++;
|
366 |
|
|
}
|
367 |
|
|
}
|
368 |
|
|
|
369 |
|
|
if (rowInt > V) {
|
370 |
|
|
rowInt = rowInt - V + A - 1;
|
371 |
|
|
}
|
372 |
|
|
|
373 |
|
|
var twoLetter = NumToAscii(colInt) + "" + NumToAscii(rowInt);
|
374 |
|
|
return twoLetter;
|
375 |
|
|
}
|
376 |
|
|
|
377 |
|
|
|
378 |
|
|
function AsciiToNum( ascii ) {
|
379 |
|
|
switch( ascii ) {
|
380 |
|
|
case 'A':
|
381 |
|
|
return 65;
|
382 |
|
|
case 'B':
|
383 |
|
|
return 66;
|
384 |
|
|
case 'C':
|
385 |
|
|
return 67;
|
386 |
|
|
case 'D':
|
387 |
|
|
return 68;
|
388 |
|
|
case 'E':
|
389 |
|
|
return 69;
|
390 |
|
|
case 'F':
|
391 |
|
|
return 70;
|
392 |
|
|
case 'G':
|
393 |
|
|
return 71;
|
394 |
|
|
case 'H':
|
395 |
|
|
return 72;
|
396 |
|
|
case 'I':
|
397 |
|
|
return 73;
|
398 |
|
|
case 'J':
|
399 |
|
|
return 74;
|
400 |
|
|
case 'K':
|
401 |
|
|
return 75;
|
402 |
|
|
case 'L':
|
403 |
|
|
return 76;
|
404 |
|
|
case 'M':
|
405 |
|
|
return 77;
|
406 |
|
|
case 'N':
|
407 |
|
|
return 78;
|
408 |
|
|
case 'O':
|
409 |
|
|
return 79;
|
410 |
|
|
case 'P':
|
411 |
|
|
return 80;
|
412 |
|
|
case 'Q':
|
413 |
|
|
return 81;
|
414 |
|
|
case 'R':
|
415 |
|
|
return 82;
|
416 |
|
|
case 'S':
|
417 |
|
|
return 83;
|
418 |
|
|
case 'T':
|
419 |
|
|
return 84;
|
420 |
|
|
case 'U':
|
421 |
|
|
return 85;
|
422 |
|
|
case 'V':
|
423 |
|
|
return 86;
|
424 |
|
|
case 'W':
|
425 |
|
|
return 87;
|
426 |
|
|
case 'X':
|
427 |
|
|
return 88;
|
428 |
|
|
case 'Y':
|
429 |
|
|
return 89;
|
430 |
|
|
case 'Z':
|
431 |
|
|
return 90;
|
432 |
|
|
}
|
433 |
|
|
}
|
434 |
|
|
|
435 |
|
|
function NumToAscii( num ) {
|
436 |
|
|
switch( num ) {
|
437 |
|
|
case 65:
|
438 |
|
|
return 'A';
|
439 |
|
|
case 66:
|
440 |
|
|
return 'B';
|
441 |
|
|
case 67:
|
442 |
|
|
return 'C';
|
443 |
|
|
case 68:
|
444 |
|
|
return 'D';
|
445 |
|
|
case 69:
|
446 |
|
|
return 'E';
|
447 |
|
|
case 70:
|
448 |
|
|
return 'F';
|
449 |
|
|
case 71:
|
450 |
|
|
return 'G';
|
451 |
|
|
case 72:
|
452 |
|
|
return 'H';
|
453 |
|
|
case 73:
|
454 |
|
|
return 'I';
|
455 |
|
|
case 74:
|
456 |
|
|
return 'J';
|
457 |
|
|
case 75 :
|
458 |
|
|
return 'K';
|
459 |
|
|
case 76:
|
460 |
|
|
return 'L';
|
461 |
|
|
case 77:
|
462 |
|
|
return 'M';
|
463 |
|
|
case 78:
|
464 |
|
|
return 'N';
|
465 |
|
|
case 79:
|
466 |
|
|
return 'O';
|
467 |
|
|
case 80:
|
468 |
|
|
return 'P';
|
469 |
|
|
case 81:
|
470 |
|
|
return 'Q';
|
471 |
|
|
case 82:
|
472 |
|
|
return 'R';
|
473 |
|
|
case 83:
|
474 |
|
|
return 'S';
|
475 |
|
|
case 84:
|
476 |
|
|
return 'T';
|
477 |
|
|
case 85:
|
478 |
|
|
return 'U';
|
479 |
|
|
case 86:
|
480 |
|
|
return 'V';
|
481 |
|
|
case 87:
|
482 |
|
|
return 'W';
|
483 |
|
|
case 88:
|
484 |
|
|
return 'X';
|
485 |
|
|
case 89:
|
486 |
|
|
return 'Y';
|
487 |
|
|
case 90:
|
488 |
|
|
return 'Z';
|
489 |
|
|
}
|
490 |
|
|
}
|
491 |
|
|
}
|