Showcase: selectable features in WME map

Shows how to add a vector feature layer where the features can receive events, just like Waze's features

目前為 2023-05-31 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Showcase: selectable features in WME map
// @author       Tom 'Glodenox' Puttemans
// @namespace    http://www.tomputtemans.com/
// @version      0.2
// @description  Shows how to add a vector feature layer where the features can receive events, just like Waze's features
// @include      /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/
// ==/UserScript==

/* global W, OpenLayers */

async function onWmeReady() {
  // Create vector layer
  let mapLayer = new OpenLayers.Layer.Vector("feature_selection_showcase", {
    styleMap: new OpenLayers.StyleMap({
      'default': new OpenLayers.Style({
        pointRadius: 10,
        strokeColor: '#aaa',
        fillColor: '${fillColor}',
        fontColor: '#fff',
        fontWeight: 'bold',
        label: '${text}'
      }),
      'highlight': new OpenLayers.Style({
        strokeColor: '#aaa',
        fillColor: '${highlightFillColor}'
      }),
      'select': new OpenLayers.Style({
        strokeColor: '#fff',
        fillColor: '${fillColor}'
      }),
      'highlightselected': new OpenLayers.Style({
        strokeColor: '#fff',
        fillColor: '${highlightFillColor}'
      })
    })
  });
  W.map.addLayer(mapLayer);
  // Move the SVG root of the new layer into the layer RootContainer used by Waze. TODO: find a better way to identify the correct RootContainer
  let layerContainer = W.map.layers.find(layer => layer.CLASS_NAME == "OpenLayers.Layer.Vector.RootContainer" && layer.layers && layer.layers.length > 5);
  layerContainer.layers.push(mapLayer);
  layerContainer.collectRoots();

  // Create a test location at the center of the map to showcase the highlighting and selection
  let location = W.map.getCenter();
  let vectorPoint = new OpenLayers.Geometry.Point(location.lon, location.lat);
  let text = "1";
  // The repositoryObject contains methods required by the Waze logic
  let vectorAttributes = {
    text: text,
    fillColor: "#555",
    highlightFillColor: "#888",
    index: `${text}`,
    repositoryObject: {
      isDeleted: () => false,
      setSelected: (state) => console.log("New selection state:", state),
      isNew: () => false,
      getType: () => null,
      getID: () => -1
    }
  };
  let testVector = new OpenLayers.Feature.Vector(vectorPoint, vectorAttributes);
  // Not needed by Waze, but some common scripts rely on the presence of a model field
  testVector.model = vectorAttributes;
  mapLayer.addFeatures([ testVector ]);
}

// Below you just find the usual bootstrap code, nothing needs to be changed there

function onWmeInitialized() {
  if (W.userscripts?.state?.isReady) {
    console.log('W is ready and in "wme-ready" state. Proceeding with initialization.');
    onWmeReady();
  } else {
    console.log('W is ready, but not in "wme-ready" state. Adding event listener.');
    document.addEventListener('wme-ready', onWmeReady, { once: true });
  }
}

function bootstrap() {
  if (!W) {
    console.log('W is not available. Adding event listener.');
    document.addEventListener('wme-initialized', onWmeInitialized, { once: true });
  } else {
    onWmeInitialized();
  }
}

bootstrap();