您需要先安装一个扩展,例如 篡改猴、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.01
- // @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.01";
- var simplifyChanges = "WME Simplify Area Geometry has been updated to version " +
- simplifyVersion + ".\n" +
- "*Minor bug fix.";
- 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, 3000);
- /*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() || 5;
- 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();