1 | <html> |
---|
2 | <head> |
---|
3 | <title>New Popular Edition - GPX Tracer</title> |
---|
4 | <style type="text/css"> |
---|
5 | body { |
---|
6 | background-color: #dddddd; |
---|
7 | } |
---|
8 | div#images { |
---|
9 | border: 0; |
---|
10 | margin: 0; |
---|
11 | padding: 0; |
---|
12 | width: 760px; |
---|
13 | float: left; |
---|
14 | } |
---|
15 | div.tilerow { |
---|
16 | border: 0; |
---|
17 | margin: 0; |
---|
18 | padding: 0; |
---|
19 | } |
---|
20 | img.tile { |
---|
21 | width: 250px; |
---|
22 | height: 250px; |
---|
23 | border: 0; |
---|
24 | margin: 0; |
---|
25 | } |
---|
26 | td { |
---|
27 | text-align: center; |
---|
28 | } |
---|
29 | #calibration { |
---|
30 | color: #990000; |
---|
31 | } |
---|
32 | </style> |
---|
33 | |
---|
34 | <!-- Include the Yahoo libraries --> |
---|
35 | <script src="js/yahoo.js"></script> |
---|
36 | <script src="js/dom.js"></script> |
---|
37 | <script src="js/connection.js"></script> |
---|
38 | <script src="js/event.js"></script> |
---|
39 | </head> |
---|
40 | <body id="body"> |
---|
41 | |
---|
42 | <div id="images"> |
---|
43 | <div id="row1" class="tilerow"><img src="empty-tile.png" class="tile" id="row1-img1" /><img src="empty-tile.png" class="tile" id="row1-img2" /><img src="empty-tile.png" class="tile" id="row1-img3" /></div> |
---|
44 | <div id="row2" class="tilerow"><img src="empty-tile.png" class="tile" id="row2-img1" /><img src="empty-tile.png" class="tile" id="row2-img2" /><img src="empty-tile.png" class="tile" id="row2-img3" /></div> |
---|
45 | <div id="row3" class="tilerow"><img src="empty-tile.png" class="tile" id="row3-img1" /><img src="empty-tile.png" class="tile" id="row3-img2" /><img src="empty-tile.png" class="tile" id="row3-img3" /></div> |
---|
46 | </div> |
---|
47 | |
---|
48 | <div style="float: right"> |
---|
49 | <div style="height: 100px"> </div> |
---|
50 | <div id="controls"> |
---|
51 | <table> |
---|
52 | <tr><td colspan="3" style="align: center"> |
---|
53 | <a href="" id="north">north</a> |
---|
54 | </td></tr> |
---|
55 | <tr><td> |
---|
56 | <a href="" id="west">west</a> |
---|
57 | </td><td /><td> |
---|
58 | <a href="" id="east">east</a> |
---|
59 | </td></tr> |
---|
60 | <tr><td colspan="3" style="align: center"> |
---|
61 | <a href="" id="south">south</a> |
---|
62 | </td></tr> |
---|
63 | <tr><td colspan="3" style="align: center"> |
---|
64 | <br /><br /> |
---|
65 | <a href="" id="browse">browse map</a> |
---|
66 | </td></tr> |
---|
67 | </table> |
---|
68 | </div> |
---|
69 | <div id="actions"> |
---|
70 | <br /><br /> |
---|
71 | <a href="javascript:request_calibrate()">calibrate</a> |
---|
72 | <br /> |
---|
73 | <a href="#help">(calibration help)</a> |
---|
74 | <br /><br /> |
---|
75 | <a href="javascript:request_gpx()">generate GPX</a> |
---|
76 | <br /><br /> |
---|
77 | <a href="/">home</a> |
---|
78 | </div> |
---|
79 | <div id="calibration"> |
---|
80 | <br /><br /> |
---|
81 | <span id="calibrateE"></span> |
---|
82 | <br /> |
---|
83 | <span id="calibrateN"></span> |
---|
84 | </div> |
---|
85 | </div> |
---|
86 | |
---|
87 | <br style="clear: both" /> |
---|
88 | <br /><br /> |
---|
89 | |
---|
90 | <div id="help"> |
---|
91 | To correct orthorectification issues, select calibrate above, then |
---|
92 | click on a 4-way grid square tile join (where 4 grid squares meet). |
---|
93 | Repeat for each of the 4 of these joins on the map. |
---|
94 | <img src="good-join.jpg" alt="example of a 4 way join between grid squares" /> |
---|
95 | <br /><br /> |
---|
96 | When in calibration mode, the screen background will go green to alert |
---|
97 | you. After you click, the calibration error will be (re)calculated and |
---|
98 | shown, and the background will return to grey. You will need to click |
---|
99 | the calibration button again before entering the next tile join. |
---|
100 | <br /> |
---|
101 | It is not advisable to try to calibrate across map sheet joins, as |
---|
102 | different sheets tend to have different errors. |
---|
103 | <img src="bad-join.jpg" alt="example of a cross-sheet join between grid squares" /> |
---|
104 | </div> |
---|
105 | |
---|
106 | <br /><br /> |
---|
107 | |
---|
108 | <div id="gpxdiv" style="width: 100%"> |
---|
109 | <a name="gpx"></a> |
---|
110 | <textarea name="gpxbox" id="gpxbox" style="width: 100%; height: 250"></textarea> |
---|
111 | <input type="button" value="Generate GPX" onclick="do_gpx()" /> |
---|
112 | </div> |
---|
113 | |
---|
114 | |
---|
115 | <script type="text/javascript" src="js/jscoord-1.1.1.js"></script> |
---|
116 | <script type="text/javascript"> |
---|
117 | var ia = document.getElementById("images"); |
---|
118 | |
---|
119 | // Calculation stuff |
---|
120 | var eastings = new Array(); |
---|
121 | var northings = new Array(); |
---|
122 | var pointPosX = new Array(); |
---|
123 | var pointPosY = new Array(); |
---|
124 | |
---|
125 | // Our calibration |
---|
126 | var errorEasting = 0; |
---|
127 | var errorNorthing = 0; |
---|
128 | var errorsEasting = new Array(); |
---|
129 | var errorsNorthing = new Array(); |
---|
130 | var clickIsCalibration = false; |
---|
131 | |
---|
132 | // The last image we added |
---|
133 | // (So we can swap colours) |
---|
134 | var lastPointImg = null; |
---|
135 | |
---|
136 | // Calibration functions |
---|
137 | function request_calibrate() { |
---|
138 | clickIsCalibration = true; |
---|
139 | document.getElementById("body").style.backgroundColor = "#77ff77"; |
---|
140 | } |
---|
141 | function do_calibrate(x, y, clickX, clickY) { |
---|
142 | clickIsCalibration = false; |
---|
143 | document.getElementById("body").style.backgroundColor = ""; |
---|
144 | |
---|
145 | // What corner are we near? |
---|
146 | if(x > 0.5) { x = x - 1.0; } |
---|
147 | if(y > 0.5) { y = y - 1.0; } |
---|
148 | |
---|
149 | // We have calculated where the corner is on the map |
---|
150 | // We need to apply the same value to all edits |
---|
151 | var errNum = errorsEasting.length; |
---|
152 | errorsEasting[errNum] = x; |
---|
153 | errorsNorthing[errNum] = y; |
---|
154 | |
---|
155 | // Compute new average |
---|
156 | errorEasting = 0; |
---|
157 | errorNorthing = 0; |
---|
158 | for(var i=0; i<errorsEasting.length; i=i+1) { |
---|
159 | errorEasting = errorEasting + errorsEasting[i]; |
---|
160 | errorNorthing = errorNorthing + errorsNorthing[i]; |
---|
161 | } |
---|
162 | errorEasting = Math.round(errorEasting / errorsEasting.length * 1000); |
---|
163 | errorNorthing = Math.round(errorNorthing / errorsNorthing.length * 1000); |
---|
164 | |
---|
165 | // Draw other cross |
---|
166 | var cross = new Image(); |
---|
167 | cross.src = "7x7-red-cross.png"; |
---|
168 | ia.appendChild(cross); |
---|
169 | cross.style.position = "absolute"; |
---|
170 | cross.style.top = clickY - 3; |
---|
171 | cross.style.left = clickX - 3; |
---|
172 | |
---|
173 | // Tell them about it |
---|
174 | var csE = document.getElementById("calibrateE"); |
---|
175 | while(csE.hasChildNodes()) { |
---|
176 | csE.removeChild( csE.firstChild ); |
---|
177 | } |
---|
178 | csE.appendChild( document.createTextNode("Easting is out by " + errorEasting + "m" ) ); |
---|
179 | |
---|
180 | var csN = document.getElementById("calibrateN"); |
---|
181 | while(csN.hasChildNodes()) { |
---|
182 | csN.removeChild( csN.firstChild ); |
---|
183 | } |
---|
184 | csN.appendChild( document.createTextNode("Northing is out by " + errorNorthing + "m" ) ); |
---|
185 | } |
---|
186 | |
---|
187 | function request_gpx() { |
---|
188 | // Zoom to the box |
---|
189 | document.location.href="#gpx"; |
---|
190 | |
---|
191 | // Do the build |
---|
192 | do_gpx(); |
---|
193 | } |
---|
194 | |
---|
195 | function do_gpx() { |
---|
196 | var gpxArea = document.getElementById("gpxbox"); |
---|
197 | |
---|
198 | var now = new Date(); |
---|
199 | function pad(val) { |
---|
200 | if(val < 10) { return "0" + val; } |
---|
201 | return val; |
---|
202 | } |
---|
203 | var nowDate = now.getFullYear() + "-" + pad(now.getMonth()+1) + "-" + |
---|
204 | pad(now.getDate()) + "T" + pad(now.getHours()) + ":" + |
---|
205 | pad(now.getMinutes()) + ":" + pad(now.getSeconds()) + "Z"; |
---|
206 | |
---|
207 | var gpx = |
---|
208 | '<?xml version="1.0"?>\n' + |
---|
209 | '<gpx\n' + |
---|
210 | 'version="1.0"\n' + |
---|
211 | 'creator="NPE to GPX Converter - http://gpx.npemap.org.uk/"\n' + |
---|
212 | 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n' + |
---|
213 | 'xmlns="http://www.topografix.com/GPX/1/0"\n' + |
---|
214 | 'xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/\n' + |
---|
215 | 'GPX/1/0/gpx.xsd">\n' + |
---|
216 | '<time>' + nowDate + '</time>\n' + |
---|
217 | '<trk><trkseg>\n'; |
---|
218 | var gpxEnd = '</trkseg></trk>\n</gpx>\n'; |
---|
219 | var gpxData = ''; |
---|
220 | for(var i=0; i<eastings.length; i++) { |
---|
221 | easting = eastings[i]; |
---|
222 | northing = northings[i]; |
---|
223 | |
---|
224 | if(easting == -1 && northing == -1) { |
---|
225 | // Deleted point, skip |
---|
226 | continue; |
---|
227 | } |
---|
228 | |
---|
229 | // Apply calibration |
---|
230 | easting = easting - errorEasting; |
---|
231 | northing = northing - errorNorthing; |
---|
232 | //alert(easting + " " + northing); |
---|
233 | |
---|
234 | // Convert |
---|
235 | var en = new OSRef(easting,northing); |
---|
236 | var latlong = en.toLatLng(); |
---|
237 | latlong.OSGB36ToWGS84(); |
---|
238 | |
---|
239 | lat = latlong.lat; |
---|
240 | lng = latlong.lng; |
---|
241 | |
---|
242 | gpxData = gpxData + |
---|
243 | '<trkpt lat="' + lat + '" lon="' + lng + '">\n' + |
---|
244 | ' <time>1950-01-01T00:00:00Z</time>\n' + |
---|
245 | ' <fix>3d</fix>\n' + |
---|
246 | ' <sat>0</sat>\n' + |
---|
247 | ' <hdop>0.00</hdop>\n' + |
---|
248 | '</trkpt>'; |
---|
249 | } |
---|
250 | |
---|
251 | |
---|
252 | gpxArea.value = gpx + gpxData + gpxEnd; |
---|
253 | return true; |
---|
254 | } |
---|
255 | |
---|
256 | function removePoint(pointNum) { |
---|
257 | var img = document.getElementById("point_" + pointNum); |
---|
258 | var pNode = img.parentNode; |
---|
259 | pNode.removeChild(img); |
---|
260 | |
---|
261 | eastings[pointNum] = -1; |
---|
262 | northings[pointNum] = -1; |
---|
263 | pointPosX[pointNum] = -1; |
---|
264 | pointPosY[pointNum] = -1; |
---|
265 | |
---|
266 | return false; |
---|
267 | } |
---|
268 | |
---|
269 | function click(e) { |
---|
270 | // Ask the yahoo library to avoid browser nastyness for us |
---|
271 | e = YAHOO.util.Event.getEvent(e); |
---|
272 | |
---|
273 | var img = img = YAHOO.util.Event.getTarget(e); |
---|
274 | var link = img.parentNode; |
---|
275 | var page = link.parentNode; |
---|
276 | |
---|
277 | // Note - this won't work in things like IE |
---|
278 | // Oh well, like we care... |
---|
279 | var drawX = YAHOO.util.Event.getPageX(e); |
---|
280 | var drawY = YAHOO.util.Event.getPageY(e); |
---|
281 | |
---|
282 | var imgPos = YAHOO.util.Dom.getXY(img); |
---|
283 | var x = drawX - imgPos[0]; |
---|
284 | var y = drawY - imgPos[1]; |
---|
285 | //alert(x + " " + y); |
---|
286 | |
---|
287 | // OK, compute and add the point |
---|
288 | // x is from left hand edge, which is what we want |
---|
289 | var facX = x / img.offsetWidth; |
---|
290 | // y is from top edge, which isn't what we want |
---|
291 | var facY = 1 - y / img.offsetHeight; |
---|
292 | |
---|
293 | if(clickIsCalibration) { |
---|
294 | do_calibrate(facX, facY, drawX, drawY); |
---|
295 | return false; |
---|
296 | } |
---|
297 | |
---|
298 | // Tiles are eee/nnn.jpg |
---|
299 | var tile = img.src.substring( img.src.lastIndexOf("/") - 3 ); |
---|
300 | var baseEasting = tile.substring(0, tile.indexOf("/")); |
---|
301 | var baseNorthing = tile.substring(tile.indexOf("/") + 1, tile.indexOf(".")); |
---|
302 | |
---|
303 | var easting = Math.round( (baseEasting * 1000) + (facX * 1000) ); |
---|
304 | var northing = Math.round( (baseNorthing * 1000) + (facY * 1000) ); |
---|
305 | //alert(easting + " " + northing); |
---|
306 | |
---|
307 | // Save where it is |
---|
308 | var pointNum = eastings.length; |
---|
309 | eastings[pointNum] = easting; |
---|
310 | northings[pointNum] = northing; |
---|
311 | pointPosX[pointNum] = drawX; |
---|
312 | pointPosY[pointNum] = drawY; |
---|
313 | |
---|
314 | // Swap the colour of the last point, if there is one |
---|
315 | if(lastPointImg != null) { |
---|
316 | lastPointImg.src = "5x5-cross.png"; |
---|
317 | } |
---|
318 | |
---|
319 | // Draw the X |
---|
320 | var cross = new Image(); |
---|
321 | cross.src = "5x5-cross-alt.png"; |
---|
322 | cross.id = "point_" + pointNum; |
---|
323 | cross.onclick = function(e) { removePoint(pointNum) }; |
---|
324 | ia.appendChild(cross); |
---|
325 | lastPointImg = cross; |
---|
326 | |
---|
327 | cross.style.position = "absolute"; |
---|
328 | cross.style.top = drawY - 2; |
---|
329 | cross.style.left = drawX - 2; |
---|
330 | |
---|
331 | // Don't do anything else |
---|
332 | return false; |
---|
333 | } |
---|
334 | |
---|
335 | function setup(map_easting,map_northing,zoom) { |
---|
336 | // Pre-load the cross images |
---|
337 | var cross = new Image(); |
---|
338 | cross.src = "5x5-cross.png"; |
---|
339 | cross.style.display = "none"; |
---|
340 | document.getElementById("body").appendChild(cross); |
---|
341 | |
---|
342 | var cross2 = new Image(); |
---|
343 | cross2.src = "5x5-cross-alt.png"; |
---|
344 | cross2.style.display = "none"; |
---|
345 | document.getElementById("body").appendChild(cross2); |
---|
346 | |
---|
347 | var cross3 = new Image(); |
---|
348 | cross3.src = "7x7-red-cross.png"; |
---|
349 | cross3.style.display = "none"; |
---|
350 | document.getElementById("body").appendChild(cross3); |
---|
351 | |
---|
352 | var tile_base = "http://tile.npemap.org.uk/scaled1/"; |
---|
353 | |
---|
354 | // Set the images |
---|
355 | for(var i=-1; i<=1; i=i+1) { |
---|
356 | for(var j=-1; j<=1; j=j+1) { |
---|
357 | var img_id = "row" + (2-i) + "-img" + (j+2); |
---|
358 | var img = document.getElementById(img_id); |
---|
359 | |
---|
360 | var img_easting = map_easting + j; |
---|
361 | var img_northing = map_northing + i; |
---|
362 | |
---|
363 | // Get to nnn format |
---|
364 | if(img_easting < 100) { |
---|
365 | if(img_easting < 10) { |
---|
366 | img_easting = "00" + img_easting; |
---|
367 | } else { |
---|
368 | img_easting = "0" + img_easting; |
---|
369 | } |
---|
370 | } |
---|
371 | if(img_northing < 100) { |
---|
372 | if(img_northing < 10) { |
---|
373 | img_northing = "00" + img_northing; |
---|
374 | } else { |
---|
375 | img_northing = "0" + img_northing; |
---|
376 | } |
---|
377 | } |
---|
378 | |
---|
379 | img.src = tile_base + img_easting + "/" + img_northing + ".jpg"; |
---|
380 | |
---|
381 | // Attach click handler |
---|
382 | img.onclick = click; |
---|
383 | } |
---|
384 | } |
---|
385 | |
---|
386 | |
---|
387 | // Setup our nsew links |
---|
388 | function navLink(dir,e,n) { |
---|
389 | var a = document.getElementById(dir); |
---|
390 | a.href = "?" + e + "," + n; |
---|
391 | } |
---|
392 | navLink("north", map_easting, (map_northing+1)); |
---|
393 | navLink("south", map_easting, (map_northing-1)); |
---|
394 | navLink("east", (map_easting+1), map_northing); |
---|
395 | navLink("west", (map_easting-1), map_northing); |
---|
396 | |
---|
397 | document.getElementById("browse").href = "map.html#" + map_easting + "," + map_northing + ",1"; |
---|
398 | } |
---|
399 | |
---|
400 | // What url did they request? |
---|
401 | var map_easting = 449; |
---|
402 | var map_northing = 210; |
---|
403 | if(location.href.indexOf("?") > 0) { |
---|
404 | var coords = location.href.substring( location.href.indexOf("?") + 1 ); |
---|
405 | if(coords.indexOf("#") > 0) { |
---|
406 | coords = coords.substring( 0, coords.indexOf("#") ); |
---|
407 | } |
---|
408 | |
---|
409 | map_easting = coords.substring( 0, coords.indexOf(",") ); |
---|
410 | map_northing = coords.substring( coords.indexOf(",") + 1 ); |
---|
411 | |
---|
412 | // handle zoom in url |
---|
413 | if(map_northing.indexOf(",") > 0) { |
---|
414 | map_northing = map_northing.substring( 0, map_northing.indexOf(",") ); |
---|
415 | } |
---|
416 | |
---|
417 | // make into numbers |
---|
418 | map_easting = map_easting / 1; |
---|
419 | map_northing = map_northing / 1; |
---|
420 | } |
---|
421 | |
---|
422 | setup(map_easting,map_northing,1); |
---|
423 | </script> |
---|
424 | |
---|
425 | </body> |
---|
426 | </html> |
---|