您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds filtering and pop-up infobox for UR, MP and camera markers
当前为
// ==UserScript== // @name UROverview Plus (URO+) // @namespace http://greasemonkey.chizzum.com // @description Adds filtering and pop-up infobox for UR, MP and camera markers // @include https://*.waze.com/*editor* // @include https://editor-beta.waze.com/* // @grant none // @version 3.44 // ==/UserScript== /* TO-DO ITEMS ======================================================================================================================= Bug fixes - MUST BE CLEARED BEFORE RELEASE ======================================================================================================================= None ======================================================================================================================= Proposed functionality ======================================================================================================================= Display full UR submission time/date in popup Extend unstacking to cameras Restricted turn info popup Place filtering - by last user to edit - collapsible filter subcategories First-run information - show quickstart guide to URO features if no existing settings are present (i.e. new installation) User-defined setting presets ======================================================================================================================= New functionality in progress ======================================================================================================================= Addition of segment and place watchlist functionality */ function uroGlobals() { uroVersion = "3.44"; uroReleaseDate = "20150425"; uroChanges = [ "Managed areas can be given user-defined names", "Popup now shows userID instead of 'undefined' for temporary users" ]; uroBetaChanges = [ ]; uroShowDebugOutput = true; uroCtrlsHidden = false; uroCurrentTab = 1; uroFID = -1; uroShownFID = -1; uroShownPopupType = null; uroInhibitSave = true; uroPopupTimer = -2; uroPopupShown = false; uroSetupListeners = true; uroRootContainer = null; uroPlacesRoot = null; uroMaskLayer = null; uroCustomMarkerFID = null; uroConfirmIntercepted = false; uroCustomMarkerList = []; uroPendingURSessionIDs = []; uroRequestedURSessionIDs = []; uroMouseInPopup = false; uroURControlsIdx = null; uroProblemControlsIdx = null; uroMaskActive = false; uroTurnsLayerIdx = null; uroNullCamLayer = false; uroNullOpenLayers = false; uroNullRootContainer = false; uroNullURLayer = false; uroNullProblemLayer = false; uroNullMapViewport = false; uroURDialogIsOpen = false; uroSelectedURID = null; uroPendingCommentDataRefresh = false; uroWaitingCommentDataRefresh = false; uroExpectedCommentCount = null; uroCachedLastCommentID = null; uroPlaceSelected = false; uroMouseIsDown = false; uroBackfilling = false; uroUserID = -1; uroURSCurrentCount = 0; uroURSPrevCount = 0; uroDOMHasTurnProblems = false; uroBetaEditor = false; uroPracticeMode = false; uroWazeBitsPresent = 0; uroCWLGroups = new Array(); uroCamWatchObjects = new Array(); uroSegWatchObjects = new Array(); uroPlaceWatchObjects = new Array(); uroFilteredCameraIDs = new Array(); uroFriendlyAreaNames = new Array(); uroAreaNameHoverTime = -1; uroAreaNameHoverObj = null; uroAreaNameOverlayShown = false; uroANEditHovered = false; uroAMPosX = null; uroAMPosY = null; dteControlsIdx = -1; dteOldestFullDrive = new Date(0); dteEpoch = new Date(0); dteTopID = ''; uroUserTabId = ''; uroUnstackedMasterID = null; uroStackList = new Array(); uroStackType = null; uroIcons = [ // stuff used within the URO tabbed UI // 0 = group collapse/group expand [ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRIqo78SIAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAADtJREFUKM9j/P//PwNJgCQN////ZyFeGyMjIwMDAxMDiWAQamDB9Bb+kKTMBmICdxgFK64AxZKiSE3eAAOXFRnJRfN6AAAAAElFTkSuQmCC", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRDHbt/O0AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAE5JREFUKM+9UkEKACAMcmP//7IdgghqMQvytoOKTiMJCRKBZNRpZgbAIcIzsa5XJcgOB8Qaaz3nSt4chlLX3nb9OXRlL7cO2V83I1Dn3QDKfhshMqWScAAAAABJRU5ErkJggg==" ], // 1 = addtogroup active/addtogroup idle [ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYVKhKBubQAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAEZJREFUOMtjYBjygBHB/P8fjzJGIszCZQA+gxkYWIjTABPDdAkL8U7G7hIcYcDISEGYwDQSFyZM5AQckYA4F7CQZ8goQAYAMCsd/TxbqrwAAAAASUVORK5CYII=", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tDee2t8AAAABPSURBVDjL7ZAxCgAgDAMT6cP6dH+mUwfBaugmeFMpbTgCPA9j6H2M7MidvCZlAadgADDlIXY7E1OVM5NtB+5kuZN4VDtpleIkVAOrhHxWJoJkNv2QAd51AAAAAElFTkSuQmCC" ], // 2 = goto active/goto idle [ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYfLAEN9AsAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAGdJREFUOMutk+EKACEIg7fD93/l3Y+uP5kmeYMgkH0NTUpCRw+acgBynHaCKsgBlpaIhDJQtQchaAtIBuNAlAQSV7OUwPYYGX2kL6Zi37hYYk6NU1ZPui/Y4XWeVsWSDpdkt8bftvEFOy0jJkeygWMAAAAASUVORK5CYII=", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tFm3TfiwAAABySURBVDjLrZNRDsAgCEPp4r306HKy7sMsMRMckZH4ZfqoYEFSMnVJshYAME7aQRS0AOaR9C5UFe5AoRnsQCbAW4wFAklRlaNd1ipIrxHeRwKGZeuuNcEjK554J5x7lohNS+g+4d39Kyqug2jGyqnwtzTengM2Gxwa0GsAAAAASUVORK5CYII=" ], // replacements for native UR/problem markers // 3 = normal/selected open roadworks UR [ "data:image/png;base64,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", "data:image/png;base64,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" ], // 4 = normal/selected closed roadworks UR [ "data:image/png;base64,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", "data:image/png;base64,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" ], // 5 = normal/selected open closure UR [ "data:image/png;base64,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", "data:image/png;base64,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" ], // 6 = normal/selected closed closure UR [ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAoCAYAAABw65OnAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94IDhUwL1o1gTwAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAADL9JREFUWMOlWG2MnNV1fs69973vO98z+22w3cX2BrdgTDy0ZGNKBgoOdjEmgv0BidKUEJGK/KhapNDUpUlUVRBFatWqEUkUJSFKK2QphI905RjoQLCXOF7AARt/QDzBa4+9O7OzM7Pz8b73qz9216yNCaS90tGdGb16z3Ofc8+Z5xzC778YACoUCtRsNmnpx1Qq5YrFogPgANjf54X0IZ+hQqHASqWSGB4eFlprr9PpcN/3WaPRoHQ67cIwtLFYzAghVKlU0sPDw7pYLNpFUO53OeAf4Jzl83lhrQ3S6XQilUqlO51O1lqbA9AjhMhJKXOMsbQxJmWMiYdhGGSzWWmM4UopWr9+vSuXy/8nJqhQKPAwDL131DsxMCSdc+m+q/tWZXdkb54dnL1mWk6vrfFan2JKetaLciZXGYgG3u4523Ng7sm5PZXXKieJqAGLeQJ1hC9UaW/JXIyVi4GgfD4vgiAI3m6+nSSPsiv/bOXlZoe572Dm4E2GGfG+R1IAPIBbrjfWNz7Ln+Tfnnpu6qhTbm5tau18t9vtTk5O6guB8IsBEELEPM/LVk11cN3OdX/56o2vPjwVm1rvmGP4EMF15Fg5KK+rbqzefuWVV9rZvbMn+v1+65wzQ0NDtlwuu/djggqFAldKxUqqlOMxvqLvn/oeeqX3lW34f65N1U3/XdlZ+brpmDKBauvi6zrFYvFcaJYzwTudTlBP1DMAhvof6f/aq7lXt8EAiACEF+xm0fSyPVw0tfh6Wkjocrw8smZ0zaXzu+f3rxar1fHjx3Wr1ToHYokJ2rp1q6zX65lutzv0yMMP/9WRI0e+2KjXF+h1DtY5gBYet9aCFj87597N42XBJgCMMQjO4QuObG8vVlxy6Xe+snPnfwRBcCaTydTHx8cjAE4AQKFQ4NPT04GUMr19y01XXbXq0nu+//WdaFRrsABmQ4VQCCSyPbCMoxt2IYRAFCm055twWiElCMIZdLvdhYrmCIPpJPoTcaSTSaxY+xHc/DcPfO7Pt9z8i2dfeLE9PT0dFgoFUywWtQBAxWKRX3HFFbFsMpm75/bbvqi/+aDc2ctRj0KA+YitXId0YRv01aNwqSQE9wACGBG41Wgf2ofZ53chOnEYLOIQxoEMQzPqIrIhfBWi38zBe+ct+fnPfvbeX7z8yyONRmN+cnKyC8AIAGzz5s2y2+0mrt24YV3ft7662cxWkJifx8pUAizTB7ExD9r0J6CRPwQ8sUi3g9Uaqnoa3twUvPYZgDsIyeEZgGsC4wRrGVjgw+MOwUwZvZ/Yct2mTZsue+GFF2qbN29u7d27V7NCoUBKKRmPxxM7tm7d4uYbEPU5SOFBDq2CvP4W8LHPg13xUZD0QEQgIjhiUGdOYO6pR9Ec/wFoegZSO0gNSE2QlhBYQlJKJHM9iP/BOvBV68D8gN9xxx03xePxhFJKFgoFEsVikefzeRmGYeLS1as2koyBxdPAitVgN9wK2vIpIJ48L+Wcc2i//iLq499HePAleBrwDEFYQBiCsARuAe4Axn2wK64BfXIM+MgfoaO7WL169UfDMEwYY2SxWORidHSUEZH0PC/I5HpWeSMbgFYLKGwDXXP9ewDYqIvWiV9j7j8fhvntcUgDeJrgWSw4N7Tg3AAs3QN2y52g2+4G+ocAAAHzkM1mh2OxWKCUkqOjo0ykUilWrVaFc07GMtmM7bsEtK0Ae9kInAzerWjOQTcqaP7P42ju+TGoOg2pCZ6lBRYWnXMLMAuwVSOg2+4G3bgdSKbeZVEZxGKxbBRFMooi0dvby0QURSSEYM45xnzfczs+DZfKQBNfqAvOgZyDOnUMzZ8/hs7ep8FbHXianUe/sAsACAx01R+DPvUXwDXXwUl/4SDOwaouYAyEzHnOOSaEYFEUkQCAWCzmut0ujIOi/kHPKY3ILMoAraGO7kd7/HtQv34JInLvib9YPD0XPuhPt4J2fAa4fMO7pdA5mG4LavodRFNHkbz2Zr3kFwCElNK1220rpTTtdns24ccGSRNaRgNRB/rAbqhnfwT39qEFp8sAcEsL1FsCS6RBt94F2n430D94/j0K2whPvI72r/bAzJZBazbUpZRGa23j8bgTzWbTcs61tTaqVqslf2hwkJxDz3wF9ed/jO7zj4PVavA0g2cXLuG5228BOAK7ZBhsx6dBt9wJBLHzM0lrtN/Yi/bLzyA6/gZkpg/1SuWktTYCoJvNphUTExM2n88rz/M6R48efW31qtXX1o9OovXzHyI88Bz4/DyEIggDkF1++oXSjEuGwe59AHTtJwDhnc9AZx7NiWcw/+JPYKbegtfRSFIKB6ZOH9Rad5RSanJy0rJCoWCklCERtR977LGXHFxo3twHc3AfRKcLTzt4FpCW4C/GX1iAOwK76lqwex+A+9gNsNzDOUHpHFT1NOZ2/wDN3T+C+81hiHoTkktQpeK+99OfPUdEbSllWCgUDCsWi9b3/Yhz3pqamiofOnSoGLzw3ELqhQaeWSpE72YA4z7YjTtA9z0I97EboIlBO7dg1qDz28OYe+a7aL/4U1B5CqKj4Wsg3jYoPfjvz588deo057zl+35ULBYtB4BSqUTpdJoLIbxjx45Vt3/5oZvE/r3SqQjUjsAtQYLADcAyfWDb7wbdeQ/cqmFoEEIHWOegwg66b+xFY/dj6ByaAGYqYJ0IiZAgRRLMwf3j0TP/fHamcqLRaFT379/fBmDOiZqRkRFwzvnc3BwymWy0+pYd15yZ2EcnK7NoRRYxL4C8fhu6d92PxtWjqFmD6mwN1VoNp6tVnC2fwumJPSgXn8DZNw+iOlPH3HyEbssBQQqxmI+nP/N3/7Z7z7Mvc87P+r5fP3nyZAjA0jINIvP5fIoxNiiFuOxv7/vClx7913/5pOq0UJ6toRlptLTBQH8/kpksBgaH4PsSxjoIIeAxQqs2A+q0QGEbRmsYbUBMoGuAr3zjm0997ZFvfEcpVbLWnp2cnGwuajS3XGOyfD4fpFKpdKvVGuKMrfnS/fd/bvKVV7Znc7nz1BQjAuMLJC79q9Ki4gIcYBeUmANQq83iyaeenvE87++TyeSBVCpVbjabjUUtYS8qdAEEYRhmSqo04Mitym3J3XTs8LEvmA0mwO3LtGV3mY60iyYWv3MAuwA8AZu9LDsuG/Lba4O1UwCmfd+vA+i+n9BFqVRyw8PDVghhKvMVRZyi7onuqbRL75NCDrR/1b4UHwchBiABIL5oiWUWAPgvuOTR5KG+VN9DoiPGGbFTcROfjsfjjQsBXLQNXALia1+3RTvSLR067Zpsmr2aqCT2unfc1epqlYJYao2XWQPwvuu1eiZ6vhyEwROu7d4eMkPlFYkVFaVU0/f98EIA79uLlkolVy6X7aaRTdpTXtQre8OGbXQJ1BWnxCtoYFSlVAI9yyR2CMQRb9318l1ftTX7ZsqmpjIsc9ZaW4vH4+2JiYmoVCrZi7WB/Hf0p9Tb24sgCJxSyvQH/TrLsmZOzbmsyx7Vt+qPR17kLw0BiJMd2TXyrdd/+fqBWlg7lfNylSiK5mOxWFir1ezMzIz7sF05jY2NscOHD3uDg4Oyp6dHEpF/yp2Ss9GsmO3OCu5zL6pHbFAN1qsbqnmEIEhg/Wvr92Qezzzbw3sqPV5PkzGmOp0OhBC8r6+Pr1ixQqxcuZJlMhm6ENB7sqPZbErOeYyIYoyxwDnneZ7nOec8xpgPIHmkdaTXwg7m/jq343j+eGHFzIrSyD+MPBpF0RnO+QyApnOuyxiLwjDURKQYY1Gz2ewGQdAZGBjojo+Pq6UUXc7E0hAk7nleVmudk1LmOOc5pVSOiLJKqQxjLJ1l2ZVZZAcyr2Wancs7gzf+8MaXZmZmAMAHAM65cM4lnHNJAAnOeYwxJqWUXEppwzA0AwMD5xrj80CMjo4KIooBSDjnUoyxBIC4MSYQQgRCCKmUks65PiKKRVEkevf1/qZSqYTWWuucs4wxBUA75zjnnAshuDGGeZ7noigyjLFIShlFUaTK5fJ7ihUD4F133XVxAKkwDFOe58WJKHDOecYYQUScMcaIiBtjhBCCExFXSlnnnOGca+eccc4ZIrJCCA1Ah2EYOec6SqmW1rrhnGsdOnSou1j23PKBhxsbG9MzMzOdZrNpwzAMY7GYnJubE0EQeIwxboxhxhgIIZgQgoVhSM45IiLn+74jImeMsVprFwSBC8NQG2OM7/uaiBQRhUqppb7eXtiVnzcky+fzvFqt8t7eXpZKpViz2eSpVIq01mSMIQBY2s9LNc7P3fpOp2M55y4IAvvWW2/ZNWvW2EajYfr7++2FBYs+YJZFi2mLmZmZ80aGH7SWRopjY2PYtWvXksOLTvL+F//XlHZcmEL/AAAAAElFTkSuQmCC", "data:image/png;base64,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" ], // 7 = normal/selected open event UR [ "data:image/png;base64,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", "data:image/png;base64,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" ], // 8 = normal/selected closed event UR [ "data:image/png;base64,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", "data:image/png;base64,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" ], // 9 = normal/selected open note UR [ "data:image/png;base64,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", "data:image/png;base64,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" ], // 10 = normal/selected closed note UR [ "data:image/png;base64,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", "data:image/png;base64,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" ] ]; uroMarkers = [ // 0 = comment count circle ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90LCxYGJyle3m4AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAv1JREFUSMfFls1r3EYYxn+zo9XsqjuSxpBQU5OCDy0Y3JODs2Z36W6P/YBCk159s+/5F9Z/QsHkUAruZZ344Jx7KPTSa2/NwSdDE1ISf8SWI63k6UVLN8ZuZFnQ56IZDYwevR/P+wguh7jieXF9Gewla3vJWeELAfA8b9ZxnFWl1P0kST7NsswDkFJGrus+i+P4cZqmP0VR9JyKIWq12owx5kff95PBYBCPRiN7EaPRyA4Gg9j3/cQY80hK6VdFwFFK3TXGvOx0OoktiE6nExtjXjSbzYUb/T3QqNfrvSAITofDob0uhsOhDcPwTVkiAmgCC8aYV2UITBMxxrwok5oGcEdr/XR5eXlsb4g8NY+uVQPAh0KIr7XW6f7+vq0Cvu8nnufNvu/jtak03FZKfbe4uGjn5uYqqe6lpSXrOM5qERIS8IEZz/O66+vrTlUttra25iql7hfSImAB+DIIgrd7e3u2KhwcHNggCE6LREIBGlBZlqn5+fnK1C4MQybqWiQdKi/O/wWTwpSAkFLGWZZVdnkURUgpoyIk/t3Uas93dnYqI7G9vY3rus+KkLBABtgoin7f3NxMqyKxtbWVxHH8uIhUG+AT4CMhxK1Wq/XD8fGxrIJEEATjNE0/ft+IrwEx8AaIrbWH1tpfV1ZWbhyNbrc7llL+XMRjyDwdTt6mzSRJ/jw5Ofkiy7JGr9crRWBjY4Pd3d3XR0dH31hrz4pOTw18BnwFPBBCPPR9/6zsKA+C4FQpdbeoc3tngAErwLfA90KIh2EYHrbb7cITtd1uj40xr+r1eq+s7jSAO0A3J/IAWG21Wr9ordN+vz++yt71+/2x1jrVWj/NR0DjukbmHVcF3ALmgJl8L4UQoeu6n3ued+/8/Hw2yzKVG91YSvlXFEW/xXH8xFr7B/A38PYqZ13EbYtcwkPgdk7kgylZF1PWPc076xR4DbwEDvN3tmwkLtZIMx/xwWTA5d1ELm6T1j4CjoGznFgpX/lfZxJwpwhMR2JCJJkobllN+QeQNNGuneopoQAAAABJRU5ErkJggg=="], // 1 = green comment marker ["data:image/png;base64,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"], // 2 = yellow (own) comment marker ["data:image/png;base64,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"] ]; } function uroBootstrap() { var bGreasemonkeyServiceDefined = false; try { bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object"); } catch (err) { /* Ignore */ } if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) { unsafeWindow = ( function () { var dummyElem = document.createElement('p'); dummyElem.setAttribute('onclick', 'return window;'); return dummyElem.onclick(); }) (); } /* begin running the code! */ uroInitialise(); } function uroAddLog(logtext) { if(uroShowDebugOutput) console.log('URO+: '+logtext); } function uroGetCBChecked(cbID) { return(document.getElementById(cbID).checked); } function uroGetElmValue(elmID) { return(document.getElementById(elmID).value); } function uroSetStyleDisplay(elm,style) { document.getElementById(elm).style.display = style; } function uroSetOnClick(elm,fn) { document.getElementById(elm).onclick = fn; } function uroAddEventListener(elm,eventType,eventFn,eventBool) { document.getElementById(elm).addEventListener(eventType, eventFn, eventBool); } function uroFirstTimerWelcomePack() { uroAddLog('welcome new users to Club URO...'); // to be completed... } function uroShowUpdateNotes() { uroAddLog('let existing users know what\'s new in this release'); var alertMsg = 'URO+ Update Notes...\n\n'; alertMsg += 'Thanks for upgrading to URO+ '+uroVersion+' ('+uroReleaseDate+'). What\'s changed?\n\n'; if(uroChanges.length > 0) { for(var loop=0; loop < uroChanges.length; loop++) { alertMsg += '* '+uroChanges[loop]+'\n'; } } if((uroBetaEditor) && (uroBetaChanges.length > 0)) { alertMsg += '\nFor WME Beta:\n'; for(var loop=0; loop < uroBetaChanges.length; loop++) { alertMsg += '* '+uroBetaChanges[loop]+'\n'; } } alert(alertMsg); } function uroAdvertiseCustomIcons() { uroAddLog('advertise the benefits of custom UR icons...'); var confirmMsg = 'URO+ Installation/Upgrade Processing...\n\n'; confirmMsg += 'Hi there. One of the features of URO+ that a lot of users find useful is the ability to use a custom marker for URs which have been tagged with a specific keyword in their description text.\n\n'; confirmMsg += 'Markers are defined for [ROADWORKS], [CONSTRUCTION], [CLOSURE], [EVENT] and [NOTE] tags.\n\n'; confirmMsg += 'Would you like me to automatically enable these custom markers?\n\n'; confirmMsg += 'If you change your mind later on, they can be enabled/disabled via the Misc tab within the URO+ settings'; if(confirm(confirmMsg) == true) { document.getElementById('_cbCustomRoadworksMarkers').checked = true; document.getElementById('_cbCustomConstructionMarkers').checked = true; document.getElementById('_cbCustomClosuresMarkers').checked = true; document.getElementById('_cbCustomEventsMarkers').checked = true; document.getElementById('_cbCustomNotesMarkers').checked = true; } } function uroGatherSettings(container) { var options = ''; var urOptions = document.getElementById(container).getElementsByTagName('input'); for (var optIdx=0;optIdx<urOptions.length;optIdx++) { var id = urOptions[optIdx].id; if((id.indexOf('_cb') == 0)||(id.indexOf('_text') == 0)||(id.indexOf('_input') == 0)) { options += ':' + id; if(urOptions[optIdx].type == 'checkbox') options += ',' + urOptions[optIdx].checked.toString(); else if((urOptions[optIdx].type == 'text')||(urOptions[optIdx].type == 'number')) options += ',' + urOptions[optIdx].value.toString(); } } return options; } function uroGatherCamWatchList() { var liststr = ''; for(var loop=0;loop<uroCamWatchObjects.length;loop++) { camObj = uroCamWatchObjects[loop]; if((camObj.fid != undefined) && (camObj.persistent == true)) { if(loop > 0) liststr += ':'; liststr += camObj.fid+','; liststr += camObj.watch.lon+','; liststr += camObj.watch.lat+','; liststr += camObj.watch.type+','; liststr += camObj.watch.azymuth+','; liststr += camObj.watch.speed+','; liststr += camObj.watch.validated+','; liststr += camObj.groupID+','; liststr += camObj.server; } } return liststr; } function uroGatherSegWatchList() { var liststr = ''; for(var loop=0;loop<uroSegWatchObjects.length;loop++) { segObj = uroSegWatchObjects[loop]; if((segObj.fid != undefined) && (segObj.persistent == true)) { if(loop > 0) liststr += ':'; liststr += segObj.fid+','; liststr += segObj.watch.left+','; liststr += segObj.watch.right+','; liststr += segObj.watch.bottom+','; liststr += segObj.watch.top+','; liststr += segObj.watch.fromNode+','; liststr += segObj.watch.toNode+','; liststr += segObj.watch.fwdDir+','; liststr += segObj.watch.revDir+','; liststr += segObj.watch.length+','; liststr += segObj.watch.level+','; liststr += segObj.watch.rank+','; liststr += segObj.watch.roadType+','; liststr += segObj.watch.updatedOn+','; liststr += segObj.groupID+','; liststr += segObj.server; } } return liststr; } function uroGatherPlaceWatchList() { var liststr = ''; for(var loop=0;loop<uroPlaceWatchObjects.length;loop++) { placeObj = uroPlaceWatchObjects[loop]; if((placeObj.fid != undefined) && (placeObj.persistent == true)) { if(loop > 0) liststr += ':'; liststr += placeObj.fid+','; liststr += placeObj.watch.left+','; liststr += placeObj.watch.right+','; liststr += placeObj.watch.bottom+','; liststr += placeObj.watch.top+','; liststr += placeObj.watch.name+','; liststr += placeObj.watch.imageCount+','; liststr += placeObj.watch.residential+','; liststr += placeObj.watch.updatedOn+','; liststr += placeObj.groupID+','; liststr += placeObj.server; } } return liststr; } function uroGatherCWLGroups() { var liststr = ''; for(var loop=0;loop<uroCWLGroups.length;loop++) { groupObj = uroCWLGroups[loop]; if(groupObj.groupID != -1) { if(loop > 0) liststr += ':'; liststr += groupObj.groupID+','; liststr += groupObj.groupName+','; liststr += groupObj.groupCollapsed; } } return liststr; } function uroGatherFriendlyAreaNames() { var liststr = ''; for(var loop=0;loop<uroFriendlyAreaNames.length;loop++) { fnObj = uroFriendlyAreaNames[loop]; if(loop > 0) liststr += ':'; liststr += fnObj.fName+','; liststr += fnObj.area+','; liststr += fnObj.server; } return liststr; } function uroSaveSettings() { if(uroInhibitSave) return; if (localStorage) { localStorage.UROverviewUROptions = uroGatherSettings('uroCtrlURs'); localStorage.UROverviewMPOptions = uroGatherSettings('uroCtrlMPs'); localStorage.UROverviewCameraOptions = uroGatherSettings('uroCtrlCameras'); localStorage.UROverviewMiscOptions = uroGatherSettings('uroCtrlMisc'); localStorage.UROverviewPlacesOptions = uroGatherSettings('uroCtrlPlaces'); localStorage.UROverviewCamWatchList = uroGatherCamWatchList(); localStorage.UROverviewSegWatchList = uroGatherSegWatchList(); localStorage.UROverviewPlaceWatchList = uroGatherPlaceWatchList(); localStorage.UROverviewCWLGroups = uroGatherCWLGroups(); localStorage.UROverviewFriendlyAreaNames = uroGatherFriendlyAreaNames(); localStorage.UROverviewCurrentVersion = uroVersion; } } function uroApplySettings(settings) { var options = settings.split(':'); for(var optIdx=0;optIdx<options.length;optIdx++) { var fields = options[optIdx].split(','); if(fields[0].indexOf('_cb') == 0) { if(document.getElementById(fields[0]) != null) { document.getElementById(fields[0]).checked = (fields[1] == 'true'); } } else if((fields[0].indexOf('_input') == 0)||(fields[0].indexOf('_text') == 0)) { if(document.getElementById(fields[0]) != null) document.getElementById(fields[0]).value = fields[1]; } } } function uroApplyCamWatchList() { var objects = localStorage.UROverviewCamWatchList.split(':'); uroCamWatchObjects = new Array(); for(var objIdx=0;objIdx<objects.length;objIdx++) { var fields = objects[objIdx].split(','); // following two bits of code add in blank fields if the user has updated their copy of URO+ from an // older version which didn't include support for either of these field types // add default groupID field if(fields.length == 7) { fields.push(0); } // set default groupID value to 0 (no group) if(fields[7] == -1) { fields[7] = 0; } // add default server field if(fields.length == 8) { fields.push('??'); } // set default server value to unknown if(fields[8] == 0) { fields[8] = '??'; } uroCamWatchObjects.push(new uroCamWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8])); } } function uroApplySegWatchList() { var objects = localStorage.UROverviewSegWatchList.split(':'); uroSegWatchObjects = new Array(); for(var objIdx=0;objIdx<objects.length;objIdx++) { var fields = objects[objIdx].split(','); uroSegWatchObjects.push(new uroSegWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8],fields[9],fields[10],fields[11],fields[12],fields[13],fields[14],fields[15])); } } function uroApplyPlaceWatchList() { var objects = localStorage.UROverviewPlaceWatchList.split(':'); uroPlaceWatchObjects = new Array(); for(var objIdx=0;objIdx<objects.length;objIdx++) { var fields = objects[objIdx].split(','); uroPlaceWatchObjects.push(new uroPlaceWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8],fields[9],fields[10])); } } function uroApplyCWLGroups() { var objects = localStorage.UROverviewCWLGroups.split(':'); uroCWLGroups = new Array(); for(var objIdx=0;objIdx<objects.length;objIdx++) { var fields = objects[objIdx].split(','); if(fields.length < 2) { fields.push(false); } uroCWLGroups.push(new uroOWLGroupObj(fields[0],fields[1],(fields[2] == 'true'))); } } function uroApplyFriendlyAreaNames() { var objects = localStorage.UROverviewFriendlyAreaNames.split(':'); uroFriendlyAreaNames = new Array(); for(var objIdx=0;objIdx<objects.length;objIdx++) { var fields = objects[objIdx].split(','); uroFriendlyAreaNames.push(new uroAFNObj(fields[0],parseFloat(fields[1]),fields[2])); } uroReplaceAreaNames(true); } function uroLoadSettings() { var isNewInstall = true; var isUpgradeInstall = true; var notifyAboutCustomIcons = true; uroAddLog('loadSettings()'); if (localStorage.UROverviewUROptions) { uroAddLog('recover UR tab settings'); uroApplySettings(localStorage.UROverviewUROptions); isNewInstall = false; } if (localStorage.UROverviewCameraOptions) { uroAddLog('recover camera tab settings'); uroApplySettings(localStorage.UROverviewCameraOptions); isNewInstall = false; } if (localStorage.UROverviewMPOptions) { uroAddLog('recover MP tab settings'); uroApplySettings(localStorage.UROverviewMPOptions); isNewInstall = false; } if (localStorage.UROverviewPlacesOptions) { uroAddLog('recover Places tab settings'); uroApplySettings(localStorage.UROverviewPlacesOptions); isNewInstall = false; } if (localStorage.UROverviewMiscOptions) { uroAddLog('recover misc tab settings'); uroApplySettings(localStorage.UROverviewMiscOptions); isNewInstall = false; if(localStorage.UROverviewCurrentVersion) { notifyAboutCustomIcons = false; } else { if(uroGetCBChecked('_cbCustomRoadworksMarkers') == true) notifyAboutCustomIcons = false; if(uroGetCBChecked('_cbCustomConstructionMarkers')== true) notifyAboutCustomIcons = false; if(uroGetCBChecked('_cbCustomClosuresMarkers') == true) notifyAboutCustomIcons = false; if(uroGetCBChecked('_cbCustomEventsMarkers') == true) notifyAboutCustomIcons = false; if(uroGetCBChecked('_cbCustomNotesMarkers') == true) notifyAboutCustomIcons = false; } } if(localStorage.UROverviewCWLGroups) { uroAddLog('recover CWL groups'); uroApplyCWLGroups(); isNewInstall = false; } else { uroAddLog('set default CWL group'); uroCWLGroups.push(new uroOWLGroupObj(0,'No group',false)); } if(localStorage.UROverviewCamWatchList) { uroAddLog('recover camera watchlist'); uroApplyCamWatchList(); uroGetCurrentCamWatchListObjects(); isNewInstall = false; } if(localStorage.UROverviewSegWatchList) { uroAddLog('recover segment watchlist'); uroApplySegWatchList(); uroGetCurrentSegWatchListObjects(); isNewInstall = false; } if(localStorage.UROverviewPlaceWatchList) { uroAddLog('recover places watchlist'); uroApplyPlaceWatchList(); //uroGetCurrentPlaceWatchListObjects(); isNewInstall = false; } if(localStorage.UROverviewCurrentVersion) { uroAddLog('comparing install versions'); if(localStorage.UROverviewCurrentVersion == uroVersion) { isUpgradeInstall = false; } } if(localStorage.UROverviewFriendlyAreaNames) { uroAddLog('recover friendly area names'); uroApplyFriendlyAreaNames(); isNewInstall = false; } if(isNewInstall) { uroFirstTimerWelcomePack(); } else if(isUpgradeInstall) { uroShowUpdateNotes(); } if(notifyAboutCustomIcons) { uroAdvertiseCustomIcons(); } uroInhibitSave = false; } function uroDefaultSettings() { if(confirm('Resetting URO+ settings cannot be undone\nAre you sure you want to do this?') == true) { var defaultSettings = ''; defaultSettings += '[UROverviewUROptions][len=1544]:_cbFilterWazeAuto,false:_cbFilterIncorrectTurn,false:_cbFilterIncorrectAddress,false:_cbFilterIncorrectRoute,false:_cbFilterMissingRoundabout,false:_cbFilterGeneralError,false:_cbFilterTurnNotAllowed,false:_cbFilterIncorrectJunction,false:_cbFilterMissingBridgeOverpass,false:_cbFilterWrongDrivingDirection,false:_cbFilterMissingExit,false:_cbFilterMissingRoad,false:_cbFilterBlockedRoad,false:_cbFilterMissingLandmark,false:_cbFilterUndefined,false:_cbFilterRoadworks,false:_cbFilterConstruction,false:_cbFilterClosure,false:_cbFilterEvent,false:_cbFilterNote,false:_cbInvertURFilter,false:_cbFilterOpenUR,false:_cbFilterClosedUR,false:_cbFilterSolved,false:_cbFilterUnidentified,false:_cbEnableMinAgeFilter,false:_inputFilterMinDays,:_cbEnableMaxAgeFilter,false:_inputFilterMaxDays,:_cbURDescriptionMustBePresent,false:_cbURDescriptionMustBeAbsent,false:_cbEnableKeywordMustBePresent,false:_textKeywordPresent,:_cbEnableKeywordMustBeAbsent,false:_textKeywordAbsent,:_cbCaseInsensitive,false:_cbHideMyComments,false:_cbHideAnyComments,false:_cbHideIfLastCommenter,false:_cbHideIfNotLastCommenter,false:_cbHideIfReporterLastCommenter,false:_cbHideIfReporterNotLastCommenter,false:_cbEnableMinCommentsFilter,false:_inputFilterMinComments,:_cbEnableMaxCommentsFilter,false:_inputFilterMaxComments,:_cbHideMyFollowed,false:_cbHideMyUnfollowed,false:_cbEnableCommentAgeFilter2,false:_inputFilterCommentDays2,:_cbEnableCommentAgeFilter,false:_inputFilterCommentDays,:_cbURUserIDFilter,false:_cbURResolverIDFilter,false:_cbNoFilterForTaggedURs,false[END]'; defaultSettings += '[UROverviewCameraOptions][len=827]:_cbShowWorldCams,true:_cbShowUSACams,true:_cbShowNonWorldCams,true:_cbShowOnlyMyCams,false:_cbShowApprovedCams,true:_cbShowNonApprovedCams,true:_cbShowOlderCreatedNonApproved,false:_inputCameraMinCreatedDays,:_cbShowOlderUpdatedNonApproved,false:_inputCameraMinUpdatedDays,:_cbShowSpeedCams,true:_cbShowIfMPHSpeedSet,true:_cbShowIfKPHSpeedSet,true:_cbShowIfNoSpeedSet,true:_cbShowRedLightCams,true:_cbShowDummyCams,true:_cbHideCreatedByMe,false:_cbHideCreatedByRank0,false:_cbHideCreatedByRank1,false:_cbHideCreatedByRank2,false:_cbHideCreatedByRank3,false:_cbHideCreatedByRank4,false:_cbHideCreatedByRank5,false:_cbHideUpdatedByMe,false:_cbHideUpdatedByRank0,false:_cbHideUpdatedByRank1,false:_cbHideUpdatedByRank2,false:_cbHideUpdatedByRank3,false:_cbHideUpdatedByRank4,false:_cbHideUpdatedByRank5,false:_cbHideCWLCams,false[END]'; defaultSettings += '[UROverviewMPOptions][len=563]:_cbMPFilterMissingJunction,false:_cbMPFilterMissingRoad,false:_cbMPFilterCrossroadsJunctionMissing,false:_cbMPFilterDrivingDirectionMismatch,false:_cbMPFilterRoadTypeMismatch,false:_cbMPFilterRestrictedTurn,false:_cbMPFilterUnknownProblem,false:_cbMPFilterTurnProblem,false:_cbMPFilterReopenedProblem,false:_cbInvertMPFilter,false:_cbMPFilterClosed,false:_cbMPFilterSolved,false:_cbMPFilterUnidentified,false:_cbMPClosedUserIDFilter,false:_cbMPNotClosedUserIDFilter,false:_cbMPFilterLowSeverity,false:_cbMPFilterMediumSeverity,false:_cbMPFilterHighSeverity,false[END]'; defaultSettings += '[UROverviewMiscOptions][len=702]:_cbNativeConvoMarkers,true:_cbNativeBetaConvoMarkers,true:_cbCommentCount,false:_cbURBackfill,false:_inputUnstackSensitivity,15:_inputUnstackZoomLevel,3:_cbCustomRoadworksMarkers,false:_cbCustomConstructionMarkers,false:_cbCustomClosuresMarkers,false:_cbCustomEventsMarkers,false:_cbCustomNotesMarkers,false:_cbInhibitURPopup,false:_cbInhibitMPPopup,false:_cbInhibitCamPopup,false:_cbInhibitSegPopup,false:_cbInhibitLandmarkPopup,false:_cbInhibitPUPopup,false:_cbWhiteBackground,false:_inputCustomBackgroundRed,255:_inputCustomBackgroundGreen,255:_inputCustomBackgroundBlue,255:_cbHideAMLayer,false:_cbDisablePlacesFiltering,false:_cbDisablePendingQuestions,false:_cbEnableDTE,false:_cbEnableSRS,false[END]'; defaultSettings += '[UROverviewCWLGroups][len=16]0,No group,false[END]'; defaultSettings += '[UROverviewPlacesOptions][len=5106]:_cbFilterUneditablePlaceUpdates,false:_cbFilterLockRankedPlaceUpdates,false:_cbFilterNewPlacePUR,false:_cbFilterUpdatedDetailsPUR,false:_cbFilterNewPhotoPUR,false:_cbFilterFlaggedPUR,false:_cbLeavePURGeos,false:_cbInvertPURFilters,false:_cbPURFilterLowSeverity,false:_cbPURFilterMediumSeverity,false:_cbPURFilterHighSeverity,false:_cbEnablePURMinAgeFilter,false:_inputPURFilterMinDays,:_cbEnablePURMaxAgeFilter,false:_inputPURFilterMaxDays,:_cbPlaceFilterEditedLessThan,false:_inputFilterPlaceEditMinDays,:_cbPlaceFilterEditedMoreThan,false:_inputFilterPlaceEditMaxDays,:_cbHidePlacesL0,false:_cbHidePlacesL1,false:_cbHidePlacesL2,false:_cbHidePlacesL3,false:_cbHidePlacesL4,false:_cbHidePlacesL5,false:_cbHidePhotoPlaces,false:_cbHideNoPhotoPlaces,false:_cbPlacesFilter-CAR_SERVICES,false:_cbPlacesFilter-GAS_STATION,false:_cbPlacesFilter-PARKING_LOT,false:_cbPlacesFilter-GARAGE_AUTOMOTIVE_SHOP,false:_cbPlacesFilter-CAR_WASH,false:_cbPlacesFilter-CHARGING_STATION,false:_cbPlacesFilter-TRANSPORTATION,false:_cbPlacesFilter-AIRPORT,false:_cbPlacesFilter-BUS_STATION,false:_cbPlacesFilter-FERRY_PIER,false:_cbPlacesFilter-SEAPORT_MARINA_HARBOR,false:_cbPlacesFilter-SUBWAY_STATION,false:_cbPlacesFilter-TRAIN_STATION,false:_cbPlacesFilter-BRIDGE,false:_cbPlacesFilter-TUNNEL,false:_cbPlacesFilter-TAXI_STATION,false:_cbPlacesFilter-JUNCTION_INTERCHANGE,false:_cbPlacesFilter-PROFESSIONAL_AND_PUBLIC,false:_cbPlacesFilter-COLLEGE_UNIVERSITY,false:_cbPlacesFilter-SCHOOL,false:_cbPlacesFilter-CONVENTIONS_EVENT_CENTER,false:_cbPlacesFilter-GOVERNMENT,false:_cbPlacesFilter-LIBRARY,false:_cbPlacesFilter-CITY_HALL,false:_cbPlacesFilter-ORGANIZATION_OR_ASSOCIATION,false:_cbPlacesFilter-PRISON_CORRECTIONAL_FACILITY,false:_cbPlacesFilter-COURTHOUSE,false:_cbPlacesFilter-CEMETERY,false:_cbPlacesFilter-FIRE_DEPARTMENT,false:_cbPlacesFilter-POLICE_STATION,false:_cbPlacesFilter-MILITARY,false:_cbPlacesFilter-HOSPITAL_MEDICAL_CARE,false:_cbPlacesFilter-OFFICES,false:_cbPlacesFilter-POST_OFFICE,false:_cbPlacesFilter-RELIGIOUS_CENTER,false:_cbPlacesFilter-KINDERGARDEN,false:_cbPlacesFilter-FACTORY_INDUSTRIAL,false:_cbPlacesFilter-EMBASSY_CONSULATE,false:_cbPlacesFilter-INFORMATION_POINT,false:_cbPlacesFilter-SHOPPING_AND_SERVICES,false:_cbPlacesFilter-ARTS_AND_CRAFTS,false:_cbPlacesFilter-BANK_FINANCIAL,false:_cbPlacesFilter-SPORTING_GOODS,false:_cbPlacesFilter-BOOKSTORE,false:_cbPlacesFilter-PHOTOGRAPHY,false:_cbPlacesFilter-CAR_DEALERSHIP,false:_cbPlacesFilter-FASHION_AND_CLOTHING,false:_cbPlacesFilter-CONVENIENCE_STORE,false:_cbPlacesFilter-PERSONAL_CARE,false:_cbPlacesFilter-DEPARTMENT_STORE,false:_cbPlacesFilter-PHARMACY,false:_cbPlacesFilter-ELECTRONICS,false:_cbPlacesFilter-FLOWERS,false:_cbPlacesFilter-FURNITURE_HOME_STORE,false:_cbPlacesFilter-GIFTS,false:_cbPlacesFilter-GYM_FITNESS,false:_cbPlacesFilter-SWIMMING_POOL,false:_cbPlacesFilter-HARDWARE_STORE,false:_cbPlacesFilter-MARKET,false:_cbPlacesFilter-SUPERMARKET_GROCERY,false:_cbPlacesFilter-JEWELRY,false:_cbPlacesFilter-LAUNDRY_DRY_CLEAN,false:_cbPlacesFilter-SHOPPING_CENTER,false:_cbPlacesFilter-MUSIC_STORE,false:_cbPlacesFilter-PET_STORE_VETERINARIAN_SERVICES,false:_cbPlacesFilter-TOY_STORE,false:_cbPlacesFilter-TRAVEL_AGENCY,false:_cbPlacesFilter-ATM,false:_cbPlacesFilter-CURRENCY_EXCHANGE,false:_cbPlacesFilter-CAR_RENTAL,false:_cbPlacesFilter-FOOD_AND_DRINK,false:_cbPlacesFilter-RESTAURANT,false:_cbPlacesFilter-BAKERY,false:_cbPlacesFilter-DESSERT,false:_cbPlacesFilter-CAFE,false:_cbPlacesFilter-FAST_FOOD,false:_cbPlacesFilter-FOOD_COURT,false:_cbPlacesFilter-BAR,false:_cbPlacesFilter-ICE_CREAM,false:_cbPlacesFilter-CULTURE_AND_ENTERTAINEMENT,false:_cbPlacesFilter-ART_GALLERY,false:_cbPlacesFilter-CASINO,false:_cbPlacesFilter-CLUB,false:_cbPlacesFilter-TOURIST_ATTRACTION_HISTORIC_SITE,false:_cbPlacesFilter-MOVIE_THEATER,false:_cbPlacesFilter-MUSEUM,false:_cbPlacesFilter-MUSIC_VENUE,false:_cbPlacesFilter-PERFORMING_ARTS_VENUE,false:_cbPlacesFilter-GAME_CLUB,false:_cbPlacesFilter-STADIUM_ARENA,false:_cbPlacesFilter-THEME_PARK,false:_cbPlacesFilter-ZOO_AQUARIUM,false:_cbPlacesFilter-RACING_TRACK,false:_cbPlacesFilter-THEATER,false:_cbPlacesFilter-OTHER,false:_cbPlacesFilter-CONSTRUCTION_SITE,false:_cbPlacesFilter-LODGING,false:_cbPlacesFilter-HOTEL,false:_cbPlacesFilter-HOSTEL,false:_cbPlacesFilter-CAMPING_TRAILER_PARK,false:_cbPlacesFilter-COTTAGE_CABIN,false:_cbPlacesFilter-BED_AND_BREAKFAST,false:_cbPlacesFilter-OUTDOORS,false:_cbPlacesFilter-PARK,false:_cbPlacesFilter-PLAYGROUND,false:_cbPlacesFilter-BEACH,false:_cbPlacesFilter-SPORTS_COURT,false:_cbPlacesFilter-GOLF_COURSE,false:_cbPlacesFilter-PLAZA,false:_cbPlacesFilter-PROMENADE,false:_cbPlacesFilter-POOL,false:_cbPlacesFilter-SCENIC_LOOKOUT_VIEWPOINT,false:_cbPlacesFilter-SKI_AREA,false:_cbPlacesFilter-NATURAL_FEATURES,false:_cbPlacesFilter-ISLAND,false:_cbPlacesFilter-SEA_LAKE_POOL,false:_cbPlacesFilter-RIVER_STREAM,false:_cbPlacesFilter-FOREST_GROVE,false:_cbPlacesFilter-FARM,false:_cbPlacesFilter-CANAL,false:_cbPlacesFilter-SWAMP_MARSH,false:_cbPlacesFilter-DAM,false:_cbFilterPrivatePlaces,false:_cbInvertPlacesFilter,false[END]'; document.getElementById('_txtSettings').value = defaultSettings; uroTextToSettings(); document.getElementById('_txtSettings').value = ''; } } function uroSettingsToText() { var txtSettings = ''; uroSaveSettings(); for(var lsEntry in localStorage) { if(lsEntry.indexOf('UROverview') == 0) { txtSettings += '['+lsEntry+'][len=' + localStorage[lsEntry].length + ']' + localStorage[lsEntry] + '[END]'; } } document.getElementById('_txtSettings').value = txtSettings; document.getElementById('_txtSettings').focus(); document.getElementById('_txtSettings').select(); } function uroTextToSettings() { var txtSettings = ''; txtSettings = uroGetElmValue('_txtSettings'); if(txtSettings.indexOf('[END]') == -1) return; var subText = txtSettings.split('[END]'); for(var i=0;i<subText.length;i++) { var bPos = subText[i].indexOf(']'); if(bPos != -1) { var settingID = subText[i].substr(1,bPos-1); subText[i] = subText[i].substr(bPos+1); bPos = subText[i].indexOf(']'); if(bPos != -1) { var settingLength = subText[i].substr(5,bPos-5); subText[i] = subText[i].substr(bPos+1); if(subText[i].length == settingLength) { localStorage[settingID] = subText[i]; } } } } uroLoadSettings(); } function uroClearSettingsText() { document.getElementById('_txtSettings').value = ''; } function uroDateToDays(dateToConvert) { var dateNow = new Date(); var elapsedSinceEpoch = dateNow.getTime(); var elapsedSinceEvent = elapsedSinceEpoch - dateToConvert; dateNow.setHours(0); dateNow.setMinutes(0); dateNow.setSeconds(0); dateNow.setMilliseconds(0); var elapsedSinceMidnight = elapsedSinceEpoch - dateNow.getTime(); if(elapsedSinceEvent < elapsedSinceMidnight) { // event occurred today... return 0; } else { // event occurred at some point prior to midnight this morning, so return a minimum value of 1... return 1 + Math.floor((elapsedSinceEvent - elapsedSinceMidnight) / 86400000); } } function uroGetURAge(urObj,ageType) { if(ageType == 0) { if((urObj.attributes.driveDate == null)||(urObj.attributes.driveDate == 0)) return -1; return uroDateToDays(urObj.attributes.driveDate); } else if(ageType == 1) { if((urObj.attributes.resolvedOn == null)||(urObj.attributes.resolvedOn == 0)) return -1; return uroDateToDays(urObj.attributes.resolvedOn); } else { return -1; } } function uroGetPURAge(purObj) { if(purObj.attributes.venueUpdateRequests[0].attributes.dateAdded != null) { return uroDateToDays(purObj.attributes.venueUpdateRequests[0].attributes.dateAdded); } else { return -1; } } function uroGetCameraAge(camObj, mode) { if(mode == 0) { if(camObj.attributes.updatedOn == null) return -1; return uroDateToDays(camObj.attributes.updatedOn); } if(mode == 1) { if(camObj.attributes.createdOn == null) return -1; return uroDateToDays(camObj.attributes.createdOn); } } function uroGetCommentAge(commentObj) { if(commentObj.createdOn == null) return -1; return uroDateToDays(commentObj.createdOn); } function uroParseDaysAgo(days) { if(days == 0) return 'today'; else if(days == 1) return '1 day ago'; else return days+' days ago'; } function uroIsCameraSpeedValid(camObj) { // returns 1 if the entered speed converts correctly into a multiple of 10MPH // returns -1 if the entered speed does not convert correctly // returns 0 if no speed data is present, or if the entered speed is 0 if(camObj.attributes.speed != null) { var speed = Math.round(camObj.attributes.speed /1.609); if(speed == 0) return 0; else if(speed % 10 == 0) return 1; else return -1; } else return 0; } // -------------------------------------------------------------------------------------------------------------------- // AREA FRIENDLYNAME STUFF // -------------------------------------------------------------------------------------------------------------------- function uroAFNObj(fName, area, server) { this.fName = fName; this.area = area; this.server = server; } function uroUpdateAreaName(name, server, area) { var foundExisting = false; for(var i=0; i<uroFriendlyAreaNames.length; i++) { if((uroFriendlyAreaNames[i].server == server) && (uroFriendlyAreaNames[i].area == area)) { if(name == "") { uroFriendlyAreaNames.splice(i,1); foundExisting = true; } else { uroFriendlyAreaNames[i].fName = name; foundExisting = true; } } } if((foundExisting == false) && (name != "")) { uroFriendlyAreaNames.push(new uroAFNObj(name,area,server)); } uroReplaceAreaNames(true); } function uroAreaNameHover() { if((uroAreaNameHoverObj == null) || (uroAreaNameHoverObj != this)) { uroAreaNameHoverTime = 0; } uroAreaNameHoverObj = this; } function uroAreaNameUnHover() { if(uroANEditHovered == true) { return false; } if(uroAreaNameOverlayShown) { uroAreaNameHoverObj.removeChild(uroANEditBox); } uroAreaNameHoverObj = null; uroAreaNameHoverTime = -1; uroAreaNameOverlayShown = false; } function uroANEditHover() { uroANEditHovered = true; uroAddEventListener('uroANEditBox','mouseout',uroANEditUnHover,false); uroAddEventListener('uroANEditBox','click',uroANEditClick,false); } function uroANEditUnHover() { var newName = document.getElementById('_textAreaName').value; // sanitise name to avoid conflicts with config storage delimiters... newName = newName.replace(',',''); newName = newName.replace(':',''); var server = W.location.code; var area = uroGetAreaArea(uroAreaNameHoverObj.parentNode.children[1]); uroAreaNameHoverObj.removeChild(uroANEditBox); uroAreaNameOverlayShown = false; uroANEditHovered = false; uroUpdateAreaName(newName, server, area) } function uroANEditClick(e) { // this traps the click to prevent it falling through to the underlying area name element and // potentially causing the map view to be relocated to that area... e.stopPropagation(); } function uroGetAreaArea(listObj) { var area = listObj.getElementsByTagName('span')[0].innerHTML; area = parseFloat(area.split(' ')[0]); return area; } function uroAreaNameOverlaySetup() { uroAreaNameOverlayShown = true; uroANEditBox = document.createElement('div'); uroANEditBox.id = "uroANEditBox"; uroANEditBox.style.position = "absolute"; uroANEditBox.style.top = '7px'; uroANEditBox.style.left = '2px'; uroANEditBox.style.width = "99%"; uroAreaNameHoverObj.appendChild(uroANEditBox); uroANEditBox.onmouseover = uroANEditHover(); var existingName = uroAreaNameHoverObj.innerHTML; var italicTagPos = existingName.indexOf(' <i>'); if(italicTagPos == -1) { existingName = ""; } else { existingName = existingName.substr(0,italicTagPos); } uroANEditBox.innerHTML = '<input type="text" style="font-size:14px; line-height:16px; height:22px; width:100%" id="_textAreaName" value="'+existingName+'">'; } function uroReplaceAreaNames(replaceAfterNameChange) { if(document.getElementById('sidepanel-areas') == undefined) { return; } if(replaceAfterNameChange == false) { if(document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0].id == "friendlyNamed") { return; } } var panelRootObj = document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0]; var areaCount = panelRootObj.children.length; if(areaCount == 0) { return; } var localisedManagedArea = I18n.translations[I18n.locale].user.areas.managed_area; for(loop=0; loop < areaCount; loop++) { var childObjPElems = panelRootObj.children[loop].getElementsByTagName('p'); var title = childObjPElems[0].innerHTML; if(title.indexOf(localisedManagedArea) > -1) { var area = uroGetAreaArea(childObjPElems[1]); childObjPElems[0].innerHTML = localisedManagedArea; for(fnIdx=0; fnIdx < uroFriendlyAreaNames.length; fnIdx++) { fnObj = uroFriendlyAreaNames[fnIdx]; if((fnObj.area == area) && (fnObj.server == W.location.code)) { childObjPElems[0].innerHTML = fnObj.fName +' <i>('+localisedManagedArea+')</i>'; usingFriendlyName = true; break; } } var titleObj = panelRootObj.getElementsByClassName('title')[loop]; titleObj.addEventListener("mouseover", uroAreaNameHover, false); titleObj.addEventListener("mouseout", uroAreaNameUnHover, false); titleObj.style.cursor = "text"; } } document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0].id = "friendlyNamed"; } // -------------------------------------------------------------------------------------------------------------------- // WATCHLIST STUFF // -------------------------------------------------------------------------------------------------------------------- // Generic Functions function uroTypeCast(varin) { if(varin == "null") return null; if(typeof varin == "string") return parseInt(varin); return varin; } function uroOWLGroupObj(groupID, groupName, groupCollapsed) { groupID = uroTypeCast(groupID); this.groupID = groupID; this.groupName = groupName; this.groupCount = 0; this.groupCollapsed = groupCollapsed; } // Camera Functions function uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon) { if(type != null) type = uroTypeCast(type); if(azymuth != null) azymuth = uroTruncate(uroTypeCast(azymuth)%360); if(speed != null) speed = uroTruncate(uroTypeCast(speed)); if(typeof validated == "string") validated = (validated == "true"); if(lat != null) lat = uroTruncate(uroTypeCast(lat)); if(lon != null) lon = uroTruncate(uroTypeCast(lon)); this.type = type; this.azymuth = azymuth; this.speed = speed; this.validated = validated; this.lat = lat; this.lon = lon; } function uroCamWatchObj(persistent, fid, lon, lat, type, azymuth, speed, validated, groupID, server) { fid = uroTypeCast(fid); groupID = uroTypeCast(groupID); if(typeof persistent == "string") persistent = (persistent == "true"); this.fid = fid; this.persistent = persistent; this.loaded = false; this.server = server; this.groupID = groupID; this.watch = new uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon); this.current = new uroCamWatchObjCheckProps(null, null, null, null, null, null); } function uroCamDataChanged(idx) { camObj = uroCamWatchObjects[idx]; if(camObj.loaded == false) return false; if(camObj.current.type != camObj.watch.type) return true; if(camObj.current.azymuth != camObj.watch.azymuth) return true; if(camObj.current.speed != camObj.watch.speed) return true; if(camObj.current.validated != camObj.watch.validated) return true; if(camObj.current.lat != camObj.watch.lat) return true; if(camObj.current.lon != camObj.watch.lon) return true; return false; } function uroIsCamOnWatchList(fid) { for(var loop=0;loop<uroCamWatchObjects.length;loop++) { if(uroCamWatchObjects[loop].fid == fid) return loop; } return -1; } function uroAddCurrentCamWatchData(idx, lat, lon, type, azymuth, speed, validated, server) { camObj = uroCamWatchObjects[idx]; camObj.loaded = true; camObj.server = server; camObj.current = new uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon) return(uroCamDataChanged(idx)); } function uroAddCamToWatchList() { if(uroIsCamOnWatchList(uroShownFID) == -1) { camObj = W.model.cameras.objects[uroShownFID]; uroCamWatchObjects.push(new uroCamWatchObj(true, uroShownFID, camObj.geometry.x, camObj.geometry.y, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, 0, W.location.code)); uroAddCurrentCamWatchData(uroCamWatchObjects.length-1, camObj.geometry.y, camObj.geometry.x, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, W.location.code); uroAddLog('added camera '+uroShownFID+' to watchlist'); uroOWLUpdateHTML(); } } function uroRemoveCamFromWatchList() { camidx = uroIsCamOnWatchList(uroShownFID); if(camidx != -1) { uroCamWatchObjects.splice(camidx,1); uroAddLog('removed camera '+uroShownFID+' from watchlist'); uroOWLUpdateHTML(); } } function uroUpdateCamWatchList() { var camIdx = uroIsCamOnWatchList(uroShownFID); if(camIdx != -1) { var camObj = W.model.cameras.objects[uroShownFID]; uroCamWatchObjects[camIdx].watch = new uroCamWatchObjCheckProps(camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, camObj.geometry.y, camObj.geometry.x); } } function uroClearCamWatchList() { if(confirm('Removing all cameras from the OWL cannot be undone\nAre you sure you want to do this?') == true) { uroCamWatchObjects = new Array(); uroOWLUpdateHTML(); } } function uroRetrieveCameras(lat, lon) { var camPos = new OpenLayers.LonLat(); var camChanged = false; camPos.lon = lon; camPos.lat = lat; camPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")); var camURL = 'https://' + document.location.host; camURL += Waze.Config.api_base; camURL += '/Features?language=en&cameras=true&bbox='; var latl = camPos.lat - 0.25; var latu = camPos.lat + 0.25; var lonl = camPos.lon - 0.25; var lonr = camPos.lon + 0.25; camURL += lonl+','+latl+','+lonr+','+latu; uroAddLog('retrieving camera data around '+camPos.lon+','+camPos.lat); camReq = new XMLHttpRequest(); camReq.open('GET',camURL,false); try { camReq.send(); uroAddLog('response '+camReq.status+' received'); if (camReq.status === 200) { camData = JSON.parse(camReq.responseText); for(var camIdx = 0; camIdx < camData.cameras.objects.length; camIdx++) { camObj = camData.cameras.objects[camIdx]; var listIdx = uroIsCamOnWatchList(camObj.id); if(listIdx != -1) { camPos.lon = camObj.geometry.coordinates[0]; camPos.lat = camObj.geometry.coordinates[1]; camPos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913")); camPos.lon = uroTruncate(camPos.lon); camPos.lat = uroTruncate(camPos.lat); camChanged |= uroAddCurrentCamWatchData(listIdx, camPos.lat, camPos.lon, camObj.type, camObj.azymuth, camObj.speed, camObj.validated, W.location.code); } else if(camObj.validated == false) { } } } else { uroAddLog('request failed (status != 200)'); } } catch(err) { uroAddLog('camera load request failed (exception '+err+' caught)'); } return camChanged; } function uroGetCurrentCamWatchListObjects() { var camChanged = false; var camsChanged = new Array(); var camsDeleted = new Array(); for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++) { camObj = uroCamWatchObjects[camidx]; if((camObj.loaded == false) && ((camObj.server == W.location.code) || (camObj.server == '??'))) { if(typeof W.model.cameras.objects[camObj.fid] == 'object') { if(W.model.cameras.objects[camObj.fid].state != "Delete") { wazeObj = W.model.cameras.objects[camObj.fid]; camChanged |= uroAddCurrentCamWatchData(camidx, wazeObj.geometry.y, wazeObj.geometry.x, wazeObj.attributes.type, wazeObj.attributes.azymuth, wazeObj.attributes.speed, wazeObj.attributes.validated); } else { camChanged |= uroRetrieveCameras(camObj.watch.lat, camObj.watch.lon); } } else { camChanged |= uroRetrieveCameras(camObj.watch.lat, camObj.watch.lon); } } } if(camChanged) { for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++) { if(uroCamDataChanged(camidx)) { camsChanged.push(uroCamWatchObjects[camidx]); } } } for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++) { camObj = uroCamWatchObjects[camidx]; if((camObj.loaded == false) && (camObj.server == W.location.code)) { camsDeleted.push(camObj); } } if((camsChanged.length > 0) || (camsDeleted.length > 0)) { var alertStr = 'Camera WatchList Alert!!!\r\n'; for(var camidx=0;camidx<camsChanged.length;camidx++) { alertStr += 'Camera ID '+camsChanged[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsChanged[camidx].groupID)+'" has been changed\r\n'; } for(var camidx=0;camidx<camsDeleted.length;camidx++) { alertStr += 'Camera ID '+camsDeleted[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsDeleted[camidx].groupID)+'" has been deleted\r\n'; } alert(alertStr); } } function uroClearDeletedCameras() { for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--) { if(uroCamWatchObjects[camidx].loaded == false) { uroShownFID = uroCamWatchObjects[camidx].fid; uroRemoveCamFromWatchList(); } } } function uroClearUnknownServerCameras() { var confirmMsg = 'Cameras with an unknown server cannot be automatically verified by URO+.\n'; confirmMsg += 'It is recommended that you manually load WME from each server (World, USA/Canada and Israel) to give URO+ a chance of locating these cameras.\n'; confirmMsg += 'If the cameras then continue to show up as an unknown server, it is safe to delete them...\n\n'; confirmMsg += 'Do you still wish to proceed with deleting all unknown server cameras?'; if(confirm(confirmMsg) == true) { for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--) { if(uroCamWatchObjects[camidx].server == '??') { uroShownFID = uroCamWatchObjects[camidx].fid; uroRemoveCamFromWatchList(); } } } } function uroRescanCamWatchList() { for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++) { uroCamWatchObjects[camidx].loaded = false; } uroGetCurrentCamWatchListObjects(); uroOWLUpdateHTML(); } function uroGotoCam() { var camidx = this.id.substr(13); var camPos = new OpenLayers.LonLat(); camPos.lon = uroCamWatchObjects[camidx].watch.lon; camPos.lat = uroCamWatchObjects[camidx].watch.lat; W.map.setCenter(camPos,4); W.map.camerasLayer.setVisibility(true); return false; } function uroSetCamGroup() { var camidx = this.id.substr(13); return false; } // Segment Functions function uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn) { if(left != null) left = uroTruncate(uroTypeCast(left)); if(right != null) right = uroTruncate(uroTypeCast(right)); if(bottom != null) bottom = uroTruncate(uroTypeCast(bottom)); if(top != null) top = uroTruncate(uroTypeCast(top)); if(fromNode != null) fromNode = uroTypeCast(fromNode); if(toNode != null) toNode = uroTypeCast(toNode); if(fwdDir != null) fwdDir = uroTypeCast(fwdDir); if(revDir != null) revDir = uroTypeCast(revDir); if(length != null) length = uroTypeCast(length); if(level != null) level = uroTypeCast(level); if(rank != null) rank = uroTypeCast(rank); if(roadType != null) roadType = uroTypeCast(roadType); if(updatedOn != null) updatedOn = uroTypeCast(updatedOn); this.left = left; this.right = right; this.bottom = bottom; this.top = top; this.fromNode = fromNode; this.toNode = toNode; this.fwdDir = fwdDir; this.revDir = revDir; this.length = length; this.level = level; this.rank = rank; this.roadType = roadType; this.updatedOn = updatedOn; } function uroSegWatchObj(persistent, fid, left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn, groupID, server) { fid = uroTypeCast(fid); groupID = uroTypeCast(groupID); if(typeof persistent == "string") persistent = (persistent == "true"); this.fid = fid; this.persistent = persistent; this.loaded = false; this.server = server; this.groupID = groupID; this.watch = new uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn); this.current = new uroSegWatchObjCheckProps(null, null, null, null, null, null, null, null, null, null, null, null, null); } function uroSegDataChanged(idx) { segObj = uroSegWatchObjects[idx]; if(segObj.loaded == false) return false; if(segObj.current.left != segObj.watch.left) return true; if(segObj.current.right != segObj.watch.right) return true; if(segObj.current.bottom != segObj.watch.bottom) return true; if(segObj.current.top != segObj.watch.top) return true; if(segObj.current.fromNode != segObj.watch.fromNode) return true; if(segObj.current.toNode != segObj.watch.toNode) return true; if(segObj.current.fwdDir != segObj.watch.fwdDir) return true; if(segObj.current.revDir != segObj.watch.revDir) return true; if(segObj.current.length != segObj.watch.length) return true; if(segObj.current.level != segObj.watch.level) return true; if(segObj.current.rank != segObj.watch.rank) return true; if(segObj.current.roadType != segObj.watch.roadType) return true; if(segObj.current.updatedOn != segObj.watch.updatedOn) return true; return false; } function uroIsSegOnWatchList(fid) { for(var loop=0;loop<uroSegWatchObjects.length;loop++) { if(uroSegWatchObjects[loop].fid == fid) return loop; } return -1; } function uroAddCurrentSegWatchData(idx, left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn, server) { segObj = uroSegWatchObjects[idx]; segObj.loaded = true; segObj.server = server; segObj.current = new uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn); return(uroSegDataChanged(idx)); } function uroClearSegWatchList() { if(confirm('Removing all segments from the OWL cannot be undone\nAre you sure you want to do this?') == true) { uroSegWatchObjects = new Array(); uroOWLUpdateHTML(); } } function uroAddUpdateSegWatchList() { selectedCount = W.selectionManager.selectedItems.length; if(selectedCount == 0) { return; } for(var loop=0;loop < selectedCount; loop++) { var segObj = W.selectionManager.selectedItems[loop].model.attributes; var fid = segObj.id; var idx = uroIsSegOnWatchList(fid); if(idx != -1) { uroSegWatchObjects[idx].watch = new uroSegWatchObjCheckProps(segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn); uroAddLog('updated watchlist details for segment '+fid); } else { uroSegWatchObjects.push(new uroSegWatchObj(true, fid, segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn, 0, W.location.code)); uroAddCurrentSegWatchData(uroSegWatchObjects.length-1, segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn, W.location.code); uroAddLog('added segment '+fid+' to watchlist'); } } //uroOWLUpdateHTML(); } function uroRemoveSegFromWatchList() { selectedCount = W.selectionManager.selectedItems.length; if(selectedCount == 0) { return; } for(var loop=0;loop < selectedCount; loop++) { var fid = W.selectionManager.selectedItems[loop].model.attributes.id; var idx = uroIsSegOnWatchList(fid); if(idx != -1) { uroSegWatchObjects.splice(idx,1); uroAddLog('removed segment '+fid+' from watchlist'); } } //uroOWLUpdateHTML(); } function uroRetrieveSegments(lat, lon) { var pos = new OpenLayers.LonLat(); var changed = false; pos.lon = lon; pos.lat = lat; pos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")); var URL = 'https://' + document.location.host; URL += Waze.Config.api_base; URL += '/Features?roadTypes=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16%2C17%2C18%2C19%2C20%2C21'; URL += '&bbox='; var latl = pos.lat - 0.25; var latu = pos.lat + 0.25; var lonl = pos.lon - 0.25; var lonr = pos.lon + 0.25; URL += lonl+','+latl+','+lonr+','+latu; URL += '&language=en'; uroAddLog('retrieving segment data around '+pos.lon+','+pos.lat); req = new XMLHttpRequest(); req.open('GET',URL,false); try { req.send(); uroAddLog('response '+req.status+' received'); if (req.status === 200) { data = JSON.parse(req.responseText); for(var idx = 0; idx < data.segments.objects.length; idx++) { obj = data.segments.objects[idx]; var listIdx = uroIsSegOnWatchList(obj.id); if(listIdx != -1) { //pos.lon = obj.geometry.coordinates[0]; //pos.lat = obj.geometry.coordinates[1]; //pos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913")); //camPos.lon = uroTruncate(camPos.lon); //camPos.lat = uroTruncate(camPos.lat); //camChanged |= uroAddCurrentCamWatchData(listIdx, camPos.lat, camPos.lon, camObj.type, camObj.azymuth, camObj.speed, camObj.validated, W.location.code); } else if(obj.validated == false) { } } } else { uroAddLog('request failed (status != 200)'); } } catch(err) { uroAddLog('segment load request failed (exception '+err+' caught)'); } return changed; } function uroGetCurrentSegWatchListObjects() { var segChanged = false; var segsChanged = new Array(); var segsDeleted = new Array(); for(var idx=0;idx<uroSegWatchObjects.length;idx++) { segObj = uroSegWatchObjects[idx]; if((segObj.loaded == false) && ((segObj.server == W.location.code) || (segObj.server == '??'))) { var segLat = (segObj.watch.top + segObj.watch.bottom) / 2; var segLon = (segObj.watch.right + segObj.watch.left) / 2; if(typeof W.model.segments.objects[segObj.fid] == 'object') { if(W.model.segments.objects[segObj.fid].state != "Delete") { wazeObj = W.model.segments.objects[segObj.fid]; segChanged |= uroAddCurrentSegWatchData(idx, wazeObj.geometry.bounds.left, wazeObj.geometry.bounds.right, wazeObj.geometry.bounds.bottom, wazeObj.geometry.bounds.top, wazeObj.fromNodeID, wazeObj.toNodeID, wazeObj.fwdDirection, wazeObj.revDirection, wazeObj.length, wazeObj.level, wazeObj.rank, wazeObj.roadType, wazeObj.updatedOn, W.location.code); } else { segChanged |= uroRetrieveSegments(segLat, segLon); } } else { segChanged |= uroRetrieveSegments(segLat, segLon); } } } if(segChanged) { for(var idx=0;idx<uroSegWatchObjects.length;idx++) { if(uroSegDataChanged(idx)) { segsChanged.push(uroSegWatchObjects[idx]); } } } for(var idx=0;idx<uroSegWatchObjects.length;idx++) { segObj = uroSegWatchObjects[idx]; if((segObj.loaded == false) && (segObj.server == W.location.code)) { segsDeleted.push(segObj); } } if((segsChanged.length > 0) || (segsDeleted.length > 0)) { var alertStr = 'Segment WatchList Alert!!!\r\n'; for(var idx=0;idx<segsChanged.length;idx++) { alertStr += 'Segment ID '+segsChanged[idx].fid+' in group "'+uroFindCWLGroupByIdx(segsChanged[idx].groupID)+'" has been changed\r\n'; } for(var idx=0;idx<segsDeleted.length;idx++) { alertStr += 'Segment ID '+segsDeleted[idx].fid+' in group "'+uroFindCWLGroupByIdx(segsDeleted[idx].groupID)+'" has been deleted\r\n'; } alert(alertStr); } } // Places Functions function uroPlaceWatchObjCheckProps(left, right, bottom, top, name, imageCount, residential, updatedOn) { if(left != null) left = uroTruncate(uroTypeCast(left)); if(right != null) right = uroTruncate(uroTypeCast(right)); if(bottom != null) bottom = uroTruncate(uroTypeCast(bottom)); if(top != null) top = uroTruncate(uroTypeCast(top)); if(imageCount != null) imageCount = uroTypeCast(imageCount); if(typeof residential == "string") residential = (residential == "true"); if(updatedOn != null) updatedOn = uroTypeCast(updatedOn); this.left = left; this.right = right; this.bottom = bottom; this.top = top; this.name = name; this.imageCount = imageCount; this.residential = residential; this.updatedOn = updatedOn; } function uroPlaceWatchObj(persistent, fid, left, right, bottom, top, imageCount, name, residential, updatedOn, groupID, server) { groupID = uroTypeCast(groupID); if(typeof persistent == "string") persistent = (persistent == "true"); this.fid = fid; this.persistent = persistent; this.loaded = false; this.server = server; this.groupID = groupID; this.watch = new uroPlaceWatchObjCheckProps(left, right, bottom, top, name, imageCount, residential, updatedOn); this.current = new uroPlaceWatchObjCheckProps(null, null, null, null, null, null, null, null); } function uroPlaceDataChanged(idx) { placeObj = uroPlaceWatchObjects[idx]; if(placeObj.loaded == false) return false; if(placeObj.current.left != placeObj.watch.left) return true; if(placeObj.current.right != placeObj.watch.right) return true; if(placeObj.current.bottom != placeObj.watch.bottom) return true; if(placeObj.current.top != placeObj.watch.top) return true; if(placeObj.current.name != placeObj.watch.name) return true; if(placeObj.current.imageCount != placeObj.watch.imageCount) return true; if(placeObj.current.residential != placeObj.watch.residential) return true; if(placeObj.current.updatedOn != placeObj.watch.updatedOn) return true; return false; } function uroIsPlaceOnWatchList(fid) { for(var loop=0;loop<uroPlaceWatchObjects.length;loop++) { if(uroPlaceWatchObjects[loop].fid == fid) return loop; } return -1; } function uroClearPlaceWatchList() { if(confirm('Removing all places from the OWL cannot be undone\nAre you sure you want to do this?') == true) { uroPlaceWatchObjects = new Array(); uroOWLUpdateHTML(); } } function uroTruncate(val) { if(val == null) return val; if(val < 0) return Math.ceil(val); return Math.floor(val); } function uroHighlightCWLEntry() { this.style.backgroundColor = '#FFFFAA'; return false; } function uroUnhighlightCWLEntry() { var camidx = this.id.substr(8); var changed = uroCamDataChanged(camidx); var deleted = (uroCamWatchObjects[camidx].loaded == false); if(uroCamWatchObjects[camidx].server != W.location.code) { if(uroCamWatchObjects[camidx].server == '??') this.style.backgroundColor = '#A0A0A0'; else this.style.backgroundColor = '#AAFFAA'; } else if(changed) this.style.backgroundColor = '#AAAAFF'; else if(deleted) this.style.backgroundColor = '#FFAAAA'; else this.style.backgroundColor = '#FFFFFF'; return false; } function uroCWLIconHighlight() { iconType = this.id.substr(11,1); this.src = uroIcons[iconType][0]; return false; } function uroCWLIconLowlight() { iconType = this.id.substr(11,1); this.src = uroIcons[iconType][1]; return false; } function uroRemoveFromCWL() { uroShownFID = uroCamWatchObjects[this.id.substr(18)].fid; uroRemoveCamFromWatchList(); } function uroSetCamGroups() { for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++) { camObj = uroCamWatchObjects[camidx]; camGroup = parseInt(uroGetElmValue("_uroGroupSelect-"+camidx)); camObj.groupID = camGroup; } } function uroPopulateCWLGroupSelect() { var selector = document.getElementById('_uroCWLGroupSelect'); while(selector.options.length > 0) { selector.options.remove(0); } for(var loop=0;loop<uroCWLGroups.length;loop++) { var groupObj = uroCWLGroups[loop]; if(groupObj.groupID != -1) { selector.options.add(new Option(groupObj.groupName,groupObj.groupID)); } } } function uroGetNextCWLGroupID() { var nextID = 1; for(var loop=0;loop<uroCWLGroups.length;loop++) { if(uroCWLGroups[loop].groupID >= nextID) { nextID = uroCWLGroups[loop].groupID + 1; } } return nextID; } function uroFindCWLGroupByName(groupName) { var groupID = -1; for(var loop=0;loop<uroCWLGroups.length;loop++) { if((uroCWLGroups[loop].groupName == groupName) && (uroCWLGroups[loop].groupID != -1)) { groupID = uroCWLGroups[loop].groupID; break; } } return groupID; } function uroFindCWLGroupByIdx(groupIdx) { var groupName = ''; for(var loop=0;loop<uroCWLGroups.length;loop++) { if(uroCWLGroups[loop].groupID == groupIdx) { groupName = uroCWLGroups[loop].groupName; break; } } return groupName; } function uroAddCWLGroup() { var groupID = uroGetNextCWLGroupID(); var groupName = uroGetElmValue('_uroCWLGroupEntry'); if(uroFindCWLGroupByName(groupName) == -1) { uroCWLGroups.push(new uroOWLGroupObj(groupID,groupName,false)); uroPopulateCWLGroupSelect(); } } function uroRemoveCWLGroup() { var selector = document.getElementById('_uroCWLGroupSelect'); var groupID = parseInt(selector.selectedOptions[0].value); if(groupID == 0) return false; // prevent deletion of the default group for(var loop=0;loop<uroCamWatchObjects.length;loop++) { var cwObj = uroCamWatchObjects[loop]; if(cwObj.groupID == groupID) { cwObj.groupID = 0; } } for(var loop=0;loop<uroCWLGroups.length;loop++) { var groupObj = uroCWLGroups[loop]; if(groupObj.groupID == groupID) { groupObj.groupID = -1; } } uroOWLUpdateHTML(); } function uroAssignCameraToGroup() { var camidx = this.id.substr(13); var selector = document.getElementById('_uroCWLGroupSelect'); uroCamWatchObjects[camidx].groupID = parseInt(selector.selectedOptions[0].value); uroOWLUpdateHTML(); return false; } function uroAddBtnEvl(btnID, evlType, evlFunction) { btnObj = document.getElementById(btnID); if(btnObj != null) { btnObj.addEventListener(evlType, evlFunction, true); } } function uroCWLGroupCollapseExpand() { var groupidx = this.id.substr(18); if(uroCWLGroups[groupidx].groupCollapsed == true) uroCWLGroups[groupidx].groupCollapsed = false; else uroCWLGroups[groupidx].groupCollapsed = true; uroOWLUpdateHTML(); return false; } function uroOWLUpdateHTML() { var camTypes = new Array("","","Speed", "Dummy", "Red Light"); var selectedGroup = 0; iHTML = ''; if(document.getElementById('_uroCWLGroupSelect') != null) { selectedGroup = document.getElementById('_uroCWLGroupSelect').selectedIndex; } iHTML = '<br><b>Camera Watchlist:</b><br><br>'; iHTML += '<div id="_uroCWLCamList" style="height:65%;overflow:auto;">'; for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++) { var groupObj = uroCWLGroups[groupidx]; iHTML += '<div id="_uroCWLGroup-'+groupidx+'">'; if(groupObj.groupCollapsed == true) { iHTML += '<img src="'+uroIcons[0][1]+'" id="_uroCWLGroupState-'+groupidx+'">'; } else { iHTML += '<img src="'+uroIcons[0][0]+'" id="_uroCWLGroupState-'+groupidx+'">'; } iHTML += '<b>'+groupObj.groupName+'</b><br>'; groupObj.groupCount = 0; for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++) { camObj = uroCamWatchObjects[camidx]; if(camObj.groupID == groupObj.groupID) { groupObj.groupCount++; var changed = uroCamDataChanged(camidx); var deleted = (camObj.loaded == false); iHTML += '<div id="_uroCWL-'+camidx+'" style="padding:3px;border-width:2px;border-style:solid;border-color:#FFFFFF;background-color:'; if(camObj.server != W.location.code) { if(camObj.server == '??') iHTML += '#A0A0A0;'; else iHTML += '#AAFFAA;'; } else if(changed) iHTML += '#AAAAFF;'; else if(deleted) iHTML += '#FFAAAA;'; else iHTML += '#FFFFFF;'; if(groupObj.groupCollapsed == true) iHTML += 'display:none;">'; else iHTML += 'display:block;">'; iHTML += 'ID: '+camObj.fid; iHTML += ' ('+camObj.server+')'; iHTML += ' Type: '+camTypes[camObj.watch.type]; if(camObj.server != W.location.code) { if(camObj.server == '??') { iHTML += '<br><i>Unknown server</i>'; } else { iHTML += '<br><i>Not on this server</i>'; } } else if(deleted) { iHTML += '<br>DELETED'; } else if(changed) { if(camObj.current.type != camObj.watch.type) { iHTML += '<br> Type changed'; iHTML += ' ('+camObj.watch.type+' to '+camObj.current.type+')'; } if(camObj.current.azymuth != camObj.watch.azymuth) { iHTML += '<br> Azimuth changed'; iHTML += ' ('+camObj.watch.azymuth+' to '+camObj.current.azymuth+')'; } if(camObj.current.speed != camObj.watch.speed) { iHTML += '<br> Speed changed'; iHTML += ' ('+camObj.watch.speed+' to '+camObj.current.speed+')'; } if(camObj.current.validated != camObj.watch.validated) { iHTML += '<br> Approval state changed'; iHTML += ' ('+camObj.watch.validated+' to '+camObj.current.validated+')'; } if(camObj.current.lat != camObj.watch.lat) { iHTML += '<br> Latitude changed'; iHTML += ' ('+camObj.watch.lat+' to '+camObj.current.lat+')'; } if(camObj.current.lon != camObj.watch.lon) { iHTML += '<br> Longitude changed'; iHTML += ' ('+camObj.watch.lon+' to '+camObj.current.lon+')'; } } if(camObj.server == W.location.code) { if(deleted == false) { iHTML += ' <img id="_uroCWLIcon1-'+camidx+'" src="'+uroIcons[1][1]+'">'; } iHTML += ' <img id="_uroCWLIcon2-'+camidx+'" src="'+uroIcons[2][1]+'">'; } iHTML += '</div>'; } } iHTML += '</div>'; } iHTML += '</div><div id="_uroCWLControls">'; iHTML += '<hr>Group control:<br>'; iHTML += '<select id="_uroCWLGroupSelect" style="width:40%;height:22px;"></select> <input type="button" id="_btnCWLGroupDel" value="Delete group"><br>'; iHTML += '<input type="text" id="_uroCWLGroupEntry" style="width:40%;height:22px;"> <input type="button" id="_btnCWLGroupAdd" value="Add group">'; iHTML += '<br><input type="button" id="_btnRescanCamWatchList" value="Refresh Camera Data"><br><br>'; iHTML += '<b>Remove cameras from OWL:</b><br>'; iHTML += '<input type="button" id="_btnRemoveDeletedCameras" value="Deleted"> '; iHTML += '<input type="button" id="_btnRemoveUnknownServerCameras" value="Unknown Server"> '; iHTML += '<input type="button" id="_btnClearCamWatchList" value="ALL Cameras">'; iHTML += '</div>'; uroOWL.innerHTML = iHTML; for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++) { document.getElementById("_uroCWL-"+camidx).onmouseover = uroHighlightCWLEntry; document.getElementById("_uroCWL-"+camidx).onmouseleave = uroUnhighlightCWLEntry; if(uroCamWatchObjects[camidx].server == W.location.code) { var icon1 = document.getElementById("_uroCWLIcon1-"+camidx); var icon2 = document.getElementById("_uroCWLIcon2-"+camidx); if(icon1 != null) { icon1.onmouseover = uroCWLIconHighlight; icon1.onmouseleave = uroCWLIconLowlight; icon1.onclick = uroAssignCameraToGroup; } if(icon2 != null) { icon2.onmouseover = uroCWLIconHighlight; icon2.onmouseleave = uroCWLIconLowlight; icon2.onclick = uroGotoCam; } } } uroAddBtnEvl('_btnClearCamWatchList', 'click', uroClearCamWatchList); uroAddBtnEvl('_btnRemoveDeletedCameras', 'click', uroClearDeletedCameras); uroAddBtnEvl('_btnRemoveUnknownServerCameras', 'click', uroClearUnknownServerCameras); uroAddBtnEvl('_btnRescanCamWatchList', 'click', uroRescanCamWatchList); uroAddBtnEvl('_btnCWLGroupDel', 'click', uroRemoveCWLGroup); uroAddBtnEvl('_btnCWLGroupAdd', 'click', uroAddCWLGroup); if(document.getElementById('_uroCWLGroupSelect') != null) { uroAddLog('populating CWL group list'); uroPopulateCWLGroupSelect(); var selector = document.getElementById('_uroCWLGroupSelect'); if(selectedGroup >= selector.length) { selectedGroup = 0; } selector.selectedIndex = selectedGroup; } for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++) { if(uroCWLGroups[groupidx].groupCount == 0) { uroSetStyleDisplay('_uroCWLGroup-'+groupidx,'none'); } else { uroSetOnClick('_uroCWLGroupState-'+groupidx,uroCWLGroupCollapseExpand); } } } // -------------------------------------------------------------------------------------------------------------------- // END OF WATCHLIST STUFF // -------------------------------------------------------------------------------------------------------------------- function uroIsOnIgnoreList(fid) { if(sessionStorage.UROverview_FID_IgnoreList.indexOf('fid:'+fid) == -1) return false; else return true; } function uroEnableIgnoreListControls() { var btnState = "visible"; if(sessionStorage.UROverview_FID_IgnoreList == '') { btnState = "hidden"; } document.getElementById('_btnUndoLastHide').style.visibility = btnState; document.getElementById('_btnClearSessionHides').style.visibility = btnState; uroFilterItems(); } function uroAddToIgnoreList() { if(!uroIsOnIgnoreList(uroShownFID)) { sessionStorage.UROverview_FID_IgnoreList += 'fid:'+uroShownFID; uroAddLog('added fid '+uroShownFID+' to ignore list'); uroAddLog(sessionStorage.UROverview_FID_IgnoreList); uroDiv.style.visibility = 'hidden'; uroEnableIgnoreListControls(); W.map.events.register("mousemove", null, uroFilterItemsOnMove); } return false; } function uroRemoveFromIgnoreList(fid) { var ignorelist = sessionStorage.UROverview_FID_IgnoreList; var fidpos = ignorelist.indexOf('fid:'+fid); if(fidpos != -1) { var preFID = ignorelist.slice(0,fidpos); ignorelist = ignorelist.slice(fidpos+1); fidpos = ignorelist.indexOf('fid:'); if(fidpos == -1) ignorelist = ''; else ignorelist = ignorelist.slice(fidpos); sessionStorage.UROverview_FID_IgnoreList = preFID + ignorelist; uroAddLog('removed fid '+fid+' from ignore list'); uroAddLog(sessionStorage.UROverview_FID_IgnoreList); uroEnableIgnoreListControls(); } } function uroRemoveLastAddedIgnore() { var ignorelist = sessionStorage.UROverview_FID_IgnoreList; var fidpos = ignorelist.lastIndexOf('fid:'); if(fidpos != -1) { ignorelist = ignorelist.slice(0,fidpos); sessionStorage.UROverview_FID_IgnoreList = ignorelist; uroAddLog('removed last fid from ignore list'); uroAddLog(sessionStorage.UROverview_FID_IgnoreList); uroEnableIgnoreListControls(); } } function uroRemoveAllIgnores() { sessionStorage.UROverview_FID_IgnoreList = ''; uroEnableIgnoreListControls(); } function uroKeywordPresent(desc, keyword) { if(uroGetCBChecked('_cbCaseInsensitive') == true) re = RegExp(keyword,'i'); else re = RegExp(keyword); if(desc.search(re) == -1) return false; else return true; } function uroClickify(desc) { var linkStartPos = desc.indexOf('http://'); if(linkStartPos == -1) linkStartPos = desc.indexOf('https://'); if(linkStartPos != -1) { var descPreLink = desc.slice(0,linkStartPos); var descURL = desc.slice(linkStartPos); var linkEndPos = descURL.indexOf(' '); var descPostLink = ''; if(linkEndPos != -1) { descPostLink = descURL.slice(linkEndPos); descURL = descURL.slice(0,linkEndPos); } var linkTarget = ''; if(descURL.indexOf('cryosphere') != -1) linkTarget = '_cryosphere'; else if(descURL.indexOf('waze.com') != -1) linkTarget = '_wazeUR'; desc = descPreLink + '<a target="'+linkTarget+'" href="'+descURL+'">here</a>' + descPostLink; } return desc; } function uroRefreshUpdateRequestSessions() { for (var urID in W.model.mapUpdateRequests.objects) { var reqPos = uroRequestedURSessionIDs.indexOf(urID); var pendPos = uroPendingURSessionIDs.indexOf(urID); if(W.model.updateRequestSessions.objects[urID] == null) { if((reqPos == -1) && (pendPos == -1)) { uroPendingURSessionIDs.push(urID); } } else { if(reqPos != -1) { uroRequestedURSessionIDs.splice(reqPos,1); } if(pendPos != -1) { uroPendingURSessionIDs.splice(pendPos,1); } } } var idList = []; while((idList.length < 500) && (uroPendingURSessionIDs.length)) { var id = uroPendingURSessionIDs.pop(); idList.push(id); uroRequestedURSessionIDs.push(id); } if(idList.length > 0) { uroAddLog('grabbing updateRequestSessions with IDs '+idList); W.model.updateRequestSessions.get(idList); } if((uroPendingURSessionIDs.length) || (uroRequestedURSessionIDs.length)) { setTimeout(uroRefreshUpdateRequestSessions,10); } } function uroURHasMyComments(fid) { var nComments = W.model.updateRequestSessions.objects[fid].comments.length; if(nComments == 0) return false; for(var cidx=0; cidx<nComments; cidx++) { if(W.model.updateRequestSessions.objects[fid].comments[cidx].userID == uroUserID) return true; } return false; } function uroACMObj(urID, customType, hasMyComments, nComments) { this.urID = urID; this.customType = customType; this.hasMyComments = hasMyComments; this.nComments = nComments; } function uroAddCustomMarkers(urID, customType, hasMyComments, nComments) { var useCustomMarker = false; if(customType == 0) useCustomMarker = (uroGetCBChecked('_cbCustomRoadworksMarkers')); else if(customType == 1) useCustomMarker = (uroGetCBChecked('_cbCustomConstructionMarkers')); else if(customType == 2) useCustomMarker = (uroGetCBChecked('_cbCustomClosuresMarkers')); else if(customType == 3) useCustomMarker = (uroGetCBChecked('_cbCustomEventsMarkers')); else if(customType == 4) useCustomMarker = (uroGetCBChecked('_cbCustomNotesMarkers')); if(!useCustomMarker) customType = -1; uroCustomMarkerList.push(new uroACMObj(urID, customType, hasMyComments, nComments)); } function uroRenderCustomMarkers() { var markersToAdd = uroCustomMarkerList.length; var useDefaultConvoMarker = false; var addCommentCount = false; if((uroGetCBChecked('_cbNativeConvoMarkers')) && (uroBetaEditor == false)) useDefaultConvoMarker = true; if((uroGetCBChecked('_cbNativeBetaConvoMarkers')) && (uroBetaEditor == true)) useDefaultConvoMarker = true; if(uroGetCBChecked('_cbCommentCount')) addCommentCount = true; var divElem = document.getElementById(W.map.updateRequestLayer.id); if(divElem.childNodes.length > 0) { for(var objIdx = 0; objIdx < uroCustomMarkerList.length; objIdx++) { var urID = uroCustomMarkerList[objIdx].urID; var customType = uroCustomMarkerList[objIdx].customType; var hasMyComments = uroCustomMarkerList[objIdx].hasMyComments; var nComments = uroCustomMarkerList[objIdx].nComments; if(nComments > 0) { var elmID = "commentCount_"+urID; if(addCommentCount) { // add a new comment count bubble if the UR doesn't already have one if(document.getElementById(elmID) == null) { var newSpan = '<span id="'+elmID+'" style="position:absolute;top:-9px;left:-11px;pointer-events:none;z-index:1">'; // define the comment-count holding span within the span used to hold the empty bubble image, and before the image is // added to the HTML, to avoid z-indexing issues when adjacent comment count bubbles are overlapped... newSpan += '<span id="'+elmID+"_inner"+'" style="position:absolute;top:4px;left:11px;font-size:11px;;pointer-events:none"></span>'; newSpan += '<img src="'+uroMarkers[0]+'">'; newSpan += '</span>'; W.map.updateRequestLayer.markers[urID].icon.$div.prepend(newSpan); } var styleLeft; if(nComments < 10) styleLeft = '11px'; else if(nComments < 100) styleLeft = '8px'; else styleLeft = '5px'; document.getElementById(elmID+"_inner").innerHTML = nComments; document.getElementById(elmID+"_inner").style.left = styleLeft; } else { // remove comment count bubble from this UR marker if one has previously been // added and the user has now disabled the option... if(document.getElementById(elmID) != null) { document.getElementById(elmID).remove(); document.getElementById(elmID+"_inner").remove(); } } var elmID = "convoMarker_"+urID; if(useDefaultConvoMarker == false) { if(document.getElementById(elmID) == null) { // z-index needs to be set to 1 here so that when a new comment is added to a UR and WME re-renders the native // conversation marker, the custom marker remains on top... var newSpan = '<span id="'+elmID+'" style="position:absolute;top:-9px;left:18px;pointer-events:none;z-index:1">'; if(hasMyComments) newSpan += '<img src="'+uroMarkers[2]+'">'; else newSpan += '<img src="'+uroMarkers[1]+'">'; newSpan += '</span>'; W.map.updateRequestLayer.markers[urID].icon.imageDiv.classList.remove("has-comments") W.map.updateRequestLayer.markers[urID].icon.$div.prepend(newSpan); } } else { // remove custom conversation marker from this UR if one has previously been // added and the user has now disabled this option if(document.getElementById(elmID) != null) { document.getElementById(elmID).remove(); } W.map.updateRequestLayer.markers[urID].icon.imageDiv.classList.add("has-comments") } } var elmID = "customMarker_"+urID; if(customType != -1) { if(document.getElementById(elmID) == null) { var newSpan = '<span id="'+elmID+'" style="position:absolute;pointer-events:none;"></span>'; W.map.updateRequestLayer.markers[urID].icon.$div.prepend(newSpan); } customType = uroGetCustomMarkerIdx(customType); if(W.model.updateRequestSessions.objects[urID] != undefined) { if(W.model.updateRequestSessions.objects[urID].open == false) customType += 1; } var customMarker = '<img src="'+uroIcons[customType][0]+'">'; document.getElementById(elmID).innerHTML = customMarker; } else { if(document.getElementById(elmID) != null) { document.getElementById(elmID).remove(); } } } } } function uroChangeCustomMarkers(urID,isHighlighted,customType) { if(document.getElementById('customMarker_'+urID) != null) { if(W.model.updateRequestSessions.objects[urID].open == false) customType += 1; if(isHighlighted == true) { document.getElementById('customMarker_'+urID).innerHTML = '<img src="'+uroIcons[customType][1]+'">'; } else { document.getElementById('customMarker_'+urID).innerHTML = '<img src="'+uroIcons[customType][0]+'">'; } } } function uroFilterPlaces() { if(uroFilterPreamble() == false) return; if(uroPlaceSelected == true) return; if(uroGetCBChecked('_cbDisablePlacesFiltering') == true) return; var filterCats = []; for(var i=0; i<W.Config.venues.categories.length; i++) { parentCategory = W.Config.venues.categories[i]; if(uroGetCBChecked('_cbPlacesFilter-'+parentCategory) == true) { filterCats.push(parentCategory); for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++) { subCategory = W.Config.venues.subcategories[parentCategory][ii]; filterCats.push(subCategory); } } else { for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++) { subCategory = W.Config.venues.subcategories[parentCategory][ii]; if(uroGetCBChecked('_cbPlacesFilter-'+subCategory) == true) { filterCats.push(subCategory); } } } } for(var v=0; v<W.map.landmarkLayer.features.length; v++) { placeStyle = 'visible'; lmObj = W.map.landmarkLayer.features[v]; // when an area place is selected, the drag points for editing the place outline now get added as objects into W.map.landmarkLayer.features, // however none of these objects have the .model property - we must therefore check each entry in features[] to see if it has .model before // attempting to filter it... if(lmObj.model != undefined) { if(lmObj.model.attributes.id < 0) { // don't apply filtering to newly-created places - this allows the user to leave their filtering settings unchanged whilst // adding a new place which, once saved, would then be hidden... break; } editDate = lmObj.model.attributes.updatedOn; if(editDate == undefined) { // where a place has never been edited since its creation, use the creation date instead... editDate = lmObj.model.attributes.createdOn; } if(editDate != undefined) { editDaysAgo = uroDateToDays(editDate); if(uroGetCBChecked('_cbPlaceFilterEditedLessThan')) { if(editDaysAgo < document.getElementById('_inputFilterPlaceEditMinDays').value) { placeStyle = 'hidden'; } } if(uroGetCBChecked('_cbPlaceFilterEditedMoreThan')) { if(editDaysAgo > document.getElementById('_inputFilterPlaceEditMaxDays').value) { placeStyle = 'hidden'; } } } if(placeStyle == 'visible') { lockLevel = lmObj.model.attributes.lockRank; if ((uroGetCBChecked('_cbHidePlacesL0')) && (lockLevel == 0)) placeStyle = 'hidden'; if ((uroGetCBChecked('_cbHidePlacesL1')) && (lockLevel == 1)) placeStyle = 'hidden'; if ((uroGetCBChecked('_cbHidePlacesL2')) && (lockLevel == 2)) placeStyle = 'hidden'; if ((uroGetCBChecked('_cbHidePlacesL3')) && (lockLevel == 3)) placeStyle = 'hidden'; if ((uroGetCBChecked('_cbHidePlacesL4')) && (lockLevel == 4)) placeStyle = 'hidden'; if ((uroGetCBChecked('_cbHidePlacesL5')) && (lockLevel == 5)) placeStyle = 'hidden'; } if(placeStyle == 'visible') { nPhotos = 0; for(var loop=0; loop<lmObj.model.attributes.images.length; loop++) { if(lmObj.model.attributes.images[loop].attributes.approved) nPhotos++; } if((uroGetCBChecked('_cbHideNoPhotoPlaces')) && (nPhotos == 0)) placeStyle = 'hidden'; if((uroGetCBChecked('_cbHidePhotoPlaces')) && (nPhotos != 0)) placeStyle = 'hidden'; } if(placeStyle == 'visible') { if((lmObj.model.attributes.residential == true) && (uroGetCBChecked('_cbFilterPrivatePlaces') == true)) { placeStyle = 'hidden'; } else { for(var cat=0; cat<filterCats.length; cat++) { if(lmObj.model.attributes.categories.contains(filterCats[cat])) { placeStyle = 'hidden'; break; } } } } } if(uroGetCBChecked('_cbInvertPlacesFilter') == true) { if(placeStyle == 'hidden') placeStyle = 'visible'; else placeStyle = 'hidden'; } geoID = W.map.landmarkLayer.features[v].geometry.id; // area places... if(document.getElementById(uroPlacesRoot).getElementsByTagName('path')[geoID] != null) { document.getElementById(uroPlacesRoot).getElementsByTagName('path')[geoID].style.visibility = placeStyle; } // point places... if(document.getElementById(uroPlacesRoot).getElementsByTagName('circle')[geoID] != null) { document.getElementById(uroPlacesRoot).getElementsByTagName('circle')[geoID].style.visibility = placeStyle; } } for(var pu in W.map.placeUpdatesLayer.markers) { puObj = W.map.placeUpdatesLayer.markers[pu]; if(W.map.placeUpdatesLayer.getVisibility() == true) { placeStyle = 'visible'; if(uroGetCBChecked('_cbFilterUneditablePlaceUpdates') == true) { if(puObj.model.attributes.permissions == 0) { placeStyle = 'hidden'; } if(W.model.loginManager.isLoggedIn()) { if(W.model.loginManager.user.rank < puObj.model.attributes.lockRank) { placeStyle = 'hidden'; } } } if(uroGetCBChecked('_cbFilterLockRankedPlaceUpdates') == true) { if(puObj.model.attributes.lockRank != 0) { placeStyle = 'hidden'; } } if(uroGetCBChecked("_cbFilterFlaggedPUR") == true) { if(puObj.icon.imageDiv.className.indexOf('flag') != -1) { placeStyle = 'hidden'; } } if(uroGetCBChecked("_cbFilterNewPlacePUR") == true) { if(puObj.icon.imageDiv.className.indexOf('add_venue') != -1) { placeStyle = 'hidden'; } } if(uroGetCBChecked("_cbFilterUpdatedDetailsPUR") == true) { if((puObj.icon.imageDiv.className.indexOf('update_venue') != -1) || (puObj.icon.imageDiv.className.indexOf('multiple') != -1)) { placeStyle = 'hidden'; } } if(uroGetCBChecked("_cbFilterNewPhotoPUR") == true) { if(puObj.icon.imageDiv.className.indexOf('add_image') != -1) { placeStyle = 'hidden'; } } if(uroGetCBChecked('_cbInvertPURFilters') == true) { if(placeStyle == 'hidden') placeStyle = 'visible'; else placeStyle = 'hidden'; } if(uroGetCBChecked('_cbEnablePURMinAgeFilter') == true) { if(uroGetPURAge(puObj.model) < uroGetElmValue('_inputPURFilterMinDays')) placeStyle = 'hidden'; } if(uroGetCBChecked('_cbEnablePURMaxAgeFilter') == true) { if(uroGetPURAge(puObj.model) > uroGetElmValue('_inputPURFilterMaxDays')) placeStyle = 'hidden'; } var purSeverity = puObj._getSeverity(); if((uroGetCBChecked('_cbPURFilterHighSeverity')) && (purSeverity == "high")) placeStyle = 'hidden'; if((uroGetCBChecked('_cbPURFilterMediumSeverity')) && (purSeverity == "medium")) placeStyle = 'hidden'; if((uroGetCBChecked('_cbPURFilterLowSeverity')) && (purSeverity == "low")) placeStyle = 'hidden'; puObj.icon.imageDiv.style.visibility = placeStyle; if(uroGetCBChecked('_cbLeavePURGeos') == false) { if(puObj.model != undefined) { if(puObj.model.geometry != undefined) { puGeo = document.getElementById(puObj.model.geometry.id); if(puGeo != null) { puGeo.style.visibility = placeStyle; } } } } } } } function uroFilterCameras() { if(uroFilterPreamble() == false) return; var camLayer = document.getElementById(uroRootContainer+'_svgRoot'); if(camLayer == null) { if(uroNullCamLayer == false) { uroAddLog('caught null camLayer'); uroNullCamLayer = true; } return; } uroNullCamLayer = false; if(uroMouseIsDown == false) W.map.camerasLayer.redraw(); for (var uroCamObj in W.model.cameras.objects) { var uroCam = W.model.cameras.objects[uroCamObj]; var uroCamStyle = 'visible'; if(W.model.users.objects[uroCam.attributes.createdBy] != null) { var uroCamCreator = W.model.users.objects[uroCam.attributes.createdBy].userName; var uroCamCreatorRank = W.model.users.objects[uroCam.attributes.createdBy].rank; } else { var uroCamCreator = ''; var uroCamCreatorRank = -1; } if(W.model.users.objects[uroCam.attributes.updatedBy] != null) { var uroCamUpdater = W.model.users.objects[uroCam.attributes.updatedBy].userName; var uroCamUpdaterRank = W.model.users.objects[uroCam.attributes.updatedBy].rank; } else { var uroCamUpdater = ''; var uroCamUpdaterRank = -1; } var uroCamApproved = uroCam.attributes.validated; var uroCamType = uroCam.attributes.type; if(uroGetCBChecked('_cbShowOnlyMyCams') == true) { if((uroUserID != uroCam.attributes.createdBy)&&(uroUserID != uroCam.attributes.updatedBy)) uroCamStyle = 'hidden'; } if((uroGetCBChecked('_cbShowWorldCams') == false) || (uroGetCBChecked('_cbShowUSACams') == false) || (uroGetCBChecked('_cbShowNonWorldCams') == false)) { var posWorld = uroCamCreator.indexOf('world_'); var posUSA = uroCamCreator.indexOf('usa_'); if((uroGetCBChecked('_cbShowWorldCams') == false) && (posWorld == 0)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbShowUSACams') == false) && (posUSA == 0)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbShowNonWorldCams') == false) && (posWorld != 0) && (posUSA != 0)) uroCamStyle = 'hidden'; } if((uroGetCBChecked('_cbShowApprovedCams') == false) || (uroGetCBChecked('_cbShowNonApprovedCams') == false)) { if((uroGetCBChecked('_cbShowApprovedCams') == false) && (uroCamApproved == true)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbShowNonApprovedCams') == false) && (uroCamApproved == false)) uroCamStyle = 'hidden'; } if((uroGetCBChecked('_cbShowNonApprovedCams') == true) && (uroCamApproved == false)) { if(((uroGetCBChecked('_cbShowOlderCreatedNonApproved') == true)) && (uroGetCameraAge(uroCam,1) <= uroGetElmValue('_inputCameraMinCreatedDays'))) uroCamStyle = 'hidden'; if(((uroGetCBChecked('_cbShowOlderUpdatedNonApproved') == true)) && (uroGetCameraAge(uroCam,0) <= uroGetElmValue('_inputCameraMinUpdatedDays'))) uroCamStyle = 'hidden'; } if((uroGetCBChecked('_cbShowSpeedCams') == false) || (uroGetCBChecked('_cbShowRedLightCams') == false) || (uroGetCBChecked('_cbShowDummyCams') == false)) { if((uroGetCBChecked('_cbShowSpeedCams') == false) && (uroCamType == 2)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbShowRedLightCams') == false) && (uroCamType == 4)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbShowDummyCams') == false) && (uroCamType == 3)) uroCamStyle = 'hidden'; } if(uroGetCBChecked('_cbShowSpeedCams') == true) { if((uroGetCBChecked('_cbShowIfMPHSpeedSet') == false) && (uroIsCameraSpeedValid(uroCam) == 1)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbShowIfNoSpeedSet') == false) && (uroIsCameraSpeedValid(uroCam) == 0)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbShowIfKPHSpeedSet') == false) && (uroIsCameraSpeedValid(uroCam) == -1)) uroCamStyle = 'hidden'; } if(uroGetCBChecked('_cbHideCreatedByMe') == true) { if(uroUserID == uroCam.attributes.createdBy) uroCamStyle = 'hidden'; } if((uroGetCBChecked('_cbHideCreatedByRank0') == true) && (uroCamCreatorRank == 0)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideCreatedByRank1') == true) && (uroCamCreatorRank == 1)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideCreatedByRank2') == true) && (uroCamCreatorRank == 2)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideCreatedByRank3') == true) && (uroCamCreatorRank == 3)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideCreatedByRank4') == true) && (uroCamCreatorRank == 4)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideCreatedByRank5') == true) && (uroCamCreatorRank == 5)) uroCamStyle = 'hidden'; if(uroGetCBChecked('_cbHideUpdatedByMe') == true) { if(uroUserID == uroCam.attributes.updatedBy) uroCamStyle = 'hidden'; } if((uroGetCBChecked('_cbHideUpdatedByRank0') == true) && (uroCamUpdaterRank == 0)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideUpdatedByRank1') == true) && (uroCamUpdaterRank == 1)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideUpdatedByRank2') == true) && (uroCamUpdaterRank == 2)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideUpdatedByRank3') == true) && (uroCamUpdaterRank == 3)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideUpdatedByRank4') == true) && (uroCamUpdaterRank == 4)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideUpdatedByRank5') == true) && (uroCamUpdaterRank == 5)) uroCamStyle = 'hidden'; if((uroGetCBChecked('_cbHideCWLCams') == true) && (uroIsCamOnWatchList(uroCam.attributes.id) != -1)) uroCamStyle = 'hidden'; var uroCamGeometryID = uroCam.geometry.id; if(camLayer.getElementById(uroCamGeometryID) != null) { var camX = parseInt(camLayer.getElementById(uroCamGeometryID).getAttribute('x')); if(uroCamStyle == "hidden") { camLayer.getElementById(uroCamGeometryID).remove(); } } } } function uroFilterURs_onObjectsChanged() { if(uroBackfilling == false) { uroURBackfill(); uroFilterURs(); } } function uroFilterURs_onObjectsAdded() { if(uroBackfilling == false) { uroURBackfill(); uroFilterURs(); } } function uroFilterURs_onObjectsRemoved() { if(uroBackfilling == false) { uroURBackfill(); uroFilterURs(); } } function uroURBackfill_GetData(lon, lat, blockSize) { lon = parseFloat(lon); lat = parseFloat(lat); blockSize = parseFloat(blockSize); uroAddLog('Backfill square '+lon+','+lat); var xmlReq = new XMLHttpRequest(); var tURL = 'https://' + document.location.host; tURL += Waze.Config.api_base; tURL += '/Features?language=en&mapUpdateRequestFilter=0'; if(uroPracticeMode == true) tURL += '&sandbox=true'; tURL += '&bbox='+(lon)+','+(lat)+','+(lon + blockSize)+','+(lat + blockSize); xmlReq.open('GET',tURL,false); try { xmlReq.send(); uroAddLog('response '+xmlReq.status+' received'); if (xmlReq.status === 200) { var tResp = JSON.parse(xmlReq.responseText); var urCount = tResp.mapUpdateRequests.objects.length; uroAddLog(urCount+' URs loaded for backfill processing'); if(urCount == 500) { uroAddLog('WARNING - backfill data may have been pre-filtered by server'); } var backfilled = 0; for(var i=0; i<urCount; i++) { var urID = tResp.mapUpdateRequests.objects[i].id; if(W.model.mapUpdateRequests.objects[urID] == undefined) { var newUR = require('Waze/Feature/Vector/UpdateRequest'); var tUR = new newUR(tResp.mapUpdateRequests.objects[i]); var tPoint = new OpenLayers.Geometry.Point(); tPoint.x = tResp.mapUpdateRequests.objects[i].geometry.coordinates[0]; tPoint.y = tResp.mapUpdateRequests.objects[i].geometry.coordinates[1]; tPoint.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913")); tUR.geometry = tPoint; W.model.mapUpdateRequests.put(tUR); backfilled++; } } uroAddLog(backfilled+' URs backfilled'); } else { uroAddLog('request failed (status != 200)'); } } catch(err) { uroAddLog('UR backfill request failed (exception '+err+' caught)'); } } function uroURBackfill() { if(uroGetCBChecked('_cbURBackfill') == false) { return; } var nativeURCount = Object.keys(W.model.mapUpdateRequests.objects).length; if(nativeURCount < 500) { return; } uroAddLog('exactly 500 URs loaded, possible server-side filtering requiring backfill...'); var subSize = 0.1; var vpWidth = W.map.getExtent().getWidth(); var vpHeight = W.map.getExtent().getHeight(); var vpCentre = W.map.getCenter(); var vpLL = new OpenLayers.LonLat(); var vpUR = new OpenLayers.LonLat(); vpLL.lon = vpCentre.lon - (vpWidth / 2); vpLL.lat = vpCentre.lat - (vpHeight / 2); vpUR.lon = vpCentre.lon + (vpWidth / 2); vpUR.lat = vpCentre.lat + (vpHeight / 2); vpLL = vpLL.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")); vpUR = vpUR.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")); vpLL.lon -= (subSize / 2); vpLL.lat -= (subSize / 2); vpUR.lon += (subSize / 2); vpUR.lat += (subSize / 2); vpLL.lon = +vpLL.lon.toFixed(1); vpLL.lat = +vpLL.lat.toFixed(1); vpUR.lon = +vpUR.lon.toFixed(1); vpUR.lat = +vpUR.lat.toFixed(1); uroBackfilling = true; for(var bfLat = vpLL.lat; bfLat <= vpUR.lat; bfLat += subSize) { for(var bfLon = vpLL.lon; bfLon <= vpUR.lon; bfLon += subSize) { uroURBackfill_GetData(bfLon, bfLat, subSize); } } uroBackfilling = false; uroFilterURs(); } function uroFilterURs() { // compatibility fix for URComments - based on code supplied by RickZabel var hasActiveURFilters = false; var urTabInputs = document.getElementById('uroCtrlURs').getElementsByTagName('input'); for(var loop = 0; loop < urTabInputs.length; loop++) { if(urTabInputs[loop].type == 'checkbox') { var ignoreCB = false; ignoreCB |= (urTabInputs[loop].id == '_cbCaseInsensitive'); ignoreCB |= (urTabInputs[loop].id == '_cbNoFilterForTaggedURs'); if((urTabInputs[loop].checked) && (ignoreCB == false)) { hasActiveURFilters = true; break; } } } sessionStorage.UROverview_hasActiveURFilters = hasActiveURFilters; if(uroFilterPreamble() == false) return; uroRefreshUpdateRequestSessions(); var selectorResolver = document.getElementById('_selectURResolverID'); var selectorCommentUser = document.getElementById('_selectURUserID'); if(uroGetCBChecked('_cbURResolverIDFilter') == false) { while(selectorResolver.options.length > 0) { selectorResolver.options.remove(0); } } if(uroGetCBChecked('_cbURUserIDFilter') == false) { while(selectorCommentUser.options.length > 0) { selectorCommentUser.options.remove(0); } } if(Object.keys(W.model.updateRequestSessions.objects).length == 0) { return; } var commenterUser = null; if(uroGetCBChecked('_cbURUserIDFilter') == true) { if(selectorCommentUser.options.length == 0) { uroUpdateUserList(); } if(selectorCommentUser.selectedOptions[0] != undefined) { commenterUser = parseInt(selectorCommentUser.selectedOptions[0].value); } } var resolverUser = null; if(uroGetCBChecked('_cbURResolverIDFilter') == true) { if(selectorResolver.options.length == 0) { uroUpdateResolverList(); } if(selectorResolver.selectedOptions[0] != undefined) { resolverUser = parseInt(selectorResolver.selectedOptions[0].value); } } uroCustomMarkerList = []; for (var urobj in W.model.mapUpdateRequests.objects) { var ureq = W.model.mapUpdateRequests.objects[urobj]; var urStyle = 'visible'; var cryosphere_link = false; var wazeauto_ur = false; var ukroadworks_ur = false; var construction_ur = false; var closure_ur = false; var event_ur = false; var note_ur = false; var hasMyComments = false; var nComments = 0; var commentDaysOld = -1; var desc = ''; if(ureq.attributes.description != null) desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, ""); var ureqID = null; if(ureq.fid == null) ureqID = ureq.attributes.id; else ureqID = ureq.fid; var customType = uroGetCustomType(ureqID); if(customType == 0) ukroadworks_ur = true; else if(customType == 1) construction_ur = true; else if(customType == 2) closure_ur = true; else if(customType == 3) event_ur = true; else if(customType == 4) note_ur = true; // check UR against current session ignore list... if(uroIsOnIgnoreList(ureqID)) urStyle = 'hidden'; // check against closed/not identified filtering if enabled... if(uroGetCBChecked('_cbFilterSolved') == true) { if(ureq.attributes.resolution == 0) urStyle = 'hidden'; } if(uroGetCBChecked('_cbFilterUnidentified') == true) { if(ureq.attributes.resolution == 1) urStyle = 'hidden'; } if((ureq.attributes.resolvedOn != null) && (uroGetCBChecked('_cbFilterClosedUR') == true)) { urStyle = 'hidden'; } if((ureq.attributes.resolvedOn == null) && (uroGetCBChecked('_cbFilterOpenUR') == true)) { urStyle = 'hidden'; } if(urStyle == 'visible') { // check UR against keyword filtering if enabled... if(uroGetCBChecked('_cbURDescriptionMustBePresent') == true) { if(desc == '') urStyle = 'hidden'; } if(uroGetCBChecked('_cbURDescriptionMustBeAbsent') == true) { if(desc != '') urStyle = 'hidden'; } if(uroGetCBChecked('_cbEnableKeywordMustBePresent') == true) { if(!uroKeywordPresent(desc,uroGetElmValue('_textKeywordPresent'))) urStyle = 'hidden'; } if(uroGetCBChecked('_cbEnableKeywordMustBeAbsent') == true) { if(uroKeywordPresent(desc,uroGetElmValue('_textKeywordAbsent'))) urStyle = 'hidden'; } } if(urStyle == 'visible') { // do age-based filtering if enabled if(uroGetCBChecked('_cbEnableMinAgeFilter') == true) { if(uroGetURAge(ureq,0) < uroGetElmValue('_inputFilterMinDays')) urStyle = 'hidden'; } if(uroGetCBChecked('_cbEnableMaxAgeFilter') == true) { if(uroGetURAge(ureq,0) > uroGetElmValue('_inputFilterMaxDays')) urStyle = 'hidden'; } } if(urStyle == 'visible') { if(resolverUser != null) { if(ureq.attributes.resolvedBy != resolverUser) urStyle = 'hidden'; } } if(urStyle == 'visible') { // do comments/following filtering if(W.model.updateRequestSessions.objects[ureqID] != null) { nComments = W.model.updateRequestSessions.objects[ureqID].comments.length; var commentDaysOld = -1; if(uroGetCBChecked('_cbEnableMinCommentsFilter') == true) { if(nComments < uroGetElmValue('_inputFilterMinComments')) urStyle = 'hidden'; } if(uroGetCBChecked('_cbEnableMaxCommentsFilter') == true) { if(nComments > uroGetElmValue('_inputFilterMaxComments')) urStyle = 'hidden'; } if(nComments > 0) { var reporterIsLastCommenter = false; if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == -1) reporterIsLastCommenter = true; if(uroGetCBChecked('_cbHideIfReporterLastCommenter') == true) { if(reporterIsLastCommenter == true) urStyle = 'hidden'; } else if(uroGetCBChecked('_cbHideIfReporterNotLastCommenter') == true) { if(reporterIsLastCommenter == false) urStyle = 'hidden'; } hasMyComments = uroURHasMyComments(ureqID); if(hasMyComments == false) { if(uroGetCBChecked('_cbHideAnyComments') == true) urStyle = 'hidden'; if(uroGetCBChecked('_cbHideIfNotLastCommenter') == true) urStyle = 'hidden'; } else { if(uroGetCBChecked('_cbHideMyComments') == true) urStyle = 'hidden'; var userIsLastCommenter = false; if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == uroUserID) userIsLastCommenter = true; if(uroGetCBChecked('_cbHideIfLastCommenter') == true) { if(userIsLastCommenter == true) urStyle = 'hidden'; } else if(uroGetCBChecked('_cbHideIfNotLastCommenter') == true) { if(userIsLastCommenter == false) urStyle = 'hidden'; } } commentDaysOld = uroGetCommentAge(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1]); if((uroGetCBChecked('_cbEnableCommentAgeFilter') == true) && (commentDaysOld != -1)) { if(uroGetElmValue('_inputFilterCommentDays') < commentDaysOld) urStyle = 'hidden'; } if((uroGetCBChecked('_cbEnableCommentAgeFilter2') == true) && (commentDaysOld != -1)) { if(uroGetElmValue('_inputFilterCommentDays2') > commentDaysOld) urStyle = 'hidden'; } if((commenterUser != null) && (urStyle != 'hidden')) { urStyle = 'hidden'; for(var cidx=0; cidx<nComments; cidx++) { if(W.model.updateRequestSessions.objects[ureqID].comments[cidx].userID == commenterUser) { urStyle = 'visible'; break; } } } } else { if(uroGetCBChecked('_cbURUserIDFilter') == true) { urStyle = 'hidden'; } } if(W.model.updateRequestSessions.objects[ureqID].isFollowing == true) { if(uroGetCBChecked('_cbHideMyFollowed') == true) urStyle = 'hidden'; } else { if(uroGetCBChecked('_cbHideMyUnfollowed') == true) urStyle = 'hidden'; } } } if(urStyle == 'visible') { // Test for Waze automatic URs before any others - these always (?) get inserted as General Error URs, // so we can't filter them by type... if(desc.indexOf('Waze Automatic:') != -1) { wazeauto_ur = true; } if(wazeauto_ur == true) { if(uroGetCBChecked('_cbFilterWazeAuto') == true) urStyle = 'hidden'; } else if(ukroadworks_ur == true) { if(uroGetCBChecked('_cbFilterRoadworks') == true) urStyle = 'hidden'; } else if(construction_ur == true) { if(uroGetCBChecked('_cbFilterConstruction') == true) urStyle = 'hidden'; } else if(closure_ur == true) { if(uroGetCBChecked('_cbFilterClosure') == true) urStyle = 'hidden'; } else if(event_ur == true) { if(uroGetCBChecked('_cbFilterEvent') == true) urStyle = 'hidden'; } else if(note_ur == true) { if(uroGetCBChecked('_cbFilterNote') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 6) { if(uroGetCBChecked('_cbFilterIncorrectTurn') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 7) { if (uroGetCBChecked('_cbFilterIncorrectAddress') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 8) { if(uroGetCBChecked('_cbFilterIncorrectRoute') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 9) { if(uroGetCBChecked('_cbFilterMissingRoundabout') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 10) { if(uroGetCBChecked('_cbFilterGeneralError') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 11) { if(uroGetCBChecked('_cbFilterTurnNotAllowed') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 12) { if(uroGetCBChecked('_cbFilterIncorrectJunction') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 13) { if(uroGetCBChecked('_cbFilterMissingBridgeOverpass') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 14) { if(uroGetCBChecked('_cbFilterWrongDrivingDirection') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 15) { if(uroGetCBChecked('_cbFilterMissingExit') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 16) { if(uroGetCBChecked('_cbFilterMissingRoad') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 18) { if(uroGetCBChecked('_cbFilterMissingLandmark') == true) urStyle = 'hidden'; } else if(ureq.attributes.type == 19) { if(uroGetCBChecked('_cbFilterBlockedRoad') == true) urStyle = 'hidden'; } else if(uroGetCBChecked('_cbFilterUndefined') == true) urStyle = 'hidden'; if(uroGetCBChecked('_cbInvertURFilter') == true) { if(urStyle == 'hidden') urStyle = 'visible'; else urStyle = 'hidden'; } } // filtering override for tagged URs if(uroGetCBChecked('_cbNoFilterForTaggedURs') == true) { if(ukroadworks_ur == true) { if(uroGetCBChecked('_cbFilterRoadworks') == false) urStyle = 'visible'; } else if(construction_ur == true) { if(uroGetCBChecked('_cbFilterConstruction') == false) urStyle = 'visible'; } else if(closure_ur == true) { if(uroGetCBChecked('_cbFilterClosure') == false) urStyle = 'visible'; } else if(event_ur == true) { if(uroGetCBChecked('_cbFilterEvent') == false) urStyle = 'visible'; } else if(note_ur == true) { if(uroGetCBChecked('_cbFilterNote') == false) urStyle = 'visible'; } } var urcFilteringIsActive = false; var urcCB = document.getElementById('URCommentsFilterEnabled'); if(urcCB != null) { if(urcCB.checked) { urcFilteringIsActive = true; } } // only touch marker visibility if we've got active filter settings, or if URComments is not // doing any filtering of its own if((hasActiveURFilters == true) || (urcFilteringIsActive == false)) { W.map.updateRequestLayer.markers[urobj].icon.imageDiv.style.visibility = urStyle; } if(urStyle != 'hidden') { var customMarkerType = -1; if(ukroadworks_ur == true) customMarkerType = 0; if(construction_ur == true) customMarkerType = 1; if(closure_ur == true) customMarkerType = 2; if(event_ur == true) customMarkerType = 3; if(note_ur == true) customMarkerType = 4; uroAddCustomMarkers(ureqID,customMarkerType, hasMyComments, nComments); } } uroRenderCustomMarkers(); } function uroFilterProblems() { if(uroFilterPreamble() == false) return; if((uroGetCBChecked('_cbMPNotClosedUserIDFilter') == false) && (uroGetCBChecked('_cbMPClosedUserIDFilter') == false)) { var selector = document.getElementById('_selectMPUserID'); while(selector.options.length > 0) { selector.options.remove(0); } } var solverUser = null; if((uroGetCBChecked('_cbMPNotClosedUserIDFilter') == true) || (uroGetCBChecked('_cbMPClosedUserIDFilter') == true)) { var selector = document.getElementById('_selectMPUserID'); if(selector.options.length == 0) { uroUpdateMPSolverList(); } if(selector.selectedOptions[0] != undefined) { solverUser = parseInt(selector.selectedOptions[0].value); } } for (var urobj in W.model.problems.objects) { var problem = W.model.problems.objects[urobj]; var problemStyle = 'visible'; // check problem against current session ignore list... if(uroIsOnIgnoreList(problem.attributes.id)) problemStyle = 'hidden'; // check against closed/not identified filtering if enabled... var problem_marker_img = ''; if(problem.geometry.id != null) { if(document.getElementById(problem.geometry.id) != null) { problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal; if(uroGetCBChecked('_cbMPFilterSolved') == true) { if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden'; } if(uroGetCBChecked('_cbMPFilterUnidentified') == true) { if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden'; } } } if(uroGetCBChecked('_cbMPFilterClosed') == true) { if(problem.attributes.open == false) { problemStyle = 'hidden'; } } if(problemStyle == 'visible') { if(solverUser != null) { if((uroGetCBChecked('_cbMPNotClosedUserIDFilter') == true) && (problem.attributes.resolvedBy == solverUser)) problemStyle = 'hidden'; if((uroGetCBChecked('_cbMPClosedUserIDFilter') == true) && (problem.attributes.resolvedBy != solverUser)) problemStyle = 'hidden'; } } if(problemStyle == 'visible') { var problemType = null; if(uroDOMHasTurnProblems) { problemType = problem.attributes.problemType; } else { problemType = problem.attributes.subType; } if(problemType == 101) { if(uroGetCBChecked('_cbMPFilterDrivingDirectionMismatch') == true) problemStyle = 'hidden'; } else if(problemType == 102) { if(uroGetCBChecked('_cbMPFilterMissingJunction') == true) problemStyle = 'hidden'; } else if(problemType == 103) { if(uroGetCBChecked('_cbMPFilterMissingRoad') == true) problemStyle = 'hidden'; } else if(problemType == 104) { if(uroGetCBChecked('_cbMPFilterCrossroadsJunctionMissing') == true) problemStyle = 'hidden'; } else if(problemType == 105) { if(uroGetCBChecked('_cbMPFilterRoadTypeMismatch') == true) problemStyle = 'hidden'; } else if(problemType == 106) { if(uroGetCBChecked('_cbMPFilterRestrictedTurn') == true) problemStyle = 'hidden'; } else if(problemType == 200) { if(uroGetCBChecked('_cbMPFilterTurnProblem') == true) problemStyle = 'hidden'; } else if(uroGetCBChecked('_cbMPFilterUnknownProblem') == true) problemStyle = 'hidden'; if(uroGetCBChecked('_cbMPFilterReopenedProblem') == true) { if((problem.attributes.open == true) && (problem.attributes.resolvedOn != null)) { problemStyle = 'hidden'; } } if(uroGetCBChecked('_cbInvertMPFilter') == true) { if(problemStyle == 'hidden') problemStyle = 'visible'; else problemStyle = 'hidden'; } if(problem.attributes.weight <= 3) { if(uroGetCBChecked('_cbMPFilterLowSeverity') == true) problemStyle = 'hidden'; } else if(problem.attributes.weight <= 7) { if(uroGetCBChecked('_cbMPFilterMediumSeverity') == true) problemStyle = 'hidden'; } else if(uroGetCBChecked('_cbMPFilterHighSeverity') == true) problemStyle = 'hidden'; } W.map.problemLayer.markers[urobj].icon.imageDiv.style.visibility = problemStyle; } if(uroDOMHasTurnProblems) { for (var urobj in W.model.turnProblems.objects) { var problem = W.model.turnProblems.objects[urobj]; var problemStyle = 'visible'; // check problem against current session ignore list... if(uroIsOnIgnoreList(problem.attributes.id)) problemStyle = 'hidden'; // check against closed/not identified filtering if enabled... var problem_marker_img = ''; if(problem.geometry.id != null) { if(document.getElementById(problem.geometry.id) != null) { problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal; if(uroGetCBChecked('_cbMPFilterSolved') == true) { if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden'; } if(uroGetCBChecked('_cbMPFilterUnidentified') == true) { if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden'; } } } if(uroGetCBChecked('_cbMPFilterClosed') == true) { if(problem.attributes.open == false) { problemStyle = 'hidden'; } } if(problemStyle == 'visible') { if(uroGetCBChecked('_cbMPFilterTurnProblem') == true) problemStyle = 'hidden'; if(uroGetCBChecked('_cbMPFilterReopenedProblem') == true) { if((problem.attributes.open == true) && (problem.attributes.resolvedOn != null)) { problemStyle = 'hidden'; } } if(uroGetCBChecked('_cbInvertMPFilter') == true) { if(problemStyle == 'hidden') problemStyle = 'visible'; else problemStyle = 'hidden'; } } W.map.problemLayer.markers[urobj].icon.imageDiv.style.visibility = problemStyle; } } } function uroToHex(decValue,digits) { var modifier = 1; for(var i=0; i<digits; i++) { modifier *= 16; } decValue = parseInt(decValue); decValue += modifier; var retval = decValue.toString(16); retval = retval.substr(-digits); retval = retval.toUpperCase(); return retval; } function uroFilterPreamble() { var mapviewport = document.getElementsByClassName("olMapViewport")[0]; if(mapviewport == null) { if(uroNullMapViewport == false) { uroAddLog('caught null mapviewport'); uroNullMapViewport = true; } return false; } uroNullMapViewport = false; if(uroGetCBChecked('_cbWhiteBackground')) { var customColour = '#' + uroToHex(uroGetElmValue('_inputCustomBackgroundRed'),2); customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundGreen'),2); customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundBlue'),2); mapviewport.style.backgroundColor = customColour; } else { mapviewport.style.backgroundColor = "#C2C2C2"; } if(uroGetCBChecked('_cbHideAMLayer')) { W.map.managedAreasLayer.setOpacity(0); } else { W.map.managedAreasLayer.setOpacity(1); } return true; } function uroFilterItems_URTabClick() { uroFilterURs(); } function uroFilterItems_MPTabClick() { uroFilterProblems(); } function uroFilterItems_PlacesTabClick() { uroFilterPlaces(); } function uroFilterItems_CamerasTabClick() { uroFilterCameras(); } function uroFilterItems_MiscTabClick() { uroFilterItems(); } function uroFilterItems() { uroFilterProblems(); uroFilterPlaces(); uroFilterCameras(); uroFilterURs(); } function uroFilterItemsOnMove() { W.map.events.unregister('mousemove',null,uroFilterItemsOnMove); uroFilterItems(); } function uroDeleteObject() { uroAddLog('delete camera ID '+uroShownFID); if(W.model.cameras.objects[uroShownFID] == null) { uroAddLog('camera object not found...'); return false; } uroRemoveCamFromWatchList(); var actionObj = require('Waze/Action/DeleteObject'); deleteAction = new actionObj(W.model.cameras.objects[uroShownFID], null); W.model.actionManager.add(deleteAction); uroExitPopup(); return false; } function uroGetUserNameAndRank(userID) { var userName; var userLevel; if(W.model.users.objects[userID] != undefined) { userName = W.model.users.objects[userID].userName; if(userName == undefined) { userName = userID; } userLevel = W.model.users.objects[userID].rank + 1; } else { userName = userID; userLevel = '?'; } return userName + ' (' + userLevel + ')'; } function uroCheckCommentsForKeyword(idSrc, keyword) { var ursObj = W.model.updateRequestSessions.objects[idSrc]; if(typeof(ursObj) == 'undefined') return false; if(ursObj.comments.length == 0) return false; for(var idx=0; idx<ursObj.comments.length; idx++) { if(ursObj.comments[idx].text.indexOf(keyword) != -1) { return true; } } return false; } function uroGetCustomMarkerIdx(customType) { if(customType == 0) return 3; if(customType == 1) return 3; if(customType == 2) return 5; if(customType == 3) return 7; if(customType == 4) return 9; return -1; } function uroGetCustomType(idSrc) { var ureq = W.model.mapUpdateRequests.objects[idSrc]; var desc = ''; if(ureq.attributes.description != null) { desc = ureq.attributes.description; if(desc.indexOf('[ROADWORKS]') != -1) return 0; if(desc.indexOf('[CONSTRUCTION]') != -1) return 1; if(desc.indexOf('[CLOSURE]') != -1) return 2; if(desc.indexOf('[EVENT]') != -1) return 3; if(desc.indexOf('[NOTE]') != -1) return 4; } if(uroCheckCommentsForKeyword(idSrc,'[ROADWORKS]')) return 0; if(uroCheckCommentsForKeyword(idSrc,'[CONSTRUCTION]')) return 1; if(uroCheckCommentsForKeyword(idSrc,'[CLOSURE]')) return 2; if(uroCheckCommentsForKeyword(idSrc,'[EVENT]')) return 3; if(uroCheckCommentsForKeyword(idSrc,'[NOTE]')) return 4; return -1; } function uroFormatRestriction(restObj) { var retval = '<tr>'; retval += '<td style="text-align:center;">'; if((restObj.days & 1) == 1) retval += 'S'; else retval += '-'; retval += '</td><td style="text-align:center;">'; if((restObj.days & 2) == 2) retval += 'M'; else retval += '-'; retval += '</td><td style="text-align:center;">'; if((restObj.days & 4) == 4) retval += 'T'; else retval += '-'; retval += '</td><td style="text-align:center;">'; if((restObj.days & 8) == 8) retval += 'W'; else retval += '-'; retval += '</td><td style="text-align:center;">'; if((restObj.days & 16) == 16) retval += 'T'; else retval += '-'; retval += '</td><td style="text-align:center;">'; if((restObj.days & 32) == 32) retval += 'F'; else retval += '-'; retval += '</td><td style="text-align:center;">'; if((restObj.days & 64) == 64) retval += 'S'; else retval += '-'; retval += '</td><td>'; if(restObj.fromDate == null) retval += 'All dates'; else retval += restObj.fromDate+' to '+restObj.toDate; retval += '</td><td>'; if(restObj.allDay == true) retval += 'All day'; else retval += restObj.fromTime+' to '+restObj.toTime; retval += '</td><td>'; if(restObj.allVehicleTypes == restObj.vehicleTypes) retval += 'All vehicles'; else retval += 'Some vehicles'; retval += '</td><td>'; var desc = restObj.description.replace(/<\/?[^>]+(>|$)/g, ""); desc = uroClickify(desc); retval += desc; retval += '</td></tr>'; return retval; } function uroHidePopup() { uroDiv.style.visibility = 'hidden'; uroPopupShown = false; uroPopupTimer = -2; uroShownFID = -1; } function uroRecentreSessionOnUR() { W.map.updateRequestLayer.markers[uroShownFID].icon.imageDiv.click(); W.map.moveTo(W.map.updateRequestLayer.markers[uroShownFID].lonlat, 5); uroHidePopup(); return false; } function uroRecentreSessionOnMP() { W.map.problemLayer.markers[uroShownFID].icon.imageDiv.click(); W.map.moveTo(W.map.problemLayer.markers[uroShownFID].lonlat, 5); uroHidePopup(); return false; } function uroRecentreSessionOnPUR() { W.map.placeUpdatesLayer.markers[uroShownFID].icon.imageDiv.click() W.map.moveTo(W.map.placeUpdatesLayer.markers[uroShownFID].lonlat, 5); uroHidePopup(); return false; } function uroParsePxString(pxString) { return parseInt(pxString.split("px")[0]); } function uroStackListObj(fid,x,y) { this.fid = fid; this.x = uroTypeCast(x); this.y = uroTypeCast(y); } function uroRestackMarkers() { if(uroStackList.length == 0) return; if(uroStackType == 1) markerCollection = W.map.updateRequestLayer.markers; else if(uroStackType == 2) markerCollection = W.map.problemLayer.markers; else if(uroStackType == 3) markerCollection = W.map.placeUpdatesLayer.markers; for(var idx=0; idx<uroStackList.length; idx++) { var orig_x = uroStackList[idx].x + 'px'; var orig_y = uroStackList[idx].y + 'px'; var fid = uroStackList[idx].fid; if(markerCollection[fid] != undefined) { markerCollection[fid].icon.imageDiv.style.left = orig_x; markerCollection[fid].icon.imageDiv.style.top = orig_y; } } uroStackList = new Array(); uroUnstackedMasterID = null; uroStackType = null; } function uroIsIDAlreadyUnstacked(idSrc) { if(uroStackList.length == 0) return false; for(var idx=0; idx<uroStackList.length; idx++) { if(uroStackList[idx].fid == idSrc) return true; } return false; } function uroCheckStacking(stackType, masterID, unstackedX, unstackedY) { if(W.map.getZoom() < uroGetElmValue('_inputUnstackZoomLevel')) return; if(uroIsIDAlreadyUnstacked(masterID) == true) return; uroAddLog('checking for marker stack, type '+stackType+'...'); var stackList = new Array(); var threshSquared = uroGetElmValue('_inputUnstackSensitivity'); threshSquared *= threshSquared; if(stackType == 1) markerCollection = W.map.updateRequestLayer.markers; else if(stackType == 2) markerCollection = W.map.problemLayer.markers; else if(stackType == 3) markerCollection = W.map.placeUpdatesLayer.markers; for(var marker in markerCollection) { testMarkerObj = markerCollection[marker]; if(testMarkerObj.icon.imageDiv.style.visibility != 'hidden') { if(testMarkerObj.id != masterID) { var xdiff = unstackedX - uroParsePxString(markerCollection[testMarkerObj.id].icon.imageDiv.style.left); var ydiff = unstackedY - uroParsePxString(markerCollection[testMarkerObj.id].icon.imageDiv.style.top); var distSquared = ((xdiff * xdiff) + (ydiff * ydiff)); if(distSquared < threshSquared) { stackList.push(testMarkerObj.id); } } } } if(stackList.length > 0) { uroAddLog('markers are stacked!'); if(uroUnstackedMasterID != masterID) { uroAddLog('unstacked ID mismatch, relocating markers...'); uroRestackMarkers(); uroStackType = stackType; uroUnstackedMasterID = masterID; uroStackList = new Array(); // push the highlighted marker onto the stacklist so uroIsIDAlreadyUnstacked() will return true uroStackList.push(new uroStackListObj(masterID,unstackedX,unstackedY)); for(var shoveIdx=0; shoveIdx < stackList.length; shoveIdx++) { var fid = stackList[shoveIdx]; var x = uroParsePxString(markerCollection[fid].icon.imageDiv.style.left); var y = uroParsePxString(markerCollection[fid].icon.imageDiv.style.top); // store the unstacked marker positions so they can be reinstated later uroStackList.push(new uroStackListObj(fid,x,y)); unstackedX += 10; unstackedY -= 30; markerCollection[fid].icon.imageDiv.style.left = unstackedX + 'px'; markerCollection[fid].icon.imageDiv.style.top = unstackedY + 'px'; } // hide other markers to prevent confusion with the unstacked markers for(var marker in markerCollection) { var toHideID = markerCollection[marker].id; if(uroIsIDAlreadyUnstacked(toHideID) == false) { markerCollection[toHideID].icon.imageDiv.style.visibility = 'hidden'; } } } } else { uroRestackMarkers(); } } function uroNewLookHighlightedItemsCheck(e) { if((uroMouseIsDown) && (e.buttons == 0)) { uroAddLog('trapped erroneous mousedown state'); uroMouseIsDown = false; } if(uroMouseIsDown) { return; } if(document.getElementsByClassName('panel')[0] != undefined) { return; } if(W.geometryEditing.activeEditor != null) { uroHidePopup(); return; } if(OpenLayers == null) { if(uroNullOpenLayers == false) { uroAddLog('caught null OpenLayers'); uroNullOpenLayers = true; } return; } uroNullOpenLayers = false; var rc = document.getElementById(uroRootContainer); if(rc == null) { if(uroNullRootContainer == false) { uroAddLog('caught null rootContainer'); uroNullRootContainer = true } return; } uroNullRootContainer = false; if(W.map.updateRequestLayer == null) { if(uroNullURLayer == false) { uroAddLog('caught null UR layer'); uroNullURLayer = true; } return; } uroNullURLayer = false; if(W.map.problemLayer == null) { if(uroNullProblemLayer == false) { uroAddLog('caught null problem layer'); uroNullProblemLayer = true; } return; } uroNullProblemLayer = false; var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left; var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top; var currentItems = rc.getElementsByTagName('g'); var result = ''; var rw; var rh; var popup_loc = new OpenLayers.LonLat(0,0); var objHasIgnoreLink = false; var objHasDeleteLink = false; var popupXOffset = uroParsePxString(window.getComputedStyle(document.getElementById('sidebar')).getPropertyValue("width")); var popupYOffset = document.getElementsByClassName('waze-header')[0].clientHeight; var uroPopupX = mouseX + popupXOffset; var uroPopupY = mouseY + popupYOffset; var objHasIgnoreLink = false; var objHasDeleteLink = false; var objHasAddWatchLink = false; var objHasRemoveWatchLink = false; var objHasUpdateWatchLink = false; var objHasRecentreSessionLink = false; var newPopupType = null; // popup for segment restrictions if(uroGetCBChecked('_cbInhibitSegPopup') == false) { for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++) { if(W.map.segmentLayer.features[slIdx].renderIntent == 'highlight') { var doPopUp = false; if(W.map.segmentLayer.features[slIdx].fid == null) segObj = W.map.segmentLayer.features[slIdx].model; else segObj = W.map.segmentLayer.features[slIdx]; result += '<table cellpadding=4 border=1">'; if(segObj.attributes.fwdRestrictions.length > 0) { doPopUp = true; result += '<tr><td colspan=11><b>A-B restrictions:</b></td></tr>'; for(var idx = 0; idx < segObj.attributes.fwdRestrictions.length; idx++) { restObj = segObj.attributes.fwdRestrictions[idx]; result += uroFormatRestriction(restObj); } } if (segObj.attributes.revRestrictions.length > 0) { doPopUp = true; result += '<tr><td colspan=11><b>B-A restrictions:</b></td></tr>'; for(var idx = 0; idx < segObj.attributes.revRestrictions.length; idx++) { restObj = segObj.attributes.revRestrictions[idx]; result += uroFormatRestriction(restObj); } } result += '</table>'; if(W.map.closuresMarkerLayer.getVisibility() == true) { result += '<table cellpadding=4 border=1" width="100%">'; if(segObj.attributes.hasClosures == true) { var hasFwd = false; var hasRev = false; for(var rc in W.model.roadClosures.objects) { rcObj = W.model.roadClosures.objects[rc]; if(rcObj.segID == segObj.attributes.id) { if(rcObj.forward == true) { if(hasFwd == false) { result += '<tr><td colspan=3><b>A-B closures:</b></td></tr>'; hasFwd = true; } if(rcObj.active == true) { result += '<tr>'; } else { result += '<tr bgcolor="#C0C0C0">'; } result += '<td>' + rcObj.startDate + ' to ' + rcObj.endDate + '</td>'; result += '<td>' + rcObj.provider + '</td>'; result += '<td>' + rcObj.reason + '</td>'; result += '</td></tr>'; } else { hasRev = true; } } } if(hasRev == true) { result += '<tr><td colspan=3><b>B-A closures:</b></td></tr>'; for(var rc in W.model.roadClosures.objects) { rcObj = W.model.roadClosures.objects[rc]; if(rcObj.segID == segObj.attributes.id) { if(rcObj.forward == false) { if(rcObj.active == true) { result += '<tr>'; } else { result += '<tr bgcolor="#C0C0C0">'; } result += '<td>' + rcObj.startDate + ' to ' + rcObj.endDate + '</td>'; result += '<td>' + rcObj.provider + '</td>'; result += '<td>' + rcObj.reason + '</td>'; result += '</td></tr>'; } } } } if((hasFwd == true) || (hasRev == true)) { doPopUp = true; } } result += '</table>'; } if(doPopUp == true) { if(segObj.attributes.id == null) uroFID = segObj.id; else uroFID = segObj.attributes.id; newPopupType = 'segment_restriction'; } break; } } } // popup for restricted turns /* if(newPopupType == null) { var idSrc = null; //if(uroGetCBChecked('_cbInhibitTurnsPopup') == false) { if(W.map.layers[uroTurnsLayerIdx].markers.length > 0) { for(var marker in W.map.layers[uroTurnsLayerIdx].markers) { markerObj = W.map.layers[uroTurnsLayerIdx].markers[marker]; markerImg = window.getComputedStyle(markerObj.icon.imageDiv.childNodes[0]).getPropertyValue("background-image"); markerPos = window.getComputedStyle(markerObj.icon.imageDiv.childNodes[0]).getPropertyValue("background-position"); markerPos = markerPos.split(' '); markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2)); var hovered = false; if(markerImg.indexOf('turns-s32af5d033c.png') != -1) { if(markerPos == -235) { hovered = true; } } if(hovered == true) { uroAddLog('hover over turn marker '+marker); break; } } } } } */ // popup for landmarks if((newPopupType == null) && (uroGetCBChecked('_cbInhibitLandmarkPopup') == false)) { uroPlaceSelected = false; for(var llFeatureIdx=0; llFeatureIdx < W.map.landmarkLayer.features.length; llFeatureIdx++) { var renderIntent = W.map.landmarkLayer.features[llFeatureIdx].renderIntent; if(renderIntent == 'highlight') { if(W.map.landmarkLayer.features[llFeatureIdx].fid == null) venueObj = W.map.landmarkLayer.features[llFeatureIdx].model; else venueObj = W.map.landmarkLayer.features[llFeatureIdx]; if(venueObj.geometry.id.indexOf('.Point_') != -1) { // override popup placement for point places var placeXY = W.map.getPixelFromLonLat(venueObj.geometry.toLonLat()); uroPopupX = placeXY.x + popupXOffset + 10; uroPopupY = placeXY.y + popupYOffset + 40; } result += '<b>'; if(venueObj.attributes.name == '') result += 'Unnamed landmark'; else result += venueObj.attributes.name; result += '</b><br>'; for(var idx = 0; idx < venueObj.attributes.categories.length; idx++) { result += I18n.translations[I18n.locale].venues.categories[venueObj.attributes.categories[idx]] + '<br>'; } if(venueObj.attributes.residential == true) { result += '<i>Private Place</i>'; } newPopupType = 'venue'; if(venueObj.attributes.id == null) uroFID = venueObj.id; else uroFID = venueObj.attributes.id; break; } else if(renderIntent == 'select') { uroPlaceSelected = true; } } } // look for URs, place updates and problems if(newPopupType == null) { var idSrc = null; var divIdx = -1; var isUR = false; var isProblem = false; var isTurnProb = false; var isPlaceUpdate = false; if(uroGetCBChecked('_cbInhibitURPopup') == false) { var hovered = false; for(var marker in W.map.updateRequestLayer.markers) { markerObj = W.map.updateRequestLayer.markers[marker]; markerImg = markerObj.icon.$div.css('background-image'); markerPos = markerObj.icon.$div.css('background-position'); markerPos = markerPos.split(' '); markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2)); var urIDSrc = markerObj.id; if(markerImg.indexOf('problems-s8f369ca968.png') != -1) { if((markerPos == -403) || (markerPos == -483) || (markerPos == -563) || (markerPos == -643)) { hovered = true; uroAddLog('UR image type 1'); } } else if(markerImg.indexOf('problems-se224ab677e.png') != -1) { if((markerPos == -40) || (markerPos == -160) || (markerPos == -200) || (markerPos == -240)) { hovered = true; uroAddLog('UR image type 2'); } } else { if(markerPos > -200) { hovered = true; uroAddLog('UR image type 3'); } } if(hovered == true) { isUR = true; newPopupType = 'ur'; uroAddLog('hover over UR ID '+urIDSrc); var unstackedX = uroParsePxString(W.map.updateRequestLayer.markers[urIDSrc].icon.imageDiv.style.left); var unstackedY = uroParsePxString(W.map.updateRequestLayer.markers[urIDSrc].icon.imageDiv.style.top); // override popup base position uroPopupX = unstackedX + popupXOffset + 6; uroPopupY = unstackedY + popupYOffset + 46; uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left); uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top); // check for stacking... if(uroShownFID != idSrc) { uroCheckStacking(1,urIDSrc, unstackedX, unstackedY); } if(urIDSrc != uroCustomMarkerFID) { if(uroCustomMarkerFID != null) { var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(uroCustomMarkerFID)); uroChangeCustomMarkers(uroCustomMarkerFID,false,customIdx); uroCustomMarkerFID = null; } var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(urIDSrc)); if(customIdx != -1) { uroCustomMarkerFID = urIDSrc; uroChangeCustomMarkers(urIDSrc,hovered,customIdx); } } idSrc = urIDSrc; break; } } if((hovered == false) && (uroStackType == 1)) { uroRestackMarkers(); uroFilterURs(); } if((idSrc == null) && (uroCustomMarkerFID != null)) { var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(uroCustomMarkerFID)); uroChangeCustomMarkers(uroCustomMarkerFID,false, customIdx); uroCustomMarkerFID = null; } } if((newPopupType == null) && (uroGetCBChecked('_cbInhibitPUPopup') == false)) { var hovered = false; for(var marker in W.map.placeUpdatesLayer.markers) { markerObj = W.map.placeUpdatesLayer.markers[marker]; markerImg = markerObj.icon.$div.css('background-image'); markerPos = markerObj.icon.$div.css('background-position'); markerPos = markerPos.split(' '); markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2)); if(markerImg.indexOf('placeUpdates-sb30471988c.png') != -1) { // absolute offsets: 0 = new place, -120 = flagged, -240 = new photo, -360 = updated details // relative offsets: 0 = green, -40 = highlighted, -80 = default if(((markerPos + 40) % 120) == 0) { hovered = true; uroAddLog('PUR marker type 1'); } } else if(markerImg.indexOf('placeUpdates-s2e8d9c5ce4.png') != -1) { if ( (markerObj.icon.$div.css("filter") == "brightness(110%)") || (markerObj.icon.$div.css("webkit-filter") == "brightness(1.1)") ) { hovered = true; uroAddLog('PUR marker type 2'); } } if(hovered == true) { var idSrc = markerObj.id; var unstackedX = uroParsePxString(W.map.placeUpdatesLayer.markers[idSrc].icon.imageDiv.style.left); var unstackedY = uroParsePxString(W.map.placeUpdatesLayer.markers[idSrc].icon.imageDiv.style.top); // override popup base position uroPopupX = unstackedX + popupXOffset + 6; uroPopupY = unstackedY + popupYOffset + 46; uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left); uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top); if(uroShownFID != idSrc) { // check for stacking... uroCheckStacking(3,idSrc, unstackedX, unstackedY); } isPlaceUpdate = true; newPopupType = 'pur'; uroAddLog('hover over placeUpdate ID '+idSrc); break; } } if((hovered == false) && (uroStackType == 3)) { uroRestackMarkers(); uroFilterPlaces(); } } if((newPopupType == null) && (uroGetCBChecked('_cbInhibitMPPopup') == false)) { var hovered = false; for(var marker in W.map.problemLayer.markers) { markerObj = W.map.problemLayer.markers[marker]; markerImg = markerObj.icon.$div.css('background-image'); markerPos = markerObj.icon.$div.css('background-position'); markerPos = markerPos.split(' '); markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2)); if(markerImg.indexOf('problems-s8f369ca968.png') != -1) { if((markerPos == -65) || (markerPos == -145) || (markerPos == -225) || (markerPos == -305)) { hovered = true; uroAddLog('Problem image type 1'); } } else if(markerImg.indexOf('problems-se224ab677e.png') != -1) { if((markerPos == -320) || (markerPos == -560) || (markerPos == -520) || (markerPos == -440)) { hovered = true; uroAddLog('Problem image type 2'); } } else { if(markerPos > -200) { hovered = true; uroAddLog('Problem image type 3'); } } if(hovered == true) { var idSrc = null; if(markerObj.model.fid == null) idSrc = markerObj.id; else idSrc = markerObj.model.fid; var unstackedX = uroParsePxString(W.map.problemLayer.markers[idSrc].icon.imageDiv.style.left); var unstackedY = uroParsePxString(W.map.problemLayer.markers[idSrc].icon.imageDiv.style.top); // override popup base position uroPopupX = unstackedX + popupXOffset + 6; uroPopupY = unstackedY + popupYOffset + 46; uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left); uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top); // check for stacking... if(uroShownFID != idSrc) { uroCheckStacking(2,idSrc, unstackedX, unstackedY); } isProblem = true; newPopupType = 'map_problem'; uroAddLog('hover over problem ID '+idSrc); break; } } if((hovered == false) && (uroStackType == 2)) { uroRestackMarkers(); uroFilterProblems(); } } if (idSrc != null) { var ureq = null; if(isUR) ureq = W.model.mapUpdateRequests.objects[idSrc]; else if(isProblem) { ureq = W.model.problems.objects[idSrc]; if(ureq == undefined) { if(uroDOMHasTurnProblems) { var ureq = W.model.turnProblems.objects[idSrc]; if(ureq != undefined) isTurnProb = true; } } } else if(isPlaceUpdate) ureq = W.map.placeUpdatesLayer.markers[idSrc].model; var ureqID = null; if(ureq.fid != null) ureqID = ureq.fid; else if(ureq.id != null) ureqID = ureq.id; else if(ureq.attributes.id != null) ureqID = ureq.attributes.id; uroFID = ureqID; } else { uroFID = -1; } //if((uroFID != uroShownFID) && (uroFID != -1)) if(uroFID != -1) { if(isUR) { uroAddLog('building popup for UR '+idSrc); result = '<b>Update Request ('+idSrc+'): ' + I18n.translations[I18n.locale].update_requests.types[ureq.attributes.type] + '</b><br>'; if(ureq.attributes.description != null) { var desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, ""); if(desc != "null") { desc = uroClickify(desc); result += desc + '<br>'; } } var uroDaysOld = uroGetURAge(ureq,0); if(uroDaysOld != -1) { result += '<i>Submitted ' + uroParseDaysAgo(uroDaysOld) + ' '; if(ureq.attributes.guestUserName != null) { result += 'via Livemap'; if(ureq.attributes.guestUserName != '') { result += ' by '+ureq.attributes.guestUserName.replace(/<\/?[^>]+(>|$)/g, ""); } } result += '</i>'; } if(ureq.attributes.resolvedOn != null) { var uroDaysResolved = uroGetURAge(ureq,1); if(uroDaysResolved != -1) { result += '<br><i>Closed ('; if(ureq.attributes.resolution == 0) result += 'solved'; else if(ureq.attributes.resolution == 1) result += 'not identified'; else result += 'unknown'; result += ') ' + uroParseDaysAgo(uroDaysResolved) + ' '; if(ureq.attributes.resolvedBy != null) { result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy); } result += '</i>'; } } if(W.model.updateRequestSessions.objects[ureqID] != null) { var hasMyComments = uroURHasMyComments(ureqID); var nComments = W.model.updateRequestSessions.objects[ureqID].comments.length; result += '<br>' + nComments + ' comment'; if(nComments != 1) result += 's'; if((hasMyComments == false) && (nComments > 0)) result += ' (none by me)'; if(nComments > 0) { var commentDaysOld = uroGetCommentAge(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1]); if(commentDaysOld != -1) { result += ', last update '+uroParseDaysAgo(commentDaysOld); } } } } else if(isProblem) { uroAddLog('building popup for problem '+idSrc); if(isTurnProb) result = '<b>Turn Problem ('+idSrc+'): ' + I18n.translations[I18n.locale].problems.types["turn"].title; else { result = '<b>Map Problem ('+idSrc+'): '; var problemType = null; if(uroDOMHasTurnProblems) { problemType = ureq.attributes.problemType; } else { problemType = ureq.attributes.subType; } if(I18n.translations[I18n.locale].problems.types[problemType] == undefined) result += 'Unknown problem type ('+problemType+')'; else result += I18n.translations[I18n.locale].problems.types[problemType].title; } result += '</b><br>'; if(ureq.attributes.resolvedOn != null) { var uroDaysResolved = uroGetURAge(ureq,1); if(uroDaysResolved != -1) { result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' '; if(ureq.attributes.resolvedBy != null) { result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy); } if((ureq.attributes.open == true) && (ureq.attributes.resolvedOn != null)) { result += '<br>Reopened by Waze'; } result += '</i>'; } } } else if(isPlaceUpdate) { uroAddLog('building popup for placeUpdate '+idSrc); result = '<b>'; if(ureq.attributes.name == '') result += 'Unnamed landmark'; else result += ureq.attributes.name; result += '</b><br>'; for(var idx = 0; idx < ureq.attributes.categories.length; idx++) { result += I18n.translations[I18n.locale].venues.categories[ureq.attributes.categories[idx]]; } if(ureq.attributes.residential == true) { result += '<br><i>Private Place</i>'; } var daysOld = uroGetPURAge(ureq); if(daysOld != -1) { result += '<br><i>Submitted '+uroParseDaysAgo(daysOld)+'</i>'; } } // add "open new WME tab" link var urPos=new OpenLayers.LonLat(); if(isPlaceUpdate) { urPos=ureq.geometry.bounds.centerLonLat.clone(); } else { urPos.lon=ureq.geometry.x; urPos.lat=ureq.geometry.y; } urPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")); var urLink = document.location.href; urLayers = '&layers='+W.map.mapState.getLayerVisibilityBitmask(); urLink = urLink.substr(0,urLink.indexOf('?zoom')); urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers; if(isUR) urLink += '&mapUpdateRequest='+idSrc; else if(isTurnProb) urLink += '&showturn='+idSrc+'&endshow'; else if(isProblem) urLink += '&mapProblem='+idSrc; else if(isPlaceUpdate) urLink += '&showpur='+idSrc+'&endshow'; result += '<hr><ul><li><a href="'+urLink+'" target="_urTab">Open in new tab</a> - '; //result += '<a href="'+urLink+'">open in current tab</a>'; result += '<a href="#" id="_recentreSession">centre in current tab</a>'; objHasRecentreSessionLink = true; // add "open new livemap tab" link var lmLink = null; if(document.getElementsByClassName("waze-header-menu").length == 0) { uroAddLog('Livemap link in livemap element'); lmLink = document.getElementById('livemap').href; } else { uroAddLog('Livemap link in header menu, locating...'); var menuItems = document.getElementsByClassName("waze-header-menu")[0]; for(var miloop = 0; miloop<menuItems.childElementCount; miloop++) { if(menuItems.children[miloop].innerHTML.indexOf('livemap') != -1) { uroAddLog('found link in menu entry '+miloop); lmLink = menuItems.children[miloop].getElementsByTagName('a')[0].href; uroAddLog(lmLink); } } } if(lmLink != null) { var zpos = lmLink.indexOf('?'); if(zpos > -1) lmLink = lmLink.substr(0,zpos); lmLink += '?zoom=17&lat='+urPos.lat+'&lon='+urPos.lon+'&layers=BTTTT'; result += '<li><a href="'+lmLink+'" target="_lmTab">Open in new livemap tab</a>'; } if(!isPlaceUpdate) { // add "ignore for this session" link result += '<li><a href="#" id="_addtoignore">Hide for this session</a></ul>'; objHasIgnoreLink = true; } } } // look for cameras if((newPopupType == null) && (uroGetCBChecked('_cbInhibitCamPopup') == false)) { for(var clFeatureIdx = 0; clFeatureIdx < W.map.camerasLayer.features.length; clFeatureIdx++) { if(W.map.camerasLayer.features[clFeatureIdx].renderIntent == 'highlight') { if(W.map.camerasLayer.features[clFeatureIdx].fid == null) ureq = W.map.camerasLayer.features[clFeatureIdx].model; else ureq = W.map.camerasLayer.features[clFeatureIdx]; var ureqID = null; if(ureq.fid == null) ureqID = ureq.attributes.id; else ureqID = ureq.fid; // test isSelected() so that we only do overview data on cameras that are being hovered over if(ureq.isSelected() == false) { // override popup base position var markerXY = W.map.getPixelFromLonLat(ureq.geometry.toLonLat()); uroPopupX = markerXY.x + popupXOffset + 20; uroPopupY = markerXY.y + popupYOffset + 60; newPopupType = 'camera'; uroFID = ureqID; uroAddLog('generating popup for camera '+uroFID); result += '<b>Camera: ' + ureq.TYPES[ureq.attributes.type] + '</b><br>'; result += 'ID: '+uroFID+'<br>'; result += 'Created by '; if(W.model.users.get(ureq.attributes.createdBy) != null) { userID = ureq.attributes.createdBy; result += uroGetUserNameAndRank(userID); } else result += 'unknown'; result += ', '; var camAge = uroGetCameraAge(ureq,1); if(camAge != -1) { result += uroParseDaysAgo(camAge); } else result += 'unknown days ago'; result += '<br>Updated by '; if(W.model.users.get(ureq.attributes.updatedBy) != null) { userID = ureq.attributes.updatedBy; userName = W.model.users.objects[userID].userName; userLevel = W.model.users.objects[userID].rank + 1; result += userName + ' (' + userLevel + ')'; } else result += 'unknown'; result += ', '; var camAge = uroGetCameraAge(ureq,0); if(camAge != -1) { result += uroParseDaysAgo(camAge); } else result += 'unknown days ago'; result += '<br>Speed data: '; if(ureq.attributes.speed != null) { result += ureq.attributes.speed + 'km/h'; var speedInMPH = Math.round(ureq.attributes.speed / 1.609); result += ' (' + speedInMPH + 'mph'; if((speedInMPH % 10) != 0) result += ' - not valid?'; result += ')</i>'; } else result += 'unknown'; var uid = W.model.loginManager.getLoggedInUser().id; result += '<hr><ul>'; if(uroIsCamOnWatchList(uroFID) != -1) { result += '<li><a href="#" id="_updatewatchlist">Update watchlist entry</a>'; result += '<li><a href="#" id="_removefromwatchlist">Remove from watchlist</a>'; objHasUpdateWatchLink = true; objHasRemoveWatchLink = true; } else { result += '<li><a href="#" id="_addtowatchlist">Add to watchlist</a>'; objHasAddWatchLink = true; } if(ureq.attributes.permissions != 0) { result += '<li><a href="#" id="_deleteobject">Delete Camera</a>'; objHasDeleteLink = true; } result += '</ul>'; } break; } } } if(newPopupType != null) { if((uroFID != uroShownFID) || (newPopupType != uroShownPopupType)) { if(uroFID != uroShownFID) uroAddLog('FID mismatch, show popup: '+uroFID+'/'+uroShownFID); else uroAddLog('Popup type mismatch: '+newPopupType+'/'+uroShownPopupType); uroShownFID = uroFID; uroShownPopupType = newPopupType; uroPopupShown = false; } if(uroPopupShown == false) { uroAddLog('display popup at '+uroPopupX+','+uroPopupY); uroPopupShown = true; uroDiv.innerHTML = result; if((uroFID != -1) && (objHasIgnoreLink == true)) { uroAddEventListener('_addtoignore','click', uroAddToIgnoreList, true); } if(objHasDeleteLink == true) { uroAddEventListener('_deleteobject','click', uroDeleteObject, true); } if(objHasRemoveWatchLink == true) { uroAddEventListener('_removefromwatchlist','click', uroRemoveCamFromWatchList, true); } if(objHasAddWatchLink == true) { uroAddEventListener('_addtowatchlist','click', uroAddCamToWatchList, true); } if(objHasUpdateWatchLink == true) { uroAddEventListener('_updatewatchlist','click', uroUpdateCamWatchList, true); } if(objHasRecentreSessionLink == true) { if(isUR) uroAddEventListener('_recentreSession','click', uroRecentreSessionOnUR, true); else if((isProblem)||(isTurnProb)) uroAddEventListener('_recentreSession','click', uroRecentreSessionOnMP, true); else if(isPlaceUpdate) uroAddEventListener('_recentreSession','click', uroRecentreSessionOnPUR, true); } rw = parseInt(uroDiv.clientWidth); rh = parseInt(uroDiv.clientHeight); if(rw > (window.innerWidth / 2)) rw = (window.innerWidth / 2); if(rh > (window.innerHeight / 2)) rh = (window.innerHeight / 2); if((uroPopupX + rw) > window.innerWidth) { uroPopupX -= (rw + 20); if(uroPopupX < 0) uroPopupX = 0; } if((uroPopupY + rh) > window.innerHeight) { uroPopupY -= (rh + 10); if(uroPopupY < 0) uroPopupY = 0; } uroDiv.style.top = uroPopupY+'px'; uroDiv.style.left = uroPopupX+'px'; uroDiv.clientWidth = rw+'px'; uroDiv.clientHeight = rh+'px'; uroDiv.style.visibility = 'visible'; } uroPopupTimer = -1; } else { if(uroPopupTimer == -1) { uroPopupTimer = uroGetElmValue('_inputPopupEntryTimeout'); } } } function uroRestyleWMETabs() { var navTabs = document.getElementById(uroUserTabId).children[1].children; for(var loop = 0; loop<navTabs.length; loop++) { navTabs[loop].children[0].style.padding = "4px"; } setTimeout(uroRestyleWMETabs,1000); } function uroExclusiveCB() { cbChecked = uroGetCBChecked(this.id); if(cbChecked == true) { if(this.id == '_cbHideMyComments') uroGetCBChecked('_cbHideAnyComments') = false; if(this.id == '_cbHideAnyComments') uroGetCBChecked('_cbHideMyComments') = false; if(this.id == '_cbHideIfLastCommenter') uroGetCBChecked('_cbHideIfNotLastCommenter') = false; if(this.id == '_cbHideIfNotLastCommenter') uroGetCBChecked('_cbHideIfLastCommenter') = false; if(this.id == '_cbHideIfReporterLastCommenter') uroGetCBChecked('_cbHideIfReporterNotLastCommenter') = false; if(this.id == '_cbHideIfReporterNotLastCommenter') uroGetCBChecked('_cbHideIfReporterLastCommenter') = false; } } function uroGetAMs(e) { var amList = ''; if(W.map.managedAreasLayer.getVisibility() == true) { var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left; var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top - document.getElementById('toolbar').clientHeight; var mousePixel = new OL.Pixel(mouseX, mouseY); var mousePoint = W.map.getLonLatFromPixel(mousePixel).toPoint(); for(var amObj in W.model.managedAreas.objects) { if(W.model.managedAreas.objects[amObj].geometry.containsPoint(mousePoint)) { if(amList != '') amList += ', '; amList += uroGetUserNameAndRank(W.model.managedAreas.objects[amObj].userID); } } if(amList == '') { amList = 'none'; } amList = "<b>Area Managers:</b> "+amList; } document.getElementById("uroAMList").innerHTML = amList; } function uroMouseDown(e) { uroMouseIsDown = true; } function uroMouseUp(e) { uroMouseIsDown = false; } function uroUREvent_onObjectsChanged() { } function uroUREvent_onObjectsAdded() { if(uroGetCBChecked('_cbURResolverIDFilter') == true) { uroUpdateResolverList(); } uroFilterURs(); } function uroUREvent_onObjectsRemoved() { } function uroGetSelectedURCommentCount() { if(W.model.updateRequestSessions.objects[uroSelectedURID] != undefined) { var cachedCommentCount = W.model.updateRequestSessions.objects[uroSelectedURID].comments.length; uroAddLog(uroSelectedURID+':'+cachedCommentCount+' '+uroExpectedCommentCount); // if there aren't the same number of cached comments as there are comments in the UR dialog list, initiate // a refresh of the comment data... if(cachedCommentCount != uroExpectedCommentCount) { if(uroPendingCommentDataRefresh == true) { if(cachedCommentCount > 0) { uroCachedLastCommentID = W.model.updateRequestSessions.objects[uroSelectedURID].comments[cachedCommentCount-1].id; } else { uroCachedLastCommentID = null; } uroAddLog('updateRequestSessions refresh required for UR '+uroSelectedURID); if(uroCachedLastCommentID != null) { uroAddLog('last comment ID for this UR is '+uroCachedLastCommentID); } else { uroAddLog('first comment for this UR, no previous comment to ID'); } var idList = []; idList.push(uroSelectedURID); // need to delete the existing cache object first, as .get() is only capable of creating new objects, // it doesn't seem able to update an existing object with new data W.model.updateRequestSessions.remove(W.model.updateRequestSessions.objects[uroSelectedURID]); W.model.updateRequestSessions.get(idList); // the call to .get() initiates a XMLHttpRequest for the data, so we now need to switch modes - the // refresh process has started so we're no longer pending, but we are now waiting for the XMLHttpRequest // to return something... uroPendingCommentDataRefresh = false; uroWaitingCommentDataRefresh = true; } else { if(cachedCommentCount > 0) { currentLastCommentID = W.model.updateRequestSessions.objects[uroSelectedURID].comments[cachedCommentCount-1].id; if(currentLastCommentID == uroCachedLastCommentID) { // most recent comment loaded for this UR is the same one that was present at the start of this // refresh process, so kick back into pending mode so we can retry the .get()... uroAddLog('latest comment ID still the same, reverting to pending mode...'); uroPendingCommentDataRefresh = true; } else { // something may have gone awry here - the most recent comment loaded for this UR doesn't have the // same ID as the one present at the start of the refresh process, yet the comment counts still don't // match up, which suggests either a comment got lost along the way or someone else has commented on // the same UR at almost the same time. To get out of the loop this would create, assume that a // mismatch in the IDs means the .get() has completed successfully no matter what the new comment // count is, and take this new count to be the count we were expecting all along... uroAddLog('latest comment ID different, but expected count not correct...'); uroExpectedCommentCount = cachedCommentCount; } } else { uroAddLog('first comment on this UR not received yet, reverting to pending mode...'); uroPendingCommentDataRefresh = true; } } } else { // if the WME session is loaded with a UR already selected, such that WME has opened the UR dialog as part // of the session startup process, adding new comments to the UR cause the cached data to be updated immediately. // This prevents URO+ from switching into waiting mode in the above block of code, so we have to instead do // it here by comparing the cached count against the expected count following the Send click event. if(cachedCommentCount >= uroExpectedCommentCount) { uroPendingCommentDataRefresh = false; uroWaitingCommentDataRefresh = true; uroExpectedCommentCount = null; } // once the cached data has been updated, refilter the URs so that the new comment count is taken into account // immediately for filtering and display purposes if(uroWaitingCommentDataRefresh == true) { uroWaitingCommentDataRefresh = false; uroFilterURs(); uroAddLog('refresh complete'); } } } } function uroAddedComment() { // when the user clicks the Send button to submit a new UR comment, this event handler fires before the new comment is // posted to the server and thus also before the comment list gets updated in the UR dialog. So we take the current // comment count and, if the new comment edit box isn't empty, increment it by 1 to get the expected count. Then we // set the pending flag true to initiate a session refresh on the next 100ms tick uroExpectedCommentCount = W.map.panelRegion.currentView.conversationView.conversation.comments.length; if(document.getElementsByClassName('new-comment-text')[0].value != '') { uroExpectedCommentCount++; uroAddLog('new comment added to UR '+uroSelectedURID+', cache refresh required...'); uroPendingCommentDataRefresh = true; } else { uroPendingCommentDataRefresh = false; } } function uroTenthSecondTick() { if(uroSetupListeners) { if((loginManager.isLoggedIn()) || (uroPracticeMode == true)) { uroSetupListeners = false; if(uroPracticeMode == true) { document.getElementsByClassName("sandbox")[0].style.display = "none"; } // filter markers when the marker objects are modified (this happens whenever WME needs to load fresh marker data // due to having panned/zoomed the map beyond the extents of the previously loaded data) W.model.mapUpdateRequests.events.register("objectschanged", null, uroFilterURs_onObjectsChanged); W.model.mapUpdateRequests.events.register("objectsadded", null, uroFilterURs_onObjectsAdded); W.model.mapUpdateRequests.events.register("objectsremoved", null, uroFilterURs_onObjectsRemoved); W.model.updateRequestSessions.events.register("objectschanged", null, uroUREvent_onObjectsChanged); W.model.updateRequestSessions.events.register("objectsadded", null, uroUREvent_onObjectsAdded); W.model.updateRequestSessions.events.register("objectsremoved", null, uroUREvent_onObjectsRemoved); W.model.cameras.events.register("objectschanged", null, uroFilterCameras); W.model.cameras.events.register("objectsadded", null, uroFilterCameras); W.model.cameras.events.register("objectsremoved", null, uroFilterCameras); W.model.problems.events.register("objectschanged", null, uroFilterProblems); W.model.problems.events.register("objectsadded", null, uroFilterProblems); W.model.problems.events.register("objectsremoved", null, uroFilterProblems); W.model.venues.events.register("objectschanged", null, uroFilterPlaces); W.model.venues.events.register("objectsadded", null, uroFilterPlaces); W.model.venues.events.register("objectsremoved", null, uroFilterPlaces); var userTabs = document.getElementById(uroUserTabId); if(uroPracticeMode == false) { var navTabs = uroTimbonesGetElementsByClassName('nav-tabs', userTabs)[0]; var tabContent = uroTimbonesGetElementsByClassName('tab-content', userTabs)[0]; newtabUR = document.createElement('li'); newtabUR.innerHTML = '<a href="#sidepanel-uroverview" data-toggle="tab">URO+</a>'; navTabs.appendChild(newtabUR); } uroControls.id = "sidepanel-uroverview"; uroControls.className = "tab-pane"; if(uroPracticeMode == false) { tabContent.appendChild(uroControls); } else { userTabs.appendChild(uroControls); } uroAddEventListener('_btnUndoLastHide',"click", uroRemoveLastAddedIgnore, true); uroAddEventListener('_btnClearSessionHides',"click", uroRemoveAllIgnores, true); uroEnableIgnoreListControls(); uroAddEventListener('_btnClearCamWatchList',"click", uroClearCamWatchList, true); uroAddEventListener('_btnSettingsToText',"click", uroSettingsToText, true); uroAddEventListener('_btnTextToSettings',"click", uroTextToSettings, true); uroAddEventListener('_btnResetSettings',"click", uroDefaultSettings, true); uroAddEventListener('_btnClearSettingsText',"click", uroClearSettingsText, true); uroSetOnClick("_linkSelectUserRequests",uroShowURTab); uroSetOnClick("_linkSelectMapProblems",uroShowMPTab); uroSetOnClick("_linkSelectPlaces",uroShowPlacesTab); uroSetOnClick("_linkSelectCameras",uroShowCameraTab); uroSetOnClick("_linkSelectMisc",uroShowMiscTab); uroSetOnClick("_linkSelectOWL",uroShowOWLTab); uroSetOnClick('_cbHideMyComments',uroExclusiveCB); uroSetOnClick('_cbHideAnyComments',uroExclusiveCB); uroSetOnClick('_cbHideIfLastCommenter',uroExclusiveCB); uroSetOnClick('_cbHideIfNotLastCommenter',uroExclusiveCB); uroSetOnClick('_cbHideIfReporterLastCommenter',uroExclusiveCB); uroSetOnClick('_cbHideIfReporterNotLastCommenter',uroExclusiveCB); var dbgMode = "none"; if(uroShowDebugOutput) { dbgMode = "inline"; } document.getElementById('_uroDebugMode').style.display = dbgMode; uroAddEventListener('_uroVersion',"click", uroToggleDebug, true); uroAddLog('finalise onload'); uroLoadSettings(); uroNewLookCheckDetailsRequest(); if(uroGetCBChecked('_cbEnableDTE')) { if(dteControlsIdx != -1) { dteSetNewTabLength(); } else { uroAddLog('ERROR - archive panel not found!'); uroSetStyleDisplay(uroUserTabId,''); } } if(uroGetCBChecked('_cbEnableSRS')) { selectionManager.events.register("selectionchanged", null, srsCheckSidePanel); uroAddLog('added SRS event handler'); } // filter markers as and when the map is moved W.map.events.register("moveend", null, uroFilterItems); W.map.events.register("mousemove", null, uroGetAMs); W.map.events.register("mousemove", null, uroNewLookHighlightedItemsCheck); W.map.events.registerPriority("mousedown", null, uroMouseDown); // trap mousedown on Streetview marker drag document.getElementsByClassName('street-view-control')[0].onmousedown = uroMouseDown; W.map.events.register("mouseup", null, uroMouseUp); uroSetStyles(uroCtrlURs); uroSetStyles(uroCtrlMPs); uroSetStyles(uroCtrlPlaces); uroSetStyles(uroCtrlCameras); uroSetStyles(uroCtrlMisc); uroSetStyles(uroOWL); uroShowURTab(); uroRestyleWMETabs(); uroUserID = loginManager.getLoggedInUser().id; uroFilterItems(); } } else { var mousePos = document.getElementsByClassName('mouse-position')[0].innerHTML; if(uroPopupShown == true) { var hidePopup = false; if((mousePos == '00.00000, 00.00000') && (uroMouseInPopup == false)) { hidePopup = true; } if(document.getElementsByClassName('panel')[0] != undefined) { hidePopup = true; } if(hidePopup == true) { uroHidePopup(); } } if((uroAreaNameHoverObj != null) && (uroAreaNameHoverTime != -1) && (uroAreaNameOverlayShown == false)) { if(++uroAreaNameHoverTime > 5) { uroAreaNameOverlaySetup(); } } uroReplaceAreaNames(false); if(uroPopupTimer > 0) { if(uroMouseInPopup == false) { uroPopupTimer--; } } if(uroPopupTimer == 0) { uroHidePopup(); } // test for the opening or closing of the UR editing dialog var URDialogIsOpen = (document.getElementsByClassName('new-comment-form').length == 1); if(URDialogIsOpen) { var thisSelectedURID = W.map.panelRegion.currentView.conversationView.conversation.getID(); if(thisSelectedURID != uroSelectedURID) { // if the user selects a new UR whilst the editing dialog is still open, treat it in the // same way as if the user had selected that UR with the dialog closed uroURDialogIsOpen = false; } if(uroURDialogIsOpen == false) { // user is editing a new UR uroSelectedURID = thisSelectedURID; document.getElementsByClassName('new-comment-form')[0].getElementsByClassName('btn')[0].addEventListener("click", uroAddedComment, false); uroAddLog('user is editing UR '+uroSelectedURID); uroExpectedCommentCount = W.model.updateRequestSessions.objects[uroSelectedURID].comments.length; } } else if(uroURDialogIsOpen == true) { // dialog was open and has now been closed uroSelectedURID = null; } uroURDialogIsOpen = URDialogIsOpen; if(((uroPendingCommentDataRefresh == true) || (uroWaitingCommentDataRefresh == true)) && (uroSelectedURID != null)) { uroAddLog('check completion of comment data refresh for UR '+uroSelectedURID+' ('+uroPendingCommentDataRefresh+','+uroWaitingCommentDataRefresh+')'); uroGetSelectedURCommentCount(); } var selectedTotal = W.selectionManager.selectedItems.length; if((selectedTotal > 0) && (document.getElementById('_uroDivOWLBtns') == null)) { var selectedClass = W.selectionManager.selectedItems[0].model.CLASS_NAME; var displayAddToOWLBtn = false; var displayUpdateOWLBtn = false; var displayRemoveFromOWLBtn = false; var selectedSegments = false; var selectedLandmarks = false; // WME only seems to allow multi-object selections for segments, so testing the class of the first object in the // selection list tells us the class of any other objects in the list too... if(selectedClass == "Waze.Feature.Vector.Segment") { selectedSegments = true; for(var loop=0; loop<selectedTotal; loop++) { var fid = W.selectionManager.selectedItems[loop].model.attributes.id; var idx = uroIsSegOnWatchList(fid); if(idx == -1) { displayAddToOWLBtn = true; } else { if(uroSegDataChanged(idx)) { displayUpdateOWLBtn = true; } displayRemoveFromOWLBtn = true; } } } else if(selectedClass == "Waze.Feature.Vector.Landmark") { selectedLandmarks = true; for(var loop=0; loop<selectedTotal; loop++) { var fid = W.selectionManager.selectedItems[loop].model.attributes.id; var idx = uroIsPlaceOnWatchList(fid); if(idx == -1) { displayAddToOWLBtn = true; } else { if(uroPlaceDataChanged(idx)) { displayUpdateOWLBtn = true; } displayRemoveFromOWLBtn = true; } } } var btnHTML = '<div id="_uroDivOWLBtns">'; if((displayAddToOWLBtn == true) && (displayUpdateOWLBtn == false)) { btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Add to OWL</button>'; } else if((displayUpdateOWLBtn == true) && (displayAddToOWLBtn == false)) { btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Update OWL</button>'; } else if((displayAddToOWLBtn == true) && (displayUpdateOWLBtn == true)) { btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Add to & Update OWL</button>'; } if(displayRemoveFromOWLBtn == true) { btnHTML += '<button class="btn btn-default" id="_btnRemoveOWL">Remove from OWL</button>'; } btnHTML += '</div>'; /* // once we get around to enabling these again, remember that altering the inner HTML of the // segment-edit-general panel when the selected segment is part of a roundabout then disables // the onclick handler for the select roundabout button... // // also remember that the current WME beta has yet another different side panel arrangement if(selectedSegments == true) { document.getElementById("segment-edit-general").innerHTML += btnHTML; } else if(selectedLandmarks == true) { document.getElementById("landmark-edit-general").innerHTML += btnHTML; } if((displayAddToOWLBtn == true)||(displayUpdateOWLBtn == true)) { if(selectedSegments == true) { uroAddEventListener('_btnAddUpdateOWL','click', uroAddUpdateSegWatchList, true); } else { uroAddEventListener('_btnAddUpdateOWL','click', uroAddUpdatePlaceWatchList, true); } } if(displayRemoveFromOWLBtn == true) { if(selectedSegments == true) { uroAddEventListener('_btnRemoveOWL','click', uroRemoveSegFromWatchList, true); } else { uroAddEventListener('_btnRemoveOWL','click', uroRemovePlaceFromWatchList, true); } } */ } } } function uroToggleURCtrls() { uroCtrlsHidden = !uroCtrlsHidden; if (!uroCtrlsHidden) { document.getElementById('_hideUCCtrl').innerHTML = "hide"; if(uroCurrentTab == 1) uroShowURTab(); else if(uroCurrentTab == 2) uroShowMPTab(); else if(uroCurrentTab == 3) uroShowPlacesTab(); else if(uroCurrentTab == 4) uroShowCameraTab(); else if(uroCurrentTab == 5) uroShowOWLTab(); else if(uroCurrentTab == 6) uroShowMiscTab(); } else { document.getElementById('_hideUCCtrl').innerHTML = "show"; uroSetStyleDisplay('uroCtrlURs','none'); uroSetStyleDisplay('uroCtrlMPs','none'); uroSetStyleDisplay('uroCtrlCameras','none'); uroSetStyleDisplay('uroCtrlMisc','none'); uroSetStyleDisplay('uroOWL','none'); } return false; } function uroActiveTab(_id) { var e = document.getElementById(_id); e.style.backgroundColor = "aliceblue"; e.style.borderTop = "1px solid"; e.style.borderLeft = "1px solid"; e.style.borderRight = "1px solid"; e.style.borderBottom = "0px solid"; } function uroInactiveTab(_id) { var e = document.getElementById(_id); e.style.backgroundColor = "white"; e.style.borderTop = "0px solid"; e.style.borderLeft = "0px solid"; e.style.borderRight = "0px solid"; e.style.borderBottom = "1px solid"; } function uroInactiveAllTabs() { uroInactiveTab("_tabSelectCameras"); uroInactiveTab("_tabSelectMapProblems"); uroInactiveTab("_tabSelectMisc"); uroInactiveTab("_tabSelectUserRequests"); uroInactiveTab("_tabSelectCWL"); uroInactiveTab("_tabSelectPlaces"); if(!uroCtrlsHidden) { uroSetStyleDisplay('uroCtrlURs','none'); uroSetStyleDisplay('uroCtrlMPs','none'); uroSetStyleDisplay('uroCtrlCameras','none'); uroSetStyleDisplay('uroCtrlMisc','none'); uroSetStyleDisplay('uroOWL','none'); uroSetStyleDisplay('uroCtrlPlaces','none'); } } function uroShowURTab() { uroInactiveAllTabs(); uroActiveTab("_tabSelectUserRequests"); uroCurrentTab = 1; if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlURs','block'); return false; } function uroShowMPTab() { uroInactiveAllTabs(); uroActiveTab("_tabSelectMapProblems"); uroCurrentTab = 2; if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMPs','block'); return false; } function uroShowPlacesTab() { uroInactiveAllTabs(); uroActiveTab("_tabSelectPlaces"); uroCurrentTab = 3; if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlPlaces','block'); return false; } function uroShowCameraTab() { uroInactiveAllTabs(); uroActiveTab("_tabSelectCameras"); uroCurrentTab = 4; if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlCameras','block'); return false; } function uroShowOWLTab() { uroInactiveAllTabs(); uroActiveTab("_tabSelectCWL"); uroCurrentTab = 5; if(!uroCtrlsHidden) uroSetStyleDisplay('uroOWL','block'); uroOWLUpdateHTML(); return false; } function uroShowMiscTab() { uroInactiveAllTabs(); uroActiveTab("_tabSelectMisc"); uroCurrentTab = 6; if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMisc','block'); return false; } function uroTimbonesGetElementsByClassName(classname, node) { if(!node) node = document.getElementsByTagName("body")[0]; var a = []; var re = new RegExp('\\b' + classname + '\\b'); var els = node.getElementsByTagName("*"); for (var i=0,j=els.length; i<j; i++) if (re.test(els[i].className)) a.push(els[i]); return a; } function uroNewLookCheckDetailsRequest() { var thisurl = document.location.href; var doRetry = true; endmarkerpos = thisurl.indexOf('&endshow'); showmarkerpos = thisurl.indexOf('&showturn='); if((endmarkerpos != -1) && (showmarkerpos != -1)) { showmarkerpos += 10; uroAddLog('showturn tab opened'); var urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos); uroAddLog(' turn problem ID = '+urID); try { W.map.problemLayer.markers[urID].icon.imageDiv.click(); doRetry = false; } catch(err) { uroAddLog('problems not fully loaded, retrying...'); } if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500); } else { showmarkerpos = thisurl.indexOf('&showpur='); if((endmarkerpos != -1) && (showmarkerpos != -1)) { showmarkerpos += 9; uroAddLog('showPUR tab opened'); var urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos); uroAddLog(' PUR ID = '+urID); try { W.map.placeUpdatesLayer.markers[urID].icon.imageDiv.click(); doRetry = false; } catch(err) { uroAddLog('PURs not fully loaded, retrying...'); } if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500); } } } function uroUpdateMPSolverList() { if(Object.keys(W.model.problems.objects).length == 0) { return; } var resolverList = []; var selector = document.getElementById('_selectMPUserID'); var selectedUser = null; if(selector.selectedOptions[0] != undefined) { selectedUser = parseInt(selector.selectedOptions[0].value); } while(selector.options.length > 0) { selector.options.remove(0); } var selectedIdx = 0; var idx = 0; for (var mpobj in W.model.problems.objects) { var prob = W.model.problems.objects[mpobj]; if(prob.attributes.resolvedBy != null) { var userID = prob.attributes.resolvedBy; var userName = W.model.users.objects[userID].userName; if(resolverList.indexOf(userName) == -1) { resolverList.push(userName); selector.options.add(new Option(userName, userID)); if(userID == selectedUser) { selectedIdx = idx; } idx++; } } } if(selectedIdx != null) { selector.selectedIndex = selectedIdx; } } function uroUpdateResolverList() { if(Object.keys(W.model.mapUpdateRequests.objects).length == 0) { return; } var resolverList = []; var selector = document.getElementById('_selectURResolverID'); var selectedUser = null; if(selector.selectedOptions[0] != undefined) { selectedUser = parseInt(selector.selectedOptions[0].value); } while(selector.options.length > 0) { selector.options.remove(0); } var selectedIdx = 0; var idx = 0; for (var urobj in W.model.mapUpdateRequests.objects) { var ureq = W.model.mapUpdateRequests.objects[urobj]; if(ureq.attributes.resolvedBy != null) { var userID = ureq.attributes.resolvedBy; var userName = W.model.users.objects[userID].userName; if(resolverList.indexOf(userName) == -1) { resolverList.push(userName); selector.options.add(new Option(userName, userID)); if(userID == selectedUser) { selectedIdx = idx; } idx++; } } } if(selectedIdx != null) { selector.selectedIndex = selectedIdx; } } function uroUpdateUserList() { if(Object.keys(W.model.updateRequestSessions.objects).length == 0) return; var selector = document.getElementById('_selectURUserID'); var selectedUser = null; if(selector.selectedOptions[0] != undefined) { selectedUser = parseInt(selector.selectedOptions[0].value); } while(selector.options.length > 0) { selector.options.remove(0); } var selectedIdx = null; var listedIDs = []; for(var ursIdx in W.model.updateRequestSessions.objects) { var ursObj = W.model.updateRequestSessions.objects[ursIdx]; if(ursObj.comments.length > 0) { for(var cidx=0; cidx < ursObj.comments.length; cidx++) { var userID = ursObj.comments[cidx].userID; if((listedIDs.indexOf(userID) == -1) && (userID != -1)) { listedIDs.push(userID); } } } } if(listedIDs.length > 0) { var users = W.model.users.getByIds(listedIDs); for(var idx=0; idx<listedIDs.length; idx++) { selector.options.add(new Option(users[idx].userName, listedIDs[idx])); if(listedIDs[idx] == selectedUser) { selectedIdx = idx; } } } if(selectedIdx != null) { selector.selectedIndex = selectedIdx; } } function uroSetStyles(obj) { obj.style.fontSize = '12px'; obj.style.lineHeight = '100%'; obj.style.overflow = 'auto'; obj.style.height = (window.innerHeight * 0.55) + 'px'; } function uroPopulatePlacesTab() { var tHTML = ''; tHTML += '<b>Filter PURs by category/status:</b><br>'; tHTML += '<input type="checkbox" id="_cbFilterUneditablePlaceUpdates">Ones I can\'t edit</input><br>'; tHTML += '<input type="checkbox" id="_cbFilterLockRankedPlaceUpdates">Ones with non-zero lockRanks</input><br>'; tHTML += '<input type="checkbox" id="_cbFilterNewPlacePUR">Ones for new places</input><br>'; tHTML += '<input type="checkbox" id="_cbFilterUpdatedDetailsPUR">Ones for updated place details</input><br>'; tHTML += '<input type="checkbox" id="_cbFilterNewPhotoPUR">Ones for new photos</input><br>'; tHTML += '<input type="checkbox" id="_cbFilterFlaggedPUR">Ones flagged for attention</input><br>'; tHTML += '<br><input type="checkbox" id="_cbLeavePURGeos">Don\'t hide place polygons/points</input><br>'; tHTML += '<br><input type="checkbox" id="_cbInvertPURFilters">Invert PUR filters</input><br>'; tHTML += '<br><b>Filter PURs by severity:</b><br>'; tHTML += '<input type="checkbox" id="_cbPURFilterLowSeverity">Low</input> '; tHTML += '<input type="checkbox" id="_cbPURFilterMediumSeverity">Medium</input> '; tHTML += '<input type="checkbox" id="_cbPURFilterHighSeverity">High</input>'; tHTML += '<br><b>Filter PURs by age of submission:</b><br>'; tHTML += '<input type="checkbox" id="_cbEnablePURMinAgeFilter">Hide PURs less than </input>'; tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPURFilterMinDays"> days old<br>'; tHTML += '<input type="checkbox" id="_cbEnablePURMaxAgeFilter">Hide PURs more than </input>'; tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPURFilterMaxDays"> days old<br>'; tHTML += '<hr>'; tHTML += '<br><b>Filter Places by state:</b><br>'; tHTML += 'Hide if last edited<br>'; tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedLessThan"> less than </input>'; tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMinDays"> days ago<br>'; tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedMoreThan"> more than </input>'; tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMaxDays"> days ago<br>'; tHTML += '<br>Hide if locked at level:<br>'; tHTML += ' <input type="checkbox" id="_cbHidePlacesL0">1</input>'; tHTML += ' <input type="checkbox" id="_cbHidePlacesL1">2</input>'; tHTML += ' <input type="checkbox" id="_cbHidePlacesL2">3</input>'; tHTML += ' <input type="checkbox" id="_cbHidePlacesL3">4</input>'; tHTML += ' <input type="checkbox" id="_cbHidePlacesL4">5</input>'; tHTML += ' <input type="checkbox" id="_cbHidePlacesL5">6</input>'; tHTML += '<br><br><input type="checkbox" id="_cbHidePhotoPlaces">Hide or </input>'; tHTML += '<input type="checkbox" id="_cbHideNoPhotoPlaces">show ones with photos</input><br>'; tHTML += '<br><br><b>Filter Places by category:</b><br>'; for(var i=0; i<W.Config.venues.categories.length; i++) { parentCategory = W.Config.venues.categories[i]; localisedName = I18n.translations[I18n.locale].venues.categories[parentCategory]; tHTML += '<input type="checkbox" id="_cbPlacesFilter-'+parentCategory+'"><b>'+localisedName+'</b></input><br>'; for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++) { subCategory = W.Config.venues.subcategories[parentCategory][ii]; localisedName = I18n.translations[I18n.locale].venues.categories[subCategory]; tHTML += ' <input type="checkbox" id="_cbPlacesFilter-'+subCategory+'">'+localisedName+'</input><br>'; } } tHTML += '<input type="checkbox" id="_cbFilterPrivatePlaces"><b>Private Places</b></input><br>'; tHTML += '<br><input type="checkbox" id="_cbInvertPlacesFilter">Invert Place filters?</input>'; uroCtrlPlaces.innerHTML = tHTML; } function uroWazeBits() { // "fake" uroWazeBits() function which only performs layer scan, to stop the uroWazeBits() call in WMETB from // messing around with other stuff in the actual uroWazeBits() function (now renamed uroRealWazeBits...) that // really only ought to be called once. for(i=0;i<W.map.layers.length;i++) { if(W.map.layers[i].name == 'Spotlight') uroMaskLayer = i; if(W.map.layers[i].name.indexOf('Waze.Control.SelectHighlightFeature') != -1) uroRootContainer = W.map.layers[i].div.id; if(W.map.layers[i].name == 'Node Connections') uroTurnsLayerIdx = i; } uroPlacesRoot = W.map.landmarkLayer.id + '_vroot'; for(i=0;i<W.map.controls.length;i++) { if(W.map.controls[i].CLASS_NAME == 'Waze.View.ArchivePanel') dteControlsIdx = i; else if(W.map.controls[i].CLASS_NAME == 'Waze.Control.Archive') dteControlsIdx = i; if(W.map.controls[i].id != null) { if(W.map.controls[i].id.indexOf('UpdateRequests') != -1) uroURControlsIdx = i; if(W.map.controls[i].id.indexOf('MapProblems') != -1) uroProblemControlsIdx = i; } } uroAddLog('uroMaskLayer at idx '+uroMaskLayer); uroAddLog('Turns layer at idx '+uroTurnsLayerIdx); uroAddLog('uroRootContainer = '+uroRootContainer); uroAddLog('Places root layer = '+uroPlacesRoot); } function uroRealWazeBits() { if(document.getElementsByClassName("sandbox").length > 0) { uroPracticeMode = true; } else { uroPracticeMode = false; } uroAddLog('adding WazeBits...'+uroToHex(uroWazeBitsPresent,4)); if((uroWazeBitsPresent & 0x0001) == 0) { if(typeof unsafeWindow.W != "undefined") { if(typeof unsafeWindow.W.controller != "undefined") { if(typeof unsafeWindow.W.controller.map != "undefined") { uroAddLog(' W.map OK'); W.map = unsafeWindow.W.controller.map; uroWazeBitsPresent |= 0x0001; } } } } if((uroWazeBitsPresent & 0x0002) == 0) { if(typeof unsafeWindow.W != "undefined") { if(typeof unsafeWindow.W.controller != "undefined") { if(typeof unsafeWindow.W.controller.model != "undefined") { uroAddLog(' W.model OK'); W.model = unsafeWindow.W.controller.model; uroWazeBitsPresent |= 0x0002; } } } } if((uroWazeBitsPresent & 0x0004) == 0) { if(typeof unsafeWindow.W != "undefined") { if(typeof unsafeWindow.W.app != "undefined") { if(typeof unsafeWindow.W.app.loginManager != "undefined") { uroAddLog(' loginManager OK'); loginManager = unsafeWindow.W.app.loginManager; uroWazeBitsPresent |= 0x0004; } } } } if((uroWazeBitsPresent & 0x0008) == 0) { if(typeof unsafeWindow.W != "undefined") { if(typeof unsafeWindow.W.geometryEditing != "undefined") { if(typeof unsafeWindow.W.geometryEditing.selectionManager != "undefined") { uroAddLog(' selectionManager OK'); selectionManager = unsafeWindow.W.geometryEditing.selectionManager; uroWazeBitsPresent |= 0x0008; } } } } if((uroWazeBitsPresent & 0x0010) == 0) { if(typeof unsafeWindow.OpenLayers != "undefined") { uroAddLog(' OpenLayers OK'); OpenLayers = unsafeWindow.OpenLayers; uroWazeBitsPresent |= 0x0010; } } if((uroWazeBitsPresent & 0x0020) == 0) { if(typeof unsafeWindow.Waze != "undefined") { uroAddLog(' Waze OK'); Waze = unsafeWindow.Waze; uroWazeBitsPresent |= 0x0020; } } if((uroWazeBitsPresent & 0x0040) == 0) { if(document.getElementById('user-tabs') != null) { uroUserTabId = 'user-tabs'; uroAddLog(' user-tabs OK'); uroWazeBitsPresent |= 0x0040; } else if(document.getElementById('user-info') != null) { uroUserTabId = 'user-info'; uroAddLog(' user-info OK'); uroWazeBitsPresent |= 0x0040; } } if((uroWazeBitsPresent & 0x0080) == 0) { if(uroPracticeMode == true) { uroAddLog(' sidepanel-drives ignored in practice mode'); uroWazeBitsPresent |= 0x0080; } else { if(document.getElementById('sidepanel-drives') != null) { uroAddLog(' sidepanel-drives OK'); uroWazeBitsPresent |= 0x0080; } } } if((uroWazeBitsPresent & 0x0100) == 0) { if(typeof unsafeWindow.I18n != "undefined") { uroAddLog(' I18n OK'); uroWazeBitsPresent |= 0x0100; } } if(uroWazeBitsPresent != 0x01FF) setTimeout(uroRealWazeBits,250); else if((loginManager.isLoggedIn() == false) && (uroPracticeMode == false)) { uroAddLog('Waiting for user log-in...'); setTimeout(uroRealWazeBits,1000); } else { uroAddLog('All WazeBits present and correct...'); uroDOMHasTurnProblems = (W.model.turnProblems != undefined); uroPopulatePlacesTab(); uroControls.appendChild(uroCtrlURs); uroControls.appendChild(uroCtrlMPs); uroControls.appendChild(uroCtrlPlaces); uroControls.appendChild(uroCtrlCameras); uroControls.appendChild(uroOWL); uroControls.appendChild(uroCtrlMisc); uroControls.appendChild(uroCtrlHides); uroControls.appendChild(uroAMList); uroCtrlURs.onclick = uroFilterItems_URTabClick; uroCtrlMPs.onclick = uroFilterItems_MPTabClick; uroCtrlPlaces.onclick = uroFilterItems_PlacesTabClick; uroCtrlCameras.onclick = uroFilterItems_CamerasTabClick; uroCtrlMisc.onclick = uroFilterItems_MiscTabClick; uroWazeBits(); uroDiv.addEventListener("mouseover", uroEnterPopup, false); uroDiv.addEventListener("mouseout", uroExitPopup, false); if(sessionStorage.UROverview_FID_IgnoreList == null) sessionStorage.UROverview_FID_IgnoreList = ''; if(sessionStorage.UROverview_FID_WatchList == null) sessionStorage.UROverview_FID_WatchList = ''; if(uroConfirmIntercepted == false) uroAddInterceptor(); setInterval(uroTenthSecondTick,100); uroShowDebugOutput = false; } } function uroAddInterceptor() { uroAddLog('Adding interceptor function...'); // add interceptor function for confirm(), so that we can auto-select the "OK" option when solving URs // which have pending question... _confirm = unsafeWindow.confirm; unsafeWindow.confirm = function(msg) { if((I18n.translations[I18n.locale].update_requests.panel.confirm == msg) && (uroGetCBChecked('_cbDisablePendingQuestions') == true)) { uroAddLog('Intercepted pending comments confirmation...'); return true; } else if(typeof(msg) == 'undefined') { uroAddLog('Intercepted blank confirmation...'); return true; } else { return _confirm(msg); } }; uroConfirmIntercepted = true; } function uroEnterPopup() { uroMouseInPopup = true; } function uroExitPopup() { uroMouseInPopup = false; } function uroToggleDebug() { uroShowDebugOutput = !uroShowDebugOutput; var dbgMode = "none"; if(uroShowDebugOutput) { dbgMode = "inline"; } document.getElementById('_uroDebugMode').style.display = dbgMode; } function uroInitialise() { uroGlobals(); if(document.URL.indexOf('editor-beta') != -1) uroBetaEditor = true; // create a new div to display the UR details floaty-box uroDiv = document.createElement('div'); uroDiv.id = "uroDiv"; uroDiv.style.position = 'absolute'; uroDiv.style.visibility = 'hidden'; uroDiv.style.top = '0'; uroDiv.style.left = '0'; uroDiv.style.zIndex = 100; uroDiv.style.backgroundColor = 'aliceblue'; uroDiv.style.borderWidth = '3px'; uroDiv.style.borderStyle = 'solid'; uroDiv.style.borderRadius = '10px'; uroDiv.style.boxShadow = '5px 5px 10px Silver'; uroDiv.style.padding = '4px'; document.body.appendChild(uroDiv); uroControls = document.createElement('section'); uroControls.style.fontSize = '12px'; uroControls.id = 'uroControls'; if(navigator.userAgent.indexOf('Chrome') == -1) { var updateURL = 'https://greasyfork.org/scripts/1952-uroverview-plus-uro'; } else { var updateURL = 'https://chrome.google.com/webstore/detail/uroverview/amdamgkgchnbaopmphhjapmjcdghdphi'; } //tabbyHTML = '<input type="checkbox" id="_cbUROMasterEnable" /> '; tabbyHTML = '<b><a href="'+updateURL+'" target="_blank">UROverview Plus</a></b> <label id="_uroVersion">'+uroVersion+'</label>'; tabbyHTML += '<label id="_uroDebugMode">(dbg)</label>'; tabbyHTML += '<p><table border=0 width="100%"><tr>'; tabbyHTML += '<td valign="center" align="center" id="_tabSelectUserRequests"><a href="#" id="_linkSelectUserRequests" style="text-decoration:none;font-size:12px">URs</a></td>'; tabbyHTML += '<td valign="center" align="center" id="_tabSelectMapProblems"><a href="#" id="_linkSelectMapProblems" style="text-decoration:none;font-size:12px">MPs</a></td>'; tabbyHTML += '<td valign="center" align="center" id="_tabSelectPlaces"><a href="#" id="_linkSelectPlaces" style="text-decoration:none;font-size:12px">Places</a></td>'; tabbyHTML += '<td valign="center" align="center" id="_tabSelectCameras"><a href="#" id="_linkSelectCameras" style="text-decoration:none;font-size:12px">Cams</a></td>'; tabbyHTML += '<td valign="center" align="center" id="_tabSelectCWL"><a href="#" id="_linkSelectOWL" style="text-decoration:none;font-size:12px">OWL</a></td>'; tabbyHTML += '<td valign="center" align="center" id="_tabSelectMisc"><a href="#" id="_linkSelectMisc" style="text-decoration:none;font-size:12px">Misc</a></td>'; tabbyHTML += '</tr></table>'; uroControls.innerHTML = tabbyHTML; uroCtrlURs = document.createElement('p'); uroCtrlMPs = document.createElement('p'); uroCtrlCameras = document.createElement('p'); uroOWL = document.createElement('p'); uroCtrlMisc = document.createElement('p'); uroAMList = document.createElement('div'); uroCtrlHides = document.createElement('div'); uroCtrlPlaces = document.createElement('p'); // UR controls tab uroCtrlURs.id = "uroCtrlURs"; uroCtrlURs.innerHTML = '<br>'; uroCtrlURs.innerHTML += '<b>Hide URs by type:</b><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWazeAuto">Waze Automatic</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectTurn">Incorrect turn</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectAddress">Incorrect address</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectRoute">Incorrect route</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoundabout">Missing roundabout</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterGeneralError">General error</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterTurnNotAllowed">Turn not allowed</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectJunction">Incorrect junction</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingBridgeOverpass">Missing bridge overpass</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWrongDrivingDirection">Wrong driving direction</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingExit">Missing exit</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoad">Missing road</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterBlockedRoad">Blocked road</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingLandmark">Missing Landmark</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUndefined">Undefined</input><br>'; uroCtrlURs.innerHTML += ' <i>Specially tagged types</i><br>'; uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterRoadworks">[ROADWORKS]</input><br>'; uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterConstruction">[CONSTRUCTION]</input><br>'; uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterClosure">[CLOSURE]</input><br>'; uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterEvent">[EVENT]</input><br>'; uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterNote">[NOTE]</input><br><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbInvertURFilter">Invert operation of type filters?</input><br>'; uroCtrlURs.innerHTML += '<hr>'; uroCtrlURs.innerHTML += '<br><b>Hide by state:</b><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterOpenUR">Open</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterClosedUR">Closed</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterSolved">Solved</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUnidentified">Not identified</input><br><br>'; uroCtrlURs.innerHTML += '<br><b>Filter URs by age of submission:</b><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinAgeFilter">Hide URs less than </input>'; uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinDays"> days old<br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxAgeFilter">Hide URs more than </input>'; uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxDays"> days old<br>'; uroCtrlURs.innerHTML += '<br><b>Filter URs by description text:</b><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBePresent">Hide</input> or '; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBeAbsent">show</input> URs with no description<br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBePresent">Hide URs not including </input>'; uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordPresent"><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBeAbsent">Hide URs including </input>'; uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordAbsent"><br>'; uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbCaseInsensitive">Case-insensitive matches?</input><br>'; uroCtrlURs.innerHTML += '<br><b>Hide URs by comments/following:</b><br>'; uroCtrlURs.innerHTML += '<i>With comments from me?</i><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyComments">Yes </input>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideAnyComments">No</input><br>'; uroCtrlURs.innerHTML += '<i>If last comment made by me?</i><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfLastCommenter">Yes </input>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfNotLastCommenter">No </input><br>'; uroCtrlURs.innerHTML += '<i>If last comment made by UR reporter?</i><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterLastCommenter">Yes </input>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterNotLastCommenter">No</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinCommentsFilter">With less than </input>'; uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinComments"> comments<br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxCommentsFilter">With more than </input>'; uroCtrlURs.innerHTML += '<input type="number" min="0" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxComments"> comments<br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyFollowed">Ones I am or </input>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyUnfollowed">am not following</input><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter2">Last comment less than </input>'; uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays2"> days ago<br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter">Last comment more than </input>'; uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays"> days ago<br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURUserIDFilter">Without comments from user</input>'; uroCtrlURs.innerHTML += '<select id="_selectURUserID" style="width:80%; height:22px;"></select><br>'; uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURResolverIDFilter">Not resolved by user</input>'; uroCtrlURs.innerHTML += '<select id="_selectURResolverID" style="width:80%; height:22px;"></select>'; uroCtrlURs.innerHTML += '<br><br><input type="checkbox" id="_cbNoFilterForTaggedURs"><b>Don\'t apply state/age filters to tagged URs</b></input><br>'; // Map problems controls tab uroCtrlMPs.id = "uroCtrlMPs"; uroCtrlMPs.innerHTML = '<br>'; uroCtrlMPs.innerHTML += '<b>Filter MPs by type:</b><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingJunction">Missing junction</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingRoad">Missing road</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterCrossroadsJunctionMissing">Missing crossroads</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterDrivingDirectionMismatch">Driving direction mismatch</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRoadTypeMismatch">Road type mismatch</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRestrictedTurn">Restricted turn might be allowed</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnknownProblem">Unknown problem type</input><br><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterTurnProblem">Turn Problems</input><br><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterReopenedProblem">Reopened Problems</input><br><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbInvertMPFilter">Invert operation of type filters?</input><br>'; uroCtrlMPs.innerHTML += '<br><b>Hide closed/solved/unidentified Problems:</b><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterClosed">Closed</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterSolved">Solved</input><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnidentified">Not identified</input><br><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPClosedUserIDFilter">Closed</input> or '; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPNotClosedUserIDFilter">Not Closed</input> by user'; uroCtrlMPs.innerHTML += '<select id="_selectMPUserID" style="width:80%; height:22px;"></select><br>'; uroCtrlMPs.innerHTML += '<br><b>Hide problems (not turn) by severity:</b><br>'; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterLowSeverity">Low</input> '; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMediumSeverity">Medium</input> '; uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterHighSeverity">High</input><br>'; // Places filtering tab uroCtrlPlaces.id = "uroCtrlPlaces"; uroCtrlPlaces.innerHTML = 'Places filter list being populated, please wait...'; // Camera controls tab uroCtrlCameras.id = "uroCtrlCameras"; uroCtrlCameras.innerHTML = '<br><b>Show Cameras by creator:</b><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowWorldCams" checked>world_* users</input><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowUSACams" checked>usa_* users</input><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonWorldCams" checked>other users</input><br>'; uroCtrlCameras.innerHTML += '<br><input type="checkbox" id="_cbShowOnlyMyCams">Show ONLY cameras created/edited by me</input><br>'; uroCtrlCameras.innerHTML += '<br><b>Show Cameras by approval status:</b><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowApprovedCams" checked>approved</input><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonApprovedCams" checked>non-approved</input><br>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowOlderCreatedNonApproved"> if created more than </input>'; uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinCreatedDays"> days ago<br>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowOlderUpdatedNonApproved"> if updated more than </input>'; uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinUpdatedDays"> days ago<br>'; uroCtrlCameras.innerHTML += '<br><b>Show Cameras by type:</b><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowSpeedCams" checked>Speed</input><br>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowIfMPHSpeedSet" checked> with MPH speeds</input><br>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowIfKPHSpeedSet" checked> with KM/H speeds</input><br>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowIfNoSpeedSet" checked> with no speed</input><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowRedLightCams" checked>Red Light</input><br>'; uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowDummyCams" checked>Dummy</input><br>'; uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by creator:</b><br>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByMe">me</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank0">L1</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank1">L2</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank2">L3</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank3">L4</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank4">L5</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank5">L6</input>'; uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by updater:</b><br>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByMe">me</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank0">L1</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank1">L2</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank2">L3</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank3">L4</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank4">L5</input>'; uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank5">L6</input>'; uroCtrlCameras.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideCWLCams">Hide cameras on watchlist</input></b><br>'; // Object watchlist tab uroOWL.id = "uroOWL"; uroOWLUpdateHTML(); // Misc controls tab uroCtrlMisc.id = "uroCtrlMisc"; uroCtrlMisc.innerHTML = '<br><b>Use default conversation markers:</b><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeConvoMarkers" checked>in public WME</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeBetaConvoMarkers" checked>in beta WME</input><br>'; uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbCommentCount">Show comment count on UR markers</input></b><br>'; uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbURBackfill">Backfill UR data</input></b><br>'; uroCtrlMisc.innerHTML += '<br><br><b>Marker Unstacking:</b><br>'; uroCtrlMisc.innerHTML += 'Distance threshold: <input type="number" min="1" max="30" value="15" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputUnstackSensitivity"><br>'; uroCtrlMisc.innerHTML += 'Disable below zoom: <input type="number" min="0" max="10" value="3" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputUnstackZoomLevel"><br>'; uroCtrlMisc.innerHTML += '<br><br><b>Use custom marker for URs tagged as:</b><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomRoadworksMarkers">[ROADWORKS]</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomConstructionMarkers">[CONSTRUCTION]</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomClosuresMarkers">[CLOSURE]</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomEventsMarkers">[EVENT]</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomNotesMarkers">[NOTE]</input><br>'; uroCtrlMisc.innerHTML += '<br><br><b>Popup entry timeout:</b><br>'; uroCtrlMisc.innerHTML += '<input type="number" min="1" max="10" value="2" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPopupEntryTimeout"> secs/10'; uroCtrlMisc.innerHTML += '<br><br><b>Disable popup for:</b><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitURPopup">URs</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitMPPopup">MPs</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitCamPopup">Cameras</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitSegPopup">Segments</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitLandmarkPopup">Landmarks</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitPUPopup">Place Updates</input><br>'; uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbWhiteBackground">Use custom background colour</input></b><br>'; uroCtrlMisc.innerHTML += 'R:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundRed">'; uroCtrlMisc.innerHTML += 'G:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundGreen">'; uroCtrlMisc.innerHTML += 'B:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundBlue"><br>'; uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideAMLayer">Hide Area Manager polygons</input></b><br>'; uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbDisablePlacesFiltering">Disable Places filtering</input></b><br>'; uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbDisablePendingQuestions">Disable UR Pending Questions confirmation</input></b><br>'; uroCtrlMisc.innerHTML += '<br><b>Enable integrated scripts:</b><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableDTE">Drive Tab Enhancement</input><br>'; uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableSRS">Select Roundabout Segments</input><br>'; uroCtrlMisc.innerHTML += '<br><br><b>Settings backup/restore/reset:</b><br>'; uroCtrlMisc.innerHTML += '<input type="button" id="_btnSettingsToText" value="Backup"> '; uroCtrlMisc.innerHTML += '<input type="button" id="_btnTextToSettings" value="Restore"> | '; uroCtrlMisc.innerHTML += '<input type="button" id="_btnResetSettings" value="Reset"><br><br>'; uroCtrlMisc.innerHTML += '<textarea id="_txtSettings" value="" /><br>'; uroCtrlMisc.innerHTML += '<input type="button" id="_btnClearSettingsText" value="Clear"><br>'; // footer for tabs container uroCtrlHides.id = 'uroCtrlHides'; uroCtrlHides.innerHTML = '<input type="button" id="_btnUndoLastHide" value="Undo last hide"> '; uroCtrlHides.innerHTML += '<input type="button" id="_btnClearSessionHides" value="Undo all hides"><p>'; // footer for AM list uroAMList.id = 'uroAMList'; window.addEventListener("beforeunload", uroSaveSettings, false); uroRealWazeBits(); } function dteAddHeader() { rlcObj = document.getElementsByClassName("result-list-container"); if(typeof rlcObj == "undefined") return; if(typeof rlcObj[0].children[0] == "undefined") return; if(typeof rlcObj[0].children[0].innerHTML == "undefined") return; var thtml = rlcObj[0].children[0].innerHTML; if(thtml.indexOf('Full drive history') == -1) { thtml += '<br><br><i><small>Full drive history goes back to '+dteOldestFullDrive.toDateString()+'</small></i>'; rlcObj[0].children[0].innerHTML = thtml; } } function dteSetNewTabLength() { uroAddLog('altering ResultsPerPage parameter...'); var t = document.getElementById('sidepanel-drives'); t.style.overflow = 'auto'; t.style.height = (window.innerHeight * 0.6) + 'px'; baseloc = 'https://'+window.location.hostname+Waze.Config.api_base+'/Archive/MyList?minDistance=1000'; var a = new XMLHttpRequest(); var idxCheckFullDrive = 0; var fullDrives = 0; var foundMissingDrive = false; while(!foundMissingDrive) { uroSetStyleDisplay(uroUserTabId,'none'); var loc = baseloc+'&offset='+fullDrives+'&count=5'; uroAddLog('requesting '+loc); var retries = 0; while(retries < 3) { a.open('GET',loc,false); a.send(); if(a.responseText != "") { break; } retries++; } if(a.responseText != "") { var b = JSON.parse(a.responseText); var loadedDrives = b.archives.objects.length; uroAddLog('received '+loadedDrives+' drives'); if(loadedDrives != 5) foundMissingDrive = true; for(var loop=0; loop < loadedDrives; loop++) { if(b.archives.objects[loop].hasFullSession == false) { foundMissingDrive = true; } else { fullDrives++; dteOldestFullDrive = new Date(b.archives.objects[loop].startTime); } } } else { foundMissingDrive = true; } } uroAddLog(fullDrives+' full drives in history'); uroAddLog('oldest drives are on '+dteOldestFullDrive.toDateString()); if(fullDrives < 5) { fullDrives = 5; uroAddLog('insufficient full drives, using standard drives tab'); } else if(fullDrives > 50) { uroAddLog('too many full drives for a single tab page, splitting over multiple pages...'); fullDrives = Math.ceil(fullDrives/Math.ceil(fullDrives/50)); } uroSetStyleDisplay(uroUserTabId,''); if((dteOldestFullDrive - dteEpoch) > 0) { uroAddLog('updating drives tab...'); W.map.controls[dteControlsIdx].sidePanelView.ResultsPerPage = fullDrives; setInterval(dteAddHeader,250); setInterval(dteCheckDriveListChanges,250); } } function dteCheckDriveListChanges() { var drivesShown = document.getElementById('sidepanel-drives').getElementsByClassName('result session').length; if(drivesShown > 0) { var topID = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[0].getAttribute('data-id'); if(topID != dteTopID) { dteTopID = topID; for(var loop = 0;loop < drivesShown; loop++) { var driveID = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[loop].getAttribute('data-id'); var driveObj = W.model.archives.objects[driveID]; var driveDistance = driveObj.totalRoadMeters; var driveSecs = Math.floor((driveObj.endTime - driveObj.startTime) / 1000); var driveHours = Math.floor(driveSecs / 3600); driveSecs -= (driveHours * 3600); var driveMins = Math.floor(driveSecs / 60); driveSecs -= (driveMins * 60); var trueTime = (driveHours+':'+("0"+driveMins).slice(-2)+'.'+("0"+driveSecs).slice(-2)); document.getElementById('sidepanel-drives').getElementsByClassName('result')[loop].getElementsByTagName('span')[1].innerHTML = trueTime; } } } } function srsSelect() { rbtID = selectionManager.selectedItems[0].model.attributes.junctionID; uroAddLog('selecting roundabout ID '+rbtID); selectionManager.selectControl.unselectAll(); for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++) { if(W.map.segmentLayer.features[slIdx].fid == null) { junctionID = W.map.segmentLayer.features[slIdx].model.attributes.junctionID; segID = W.map.segmentLayer.features[slIdx].model.attributes.id; } else { junctionID = W.map.segmentLayer.features[slIdx].attributes.junctionID; segID = W.map.segmentLayer.features[slIdx].fid; } if(junctionID == rbtID) { uroAddLog('...adding segment '+segID); selectionManager.selectControl.select(W.map.segmentLayer.features[slIdx]); } } } function srsCheckSidePanel() { if(selectionManager.selectedItems.length == 0) return; if(document.getElementById('srsCtrl') != null) return; var junctionID = selectionManager.selectedItems[0].model.attributes.junctionID; if(junctionID == null) return; srsCtrl = document.createElement('section'); srsCtrl.id = 'srsCtrl'; srsCtrl.innerHTML = '<button id="srsButton" class="btn btn-default">Select roundabout</button>'; document.getElementById('segment-edit-general').appendChild(srsCtrl); uroSetOnClick('srsButton',srsSelect); } uroBootstrap();