Post by Twister-UK
Ooh, thanks Tim, I'll test that tonight - would be nice to start editing on Chrome again, I'd forgotten just how frustrating the Firefox "wave mouse pointer around until the horizontal segment gets highlighted" issue was...
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
Bah humbug, Chrome is still a no-go zone :cry:

Tim's suggestion allows the OS data to be retrieved in Firefox without using the @require directive, but in its current form it doesn't appear to do anything in Chrome. However, Firefox testing threw up a much bigger issue - whereas @require caches the data locally during the script installation, this workaround downloads the data every time you (re)load the WME page, and at 120MB that's a lot of data to be grabbing every time you start up an editing session, or reload the page to kick WME back into life after it goes loopy again...

Thanks again for the suggestion Tim, but alas it's back to the drawing board as far as Chrome support goes, and back to editing in Firefox.
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
Haven't yet looked at Chrome compatibility again, been a little bit busy with other tweaks. Tonights update is therefore brought to you courtesy of three little words.

Bounding. Box. Visualisation...

The placement of the bounding box highlight is sometimes a bit off, but it's generally good enough to leave the user in no doubt as to which street name refers to the highlighted segment. If anyone notices the placement being significantly off in a certain area, please reply with a permalink and I'll see if I can fine tune the coordinate conversion.

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://world.waze.com/map-editor/*
// @include             https://descartesw.waze.com/beta/*
// @require             http://greasemonkey.chizzum.com/osl_10km.js
// @version             0.8.3
// ==/UserScript==

// Contains Ordnance Survey data Crown copyright and database right 2012
// Contents of the osl_10km.js file are derived under the Open Government Licence from the OS Locator dataset


//-----------------------------------------------------------------------------------------------------------------------------------------
// all code between here and the next ------------- marker line is a stripped down version of the original from Paul Dixon
//
// * GeoTools javascript coordinate transformations
// * http://files.dixo.net/geotools.html
// *
// * This file copyright (c)2005 Paul Dixon (paul@elphin.com)
// *
// * This program is free software; you can redistribute it and/or
// * modify it under the terms of the GNU General Public License
// * as published by the Free Software Foundation; either version 2
// * of the License, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program; if not, write to the Free Software
// * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// *
// * ---------------------------------------------------------------------------
// *
// * Credits
// *
// * The algorithm used by the script for WGS84-OSGB36 conversions is derived
// * from an OSGB spreadsheet (www.gps.gov.uk) with permission. This has been
// * adapted into Perl by Ian Harris, and into PHP by Barry Hunter. Conversion
// * accuracy is in the order of 7m for 90% of Great Britain, and should be
// * be similar to the conversion made by a typical GPSr
// *
// * See accompanying documentation for more information
// * http://files.dixo.net/geotools.html

var northings;
var eastings;
var latitude;
var longitude;

var helmX, helmY, helmZ;
var Pi = 3.14159265358979;

function wgs_to_osgb()
{
	LatLon_to_HelmXYZ();
   var latitude2  = XYZ_to_Lat();
	var longitude2 = Math.atan2(helmY , helmX) * (180 / Pi);
	LatLon_to_OSGrid(latitude2,longitude2);
}

function LatLon_to_HelmXYZ()
{
   var a = 6378137.0;
   var b = 6356752.313;
   var DX = -446.448;
   var DY = 125.157;
   var DZ = -542.060;
   var rotX = -0.1502;
   var rotY = -0.2470;
   var rotZ = -0.8421;
	var sfactor = 20.4894 * 0.000001;

   // perform initial lat-lon to cartesian coordinate translation
   var RadPHI = latitude * (Pi / 180);
   var RadLAM = longitude * (Pi / 180);
   var e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
   var V = a / (Math.sqrt(1 - (e2 * (  Math.pow(Math.sin(RadPHI),2)))));
   var cartX = V * (Math.cos(RadPHI)) * (Math.cos(RadLAM));
   var cartY = V * (Math.cos(RadPHI)) * (Math.sin(RadLAM));
   var cartZ = (V * (1 - e2)) * (Math.sin(RadPHI));

   // Compute Helmert transformed coordinates
	var RadX_Rot = (rotX / 3600) * (Pi / 180);
	var RadY_Rot = (rotY / 3600) * (Pi / 180);
	var RadZ_Rot = (rotZ / 3600) * (Pi / 180);
   helmX = (cartX + (cartX * sfactor) - (cartY * RadZ_Rot) + (cartZ * RadY_Rot) + DX);
	helmY = (cartX * RadZ_Rot) + cartY + (cartY * sfactor) - (cartZ * RadX_Rot) + DY;
	helmZ = (-1 * cartX * RadY_Rot) + (cartY * RadX_Rot) + cartZ + (cartZ * sfactor) + DZ;
}

function XYZ_to_Lat()
{
   var a = 6377563.396;
   var b = 6356256.910;
   var RootXYSqr = Math.sqrt(Math.pow(helmX,2) + Math.pow(helmY,2));
   var e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
   var PHI1 = Math.atan2(helmZ , (RootXYSqr * (1 - e2)) );
   var PHI = Iterate_XYZ_to_Lat(a, e2, PHI1, helmZ, RootXYSqr);
   return PHI * (180 / Pi);
}

function Iterate_XYZ_to_Lat(a, e2, PHI1, Z, RootXYSqr)
{
   var V = a / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(PHI1),2))));
   var PHI2 = Math.atan2((Z + (e2 * V * (Math.sin(PHI1)))) , RootXYSqr);
   while (Math.abs(PHI1 - PHI2) > 0.000000001)
   {
      PHI1 = PHI2;
      V = a / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(PHI1),2))));
      PHI2 = Math.atan2((Z + (e2 * V * (Math.sin(PHI1)))) , RootXYSqr);
   }
   return PHI2;
}

function Marc(bf0, n, PHI0, PHI)
{
   return bf0 * (((1 + n + ((5 / 4) * Math.pow(n,2)) + ((5 / 4) * Math.pow(n,3))) * (PHI - PHI0)) - (((3 * n) + (3 * Math.pow(n,2)) +
          ((21 / 8) * Math.pow(n,3))) * (Math.sin(PHI - PHI0)) * (Math.cos(PHI + PHI0))) + ((((15 / 8) * Math.pow(n,2)) + ((15 / 8) *
          Math.pow(n,3))) * (Math.sin(2 * (PHI - PHI0))) * (Math.cos(2 * (PHI + PHI0)))) - (((35 / 24) * Math.pow(n,3)) *
          (Math.sin(3 * (PHI - PHI0))) * (Math.cos(3 * (PHI + PHI0)))));
}

function LatLon_to_OSGrid(PHI, LAM)
{
   var a = 6377563.396;
   var b = 6356256.910;
   var e0 = 400000;
   var n0 = -100000;
   var f0 = 0.999601272;
   var PHI0 = 49.00000;
   var LAM0 = -2.00000;

   var RadPHI = PHI * (Pi / 180);
   var RadLAM = LAM * (Pi / 180);
   var RadPHI0 = PHI0 * (Pi / 180);
   var RadLAM0 = LAM0 * (Pi / 180);
   var af0 = a * f0;
   var bf0 = b * f0;
   var e2 = (Math.pow(af0,2) - Math.pow(bf0,2)) / Math.pow(af0,2);
   var n = (af0 - bf0) / (af0 + bf0);
   var nu = af0 / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(RadPHI),2) )));
   var rho = (nu * (1 - e2)) / (1 - (e2 * Math.pow(Math.sin(RadPHI),2) ));
   var eta2 = (nu / rho) - 1;
   var p = RadLAM - RadLAM0;
   var M = Marc(bf0, n, RadPHI0, RadPHI);
   var I = M + n0;
   var II = (nu / 2) * (Math.sin(RadPHI)) * (Math.cos(RadPHI));
   var III = ((nu / 24) * (Math.sin(RadPHI)) * (Math.pow(Math.cos(RadPHI),3))) * (5 - (Math.pow(Math.tan(RadPHI),2)) + (9 * eta2));
   var IIIA = ((nu / 720) * (Math.sin(RadPHI)) * (Math.pow(Math.cos(RadPHI),5))) * (61 - (58 * (Math.pow(Math.tan(RadPHI),2))) + (Math.pow(Math.tan(RadPHI),4)));
   var IV = nu * (Math.cos(RadPHI));
   var V = (nu / 6) * ( Math.pow(Math.cos(RadPHI),3)) * ((nu / rho) - (Math.pow(Math.tan(RadPHI),2)));
   var VI = (nu / 120) * (Math.pow(Math.cos(RadPHI),5)) * (5 - (18 * (Math.pow(Math.tan(RadPHI),2))) + (Math.pow(Math.tan(RadPHI),4)) + (14 * eta2) - (58 * (Math.pow(Math.tan(RadPHI),2)) * eta2));
   eastings = Math.round(e0 + (p * IV) + (Math.pow(p,3) * V) + (Math.pow(p,5) * VI));
   northings = Math.round(I + (Math.pow(p,2) * II) + (Math.pow(p,4) * III) + (Math.pow(p,6) * IIIA));
}
//-----------------------------------------------------------------------------------------------------------------------------------------

function caseCorrect(wrongcase)
{
   var loop;
   var correctedCase = '';
   for(loop=0;loop<wrongcase.length;loop++)
   {
      if((loop == 0)||(wrongcase[loop-1] == ' ')||(wrongcase[loop-1] == '(')) correctedCase += wrongcase[loop].toUpperCase();
      else correctedCase += wrongcase[loop].toLowerCase();
   }
   return correctedCase;
}


function wazeifyStreetName(oslName)
{
   var wazeName = '';
   var loop;

   wazeName = caseCorrect(oslName);

   var namePieces = wazeName.split(' ');
   if(namePieces.length > 1)
   {
      var roadType;
      var dirSuffix;
      var thePrefix;
      var namePrefix = '';
      if((namePieces[namePieces.length-1] == 'North')||(namePieces[namePieces.length-1] == 'South')||(namePieces[namePieces.length-1] == 'East')||(namePieces[namePieces.length-1] == 'West'))
      {
         dirSuffix = namePieces[namePieces.length-1][0];
         roadType = namePieces[namePieces.length-2];
         if(namePieces.length > 2)
         {
            if(namePieces[namePieces.length-3] == 'The') thePrefix = true;
            else thePrefix = false;
         }
         for(loop=0;loop<namePieces.length-2;loop++) namePrefix += (namePieces[loop] + ' ');
      }
      else
      {
         dirSuffix = '';
         roadType = namePieces[namePieces.length-1];
         if(namePieces[namePieces.length-2] == 'The') thePrefix = true;
         else thePrefix = false;
         for(loop=0;loop<namePieces.length-1;loop++) namePrefix += (namePieces[loop] + ' ');

      }
      if(thePrefix == false)
      {
         roadType = roadType.replace('Avenue','Ave');
         roadType = roadType.replace('Boulevard','Blvd');
         roadType = roadType.replace('Broadway','Bdwy');
         roadType = roadType.replace('Close','Cl');
         roadType = roadType.replace('Court','Ct');
         roadType = roadType.replace('Crescent','Cr');
         roadType = roadType.replace('Drive','Dr');
         roadType = roadType.replace('Gardens','Gdns');
         roadType = roadType.replace('Garden','Gdn');
         roadType = roadType.replace('Green','Gn');
         roadType = roadType.replace('Grove','Gr');
         roadType = roadType.replace('Lane','Ln');
         roadType = roadType.replace('Mount','Mt');
         roadType = roadType.replace('Place','Pl');
         roadType = roadType.replace('Park','Pk');
         roadType = roadType.replace('Road','Rd');
         roadType = roadType.replace('Square','Sq');
         roadType = roadType.replace('Street','St');
         roadType = roadType.replace('Terrace','Ter');
      }
      wazeName = namePrefix + roadType + ' ' + dirSuffix;
   }
   return wazeName;
}


function cpDistance(cpE, cpN, posE, posN)
{
   return Math.sqrt(((posE - cpE) * (posE - cpE)) + ((posN - cpN) * (posN - cpN)));
}

function gradMinRatio(bbW, bbE, bbS, bbN, posE, posN)
{
   var gradPosToSW = (posN - bbS) / (posE - bbW);
   var gradPosToSE = (posN - bbS) / (posE - bbE);
   var gradNEToSW = (bbN - bbS) / (bbE - bbW);
   var gradNWToSE = (bbN - bbS) / (bbW - bbE);

   var ratioSW = gradPosToSW / gradNEToSW;
   var ratioSE = gradPosToSE / gradNWToSE;
   if(ratioSW < 1) ratioSW = 1 / ratioSW;
   if(ratioSE < 1) ratioSE = 1 / ratioSE;
   if(ratioSW < ratioSE) return ratioSW;
   else return ratioSE;
}

var vpLeft = 0;
var vpRight = 0;
var vpBottom = 0;
var vpTop = 0;

function visualiseBoundingBox(boxW, boxE, boxS, boxN)
{
   if(boxW < vpLeft) boxW = vpLeft;
   if(boxE >  vpRight) boxE = vpRight;
   if(boxS < vpBottom) boxS = vpBottom;
   if(boxN > vpTop) boxN = vpTop;

   boxE -= vpLeft;
   boxW -= vpLeft;
   boxS = vpTop - boxS;
   boxN = vpTop - boxN;

   var wmeScale = 22550 / (950 * Math.pow(2,sessionStorage.zoom));
   boxE /= wmeScale;
   boxW /= wmeScale;
   boxS /= wmeScale;
   boxN /= wmeScale;

   boxE = Math.round(boxE);
   boxW = Math.round(boxW);
   boxS = Math.round(boxS);
   boxN = Math.round(boxN);

   var svgSrc = '<svg xmlns="http://www.w3.org/2000/svg" width="'+document.getElementById('WazeMap').offsetWidth+'px" height="'+document.getElementById('WazeMap').offsetHeight+'px" version="1.1">';
   svgSrc += '<rect x="'+boxW+'" y="'+boxN+'" width="'+((boxE-boxW)*1.1)+'" height="'+((boxS-boxN)*1.1)+'" style="fill:yellow;stroke:pink;stroke-width:4;fill-opacity:1;stroke-opacity:1"/>';
   svgSrc += '</svg>';
   bbDiv.innerHTML = svgSrc;
}


function radioClick()
{
   var oslElements = document.getElementById('oslDiv');
   for(var loop=0;loop<oslElements.childNodes.length;loop++)
   {
      if(oslElements.childNodes[loop].nodeType == 1)
      {
         attr = oslElements.childNodes[loop].attributes.getNamedItem("type");
         if(attr != null)
         {
            if(attr.value == "radio")
            {
               if(oslElements.childNodes[loop].checked)
               {
                  attr = oslElements.childNodes[loop].attributes.getNamedItem("id").value;
                  oslID = attr.split('_');
                  evalstr = 'var roadData = locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
                  eval(evalstr);
                  var locatorElements = roadData.split(":");

                  visualiseBoundingBox(locatorElements[4],locatorElements[5],locatorElements[6],locatorElements[7])
               }
            }
         }
      }
   }
}


function oslClick()
{
   var cityName = caseCorrect(document.getElementById('myCityName').value);
   sessionStorage.myCity = cityName;
   var oslElements = document.getElementById('oslDiv');
   for(var loop=0;loop<oslElements.childNodes.length;loop++)
   {
      if(oslElements.childNodes[loop].nodeType == 1)
      {
         attr = oslElements.childNodes[loop].attributes.getNamedItem("type");
         if(attr != null)
         {
            if(attr.value == "radio")
            {
               if(oslElements.childNodes[loop].checked)
               {
                  attr = oslElements.childNodes[loop].attributes.getNamedItem("id").value;
                  oslID = attr.split('_');
                  evalstr = 'var roadData = locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
                  eval(evalstr);
                  var locatorElements = roadData.split(":");

                  // auto-click the Edit Address link...
                  var editAddress = document.getElementById('editSegmentsApplyChanges');
                  var editButtons = editAddress.getElementsByClassName('edit-button');
                  editButtons[0].click();

                  // fill in the City field
                  //oslName = caseCorrect(locatorElements[9]);
                  //if(locatorElements[8].length > 0) oslName += ' ('+caseCorrect(locatorElements[8])+')';
                  var snelms = document.getElementsByName('cityName');
                  //snelms[0].value = oslName;
                  snelms[0].value = cityName;
                  snelms[0].disabled = false;
                  snelms = document.getElementsByName('emptyCity');
                  snelms[0].checked = false;

                  // and the Street field
                  oslName = locatorElements[1];
                  if((locatorElements[0].length > 0)&&(locatorElements[1].length > 0)) oslName += ' - ';
                  oslName += wazeifyStreetName(locatorElements[0]);

                  snelms = document.getElementsByName('streetName');
                  snelms[0].value = oslName;
                  snelms[0].disabled = false;
                  snelms = document.getElementsByName('emptyStreet');
                  snelms[0].checked = false;

                  bbDiv.innerHTML = '';
               }
            }
         }
      }
   }
}


function oslMatch(oslLink, oslDistance, oslMinGradRatio, oslRadioID)
{
   this.oslLink = oslLink;
   this.oslDistance = oslDistance;
   this.oslMinGradRatio = oslMinGradRatio;
   this.oslRadioID = oslRadioID;
}
function sortCandidates(a,b)
{
   var x = a.oslDistance;
   var y = b.oslDistance;
   return((x<y) ? -1 : ((x>y) ? 1 : 0));
}

function toOSGrid(lat, lon, mode)
{
   latitude = lat;
   longitude = lon;
   wgs_to_osgb();

   if(mode == 1)  // OS Locator lookup
   {
      // determine which 10km grid block contains the current WME centrepoint
      var eBlock = (Math.floor(eastings/10000)) * 10000;
      var nBlock = (Math.floor(northings/10000)) * 10000;
      // check to see if there's a corresponding array in the osl_10km data
      var evalstr = 'typeof locatorData_'+eBlock+'_'+nBlock;
      if(eval(evalstr) != "undefined")
      {
         // yes...  make a local copy to avoid having an eval() in each iteration of the loop
         evalstr = 'var blockData = locatorData_'+eBlock+'_'+nBlock;
         eval(evalstr);
         oslDiv.innerHTML = 'OSL matches at '+eastings+','+northings+':<br>';
         var candidates = new Array();

         for(var loop = 0;loop < blockData.length; loop++)
         {
            // for each entry in the array, test the centrepoint position to see if it lies within the bounding box for that entry
            // note that we allow a 10m tolerance on all sides of the box to allow for inaccuracies in the latlon->gridref conversion,
            // and to increase the chance of a successful match when the road runs E-W or N-S and thus has a long but narrow bounding box
            var locatorElements = blockData[loop].split(":");

            var bbW = parseInt(locatorElements[4]);
            var bbE = parseInt(locatorElements[5]);
            var bbS = parseInt(locatorElements[6]);
            var bbN = parseInt(locatorElements[7]);
            if((eastings>=(bbW-10))&&(eastings<=(bbE+10))&&(northings>=(bbS-10))&&(northings<=(bbN+10)))
            {
               var radioID = 'oslID_'+eBlock+'_'+nBlock+'_'+loop;
               var oslLink = '<input type="radio" name="oslChoice" id="'+radioID+'"></input>';
               if(locatorElements[1].length > 0)
               {
                  oslLink += locatorElements[1];
                  if(locatorElements[0].length > 0)
                  {
                     oslLink += ' - ';
                  }
               }
               oslLink += wazeifyStreetName(locatorElements[0])+'<br>';
               var dist = cpDistance(parseInt(locatorElements[2]),parseInt(locatorElements[3]),eastings,northings);
               var ratio = gradMinRatio(bbW, bbE, bbS, bbN, eastings, northings);
               candidates[candidates.length++] = new oslMatch(oslLink,dist,ratio,radioID);
            }
         }
         if(candidates.length > 0)
         {
            if(candidates.length > 1) candidates.sort(sortCandidates);
            for(var loop=0;loop<candidates.length;loop++)
            {
               oslDiv.innerHTML += candidates[loop].oslLink;
               //oslDiv.innerHTML += candidates[loop].oslLink + candidates[loop].oslDistance + ' ' + candidates[loop].oslMinGradRatio + '<br>';
            }
            oslDiv.innerHTML += '<br>City: <input id="myCityName" type="text" value="'+sessionStorage.myCity+'"/><br>';
            oslDiv.innerHTML += '<br><input id="oslSelect" type="button" value="Copy to Properties" />';
            document.getElementById('oslSelect').addEventListener("click", oslClick, true);
            for(var loop=0;loop<candidates.length;loop++)
            {
               document.getElementById(candidates[loop].oslRadioID).addEventListener("click", radioClick, true);
            }
         }
      }
   }
   else return '?e='+eastings+'&n='+northings;
}

function processPermalink()
{
   var mousepos = document.getElementById("OpenLayers.Control.MousePosition_26").innerHTML;
   if(mousepos != sessionStorage.mousepos)
   {
      sessionStorage.mousepos = mousepos;
      if(document.getElementById("editPanel").innerHTML.indexOf("editSegmentStreetDetailsForm") == -1)  // segment properties panel isn't open...
      {
         if
         (
            (document.getElementById("OpenLayers.Layer.Vector.RootContainer_221").innerHTML.indexOf('#03b9da') != -1) || // ...and segment is highlighted
            (document.getElementById("OpenLayers.Layer.Vector.RootContainer_221").innerHTML.indexOf('#ff3300') != -1)
         )
         {
            // so update the OS Locator matches
            mouselatlon = mousepos.split(",");
            toOSGrid(mouselatlon[1],mouselatlon[0],1);
         }
      }
   }

   // 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)));

      // accommodate both the original permalink ordering of zoom, lat then lon, and the present
      // ordering (as of early July 2012) of zoom, lon then lat...
      if(latpos < lonpos)
      {
         var lat = plsrc.substr(latpos+9,lonpos-(latpos+9));
         var lon = plsrc.substr(lonpos+9,layerpos-(lonpos+9));
      }
      else
      {
         var lat = plsrc.substr(latpos+9,layerpos-(latpos+9));
         var lon = plsrc.substr(lonpos+9,latpos-(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,0)+'&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');

         // recalculate the map viewport extents in terms of eastings/northings
         var viewportWidth = document.getElementById('WazeMap').offsetWidth;
         var viewportHeight = document.getElementById('WazeMap').offsetHeight;
         var wmeScale = 22550 / (950 * Math.pow(2,sessionStorage.zoom));
         var vpHalfWidth = Math.round((viewportWidth * wmeScale) / 2);
         var vpHalfHeight = Math.round((viewportHeight * wmeScale) / 2);
         vpLeft = eastings - vpHalfWidth;
         vpRight = eastings + vpHalfWidth;
         vpBottom = northings - vpHalfHeight;
         vpTop = northings + vpHalfHeight;
         bbDiv.innerHTML = '';
      }
   }
}

// 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 attribution 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);

// add a new div to the edit properties panel, to hold the OS Locator results
var oslDiv = document.createElement('div');
oslDiv.id = "oslDiv";
oslDiv.style.backgroundColor = '#DDFFDD';
document.getElementById('editPanel').appendChild(oslDiv);

// add a new div to the map viewport, to hold the bounding box SVG
var bbDiv = document.createElement('div');
bbDiv.id = "bbDiv";
bbDiv.style.position = 'absolute';
bbDiv.style.top = '0';
bbDiv.style.left = '0';
bbDiv.style.width = document.getElementById('WazeMap').offsetWidth;
bbDiv.style.height = document.getElementById('WazeMap').offsetHeight;
bbDiv.style.zIndex = 100;
document.getElementById('WazeMap').appendChild(bbDiv);

// set up a 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
Thanks to the help given by Timbones, we're now good to go in Chrome :D Note that in Chrome (and Firefox if you're using Noscript or some other scripting blocker), you'll need to allow scripting access to chizzum.com whilst in WME in order for the OS Locator data to be downloaded on the fly - you don't want to know how long it took me to realise why Tim's code didn't seem to be working, or the magnitude of the "doh" event once the penny finally dropped :oops:

In other news...

The city field is now genuinely ignored if it's blank - I'd always intended it to work this way (as one of my earlier posts implied), and now it does... It also no longer gets initialised to "null".

The bounding box highlight is now cleared whenever a new segment is highlighted.

Bounding box positioning has been tweaked slightly, and a minimum height/width limit of 20 pixels is now enforced to avoid visibility problems when the road segment defined by the box runs exactly or very nearly E-W or N-S

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://world.waze.com/map-editor/*
// @include             https://descartesw.waze.com/beta/*
// @version             0.8.4
// ==/UserScript==

// Contains Ordnance Survey data Crown copyright and database right 2012
// Contents of the osl_10km.js file are derived under the Open Government Licence from the OS Locator dataset

//-----------------------------------------------------------------------------------------------------------------------------------------
// all code between here and the next ------------- marker line is taken from stackoverflow
// From: http://stackoverflow.com/questions/1622145/how-can-i-mimic-greasemonkey-firefoxs-unsafewindow-functionality-in-chrome
//
// 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.
//
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 ();
      }
   ) ();
}
//-----------------------------------------------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------------------------------------------
// all code between here and the next ------------- marker line is a stripped down version of the original from Paul Dixon
//
// * GeoTools javascript coordinate transformations
// * http://files.dixo.net/geotools.html
// *
// * This file copyright (c)2005 Paul Dixon (paul@elphin.com)
// *
// * This program is free software; you can redistribute it and/or
// * modify it under the terms of the GNU General Public License
// * as published by the Free Software Foundation; either version 2
// * of the License, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program; if not, write to the Free Software
// * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// *
// * ---------------------------------------------------------------------------
// *
// * Credits
// *
// * The algorithm used by the script for WGS84-OSGB36 conversions is derived
// * from an OSGB spreadsheet (www.gps.gov.uk) with permission. This has been
// * adapted into Perl by Ian Harris, and into PHP by Barry Hunter. Conversion
// * accuracy is in the order of 7m for 90% of Great Britain, and should be
// * be similar to the conversion made by a typical GPSr
// *
// * See accompanying documentation for more information
// * http://files.dixo.net/geotools.html

var northings;
var eastings;
var latitude;
var longitude;

var helmX, helmY, helmZ;
var Pi = 3.14159265358979;

function wgs_to_osgb()
{
	LatLon_to_HelmXYZ();
   var latitude2  = XYZ_to_Lat();
	var longitude2 = Math.atan2(helmY , helmX) * (180 / Pi);
	LatLon_to_OSGrid(latitude2,longitude2);
}

function LatLon_to_HelmXYZ()
{
   var a = 6378137.0;
   var b = 6356752.313;
   var DX = -446.448;
   var DY = 125.157;
   var DZ = -542.060;
   var rotX = -0.1502;
   var rotY = -0.2470;
   var rotZ = -0.8421;
	var sfactor = 20.4894 * 0.000001;

   // perform initial lat-lon to cartesian coordinate translation
   var RadPHI = latitude * (Pi / 180);
   var RadLAM = longitude * (Pi / 180);
   var e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
   var V = a / (Math.sqrt(1 - (e2 * (  Math.pow(Math.sin(RadPHI),2)))));
   var cartX = V * (Math.cos(RadPHI)) * (Math.cos(RadLAM));
   var cartY = V * (Math.cos(RadPHI)) * (Math.sin(RadLAM));
   var cartZ = (V * (1 - e2)) * (Math.sin(RadPHI));

   // Compute Helmert transformed coordinates
	var RadX_Rot = (rotX / 3600) * (Pi / 180);
	var RadY_Rot = (rotY / 3600) * (Pi / 180);
	var RadZ_Rot = (rotZ / 3600) * (Pi / 180);
   helmX = (cartX + (cartX * sfactor) - (cartY * RadZ_Rot) + (cartZ * RadY_Rot) + DX);
	helmY = (cartX * RadZ_Rot) + cartY + (cartY * sfactor) - (cartZ * RadX_Rot) + DY;
	helmZ = (-1 * cartX * RadY_Rot) + (cartY * RadX_Rot) + cartZ + (cartZ * sfactor) + DZ;
}

function XYZ_to_Lat()
{
   var a = 6377563.396;
   var b = 6356256.910;
   var RootXYSqr = Math.sqrt(Math.pow(helmX,2) + Math.pow(helmY,2));
   var e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
   var PHI1 = Math.atan2(helmZ , (RootXYSqr * (1 - e2)) );
   var PHI = Iterate_XYZ_to_Lat(a, e2, PHI1, helmZ, RootXYSqr);
   return PHI * (180 / Pi);
}

function Iterate_XYZ_to_Lat(a, e2, PHI1, Z, RootXYSqr)
{
   var V = a / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(PHI1),2))));
   var PHI2 = Math.atan2((Z + (e2 * V * (Math.sin(PHI1)))) , RootXYSqr);
   while (Math.abs(PHI1 - PHI2) > 0.000000001)
   {
      PHI1 = PHI2;
      V = a / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(PHI1),2))));
      PHI2 = Math.atan2((Z + (e2 * V * (Math.sin(PHI1)))) , RootXYSqr);
   }
   return PHI2;
}

function Marc(bf0, n, PHI0, PHI)
{
   return bf0 * (((1 + n + ((5 / 4) * Math.pow(n,2)) + ((5 / 4) * Math.pow(n,3))) * (PHI - PHI0)) - (((3 * n) + (3 * Math.pow(n,2)) +
          ((21 / 8) * Math.pow(n,3))) * (Math.sin(PHI - PHI0)) * (Math.cos(PHI + PHI0))) + ((((15 / 8) * Math.pow(n,2)) + ((15 / 8) *
          Math.pow(n,3))) * (Math.sin(2 * (PHI - PHI0))) * (Math.cos(2 * (PHI + PHI0)))) - (((35 / 24) * Math.pow(n,3)) *
          (Math.sin(3 * (PHI - PHI0))) * (Math.cos(3 * (PHI + PHI0)))));
}

function LatLon_to_OSGrid(PHI, LAM)
{
   var a = 6377563.396;
   var b = 6356256.910;
   var e0 = 400000;
   var n0 = -100000;
   var f0 = 0.999601272;
   var PHI0 = 49.00000;
   var LAM0 = -2.00000;

   var RadPHI = PHI * (Pi / 180);
   var RadLAM = LAM * (Pi / 180);
   var RadPHI0 = PHI0 * (Pi / 180);
   var RadLAM0 = LAM0 * (Pi / 180);
   var af0 = a * f0;
   var bf0 = b * f0;
   var e2 = (Math.pow(af0,2) - Math.pow(bf0,2)) / Math.pow(af0,2);
   var n = (af0 - bf0) / (af0 + bf0);
   var nu = af0 / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(RadPHI),2) )));
   var rho = (nu * (1 - e2)) / (1 - (e2 * Math.pow(Math.sin(RadPHI),2) ));
   var eta2 = (nu / rho) - 1;
   var p = RadLAM - RadLAM0;
   var M = Marc(bf0, n, RadPHI0, RadPHI);
   var I = M + n0;
   var II = (nu / 2) * (Math.sin(RadPHI)) * (Math.cos(RadPHI));
   var III = ((nu / 24) * (Math.sin(RadPHI)) * (Math.pow(Math.cos(RadPHI),3))) * (5 - (Math.pow(Math.tan(RadPHI),2)) + (9 * eta2));
   var IIIA = ((nu / 720) * (Math.sin(RadPHI)) * (Math.pow(Math.cos(RadPHI),5))) * (61 - (58 * (Math.pow(Math.tan(RadPHI),2))) + (Math.pow(Math.tan(RadPHI),4)));
   var IV = nu * (Math.cos(RadPHI));
   var V = (nu / 6) * ( Math.pow(Math.cos(RadPHI),3)) * ((nu / rho) - (Math.pow(Math.tan(RadPHI),2)));
   var VI = (nu / 120) * (Math.pow(Math.cos(RadPHI),5)) * (5 - (18 * (Math.pow(Math.tan(RadPHI),2))) + (Math.pow(Math.tan(RadPHI),4)) + (14 * eta2) - (58 * (Math.pow(Math.tan(RadPHI),2)) * eta2));
   eastings = Math.round(e0 + (p * IV) + (Math.pow(p,3) * V) + (Math.pow(p,5) * VI));
   northings = Math.round(I + (Math.pow(p,2) * II) + (Math.pow(p,4) * III) + (Math.pow(p,6) * IIIA));
}
//-----------------------------------------------------------------------------------------------------------------------------------------

function caseCorrect(wrongcase)
{
   var loop;
   var correctedCase = '';
   for(loop=0;loop<wrongcase.length;loop++)
   {
      if((loop == 0)||(wrongcase[loop-1] == ' ')||(wrongcase[loop-1] == '(')) correctedCase += wrongcase[loop].toUpperCase();
      else correctedCase += wrongcase[loop].toLowerCase();
   }
   return correctedCase;
}


function wazeifyStreetName(oslName)
{
   var wazeName = '';
   var loop;

   wazeName = caseCorrect(oslName);

   var namePieces = wazeName.split(' ');
   if(namePieces.length > 1)
   {
      var roadType;
      var dirSuffix;
      var thePrefix;
      var namePrefix = '';
      if((namePieces[namePieces.length-1] == 'North')||(namePieces[namePieces.length-1] == 'South')||(namePieces[namePieces.length-1] == 'East')||(namePieces[namePieces.length-1] == 'West'))
      {
         dirSuffix = namePieces[namePieces.length-1][0];
         roadType = namePieces[namePieces.length-2];
         if(namePieces.length > 2)
         {
            if(namePieces[namePieces.length-3] == 'The') thePrefix = true;
            else thePrefix = false;
         }
         for(loop=0;loop<namePieces.length-2;loop++) namePrefix += (namePieces[loop] + ' ');
      }
      else
      {
         dirSuffix = '';
         roadType = namePieces[namePieces.length-1];
         if(namePieces[namePieces.length-2] == 'The') thePrefix = true;
         else thePrefix = false;
         for(loop=0;loop<namePieces.length-1;loop++) namePrefix += (namePieces[loop] + ' ');

      }
      if(thePrefix == false)
      {
         roadType = roadType.replace('Avenue','Ave');
         roadType = roadType.replace('Boulevard','Blvd');
         roadType = roadType.replace('Broadway','Bdwy');
         roadType = roadType.replace('Close','Cl');
         roadType = roadType.replace('Court','Ct');
         roadType = roadType.replace('Crescent','Cr');
         roadType = roadType.replace('Drive','Dr');
         roadType = roadType.replace('Gardens','Gdns');
         roadType = roadType.replace('Garden','Gdn');
         roadType = roadType.replace('Green','Gn');
         roadType = roadType.replace('Grove','Gr');
         roadType = roadType.replace('Lane','Ln');
         roadType = roadType.replace('Mount','Mt');
         roadType = roadType.replace('Place','Pl');
         roadType = roadType.replace('Park','Pk');
         roadType = roadType.replace('Road','Rd');
         roadType = roadType.replace('Square','Sq');
         roadType = roadType.replace('Street','St');
         roadType = roadType.replace('Terrace','Ter');
      }
      wazeName = namePrefix + roadType + ' ' + dirSuffix;
   }
   return wazeName;
}


function cpDistance(cpE, cpN, posE, posN)
{
   return Math.sqrt(((posE - cpE) * (posE - cpE)) + ((posN - cpN) * (posN - cpN)));
}

function gradMinRatio(bbW, bbE, bbS, bbN, posE, posN)
{
   var gradPosToSW = (posN - bbS) / (posE - bbW);
   var gradPosToSE = (posN - bbS) / (posE - bbE);
   var gradNEToSW = (bbN - bbS) / (bbE - bbW);
   var gradNWToSE = (bbN - bbS) / (bbW - bbE);

   var ratioSW = gradPosToSW / gradNEToSW;
   var ratioSE = gradPosToSE / gradNWToSE;
   if(ratioSW < 1) ratioSW = 1 / ratioSW;
   if(ratioSE < 1) ratioSE = 1 / ratioSE;
   if(ratioSW < ratioSE) return ratioSW;
   else return ratioSE;
}

var vpLeft = 0;
var vpRight = 0;
var vpBottom = 0;
var vpTop = 0;

function visualiseBoundingBox(boxW, boxE, boxS, boxN)
{
   if(boxW < vpLeft) boxW = vpLeft;
   if(boxE >  vpRight) boxE = vpRight;
   if(boxS < vpBottom) boxS = vpBottom;
   if(boxN > vpTop) boxN = vpTop;

   boxE -= vpLeft;
   boxW -= vpLeft;
   boxS = vpTop - boxS;
   boxN = vpTop - boxN;

   var wmeScale = 22550 / (950 * Math.pow(2,sessionStorage.zoom));
   boxE /= wmeScale;
   boxW /= wmeScale;
   boxS /= wmeScale;
   boxN /= wmeScale;

   var boxToleranceWidth = ((boxE - boxW) * 0.05);
   var boxToleranceHeight = ((boxS - boxN) * 0.05);

   boxW -= boxToleranceWidth;
   boxE += boxToleranceWidth;
   boxS += boxToleranceHeight;
   boxN -= boxToleranceHeight;

   boxE = Math.round(boxE);
   boxW = Math.round(boxW);
   boxS = Math.round(boxS);
   boxN = Math.round(boxN);

   // extend width/height of box if the calculated dimension is too small for the box to be readily visible
   if(boxE-boxW < 20)
   {
      boxE += 10;
      boxW -= 10;
   }
   if(boxS-boxN < 20)
   {
      boxS += 10;
      boxN -= 10;
   }

   var svgSrc = '<svg xmlns="http://www.w3.org/2000/svg" width="'+document.getElementById('WazeMap').offsetWidth+'px" height="'+document.getElementById('WazeMap').offsetHeight+'px" version="1.1">';
   svgSrc += '<rect x="'+boxW+'" y="'+boxN+'" width="'+(boxE-boxW)+'" height="'+(boxS-boxN)+'" style="fill:yellow;stroke:pink;stroke-width:4;fill-opacity:1;stroke-opacity:1"/>';
   svgSrc += '</svg>';
   bbDiv.innerHTML = svgSrc;
}


function radioClick()
{
   var oslElements = document.getElementById('oslDiv');
   for(var loop=0;loop<oslElements.childNodes.length;loop++)
   {
      if(oslElements.childNodes[loop].nodeType == 1)
      {
         attr = oslElements.childNodes[loop].attributes.getNamedItem("type");
         if(attr != null)
         {
            if(attr.value == "radio")
            {
               if(oslElements.childNodes[loop].checked)
               {
                  attr = oslElements.childNodes[loop].attributes.getNamedItem("id").value;
                  oslID = attr.split('_');
                  evalstr = 'var roadData = unsafeWindow.locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
                  eval(evalstr);
                  var locatorElements = roadData.split(":");

                  visualiseBoundingBox(locatorElements[4],locatorElements[5],locatorElements[6],locatorElements[7])
               }
            }
         }
      }
   }
}


function oslClick()
{
   var cityName = caseCorrect(document.getElementById('myCityName').value);
   sessionStorage.myCity = cityName;
   var oslElements = document.getElementById('oslDiv');
   for(var loop=0;loop<oslElements.childNodes.length;loop++)
   {
      if(oslElements.childNodes[loop].nodeType == 1)
      {
         attr = oslElements.childNodes[loop].attributes.getNamedItem("type");
         if(attr != null)
         {
            if(attr.value == "radio")
            {
               if(oslElements.childNodes[loop].checked)
               {
                  attr = oslElements.childNodes[loop].attributes.getNamedItem("id").value;
                  oslID = attr.split('_');
                  evalstr = 'var roadData = unsafeWindow.locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
                  eval(evalstr);
                  var locatorElements = roadData.split(":");

                  // auto-click the Edit Address link...
                  var editAddress = document.getElementById('editSegmentsApplyChanges');
                  var editButtons = editAddress.getElementsByClassName('edit-button');
                  editButtons[0].click();

                  // fill in the City field
                  //oslName = caseCorrect(locatorElements[9]);
                  //if(locatorElements[8].length > 0) oslName += ' ('+caseCorrect(locatorElements[8])+')';
                  //snelms[0].value = oslName;

                  if(cityName.length > 0)
                  {
                     var snelms = document.getElementsByName('cityName');
                     snelms[0].value = cityName;
                     snelms[0].disabled = false;
                     snelms = document.getElementsByName('emptyCity');
                     snelms[0].checked = false;
                  }

                  // and the Street field
                  oslName = locatorElements[1];
                  if((locatorElements[0].length > 0)&&(locatorElements[1].length > 0)) oslName += ' - ';
                  oslName += wazeifyStreetName(locatorElements[0]);

                  snelms = document.getElementsByName('streetName');
                  snelms[0].value = oslName;
                  snelms[0].disabled = false;
                  snelms = document.getElementsByName('emptyStreet');
                  snelms[0].checked = false;

                  bbDiv.innerHTML = '';
               }
            }
         }
      }
   }
}


function oslMatch(oslLink, oslDistance, oslMinGradRatio, oslRadioID)
{
   this.oslLink = oslLink;
   this.oslDistance = oslDistance;
   this.oslMinGradRatio = oslMinGradRatio;
   this.oslRadioID = oslRadioID;
}
function sortCandidates(a,b)
{
   var x = a.oslDistance;
   var y = b.oslDistance;
   return((x<y) ? -1 : ((x>y) ? 1 : 0));
}

function toOSGrid(lat, lon, mode)
{
   if(lat != 0)
   {
      latitude = lat;
      longitude = lon;
      wgs_to_osgb();
   }

   if(mode == 1)  // OS Locator lookup
   {
      // determine which 10km grid block contains the current mouse position
      var eBlock = (Math.floor(eastings/10000)) * 10000;
      var nBlock = (Math.floor(northings/10000)) * 10000;
      // check to see if there's a corresponding array in the osl_10km data
      var evalstr = 'typeof unsafeWindow.locatorData_'+eBlock+'_'+nBlock;

      if(eval(evalstr) == "undefined") // Thanks to Timbones :-)
      {
         // inject 10km block data
         var script = document.createElement("script");
         script.setAttribute('type','text/javascript');
         script.src = 'http://greasemonkey.chizzum.com/osl_v1/locatorData_'+eBlock+'_'+nBlock+'.js';
         document.head.appendChild(script);
      }

      if(eval(evalstr) != "undefined")
      {
         // yes...  make a local copy to avoid having an eval() in each iteration of the loop
         evalstr = 'var blockData = unsafeWindow.locatorData_'+eBlock+'_'+nBlock;
         eval(evalstr);
         oslDiv.innerHTML = 'OSL matches at '+eastings+','+northings+':<br>';
         var candidates = new Array();

         for(var loop = 0;loop < blockData.length; loop++)
         {
            // for each entry in the array, test the centrepoint position to see if it lies within the bounding box for that entry
            // note that we allow a 10m tolerance on all sides of the box to allow for inaccuracies in the latlon->gridref conversion,
            // and to increase the chance of a successful match when the road runs E-W or N-S and thus has a long but narrow bounding box
            var locatorElements = blockData[loop].split(":");

            var bbW = parseInt(locatorElements[4]);
            var bbE = parseInt(locatorElements[5]);
            var bbS = parseInt(locatorElements[6]);
            var bbN = parseInt(locatorElements[7]);
            if((eastings>=(bbW-10))&&(eastings<=(bbE+10))&&(northings>=(bbS-10))&&(northings<=(bbN+10)))
            {
               var radioID = 'oslID_'+eBlock+'_'+nBlock+'_'+loop;
               var oslLink = '<input type="radio" name="oslChoice" id="'+radioID+'"></input>';
               if(locatorElements[1].length > 0)
               {
                  oslLink += locatorElements[1];
                  if(locatorElements[0].length > 0)
                  {
                     oslLink += ' - ';
                  }
               }
               oslLink += wazeifyStreetName(locatorElements[0])+'<br>';
               var dist = cpDistance(parseInt(locatorElements[2]),parseInt(locatorElements[3]),eastings,northings);
               var ratio = gradMinRatio(bbW, bbE, bbS, bbN, eastings, northings);
               candidates[candidates.length++] = new oslMatch(oslLink,dist,ratio,radioID);
            }
         }
         if(candidates.length > 0)
         {
            bbDiv.innerHTML = '';
            if(candidates.length > 1) candidates.sort(sortCandidates);
            for(var loop=0;loop<candidates.length;loop++)
            {
               oslDiv.innerHTML += candidates[loop].oslLink;
               //oslDiv.innerHTML += candidates[loop].oslLink + candidates[loop].oslDistance + ' ' + candidates[loop].oslMinGradRatio + '<br>';
            }
            oslDiv.innerHTML += '<br>City: <input id="myCityName" type="text" value="'+sessionStorage.myCity+'"/><br>';
            oslDiv.innerHTML += '<br><input id="oslSelect" type="button" value="Copy to Properties" />';
            document.getElementById('oslSelect').addEventListener("click", oslClick, true);
            for(var loop=0;loop<candidates.length;loop++)
            {
               document.getElementById(candidates[loop].oslRadioID).addEventListener("click", radioClick, true);
            }
         }
      }
   }
   else return '?e='+eastings+'&n='+northings;
}

function processPermalink()
{
   var mousepos = document.getElementById("OpenLayers.Control.MousePosition_26").innerHTML;
   if(mousepos != sessionStorage.mousepos)
   {
      sessionStorage.mousepos = mousepos;
      if(document.getElementById("editPanel").innerHTML.indexOf("editSegmentStreetDetailsForm") == -1)  // segment properties panel isn't open...
      {
         if
         (
            (document.getElementById("OpenLayers.Layer.Vector.RootContainer_221").innerHTML.indexOf('#03b9da') != -1) || // ...and segment is highlighted
            (document.getElementById("OpenLayers.Layer.Vector.RootContainer_221").innerHTML.indexOf('#ff3300') != -1)
         )
         {
            // so update the OS Locator matches
            mouselatlon = mousepos.split(",");
            toOSGrid(mouselatlon[1],mouselatlon[0],1);
         }
      }
   }

   // 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)));

      // accommodate both the original permalink ordering of zoom, lat then lon, and the present
      // ordering (as of early July 2012) of zoom, lon then lat...
      if(latpos < lonpos)
      {
         var lat = plsrc.substr(latpos+9,lonpos-(latpos+9));
         var lon = plsrc.substr(lonpos+9,layerpos-(lonpos+9));
      }
      else
      {
         var lat = plsrc.substr(latpos+9,layerpos-(latpos+9));
         var lon = plsrc.substr(lonpos+9,latpos-(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,0)+'&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');

         // recalculate the map viewport extents in terms of eastings/northings
         var viewportWidth = document.getElementById('WazeMap').offsetWidth;
         var viewportHeight = document.getElementById('WazeMap').offsetHeight;
         var wmeScale = 22550 / (950 * Math.pow(2,sessionStorage.zoom));
         var vpHalfWidth = Math.round((viewportWidth * wmeScale) / 2);
         var vpHalfHeight = Math.round((viewportHeight * wmeScale) / 2);
         vpLeft = eastings - vpHalfWidth;
         vpRight = eastings + vpHalfWidth;
         vpBottom = northings - vpHalfHeight;
         vpTop = northings + vpHalfHeight;
         bbDiv.innerHTML = '';
      }
   }
}

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

// 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 attribution 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);

// add a new div to the edit properties panel, to hold the OS Locator results
var oslDiv = document.createElement('div');
oslDiv.id = "oslDiv";
oslDiv.style.backgroundColor = '#DDFFDD';
document.getElementById('editPanel').appendChild(oslDiv);

// add a new div to the map viewport, to hold the bounding box SVG
var bbDiv = document.createElement('div');
bbDiv.id = "bbDiv";
bbDiv.style.position = 'absolute';
bbDiv.style.top = '0';
bbDiv.style.left = '0';
bbDiv.style.width = document.getElementById('WazeMap').offsetWidth;
bbDiv.style.height = document.getElementById('WazeMap').offsetHeight;
bbDiv.style.zIndex = 100;
document.getElementById('WazeMap').appendChild(bbDiv);

// set up a 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
Timbones wrote:This issue would go away if Twister is able to serve the OS data from a https server.
Big if, since my hosting package doesn't already include SSL support and adding it on is way too costly. Unless someone has a much cheaper option for hosting the OS data on a SSL server, Chrome users will just have to remember to keep allowing insecure data access (for as long as Google continue to allow them to do that...)
Timbones wrote:It seems that Google are tightening up the security of Chrome. In the beta versions, you can no longer install scripts or extensions unless they come from the Chrome Web Store.
Not entirely true, although you can no longer drag and drop onto the main Chrome window, you can still drag and drop onto the Extensions tab.
Timbones wrote:Might have to stick to Firefox for editing...
...and if Waze could figure out a way to fix the horizontal segment selection bug, there'd be no reason to use anything other than Firefox for editing. Even with that bug, I now find myself doing pretty much all of my edits in FF, because all these security-related tweaks to Chrome are making it less appealing for scripting work.


Anyway, this topic bump has reminded me there's a long overdue update to the script ready for release... The changes of note compared with 0.8.4 are as follows:
  • Runs within the WME context, allowing direct access to WME functions and data without the need for unsafeWindow hackery (thanks to timbones for the code)
  • Uses the latest road name abbreviations list from the wiki
  • The bounding box now works with the aerial images layer
  • "Un-named segment" is now permanently available as a name choice - handy for filling in the details on new roundabouts...
  • Country/State fields are set to "United Kingdom" and "Other" if they aren't already (suggested by Dave2084)

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://world.waze.com/map-editor/*
// @include             https://descartesw.waze.com/beta/*
// @version             0.8.7
// ==/UserScript==

// Contains Ordnance Survey data Crown copyright and database right 2012
// Contents of the osl_10km.js file are derived under the Open Government Licence from the OS Locator dataset

//-----------------------------------------------------------------------------------------------------------------------------------------
// all code between here and the next ------------- marker line provided by timbones to replace the unsafeWindow workaround
if ('undefined' == typeof __RTLM_PAGE_SCOPE_RUN__)
{
   (
      function page_scope_runner()
      {
         // If we're _not_ already running in the page, grab the full source
         // of this script.
         var my_src = "(" + page_scope_runner.caller.toString() + ")();";

         // Create a script node holding this script, plus a marker that lets us
         // know we are running in the page scope (not the Greasemonkey sandbox).
         // Note that we are intentionally *not* scope-wrapping here.
         var script = document.createElement('script');
         script.setAttribute("type", "text/javascript");
         script.textContent = "var __RTLM_PAGE_SCOPE_RUN__ = true;\n" + my_src;

         // Insert the script node into the page, so it will run, and immediately
         // remove it to clean up.  Use setTimeout to force execution "outside" of
         // the user script scope completely.
         setTimeout(function(){document.body.appendChild(script);document.body.removeChild(script);}, 0);
      }
   )();
   // Stop running, because we know Greasemonkey actually runs us in
   // an anonymous wrapper.
   return;
}
//-----------------------------------------------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------------------------------------------
// all code between here and the next ------------- marker line is a stripped down version of the original from Paul Dixon
//
// * GeoTools javascript coordinate transformations
// * http://files.dixo.net/geotools.html
// *
// * This file copyright (c)2005 Paul Dixon (paul@elphin.com)
// *
// * This program is free software; you can redistribute it and/or
// * modify it under the terms of the GNU General Public License
// * as published by the Free Software Foundation; either version 2
// * of the License, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program; if not, write to the Free Software
// * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// *
// * ---------------------------------------------------------------------------
// *
// * Credits
// *
// * The algorithm used by the script for WGS84-OSGB36 conversions is derived
// * from an OSGB spreadsheet (www.gps.gov.uk) with permission. This has been
// * adapted into Perl by Ian Harris, and into PHP by Barry Hunter. Conversion
// * accuracy is in the order of 7m for 90% of Great Britain, and should be
// * be similar to the conversion made by a typical GPSr
// *
// * See accompanying documentation for more information
// * http://files.dixo.net/geotools.html

var northings;
var eastings;
var latitude;
var longitude;

var helmX, helmY, helmZ;
var Pi = 3.14159265358979;

function wgs_to_osgb()
{
	LatLon_to_HelmXYZ();
   var latitude2  = XYZ_to_Lat();
	var longitude2 = Math.atan2(helmY , helmX) * (180 / Pi);
	LatLon_to_OSGrid(latitude2,longitude2);
}

function LatLon_to_HelmXYZ()
{
   var a = 6378137.0;
   var b = 6356752.313;
   var DX = -446.448;
   var DY = 125.157;
   var DZ = -542.060;
   var rotX = -0.1502;
   var rotY = -0.2470;
   var rotZ = -0.8421;
	var sfactor = 20.4894 * 0.000001;

   // perform initial lat-lon to cartesian coordinate translation
   var RadPHI = latitude * (Pi / 180);
   var RadLAM = longitude * (Pi / 180);
   var e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
   var V = a / (Math.sqrt(1 - (e2 * (  Math.pow(Math.sin(RadPHI),2)))));
   var cartX = V * (Math.cos(RadPHI)) * (Math.cos(RadLAM));
   var cartY = V * (Math.cos(RadPHI)) * (Math.sin(RadLAM));
   var cartZ = (V * (1 - e2)) * (Math.sin(RadPHI));

   // Compute Helmert transformed coordinates
	var RadX_Rot = (rotX / 3600) * (Pi / 180);
	var RadY_Rot = (rotY / 3600) * (Pi / 180);
	var RadZ_Rot = (rotZ / 3600) * (Pi / 180);
   helmX = (cartX + (cartX * sfactor) - (cartY * RadZ_Rot) + (cartZ * RadY_Rot) + DX);
	helmY = (cartX * RadZ_Rot) + cartY + (cartY * sfactor) - (cartZ * RadX_Rot) + DY;
	helmZ = (-1 * cartX * RadY_Rot) + (cartY * RadX_Rot) + cartZ + (cartZ * sfactor) + DZ;
}

function XYZ_to_Lat()
{
   var a = 6377563.396;
   var b = 6356256.910;
   var RootXYSqr = Math.sqrt(Math.pow(helmX,2) + Math.pow(helmY,2));
   var e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
   var PHI1 = Math.atan2(helmZ , (RootXYSqr * (1 - e2)) );
   var PHI = Iterate_XYZ_to_Lat(a, e2, PHI1, helmZ, RootXYSqr);
   return PHI * (180 / Pi);
}

function Iterate_XYZ_to_Lat(a, e2, PHI1, Z, RootXYSqr)
{
   var V = a / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(PHI1),2))));
   var PHI2 = Math.atan2((Z + (e2 * V * (Math.sin(PHI1)))) , RootXYSqr);
   while (Math.abs(PHI1 - PHI2) > 0.000000001)
   {
      PHI1 = PHI2;
      V = a / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(PHI1),2))));
      PHI2 = Math.atan2((Z + (e2 * V * (Math.sin(PHI1)))) , RootXYSqr);
   }
   return PHI2;
}

function Marc(bf0, n, PHI0, PHI)
{
   return bf0 * (((1 + n + ((5 / 4) * Math.pow(n,2)) + ((5 / 4) * Math.pow(n,3))) * (PHI - PHI0)) - (((3 * n) + (3 * Math.pow(n,2)) +
          ((21 / 8) * Math.pow(n,3))) * (Math.sin(PHI - PHI0)) * (Math.cos(PHI + PHI0))) + ((((15 / 8) * Math.pow(n,2)) + ((15 / 8) *
          Math.pow(n,3))) * (Math.sin(2 * (PHI - PHI0))) * (Math.cos(2 * (PHI + PHI0)))) - (((35 / 24) * Math.pow(n,3)) *
          (Math.sin(3 * (PHI - PHI0))) * (Math.cos(3 * (PHI + PHI0)))));
}

function LatLon_to_OSGrid(PHI, LAM)
{
   var a = 6377563.396;
   var b = 6356256.910;
   var e0 = 400000;
   var n0 = -100000;
   var f0 = 0.999601272;
   var PHI0 = 49.00000;
   var LAM0 = -2.00000;

   var RadPHI = PHI * (Pi / 180);
   var RadLAM = LAM * (Pi / 180);
   var RadPHI0 = PHI0 * (Pi / 180);
   var RadLAM0 = LAM0 * (Pi / 180);
   var af0 = a * f0;
   var bf0 = b * f0;
   var e2 = (Math.pow(af0,2) - Math.pow(bf0,2)) / Math.pow(af0,2);
   var n = (af0 - bf0) / (af0 + bf0);
   var nu = af0 / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(RadPHI),2) )));
   var rho = (nu * (1 - e2)) / (1 - (e2 * Math.pow(Math.sin(RadPHI),2) ));
   var eta2 = (nu / rho) - 1;
   var p = RadLAM - RadLAM0;
   var M = Marc(bf0, n, RadPHI0, RadPHI);
   var I = M + n0;
   var II = (nu / 2) * (Math.sin(RadPHI)) * (Math.cos(RadPHI));
   var III = ((nu / 24) * (Math.sin(RadPHI)) * (Math.pow(Math.cos(RadPHI),3))) * (5 - (Math.pow(Math.tan(RadPHI),2)) + (9 * eta2));
   var IIIA = ((nu / 720) * (Math.sin(RadPHI)) * (Math.pow(Math.cos(RadPHI),5))) * (61 - (58 * (Math.pow(Math.tan(RadPHI),2))) + (Math.pow(Math.tan(RadPHI),4)));
   var IV = nu * (Math.cos(RadPHI));
   var V = (nu / 6) * ( Math.pow(Math.cos(RadPHI),3)) * ((nu / rho) - (Math.pow(Math.tan(RadPHI),2)));
   var VI = (nu / 120) * (Math.pow(Math.cos(RadPHI),5)) * (5 - (18 * (Math.pow(Math.tan(RadPHI),2))) + (Math.pow(Math.tan(RadPHI),4)) + (14 * eta2) - (58 * (Math.pow(Math.tan(RadPHI),2)) * eta2));
   eastings = Math.round(e0 + (p * IV) + (Math.pow(p,3) * V) + (Math.pow(p,5) * VI));
   northings = Math.round(I + (Math.pow(p,2) * II) + (Math.pow(p,4) * III) + (Math.pow(p,6) * IIIA));
}
//-----------------------------------------------------------------------------------------------------------------------------------------

function caseCorrect(wrongcase)
{
   var loop;
   var correctedCase = '';
   for(loop=0;loop<wrongcase.length;loop++)
   {
      if((loop == 0)||(wrongcase[loop-1] == ' ')||(wrongcase[loop-1] == '(')) correctedCase += wrongcase[loop].toUpperCase();
      else correctedCase += wrongcase[loop].toLowerCase();
   }
   return correctedCase;
}


function wazeifyStreetName(oslName)
{
   var wazeName = '';
   var loop;

   wazeName = caseCorrect(oslName);

   var namePieces = wazeName.split(' ');
   if(namePieces.length > 1)
   {
      var roadType;
      var dirSuffix;
      var thePrefix;
      var namePrefix = '';
      if((namePieces[namePieces.length-1] == 'North')||(namePieces[namePieces.length-1] == 'South')||(namePieces[namePieces.length-1] == 'East')||(namePieces[namePieces.length-1] == 'West'))
      {
         dirSuffix = namePieces[namePieces.length-1][0];
         roadType = namePieces[namePieces.length-2];
         if(namePieces.length > 2)
         {
            if(namePieces[namePieces.length-3] == 'The') thePrefix = true;
            else thePrefix = false;
         }
         for(loop=0;loop<namePieces.length-2;loop++) namePrefix += (namePieces[loop] + ' ');
      }
      else
      {
         dirSuffix = '';
         roadType = namePieces[namePieces.length-1];
         if(namePieces[namePieces.length-2] == 'The') thePrefix = true;
         else thePrefix = false;
         for(loop=0;loop<namePieces.length-1;loop++) namePrefix += (namePieces[loop] + ' ');

      }
      if(thePrefix == false)
      {
         roadType = roadType.replace('Avenue','Ave');
         roadType = roadType.replace('Boulevard','Blvd');
         roadType = roadType.replace('Broadway','Bdwy');
         roadType = roadType.replace('Circus','Cir');
         roadType = roadType.replace('Close','Cl');
         roadType = roadType.replace('Court','Ct');
         roadType = roadType.replace('Crescent','Cr');
         roadType = roadType.replace('Drive','Dr');
         roadType = roadType.replace('Gardens','Gdns');
         roadType = roadType.replace('Garden','Gdn');
         roadType = roadType.replace('Green','Gn');
         roadType = roadType.replace('Grove','Gr');
         roadType = roadType.replace('Lane','Ln');
         roadType = roadType.replace('Mount','Mt');
         roadType = roadType.replace('Place','Pl');
         roadType = roadType.replace('Park','Pk');
         roadType = roadType.replace('Ridge','Rdg');
         roadType = roadType.replace('Road','Rd');
         roadType = roadType.replace('Square','Sq');
         roadType = roadType.replace('Street','St');
         roadType = roadType.replace('Terrace','Ter');
         roadType = roadType.replace('Valley','Val');
         roadType = roadType.replace('By-pass','Bypass');
      }
      wazeName = namePrefix + roadType + ' ' + dirSuffix;
   }
   return wazeName;
}


function cpDistance(cpE, cpN, posE, posN)
{
   return Math.sqrt(((posE - cpE) * (posE - cpE)) + ((posN - cpN) * (posN - cpN)));
}

function gradMinRatio(bbW, bbE, bbS, bbN, posE, posN)
{
   return 1;
}

function _gradMinRatio(bbW, bbE, bbS, bbN, posE, posN)
{
   // keep posE/posN within bounding box to prevent gradient
   // calculation glitches
   if(posN < bbS) posN = bbS;
   if(posN > bbN) posN = bbN;
   if(posE <= bbW) posE = (bbW + 1);   // shift inwards by 1m to prevent divide by zero errors
   if(posE >= bbE) posE = (bbE - 1);

   var gradPosToSW = (posN - bbS) / (posE - bbW);
   var gradNEToPos = (bbN - posN) / (bbE - posE);
   if(gradNEToPos < gradPosToSW) gradPosToSW = gradNEToPos;

   var gradPosToSE = (posN - bbS) / (posE - bbE);
   var gradNWToPos = (bbN - posN) / (bbW - posE);
   if(gradNWToPos < gradPosToSE) gradPosToSE = gradNWToPos;

   var gradNEToSW = (bbN - bbS) / (bbE - bbW);
   var gradNWToSE = (bbN - bbS) / (bbW - bbE);

   var ratioSW = gradPosToSW / gradNEToSW;
   var ratioSE = gradPosToSE / gradNWToSE;
   if(ratioSW < 1) ratioSW = 1 / ratioSW;
   if(ratioSE < 1) ratioSE = 1 / ratioSE;
   if(ratioSW < ratioSE) return ratioSW;
   else return ratioSE;
}

var vpLeft = 0;
var vpRight = 0;
var vpBottom = 0;
var vpTop = 0;

function visualiseBoundingBox(boxW, boxE, boxS, boxN)
{
   if(boxW < vpLeft) boxW = vpLeft;
   if(boxE >  vpRight) boxE = vpRight;
   if(boxS < vpBottom) boxS = vpBottom;
   if(boxN > vpTop) boxN = vpTop;

   boxE -= vpLeft;
   boxW -= vpLeft;
   boxS = vpTop - boxS;
   boxN = vpTop - boxN;

   var wmeScale = 22550 / (950 * Math.pow(2,sessionStorage.zoom));
   boxE /= wmeScale;
   boxW /= wmeScale;
   boxS /= wmeScale;
   boxN /= wmeScale;

   var boxToleranceWidth = ((boxE - boxW) * 0.05);
   var boxToleranceHeight = ((boxS - boxN) * 0.05);

   boxW -= boxToleranceWidth;
   boxE += boxToleranceWidth;
   boxS += boxToleranceHeight;
   boxN -= boxToleranceHeight;

   boxE = Math.round(boxE);
   boxW = Math.round(boxW);
   boxS = Math.round(boxS);
   boxN = Math.round(boxN);

   // extend width/height of box if the calculated dimension is too small for the box to be readily visible
   if(boxE-boxW < 20)
   {
      boxE += 10;
      boxW -= 10;
   }
   if(boxS-boxN < 20)
   {
      boxS += 10;
      boxN -= 10;
   }

   var svgSrc = '<svg xmlns="http://www.w3.org/2000/svg" width="'+document.getElementById('WazeMap').offsetWidth+'px" height="'+document.getElementById('WazeMap').offsetHeight+'px" version="1.1">';
   svgSrc += '<rect x="'+boxW+'" y="'+boxN+'" width="'+(boxE-boxW)+'" height="'+(boxS-boxN)+'" style="fill:yellow;stroke:pink;stroke-width:4;fill-opacity:0.75;stroke-opacity:0.75"/>';
   svgSrc += '</svg>';
   bbDiv.innerHTML = svgSrc;
}


function radioClick()
{
   var oslElements = document.getElementById('oslDiv');
   for(var loop=0;loop<oslElements.childNodes.length;loop++)
   {
      if(oslElements.childNodes[loop].nodeType == 1)
      {
         attr = oslElements.childNodes[loop].attributes.getNamedItem("type");
         if(attr != null)
         {
            if(attr.value == "radio")
            {
               if(oslElements.childNodes[loop].checked)
               {
                  attr = oslElements.childNodes[loop].attributes.getNamedItem("id").value;
                  var roadData = '';
                  oslID = attr.split('_');
                  if(oslID[1] != 'null')
                  {
                     evalstr = 'roadData = locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
                     eval(evalstr);
                  }
                  else
                  {
                     roadData = "null:null";
                  }
                  var locatorElements = roadData.split(":");
                  if(locatorElements[0] != 'null')
                  {
                     visualiseBoundingBox(locatorElements[4],locatorElements[5],locatorElements[6],locatorElements[7])
                  }
                  else
                  {
                     bbDiv.innerHTML = '';
                  }
               }
            }
         }
      }
   }
}


function oslClick()
{
   var cityName = caseCorrect(document.getElementById('myCityName').value);
   sessionStorage.myCity = cityName;
   var oslElements = document.getElementById('oslDiv');
   for(var loop=0;loop<oslElements.childNodes.length;loop++)
   {
      if(oslElements.childNodes[loop].nodeType == 1)
      {
         attr = oslElements.childNodes[loop].attributes.getNamedItem("type");
         if(attr != null)
         {
            if(attr.value == "radio")
            {
               if(oslElements.childNodes[loop].checked)
               {
                  attr = oslElements.childNodes[loop].attributes.getNamedItem("id").value;
                  var roadData = '';
                  oslID = attr.split('_');
                  if(oslID[1] != 'null')
                  {
                     evalstr = 'roadData = locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
                     eval(evalstr);
                  }
                  else
                  {
                     roadData = ":";
                  }
                  var locatorElements = roadData.split(":");

                  // auto-click the Edit Address link...
                  var editAddress = document.getElementById('editSegmentsApplyChanges');
                  var editButtons = editAddress.getElementsByClassName('edit-button');
                  editButtons[0].click();

                  // set Country to "United Kingdom" and State to "Other" if they aren't already set to something
                  var snelms = document.getElementsByName('countryID');
                  if(snelms[0].value != 234) snelms[0].value = 234;
                  snelms = document.getElementsByName('stateID');
                  if(snelms[0].value != 99) snelms[0].value = 99;

                  // fill in the City field
                  snelms = document.getElementsByName('cityName');
                  if(cityName.length > 0)
                  {
                     snelms[0].value = cityName;
                     snelms[0].disabled = false;
                     snelms = document.getElementsByName('emptyCity');
                     snelms[0].checked = false;
                  }
                  else if(snelms[0].value.length == 0)
                  {
                     snelms[0].disabled = true;
                     snelms = document.getElementsByName('emptyCity');
                     snelms[0].checked = true;
                  }

                  // finally the Street field
                  var oslName = locatorElements[1];
                  if((locatorElements[0].length > 0)&&(locatorElements[1].length > 0)) oslName += ' - ';
                  if((oslName.length > 0)||(locatorElements[0].length > 0))
                  {
                     oslName += wazeifyStreetName(locatorElements[0]);
                     snelms = document.getElementsByName('streetName');
                     snelms[0].value = oslName;
                     snelms[0].disabled = false;
                     snelms = document.getElementsByName('emptyStreet');
                     snelms[0].checked = false;
                  }
                  else
                  {
                     snelms = document.getElementsByName('streetName');
                     snelms[0].value = '';
                     snelms[0].disabled = true;
                     snelms = document.getElementsByName('emptyStreet');
                     snelms[0].checked = true;
                  }

                  bbDiv.innerHTML = '';
               }
            }
         }
      }
   }
}


function oslMatch(oslLink, oslDistance, oslMinGradRatio, oslRadioID)
{
   this.oslLink = oslLink;
   this.oslDistance = oslDistance;
   this.oslMinGradRatio = oslMinGradRatio;
   this.oslRadioID = oslRadioID;
}
function sortCandidates(a,b)
{
   var x = a.oslDistance;
   var y = b.oslDistance;
   return((x<y) ? -1 : ((x>y) ? 1 : 0));
}

function toOSGrid(lat, lon, mode)
{
   if(lat != 0)
   {
      latitude = lat;
      longitude = lon;
      wgs_to_osgb();
   }

   if(mode == 1)  // OS Locator lookup
   {
      // determine which 10km grid block contains the current mouse position
      var eBlock = (Math.floor(eastings/10000)) * 10000;
      var nBlock = (Math.floor(northings/10000)) * 10000;
      // check to see if there's a corresponding array in the osl_10km data
      var evalstr = 'typeof locatorData_'+eBlock+'_'+nBlock;

      if(eval(evalstr) == "undefined") // Thanks to Timbones :-)
      {
         // inject 10km block data
         var script = document.createElement("script");
         script.setAttribute('type','text/javascript');
         script.src = 'http://greasemonkey.chizzum.com/osl_v1/locatorData_'+eBlock+'_'+nBlock+'.js';
         document.head.appendChild(script);
      }

      if(eval(evalstr) != "undefined")
      {
         // yes...  make a local copy to avoid having an eval() in each iteration of the loop
         evalstr = 'var blockData = locatorData_'+eBlock+'_'+nBlock;
         eval(evalstr);
         oslDiv.innerHTML = 'OSL matches at '+eastings+','+northings+':<br>';
         var candidates = new Array();

         candidates[candidates.length++] = new oslMatch('<input type="radio" name="oslChoice" id="oslID_null_null_null"></input>Un-named segment<br>',1000000,0,'oslID_null_null_null');

         for(var loop = 0;loop < blockData.length; loop++)
         {
            // for each entry in the array, test the centrepoint position to see if it lies within the bounding box for that entry
            // note that we allow a 10m tolerance on all sides of the box to allow for inaccuracies in the latlon->gridref conversion,
            // and to increase the chance of a successful match when the road runs E-W or N-S and thus has a long but narrow bounding box
            var locatorElements = blockData[loop].split(":");

            var bbW = parseInt(locatorElements[4])-10;
            var bbE = parseInt(locatorElements[5])+10;
            var bbS = parseInt(locatorElements[6])-10;
            var bbN = parseInt(locatorElements[7])+10;
            if((eastings>=bbW)&&(eastings<=bbE)&&(northings>=bbS)&&(northings<=bbN))
            {
               var radioID = 'oslID_'+eBlock+'_'+nBlock+'_'+loop;
               var oslLink = '<input type="radio" name="oslChoice" id="'+radioID+'"></input>';
               if(locatorElements[1].length > 0)
               {
                  oslLink += locatorElements[1];
                  if(locatorElements[0].length > 0)
                  {
                     oslLink += ' - ';
                  }
               }
               oslLink += wazeifyStreetName(locatorElements[0])+'<br>';
               var dist = cpDistance(parseInt(locatorElements[2]),parseInt(locatorElements[3]),eastings,northings);
               var ratio = gradMinRatio(bbW, bbE, bbS, bbN, eastings, northings);
               //oslLink += wazeifyStreetName(locatorElements[0])+'('+ratio+')<br>';
               // apply strong weighting to segment distance if the gradient ratio suggests it's a better match than the
               // distance alone might otherwise suggest...
               //if(ratio <= 1.1) dist -= 10000;

               candidates[candidates.length++] = new oslMatch(oslLink,dist,ratio,radioID);
            }
         }
         if(candidates.length > 0)
         {
            //bbDiv.innerHTML = '';
            if(candidates.length > 1) candidates.sort(sortCandidates);
            for(var loop=0;loop<candidates.length;loop++)
            {
               oslDiv.innerHTML += candidates[loop].oslLink;
               //oslDiv.innerHTML += candidates[loop].oslLink + candidates[loop].oslDistance + ' ' + candidates[loop].oslMinGradRatio + '<br>';
            }
            oslDiv.innerHTML += '<br>City: <input id="myCityName" type="text" value="'+sessionStorage.myCity+'"/><br>';
            oslDiv.innerHTML += '<br><input id="oslSelect" type="button" value="Copy to Properties" />';
            document.getElementById('oslSelect').addEventListener("click", oslClick, true);
            for(var loop=0;loop<candidates.length;loop++)
            {
               document.getElementById(candidates[loop].oslRadioID).addEventListener("click", radioClick, true);
            }
         }
      }
   }
   else return '?e='+eastings+'&n='+northings;
}

function processPermalink()
{
   var mousepos = document.getElementById("OpenLayers.Control.MousePosition_26").innerHTML;
   if(mousepos != sessionStorage.mousepos)
   {
      sessionStorage.mousepos = mousepos;
      if(document.getElementById("editPanel").innerHTML.indexOf("editSegmentStreetDetailsForm") == -1)  // segment properties panel isn't open...
      {
         if
         (
            (document.getElementById("OpenLayers.Layer.Vector.RootContainer_221").innerHTML.indexOf('#03b9da') != -1) || // ...and segment is highlighted
            (document.getElementById("OpenLayers.Layer.Vector.RootContainer_221").innerHTML.indexOf('#ff3300') != -1)
         )
         {
            // so update the OS Locator matches
            mouselatlon = mousepos.split(",");
            toOSGrid(mouselatlon[1],mouselatlon[0],1);
         }
      }
   }

   // 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)));

      // accommodate both the original permalink ordering of zoom, lat then lon, and the present
      // ordering (as of early July 2012) of zoom, lon then lat...
      if(latpos < lonpos)
      {
         var lat = plsrc.substr(latpos+9,lonpos-(latpos+9));
         var lon = plsrc.substr(lonpos+9,layerpos-(lonpos+9));
      }
      else
      {
         var lat = plsrc.substr(latpos+9,layerpos-(latpos+9));
         var lon = plsrc.substr(lonpos+9,latpos-(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,0)+'&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');

         // recalculate the map viewport extents in terms of eastings/northings
         var viewportWidth = document.getElementById('WazeMap').offsetWidth;
         var viewportHeight = document.getElementById('WazeMap').offsetHeight;
         var wmeScale = 22550 / (950 * Math.pow(2,sessionStorage.zoom));
         var vpHalfWidth = Math.round((viewportWidth * wmeScale) / 2);
         var vpHalfHeight = Math.round((viewportHeight * wmeScale) / 2);
         vpLeft = eastings - vpHalfWidth;
         vpRight = eastings + vpHalfWidth;
         vpBottom = northings - vpHalfHeight;
         vpTop = northings + vpHalfHeight;
         bbDiv.innerHTML = '';
      }
   }
}

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

// 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 attribution 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);

var debugDiv = document.createElement('div');
debugDiv.id = "debugDiv";
document.getElementById('map-footer').appendChild(debugDiv);

// add a new div to the edit properties panel, to hold the OS Locator results
var oslDiv = document.createElement('div');
oslDiv.id = "oslDiv";
oslDiv.style.backgroundColor = '#DDFFDD';
document.getElementById('editPanel').appendChild(oslDiv);

// add a new div to the map viewport, to hold the bounding box SVG
var bbDiv = document.createElement('div');
bbDiv.id = "bbDiv";
bbDiv.style.position = 'absolute';
bbDiv.style.top = '0';
bbDiv.style.left = '0';
bbDiv.style.width = document.getElementById('WazeMap').offsetWidth;
bbDiv.style.height = document.getElementById('WazeMap').offsetHeight;
bbDiv.style.zIndex = 100;
document.getElementById('WazeMap').appendChild(bbDiv);

// set up a 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
Yeah, I'll be doing that soon, once I'm happy with the most recent tweaks - one or two more large-scale editing sessions should shake down the code nicely and get it ready for an 0.9 release over the weekend... After that I think I'll take a break from OS integration and spend some time playing around with a few other ideas I've been having to improve the editing 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

Post by Twister-UK
That rules me out then :D I'll have another look at the available segment properties to see if there's an easy way to determine which segments correspond to a single roundabout, and if so whether it's possible to programmatically select them all, but no promises...
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
Yeah, I was hoping the visual marking of new roundabouts would be easy to pick out of the source code, but last time I looked into this it didn't seem to be at all obvious. Having said that, I've learned a bit more about how WME goes about its business since then, so perhaps I was overlooking something that time...

True, it won't work for messed up roundabouts, but I think the main use for this option would be to make it easier to correctly name (or not-name) a newly forged roundabout, to prevent it from ending up an annoying red blotch on the map.
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
As a little Friday diversion, with the OS data now neatly packaged into 10x10km squares, I wondered what a scatter plot of the filesizes would look like...

http://i1056.photobucket.com/albums/t37 ... 8316e4.png

Not too much of a surprise I guess!
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
If people stop giving me last minute ideas, then I plan to do a release in the next 24 hours...
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