|
|
(6 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
| // ==UserScript==
| | #REDIRECT [[Scripts#WME_Junction_Angle_info]] |
| // @name WME Junction Angle info
| |
| // @namespace http://pyrczak.pl/
| |
| // @description Show the angle between two selected (and connected) segments
| |
| // @include https://*.waze.com/*/editor/*
| |
| // @include https://*.waze.com/editor/*
| |
| // @include https://*.waze.com/map-editor/*
| |
| // @include https://*.waze.com/beta_editor/*
| |
| // @include https://editor-beta.waze.com/*
| |
| // @version 1.5.7.3
| |
| // @grant none
| |
| // @copyright 2013 Michael Wikberg <michael@wikberg.fi>
| |
| // @license CC-BY-NC-SA
| |
| // ==/UserScript==
| |
| | |
| /**
| |
| * Copyright 2013 Michael Wikberg <michael@wikberg.fi>
| |
| *
| |
| * Fixed for new WME: 2014 Paweł Pyrczak <support@pyrczak.pl>
| |
| *
| |
| */
| |
| function run_ja() {
| |
| | |
| | |
| var junctionangle_version = "1.5.7.3";
| |
| var junctionangle_debug = 1; //0: no output, 1: basic info, 2: debug 3: crazy debug
| |
| var ja_wazeModel, ja_wazeMap, $;
| |
| var ja_features = [];
| |
| | |
| var ja_wazeMap = {};
| |
| var ja_wazeModel = {};
| |
| var ja_loginManager = {};
| |
| var ja_selectionManager = {};
| |
| var ja_OpenLayers = {};
| |
| | |
| | |
| | |
| function junctionangle_bootstrap() {
| |
| var bGreasemonkeyServiceDefined = false;
| |
| | |
|
| |
| // not needed
| |
| /*
| |
|
| |
| try
| |
| {
| |
| if (typeof Components.interfaces.gmIGreasemonkeyService === "object")
| |
| {
| |
| bGreasemonkeyServiceDefined = true;
| |
| }
| |
| }
| |
| catch (err)
| |
| {
| |
| //Ignore.
| |
| }
| |
| if ( typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined)
| |
| {
| |
| unsafeWindow = ( function ()
| |
| {
| |
| var dummyElem = document.createElement('p');
| |
| dummyElem.setAttribute ('onclick', 'return window;');
| |
| return dummyElem.onclick ();
| |
| } ) ();
| |
| }
| |
|
| |
| */
| |
| /* begin running the code! */
| |
| setTimeout(ja_startcode, 500);
| |
| }
| |
| | |
| | |
| function ja_startcode() {
| |
| //
| |
| try {
| |
| if ((typeof window.Waze.map != undefined) && (undefined != typeof window.Waze.map.events.register) && (undefined != typeof window.Waze.selectionManager.events.register ) && (undefined != typeof window.Waze.loginManager.events.register) ) {
| |
| setTimeout(junctionangle_init, 500);
| |
| } else {
| |
| setTimeout(ja_startcode, 1000);
| |
| }
| |
| } catch(err) {
| |
| setTimeout(ja_startcode, 1000);
| |
| }
| |
| | |
| }
| |
| | |
| | |
| function ja_log(ja_log_msg, ja_log_level) {
| |
| return true;
| |
|
| |
| if(ja_log_level <= junctionangle_debug) {
| |
| if(typeof ja_log_msg == "object") {
| |
| //ja_log(arguments.callee.caller.toString(), ja_log_level);
| |
| // console.log(ja_log_msg);
| |
| }
| |
| else {
| |
| //console.log("WME Junction Angle: " + ja_log_msg);
| |
| }
| |
| }
| |
| }
| |
| | |
| function junctionangle_init()
| |
| {
| |
| | |
| | |
| ja_wazeMap = window.Waze.map;
| |
| ja_wazeModel = window.Waze.model;
| |
| ja_loginManager = window.Waze.loginManager;
| |
| ja_selectionManager = window.Waze.selectionManager;
| |
| ja_OpenLayers = window.OpenLayers;
| |
| //get jQuery support (not needed now)
| |
| //$ = window.$;
| |
| | |
| //selected nodes changed
| |
| ja_selectionManager.events.register("selectionchanged", null, ja_calculate);
| |
|
| |
| //probably unnecessary
| |
| //map is moved or resized
| |
| //ja_wazeMap.events.register("moveend", null, ja_calculate);
| |
| | |
| //mouse button released (FIXME: wanted to listen to "segment or node moved", but could not find a suitable event...)
| |
| // FIXED
| |
| //ja_wazeMap.events.register("mouseup", null, ja_calculate);
| |
| ja_wazeModel.segments.events.on({
| |
| "objectschanged": ja_calculate,
| |
| "objectsremoved": ja_calculate,
| |
| });
| |
| ja_wazeModel.nodes.events.on({
| |
| "objectschanged": ja_calculate,
| |
| "objectsremoved": ja_calculate,
| |
| });
| |
| | |
| //HTML changes after login. Better do init again.
| |
| ja_loginManager.events.register("afterloginchanged", null, junctionangle_init);
| |
|
| |
| /**
| |
| * Make some style settings
| |
| */
| |
| var ja_style = new ja_OpenLayers.Style({
| |
| fillColor: "#ffcc88",
| |
| strokeColor: "#ff9966",
| |
| strokeWidth: 2,
| |
| label: "${angle}",
| |
| fontWeight: "bold",
| |
| pointRadius: 10,
| |
| fontSize: "10px"
| |
| }, {
| |
| rules: [
| |
| new window.OpenLayers.Rule({
| |
| symbolizer: {
| |
| }
| |
| }),
| |
| new window.OpenLayers.Rule({
| |
| filter: new window.OpenLayers.Filter.Comparison({
| |
| type: window.OpenLayers.Filter.Comparison.EQUAL_TO,
| |
| property: "ja_type",
| |
| value: "junction"
| |
| }),
| |
| symbolizer: {
| |
| pointRadius: 13,
| |
| fontSize: "12px",
| |
| fillColor: "#4cc600",
| |
| strokeColor: "#183800"
| |
| }
| |
| })
| |
| ]
| |
| });
| |
| | |
| //try to see if we already have a layer
| |
| if(window.Waze.map.getLayersByName("Junction Angles").length > 0) {
| |
|
| |
| } else {
| |
| // Create a vector layer and give it your style map.
| |
| ja_mapLayer = new ja_OpenLayers.Layer.Vector("Junction Angles", {
| |
| displayInLayerSwitcher: true,
| |
| uniqueName: "JunctionAngles",
| |
| shortcutKey: "S+j",
| |
| accelerator: "toggleJunctionAngles",
| |
| | |
| styleMap: new ja_OpenLayers.StyleMap(ja_style)
| |
| });
| |
| | |
| ja_wazeMap.addLayer(ja_mapLayer);
| |
| ja_log("version " + junctionangle_version + " loaded.", 0);
| |
|
| |
| ja_log(ja_wazeMap,3);
| |
| ja_log(ja_wazeModel,3);
| |
| ja_log(ja_loginManager,3);
| |
| ja_log(ja_selectionManager,3);
| |
| ja_log(ja_mapLayer,3);
| |
| ja_log(ja_OpenLayers,3);
| |
| | |
| //try to resize the layer selection box... Apparently the only (easy) way is to actually override the CSS
| |
| //No longer needed. Commented out.
| |
| //var newSwitcherStyle = $('<style>.WazeControlLayerSwitcher:hover {background-color: #FFFFFF; max-height: 390px; width: 200px;}</style>');
| |
| //$('html > head').append(newSwitcherStyle);
| |
| }
| |
| }
| |
| | |
| function ja_calculate()
| |
| {
| |
| //clear old info
| |
| ja_mapLayer.destroyFeatures();
| |
| | |
| //try to show all angles for all selected segments
| |
| if(ja_selectionManager.selectedItems.length == 0) return 1;
| |
| ja_log("Checking junctions for " + ja_selectionManager.selectedItems.length + " segments", 1);
| |
| var ja_nodes = [];
| |
| | |
| for(i = 0; i < ja_selectionManager.selectedItems.length; i++) {
| |
| ja_log(ja_selectionManager.selectedItems[i],3);
| |
| switch(ja_selectionManager.selectedItems[i].type) {
| |
| case "node":
| |
| ja_nodes.push(ja_selectionManager.selectedItems[i].fid);
| |
| break;
| |
| case "segment":
| |
| //segments selected?
| |
| if(ja_selectionManager.selectedItems[i].attributes.fromNodeID != null &&
| |
| ja_nodes.indexOf(ja_selectionManager.selectedItems[i].attributes.fromNodeID) == -1) {
| |
| ja_nodes.push(ja_selectionManager.selectedItems[i].attributes.fromNodeID);
| |
| }
| |
| if(ja_nodes.indexOf(ja_selectionManager.selectedItems[i].attributes.toNodeID != null &&
| |
| ja_nodes.indexOf(ja_selectionManager.selectedItems[i].attributes.toNodeID) == -1)) {
| |
| ja_nodes.push(ja_selectionManager.selectedItems[i].attributes.toNodeID);
| |
| }
| |
| break;
| |
| default:
| |
| ja_log("Found unknown item type: " + ja_selectionManager.selectedItems[i].type,1);
| |
| }
| |
| }
| |
| | |
| ja_features = [];
| |
| | |
| for(i = 0; i < ja_nodes.length; i++) {
| |
| node = ja_wazeModel.nodes.get(ja_nodes[i]);
| |
| if(node == null || !node.hasOwnProperty('attributes')) {
| |
| //Oh oh.. should not happen?
| |
| ja_log(ja_nodes,2)
| |
| ja_log(ja_wazeModel,3)
| |
| ja_log(ja_wazeModel.nodes,3)
| |
| continue;
| |
| }
| |
| //check connected segments
| |
| segments = node.attributes.segIDs;
| |
| ja_log(node,2);
| |
|
| |
| //ignore of we have less than 2 segments
| |
| if(segments.length <= 1) {
| |
| ja_log("Found only " + segments.length + " connected segments at " + ja_nodes[i] + ", not calculating anything...", 2);
| |
| continue;
| |
| }
| |
|
| |
| ja_log("Calculating angles for " + segments.length + " segments", 2);
| |
|
| |
| angles = new Array();
| |
| selected_segments = 0;
| |
| | |
| for(j = 0; j < segments.length; j++) {
| |
| s = ja_wazeModel.segments.get(segments[j]);
| |
| a = ja_getAngle(ja_nodes[i], s);
| |
| ja_log("j: " + j + "; Segment " + segments[j] + " angle is " + a, 3);
| |
| angles[j] = new Array(a, segments[j], s != null ? s.isSelected() : false);
| |
| if(s != null ? s.isSelected() : false) selected_segments++;
| |
| }
| |
| | |
| ja_log(angles,2);
| |
| //sort angle data (ascending)
| |
| angles.sort(function(a,b){return a[0] - b[0]});
| |
| ja_log(angles,3);
| |
| ja_log(selected_segments,3);
| |
| | |
| switch (ja_wazeMap.zoom) {
| |
| case 9:
| |
| ja_label_distance = 4;
| |
| break;
| |
| case 8:
| |
| ja_label_distance = 8;
| |
| break;
| |
| case 7:
| |
| ja_label_distance = 15;
| |
| break;
| |
| case 6:
| |
| ja_label_distance = 25;
| |
| break;
| |
| case 5:
| |
| ja_label_distance = 40;
| |
| break;
| |
| case 4:
| |
| ja_label_distance = 80;
| |
| break;
| |
| case 3:
| |
| ja_label_distance = 140;
| |
| break;
| |
| case 2:
| |
| ja_label_distance = 300;
| |
| break;
| |
| case 1:
| |
| ja_label_distance = 400;
| |
| break;
| |
| }
| |
| ja_log("zoom: " + ja_wazeMap.zoom + " -> distance: " + ja_label_distance, 2);
| |
|
| |
| //if we have two connected segments selected, do some magic to get the turn angle only =)
| |
| if(selected_segments == 2) {
| |
| ja_selected = [];
| |
| ja_extra_space_multiplier = 1;
| |
|
| |
| for(j = 0; j < angles.length; j++) {
| |
| if(angles[j][2]) {
| |
| ja_selected.push(angles[j]);
| |
| }
| |
| }
| |
|
| |
| a = ((ja_selected[1][0] - ja_selected[0][0]) + 360) % 360;
| |
| ha = (360 + (ja_selected[0][0]+ja_selected[1][0])/2) % 360;
| |
| | |
| ja_log(a,3);
| |
| if(a < 60) {
| |
| ja_log("Sharp angle", 2);
| |
| ja_extra_space_multiplier = 2;
| |
| }
| |
| | |
| if(a > 180) {
| |
| //a2 = a - 180;
| |
| ha = ha + 180;
| |
| }
| |
| | |
|
| |
| ja_log("Angle between " + ja_selected[0][1] + " and " + ja_selected[1][1] + " is " + a + " and position for label should be at " + ha, 3);
| |
| | |
| //put the angle point
| |
| ja_features.push(new ja_OpenLayers.Feature.Vector(
| |
| new ja_OpenLayers.Geometry.Point(
| |
| node.geometry.x + (ja_extra_space_multiplier * ja_label_distance * Math.cos((ha*Math.PI)/180)),
| |
| node.geometry.y + (ja_extra_space_multiplier * ja_label_distance * Math.sin((ha*Math.PI)/180))
| |
| )
| |
| , { angle: Math.round(Math.abs(180 - a))+"°", ja_type: "junction" }
| |
| ));
| |
| }
| |
| else {
| |
| //get all segment angles
| |
| for(j = 0; j < angles.length; j++) {
| |
| a = (360 + (angles[(j+1)%angles.length][0] - angles[j][0])) % 360;
| |
| ha = (360 + ((a/2) + angles[j][0])) % 360;
| |
|
| |
| ja_log("Angle between " + angles[j][1] + " and " + angles[(j+1)%angles.length][1] + " is " + a + " and position for label should be at " + ha, 3);
| |
| //push the angle point
| |
| ja_features.push(new ja_OpenLayers.Feature.Vector(
| |
| new ja_OpenLayers.Geometry.Point(
| |
| node.geometry.x + (ja_label_distance * Math.cos((ha*Math.PI)/180)), node.geometry.y + (ja_label_distance * Math.sin((ha*Math.PI)/180))
| |
| )
| |
| , { angle: Math.round(a)+"°", ja_type: "generic" }
| |
| ));
| |
| }
| |
| }
| |
| }
| |
| | |
| ja_log(ja_features, 2);
| |
| //Update the displayed angles
| |
| ja_mapLayer.addFeatures(ja_features);
| |
| }
| |
| | |
| function ja_points_equal(point1, point2) {
| |
| return (point1.x == point2.x && point1.y == point2.y);
| |
| }
| |
| | |
| function ja_get_first_point(segment) {
| |
| return segment.geometry.components[0];
| |
| }
| |
| | |
| function ja_get_last_point(segment) {
| |
| return segment.geometry.components[segment.geometry.components.length-1];
| |
| }
| |
| | |
| function ja_get_second_point(segment) {
| |
| return segment.geometry.components[1];
| |
| }
| |
| | |
| function ja_get_next_to_last_point(segment) {
| |
| return segment.geometry.components[segment.geometry.components.length-2];
| |
| }
| |
| | |
| //get the absolute angle for a segment end point
| |
| function ja_getAngle(ja_node, ja_segment) {
| |
| if(ja_node == null || ja_segment == null) return null;
| |
| if(ja_segment.attributes.fromNodeID == ja_node) {
| |
| ja_dx = ja_get_second_point(ja_segment).x - ja_get_first_point(ja_segment).x;
| |
| ja_dy = ja_get_second_point(ja_segment).y - ja_get_first_point(ja_segment).y;
| |
| } else {
| |
| ja_dx = ja_get_next_to_last_point(ja_segment).x - ja_get_last_point(ja_segment).x;
| |
| ja_dy = ja_get_next_to_last_point(ja_segment).y - ja_get_last_point(ja_segment).y;
| |
| }
| |
| ja_log(ja_node + " / " + ja_segment + ": dx:" + ja_dx + ", dy:" + ja_dy);
| |
| ja_angle = Math.atan2(ja_dy,ja_dx);
| |
| return (360+(ja_angle*180/Math.PI))%360;
| |
| }
| |
| | |
| junctionangle_bootstrap();
| |
| | |
| | |
| }
| |
| | |
| var DLscript = document.createElement("script");
| |
| DLscript.textContent =''+
| |
| run_ja.toString()+' \n'+
| |
| 'run_ja();';
| |
| DLscript.setAttribute("type", "application/javascript");
| |
| document.body.appendChild(DLscript);
| |