您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Simplifies geometry of area places in WME
当前为
// ==UserScript== // @name WME Simplify Place Geometry // @description Simplifies geometry of area places in WME // @version 1.00 // @author SAR85 // @copyright SAR85 // @license CC BY-NC-ND // @grant none // @include https://www.waze.com/editor/* // @include https://www.waze.com/*/editor/* // @include https://editor-beta.waze.com/* // @namespace https://greasyfork.org/users/9321 // ==/UserScript== /* Global vars */ var simplifyVersion = "1.00"; var simplifyChanges = "WME Simplify Area Geometry has been updated to version " + simplifyVersion + ".\n" + "*User interface has been changed to draggable window in map that appears when an area place is selected.\n" + "*Fixed save error when using clear geometry feature."; var simpUpdateFeatureGeometry = require("Waze/Action/UpdateFeatureGeometry"); var simpUpdateObject = require("Waze/Action/UpdateObject"); function simpBootstrap() { var bGreasemonkeyServiceDefined = false; try { if ("object" === typeof Components.interfaces.gmIGreasemonkeyService) { bGreasemonkeyServiceDefined = true; } } catch (err) { // Ignore. } if ( "undefined" === typeof unsafeWindow || ! bGreasemonkeyServiceDefined) { unsafeWindow = ( function () { var dummyElem = document.createElement('p'); dummyElem.setAttribute ('onclick', 'return window;'); return dummyElem.onclick (); } ) (); } /* begin running the code! */ window.setTimeout(simpInit, 2000); /*doesn't work in FF: $(document).ready(simpInit); */ } function addSimplifyFunc() { /* (c) 2013, Vladimir Agafonkin Simplify.js, a high-performance JS polyline simplification library mourner.github.io/simplify-js */ (function () { 'use strict'; // to suit your point format, run search/replace for '.x' and '.y'; // for 3D version, see 3d branch (configurability would draw significant performance overhead) // square distance between 2 points function getSqDist(p1, p2) { var dx = p1.x - p2.x, dy = p1.y - p2.y; return dx * dx + dy * dy; } // square distance from a point to a segment function getSqSegDist(p, p1, p2) { var x = p1.x, y = p1.y, dx = p2.x - x, dy = p2.y - y; if (dx !== 0 || dy !== 0) { var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy); if (t > 1) { x = p2.x; y = p2.y; } else if (t > 0) { x += dx * t; y += dy * t; } } dx = p.x - x; dy = p.y - y; return dx * dx + dy * dy; } // rest of the code doesn't care about point format // basic distance-based simplification function simplifyRadialDist(points, sqTolerance) { var prevPoint = points[0], newPoints = [prevPoint], point; for (var i = 1, len = points.length; i < len; i++) { point = points[i]; if (getSqDist(point, prevPoint) > sqTolerance) { newPoints.push(point); prevPoint = point; } } if (prevPoint !== point) newPoints.push(point); return newPoints; } // simplification using optimized Douglas-Peucker algorithm with recursion elimination function simplifyDouglasPeucker(points, sqTolerance) { var len = points.length, MarkerArray = typeof Uint8Array !== 'undefined' ? Uint8Array : Array, markers = new MarkerArray(len), first = 0, last = len - 1, stack = [], newPoints = [], i, maxSqDist, sqDist, index; markers[first] = markers[last] = 1; while (last) { maxSqDist = 0; for (i = first + 1; i < last; i++) { sqDist = getSqSegDist(points[i], points[first], points[last]); if (sqDist > maxSqDist) { index = i; maxSqDist = sqDist; } } if (maxSqDist > sqTolerance) { markers[index] = 1; stack.push(first, index, index, last); } last = stack.pop(); first = stack.pop(); } for (i = 0; i < len; i++) { if (markers[i]) newPoints.push(points[i]); } return newPoints; } // both algorithms combined for awesome performance function simplify(points, tolerance, highestQuality) { if (points.length <= 1) return points; var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1; points = highestQuality ? points : simplifyRadialDist(points, sqTolerance); points = simplifyDouglasPeucker(points, sqTolerance); return points; } // export as AMD module / Node module / browser or worker variable if (typeof define === 'function' && define.amd) define(function() { return simplify; }); else if (typeof module !== 'undefined') module.exports = simplify; else if (typeof self !== 'undefined') self.simplify = simplify; else window.simplify = simplify; })(); } function simpInit() { /* HTML */ var content = '<div id="simplifyarea"><p id="simplifyhelp" style="text-align: center; margin-bottom: 2px; text-decoration: underline; font-weight: bold; cursor: help;">WME Simplify Area Geometry</p><p style="text-align: center; margin: 0px;">Simplification factor: <input type="number" min="1" max="20" id="simpE" style="height: 20px; background-color: rgba(0,0,0,0.8); padding-left: 2px; border: 1px solid white; color: white; width: 50px"></p><p style="color: white;margin: 2px 0 0 0;"><a id="simplifylink" style="cursor:pointer; color: rgb(27,237,30)">Simplify Geometry</a> | <a id="clearlink" style="cursor:pointer; color: red;">Clear Geometry</a></p></div>'; var css = { "display": "none", "position": "absolute", "top": "120px", "left": "73px", "padding": "4px", "background-color": "rgba(0,0,0,0.8)", "border-radius": "5px", "border": "none", "color": "white", "font-size": "0.9em" }; /* Initialize simplification library */ addSimplifyFunc(); /* Add HTML to page and initialize*/ $('#map').append(content); $('#simplifyarea').css(css); $('#simpE').val(localStorage.simplifyE || '5'); $('#simplifylink').click(simplifyFeatureGeometry); $('#clearlink').click(clearFeatureGeometry); try {$('#simplifyarea').draggable();} catch(err) {} /* Event listeners */ $('#simplifyhelp').click(function(){ alert('To use WME Simplify Place Geometry: \n' + '1. Select an area place \n' + '2. Select an appropriate simplification factor (usually 5-10) \n' + '3. Click the link to simplify or clear the geometry' );}); $('#simpE').change(function() { localStorage.simplifyE = $('#simpE').val(); }); W.selectionManager.events.register("selectionchanged",null,function() { if (W.selectionManager.hasSelectedItems()) { var selectedItem = W.selectionManager.selectedItems[0].model; if (!(selectedItem.geometry instanceof OpenLayers.Geometry.Polygon)) return; $('#simplifyarea').fadeIn('fast'); } else { $('#simplifyarea').fadeOut('fast'); }}); /* Add functions to page */ self.simplifyFeatureGeometry = simplifyFeatureGeometry; self.clearFeatureGeometry = clearFeatureGeometry; /* Shortcut key = shift+j for simplifying */ W.accelerators.addAction('simplifyFeatureGeometry', {group: "editing"}); W.accelerators.events.register('simplifyFeatureGeometry',null,function(){simplifyFeatureGeometry()}); W.accelerators.registerShortcuts({'S+j': "simplifyFeatureGeometry"}); /* Shortcut key = ctrl-shift-j for clearing */ W.accelerators.addAction('clearFeatureGeometry', {group: "editing"}); W.accelerators.events.register('clearFeatureGeometry',null,function(){clearFeatureGeometry()}); W.accelerators.registerShortcuts({'CS+j': "clearFeatureGeometry"}); console.log("WME Simplify Area Geometry Initialized"); /* Update Alert */ if (window.localStorage.simplifyVersion == 'undefined' || window.localStorage.simplifyVersion !== simplifyVersion) { alert(simplifyChanges); window.localStorage.simplifyVersion = simplifyVersion; } } function simplifyFeatureGeometry(e) { if (!W.selectionManager.hasSelectedItems() || W.selectionManager.selectedItems[0].model.type !== "venue" || !W.selectionManager.selectedItems[0].model.isGeometryEditable() || !W.selectionManager.selectedItems[0].model.geometry instanceof OpenLayers.Geometry.Polygon) return; e = $('#simpE').val(); var place = W.selectionManager.selectedItems[0]; var oldGeometry = place.geometry.clone(); var newGeometry = oldGeometry.clone(); newGeometry.components[0].components = simplify(oldGeometry.components[0].components, e, false); if (newGeometry.components[0].components.length < oldGeometry.components[0].components.length) { W.model.actionManager.add(new simpUpdateFeatureGeometry(place.model,W.model.venues,oldGeometry,newGeometry)); console.log("WME Simplify Area Geometry: " + place.model.attributes.name + " simplified from " + oldGeometry.components[0].components.length + " to " + newGeometry.components[0].components.length + " geo nodes using factor " + e + "."); } else { console.log("Geo nodes cannot be simplified from " + oldGeometry.components[0].components.length + " to " + newGeometry.components[0].components.length + "."); } } function clearFeatureGeometry() { if (!W.selectionManager.hasSelectedItems() || W.selectionManager.selectedItems[0].model.type !== "venue" || !W.selectionManager.selectedItems[0].model.isGeometryEditable() || !W.selectionManager.selectedItems[0].model.geometry instanceof OpenLayers.Geometry.Polygon) return; var newGeometry, navAction; var venue = W.selectionManager.selectedItems[0].model; var newEntryExitPoint = {entry: true, exit: true}; var oldGeometry = venue.geometry; if (oldGeometry.components[0].components.length > 4) { newGeometry = oldGeometry.getBounds().toGeometry(); if (newGeometry.getArea() > 160) newGeometry.resize(0.5,newGeometry.getCentroid()); newEntryExitPoint.point = newGeometry.getCentroid(); W.model.actionManager.add(new simpUpdateFeatureGeometry(venue,W.model.venues,oldGeometry,newGeometry)); navAction = new simpUpdateObject(venue,{entryExitPoints: [newEntryExitPoint]}); navAction.eachGeometryField = function(e, t) { var i, n, s, r, o; for (r = e.entryExitPoints, o = [], n = 0, s = r.length; s > n; n++) i = r[n], o.push(t.call(this, "point", i.point, i)); return o; }; W.model.actionManager.add(navAction); } } simpBootstrap();