Post by Twister-UK
Ah, so you mean somewhere on the WME display you'd have a button to open up OSMC/OSOD at the same co-ords... In theory it's possible - I haven't delved into the WME code yet to see how easy it'd be to extract the location, but if getting that isn't a complete ballache then it'd be trivial to pass that across to OSMC using its internal permalink feature or to OSOD via my script.


Meanwhile...

Code: Select all

// ==UserScript==
// @name                OS OpenData FullHeight
// @namespace	        http://greasemonkey.chizzum.com
// @description	        Increases height of map window on OS OpenData site
// @include		http://www.ordnancesurvey.co.uk/oswebsite/opendata/viewer/*
// ==/UserScript==

function resizemap(event)
{
  // resizes map viewport whenever browser window changes size
   var elmModify = document.getElementById("map");
   elmModify.style.height = (window.innerHeight-10)+'px';
   elmModify.style.width = (window.innerWidth-10)+'px';
}

function recentreMap(eastings, northings, zoom)
{
   /*
   Create a proper unsafeWindow object on browsers where it doesn't exist (Chrome, mainly).
   Chrome now defines unsafeWindow, but does not give it the same access to a page's 
   javascript that a properly unsafe, unsafeWindow has. This code remedies that.
   
   From: http://stackoverflow.com/questions/1622145/how-can-i-mimic-greasemonkey-firefoxs-unsafewindow-functionality-in-chrome
   */
   var bGreasemonkeyServiceDefined     = false;
   try
   {
      if (typeof Components.interfaces.gmIGreasemonkeyService === "object")
      {
         bGreasemonkeyServiceDefined = true;
      }
   }
   catch (err)
   {
      //Ignore.
   }
   if ( typeof unsafeWindow === "undefined"  ||  ! bGreasemonkeyServiceDefined)
   {
      unsafeWindow    = ( function () {
         var dummyElem   = document.createElement('p');
         dummyElem.setAttribute ('onclick', 'return window;');
         return dummyElem.onclick ();
      } ) ();
   }
   // end of stackoverflow code


   // call the OS provided functions required to point the map at a
   // given grid ref and zoom level
   mymapCenter = new unsafeWindow.OpenSpace.MapPoint(eastings, northings);
   
   // not sure why, but passing zoom directly into setCenter prevents the
   // mouse scrollwheel from zooming in/out of the recentred map...  as a
   // workaround for now, test the value of zoom and use hardcoded calls
   //unsafeWindow.osMap.setCenter(mymapCenter, zoom);
   if(zoom==0)unsafeWindow.osMap.setCenter(mymapCenter, 0);
   if(zoom==1)unsafeWindow.osMap.setCenter(mymapCenter, 1);
   if(zoom==2)unsafeWindow.osMap.setCenter(mymapCenter, 2);
   if(zoom==3)unsafeWindow.osMap.setCenter(mymapCenter, 3);
   if(zoom==4)unsafeWindow.osMap.setCenter(mymapCenter, 4);
   if(zoom==5)unsafeWindow.osMap.setCenter(mymapCenter, 5);
   if(zoom==6)unsafeWindow.osMap.setCenter(mymapCenter, 6);
   if(zoom==7)unsafeWindow.osMap.setCenter(mymapCenter, 7);
   if(zoom==8)unsafeWindow.osMap.setCenter(mymapCenter, 8);
   if(zoom==9)unsafeWindow.osMap.setCenter(mymapCenter, 9);
   if(zoom==10)unsafeWindow.osMap.setCenter(mymapCenter, 10);
}


function checkMapLoaded()
{
   // if the "Powered by OS" logo hasn't loaded in the lower-left corner, we know the original map view
   // is still being rendered by the OpenData code, so wait 100ms and then cbeck for its presence again
   if(document.getElementById('newpoweredby') == null)
   {
      setTimeout(checkMapLoaded,100);
   }
   // once the logo is present, recentre the map view to the desired location and zoom level...
   else
   {
      recentreMap(eastings,northings,zoom);
   }
}

// remove the OS logos from the top...
var elmDeleted = document.getElementById("logos");
elmDeleted.parentNode.removeChild(elmDeleted);

// ...and the huge "about    help    keep in touch" bit from the bottom
var elmDeleted = document.getElementById("sitefooter");
elmDeleted.parentNode.removeChild(elmDeleted);

// reduce the width of the whitespace around the map viewport
var elmModify = document.getElementById("wrapper");
elmModify.style.padding = '4px';

// move the "boundary layers" menu selector into the map viewport
var elmModify = document.getElementById("mapmast");
elmModify.style.height = '0px';
elmModify.style.top = '64px';
elmModify.style.right = '64px';
elmModify.style.zIndex = '2';
// adjust the "boundary layers" border and background colour so it shows up nicely
var elmModify = document.getElementById("mapoptions");
var childModify = elmModify.getElementsByTagName("LI");
childModify[0].style.borderStyle = 'solid';
childModify[0].style.backgroundColor = '#FFFFFF';
childModify[0].style.borderWidth = '1px';

// extract the starting coords/zoom from the url...

var userloc = document.location.href;
upos = userloc.indexOf("?e=");
if(upos != -1)
{
   eastings = userloc.substr(upos+3,6);
   upos = userloc.indexOf("&n=");
   if(upos != -1)
   {
      northings = userloc.substr(upos+3,6);
      upos = userloc.indexOf("&z=");
      if(upos != -1)
      {
         zoom = userloc.substr(upos+3,2);
         //...then recentre the map 1s after the page has loaded
         checkMapLoaded();
      }
   }
}


// re-render the map now we're done removing/adjusting all the original elements...
resizemap();

// and finally add in a hook to the onResize event, to call resizemap() each time the
// browser window changes size
window.addEventListener('resize', resizemap, true);
...now properly waits for the default OS map to load before relocating, and plays nicely with Chrome again.
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
Did the previous version (with the hardcoded delay) work OK?
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
Good to hear the revised script is working as expected... I'm now working on another script for adding new links to WME, which will open up OS OpenData or Musical Chairs at the WME location.
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
For the OS Musical Chairs afficionados, here's a sneak pre-release look at the new script... This version adds a link to OSMC in the lower-right corner of the WME window, between the existing permalink and "Imagery by Bing" elements.

Code: Select all

// ==UserScript==
// @name                WME to OS link
// @namespace           http://greasemonkey.chizzum.com
// @description         Adds link to WME to open up OS Open Data/Musical Chairs sites at same map location
// @include             https://world.waze.com/editor/*
// ==/UserScript==

function processPermalink()
{
   // extract current lat/lon & zoom level from the permalink URL
   var plsrc = document.getElementById("permalink-container").innerHTML;
   var zoompos = plsrc.indexOf("?zoom=");
   var latpos = plsrc.indexOf("&lat=");
   var lonpos = plsrc.indexOf("&lon=");
   var layerpos = plsrc.indexOf("&layers=");
   
   // does the URL contain all three parameters?
   if((zoompos != -1)&&(latpos != -1)&&(lonpos != -1)&&(layerpos != -1))
   {
      // yes, so extract them...
      var zoom = parseInt(plsrc.substr(zoompos+6,latpos-(zoompos+6)));
      var lat = plsrc.substr(latpos+9,lonpos-(latpos+9));
      var lon = plsrc.substr(lonpos+9,layerpos-(lonpos+9));

      // compare the freshly extracted parameters against the persistent copies, and update the 
      // links to OSMC & OSOD only if there's a change required - the newly-inserted <a> element
      // can't be clicked on until the insertion process is complete, and if we were to re-insert
      // it every 250ms then it'd spend a lot of its time giving the appearance of being clickable
      // but without actually doing anything...
      if((zoom != sessionStorage.zoom)||(lat != sessionStorage.lat)||(lon != sessionStorage.lon))
      {
         // update the persistent vars with the new position
         sessionStorage.zoom = zoom;
         sessionStorage.lat = lat;
         sessionStorage.lon = lon;

         // translate the zoom level between WME and Musical Chairs
         var mczoom = zoom + 12;
         if(mczoom > 18) mczoom = 18;

         // generate the Musical Chairs URL
         var osmc_url = 'http://ris.dev.openstreetmap.org/oslmusicalchairs/map?zoom='+mczoom+'&lat='+lat+'&lon='+lon+'&layers=B0TT&view_mode=pseudorandom';

         // "borrow" the Bing attribution div to insert the new clicky-links, remembering to maintain the attribution after we're done messing with it!
         document.getElementById("bing-attribution").innerHTML = '- <a href="'+osmc_url+'">OS Musical Chairs</a> - Imagery by Bing';
      }
   }
}

// initialise persistent vars
sessionStorage.zoom = 0;
sessionStorage.lat = '';
sessionStorage.lon = '';

// check for new map co-ords every 250ms
setInterval(processPermalink,250);
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
How weird, all this time I've been looking at that bit of the screen, and I never noticed there was already a vertical seperator between the permalink and Bing attribution...
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
A minor update to the OS OpenData FullHeight script, removing the hardcoded 6-digit length for eastings/northings...

Code: Select all

// ==UserScript==
// @name                OS OpenData FullHeight
// @namespace	        http://greasemonkey.chizzum.com
// @description	        Increases height of map window on OS OpenData site
// @include		http://www.ordnancesurvey.co.uk/oswebsite/opendata/viewer/*
// ==/UserScript==

function resizemap(event)
{
  // resizes map viewport whenever browser window changes size
   var elmModify = document.getElementById("map");
   elmModify.style.height = (window.innerHeight-10)+'px';
   elmModify.style.width = (window.innerWidth-10)+'px';
}

function recentreMap(eastings, northings, zoom)
{
   /*
   Create a proper unsafeWindow object on browsers where it doesn't exist (Chrome, mainly).
   Chrome now defines unsafeWindow, but does not give it the same access to a page's 
   javascript that a properly unsafe, unsafeWindow has. This code remedies that.
   
   From: http://stackoverflow.com/questions/1622145/how-can-i-mimic-greasemonkey-firefoxs-unsafewindow-functionality-in-chrome
   */
   var bGreasemonkeyServiceDefined     = false;
   try
   {
      if (typeof Components.interfaces.gmIGreasemonkeyService === "object")
      {
         bGreasemonkeyServiceDefined = true;
      }
   }
   catch (err)
   {
      //Ignore.
   }
   if ( typeof unsafeWindow === "undefined"  ||  ! bGreasemonkeyServiceDefined)
   {
      unsafeWindow    = ( function () {
         var dummyElem   = document.createElement('p');
         dummyElem.setAttribute ('onclick', 'return window;');
         return dummyElem.onclick ();
      } ) ();
   }
   // end of stackoverflow code


   // call the OS provided functions required to point the map at a
   // given grid ref and zoom level
   mymapCenter = new unsafeWindow.OpenSpace.MapPoint(eastings, northings);
   
   // not sure why, but passing zoom directly into setCenter prevents the
   // mouse scrollwheel from zooming in/out of the recentred map...  as a
   // workaround for now, test the value of zoom and use hardcoded calls
   //unsafeWindow.osMap.setCenter(mymapCenter, zoom);
   if(zoom==0)unsafeWindow.osMap.setCenter(mymapCenter, 0);
   if(zoom==1)unsafeWindow.osMap.setCenter(mymapCenter, 1);
   if(zoom==2)unsafeWindow.osMap.setCenter(mymapCenter, 2);
   if(zoom==3)unsafeWindow.osMap.setCenter(mymapCenter, 3);
   if(zoom==4)unsafeWindow.osMap.setCenter(mymapCenter, 4);
   if(zoom==5)unsafeWindow.osMap.setCenter(mymapCenter, 5);
   if(zoom==6)unsafeWindow.osMap.setCenter(mymapCenter, 6);
   if(zoom==7)unsafeWindow.osMap.setCenter(mymapCenter, 7);
   if(zoom==8)unsafeWindow.osMap.setCenter(mymapCenter, 8);
   if(zoom==9)unsafeWindow.osMap.setCenter(mymapCenter, 9);
   if(zoom==10)unsafeWindow.osMap.setCenter(mymapCenter, 10);
}


function checkMapLoaded()
{
   // if the "Powered by OS" logo hasn't loaded in the lower-left corner, we know the original map view
   // is still being rendered by the OpenData code, so wait 100ms and then cbeck for its presence again
   if(document.getElementById('newpoweredby') == null)
   {
      setTimeout(checkMapLoaded,100);
   }
   // once the logo is present, recentre the map view to the desired location and zoom level...
   else
   {
      recentreMap(eastings,northings,zoom);
   }
}

// remove the OS logos from the top...
var elmDeleted = document.getElementById("logos");
elmDeleted.parentNode.removeChild(elmDeleted);

// ...and the huge "about    help    keep in touch" bit from the bottom
var elmDeleted = document.getElementById("sitefooter");
elmDeleted.parentNode.removeChild(elmDeleted);

// reduce the width of the whitespace around the map viewport
var elmModify = document.getElementById("wrapper");
elmModify.style.padding = '4px';

// move the "boundary layers" menu selector into the map viewport
var elmModify = document.getElementById("mapmast");
elmModify.style.height = '0px';
elmModify.style.top = '64px';
elmModify.style.right = '64px';
elmModify.style.zIndex = '2';
// adjust the "boundary layers" border and background colour so it shows up nicely
var elmModify = document.getElementById("mapoptions");
var childModify = elmModify.getElementsByTagName("LI");
childModify[0].style.borderStyle = 'solid';
childModify[0].style.backgroundColor = '#FFFFFF';
childModify[0].style.borderWidth = '1px';

// extract the starting coords/zoom from the url...
var userloc = document.location.href;
epos = userloc.indexOf("?e=");
npos = userloc.indexOf("&n=");
zpos = userloc.indexOf("&z=");
if((epos != -1)&&(npos != -1)&&(zpos != -1))
{
   eastings = userloc.substr(epos+3,npos-(epos+3));
   northings = userloc.substr(npos+3,zpos-(npos+3));
   zoom = userloc.substr(zpos+3,2);
   //...then recentre the map 1s after the page has loaded
   checkMapLoaded();
}


// re-render the map now we're done removing/adjusting all the original elements...
resizemap();

// and finally add in a hook to the onResize event, to call resizemap() each time the
// browser window changes size
window.addEventListener('resize', resizemap, true);

...in order for it to support all the possible grid refs passed to it by the full version of WME to OS.

Code: Select all

// ==UserScript==
// @name                WME to OS link
// @namespace           http://greasemonkey.chizzum.com
// @description         Adds link to WME to open up OS Open Data/Musical Chairs sites at same map location
// @include             https://world.waze.com/editor/*
// ==/UserScript==


// Modified from the original (c) Chris Veness 2005-2012
//   www.movable-type.co.uk/scripts/gridref.js
//   www.movable-type.co.uk/scripts/latlon-gridref.html
function toOSGrid(lat, lon)
{
   lat = (lat * Math.PI) / 180;
   lon = (lon * Math.PI) / 180;
   
   // Airy 1830 major & minor semi-axes
   var a = 6377563.396;
   var b = 6356256.910;
   // NatGrid scale factor on central meridian
   var F0 = 0.9996012717;
   // NatGrid true origin is 49N,2W
   var lat0 = 0.85521;
   var lon0 = -0.0349;
   // northing & easting of true origin, metres
   var N0 = -100000;
   var E0 = 400000;
   // eccentricity squared
   var e2 = 1 - (b*b)/(a*a);

   var n = (a-b)/(a+b);
   var n2 = n*n;
   var n3 = n*n*n;
   var cosLat = Math.cos(lat);
   var sinLat = Math.sin(lat);
   // transverse radius of curvature
   var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);
   // meridional radius of curvature
   var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);
   var eta2 = nu/rho-1;
   var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
   var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
   var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
   var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
   // meridional arc
   var M = b * F0 * (Ma - Mb + Mc - Md);
   var cos3lat = cosLat*cosLat*cosLat;
   var cos5lat = cos3lat*cosLat*cosLat;
   var tan2lat = Math.tan(lat)*Math.tan(lat);
   var tan4lat = tan2lat*tan2lat;
   var I = M + N0;
   var II = (nu/2)*sinLat*cosLat;
   var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2);
   var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat);
   var IV = nu*cosLat;
   var V = (nu/6)*cos3lat*(nu/rho-tan2lat);
   var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2);
   var dLon = lon-lon0;
   var dLon2 = dLon*dLon;
   var dLon3 = dLon2*dLon;
   var dLon4 = dLon3*dLon;
   var dLon5 = dLon4*dLon;
   var dLon6 = dLon5*dLon;
   var N = Math.round(I + II*dLon2 + III*dLon4 + IIIA*dLon6);
   var E = Math.round(E0 + IV*dLon + V*dLon3 + VI*dLon5);
   return '?e='+E+'&n='+N;
}


function processPermalink()
{
   // extract current lat/lon & zoom level from the permalink URL
   var plsrc = document.getElementById("permalink-container").innerHTML;
   var zoompos = plsrc.indexOf("?zoom=");
   var latpos = plsrc.indexOf("&lat=");
   var lonpos = plsrc.indexOf("&lon=");
   var layerpos = plsrc.indexOf("&layers=");

   // does the URL contain all three parameters?
   if((zoompos != -1)&&(latpos != -1)&&(lonpos != -1)&&(layerpos != -1))
   {
      // yes, so extract them...
      var zoom = parseInt(plsrc.substr(zoompos+6,latpos-(zoompos+6)));
      var lat = plsrc.substr(latpos+9,lonpos-(latpos+9));
      var lon = plsrc.substr(lonpos+9,layerpos-(lonpos+9));

      // compare the freshly extracted parameters against the persistent copies, and update the
      // links to OSMC & OSOD only if there's a change required - the newly-inserted <a> element
      // can't be clicked on until the insertion process is complete, and if we were to re-insert
      // it every 250ms then it'd spend a lot of its time giving the appearance of being clickable
      // but without actually doing anything...
      if((zoom != sessionStorage.zoom)||(lat != sessionStorage.lat)||(lon != sessionStorage.lon))
      {
         // update the persistent vars with the new position
         sessionStorage.zoom = zoom;
         sessionStorage.lat = lat;
         sessionStorage.lon = lon;

         // translate the zoom level between WME and Musical Chairs - this gives a pretty close match
         var mczoom = zoom + 12;
         if(mczoom > 18) mczoom = 18;
         // generate the Musical Chairs URL
         var osmc_url = 'http://ris.dev.openstreetmap.org/oslmusicalchairs/map?zoom='+mczoom+'&lat='+lat+'&lon='+lon+'&layers=B0TT&view_mode=pseudorandom';

         // translate the zoom level between WME and OpenData - the match here isn't quite so good...
         var odzoom = zoom + 5;
         if(odzoom < 6) odzoom = 6;
         if(odzoom > 10) odzoom = 10;
         // generate the OpenData URL - requires the support of os_opendata_fullheight.user.js
         var osod_url = 'http://www.ordnancesurvey.co.uk/oswebsite/opendata/viewer/'+toOSGrid(lat,lon)+'&z='+odzoom;
         
         // "borrow" the Bing attribution div to insert the new clicky-links, remembering to maintain the attribution after we're done messing with it!
         document.getElementById("bing-attribution").innerHTML = ' <a href="'+osod_url+'" target=_blank>OS OpenData</a> | <a href="'+osmc_url+'" target=_blank>OS Musical Chairs</a> | Imagery by Bing';
      }
   }
}

// initialise persistent vars
sessionStorage.zoom = 0;
sessionStorage.lat = '';
sessionStorage.lon = '';

// check for new map co-ords every 250ms
setInterval(processPermalink,250);
Yes, this means we now have two new links at the bottom of WME, allowing the current WME position and zoom level to be passed to OS OpenData or OS Musical Chairs.

Includes Dave2084's edits so that the links automatically open in new tabs (I'm so used to centre-clicking links to open in a new tab I hadn't given a second thought to letting the script do it for me...) and the seperators are visually consistent.

Enjoy!
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
Update for WME to OS, incorporating various suggestions made above...

Code: Select all

// ==UserScript==
// @name                WME to OS link
// @namespace           http://greasemonkey.chizzum.com
// @description         Adds link to WME to open up OS Open Data/Musical Chairs sites at same map location
// @include             https://world.waze.com/editor/*
// @version             0.3
// ==/UserScript==


// Modified from the original (c) Chris Veness 2005-2012
//   www.movable-type.co.uk/scripts/gridref.js
//   www.movable-type.co.uk/scripts/latlon-gridref.html
function toOSGrid(lat, lon)
{
   lat = (lat * Math.PI) / 180;
   lon = (lon * Math.PI) / 180;

   // Airy 1830 major & minor semi-axes
   var a = 6377563.396;
   var b = 6356256.910;
   // NatGrid scale factor on central meridian
   var F0 = 0.9996012717;
   // NatGrid true origin is 49N,2W
   var lat0 = 0.85521;
   var lon0 = -0.0349;
   // northing & easting of true origin, metres
   var N0 = -100000;
   var E0 = 400000;
   // eccentricity squared
   var e2 = 1 - (b*b)/(a*a);

   var n = (a-b)/(a+b);
   var n2 = n*n;
   var n3 = n*n*n;
   var cosLat = Math.cos(lat);
   var sinLat = Math.sin(lat);
   // transverse radius of curvature
   var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);
   // meridional radius of curvature
   var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);
   var eta2 = nu/rho-1;
   var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
   var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
   var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
   var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
   // meridional arc
   var M = b * F0 * (Ma - Mb + Mc - Md);
   var cos3lat = cosLat*cosLat*cosLat;
   var cos5lat = cos3lat*cosLat*cosLat;
   var tan2lat = Math.tan(lat)*Math.tan(lat);
   var tan4lat = tan2lat*tan2lat;
   var I = M + N0;
   var II = (nu/2)*sinLat*cosLat;
   var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2);
   var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat);
   var IV = nu*cosLat;
   var V = (nu/6)*cos3lat*(nu/rho-tan2lat);
   var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2);
   var dLon = lon-lon0;
   var dLon2 = dLon*dLon;
   var dLon3 = dLon2*dLon;
   var dLon4 = dLon3*dLon;
   var dLon5 = dLon4*dLon;
   var dLon6 = dLon5*dLon;
   var N = Math.round(I + II*dLon2 + III*dLon4 + IIIA*dLon6);
   var E = Math.round(E0 + IV*dLon + V*dLon3 + VI*dLon5);
   return '?e='+E+'&n='+N;
}


function processPermalink()
{
   // extract current lat/lon & zoom level from the permalink URL
   var plsrc = document.getElementById("permalink-container").innerHTML;
   var zoompos = plsrc.indexOf("?zoom=");
   var latpos = plsrc.indexOf("&lat=");
   var lonpos = plsrc.indexOf("&lon=");
   var layerpos = plsrc.indexOf("&layers=");

   // does the URL contain all three parameters?
   if((zoompos != -1)&&(latpos != -1)&&(lonpos != -1)&&(layerpos != -1))
   {
      // yes, so extract them...
      var zoom = parseInt(plsrc.substr(zoompos+6,latpos-(zoompos+6)));
      var lat = plsrc.substr(latpos+9,lonpos-(latpos+9));
      var lon = plsrc.substr(lonpos+9,layerpos-(lonpos+9));

      // compare the freshly extracted parameters against the persistent copies, and update the
      // links to OSMC & OSOD only if there's a change required - the newly-inserted <a> element
      // can't be clicked on until the insertion process is complete, and if we were to re-insert
      // it every 250ms then it'd spend a lot of its time giving the appearance of being clickable
      // but without actually doing anything...
      if((zoom != sessionStorage.zoom)||(lat != sessionStorage.lat)||(lon != sessionStorage.lon))
      {
         // update the persistent vars with the new position
         sessionStorage.zoom = zoom;
         sessionStorage.lat = lat;
         sessionStorage.lon = lon;

         // translate the zoom level between WME and Musical Chairs - this gives a pretty close match
         var mczoom = zoom + 12;
         if(mczoom > 18) mczoom = 18;
         // generate the Musical Chairs URL
         var osmc_url = 'http://ris.dev.openstreetmap.org/oslmusicalchairs/map?zoom='+mczoom+'&lat='+lat+'&lon='+lon+'&layers=B0TT&view_mode=pseudorandom';

         // translate the zoom level between WME and OpenData - the match here isn't quite so good...
         var odzoom = zoom + 5;
         if(odzoom < 6) odzoom = 6;
         if(odzoom > 10) odzoom = 10;
         // generate the OpenData URL - requires the support of os_opendata_fullheight.user.js
         var osod_url = 'http://www.ordnancesurvey.co.uk/oswebsite/opendata/viewer/'+toOSGrid(lat,lon)+'&z='+odzoom;

         // translate the zoom level between WME and live map.  The only correlation is (WME)=[Live] (0 or 1)=[7], (2 or 3)=[8], (4 or more)=[9]
         var livemap_zoom = Math.floor(zoom/2)+7;
         if (livemap_zoom > 9 ) livemap_zoom = 9;
         var livemap_url = 'https://world.waze.com/livemap/?zoom='+livemap_zoom+'&lat='+lat+'&lon='+lon+'&layers=BTTTT';
         // Modify existing livemap link to reference current position in WME
         document.getElementById("livemap").href = livemap_url;
         document.getElementById("livemap").target = '_blank';

         // "borrow" the Bing attribution div to insert the new clicky-links, remembering to maintain the attribution after we're done messing with it!
         var pl_colour = document.defaultView.getComputedStyle(document.getElementById("map-footer"),"").getPropertyValue("color");
         document.getElementById("bing-attribution").innerHTML = ' <a href="'+osod_url+'" target=_osopendata style="color:' + pl_colour +'">OS OpenData</a> | <a href="'+osmc_url+'" target=_osmusicalchairs style="color:' + pl_colour +'">OS Musical Chairs</a> | Imagery by Bing';

         // uncomment these lines if you want the OpenData and/or MusicalChairs tabs to auto-follow the WME location...
         // window.open(osod_url,'_osopendata');
         // window.open(osmc_url,'_osmusicalchairs');
      }
   }
}

// initialise persistent vars
sessionStorage.zoom = 0;
sessionStorage.lat = '';
sessionStorage.lon = '';

// check for new map co-ords every 250ms
setInterval(processPermalink,250);
Changes:
* Top navbar link back to the livemap uses WME location (Dave2084)
* OSMC/OSOD links copy style from permalink (Dave2084)
* OpenData and MusicalChairs links reuse any existing tabs/windows (Timbones)

Not enabled by default, uncomment the last two lines in the processPermalink() function:
* OpenData and MusicalChairs tabs/windows automatically track WME position (xteejx)

I didn't enable this last change by default since I'm not entirely sure I like it - if the extents of the OSOD map viewport exactly matched that of the WME viewport for all zoom levels, it might work well, but there are often times when the mismatch between the two viewports means that I only need to drag the WME map a little to expose a road which is still visible on the OSOD map (don't really use OSMC so I'm not sure if that is any better in this respect), and I wouldn't then want OSOD to reload. Comments are welcomed from anyone who does try it out!
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK

Code: Select all

// ==UserScript==
// @name                WME to OS link
// @namespace           http://greasemonkey.chizzum.com
// @description         Adds link to WME to open up various mapping sites at the same map location
// @include             https://world.waze.com/editor/*
// @include             https://descartesw.waze.com/beta/*
// @version             0.4
// ==/UserScript==


// Modified from the original (c) Chris Veness 2005-2012
//   www.movable-type.co.uk/scripts/gridref.js
//   www.movable-type.co.uk/scripts/latlon-gridref.html
function toOSGrid(lat, lon)
{
   lat = (lat * Math.PI) / 180;
   lon = (lon * Math.PI) / 180;

   // Airy 1830 major & minor semi-axes
   var a = 6377563.396;
   var b = 6356256.910;
   // NatGrid scale factor on central meridian
   var F0 = 0.9996012717;
   // NatGrid true origin is 49N,2W
   var lat0 = 0.85521;
   var lon0 = -0.0349;
   // northing & easting of true origin, metres
   var N0 = -100000;
   var E0 = 400000;
   // eccentricity squared
   var e2 = 1 - (b*b)/(a*a);

   var n = (a-b)/(a+b);
   var n2 = n*n;
   var n3 = n*n*n;
   var cosLat = Math.cos(lat);
   var sinLat = Math.sin(lat);
   // transverse radius of curvature
   var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);
   // meridional radius of curvature
   var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);
   var eta2 = nu/rho-1;
   var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
   var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
   var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
   var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
   // meridional arc
   var M = b * F0 * (Ma - Mb + Mc - Md);
   var cos3lat = cosLat*cosLat*cosLat;
   var cos5lat = cos3lat*cosLat*cosLat;
   var tan2lat = Math.tan(lat)*Math.tan(lat);
   var tan4lat = tan2lat*tan2lat;
   var I = M + N0;
   var II = (nu/2)*sinLat*cosLat;
   var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2);
   var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat);
   var IV = nu*cosLat;
   var V = (nu/6)*cos3lat*(nu/rho-tan2lat);
   var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2);
   var dLon = lon-lon0;
   var dLon2 = dLon*dLon;
   var dLon3 = dLon2*dLon;
   var dLon4 = dLon3*dLon;
   var dLon5 = dLon4*dLon;
   var dLon6 = dLon5*dLon;
   var N = Math.round(I + II*dLon2 + III*dLon4 + IIIA*dLon6);
   var E = Math.round(E0 + IV*dLon + V*dLon3 + VI*dLon5);
   return '?e='+E+'&n='+N;
}


function processPermalink()
{
   // extract current lat/lon & zoom level from the permalink URL
   var plsrc = document.getElementById("permalink-container").innerHTML;
   var zoompos = plsrc.indexOf("?zoom=");
   var latpos = plsrc.indexOf("&lat=");
   var lonpos = plsrc.indexOf("&lon=");
   var layerpos = plsrc.indexOf("&layers=");

   // does the URL contain all three parameters?
   if((zoompos != -1)&&(latpos != -1)&&(lonpos != -1)&&(layerpos != -1))
   {
      // yes, so extract them...
      var zoom = parseInt(plsrc.substr(zoompos+6,latpos-(zoompos+6)));
      var lat = plsrc.substr(latpos+9,lonpos-(latpos+9));
      var lon = plsrc.substr(lonpos+9,layerpos-(lonpos+9));

      // compare the freshly extracted parameters against the persistent copies, and update the
      // links to OSMC & OSOD only if there's a change required - the newly-inserted <a> element
      // can't be clicked on until the insertion process is complete, and if we were to re-insert
      // it every 250ms then it'd spend a lot of its time giving the appearance of being clickable
      // but without actually doing anything...
      if((zoom != sessionStorage.zoom)||(lat != sessionStorage.lat)||(lon != sessionStorage.lon))
      {
         // update the persistent vars with the new position
         sessionStorage.zoom = zoom;
         sessionStorage.lat = lat;
         sessionStorage.lon = lon;

         // translate the zoom level between WME and Musical Chairs - this gives a pretty close match
         var mczoom = zoom + 12;
         if(mczoom > 18) mczoom = 18;
         // generate the Musical Chairs URL
         var osmc_url = 'http://ris.dev.openstreetmap.org/oslmusicalchairs/map?zoom='+mczoom+'&lat='+lat+'&lon='+lon+'&layers=B0TT&view_mode=pseudorandom';

         // translate the zoom level between WME and OpenData - the match here isn't quite so good...
         var odzoom = zoom + 5;
         if(odzoom < 6) odzoom = 6;
         if(odzoom > 10) odzoom = 10;
         // generate the OpenData URL - requires the support of os_opendata_fullheight.user.js
         var osod_url = 'http://www.ordnancesurvey.co.uk/oswebsite/opendata/viewer/'+toOSGrid(lat,lon)+'&z='+odzoom;

         // generate the Cartouche URL
         var cartouche_url = 'http://world.waze.com/cartouche_old/?zoom='+zoom+'&lon='+lon+'&lat='+lat;

         // translate the zoom level between WME and live map.  The only correlation is (WME)=[Live] (0 or 1)=[7], (2 or 3)=[8], (4 or more)=[9]
         var livemap_zoom = Math.floor(zoom/2)+7;
         if (livemap_zoom > 9 ) livemap_zoom = 9;
         var livemap_url = 'https://world.waze.com/livemap/?zoom='+livemap_zoom+'&lat='+lat+'&lon='+lon+'&layers=BTTTT';
         // Modify existing livemap link to reference current position in WME
         document.getElementById("livemap").href = livemap_url;
         document.getElementById("livemap").target = '_blank';

         // update the link URLs
         document.getElementById("_linkOSOD").href = osod_url;
         document.getElementById("_linkOSMC").href = osmc_url;
         document.getElementById("_linkCartouche").href = cartouche_url;

         // refresh any of the site tabs/windows we've checked for auto-tracking
         if(document.getElementById('_cbAutoTrackOSOD').checked == 1) window.open(osod_url,'_osopendata');
         if(document.getElementById('_cbAutoTrackOSMC').checked == 1) window.open(osmc_url,'_osmusicalchairs');
         if(document.getElementById('_cbAutoTrackCartouche').checked == 1) window.open(cartouche_url,'_cartouche');
      }
   }
}

// initialise persistent vars
sessionStorage.zoom = 0;
sessionStorage.lat = '';
sessionStorage.lon = '';

// get the colour attribute for the permalink, so that our new links are visually consistent
var pl_colour = document.defaultView.getComputedStyle(document.getElementById("map-footer"),"").getPropertyValue("color");
// create a new child div in the existing map footer div, so we don't have to borrow the bing attrinution one any more...
var mlcDiv = document.createElement('div');
mlcDiv.setAttribute('id','MapLinkControls');
// add the anchors and auto-track checkboxes for OS OpenData, Musical Chairs and Cartouche.  Note that the urls are blank at this stage,
// they'll be filled in as soon as we've done our first processPermalink() call
mlcDiv.innerHTML = '<a href="" id="_linkOSOD" target=_osopendata style="color:' + pl_colour +'">OS OpenData</a> <input type="checkbox" id="_cbAutoTrackOSOD"></input> | ';
mlcDiv.innerHTML += '<a href="" id="_linkOSMC" target=_osmusicalchairs style="color:' + pl_colour +'">OS Musical Chairs</a> <input type="checkbox" id="_cbAutoTrackOSMC"></input> | ';
mlcDiv.innerHTML += '<a href="" id="_linkCartouche" target=_cartouche style="color:' + pl_colour +'">Cartouche</a> <input type="checkbox" id="_cbAutoTrackCartouche"></input>';
mlcDiv.innerHTML += '<br>(Checkboxes enable auto-tracking)';
document.getElementById('map-footer').appendChild(mlcDiv);

// set up a check for new map co-ords every 250ms
setInterval(processPermalink,250);
On the "what's new" menu for today...
  • Enabled for descartes - I can't fully test it as I don't have a login, but I at least can see the new links are being inserted as expected, so it looks as if it'll work ok...
  • Added link to Cartouche
  • Moved links over to left of screen in their own div
  • Added checkboxes to enable auto-tracking without requiring any code edits - if the relevant box is ticked, that site will be reloaded each time the script detects a change in the current map position/zoom level
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
Now uploaded both scripts to userscripts.org
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png

Post by Twister-UK
Yep, I always test for compatibility with whatever the current release versions are of FF and Chrome for Win7, and so unless stated otherwise then I expect them to behave the same in either browser.

Now that they're on userscripts I don't think there should be any installation issues if you're just using the unmodified code, but if you've got it saved locally for tweaking purposes, then provided you remember to add the .user.js double-suffix onto the filename, you can also simply drag and drop the file onto FF or Chrome to invoke the script installation process.
Twister-UK
Waze Local Champs
Waze Local Champs
Posts: 4698
Answers: 2
Has thanked: 743 times
Been thanked: 4737 times
Send a message
Chris (not to be confused with Chris or Chris, or even Tim, Stu, or any of the other champs team...)
AM SE England & Shetland Islands, UK Local Champ, WME Beta Tester & ScriptMangler
WME/Livemap enhancement scripts @ GreasyFork


https://chizzum.com/greasemonkey/images/beta.pnghttps://chizzum.com/greasemonkey/images/s0400.pnghttps://chizzum.com/greasemonkey/images/c5s.png