// ==UserScript==
// @name WME OpenData
// @namespace http://greasemonkey.chizzum.com
// @description Provides access to certain OS OpenData products within the WME environment
// @include https://*.waze.com/*editor*
// @include https://editor-beta.waze.com/*
// @include https://beta.waze.com/*
// @include https://one.network/*
// @include http://public.londonworks.gov.uk/roadworks/*
// @include http://streetworks.wiltshire.gov.uk/*
// @include https://openspacewmb.ordnancesurvey.co.uk/osmapapi/mapbuilder*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addValueChangeListener
// @grant unsafeWindow
// @version 3.10
// ==/UserScript==
// Contains Ordnance Survey data Crown copyright and database right 2012-2020
//
// Contents of the locatorData_*.js files are derived under the
// Open Government Licence from the OS Open Names and Open Roads datasets
//
// Contents of the gazetteer.js file are derived under the
// Open Government Licence from the OS Open Names dataset
/*
=======================================================================================================================
DONE FOR THIS RELEASE
=======================================================================================================================
Uses gazetteer data derived from the Open Names dataset
Fixes startup error on one.network page
=======================================================================================================================
Bug fixes - MUST BE CLEARED BEFORE RELEASE
=======================================================================================================================
=======================================================================================================================
Things to be checked
=======================================================================================================================
=======================================================================================================================
Proposed functionality
=======================================================================================================================
Restrict city name uniqueness testing to within each county rather than country-wide
=======================================================================================================================
New functionality in progress
=======================================================================================================================
Mark on map where the OS city names are located
*/
/* JSHint Directives */
/* globals OpenLayers: true */
/* globals osMap: true */
/* globals OpenSpace: true */
/* globals Elgin: true */
/* globals google: true */
/* globals gazetteerDataA: true */
/* globals gazetteerDataB: true */
/* globals oslRoadNameMatches: true */
/* globals map: true */
/* globals GM_setValue: true */
/* globals GM_getValue: true */
/* globals GM_addValueChangeListener: true */
/* globals unsafeWindow: true */
/* jshint bitwise: false */
/* jshint evil: true */
/* jshint esversion: 6 */
const oslVersion = '3.10';
const oslUpdateURL = 'https://greasyfork.org/scripts/1941-wme-to-os-link';
const oslBlockPath = 'https://greasemonkey.chizzum.com/osl_v3.0/';
const oslGazetteerURL = 'https://chizzum.com/greasemonkey/gaz_v5/gazetteer.js';
const oslPi = 3.14159265358979;
const oslPiDiv180 = (oslPi / 180);
const osl180DivPi = (180 / oslPi);
const oslLocatorBlockSize = 1000;
const oslCacheDecayPeriod = 60;
const oslMinUIWidth = 360;
const GAZ_ELM =
{
Name: 0,
CEast: 1,
CNorth: 2,
Type: 3,
Area: 4,
LEast: 5,
LNorth: 6,
REast: 7,
RNorth: 8
};
const OSL_ELM =
{
RoadName: 0,
RoadNumber: 1,
BoundW: 2,
BoundE: 3,
BoundS: 4,
BoundN: 5,
Geometry: 6,
AreaName: 7,
AltName: 8,
Classification: 9,
Function: 10,
Form: 11,
Structure: 12,
IsPrimary: 13,
IsTrunk: 14,
MAX: 15
};
const OSL_MODE =
{
Conversion: 0,
OpenNames: 1,
NameCheck: 2,
OpenRoads: 3,
};
const OSL_ROADCLASSIFICATIONS =
{
Undefined: 0,
Motorway: 1,
A_Road: 2,
B_Road: 3,
Classified_Unnumbered: 4,
Unclassified: 5,
Not_Classified: 6,
Unknown: 7
};
const oslRoadClassifications = new Array
(
'Undefined',
'Motorway',
'A Road',
'B Road',
'Classified Unnumbered',
'Unclassified',
'Not Classified',
'Unknown'
);
const OSL_ROADFUNCTIONS =
{
Undefined: 0,
Motorway: 1,
A_Road: 2,
B_Road: 3,
Minor_Road: 4,
Local_Road: 5,
Local_Access_Road: 6,
Restricted_Local_Access_Road: 7,
Secondary_Access_Road: 8
};
const oslRoadFunctions = new Array
(
'Undefined',
'Motorway',
'A Road',
'B Road',
'Minor Road',
'Local Road',
'Local Access Road',
'Restricted Local Access Road',
'Secondary Access Road'
);
const oslStrokeColoursByFunction = new Array
(
"red",
"deepskyblue",
"limegreen",
"darkorange",
"yellow",
"white",
"grey",
"tan",
"grey"
);
const OSL_ROADSTRUCTURES =
{
Undefined: 0,
Road_In_Tunnel: 1,
Road_On_Bridge: 2
};
const oslRoadStructures = new Array
(
'Undefined',
'Road In Tunnel',
'Road On Bridge'
);
const OSL_FORMSOFWAY =
{
Undefined: 0,
Single_Carriageway: 1,
Dual_Carriageway: 2,
Slip_Road: 3,
Roundabout: 4,
Collapsed_Dual_Carriageway: 5,
Guided_Busway: 6,
Shared_Use_Carriageway: 7
};
const oslFormsOfWay = new Array
(
'Undefined',
'Single Carriageway',
'Dual Carriageway',
'Slip Road',
'Roundabout',
'Collapsed Dual Carriageway',
'Guided Busway',
'Shared Use Carriageway'
);
// include names that don't get abbreviated, so that for names such as "Somewhere Green Way", the
// abbreviation function is able to detect the "Way" part of the name as the part that ought to
// be abbreviated, rather than treating it as a non-abbreviatable suffix and instead abbreviating
// the "Green" part instead...
const oslNameAbbreviations = new Array
(
'Avenue','Ave',
'Boulevard','Blvd',
'Broadway','Bdwy',
'Circus','Cir',
'Close','Cl',
'Court','Ct',
'Crescent','Cr',
'Drive','Dr',
'Garden','Gdn',
'Gardens','Gdns',
'Green','Gn',
'Grove','Gr',
'Lane','Ln',
'Mews','Mews',
'Mount','Mt',
'Place','Pl',
'Park','Pk',
'Ridge','Rdg',
'Road','Rd',
'Square','Sq',
'Street','St',
'Terrace','Ter',
'Valley','Val',
'By-pass','Bypass',
'Way','Way'
);
var oslUserPrefs = {};
var oslGazetteerData = [];
var oslAdvancedMode = false;
var oslEvalString = '';
var oslLoadingMsg = false;
var oslMLCDiv = null;
var oslOSLDiv = null;
var oslBBDiv = null;
var oslPrevHighlighted = null;
var oslSegmentHighlighted = false;
var oslPrevMouseX = null;
var oslPrevMouseY = null;
var oslDivDragging = false;
var oslPrevSelected = null;
var oslDoOSLUpdate = false;
var oslMousepos = null;
var oslMousePixelpos = null;
var oslDoneOnload = false;
var oslRefreshAutoTrack = false;
var oslOSOD_url = '';
var oslOSMC_url = '';
var oslRWO_url = '';
var oslLRR_url = '';
var oslSWG_url = '';
var oslPrevStreetName = '';
var oslMergeGazData = false;
var oslOSLMaskLayer = null;
var oslOSLNameCheckTimer = 0;
var oslOSLNCSegments = [];
var oslInUK = false;
var oslInLondon = false;
var oslInWiltshire = false;
var oslNorthings = null;
var oslEastings = null;
var oslLatitude = null;
var oslLongitude = null;
var oslHelmX = null;
var oslHelmY = null;
var oslHelmZ = null;
var oslBlocksToLoad = [];
var oslBlocksToTest = [];
// 50.06574112187924 -5.699894626953322
// 135261,25033
// 135256,25014
// +6, +19
// 51.35363338966115 1.4443961072966522
// 639795,167306
// 639800,167284
// -5, +22
// 60.15795987870581 -1.1466271562283679
// 447367,1141743
// 447362,1141733
// +5, +10
var oslVPLeft = 0;
var oslVPRight = 0;
var oslVPBottom = 0;
var oslVPTop = 0;
var oslBBDivInnerHTML = '';
var oslEvalEBlock = 0;
var oslEvalNBlock = 0;
var oslBlockData = null;
var oslBlockCacheList = [];
var oslBlockCacheTestTimer = (oslCacheDecayPeriod * 10);
var oslSegGeoDivInnerHTML = '';
var oslONC_E = null;
var oslONC_N = null;
var oslEBlock_min = null;
var oslEBlock_max = null;
var oslNBlock_min = null;
var oslNBlock_max = null;
var oslWazeBitsPresent = 0;
var oslOSLDivLeft;
var oslOSLDivTop;
var oslSegGeoDiv;
var oslWazeMapElement;
var oslDragBar;
var oslWindow;
var oslOSLDivTopMinimised;
var oslNCDiv;
var oslSegGeoUIDiv;
var oslOffsetToolbar = false;
var oslMOAdded = false;
var oslMTEMode = false;
var oslLocatorElements = null;
var oslUsingNewName = false;
var oslUseName = false;
var oslCityName = '';
var oslCountyName = '';
var oslUseAlt = false;
var oslAltNamesClearing = false;
var oslRORCenter = null;
var oslRORZoom = null;
var W = null;
function oslBootstrap()
{
if(document.location.host == 'one.network')
{
hlp_ONE.init();
}
else if(document.location.host == 'openspacewmb.ordnancesurvey.co.uk')
{
hlp_ODM.init();
}
else if(document.location.host == 'public.londonworks.gov.uk')
{
hlp_LRR.init();
}
else if(document.location.host == 'streetworks.wiltshire.gov.uk')
{
hlp_WSW.init();
}
else
{
// something in this version prevents WME from starting up properly if we initialise early in the WME startup.
// since I haven't yet figured out what it is we need to wait for, using a fixed delay of 2s seems to work OK...
window.setTimeout(oslInitialise,2000);
}
}
function oslAddLog(logtext)
{
console.log('WMEOpenData: '+logtext);
}
//-----------------------------------------------------------------------------------------------------------------------------------------
// 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://www.nearby.org.uk/tests/geotools2.js
// *
// * This file copyright (c)2005 Paul Dixon ([email protected])
// *
// * 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://www.nearby.org.uk/tests/GeoTools2.html
function oslOSGBtoWGS(oseast, osnorth)
{
const a = 6377563.396;
const b = 6356256.910;
const e0 = 400000;
const n0 = -100000;
const f0 = 0.999601272;
const PHI0 = 49.00000;
const LAM0 = -2.00000;
const RadPHI0 = PHI0 * oslPiDiv180;
const RadLAM0 = LAM0 * oslPiDiv180;
//Compute af0, bf0, e squared (e2), n and Et
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 Et = oseast - e0;
//Compute initial value for oslLatitude (PHId) in radians
var PHI1 = ((osnorth - n0) / af0) + RadPHI0;
var M = oslMarc(bf0, n, RadPHI0, PHI1);
var PHId = ((osnorth - n0 - M) / af0) + PHI1;
while (Math.abs(osnorth - n0 - M) > 0.00001)
{
PHId = ((osnorth - n0 - M) / af0) + PHI1;
M = oslMarc(bf0, n, RadPHI0, PHId);
PHI1 = PHId;
}
//Compute nu, rho and eta2 using value for PHId
var nu = af0 / (Math.sqrt(1 - (e2 * ( Math.pow(Math.sin(PHId),2)))));
var rho = (nu * (1 - e2)) / (1 - (e2 * Math.pow(Math.sin(PHId),2)));
var eta2 = (nu / rho) - 1;
//Compute Latitude
var VII = (Math.tan(PHId)) / (2 * rho * nu);
var VIII = ((Math.tan(PHId)) / (24 * rho * Math.pow(nu,3))) * (5 + (3 * (Math.pow(Math.tan(PHId),2))) + eta2 - (9 * eta2 * (Math.pow(Math.tan(PHId),2))));
//var IX = ((Math.tan(PHId)) / (720 * rho * Math.pow(nu,5))) * (61 + (90 * ((Math.tan(PHId)) ^ 2)) + (45 * (Math.pow(Math.tan(PHId),4))));
var IX = ((Math.tan(PHId)) / (720 * rho * Math.pow(nu,5))) * (61 + (90 * (Math.pow(Math.tan(PHId), 2))) + (45 * (Math.pow(Math.tan(PHId),4))));
//oslLatitude = osl180DivPi * (PHId - (Math.pow(Et,2) * VII) + (Math.pow(Et,4) * VIII) - ((Et ^ 6) * IX));
oslLatitude = osl180DivPi * (PHId - (Math.pow(Et,2) * VII) + (Math.pow(Et,4) * VIII) - (Math.pow(Et, 6) * IX));
//Compute Longitude
var X = (Math.pow(Math.cos(PHId),-1)) / nu;
var XI = ((Math.pow(Math.cos(PHId),-1)) / (6 * Math.pow(nu,3))) * ((nu / rho) + (2 * (Math.pow(Math.tan(PHId),2))));
var XII = ((Math.pow(Math.cos(PHId),-1)) / (120 * Math.pow(nu,5))) * (5 + (28 * (Math.pow(Math.tan(PHId),2))) + (24 * (Math.pow(Math.tan(PHId),4))));
var XIIA = ((Math.pow(Math.cos(PHId),-1)) / (5040 * Math.pow(nu,7))) * (61 + (662 * (Math.pow(Math.tan(PHId),2))) + (1320 * (Math.pow(Math.tan(PHId),4))) + (720 * (Math.pow(Math.tan(PHId),6))));
oslLongitude = osl180DivPi * (RadLAM0 + (Et * X) - (Math.pow(Et,3) * XI) + (Math.pow(Et,5) * XII) - (Math.pow(Et,7) * XIIA));
var RadPHI = oslLatitude * oslPiDiv180;
var RadLAM = oslLongitude * oslPiDiv180;
e2 = (Math.pow(6377563.396,2) - Math.pow(6356256.910,2)) / Math.pow(6377563.396,2);
var V = a / (Math.sqrt(1 - (e2 * ( Math.pow(Math.sin(RadPHI),2)))));
X = V * (Math.cos(RadPHI)) * (Math.cos(RadLAM));
var Y = V * (Math.cos(RadPHI)) * (Math.sin(RadLAM));
var Z = (V * (1 - e2)) * (Math.sin(RadPHI));
// do Helmert transforms
var sfactor = -20.4894 * 0.000001;
var RadX_Rot = (0.1502 / 3600) * oslPiDiv180;
var RadY_Rot = (0.2470 / 3600) * oslPiDiv180;
var RadZ_Rot = (0.8421 / 3600) * oslPiDiv180;
var X2 = (X + (X * sfactor) - (Y * RadZ_Rot) + (Z * RadY_Rot) + 446.448);
var Y2 = (X * RadZ_Rot) + Y + (Y * sfactor) - (Z * RadX_Rot) -125.157;
var Z2 = (-1 * X * RadY_Rot) + (Y * RadX_Rot) + Z + (Z * sfactor) + 542.060;
var RootXYSqr = Math.sqrt(Math.pow(X2,2) + Math.pow(Y2,2));
e2 = (Math.pow(6378137.000,2) - Math.pow(6356752.313,2)) / Math.pow(6378137.000,2);
PHI1 = Math.atan2(Z2 , (RootXYSqr * (1 - e2)) );
V = 6378137.000 / (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 = 6378137.000 / (Math.sqrt(1 - (e2 * Math.pow(Math.sin(PHI1),2))));
PHI2 = Math.atan2((Z2 + (e2 * V * (Math.sin(PHI1)))) , RootXYSqr);
}
oslLatitude = PHI2 * osl180DivPi;
oslLongitude = Math.atan2(Y2 , X2) * osl180DivPi;
}
function oslWGStoOSGB()
{
oslLatLontoHelmXYZ();
var oslLatitude2 = oslXYZtoLat();
var oslLongitude2 = Math.atan2(oslHelmY , oslHelmX) * osl180DivPi;
oslLatLonoslToOSGrid(oslLatitude2,oslLongitude2);
}
function oslLatLontoHelmXYZ()
{
const a = 6378137.0;
const b = 6356752.313;
const DX = -446.448;
const DY = 125.157;
const DZ = -542.060;
const rotX = -0.1502;
const rotY = -0.2470;
const rotZ = -0.8421;
const sfactor = 20.4894 * 0.000001;
const e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
// perform initial lat-lon to cartesian coordinate translation
var RadPHI = oslLatitude * oslPiDiv180;
var RadLAM = oslLongitude * oslPiDiv180;
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) * oslPiDiv180;
var RadY_Rot = (rotY / 3600) * oslPiDiv180;
var RadZ_Rot = (rotZ / 3600) * oslPiDiv180;
oslHelmX = (cartX + (cartX * sfactor) - (cartY * RadZ_Rot) + (cartZ * RadY_Rot) + DX);
oslHelmY = (cartX * RadZ_Rot) + cartY + (cartY * sfactor) - (cartZ * RadX_Rot) + DY;
oslHelmZ = (-1 * cartX * RadY_Rot) + (cartY * RadX_Rot) + cartZ + (cartZ * sfactor) + DZ;
}
function oslXYZtoLat()
{
const a = 6377563.396;
const b = 6356256.910;
const e2 = (Math.pow(a,2) - Math.pow(b,2)) / Math.pow(a,2);
var RootXYSqr = Math.sqrt(Math.pow(oslHelmX,2) + Math.pow(oslHelmY,2));
var PHI1 = Math.atan2(oslHelmZ , (RootXYSqr * (1 - e2)) );
var PHI = oslIterateOSLXYZtoLat(a, e2, PHI1, oslHelmZ, RootXYSqr);
return PHI * osl180DivPi;
}
function oslIterateOSLXYZtoLat(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 oslMarc(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 oslLatLonoslToOSGrid(PHI, LAM)
{
const a = 6377563.396;
const b = 6356256.910;
const e0 = 400000;
const n0 = -100000;
const f0 = 0.999601272;
const PHI0 = 49.00000;
const LAM0 = -2.00000;
const RadPHI0 = PHI0 * oslPiDiv180;
const RadLAM0 = LAM0 * oslPiDiv180;
const af0 = a * f0;
const bf0 = b * f0;
const n = (af0 - bf0) / (af0 + bf0);
const e2 = (Math.pow(af0,2) - Math.pow(bf0,2)) / Math.pow(af0,2);
var RadPHI = PHI * oslPiDiv180;
var RadLAM = LAM * oslPiDiv180;
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 = oslMarc(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));
oslEastings = Math.round(e0 + (p * IV) + (Math.pow(p,3) * V) + (Math.pow(p,5) * VI));
oslNorthings = Math.round(I + (Math.pow(p,2) * II) + (Math.pow(p,4) * III) + (Math.pow(p,6) * IIIA));
oslNorthings -= 16; // the above calculations give a northings error of between 10-22m, so add a final adjustment so that the error is evened out and reduced to +/- 6m
}
//-----------------------------------------------------------------------------------------------------------------------------------------
function oslCaseCorrect(wrongcase)
{
var loop;
var correctedCase = '';
for(loop=0;loop<wrongcase.length;loop++)
{
// capitalise first letter following one of these substrings
if
(
(loop === 0)||
(wrongcase[loop-1] == ' ')||
(wrongcase[loop-1] == '(')||
(wrongcase.substr(loop-3,3) == '-Y-')||
(wrongcase.substr(loop-4,4) == '-YR-')
) correctedCase += wrongcase[loop].toUpperCase();
else correctedCase += wrongcase[loop].toLowerCase();
}
// recapitalise any roman numerals
correctedCase = correctedCase.replace(' Ii ',' II ');
correctedCase = correctedCase.replace(' Iii ',' III ');
correctedCase = correctedCase.replace(' Iv ',' IV ');
correctedCase = correctedCase.replace(' Vi ',' VI ');
correctedCase = correctedCase.replace(' Vii ',' VII ');
return correctedCase;
}
function oslSaintsPreserveUs(oslName)
{
var nameBits = [];
if(oslName.indexOf('St ') != -1)
{
nameBits = oslName.split('St ');
oslName = nameBits[0] + 'St. ' + nameBits[1];
}
else if(oslName.indexOf('Saint ') != -1)
{
nameBits = oslName.split('Saint ');
oslName = nameBits[0] + 'St. ' + nameBits[1];
}
return oslName;
}
function oslWazeifyStreetName(oslName, debugOutput)
{
var wazeName = '';
var loop;
// strip out any HTML encoding added by the server when returning the street name data...
var textArea = document.createElement('textarea');
textArea.innerHTML = oslName;
oslName = textArea.value;
wazeName = oslCaseCorrect(oslName);
wazeName = oslSaintsPreserveUs(wazeName);
var nameoslPieces = wazeName.split(' ');
if(nameoslPieces.length > 1)
{
var dirSuffix = '';
var namePrefix = '';
if((nameoslPieces[nameoslPieces.length-1] == 'North')||(nameoslPieces[nameoslPieces.length-1] == 'South')||(nameoslPieces[nameoslPieces.length-1] == 'East')||(nameoslPieces[nameoslPieces.length-1] == 'West'))
{
dirSuffix = ' ' + nameoslPieces[nameoslPieces.length-1][0];
for(loop=0;loop<nameoslPieces.length-1;loop++) namePrefix += (nameoslPieces[loop] + ' ');
}
else
{
for(loop=0;loop<nameoslPieces.length;loop++) namePrefix += (nameoslPieces[loop] + ' ');
}
namePrefix = namePrefix.trimRight(1);
if(debugOutput === true) console.log(oslName);
// replace road type with abbreviated form
for(var pass=0;pass<2;pass++)
{
for(loop=0;loop<oslNameAbbreviations.length;loop+=2)
{
var abbrPos = namePrefix.lastIndexOf(oslNameAbbreviations[loop]);
var abbrLen = oslNameAbbreviations[loop].length;
var npLength = namePrefix.length;
var npRemaining = npLength - abbrPos;
if(debugOutput === true) console.log(pass,' ',oslNameAbbreviations[loop],' ',abbrPos,' ',abbrLen,' ',npLength,' ',npRemaining);
if(abbrPos != -1)
{
// make sure the road type we've found comes firstly at the end of the name string, or is suffixed with a space
// if there's a non-road type at the end of the string (e.g. High Road Eastcote)
// isn't, then we've actually found a type match within a longer string segment (e.g. The Parkside) and so we
// should leave it alone...
if
(
((pass === 0) && (npRemaining == abbrLen)) ||
((pass == 1) && (namePrefix[abbrPos+abbrLen] == ' '))
)
{
var preName = namePrefix.substr(0,abbrPos);
if((preName.length >= 4) && (preName.lastIndexOf("The") != (preName.length - 4)))
{
var theName = namePrefix.substr(abbrPos);
theName = theName.replace(oslNameAbbreviations[loop],oslNameAbbreviations[loop+1]);
wazeName = preName + theName + dirSuffix;
return wazeName;
}
}
}
}
}
wazeName = namePrefix + dirSuffix;
}
return wazeName;
}
function oslCPDistance(cpE, cpN, posE, posN)
{
return Math.round(Math.sqrt(((posE - cpE) * (posE - cpE)) + ((posN - cpN) * (posN - cpN))));
}
function oslGetBBCornerPixels(boxW, boxE, boxS, boxN)
{
var lonlat_sw = new OpenLayers.LonLat(boxW,boxS);
var lonlat_se = new OpenLayers.LonLat(boxE,boxS);
var lonlat_nw = new OpenLayers.LonLat(boxW,boxN);
var lonlat_ne = new OpenLayers.LonLat(boxE,boxN);
lonlat_sw.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
lonlat_se.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
lonlat_nw.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
lonlat_ne.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
var pix_sw = W.map.getPixelFromLonLat(lonlat_sw);
var pix_se = W.map.getPixelFromLonLat(lonlat_se);
var pix_ne = W.map.getPixelFromLonLat(lonlat_ne);
var pix_nw = W.map.getPixelFromLonLat(lonlat_nw);
boxE = (pix_ne.x + pix_se.x) / 2;
boxW = (pix_nw.x + pix_sw.x) / 2;
boxN = (pix_ne.y + pix_nw.y) / 2;
boxS = (pix_se.y + pix_sw.y) / 2;
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;
}
return [boxW, boxE, boxS, boxN];
}
function oslVisualiseBoundingBox(boxW, boxE, boxS, boxN, mode)
{
if(oslOSLDiv.style.height == '0px')
{
oslBBDiv.innerHTML = '';
return;
}
var boxPos = [boxW, boxE, boxS, boxN];
if((mode == 1) || (mode == 2))
{
boxPos = oslGetBBCornerPixels(boxW, boxE, boxS, boxN);
}
if(mode === 0)
{
oslBBDivInnerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="'+document.getElementById('WazeMap').offsetWidth+'px" height="'+document.getElementById('WazeMap').offsetHeight+'px" version="1.1">';
}
else if(mode == 1)
{
oslBBDivInnerHTML += '<rect x="'+boxPos[0]+'" y="'+boxPos[3]+'" width="'+(boxPos[1]-boxPos[0])+'" height="'+(boxPos[2]-boxPos[3])+'" style="fill:yellow;stroke:pink;stroke-width:4;fill-opacity:0.25;stroke-opacity:0.25"/>';
}
else if(mode == 2)
{
oslBBDivInnerHTML += '<rect x="'+boxPos[0]+'" y="'+boxPos[3]+'" width="'+(boxPos[1]-boxPos[0])+'" height="'+(boxPos[2]-boxPos[3])+'" style="fill:lightgrey;stroke:grey;stroke-width:4;fill-opacity:0.25;stroke-opacity:0.25"/>';
}
else if(mode == 3)
{
oslBBDivInnerHTML += '</svg>';
oslBBDiv.innerHTML = oslBBDivInnerHTML;
}
}
function oslMergeGazetteerData()
{
if((typeof(gazetteerDataA) == "undefined") || (typeof(gazetteerDataB) == "undefined")) return false;
if(oslMergeGazData)
{
oslGazetteerData = gazetteerDataA;
oslGazetteerData = oslGazetteerData.concat(gazetteerDataB);
oslMergeGazData = false;
for(var idx=0;idx<oslGazetteerData.length;idx++)
{
oslGazetteerData[idx] = oslSaintsPreserveUs(oslGazetteerData[idx]);
}
oslAddLog('gazetteer data loaded, '+oslGazetteerData.length+' entries');
}
return true;
}
function oslHighlightOSCityName()
{
var selectedIdx = document.getElementById('oslOSCityNames').selectedIndex;
}
function oslGetNearbyCityNames()
{
if(oslMergeGazetteerData() === false) return;
var names = [];
for(var idx=0;idx<oslGazetteerData.length;idx++)
{
var gazElements = oslGazetteerData[idx].split(':');
var cnEastings = gazElements[GAZ_ELM.CEast];
var cnNorthings = gazElements[GAZ_ELM.CNorth];
if((Math.abs(cnNorthings-oslNorthings) <= 5000)&&(Math.abs(cnEastings-oslEastings) <= 5000))
{
var dist = oslCPDistance(cnEastings,cnNorthings,oslEastings,oslNorthings);
if(dist <= 5000)
{
names.push((dist * 1000000) + idx);
}
}
}
if(names.length > 1) names.sort(function(a,b){return a-b;});
var cityInTopTen = false;
var matchedOSName = false;
var matchedIdx = -1;
var listLength = names.length;
if(listLength > 10) listLength = 10;
var listOpt;
var gElements;
var gDist;
var cityName;
var oOCN = document.getElementById('oslOSCityNames');
for(idx=0;idx<listLength;idx++)
{
gElements = oslGazetteerData[names[idx] % 1000000].split(':');
gDist = (Math.round(names[idx] / 100000000)/10);
// Build namestring for entry in the drop-down list - start with the placename :-)
listOpt = document.createElement('option');
cityName = gElements[GAZ_ELM.Name];
listOpt.text = cityName;
// if the name is neither a city nor unique, append a (county) suffix
if(gElements[GAZ_ELM.Type] == 'C') cityInTopTen = true;
else
{
if(oslCheckCityNameDuplicates(gElements[GAZ_ELM.Name],1) > 1)
{
listOpt.text += ', '+gElements[GAZ_ELM.Area];
}
}
if(sessionStorage.cityNameRB == 'optUseOS')
{
if(cityName == sessionStorage.myCity)
{
matchedOSName = true;
matchedIdx = idx;
}
}
// Add place type and distance in [] brackets to allow easy removal later...
if(gElements[GAZ_ELM.Type] == 'C') listOpt.text += ' [City, ';
else if(gElements[GAZ_ELM.Type] == 'T') listOpt.text += ' [Town, ';
else if(gElements[GAZ_ELM.Type] == 'V') listOpt.text += ' [Village, ';
else if(gElements[GAZ_ELM.Type] == 'H') listOpt.text += ' [Hamlet, ';
else listOpt.text += ' [Other, ';
listOpt.text += gDist + 'km]';
oOCN.add(listOpt,null);
}
if((!cityInTopTen) && (names.length > 10))
{
idx = 10;
while((idx < names.length) && (!cityInTopTen))
{
gElements = oslGazetteerData[names[idx] % 1000000].split(':');
if(gElements[GAZ_ELM.Type] == 'C')
{
cityInTopTen = true;
gDist = ' [City, '+(Math.round(names[idx] / 100000000)/10)+'km]';
listOpt = document.createElement('option');
listOpt.text = gElements[GAZ_ELM.Name]+gDist;
oOCN.add(listOpt,null);
if(sessionStorage.cityNameRB == 'optUseOS')
{
if(gElements[GAZ_ELM.Name] == sessionStorage.myCity)
{
matchedOSName = true;
matchedIdx = 10;
break;
}
}
}
idx++;
}
}
//oOCN.addEventListener("input", oslHighlightOSCityName, false);
if(matchedOSName === true) oOCN.options.selectedIndex = matchedIdx;
if((sessionStorage.cityNameRB == 'optUseOS') && (matchedOSName === false))
{
oslAddLog('Selected city name no longer in nearby OS list...');
alert('City name no longer present in nearby OS data, please reselect');
sessionStorage.cityNameRB = 'optUseExisting';
document.getElementById('optUseExisting').checked = true;
}
}
function oslCheckCityNameDuplicates(cityName, mode)
{
if(oslMergeGazetteerData() === false) return;
var cnCount = 0;
var searchDist = Math.round(oslGazetteerData.length/2);
var searchIdx = searchDist;
var hasCounty = false;
var debugOutput = false;
// remove county suffix from actual city name string if present
if(cityName.indexOf('(') != -1)
{
cityName = cityName.substr(0,cityName.indexOf('('));
cityName = cityName.replace(/^\s+|\s+$/g, "");
hasCounty = true;
}
// remove script-appended county suffix from city name held in drop down if present
if(cityName.indexOf(',') != -1)
{
cityName = cityName.substr(0,cityName.indexOf(','));
cityName = cityName.replace(/^\s+|\s+$/g, "");
}
cityName = cityName.toLowerCase();
cityName = cityName.replace(/-/g, ' ');
var gazName = '';
if(debugOutput === true) console.log('scan for duplicates of '+cityName);
var gazElements = [];
while((searchDist > 1) && (cityName.localeCompare(gazName) !== 0))
{
searchDist = Math.round(searchDist/2);
gazElements = oslGazetteerData[searchIdx].split(':');
gazName = gazElements[GAZ_ELM.Name].toLowerCase();
gazName = gazName.replace(/-/g, ' ');
if(debugOutput === true) console.log('a: '+searchDist+' '+searchIdx+' '+gazName);
if(cityName.localeCompare(gazName) > 0) searchIdx += searchDist;
else if(cityName.localeCompare(gazName) < 0) searchIdx -= searchDist;
if(searchIdx >= oslGazetteerData.length) searchIdx = oslGazetteerData.length-1;
if(searchIdx < 0) searchIdx = 0;
}
gazElements = oslGazetteerData[searchIdx].split(':');
gazName = gazElements[GAZ_ELM.Name].toLowerCase();
gazName = gazName.replace(/-/g, ' ');
while((searchIdx > 0) && (cityName.localeCompare(gazName) <= 0))
{
gazElements = oslGazetteerData[--searchIdx].split(':');
gazName = gazElements[GAZ_ELM.Name].toLowerCase();
gazName = gazName.replace(/-/g, ' ');
if(debugOutput === true) console.log('b: '+(searchIdx)+' '+gazName);
}
gazElements = oslGazetteerData[searchIdx].split(':');
gazName = gazElements[GAZ_ELM.Name].toLowerCase();
gazName = gazName.replace(/-/g, ' ');
while((searchIdx < oslGazetteerData.length) && (cityName.localeCompare(gazName) > 0))
{
gazElements = oslGazetteerData[++searchIdx].split(':');
gazName = gazElements[GAZ_ELM.Name].toLowerCase();
gazName = gazName.replace(/-/g, ' ');
if(debugOutput === true) console.log('c: '+(searchIdx)+' '+gazName);
}
while((cityName.localeCompare(gazName) === 0) && (searchIdx < oslGazetteerData.length))
{
cnCount++;
gazElements = oslGazetteerData[++searchIdx].split(':');
gazName = gazElements[GAZ_ELM.Name].toLowerCase();
gazName = gazName.replace(/-/g, ' ');
if(debugOutput === true) console.log('d: '+(searchIdx)+' '+gazName+' '+cnCount);
}
if(mode === 0)
{
var newHTML = '';
if(cnCount === 0) newHTML = ' Place name is not in OS data';
else if(cnCount == 1)
{
newHTML = ' Place name is unique';
if(hasCounty) newHTML += '<br> <i>(County) suffix not required</i>';
}
else
{
newHTML = ' Place name is not unique';
}
document.getElementById('oslCNInfo').innerHTML = newHTML;
}
else return cnCount;
}
function oslHighlightAdjacentSameNameSegments(ldEastings, ldNorthings, ldIgnoreIdx, srcElements)
{
ldNorthings -= oslLocatorBlockSize;
ldEastings -= oslLocatorBlockSize;
for(var x = 0; x < 3; ++x)
{
for(var y = 0; y < 3; ++y)
{
var arrayName = 'locatorData_'+(ldEastings + (x * oslLocatorBlockSize))+'_'+(ldNorthings + (y * oslLocatorBlockSize));
oslEvalString = 'typeof '+arrayName;
if(eval(oslEvalString) != "undefined")
{
oslEvalString = 'oslBlockData = '+arrayName;
eval(oslEvalString);
for(var loop = 0; loop < oslBlockData.length; ++loop)
{
if(loop != ldIgnoreIdx)
{
var locatorElements = oslBlockData[loop].split(':');
if
(
(locatorElements[OSL_ELM.RoadName] == srcElements[OSL_ELM.RoadName]) &&
(locatorElements[OSL_ELM.RoadNumber] == srcElements[OSL_ELM.RoadNumber]) &&
(locatorElements[OSL_ELM.AreaName] == srcElements[OSL_ELM.AreaName])
)
{
oslVisualiseBoundingBox(locatorElements[OSL_ELM.BoundW],locatorElements[OSL_ELM.BoundE],locatorElements[OSL_ELM.BoundS],locatorElements[OSL_ELM.BoundN],2);
}
}
}
}
}
}
}
function oslRadioClick()
{
var oslElements = document.getElementById('oslRoadNameMatches');
var selectedName = '';
var loop;
var roadData;
var locatorElements;
var tagname;
var attr;
var oslID;
var evalstr;
for(loop=0;loop<oslElements.childNodes.length;loop++)
{
if(oslElements.childNodes[loop].nodeType == 1)
{
tagname = oslElements.childNodes[loop].tagName;
if(tagname !== null)
{
if(tagname == "LABEL")
{
if(oslElements.childNodes[loop].childNodes[0].checked)
{
attr = oslElements.childNodes[loop].childNodes[0].attributes.getNamedItem("id").value;
if((attr.indexOf('oslID_') === 0) || (attr.indexOf('alt-oslID_') === 0))
{
roadData = '';
oslID = attr.split('_');
if(oslID[1] != 'null')
{
evalstr = 'var roadData = locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
eval(evalstr);
}
else
{
roadData = "null:null";
}
locatorElements = roadData.split(":");
if(locatorElements[OSL_ELM.RoadName] != 'null')
{
selectedName = locatorElements[OSL_ELM.RoadName]+locatorElements[OSL_ELM.RoadNumber];
oslVisualiseBoundingBox(0,0,0,0,0);
oslVisualiseBoundingBox(locatorElements[OSL_ELM.BoundW],locatorElements[OSL_ELM.BoundE],locatorElements[OSL_ELM.BoundS],locatorElements[OSL_ELM.BoundN],1);
oslHighlightAdjacentSameNameSegments(oslID[1], oslID[2], oslID[3], locatorElements);
}
else
{
oslBBDiv.innerHTML = '';
}
}
}
}
}
}
}
if(selectedName === '')
{
oslBBDiv.innerHTML = '';
return;
}
oslVisualiseBoundingBox(0,0,0,0,3);
}
function oslClick()
{
oslCityName = '';
oslCountyName = '';
oslUsingNewName = false;
if(document.getElementById('optUseNewManual').checked)
{
oslCityName = oslCaseCorrect(document.getElementById('myCityName').value);
oslUsingNewName = true;
}
else if(document.getElementById('optUseExistingWME').checked)
{
var oWCN = document.getElementById('oslWMECityNames');
oslCityName = oWCN.options[oWCN.options.selectedIndex].text;
if(oslCityName.indexOf(', ') !== -1)
{
oslCountyName = oslCityName.split(', ')[1];
oslCityName = oslCityName.split(', ')[0];
}
oslUsingNewName = true;
}
else if(document.getElementById('optUseOS').checked)
{
var oOCN = document.getElementById('oslOSCityNames');
oslCityName = oOCN.options[oOCN.options.selectedIndex].text;
oslCityName = oslCityName.substring(0,oslCityName.indexOf('[')-1);
if(oslCityName.indexOf(', ') !== -1)
{
oslCountyName = oslCityName.split(', ')[1];
oslCityName = oslCityName.split(', ')[0];
}
oslUsingNewName = true;
}
if(sessionStorage.myCity === '')
{
oslAddLog('Update city name position at '+oslEastings+'x'+oslNorthings);
sessionStorage.cityChangeEastings = oslEastings;
sessionStorage.cityChangeNorthings = oslNorthings;
}
if(oslCountyName !== '')
{
sessionStorage.myCity = oslCityName+', '+oslCountyName;
}
else
{
sessionStorage.myCity = oslCityName;
}
oslUseName = false;
if((oslCityName.length > 0) && oslUsingNewName)
{
oslCheckCityNameDuplicates(oslCityName,0);
if(oslCityName != sessionStorage.prevCityName)
{
oslAddLog('Change of city name at '+oslEastings+'x'+oslNorthings);
sessionStorage.cityChangeEastings = oslEastings;
sessionStorage.cityChangeNorthings = oslNorthings;
sessionStorage.prevCityName = oslCityName;
oslUseName = true;
}
else
{
var nameChangeDist = oslCPDistance(oslEastings,oslNorthings,sessionStorage.cityChangeEastings,sessionStorage.cityChangeNorthings);
oslAddLog('Current name was set '+nameChangeDist+'m away from segment location');
if(nameChangeDist > 1000)
{
oslAddLog('Distance exceeds 1km threshold, name verification required...');
if(confirm('Confirm continued use of this city name'))
{
oslAddLog('Confirm city name at '+oslEastings+'x'+oslNorthings);
sessionStorage.cityChangeEastings = oslEastings;
sessionStorage.cityChangeNorthings = oslNorthings;
oslUseName = true;
}
}
else
{
oslUseName = true;
}
}
}
var oslElements = document.getElementById('oslRoadNameMatches');
for(var loop=0;loop<oslElements.childNodes.length;loop++)
{
if(oslElements.childNodes[loop].nodeType == 1)
{
var tagname = oslElements.childNodes[loop].tagName;
if(tagname !== null)
{
if(tagname == "LABEL")
{
var rbElement = oslElements.childNodes[loop].childNodes[0];
if((rbElement.name == "oslChoice") && (rbElement.checked))
{
var attr = rbElement.attributes.getNamedItem("id").value;
var useMain = (attr.indexOf('oslID_') === 0);
oslUseAlt = (attr.indexOf('alt-oslID_') === 0);
if((useMain === true) || (oslUseAlt === true))
{
var roadData = '';
var oslID = attr.split('_');
if(oslID[1] != 'null')
{
var evalstr = 'var roadData = locatorData_'+oslID[1]+'_'+oslID[2]+'['+oslID[3]+']';
eval(evalstr);
}
else
{
for(var i = 0; i < OSL_ELM.MAX; ++i)
{
roadData += ':';
}
}
oslLocatorElements = roadData.split(":");
// auto-click the Edit Address link...
document.getElementsByClassName('full-address')[0].click();
oslAltNamesClearing = false;
oslWaitAddressElementOpen();
}
}
}
}
}
}
}
function oslWaitAddressElementOpen()
{
// clear any altnames that may be present...
var altNames = document.getElementsByClassName('alt-street-delete').length;
if(altNames > 0)
{
if(oslAltNamesClearing == false)
{
if(document.getElementsByClassName('alt-street-delete')[0].offsetHeight == 0)
{
window.setTimeout(oslWaitAddressElementOpen, 500);
return;
}
}
oslAltNamesClearing = true;
for(var j = 0; j < altNames; ++j)
{
document.getElementsByClassName('alt-street-delete')[j].click();
if(document.getElementsByClassName('alt-street-delete')[j].offsetHeight > 0)
{
window.setTimeout(oslWaitAddressElementOpen, 500);
return;
}
}
}
// make sure the Country field is set to "United Kingdom"
var snelm = document.getElementsByClassName('country-id')[0];
if(snelm.value != 234) snelm.value = 234;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
// fill in the City field
snelm = document.getElementsByClassName('city-name')[0];
if(oslUsingNewName)
{
if(document.getElementById('optUseNewManual').checked === true)
{
sessionStorage.cityNameRB = 'optUseNewManual';
}
else if(document.getElementById('optUseExistingWME').checked === true)
{
sessionStorage.cityNameRB = 'optUseExistingWME';
}
else if(document.getElementById('optUseOS').checked === true)
{
sessionStorage.cityNameRB = 'optUseOS';
}
if(oslUseName)
{
snelm.value = oslCityName;
snelm.disabled = false;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
snelm = document.getElementsByClassName('empty-city')[0];
snelm.checked = false;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
if(oslCountyName !== '')
{
// set the county field if one was provided with the selected city name
var countyIdx;
for(countyIdx = 0; countyIdx < document.getElementsByClassName('state-id')[0].options.length; countyIdx++)
{
if(document.getElementsByClassName('state-id')[0].options[countyIdx].innerHTML == oslCountyName)
{
document.getElementsByClassName('state-id')[0].options.selectedIndex = countyIdx;
document.getElementsByClassName('state-id')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
break;
}
}
}
}
}
else if(document.getElementById('optClearExisting').checked === true)
{
sessionStorage.cityNameRB = 'optClearExisting';
snelm.disabled = true;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
snelm = document.getElementsByClassName('empty-city')[0];
snelm.checked = true;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
}
else
{
sessionStorage.cityNameRB = 'optUseExisting';
}
if(oslUseAlt === true)
{
var tName = oslLocatorElements[OSL_ELM.RoadName];
oslLocatorElements[OSL_ELM.RoadName] = oslLocatorElements[OSL_ELM.AltName];
oslLocatorElements[OSL_ELM.AltName] = tName;
}
// finally the Street field
var oslName = oslLocatorElements[OSL_ELM.RoadNumber];
if((oslLocatorElements[OSL_ELM.RoadName].length > 0)&&(oslLocatorElements[OSL_ELM.RoadNumber].length > 0)) oslName += ' - ';
var altName = oslName;
if((oslName.length > 0)||(oslLocatorElements[OSL_ELM.RoadName].length > 0))
{
oslName += oslWazeifyStreetName(oslLocatorElements[OSL_ELM.RoadName], false);
oslPrevStreetName = oslName;
snelm = document.getElementsByClassName('street-name')[0];
snelm.value = oslName;
snelm.disabled = false;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
snelm = document.getElementsByClassName('empty-street')[0];
snelm.checked = false;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
}
else
{
snelm = document.getElementsByClassName('street-name')[0];
snelm.value = '';
snelm.disabled = true;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
snelm = document.getElementsByClassName('empty-street')[0];
snelm.checked = true;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
}
if(oslLocatorElements[OSL_ELM.AltName] != '')
{
altName += oslWazeifyStreetName(oslLocatorElements[OSL_ELM.AltName], false);
document.getElementsByClassName('add-alt-street-btn')[0].click();
snelm = document.getElementsByClassName('alt-street-name')[0];
snelm.value = altName;
snelm.disabled = false;
snelm.dispatchEvent(new Event('change', { 'bubbles': true}));
if(document.getElementById('optUseExisting').checked === true)
{
if(document.getElementsByClassName('empty-city')[0].checked === true)
{
snelm = document.getElementsByClassName('alt-address empty-city')[0];
snelm.checked = true;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
}
else
{
oslUsingNewName = true;
oslUseName = true;
oslCityName = document.getElementsByClassName("city-name form-control")[0].value;
}
}
snelm = document.getElementsByClassName('alt-city-name')[0];
if(oslUsingNewName)
{
if(oslUseName)
{
snelm.value = oslCityName;
snelm.disabled = false;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
snelm = document.getElementsByClassName('alt-address empty-city')[0];
snelm.checked = false;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
}
}
else if(document.getElementById('optClearExisting').checked === true)
{
snelm.disabled = true;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
snelm = document.getElementsByClassName('alt-address empty-city')[0];
snelm.checked = true;
snelm.dispatchEvent(new Event('change', { 'bubbles': true }));
}
}
if(oslAdvancedMode)
{
// auto-click the Apply button...
document.getElementsByClassName('address-form')[0].getElementsByClassName('save-button')[0].click();
}
}
function oslMatch(oslLink, oslArea, oslRadioID, oslAltRadioID)
{
this.oslLink = oslLink;
this.oslArea = oslArea;
this.oslRadioID = oslRadioID;
this.oslAltRadioID = oslAltRadioID;
}
function oslSortCandidates(a,b)
{
var x = a.oslArea;
var y = b.oslArea;
return((x<y) ? -1 : ((x>y) ? 1 : 0));
}
function oslCityNameKeyup()
{
oslCheckCityNameDuplicates(oslCaseCorrect(document.getElementById('myCityName').value),0);
document.getElementById('optUseNewManual').checked = true;
}
function oslSelectWMEName()
{
var oWCN = document.getElementById('oslWMECityNames');
var cityName = oWCN.options[oWCN.options.selectedIndex].text;
oslCheckCityNameDuplicates(cityName,0);
document.getElementById('optUseExistingWME').checked = true;
}
function oslSelectOSName()
{
var oOCN = document.getElementById('oslOSCityNames');
var cityName = oOCN.options[oOCN.options.selectedIndex].text;
cityName = cityName.substring(0,cityName.indexOf('[')-1);
document.getElementById('optUseOS').checked = true;
document.getElementById('oslCNInfo').innerHTML = '';
}
function oslBlockCacheObj(blockName)
{
this.blockName = blockName;
this.lastAccessed = Math.floor(new Date().getTime() / 1000);
}
function oslLoadBlocks()
{
for(var i = 0; i < oslBlocksToLoad.length;)
{
// inject block data
var script = document.createElement("script");
script.setAttribute('type','text/javascript');
script.setAttribute('charset','UTF-8');
script.src = oslBlocksToLoad[i];
document.head.appendChild(script);
oslLoadingMsg = true;
oslBlockCacheList.push(new oslBlockCacheObj(oslBlocksToLoad[i+1]));
i += 2;
}
}
function oslToOSGrid(lat, lon, mode)
{
if(oslInUK === false) return;
var loop;
var i;
var x;
var y;
var eBlock_point;
var nBlock_point;
var eBlock;
var nBlock;
if((lat !== 0) && (mode != OSL_MODE.OpenRoads))
{
if(mode == OSL_MODE.NameCheck)
{
oslEastings = lat;
oslNorthings = lon;
}
else
{
oslLatitude = lat;
oslLongitude = lon;
oslWGStoOSGB();
}
}
if((mode == OSL_MODE.OpenNames) || (mode == OSL_MODE.NameCheck))
{
// determine which grid block contains the current mouse position
eBlock_point = (Math.floor(oslEastings/oslLocatorBlockSize)) * oslLocatorBlockSize;
nBlock_point = (Math.floor(oslNorthings/oslLocatorBlockSize)) * oslLocatorBlockSize;
var candidates = [];
oslBlocksToLoad = [];
var arrayName;
var oslEvalString;
for(x = -1; x < 2; x++)
{
for(y = -1; y < 2; y++)
{
eBlock = (eBlock_point + (oslLocatorBlockSize * x));
nBlock = (nBlock_point + (oslLocatorBlockSize * y));
// check we're within the outer bounds of the current OS dataset...
if
(
(eBlock >= 64000) &&
(eBlock <= 655999) &&
(nBlock >= 8000) &&
(nBlock <= 1214999)
)
{
arrayName = 'locatorData_'+eBlock+'_'+nBlock;
// check to see if there's a corresponding array already loaded...
oslEvalString = 'typeof '+arrayName;
if(eval(oslEvalString) == "undefined")
{
// create a blank placeholder which will get replaced by the actual data if the array is present on the server...
eval(arrayName+' = []');
oslBlocksToLoad.push(oslBlockPath+Math.floor(eBlock / 100000)+'/'+Math.floor(nBlock / 100000)+'/'+arrayName+'.user.js');
oslBlocksToLoad.push(arrayName);
}
}
}
}
if(oslBlocksToLoad.length > 0)
{
oslLoadBlocks();
}
candidates = [];
if(mode == OSL_MODE.OpenNames) candidates[candidates.length++] = new oslMatch('<label style="display:inline;"><input type="radio" name="oslChoice" id="oslID_null_null_null" />Un-named segment</label><br>',1000000000000,'oslID_null_null_null',null);
for(x = -1; x < 2; x++)
{
for(y = -1; y < 2; y++)
{
eBlock = (eBlock_point + (oslLocatorBlockSize * x));
nBlock = (nBlock_point + (oslLocatorBlockSize * y));
// check we're within the outer bounds of the current OS dataset...
if ((eBlock >= 64000) && (eBlock <= 655999) && (nBlock >= 8000) && (nBlock <= 1214999))
{
arrayName = 'locatorData_'+eBlock+'_'+nBlock;
oslEvalString = 'typeof '+arrayName;
if(eval(oslEvalString) != "undefined")
{
oslLoadingMsg = false;
// yes... make a local copy to avoid having an eval() in each iteration of the loop
if((eBlock != oslEvalEBlock) || (nBlock != oslEvalNBlock))
{
oslEvalEBlock = eBlock;
oslEvalNBlock = nBlock;
var evalstr = 'oslBlockData = locatorData_'+eBlock+'_'+nBlock;
eval(evalstr);
}
for (var bcObj in oslBlockCacheList)
{
if(oslBlockCacheList[bcObj].blockName == arrayName)
{
oslBlockCacheList[bcObj].lastAccessed = Math.floor(new Date().getTime() / 1000);
}
}
var bdstr = '';
var preselect = false;
for(loop = 0;loop < oslBlockData.length; loop++)
{
var locatorElements = [];
// 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 30m 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
// the following block of code more or less replicates the string.split() method, but is around 2x faster in the Chrome
// JS engine...
if(navigator.userAgent.indexOf("Chrome") != -1)
{
bdstr = oslBlockData[loop];
while(bdstr.indexOf(':') != -1)
{
locatorElements.push(bdstr.substr(0,bdstr.indexOf(':')));
bdstr = bdstr.substr(bdstr.indexOf(':')+1);
}
locatorElements.push(bdstr);
}
else
{
locatorElements = oslBlockData[loop].split(':');
}
if((locatorElements[OSL_ELM.RoadName].length > 0) || (locatorElements[OSL_ELM.RoadNumber].length > 0))
{
var tolE;
var tolN;
if(mode == OSL_MODE.NameCheck)
{
// wider tolerance when doing a namecheck lookup, to reduce falsely flagging roads as being mis-named
tolE = 20;
tolN = 30;
}
else
{
// tighter tolerance when doing other lookups
tolE = 10;
tolN = 10;
}
var streetName = '';
if(locatorElements[OSL_ELM.RoadNumber].length > 0)
{
streetName += locatorElements[OSL_ELM.RoadNumber];
if(locatorElements[OSL_ELM.RoadName].length > 0)
{
streetName += ' - ';
}
}
streetName += oslWazeifyStreetName(locatorElements[OSL_ELM.RoadName], false);
var altName = '';
if(locatorElements[OSL_ELM.AltName] != '')
{
if(locatorElements[OSL_ELM.RoadNumber].length > 0)
{
altName += locatorElements[OSL_ELM.RoadNumber];
if(locatorElements[OSL_ELM.AltName].length > 0)
{
altName += ' - ';
}
}
altName += oslWazeifyStreetName(locatorElements[OSL_ELM.AltName], false);
}
if(mode == OSL_MODE.OpenNames)
{
// Name search from mouse position...
var bbPix = oslGetBBCornerPixels(parseFloat(locatorElements[OSL_ELM.BoundW]), parseFloat(locatorElements[OSL_ELM.BoundE]), parseFloat(locatorElements[OSL_ELM.BoundS]), parseFloat(locatorElements[OSL_ELM.BoundN]));
bbPix[0] -= tolE;
bbPix[1] += tolE;
bbPix[2] += tolN;
bbPix[3] -= tolN;
if((oslMousePixelpos.x >= bbPix[0])&&(oslMousePixelpos.x <= bbPix[1])&&(oslMousePixelpos.y <= bbPix[2])&&(oslMousePixelpos.y >= bbPix[3]))
{
var area = ((bbPix[1] - bbPix[0]) * (bbPix[2] - bbPix[3]));
var radioID = 'oslID_'+eBlock+'_'+nBlock+'_'+loop;
var altRadioID = null;
var oslLink = '<label style="display:inline;"><input type="radio" name="oslChoice" id="'+radioID+'"';
if((streetName == oslPrevStreetName)&&(preselect === false))
{
oslLink += 'checked="true"';
preselect = true;
}
oslLink += '/>';
oslLink += streetName+' [<i>'+locatorElements[OSL_ELM.AreaName]+'</i>]</label>';
if(altName != '')
{
altRadioID = 'alt-'+radioID;
oslLink += '<br> <label style="display:inline;"><input type="radio" name="oslChoice" id="'+altRadioID+'"';
if((altName == oslPrevStreetName)&&(preselect === false))
{
oslLink += 'checked="true"';
preselect = true;
}
oslLink += '/>';
oslLink += '<i>Alt name: '+altName+'</i></label>';
}
if(locatorElements[OSL_ELM.Form] == 'Collapsed Dual Carriageway')
{
locatorElements[OSL_ELM.Form] = 'Dual Carriageway';
}
oslLink += '<br> <i>'+oslRoadClassifications[locatorElements[OSL_ELM.Classification]] + ' - ';
oslLink += oslRoadFunctions[locatorElements[OSL_ELM.Function]] + ' - ' + oslFormsOfWay[locatorElements[OSL_ELM.Form]];
if(locatorElements[OSL_ELM.Structure] == OSL_ROADSTRUCTURES.Road_In_Tunnel)
{
oslLink += ' [Tunnel]';
}
else if(locatorElements[OSL_ELM.Structure] == OSL_ROADSTRUCTURES.Road_On_Bridge)
{
oslLink += ' [Bridge]';
}
if(locatorElements[OSL_ELM.IsPrimary] == 'Y')
{
oslLink += ' (PRN)';
}
if(locatorElements[OSL_ELM.IsTrunk] == 'Y')
{
oslLink += ' (TRN)';
}
oslLink += '</i><br>';
candidates[candidates.length++] = new oslMatch(oslLink,area,radioID,altRadioID);
}
}
else if(mode == OSL_MODE.NameCheck)
{
// NameCheck comparisons...
var bbW = parseFloat(locatorElements[OSL_ELM.BoundW]) - tolE;
var bbE = parseFloat(locatorElements[OSL_ELM.BoundE]) + tolE;
var bbS = parseFloat(locatorElements[OSL_ELM.BoundS]) - tolN;
var bbN = parseFloat(locatorElements[OSL_ELM.BoundN]) + tolN;
for(i=0;i<oslOSLNCSegments.length;i++)
{
if(oslOSLNCSegments[i].match === false)
{
if
(
((oslOSLNCSegments[i].lonA >= bbW) && (oslOSLNCSegments[i].lonA <= bbE)) &&
((oslOSLNCSegments[i].lonB >= bbW) && (oslOSLNCSegments[i].lonB <= bbE)) &&
((oslOSLNCSegments[i].latA >= bbS) && (oslOSLNCSegments[i].latA <= bbN)) &&
((oslOSLNCSegments[i].latB >= bbS) && (oslOSLNCSegments[i].latB <= bbN))
)
{
if((oslOSLNCSegments[i].streetname == streetName) || (oslOSLNCSegments[i].streetname == altName)) oslOSLNCSegments[i].match = true;
}
}
}
}
}
}
}
}
}
}
if(mode == OSL_MODE.OpenNames)
{
var newHTML = '<b>Matches at '+oslEastings+', '+oslNorthings+'</b>';
if(candidates.length > 0)
{
var btnStyle = "cursor:pointer;";
btnStyle += "font-size:14px;";
btnStyle += "border: thin outset black;";
btnStyle += "padding:2px 10px 2px 10px;";
btnStyle += "background: #ccccff;";
newHTML += '<div style="margin:10px;"><span id="oslSelect" style="'+btnStyle+'">';
if(oslAdvancedMode) newHTML += 'Apply to Properties';
else newHTML += 'Copy to Properties';
newHTML += '</span></div>';
if(candidates.length > 1) candidates.sort(oslSortCandidates);
for(loop=0;loop<candidates.length;loop++)
{
newHTML += candidates[loop].oslLink;
}
newHTML += '<br>City name:<br>';
newHTML += '<label style="display:inline;"><input type="radio" name="oslCityNameOpt" id="optUseExisting"/>Use existing segment name(s)</label><br>';
newHTML += '<label style="display:inline;"><input type="radio" name="oslCityNameOpt" id="optClearExisting" />Clear existing segment name(s)</label><br>';
newHTML += '<label style="display:inline;"><input type="radio" name="oslCityNameOpt" id="optUseNewManual" />Use new name:</label><br>';
newHTML += ' <input id="myCityName" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px; transition:none; focus:none; box-shadow:none" type="text"';
if(sessionStorage.cityNameRB == 'optUseNewManual') newHTML += 'value="'+sessionStorage.myCity+'"/><br>';
else newHTML += 'value=""/><br>';
newHTML += '<label style="display:inline;"><input type="radio" name="oslCityNameOpt" id="optUseExistingWME" />Use name from map:</label><br>';
newHTML += ' <select id="oslWMECityNames"></select><br>';
newHTML += '<label style="display:inline;"><input type="radio" name="oslCityNameOpt" id="optUseOS" />Use name from OS Gazetteer:</label><br>';
newHTML += ' <select id="oslOSCityNames"></select><br>';
newHTML += '<div id="oslCNInfo"></div><br>';
oslRoadNameMatches.innerHTML = newHTML;
oslGetNearbyCityNames();
var oWCN = document.getElementById('oslWMECityNames');
var nameList = [];
for(var cityObj in W.model.cities.objects)
{
if(W.model.cities.objects.hasOwnProperty(cityObj))
{
var cityname = W.model.cities.objects[cityObj].attributes.name;
if(cityname !== '')
{
var countyID = [];
countyID[0] = W.model.cities.objects[cityObj].attributes.stateID;
var countyName = W.model.states.getByIds(countyID)[0].name;
if(countyName !== '')
{
cityname += ', '+countyName;
}
nameList.push(cityname);
}
}
}
nameList.sort();
var matchedWMEName = false;
for(i=0; i<nameList.length; i++)
{
var listOpt = document.createElement('option');
listOpt.text = nameList[i];
oWCN.add(listOpt,null);
if(sessionStorage.cityNameRB == 'optUseExistingWME')
{
if(nameList[i] == sessionStorage.myCity)
{
oWCN.options.selectedIndex = i;
matchedWMEName = true;
}
}
}
if((!matchedWMEName) && (sessionStorage.cityNameRB == 'optUseExistingWME'))
{
oWCN.options.selectedIndex = 0;
}
document.getElementById('oslSelect').addEventListener("click", oslClick, true);
document.getElementById('oslWMECityNames').addEventListener("click", oslSelectWMEName, true);
document.getElementById('optUseExistingWME').addEventListener("click", oslSelectWMEName, true);
document.getElementById('oslOSCityNames').addEventListener("click", oslSelectOSName, true);
document.getElementById('optUseOS').addEventListener("click", oslSelectOSName, true);
document.getElementById('myCityName').addEventListener("keyup", oslCityNameKeyup, true);
document.getElementById('optUseNewManual').addEventListener("click", oslCityNameKeyup, true);
for(loop=0;loop<candidates.length;loop++)
{
document.getElementById(candidates[loop].oslRadioID).addEventListener("click", oslRadioClick, true);
if(candidates[loop].oslAltRadioID != null)
{
document.getElementById(candidates[loop].oslAltRadioID).addEventListener("click", oslRadioClick, true);
}
}
document.getElementById(sessionStorage.cityNameRB).checked = true;
oslKeepUIVisible();
}
else oslRoadNameMatches.innerHTML = newHTML;
}
}
if(mode == OSL_MODE.OpenRoads)
{
// OpenRoads check
var eastingsLeft = (Math.floor(oslVPLeft/oslLocatorBlockSize) - 1) * oslLocatorBlockSize;
var eastingsRight = (Math.ceil(oslVPRight/oslLocatorBlockSize) + 1) * oslLocatorBlockSize;
var northingsTop = (Math.ceil(oslVPTop/oslLocatorBlockSize) + 1) * oslLocatorBlockSize;
var northingsBottom = (Math.floor(oslVPBottom/oslLocatorBlockSize) - 1) * oslLocatorBlockSize;
var highlightMode = 0;
for(var eLoop = eastingsLeft; eLoop <= eastingsRight; eLoop += oslLocatorBlockSize)
{
for(var nLoop = northingsBottom; nLoop <= northingsTop; nLoop += oslLocatorBlockSize)
{
highlightMode = oslHighlightOpenRoads(eLoop,nLoop,highlightMode);
}
}
oslHighlightOpenRoads(0,0,2);
}
else return '?e='+oslEastings+'&n='+oslNorthings;
}
function oslRemoveDirSuffix(currentName, dirSuffix)
{
var dPos = currentName.indexOf(dirSuffix);
if(dPos != -1)
{
var dLength = dirSuffix.length;
currentName = currentName.substr(0,dPos) + currentName.substr(dPos+dLength);
}
return currentName;
}
function oslNameCheckTrigger()
{
oslOSLNameCheckTimer = 2;
}
function oslNameComparison()
{
for(;oslONC_E<=oslEBlock_max;)
{
for(;oslONC_N<=oslNBlock_max;)
{
oslToOSGrid(oslONC_E*oslLocatorBlockSize, oslONC_N*oslLocatorBlockSize, OSL_MODE.NameCheck);
if(oslLoadingMsg === true)
{
window.setTimeout(oslNameComparison,500);
return;
}
oslONC_N++;
}
oslONC_N = oslNBlock_min;
oslONC_E++;
}
for(var i=0;i<oslOSLNCSegments.length;i++)
{
if(oslOSLNCSegments[i].match === false)
{
var pline = oslOSLNCSegments[i].pline;
pline.setAttribute("stroke","#000000");
pline.setAttribute("stroke-opacity","0.5");
pline.setAttribute("stroke-width","9");
pline.setAttribute("stroke-dasharray","none");
}
}
}
function oslNCCandidateNew(pline, lonA, latA, lonB, latB, streetname)
{
this.pline = pline;
this.lonA = lonA;
this.latA = latA;
this.lonB = lonB;
this.latB = latB;
this.streetname = streetname;
this.match = false;
}
function oslNCStateChange()
{
if(document.getElementById('_cbNCEnabled').checked === false)
{
for(var segObj in W.model.segments.objects)
{
if(W.model.segments.objects.hasOwnProperty(segObj))
{
var seg = W.model.segments.objects[segObj];
var pline = document.getElementById(seg.geometry.id);
if(pline !== null)
{
pline.setAttribute("stroke-width","5");
pline.setAttribute("stroke","#dd7700");
pline.setAttribute("stroke-opacity","0.001");
pline.setAttribute("stroke-dasharray","none");
}
}
}
}
else
{
if(W.map.getZoom() >= 4) oslNameCheck();
}
}
function oslOpenRoadsStateChange(e)
{
oslMapIsStaticProcessing(true);
oslUpdateHighlightCBs(e.srcElement.id);
}
function oslNameCheck()
{
if((document.getElementById('_cbNCEnabled').checked === false) || (W.map.getZoom() < 4)) return;
var geoCenter=new OpenLayers.LonLat(W.map.getCenter().lon,W.map.getCenter().lat);
geoCenter.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
oslToOSGrid(geoCenter.lat, geoCenter.lon, OSL_MODE.Conversion);
if(oslLoadingMsg === true)
{
window.setTimeout(oslNameCheck,500);
return;
}
oslEBlock_min = 99999;
oslEBlock_max = -1;
oslNBlock_min = 99999;
oslNBlock_max = -1;
var mapExtents = W.map.getExtent();
var ignoreSegment;
oslOSLNCSegments = [];
for(var segObj in W.model.segments.objects)
{
if(W.model.segments.objects.hasOwnProperty(segObj))
{
ignoreSegment = false;
var seg = W.model.segments.objects[segObj];
var segRT = seg.attributes.roadType;
if
(
(seg.geometry.bounds.left > mapExtents.right) ||
(seg.geometry.bounds.right < mapExtents.left) ||
(seg.geometry.bounds.top < mapExtents.bottom) ||
(seg.geometry.bounds.bottom > mapExtents.top)
)
{
// ignore segment as it's not visible...
ignoreSegment = true;
}
if
(
(segRT < 1) ||
((segRT > 3) && (segRT < 6)) ||
((segRT > 8) && (segRT < 17)) ||
((segRT > 17) && (segRT < 20)) ||
(segRT > 21)
)
{
// ignore segment as it's non-driveable...
ignoreSegment = true;
}
if(ignoreSegment === false)
{
var streetObj = W.model.streets.objects[seg.attributes.primaryStreetID];
if(streetObj !== undefined)
{
var currentName = streetObj.name;
var gid = seg.geometry.id;
var pline = document.getElementById(gid);
if((currentName !== null) && (pline !== null))
{
currentName = oslRemoveDirSuffix(currentName,' (N)');
currentName = oslRemoveDirSuffix(currentName,' (S)');
currentName = oslRemoveDirSuffix(currentName,' (E)');
currentName = oslRemoveDirSuffix(currentName,' (W)');
currentName = oslRemoveDirSuffix(currentName,' (CW)');
currentName = oslRemoveDirSuffix(currentName,' (ACW)');
var endPointA = new OpenLayers.LonLat(seg.geometry.components[0].x,seg.geometry.components[0].y);
endPointA.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
oslToOSGrid(endPointA.lat, endPointA.lon, OSL_MODE.Conversion);
var eBlock = Math.floor(oslEastings/oslLocatorBlockSize);
var nBlock = Math.floor(oslNorthings/oslLocatorBlockSize);
if(eBlock < oslEBlock_min) oslEBlock_min = eBlock;
if(eBlock > oslEBlock_max) oslEBlock_max = eBlock;
if(nBlock < oslNBlock_min) oslNBlock_min = nBlock;
if(nBlock > oslNBlock_max) oslNBlock_max = nBlock;
var endPointB = new OpenLayers.LonLat(seg.geometry.components[seg.geometry.components.length-1].x,seg.geometry.components[seg.geometry.components.length-1].y);
endPointB.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
oslToOSGrid(endPointB.lat, endPointB.lon, OSL_MODE.Conversion);
oslOSLNCSegments.push(new oslNCCandidateNew(pline, endPointA.lon, endPointA.lat, endPointB.lon, endPointB.lat, currentName));
eBlock = Math.floor(oslEastings/oslLocatorBlockSize);
nBlock = Math.floor(oslNorthings/oslLocatorBlockSize);
if(eBlock < oslEBlock_min) oslEBlock_min = eBlock;
if(eBlock > oslEBlock_max) oslEBlock_max = eBlock;
if(nBlock < oslNBlock_min) oslNBlock_min = nBlock;
if(nBlock > oslNBlock_max) oslNBlock_max = nBlock;
}
}
}
}
}
if(oslOSLNCSegments.length > 0)
{
oslONC_E = oslEBlock_min;
oslONC_N = oslNBlock_min;
oslNameComparison();
}
}
function oslTenthSecondTick()
{
if(W.app.modeController.mode.mteModeState !== undefined)
{
if(!oslMTEMode)
{
oslAddLog('MTE mode, sleeping until normal service is resumed...');
oslWindowMinimise();
}
oslMTEMode = true;
return;
}
oslMTEMode = false;
if(oslMOAdded === false)
{
if(document.getElementById('edit-panel') !== null)
{
oslAddLog('edit-panel mutation observer added...');
var editPanelMO = new MutationObserver(oslEditPanelCheck);
editPanelMO.observe(document.getElementById('edit-panel'),{childList:true,subtree:true});
oslMOAdded = true;
}
}
var hideUI = Boolean
(
(document.getElementsByClassName('menu')[0].className.indexOf('not-visible') === -1) &&
(document.getElementsByClassName('menu')[0].className.indexOf('hide') === -1)
);
hideUI = Boolean(hideUI || (document.getElementsByClassName('toolbar-group open').length > 0));
if(hideUI === false)
{
oslWindow.style.zIndex = 2000;
}
else
{
oslWindow.style.zIndex = -2000;
}
if(!oslAdvancedMode) oslEnableAdvancedOptions();
var oslSelectedItems = [];
if(W.selectionManager.selectedItems === undefined)
{
oslSelectedItems = W.selectionManager._selectedFeatures;
}
else
{
oslSelectedItems = W.selectionManager.selectedItems;
}
if(oslSelectedItems.length == 1)
{
if(oslPrevSelected === null) oslDoOSLUpdate = true;
else if(oslSelectedItems[0].model.attributes.id != oslPrevSelected) oslDoOSLUpdate = true;
oslPrevSelected = oslSelectedItems[0].model.attributes.id;
}
else
{
oslPrevSelected = null;
}
if(document.getElementById('oslSelect') !== null)
{
var editDisabled = ((document.getElementsByClassName('full-address disabled').length > 0) || (document.getElementsByClassName('full-address-container').length === 0));
if(editDisabled === true)
{
document.getElementById('oslSelect').style.background = "rgb(160, 160, 160)";
}
else
{
document.getElementById('oslSelect').style.background = "rgb(204, 204, 255)";
}
document.getElementById('oslSelect').disabled = editDisabled;
}
if(oslOSLNameCheckTimer > 0)
{
if(--oslOSLNameCheckTimer === 0) oslNameCheck();
}
var bcIdx;
var timeNow;
if(--oslBlockCacheTestTimer === 0)
{
oslBlockCacheTestTimer = (oslCacheDecayPeriod * 10);
timeNow = Math.floor(new Date().getTime() / 1000);
for(bcIdx = oslBlockCacheList.length-1; bcIdx >= 0; bcIdx--)
{
if((timeNow - oslBlockCacheList[bcIdx].lastAccessed) > oslCacheDecayPeriod)
{
eval('delete '+oslBlockCacheList[bcIdx].blockName);
oslBlockCacheList.splice(bcIdx,1);
}
}
}
if((oslDoOSLUpdate === true) && (oslMousepos !== null))
{
// update the OS Locator matches
oslToOSGrid(oslMousepos.lat,oslMousepos.lon,OSL_MODE.OpenNames);
oslDoOSLUpdate = oslLoadingMsg;
if(!oslDoOSLUpdate) oslRadioClick();
}
if(oslRefreshAutoTrack)
{
// refresh any of the site tabs/windows we've checked for auto-tracking
if(oslInUK === true)
{
if(document.getElementById('_cbAutoTrackOSOD').checked == 1) window.open(oslOSOD_url,'_osopendata');
if(document.getElementById('_cbAutoTrackRWO').checked == 1) window.open(oslRWO_url,'_roadworksorg');
if(oslInWiltshire === true)
{
if(document.getElementById('_cbAutoTrackSWG').checked == 1) window.open(oslSWG_url,'_wiltshire');
}
if(oslInLondon === true)
{
if(document.getElementById('_cbAutoTrackLRR').checked == 1) window.open(oslLRR_url,'_londonregister');
}
}
oslRefreshAutoTrack = false;
}
if(oslBlocksToTest.length > 0)
{
for(var i=0; i<oslBlocksToTest.length; i++)
{
var oslEvalString = 'typeof '+oslBlocksToTest[i];
if(eval(oslEvalString) != 'undefined')
{
oslBlocksToTest.splice(i, 1);
}
}
if(oslBlocksToTest.length === 0)
{
oslMapIsStaticProcessing(true);
}
}
}
function oslEnableAdvancedOptions()
{
if (oslAdvancedMode) return;
if(W.loginManager === null) return;
if(W.loginManager.isLoggedIn() === true)
{
var thisUser = W.loginManager.user;
if (thisUser !== null && thisUser.getRank() >= 2)
{
oslAdvancedMode = true;
oslAddLog('advanced mode enabled');
}
}
}
function oslUpdateLiveMapLink()
{
var lmLink = document.getElementById('livemap-link');
if(lmLink === null)
{
window.setTimeout(oslUpdateLiveMapLink,100);
return;
}
// translate the zoom level between WME and live map.
var livemap_zoom = parseInt(sessionStorage.zoom)+12;
if (livemap_zoom > 17) livemap_zoom = 17;
var livemap_url = 'https://www.waze.com/livemap/?';
livemap_url += 'lon='+sessionStorage.lon;
livemap_url += '&lat='+sessionStorage.lat;
livemap_url += '&zoom='+livemap_zoom;
// Modify existing livemap link to reference current position in WME
lmLink.href = livemap_url;
lmLink.target = '_blank';
}
function oslOSGridRefToPixel(osEast, osNorth)
{
var lonlat = new OpenLayers.LonLat();
lonlat.lon = parseFloat(osEast);
lonlat.lat = parseFloat(osNorth);
lonlat.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
return W.map.getPixelFromLonLat(lonlat);
}
function oslBoundsCheck(pix1, pix2, width, height)
{
var xmin = Math.min(pix1.x,pix2.x);
var xmax = Math.max(pix1.x,pix2.x);
var ymin = Math.min(pix1.y,pix2.y);
var ymax = Math.max(pix1.y,pix2.y);
var retval =
(
(xmin <= width) &&
(xmax >= 0) &&
(ymin <= height) &&
(ymax >= 0)
);
return retval;
}
function oslHighlightOpenRoads(oslEastings, oslNorthings, mode)
{
oslBlocksToLoad = [];
if((mode === 0) || (mode == 1))
{
var arrayName = 'locatorData_'+oslEastings+'_'+oslNorthings;
// check to see if there's a corresponding array loaded already
var oslEvalString = 'typeof '+arrayName;
if(eval(oslEvalString) == "undefined")
{
// create a blank placeholder which will get replaced by the actual data if the array is present on the server...
eval(arrayName+' = []');
oslBlocksToLoad.push(oslBlockPath+Math.floor(oslEastings / 100000)+'/'+Math.floor(oslNorthings / 100000)+'/'+arrayName+'.user.js');
oslBlocksToLoad.push(arrayName);
oslBlocksToTest.push(arrayName);
oslLoadBlocks();
}
var divWidth = document.getElementById('WazeMap').offsetWidth;
var divHeight = document.getElementById('WazeMap').offsetHeight;
var displayPoints = false;
if(mode === 0)
{
// initialise SVG container
oslSegGeoDivInnerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="'+divWidth+'px" height="'+divHeight+'px" version="1.1">';
}
// create local copy of array to avoid an eval() in each iteration of the loop
if(eval('typeof '+arrayName) == "undefined") return;
var oslOpenRoadsData;
eval('oslOpenRoadsData = '+arrayName);
// calculate an appropriate stroke width for the current zoom level
var strokeWidth = W.map.getZoom();
if(strokeWidth < 2) strokeWidth = 2;
if(strokeWidth > 9) strokeWidth = 9;
var renderByFunction = [];
renderByFunction.push(true); // Undefined roads always get rendered when the OpenRoads layer is enabled
renderByFunction.push(document.getElementById('_cbSegGeoMotorway').checked);
renderByFunction.push(document.getElementById('_cbSegGeoARoad').checked);
renderByFunction.push(document.getElementById('_cbSegGeoBRoad').checked);
renderByFunction.push(document.getElementById('_cbSegGeoMinor').checked);
renderByFunction.push(document.getElementById('_cbSegGeoLocal').checked);
if(oslAdvancedMode == true)
{
renderByFunction.push(document.getElementById('_cbSegGeoLocalAccess').checked);
renderByFunction.push(document.getElementById('_cbSegGeoRestricted').checked);
renderByFunction.push(document.getElementById('_cbSegGeoSecondary').checked);
}
else
{
renderByFunction.push(false);
renderByFunction.push(false);
renderByFunction.push(false);
}
var useFullGeo = document.getElementById('_cbOpenRoadsUseGeo').checked;
var enhancePolylines = document.getElementById('_cbOpenRoadsEnhanceGeoVis').checked;
var pix1;
var pix2;
var nameColour;
for(var roadIdx = 0; roadIdx < oslOpenRoadsData.length; roadIdx++)
{
var roadEntry = oslOpenRoadsData[roadIdx];
var elements = roadEntry.split(':');
var roadFunction = parseInt(elements[OSL_ELM.Function]);
if ((elements[OSL_ELM.RoadName] == '') && (elements[OSL_ELM.RoadNumber] == ''))
{
nameColour = 'cyan';
}
else
{
nameColour = 'magenta';
}
if(renderByFunction[roadFunction] == true)
{
pix1 = oslOSGridRefToPixel(elements[OSL_ELM.BoundW], elements[OSL_ELM.BoundS]);
pix2 = oslOSGridRefToPixel(elements[OSL_ELM.BoundE], elements[OSL_ELM.BoundN]);
if(oslBoundsCheck(pix1, pix2, divWidth, divHeight) == true)
{
if(useFullGeo == true)
{
var geoPairs = elements[OSL_ELM.Geometry].split(' ');
var geoPoints = geoPairs[0].split(' ');
var isTunnel = (elements[OSL_ELM.Structure] == OSL_ROADSTRUCTURES.Road_In_Tunnel);
pix1 = oslOSGridRefToPixel(geoPoints[0], geoPoints[1]);
var pline = '';
for(var pts=1; pts < geoPairs.length; pts++)
{
geoPoints = geoPairs[pts].split(' ');
pix2 = oslOSGridRefToPixel(geoPoints[0],geoPoints[1]);
if(oslBoundsCheck(pix1, pix2, divWidth, divHeight) == true)
{
if(displayPoints === false)
{
pline += '<polyline points="';
displayPoints = true;
}
pline += pix1.x+','+pix1.y+' '+pix2.x+','+pix2.y+' ';
}
pix1 = pix2;
}
if(displayPoints === true)
{
var strokeColour = oslStrokeColoursByFunction[roadFunction];
var strokeArray = '';
if(isTunnel == true)
{
strokeArray = 'stroke-dasharray:10,10;';
}
if(enhancePolylines == true)
{
oslSegGeoDivInnerHTML += pline + '" style="stroke:';
oslSegGeoDivInnerHTML += nameColour;
oslSegGeoDivInnerHTML += ';'+strokeArray+'stroke-width:'+(strokeWidth+11)+';stroke-linecap:round;fill:none"/>';
}
oslSegGeoDivInnerHTML += pline + '" style="stroke:black;'+strokeArray+'stroke-width:'+(strokeWidth+2)+';stroke-linecap:round;fill:none"/>';
oslSegGeoDivInnerHTML += pline + '" style="stroke:'+strokeColour+';'+strokeArray+'stroke-width:'+strokeWidth+';stroke-linecap:round;fill:none"/>';
displayPoints = false;
}
}
else
{
const minDim = 20;
var bWidth = Math.abs(pix2.x-pix1.x);
if(bWidth < minDim) bWidth = minDim;
var bHeight = Math.abs(pix2.y-pix1.y);
if(bHeight < minDim) bHeight = minDim;
oslSegGeoDivInnerHTML += '<rect x="'+pix1.x+'" y="'+pix2.y+'" width="'+bWidth+'" height="'+bHeight+'" style="fill:';
oslSegGeoDivInnerHTML += nameColour;
oslSegGeoDivInnerHTML += ';stroke:black;stroke-width:4;fill-opacity:0.25;stroke-opacity:0.25"/>';
}
}
}
}
}
else if(mode == 2)
{
// finalise SVG
oslSegGeoDivInnerHTML += '</svg>';
oslSegGeoDiv.innerHTML = oslSegGeoDivInnerHTML;
}
else if(mode == 3)
{
// erase SVG
oslSegGeoDiv.innerHTML = '';
}
return 1;
}
function oslRepositionOverlays(doBoth)
{
var divTop = (0 - parseInt(oslWazeMapElement.style.top.replace('px','')));
var divLeft = (0 - parseInt(oslWazeMapElement.style.left.replace('px','')));
oslBBDiv.style.top = divTop + 'px';
oslBBDiv.style.left = divLeft + 'px';
if(doBoth == true)
{
oslSegGeoDiv.style.top = divTop + 'px';
oslSegGeoDiv.style.left = divLeft + 'px';
}
}
function oslGetCorrectedLonLatFromPixelPos(px, py, toolbarCompensation)
{
if((toolbarCompensation) && (oslOffsetToolbar)) py -= document.getElementById('toolbar').clientHeight;
py -= document.getElementById('topbar-container').clientHeight;
var pixelPos = new OpenLayers.Pixel(px, py);
return W.map.getLonLatFromPixel(pixelPos);
}
function oslGetOffsetMapCentre()
{
// get lon/lat of viewport centrepoint for modifying the livemap link and for passing to the external mapping sites.
// shift the longitude pixel offset by half the width of the WME sidebar to account for the lateral offset that would
// otherwise occur when switching between the WME tab and the other map tabs - all of those use a full-width map view,
// so their map centre is further to the left within the browser window than the WME centrepoint...
var mapVPX = (W.map.olMap.getViewport().clientWidth / 2) - (document.getElementById('sidebar').clientWidth / 2);
var mapVPY = W.map.olMap.getViewport().clientHeight / 2;
return oslGetCorrectedLonLatFromPixelPos(mapVPX, mapVPY, false);
}
function oslMouseMoveAndUp(e)
{
if(oslUserPrefs.ui.state == 'minimised') return;
var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top;
oslMousePixelpos = new OpenLayers.Pixel(mouseX, mouseY);
oslMousepos = oslGetCorrectedLonLatFromPixelPos(mouseX, mouseY, true).transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
if((oslMousepos != sessionStorage.oslMousepos) || (oslLoadingMsg && (eval(oslEvalString) != "undefined")))
{
oslLoadingMsg = false;
sessionStorage.oslMousepos = oslMousepos;
oslDoOSLUpdate = false;
// update the OSL results if there are no selected segments, but there is a highlighted segment
// which we haven't already done an update for
oslSegmentHighlighted = false;
var noneSelected = false;
if(W.selectionManager.selectedItems !== undefined)
{
noneSelected = (W.selectionManager.selectedItems.length === 0);
}
else
{
noneSelected = (W.selectionManager._selectedFeatures.length === 0);
}
if(noneSelected === true)
{
for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++)
{
if(W.map.segmentLayer.features[slIdx].renderIntent == 'highlight')
{
if(slIdx != oslPrevHighlighted)
{
oslPrevHighlighted = slIdx;
}
oslDoOSLUpdate = true;
oslSegmentHighlighted = true;
}
}
}
}
var geoCenter = oslGetOffsetMapCentre();
var geoCenterTransform = oslGetOffsetMapCentre().transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
var lat = geoCenterTransform.lat;
var lon = geoCenterTransform.lon;
var zoom = W.map.getZoom();
// compare the new parameters against the persistent copies, and update the external links
// 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 timeout
// then it'd spend a lot of its time giving the appearance of being clickable but without
// actually doing anything...
if((zoom != parseInt(sessionStorage.zoom))||(lat != parseFloat(sessionStorage.lat))||(lon != parseFloat(sessionStorage.lon)))
{
var country = null;
if((W.model.countries.top === undefined)||(W.model.countries.top === null))
{
if(W.model.countries.additionalInfo !== null)
{
country = W.model.countries.additionalInfo[0].name;
}
}
else
{
country = W.model.countries.top.name;
}
if(country == "United Kingdom")
{
if (oslInUK === false)
{
oslAddLog('location is the UK, enabling full UI...');
oslInUK = true;
document.getElementById('oslOSLDiv').style.display = "block";
document.getElementById('oslNCDiv').style.display = "block";
document.getElementById('oslSegGeoUIDiv').style.display = "block";
document.getElementById('_extlinksUK').style.display = "block";
}
}
else
{
// ...somewhere not yet supported, or WME isn't telling us just yet...
oslAddLog('location not recognised, disabling UK-specific parts of UI...');
oslInUK = false;
oslInLondon = false;
document.getElementById('oslOSLDiv').style.display = "none";
document.getElementById('oslNCDiv').style.display = "none";
document.getElementById('oslSegGeoUIDiv').style.display = "none";
document.getElementById('_extlinksUK').style.display = "none";
}
if(oslInUK === true)
{
// we're in the UK, so test to see if we're within the approximate Greater London bounding box
if((lon >= -0.55) && (lon <= 0.30) && (lat >= 51.285) && (lat <= 51.695))
{
oslInLondon = true;
document.getElementById('lrrCtrls').style.display='inline';
}
else
{
oslInLondon = false;
document.getElementById('lrrCtrls').style.display='none';
}
// also see if we're more or less within Wiltshire
if((lon >= -2.33) && (lon <= -1.50) && (lat >= 50.94) && (lat <= 51.71))
{
oslInWiltshire = true;
document.getElementById('swgCtrls').style.display='inline';
}
else
{
oslInWiltshire = false;
document.getElementById('swgCtrls').style.display='none';
}
}
if(zoom != sessionStorage.zoom)
{
if(zoom < 4) document.getElementById('_cbNCEnabled').disabled = true;
else document.getElementById('_cbNCEnabled').disabled = false;
}
// update the persistent vars with the new position
sessionStorage.zoom = zoom;
sessionStorage.lat = lat;
sessionStorage.lon = lon;
if(oslInUK === true)
{
// calculate the OS eastings/northings for the current WME centrepoint - this is required by the OpenData and London Roadworks sites...
var osCoords = oslToOSGrid(lat,lon,OSL_MODE.Conversion);
// translate the zoom level between WME and OpenData - the match here isn't quite so good...
var odzoom = zoom + 8;
if(odzoom < 6) odzoom = 6;
if(odzoom > 12) odzoom = 12;
// generate the OpenData URL
oslOSOD_url = 'https://openspacewmb.ordnancesurvey.co.uk/osmapapi/mapbuilder?'+osCoords+'&z='+odzoom;
// generate the one.network URL - no zoom translation required here
oslRWO_url = 'https://one.network?lat='+lat+'&lon='+lon+'&z='+zoom+'&showlinks=true';
// generate the Wiltshire streetworks URL - use mapCenter() as is, but translate the zoom level
var swgzoom = zoom + 2;
if(swgzoom > 11) swgzoom = 11;
oslSWG_url = 'http://streetworks.wiltshire.gov.uk/map.aspx?lat='+geoCenter.lat+'&lon='+geoCenter.lon+'&z='+swgzoom;
// translate the zoom level between WME and London Roadworks Register - this gives reasonable results up to WME zoom of 5, beyond
// which the LRR site can't zoom in any further...
var lrrzoom = zoom;
if(lrrzoom > 5) lrrzoom = 5;
// generate the roadworks register URL
oslLRR_url = 'http://public.londonworks.gov.uk/roadworks/home'+osCoords+'&z='+lrrzoom;
}
// wait to update the livemap link, as WME now does its own update after this point so any changes we make here
// end up being wiped out...
window.setTimeout(oslUpdateLiveMapLink,100);
// update the link URLs
if(oslInUK === true)
{
document.getElementById("_linkOSOD").href = oslOSOD_url;
document.getElementById("_linkRWO").href = oslRWO_url;
document.getElementById("_linkSWG").href = oslSWG_url;
document.getElementById("_linkLRR").href = oslLRR_url;
}
document.getElementById('_linkPermalink').href = document.getElementsByClassName('WazeControlPermalink')[0].getElementsByTagName('a')[0].href;
// refreshing the tabs within the event handler causes Chrome to switch focus to the tabs, so we
// simply set the flag here and let the refresh occur within the 100ms tick handler as before
oslRefreshAutoTrack = true;
oslRadioClick();
}
oslRepositionOverlays(false);
if((e.type == "mouseup") || (e.type == "zoomend"))
{
oslMapIsStaticProcessing(false);
}
}
var oslWaitingForMapToStopMoving = false;
function oslMapIsStaticProcessing(forceUpdate)
{
if(oslUserPrefs.ui.state == 'maximised')
{
var tCenter = W.map.getCenter();
var tZoom = W.map.getZoom();
if
(
(oslRORCenter == null) || (tCenter.lat != oslRORCenter.lat) || (tCenter.lon != oslRORCenter.lon) ||
(oslRORZoom == null) || (tZoom != oslRORZoom)
)
{
oslWaitingForMapToStopMoving = true;
oslRORCenter = tCenter;
oslRORZoom = tZoom;
window.setTimeout(oslMapIsStaticProcessing, 250);
return;
}
if((oslWaitingForMapToStopMoving == false) && (forceUpdate == false))
{
return;
}
oslWaitingForMapToStopMoving = false;
var geoCenter=new OpenLayers.LonLat(W.map.getCenter().lon,W.map.getCenter().lat);
geoCenter.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
oslToOSGrid(geoCenter.lat, geoCenter.lon, OSL_MODE.Conversion);
oslNameCheck();
if(oslInUK === true)
{
// recalculate the map viewport extents in terms of oslEastings/oslNorthings
var vpHalfWidth = (W.map.getExtent().right-W.map.getExtent().left) / (2 * 1.61);
var vpHalfHeight = (W.map.getExtent().top-W.map.getExtent().bottom) / (2 * 1.61);
oslVPLeft = oslEastings - vpHalfWidth;
oslVPRight = oslEastings + vpHalfWidth;
oslVPBottom = oslNorthings - vpHalfHeight;
oslVPTop = oslNorthings + vpHalfHeight;
if(document.getElementById('_cbOpenRoadsEnabled').checked === true)
{
oslToOSGrid(oslEastings,oslNorthings,OSL_MODE.OpenRoads);
}
else
{
oslHighlightOpenRoads(0,0,3);
}
}
else
{
oslHighlightOpenRoads(0,0,3);
}
oslRepositionOverlays(true);
}
}
function oslTestPointerOutsideMap(mX, mY)
{
var mapElm = document.getElementById("map");
if(mapElm === undefined) return false;
var bLeft = mapElm.parentElement.offsetLeft;
var bRight = (bLeft + mapElm.offsetWidth);
var bTop = (mapElm.parentElement.offsetTop + document.getElementById("topbar-container").clientHeight);
var bBottom = (mapElm.parentElement.offsetTop + mapElm.offsetHeight + document.getElementById("topbar-container").clientHeight - document.getElementsByClassName("WazeMapFooter")[0].clientHeight);
if((mX < bLeft) || (mX > bRight) || (mY < bTop) || (mY > bBottom)) return true;
else return false;
}
function oslMouseOut(e)
{
if(oslTestPointerOutsideMap(e.clientX, e.clientY))
{
// when the mouse pointer leaves the map area, WME treats it similarly to a mouseup
// event without generating an actual mouseup event, so we need to do the same...
oslMapIsStaticProcessing(false);
}
}
function oslCancelEvent(e)
{
e = e ? e : window.event;
if(e.stopPropagation)
e.stopPropagation();
if(e.preventDefault)
e.preventDefault();
e.cancelBubble = true;
e.cancel = true;
e.returnValue = false;
return false;
}
function oslOSLDivMouseDown(e)
{
oslPrevMouseX = e.pageX;
oslPrevMouseY = e.pageY;
oslDivDragging = true;
oslDragBar.style.cursor = 'move';
document.body.addEventListener('mousemove', oslOSLDivMouseMove, false);
document.body.addEventListener('mouseup', oslOSLDivMouseUp, false);
// lock the UI width during a drag so we can correctly detect for falling off the window edge
oslWindow.style.width = oslWindow.getBoundingClientRect().width+'px';
return true;
}
function oslOSLDivMouseUp()
{
if(oslDivDragging)
{
oslDivDragging = false;
oslUserPrefs.ui.x = oslOSLDivLeft;
oslUserPrefs.ui.y = oslOSLDivTop;
oslWriteUserPrefs();
// unlock the UI width again so we can expand/contract as required based on other script behaviour
oslWindow.style.width = "auto";
}
oslDragBar.style.cursor = 'auto';
document.body.removeEventListener('mousemove', oslOSLDivMouseMove, false);
document.body.removeEventListener('mouseup', oslOSLDivMouseUp, false);
return true;
}
function oslOSLDivMouseMove(e)
{
var vpHeight = window.innerHeight;
var vpWidth = window.innerWidth;
oslOSLDivTop = parseInt(oslOSLDivTop) + parseInt((e.pageY - oslPrevMouseY));
oslOSLDivLeft = parseInt(oslOSLDivLeft) + parseInt((e.pageX - oslPrevMouseX));
oslPrevMouseX = e.pageX;
oslPrevMouseY = e.pageY;
if(oslOSLDivTop < 0) oslOSLDivTop = 0;
if(oslOSLDivTop + 16 >= vpHeight) oslOSLDivTop = vpHeight-16;
if(oslOSLDivLeft < 0) oslOSLDivLeft = 0;
if(oslOSLDivLeft + 32 >= vpWidth) oslOSLDivLeft = vpWidth-32;
oslWindow.style.top = oslOSLDivTop+'px';
oslWindow.style.left = oslOSLDivLeft+'px';
return oslCancelEvent(e);
}
function oslKeepUIVisible()
{
var vpHeight = window.innerHeight;
var vpWidth = window.innerWidth;
var topbarHeight = document.getElementById('toolbar').offsetHeight;
var maxUIHeight = (vpHeight - topbarHeight);
// Restore auto-sizing so we can see the effect of whatever UI change caused us to get here...
oslWindow.style.height = "auto";
oslWindow.style.overflow = "hidden";
// If the bottom edge of the ui would fall off the bottom edge of the map viewport, nudge
// the UI up as far as required to keep the whole UI visible. If this would however require
// the top edge of the UI to be pushed off the top of the map viewport, constrain the UI
// height to the viewport height and enable a scrollbar...
if(oslWindow.getBoundingClientRect().bottom >= maxUIHeight)
{
var newTop = (vpHeight-oslWindow.getBoundingClientRect().height);
if(newTop < topbarHeight)
{
newTop = topbarHeight;
oslWindow.style.height = maxUIHeight+'px';
oslWindow.style.overflow = "scroll";
}
oslOSLDivTop = newTop;
oslUserPrefs.ui.y = oslOSLDivTop;
oslWindow.style.top = oslOSLDivTop+'px';
}
}
function oslMinimiseDiv(divID)
{
var tDiv = document.getElementById(divID);
if(tDiv != null)
{
tDiv.style.height = '0px';
tDiv.style.padding = '0px';
tDiv.style.overflow = 'hidden';
}
}
function oslMaximiseDiv(divID)
{
var tDiv = document.getElementById(divID);
if(tDiv != null)
{
tDiv.style.height = 'auto';
tDiv.style.padding = '2px';
tDiv.style.overflow = 'auto';
}
}
function oslWindowMaximise()
{
var tHTML = '';
tHTML += '<span style="float:left"><a href="'+oslUpdateURL+'" target="_blank"><b>WMEOpenData</a> v'+oslVersion+'</b></span>';
tHTML += '<span id="_minimax" style="float:right"><i class="fa fa-chevron-circle-up"></i></span>';
tHTML += '<br>';
oslDragBar.innerHTML = tHTML;
document.getElementById('_minimax').addEventListener('click', oslWindowMinimise, false);
oslMaximiseDiv('oslOSLDiv');
oslMaximiseDiv('oslNCDiv');
oslMaximiseDiv('oslSegGeoUIDiv');
oslMaximiseDiv('oslMLCDiv');
oslKeepUIVisible();
oslUserPrefs.ui.state = 'maximised';
oslWriteUserPrefs();
oslRepositionOverlays(true);
oslMapIsStaticProcessing(true);
}
function oslWindowMinimise()
{
var tHTML = '';
tHTML += '<span style="float:left"><b>WMEOpenData v'+oslVersion+'</b></span>';
tHTML += '<span id="_minimax" style="float:right"><i class="fa fa-chevron-circle-down"></i></span>';
tHTML += '<br>';
oslDragBar.innerHTML = tHTML;
document.getElementById('_minimax').addEventListener('click', oslWindowMaximise, false);
oslMinimiseDiv('oslOSLDiv');
oslMinimiseDiv('oslNCDiv');
oslMinimiseDiv('oslSegGeoUIDiv');
oslMinimiseDiv('oslMLCDiv');
oslKeepUIVisible();
oslBBDiv.innerHTML = '';
oslSegGeoDiv.innerHTML = '';
oslUserPrefs.ui.state = 'minimised';
oslWriteUserPrefs();
}
function oslSubDivSetState(divID, state)
{
var tSubDiv = document.getElementById(divID).children[1];
var tToggle = document.getElementById(divID).children[0].children[1].children[0];
if(state == 'minimised')
{
tSubDiv.style.height = "0px";
tSubDiv.style.padding = "0px";
tSubDiv.style.overflow = "hidden";
tToggle.className = "fa fa-chevron-circle-down";
}
else
{
tSubDiv.style.height = "auto";
tSubDiv.style.width = "100%";
tSubDiv.style.padding = "2px";
tSubDiv.style.overflow = "auto";
tToggle.className = "fa fa-chevron-circle-up";
}
}
function oslUIMinMax(e)
{
var headerDivID = e.srcElement.parentElement.parentElement.parentElement.id;
var tSubDiv = document.getElementById(headerDivID).children[1];
if(tSubDiv != null)
{
var newState;
if(tSubDiv.style.height == "auto")
{
newState = 'minimised';
}
else
{
newState = 'maximised';
}
oslSubDivSetState(headerDivID, newState);
oslUpdateMinMax(headerDivID, newState);
}
oslKeepUIVisible();
}
function oslNestedTypeof(nestedObj)
{
var objFields = nestedObj.split(".");
var retval = "unknown";
var fieldIdx = 0;
var level = unsafeWindow;
while((retval != "undefined") && (fieldIdx < objFields.length))
{
level = level[objFields[fieldIdx++]];
retval = typeof(level);
}
return retval;
}
function oslEditPanelCheck()
{
if(document.getElementById('edit-panel').getElementsByClassName('map-comment-feature-editor').length)
{
document.body.style.overflow = "auto";
}
else
{
document.body.style.overflow = "hidden";
}
}
function oslSetupBBDiv()
{
// add a new div to the map viewport, to hold the bounding box SVG
oslAddLog('create bounding box DIV');
oslBBDiv = document.createElement('div');
oslBBDiv.id = "oslBBDiv";
oslBBDiv.style.position = 'absolute';
oslBBDiv.style.top = (0-parseInt(oslWazeMapElement.style.top.replace('px',''))) + 'px';
oslBBDiv.style.left = (0-parseInt(oslWazeMapElement.style.left.replace('px',''))) + 'px';
oslBBDiv.style.overflow = 'hidden';
oslBBDiv.style.width = window.innerWidth;
oslBBDiv.style.height = window.innerHeight;
oslWazeMapElement.appendChild(oslBBDiv);
}
function oslSetupORDiv()
{
// add a new div to the map viewport, to hold the OpenRoads SVG
oslAddLog('create OpenRoads DIV');
oslSegGeoDiv = document.createElement('div');
oslSegGeoDiv.id = "oslSegGeoDiv";
oslSegGeoDiv.style.position = 'absolute';
oslSegGeoDiv.style.top = (0-parseInt(oslWazeMapElement.style.top.replace('px',''))) + 'px';
oslSegGeoDiv.style.left = (0-parseInt(oslWazeMapElement.style.left.replace('px',''))) + 'px';
oslSegGeoDiv.style.overflow = 'hidden';
oslSegGeoDiv.style.width = window.innerWidth;
oslSegGeoDiv.style.height = window.innerHeight;
oslWazeMapElement.appendChild(oslSegGeoDiv);
}
function oslGenerateOpenRoadsCBHTML(isStd, ID, label, indentLevel)
{
var tHTML = '';
var indent = 'padding-left: '+(indentLevel * 0.5)+'em;';
tHTML += '<label style="display: inline; '+indent+'">';
tHTML += '<input type="checkbox" name="oslOpenRoads_';
if(isStd == true) tHTML += 'std';
else tHTML += 'adv';
tHTML += '" id="' + ID + '" />';
tHTML += label + '</label>';
return tHTML;
}
function oslGenerateCollapsibleSubDiv(headerText, subDivHTML)
{
var tHTML;
tHTML = '<div><span style="float:left"><b>'+headerText+'</b></span>';
tHTML += '<span name="oslMinMaxToggle" style="float:right"><i class="fa fa-chevron-circle-down"></i></span></div>';
tHTML += '<div style="height: 0px; padding: 0px; overflow: hidden;">';
tHTML += subDivHTML;
tHTML += '</div>';
return tHTML;
}
function oslSetupUI()
{
var subDivHTML;
// add a new div to hold the OS Locator results, in the form of a draggable window
oslAddLog('create lookup results DIV');
oslWindow = document.createElement('div');
oslWindow.id = "oslWindow";
oslWindow.style.position = 'absolute';
oslWindow.style.border = '1px solid #BBDDBB';
oslWindow.style.borderRadius = '4px';
oslWindow.style.overflow = 'hidden';
oslWindow.style.zIndex = 2000;
oslWindow.style.opacity = 0;
oslWindow.style.transitionProperty = "opacity";
oslWindow.style.transitionDuration = "1000ms";
oslWindow.style.webkitTransitionProperty = "opacity";
oslWindow.style.webkitTransitionDuration = "1000ms";
oslWindow.style.boxShadow = '5px 5px 10px Silver';
document.body.appendChild(oslWindow);
// dragbar div
oslAddLog('create dragbar DIV');
oslDragBar = document.createElement('div');
oslDragBar.id = "oslDragBar";
oslDragBar.style.backgroundColor = '#D0D0D0';
oslDragBar.style.padding = '4px';
oslDragBar.style.fontSize = '16px';
oslDragBar.style.lineHeight = '18px';
oslWindow.appendChild(oslDragBar);
// OS results div
oslAddLog('create results DIV');
oslOSLDiv = document.createElement('div');
oslOSLDiv.id = "oslOSLDiv";
oslOSLDiv.style.backgroundColor = '#DDFFDD';
oslOSLDiv.style.padding = '2px';
oslOSLDiv.style.fontSize = '14px';
oslOSLDiv.style.lineHeight = '16px';
oslOSLDiv.style.display = 'none';
subDivHTML = "<div id='oslRoadNameMatches'></div>";
oslOSLDiv.innerHTML = oslGenerateCollapsibleSubDiv("OS Open Names", subDivHTML);
oslWindow.appendChild(oslOSLDiv);
// Segment geometry control div
oslAddLog('create SegGeo control DIV');
oslSegGeoUIDiv = document.createElement('div');
oslSegGeoUIDiv.id = "oslSegGeoUIDiv";
oslSegGeoUIDiv.style.backgroundColor = '#40A040';
oslSegGeoUIDiv.style.padding = '2px';
oslSegGeoUIDiv.style.fontSize = '14px';
oslSegGeoUIDiv.style.lineHeight = '16px';
oslSegGeoUIDiv.style.display = 'none';
subDivHTML = oslGenerateOpenRoadsCBHTML(true, "_cbOpenRoadsEnabled", "Highlight by Classification:", 0) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(true, "_cbSegGeoMotorway", "Motorway", 1) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(true, "_cbSegGeoARoad", "A Road", 1) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(true, "_cbSegGeoBRoad", "B Road", 1) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(true, "_cbSegGeoMinor", "Minor Road", 1) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(true, "_cbSegGeoLocal", "Local Road", 1) + '<br>';
if(oslAdvancedMode == true)
{
subDivHTML += oslGenerateOpenRoadsCBHTML(false, "_cbSegGeoLocalAccess", "Local Access Road", 1) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(false, "_cbSegGeoRestricted", "Restricted Access Road", 1) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(false, "_cbSegGeoSecondary", "Secondary Access Road", 1) + '<br>';
}
subDivHTML += '<br>' + oslGenerateOpenRoadsCBHTML(true, "_cbOpenRoadsUseGeo", "Show as polylines", 0) + '<br>';
subDivHTML += oslGenerateOpenRoadsCBHTML(true, "_cbOpenRoadsEnhanceGeoVis", "Enhance polyline visibility", 1);
oslSegGeoUIDiv.innerHTML = oslGenerateCollapsibleSubDiv("OS Open Roads", subDivHTML);
oslWindow.appendChild(oslSegGeoUIDiv);
// NameCheck div
oslAddLog('create NameCheck DIV');
oslNCDiv = document.createElement('div');
oslNCDiv.id = "oslNCDiv";
oslNCDiv.style.backgroundColor = '#DDDDFF';
oslNCDiv.style.padding = '2px';
oslNCDiv.style.fontSize = '14px';
oslNCDiv.style.lineHeight = '16px';
oslNCDiv.style.display = 'none';
subDivHTML = '<label style="display:inline;"><input type="checkbox" id="_cbNCEnabled" />Highlight potential naming errors</label>';
subDivHTML += '<br><i>Note: only active at at zoom level 4 and above</i>';
oslNCDiv.innerHTML = oslGenerateCollapsibleSubDiv("NameCheck", subDivHTML);
oslWindow.appendChild(oslNCDiv);
// external links div
oslAddLog('create extern links DIV');
oslMLCDiv = document.createElement('div');
oslMLCDiv.id = "oslMLCDiv";
oslMLCDiv.style.backgroundColor = '#EEFFEE';
oslMLCDiv.style.padding = '2px';
oslMLCDiv.style.fontSize = '14px';
oslMLCDiv.style.lineHeight = '16px';
// add the anchors and auto-track checkboxes for external sites. Note that the urls are blank at this stage,
// they'll be filled in by oslMouseMoveAndUp()...
subDivHTML = '<div id="_extlinksUK" style="display: none;">';
subDivHTML += '<a href="" id="_linkOSOD" target="_osopendata">OS OpenData</a> <input type="checkbox" id="_cbAutoTrackOSOD"></input> | ';
subDivHTML += '<a href="" id="_linkRWO" target="_roadworksorg">one.network</a> <input type="checkbox" id="_cbAutoTrackRWO"></input><br>';
subDivHTML += '<div id="swgCtrls"><a href="" id="_linkSWG" target="_wiltshire">Wiltshire</a> <input type="checkbox" id="_cbAutoTrackSWG"></input></div>';
subDivHTML += '<div id="lrrCtrls"><a href="" id="_linkLRR" target="_londonregister">London Roadworks</a> <input type="checkbox" id="_cbAutoTrackLRR"></input></div>';
subDivHTML += '</div>';
subDivHTML += '<br>(Checkboxes enable auto-tracking)';
subDivHTML += '<br><br><a href="" id="_linkPermalink">Permalink</a>';
oslMLCDiv.innerHTML = oslGenerateCollapsibleSubDiv("External resources", subDivHTML);
oslWindow.appendChild(oslMLCDiv);
}
function oslSetupEventListeners()
{
var idx;
oslAddLog('adding event listeners');
oslDragBar.addEventListener('mousedown', oslOSLDivMouseDown, false);
oslDragBar.addEventListener('mouseup', oslOSLDivMouseUp, false);
W.map.events.register("zoomend", null, oslMouseMoveAndUp);
W.map.events.register("mouseout", null, oslMouseOut);
document.getElementById('_cbNCEnabled').addEventListener('click', oslNCStateChange, false);
for(idx = 0; idx < document.getElementsByName('oslOpenRoads_std').length; ++idx)
{
document.getElementsByName('oslOpenRoads_std')[idx].addEventListener('click', oslOpenRoadsStateChange, false);
}
if(oslAdvancedMode == true)
{
for(idx = 0; idx < document.getElementsByName('oslOpenRoads_adv').length; ++idx)
{
document.getElementsByName('oslOpenRoads_adv')[idx].addEventListener('click', oslOpenRoadsStateChange, false);
}
}
for(idx = 0; idx < document.getElementsByName('oslMinMaxToggle').length; ++idx)
{
document.getElementsByName('oslMinMaxToggle')[idx].addEventListener('click', oslUIMinMax, false);
}
W.map.events.register("mousemove", null, oslMouseMoveAndUp);
W.map.events.register("mouseup", null, oslMouseMoveAndUp);
W.map.segmentLayer.events.register("featuresadded", null, oslNameCheckTrigger);
W.map.segmentLayer.events.register("featuresremoved", null, oslNameCheckTrigger);
}
function oslSetupUIPosition()
{
oslAddLog('adjusting UI position...');
document.body.style.overflow = 'hidden';
var vpHeight = window.innerHeight;
var vpWidth = window.innerWidth;
if
(
(oslUserPrefs.ui.y === null)||
(oslUserPrefs.ui.x === null)||
(oslUserPrefs.ui.y > vpHeight)||
(oslUserPrefs.ui.x > vpWidth)||
(oslUserPrefs.ui.y < 0)||
(oslUserPrefs.ui.x < 0)
)
{
oslOSLDivTop = document.getElementById('sidebar').getBoundingClientRect().top + (document.getElementById('sidebar').getBoundingClientRect().height / 2);
oslOSLDivLeft = 8;
}
else
{
oslOSLDivTop = oslUserPrefs.ui.y;
oslOSLDivLeft = oslUserPrefs.ui.x;
}
if(oslUserPrefs.ui.state === undefined) oslUserPrefs.ui.state = 'maximised';
oslOSLDivTopMinimised = oslOSLDivTop;
oslWindow.style.left = oslOSLDivLeft+'px';
oslWindow.style.top = oslOSLDivTop+'px';
if(oslUserPrefs.ui.state == 'maximised') oslWindowMaximise();
else oslWindowMinimise();
oslWindow.style.opacity = 1;
}
function oslSetLayerZIndices()
{
oslAddLog('setting layer zIndices...');
for(var i=0; i < W.map.layers.length; i++)
{
if(W.map.layers[i].uniqueName == 'satellite_imagery')
{
oslBBDiv.style.zIndex = parseInt(W.map.layers[i].div.style.zIndex) + 1;
oslSegGeoDiv.style.zIndex = parseInt(W.map.layers[i].div.style.zIndex) + 2;
}
if(W.map.layers[i].name == 'Spotlight') oslOSLMaskLayer = W.map.layers[i].div;
}
}
function oslCheckAccessKey()
{
var lastAccessKey = GM_getValue('_rwoAccessKey', null);
var keyFound = false;
if(lastAccessKey !== null)
{
lastAccessKey = parseInt(lastAccessKey);
if((Date.now() - lastAccessKey) <= 10000)
{
keyFound = true;
}
}
if(keyFound === false)
{
oslAddLog('No recent access key found, generating one for this tab and setting up message listener');
oslAccessKeyUpdate();
window.setInterval(oslAccessKeyUpdate,5000);
GM_addValueChangeListener("_rwoPositionToWME", function()
{
if(arguments[3] === true)
{
oslAddLog('WME reposition request from one.network...');
var tPos = new OpenLayers.LonLat();
var posBits = arguments[2].split(',');
tPos.lat = parseFloat(posBits[2]);
tPos.lon = parseFloat(posBits[3]);
tPos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
W.map.setCenter(tPos);
var tZoom = parseInt(posBits[4]);
if(tZoom < 0) tZoom = 0;
if(tZoom > 10) tZoom = 10;
W.map.zoomTo(tZoom);
}
});
}
}
function oslLoadOrInitPrefs()
{
// See if this system already has something in localStorage
var userPrefs = localStorage.oslUserPrefs;
if(userPrefs != undefined)
{
oslUserPrefs = JSON.parse(userPrefs);
}
// Fill out any undefined parts of the prefs object with default values - this works both to initialise
// the object if nothing at all is stored in localStorage, and can also be used to initialise any newer
// parameters that might get added later on which aren't yet defined in the localStorage copy
if(oslUserPrefs.minmax == undefined) oslUserPrefs.minmax = [];
if(oslUserPrefs.openRoads == undefined) oslUserPrefs.openRoads = [];
if(oslUserPrefs.ui == undefined) oslUserPrefs.ui = {};
if(oslUserPrefs.ui.x == undefined) oslUserPrefs.ui.x = null;
if(oslUserPrefs.ui.y == undefined) oslUserPrefs.ui.y = null;
if(oslUserPrefs.ui.state == undefined) oslUserPrefs.ui.state = null;
// Import any older preferences set on this system, then remove from localStorage - this should only ever
// occur the first time this version of the script is run after updating an existing setup, so there
// wouldn't be anything already stored in these three properties that would get wiped out by the import.
if(localStorage.oslOSLDivState != undefined)
{
oslUserPrefs.ui.state = localStorage.oslOSLDivState;
localStorage.removeItem("oslOSLDivState");
}
if(localStorage.oslOSLDivLeft != undefined)
{
oslUserPrefs.ui.x = localStorage.oslOSLDivLeft;
localStorage.removeItem("oslOSLDivLeft");
}
if(localStorage.oslOSLDivTop != undefined)
{
oslUserPrefs.ui.y = localStorage.oslOSLDivTop;
localStorage.removeItem("oslOSLDivTop");
}
}
function oslApplyPrefs()
{
var i;
// subDiv states
for(i = 0; i < oslUserPrefs.minmax.length; ++i)
{
oslSubDivSetState(oslUserPrefs.minmax[i][0], oslUserPrefs.minmax[i][1]);
}
// Open Roads options
for(i = 0; i < oslUserPrefs.openRoads.length; ++i)
{
var cbID = oslUserPrefs.openRoads[i][0];
if(document.getElementById(cbID) != undefined)
{
document.getElementById(cbID).checked = oslUserPrefs.openRoads[i][1];
}
}
// Force-disable Open Roads display on startup to avoid problems if the current WME viewport is
// showing a more densely mapped area than before...
document.getElementById('_cbOpenRoadsEnabled').checked = false;
}
function oslWriteUserPrefs()
{
localStorage.oslUserPrefs = JSON.stringify(oslUserPrefs);
}
function oslUpdateMinMax(key, value)
{
var found = false;
for(var i = 0; i < oslUserPrefs.minmax.length; ++i)
{
if(oslUserPrefs.minmax[i][0] == key)
{
oslUserPrefs.minmax[i][1] = value;
found = true;
break;
}
}
if(found == false)
{
oslUserPrefs.minmax.push([key, value]);
}
oslWriteUserPrefs();
}
function oslUpdateHighlightCBs(key)
{
var found = false;
var value = document.getElementById(key).checked;
for(var i = 0; i < oslUserPrefs.openRoads.length; ++i)
{
if(oslUserPrefs.openRoads[i][0] == key)
{
oslUserPrefs.openRoads[i][1] = value;
found = true;
break;
}
}
if(found == false)
{
oslUserPrefs.openRoads.push([key, value]);
}
oslWriteUserPrefs();
}
function oslFinaliseSetup()
{
oslEnableAdvancedOptions();
oslLoadOrInitPrefs();
oslSetupBBDiv();
oslSetupORDiv();
oslSetupUI();
oslSetupEventListeners();
oslSetupUIPosition();
oslSetLayerZIndices();
oslCheckAccessKey();
oslApplyPrefs();
oslOffsetToolbar = document.getElementById('map').contains(document.getElementById('toolbar'));
window.setInterval(oslTenthSecondTick,100);
oslDoneOnload = true;
}
function oslWazeBits()
{
if(document.location.href.indexOf('user') !== -1)
{
oslAddLog('User profile page detected, script is disabled...');
return;
}
oslAddLog('adding WazeBits...'+oslWazeBitsPresent);
if((oslWazeBitsPresent & 0x01) === 0)
{
if(oslNestedTypeof("W.selectionManager") != "undefined")
{
W = unsafeWindow.W;
oslAddLog(' W.selectionManager OK');
oslWazeBitsPresent |= 0x01;
}
}
if((oslWazeBitsPresent & 0x02) === 0)
{
if(typeof(OpenLayers) != "undefined")
{
oslAddLog(' OpenLayers OK');
oslWazeBitsPresent |= 0x02;
}
}
if((oslWazeBitsPresent & 0x04) === 0)
{
if(oslNestedTypeof("W.map.segmentLayer.div.parentElement.id") != "undefined")
{
if(document.getElementById(W.map.segmentLayer.div.parentElement.id) !== null)
{
oslAddLog(' WazeMap OK');
oslWazeBitsPresent |= 0x04;
oslWazeMapElement = document.getElementById(W.map.segmentLayer.div.parentElement.id);
}
}
}
if((oslWazeBitsPresent & 0x08) === 0)
{
if(oslNestedTypeof("W.model.countries") != "undefined")
{
oslAddLog(' W.model.countries OK');
oslWazeBitsPresent |= 0x08;
}
}
if(oslWazeBitsPresent != 0x0F)
{
window.setTimeout(oslWazeBits,250);
}
else
{
oslFinaliseSetup();
}
}
function oslAccessKeyUpdate()
{
GM_setValue('_rwoAccessKey',Date.now());
}
function oslInitialise()
{
oslAddLog('initialise()');
var nameTestMode = false;
// oslWazeifyStreetName() functionality test code
if(nameTestMode === true)
{
console.log(oslWazeifyStreetName("North Street", true));
console.log(oslWazeifyStreetName("South Street", true));
console.log(oslWazeifyStreetName("East Street", true));
console.log(oslWazeifyStreetName("West Street", true));
console.log(oslWazeifyStreetName("North Town Street", true));
console.log(oslWazeifyStreetName("South Town Street", true));
console.log(oslWazeifyStreetName("East Town Street", true));
console.log(oslWazeifyStreetName("West Town Street", true));
console.log(oslWazeifyStreetName("Green Street", true));
console.log(oslWazeifyStreetName("The Boulevard", true));
console.log(oslWazeifyStreetName("Aston Boulevard West", true));
console.log(oslWazeifyStreetName("Saint Albans Way", true));
console.log(oslWazeifyStreetName("Orchard On The Green", true));
console.log(oslWazeifyStreetName("The Orchard On The Green", true));
console.log(oslWazeifyStreetName("The Avenue", true));
console.log(oslWazeifyStreetName("High Road Ickenham", true));
console.log(oslWazeifyStreetName("Westway Avenue", true));
console.log(oslWazeifyStreetName("Parkway Park", true));
console.log(oslWazeifyStreetName("Parkway Crescent", true));
console.log(oslWazeifyStreetName("Breakspear Road North", true));
console.log(oslWazeifyStreetName("Breakspear Road South", true));
console.log(oslWazeifyStreetName("Breakspear Road East", true));
console.log(oslWazeifyStreetName("Breakspear Road West", true));
console.log(oslWazeifyStreetName("Kensal Green Way", true));
console.log(oslWazeifyStreetName("Great North Road", true));
return;
}
// inject gazetteer data
var gazscript = document.createElement("script");
gazscript.setAttribute('type','text/javascript');
gazscript.setAttribute('charset','windows-1252');
gazscript.src = oslGazetteerURL;
document.head.appendChild(gazscript);
oslMergeGazData = true;
// initialise persistent vars
sessionStorage.zoom = 0;
sessionStorage.lat = '';
sessionStorage.lon = '';
sessionStorage.myCity = '';
sessionStorage.prevCity = '';
sessionStorage.cityChangeEastings = 0;
sessionStorage.cityChangeNorthings = 0;
sessionStorage.cityNameRB = 'optUseExisting';
sessionStorage.oslTabCreated = 0;
oslWazeBits();
}
// External site helper functions
const hlp_ONE =
{
// one.network helper functions
addLog: function(logtext)
{
console.log('ONE: '+logtext);
},
clickToWME: function()
{
var elginLat = Elgin.map.getCenter().lat();
var elginLon = Elgin.map.getCenter().lng();
var elginZoom = Elgin.map.getZoom() - 12;
if(elginZoom < 0) elginZoom = 0;
if(elginZoom > 10) elginZoom = 10;
// check for an active WME tab...
var tabFound = false;
var lastAccessKey = GM_getValue('_rwoAccessKey', null);
if(lastAccessKey !== null)
{
lastAccessKey = parseInt(lastAccessKey);
if((Date.now() - lastAccessKey) <= 10000)
{
// the access key was written within the last 10s which implies an active tab, so send it the repositioning data
var toWrite = Date.now()+','+lastAccessKey+','+elginLat+','+elginLon+','+elginZoom;
GM_setValue('_rwoPositionToWME',toWrite);
tabFound = true;
}
}
if(tabFound === false)
{
// couldn't find a WME tab to reposition, so open a new one...
var wmeURL = 'https://www.waze.com/editor?';
wmeURL += 'lon='+elginLon;
wmeURL += '&lat='+elginLat;
wmeURL += '&zoom='+elginZoom;
window.open(wmeURL);
}
},
init: function()
{
hlp_ONE.addLog('initialise()');
hlp_ONE.addLog('waiting for map objects...');
var waitSomeMore = false;
try
{
if(Elgin === undefined)
{
waitSomeMore = true;
}
else if (Elgin.map === undefined)
{
waitSomeMore = true;
}
if(google === undefined)
{
waitSomeMore = true;
}
else if(google.maps === undefined)
{
waitSomeMore = true;
}
}
catch
{
waitSomeMore = true;
}
if(document.getElementById('map-canvas') === null)
{
waitSomeMore = true;
}
if(document.getElementsByClassName('gm-bundled-control-on-bottom').length == 0)
{
waitSomeMore = true;
}
if(waitSomeMore)
{
window.setTimeout(hlp_ONE.init,500);
return;
}
hlp_ONE.addLog('all required objects found...');
// Add "open in WME" button...
var tBtnDiv = document.createElement('div');
tBtnDiv.id = 'rwoWMELink';
var tHTML = '<div class="gmnoprint" draggable="false" controlwidth="40" controlheight="40" style="margin: 10px; user-select: none; position: absolute; bottom: 220px; right: 40px;">';
tHTML += '<div class="gmnoprint" controlwidth="40" controlheight="40" style="position: absolute; left: 0px; top: 0px;">';
tHTML += '<div draggable="false" style="user-select: none; box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px; border-radius: 2px; cursor: pointer; background-color: rgb(255, 255, 128); width: 40px; height: 40px;">';
tHTML += '<button draggable="false" title="Open in WME" aria-label="Open in WME" type="button" class="gm-control-active" style="background: none; display: block; border: 0px; margin: 0px; padding: 0px; position: relative; cursor: pointer; user-select: none; overflow: hidden; width: 40px; height: 40px; top: 0px; left: 0px;"><strong>WME</strong></button>';
tHTML += '</div></div></div>';
tBtnDiv.innerHTML = tHTML;
document.getElementById('map-canvas').firstChild.appendChild(tBtnDiv);
document.getElementById('rwoWMELink').addEventListener('click', hlp_ONE.clickToWME, false);
// extract the coords/zoom from the url...
var userloc = document.location.href;
var latpos = userloc.indexOf("?lat=");
var lonpos = userloc.indexOf("&lon=");
var zpos = userloc.indexOf("&z=");
if((latpos != -1)&&(lonpos != -1)&&(zpos != -1))
{
var rwoLat = parseFloat(userloc.substr(latpos+5,lonpos-(latpos+5)));
var rwoLon = parseFloat(userloc.substr(lonpos+5,zpos-(lonpos+5)));
var rwoZoom = parseInt(userloc.substr(zpos+3,2))+12;
Elgin.map.setCenter(new google.maps.LatLng(rwoLat,rwoLon));
Elgin.map.setZoom(rwoZoom);
hlp_ONE.addLog('map repositioned');
}
}
};
const hlp_WSW =
{
// Wiltshire Streetworks helper functions
addLog: function(logtext)
{
console.log('WSW: '+logtext);
},
init: function()
{
hlp_WSW.addLog('initialise()');
hlp_WSW.addLog('waiting for map objects...');
var waitSomeMore = false;
if((map === null) || (map === undefined))
{
waitSomeMore = true;
hlp_WSW.addLog('map not found...');
}
else
{
if(map.setCenter === undefined)
{
waitSomeMore = true;
hlp_WSW.addLog('map.setCenter not found...');
}
if(map.zoomTo === undefined)
{
waitSomeMore = true;
hlp_WSW.addLog('map.zoomTo not found...');
}
}
if((OpenLayers === null) || (OpenLayers === undefined))
{
waitSomeMore = true;
hlp_WSW.addLog('OpenLayers not found...');
}
else
{
if(OpenLayers.LonLat === undefined)
{
waitSomeMore = true;
hlp_WSW.addLog('OpenLayers.LonLat not found...');
}
}
if(waitSomeMore)
{
window.setTimeout(hlp_WSW.init,500);
return;
}
hlp_WSW.addLog('all required objects found...');
// extract the coords/zoom from the url...
var userloc = document.location.href;
var latpos = userloc.indexOf("?lat=");
var lonpos = userloc.indexOf("&lon=");
var zpos = userloc.indexOf("&z=");
if((latpos != -1)&&(lonpos != -1)&&(zpos != -1))
{
var swgLat = parseFloat(userloc.substr(latpos+5,lonpos-(latpos+5)));
var swgLon = parseFloat(userloc.substr(lonpos+5,zpos-(lonpos+5)));
var swgZoom = parseInt(userloc.substr(zpos+3,2));
map.setCenter(new OpenLayers.LonLat(swgLon,swgLat));
map.zoomTo(swgZoom);
hlp_WSW.addLog('map repositioned');
}
}
};
const hlp_LRR =
{
// London Roadworks Register helper functions
addLog: function(logtext)
{
console.log('LRR: '+logtext);
},
init: function()
{
// trap the page reload that occurs when the map view is generated...
if(document.location.href.indexOf('home') == -1)
{
hlp_LRR.addLog('page reloaded during map generation - redirecting to second stage initialisation...');
hlp_LRR.initPartDeux();
return;
}
hlp_LRR.addLog('initialise()');
hlp_LRR.addLog('waiting for search page to load...');
var waitSomeMore = false;
if(document.getElementsByName('mapResults')[0].length < 1)
{
waitSomeMore = true;
}
if(document.getElementsByName('postCode')[0].length < 1)
{
waitSomeMore = true;
}
if(waitSomeMore === true)
{
window.setTimeout(hlp_LRR.init,500);
return;
}
// extract the coords/zoom from the url...
var userloc = document.location.href;
var epos = userloc.indexOf("?e=");
var npos = userloc.indexOf("&n=");
var zpos = userloc.indexOf("&z=");
if((epos != -1)&&(npos != -1)&&(zpos != -1))
{
var lrrLon = userloc.substr(epos+3,npos-(epos+3));
var lrrLat = userloc.substr(npos+3,zpos-(npos+3));
var lrrZoom = userloc.substr(zpos+3,2);
sessionStorage.setItem('lrrLon',lrrLon);
sessionStorage.setItem('lrrLat',lrrLat);
sessionStorage.setItem('lrrZoom',lrrZoom);
hlp_LRR.addLog('accessing map...');
// first set a "safe" postcode as the search criteria - whilst asking for the map view to be generated without any
// search terms usually works OK, from time to time the site throws a wobbler and refuses to do anything without
// having the search narrowed down a bit...
document.getElementsByName('postCode')[0].value="EC1A 1AA";
document.getElementsByName('mapResults')[0].click();
}
},
initPartDeux: function()
{
hlp_LRR.addLog('waiting for map objects...');
var waitSomeMore = false;
if(map === undefined)
{
waitSomeMore = true;
}
if(OpenLayers === undefined)
{
waitSomeMore = true;
}
if(waitSomeMore)
{
window.setTimeout(hlp_LRR.initPartDeux,500);
return;
}
hlp_LRR.addLog('all required objects found...');
var lrrLon = parseInt(sessionStorage.getItem('lrrLon'));
var lrrLat = parseInt(sessionStorage.getItem('lrrLat'));
var lrrZoom = parseInt(sessionStorage.getItem('lrrZoom'));
map.setCenter(new OpenLayers.LonLat(lrrLon,lrrLat));
map.zoomTo(lrrZoom);
hlp_LRR.addLog('map repositioned');
}
};
const hlp_ODM =
{
// OS OpenData map helper functions
eastings: 0,
northings: 0,
zoom: 0,
addLog: function(logtext)
{
console.log('ODM: '+logtext);
},
resizeMap: function()
{
hlp_ODM.addLog('resize');
// resizes map viewport whenever browser window changes size
var newWidth = window.innerWidth - 10;
var newHeight = window.innerHeight - 10;
hlp_ODM.addLog(' '+newWidth+' x '+newHeight);
osMap.size.w = newWidth;
osMap.size.h = newHeight;
var elm = document.getElementById("map");
// first we need to move the map DIV out of its original placement heirarchy, so that
// it can flow to the left of the browser window rather than to the left of its
// parent block...
document.children[0].appendChild(elm);
// then we resize it to fill the available space
elm.style.height = newHeight+'px';
elm.style.width = newWidth+'px';
elm.style.left = "4px";
// force a redraw of the map object to use the resized viewport correctly
osMap.render('map');
},
recentreMap: function()
{
// call the OS provided functions required to point the map at a
// given grid ref and zoom level
var mymapCenter = new OpenSpace.MapPoint(this.eastings, this.northings);
osMap.setCenter(mymapCenter, this.zoom);
},
hideThing: function(thing)
{
if((thing === null)||(thing === undefined))
{
hlp_ODM.addLog(' not found');
}
else
{
thing.style.visibility = "hidden";
thing.style.position = "absolute";
thing.style.top = "0px";
hlp_ODM.addLog(' hidden');
}
},
hideElement: function(elmID)
{
hlp_ODM.addLog('hiding element '+elmID);
var elm = document.getElementById(elmID);
hlp_ODM.hideThing(elm);
},
hideTagName: function(elmID)
{
hlp_ODM.addLog('hiding tag '+elmID);
var elm = document.getElementsByTagName(elmID)[0];
hlp_ODM.hideThing(elm);
},
fakeOnload: function()
{
// remove the non-map stuff from the page...
hlp_ODM.hideElement("openspace.mapbuilder.header");
hlp_ODM.hideElement("col2");
hlp_ODM.hideTagName("h1");
hlp_ODM.hideElement("div1");
// reduce the width of the whitespace around the map viewport
document.getElementById("wrapper").style.padding = '4px';
// resize the map viewport...
hlp_ODM.resizeMap();
window.addEventListener('resize', hlp_ODM.resizeMap, true);
// extract the starting coords/zoom from the url...
var userloc = document.location.href;
var epos = userloc.indexOf("?e=");
var npos = userloc.indexOf("&n=");
var zpos = userloc.indexOf("&z=");
if((epos != -1)&&(npos != -1)&&(zpos != -1))
{
this.eastings = userloc.substr(epos+3,npos-(epos+3));
this.northings = userloc.substr(npos+3,zpos-(npos+3));
this.zoom = userloc.substr(zpos+3,2);
//...then recentre the map
hlp_ODM.recentreMap();
}
},
init: function()
{
hlp_ODM.addLog('initialise()');
if(osMap === undefined) window.setTimeout(hlp_ODM.init,500);
else hlp_ODM.fakeOnload();
}
};
oslBootstrap();