Greasemonkey script for easy river drawing

The place to get information and ask questions about everything to do with properly and successfully editing the Waze Map.

Use this forum for all general editing questions, and the sub-forums for specific types of Waze Map Editor features.

Moderators: support, The Fej, Unholy, krankyd

Re: Greasemonkey script for easy river drawing

Postby BastianL » Wed Jun 27, 2012 8:35 pm

Hello,
I want to draw a river that has already a beginning.
Is it possible to add kilometer's to a existing river with this plugin?

Gruß!
BastianL
 
Posts: 6
Joined: Tue Jun 19, 2012 2:15 pm
Has thanked: 0 time
Been thanked: 0 time

Greasemonkey script for easy river drawing

Postby Dave2084 » Tue Jan 03, 2012 2:14 pm

This sounds interesting, I will have to install it and give it a go!
iPhone 4S 32GB (Jailed) • iOS 6.1.2 • Waze Beta 3.7.0.996
Lincolnshire Area Manager • UK Country Administrator • iOS Beta Tester • iPhone Expert
UK WikiUK ForumWaze UK on FacebookBecome a UK Area ManagerWaze Status
Dave2084
Waze Champs
 
Posts: 1558
Joined: Tue Feb 09, 2010 12:58 am
Location: Lincoln, UK
Has thanked: 27 times
Been thanked: 37 times

Re: Greasemonkey script for easy river drawing

Postby Dave2084 » Mon Jan 30, 2012 5:35 am

Thanks!
iPhone 4S 32GB (Jailed) • iOS 6.1.2 • Waze Beta 3.7.0.996
Lincolnshire Area Manager • UK Country Administrator • iOS Beta Tester • iPhone Expert
UK WikiUK ForumWaze UK on FacebookBecome a UK Area ManagerWaze Status
Dave2084
Waze Champs
 
Posts: 1558
Joined: Tue Feb 09, 2010 12:58 am
Location: Lincoln, UK
Has thanked: 27 times
Been thanked: 37 times

Re: Greasemonkey script for easy river drawing

Postby DGlanem » Fri May 25, 2012 7:52 am

I want to make a Railroad-Landmark from an existing street(railroad).

The tool gives me a messagebox "there are no new streets" (or so).

A few minutes later I try it again - the messagebox say "...succsessful created..." . :shock:


Where is my Bug?


regards from germany
#Dominik
Area-Manager: Landkreis Helmstedt (city & county), germany, Niedersachsen (lower saxony)
Wazing with Volkswagen Caddy and Samsung Galaxy S3

* * * Excuse my terrible english... * * *
DGlanem
 
Posts: 92
Joined: Fri Aug 19, 2011 6:42 am
Location: Helmstedt, Germany
Has thanked: 1 time
Been thanked: 1 time

Re: Greasemonkey script for easy river drawing

Postby EduardoCarvajal » Mon May 20, 2013 1:53 am

Solved: Tampermonkey + Chrome

Hi,
I found 2 unhandled exceptions that crash script execution on Google Chome/Tampermonkey. That’s the reasons this script doesn’t work on Tampermonkey.

It's very easy to solve this issue, just replace the code for the following functions:

FUNCTION #01:
Code: Select all
function insertButtons() {
    if(selectionManager.selectedItems.length == 0) return;
     
    // 2013-04-19: Catch exception
    try{
       if(document.getElementById('streetToRiver') != null) return;
    }
    catch(e){ }
   
      
    var btn1 = $('<button class="btn" title="create a new street, select and click this button">Street to river</button>');
    btn1.click(doRiver);
    var btn2 = $('<button class="btn" title="create a new street, select and click this button">Street to railway</button>');
    btn2.click(doRailway);

    var cnt = $('<section id="streetToRiver"/>');
    cnt.append(btn1);
    cnt.append(btn2);
    $("#segment-edit-general").append(cnt);
    console_log("Street to river initialized");
  }

FUNCTION #02:
Code: Select all
function console_log(msg) {
    //if (console.log)
    // 2013-05-19: Alternate method to valided console object
    if(typeof console != "undefined")
      console.log(msg);
  }


THE NEW SCRIPT:
Code: Select all
// ==UserScript==
// @name WME Street to river
// @description This script create a new river landmark in waze editor papyrus. It transforms the the geometry of a new unsaved street to a polygon.
// @namespace http://www.tay-tec.de/waze-street-to-river
// @grant none
// @version 12.12.20.1
// @include https://*.waze.com/editor/*
// @include https://*.waze.com/map-editor/*
// @include https://*.waze.com/beta_editor/*
// @include https://descartes.waze.com/beta/*
// @include https://descartesw.waze.com/beta/*
// ==/UserScript==


// Mini howto:
// 1) install this script as greasemonkey script or chrome extension
// 2) draw a new street but do not save the street
// 3) add and apply a street name to define the rivers name and the the width of the river
//    Example: "20m Spree" creates a 20 meters width river named "Spree"
// 4) Select the helper street
// 5) Click the "Street to river" button
// 4) Delete the helper street
// 5) Edit the new landmark as you like


if ('undefined' == typeof __RTLM_PAGE_SCOPE_RUN__) {
  (function page_scope_runner() {
    // If we're _not_ already running in the page, grab the full source
    // of this script.
    var my_src = "(" + page_scope_runner.caller.toString() + ")();";

    // Create a script node holding this script, plus a marker that lets us
    // know we are running in the page scope (not the Greasemonkey sandbox).
    // Note that we are intentionally *not* scope-wrapping here.
    var script = document.createElement('script');
    script.setAttribute("type", "text/javascript");
    script.textContent = "var __RTLM_PAGE_SCOPE_RUN__ = true;\n" + my_src;

    // Insert the script node into the page, so it will run, and immediately
    // remove it to clean up.  Use setTimeout to force execution "outside" of
    // the user script scope completely.
    setTimeout(function() {
          document.body.appendChild(script);
          document.body.removeChild(script);
        }, 0);
  })();

  // Stop running, because we know Greasemonkey actually runs us in
  // an anonymous wrapper.
  return;
}


function streetToRiver() {

  var defaultWidth = 20;

  function insertButtons() {
    if(selectionManager.selectedItems.length == 0) return;
     
    // 2013-04-19: Catch exception
    try{
       if(document.getElementById('streetToRiver') != null) return;
    }
    catch(e){ }
   
      
    var btn1 = $('<button class="btn" title="create a new street, select and click this button">Street to river</button>');
    btn1.click(doRiver);
    var btn2 = $('<button class="btn" title="create a new street, select and click this button">Street to railway</button>');
    btn2.click(doRailway);

    var cnt = $('<section id="streetToRiver"/>');
    cnt.append(btn1);
    cnt.append(btn2);
    $("#segment-edit-general").append(cnt);
    console_log("Street to river initialized");
  }

  function doRiver(ev) {
    var foundSelectedSegment = false;
    for (var s=selectionManager.selectedItems.length-1; s>=0; s--) {
      var sel = selectionManager.selectedItems[s];
      if (sel.type == "segment" && sel.state == "Insert") {
        // found segment
        foundSelectedSegment = true;
        if (convertToLandmark(sel, "H3010"))
        {
          alert("Successfully created new river landmark");
        }
      }
    }
    if (! foundSelectedSegment) {
        alert("No unsaved and selected new street found!");
      }
  }

  function doRailway(ev) {
    var foundSelectedSegment = false;
    for (var s=selectionManager.selectedItems.length-1; s>=0; s--) {
      var sel = selectionManager.selectedItems[s];
      if (sel.type == "segment" && (sel.state == "Insert" || sel.data.roadType == 18)) {
        // found segment
        foundSelectedSegment = true;
        defaultWidth = 8;
        if (convertToLandmark(sel, "W0200"))
        {
          alert("Successfully created new railway landmark");
        }
        defaultWidth = 20;
      }
    }
    if (! foundSelectedSegment) {
        alert("No unsaved new street or railroad found!");
      }
  }

  function convertToLandmark(sel, lmtype) {

    var leftPa, rightPa, leftPb, rightPb;
    var prevLeftEq, prevRightEq;
    var street = getStreet(sel);

    var displacement = getDisplacement(street);

    var polyPoints = null;
    var vertices = sel.geometry.getVertices();
    for (var i=vertices.length-1; i>0; i--)
    {
      var pa = vertices[i];
      var pb = vertices[i-1];
      var scale = (pa.distanceTo(pb) + displacement) / pa.distanceTo(pb);

      leftPa = pa.clone();
      leftPa.resize(scale, pb, 1);
      rightPa = leftPa.clone();
      leftPa.rotate(90,pa);
      rightPa.rotate(-90,pa);

      leftPb = pb.clone();
      leftPb.resize(scale, pa, 1);
      rightPb = leftPb.clone();
      leftPb.rotate(-90,pb);
      rightPb.rotate(90,pb);

      var leftEq = getEquation({ 'x1': leftPa.x, 'y1': leftPa.y, 'x2': leftPb.x, 'y2': leftPb.y });
      var rightEq = getEquation({ 'x1': rightPa.x, 'y1': rightPa.y, 'x2': rightPb.x, 'y2': rightPb.y });
      if (polyPoints == null) {
        polyPoints = [ leftPa, rightPa ];
      }
      else {
        var li = intersectX(leftEq, prevLeftEq);
        var ri = intersectX(rightEq, prevRightEq);
        if (li && ri) {
          polyPoints.unshift(li);
          polyPoints.push(ri);
        }
        else {
          polyPoints.unshift(leftPb.clone());
          polyPoints.push(rightPb.clone());
        }
      }

      prevLeftEq = leftEq;
      prevRightEq = rightEq;
    }

    polyPoints.push(rightPb);
    polyPoints.push(leftPb);

    var polygon = new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(polyPoints));

    var landmark = new Waze.Feature.Vector.Landmark(polygon);
    landmark.attributes.mtfcc = lmtype;
    if (street) {
      landmark.attributes.name = street.name.replace(/^\d+(m|ft)\s*/, '');
    }
    var what = wazeModel.actionManager.add(new Waze.Action.AddLandmark(landmark));

    return true;
  }


  function getEquation(segment) {
    if (segment.x2 == segment.x1)
      return { 'x': segment.x1 };

    var slope =  (segment.y2 - segment.y1) / (segment.x2 - segment.x1);
    var offset = segment.y1 - (slope  * segment.x1)
    return { 'slope': slope, 'offset': offset };
  }

  //
  // line A: y = ax + b
  // line B: y = cx + b
  //
  // x = (d - b) / (a - c)
  function intersectX(eqa,eqb,defaultPoint) {
    if ("number" == typeof eqa.slope && "number" == typeof eqb.slope) {
      if (eqa.slope == eqb.slope)
        return null;

      var ix = (eqb.offset - eqa.offset) / (eqa.slope - eqb.slope);
      var iy = eqa.slope * ix + eqa.offset;
      return new OpenLayers.Geometry.Point(ix, iy);
    }
    else if ("number" == typeof eqa.x) {
      return new OpenLayers.Geometry.Point(eqa.x, eqb.slope * eqa.x + eqb.offset);
    }
    else if ("number" == typeof eqb.y) {
      return new OpenLayers.Geometry.Point(eqb.x, eqa.slope * eqb.x + eqa.offset);
    }
    return null;
  }


  function getStreet(segment) {
    if (! segment.attributes.primaryStreetID)
      return null;
    var street = segment.model.streets.get(segment.attributes.primaryStreetID)
    return street;
  }

  function getDisplacement(street) {
    if (! street)
      return defaultWidth;
    if (street.name.match(/^(\d+)m\b/))
      return parseInt(RegExp.$1);
    if (street.name.match(/^(\d+)ft\b/))
      return parseInt(RegExp.$1) * 0.3048;
    return defaultWidth;
  }

  function console_log(msg) {
    //if (console.log)
    // 2013-05-19: Alternate method to valided console object
    if(typeof console != "undefined")
      console.log(msg);
  }
 
  selectionManager.events.register("selectionchanged", null, insertButtons);
}

streetToRiver();
EduardoCarvajal
 
Posts: 5
Joined: Sun Jul 01, 2012 5:57 pm
Has thanked: 0 time
Been thanked: 2 times

Street to River PLUS

Postby EduardoCarvajal » Tue Jun 04, 2013 2:30 pm

Hi,

This is a modified version of Street to River Script that I call Street to River PLUS.

Mini howto:
    1.install this script from userscripts.org as Greasemonkey script, Chrome extension or Tampermonkey script.


To add a new river:
    1.Draw a new street but do not save the Street.
    2.Add and apply a street name to define the rivers name and the width of the river.
    Example: "20m Spree" creates a 20 meters width river named "Spree".
    3.Select the helper Street.
    4.Click the "Street to river" button.
    5.Delete the helper Street.
    6.Edit the new landmark as you like.

To expand an existing river:
    1.Draw a new Street that starts inside an existing river, but do not save the Street.
    2.Select the helper Street.
    3.Click the "Street to river" button.
    4.Delete the helper Street.
    5.Edit the new landmark as you like.

Version 13.6.3.1
    1.Added support to Google Chrome and Tampermonkey.
    2.Now it's possible to expand an existing river.
    3.Fixed save problem on large rivers.
EduardoCarvajal
 
Posts: 5
Joined: Sun Jul 01, 2012 5:57 pm
Has thanked: 0 time
Been thanked: 2 times

Re: Greasemonkey script for easy river drawing

Postby fvwazing » Fri Jan 06, 2012 9:13 pm

Nice work, aeytom! Created a small stream in my hood that was so curvy that I didn't have the courage to create it until now. Your script makes it very easy.

However... to make that river look really good I had to make a little bit of variation in the width, so that curves are a bit wider that the straights.

Geul_Landmark.jpg
Geul - a small stream that "swings"
Geul_Landmark.jpg (90.65 KiB) Viewed 1272 times


To create this effect automatically, I took the liberty of adding a bit of code to your script. Now it takes an extra parameter, "variancy", expressed as an extra parameter in the name of the river. As in "20m 30v Spree". Shorter segments are a bit wider, longer segments are a bit more narrow now. I would love to have created the effect depending on the angle between consecutive segments but I am afraid I did not completely grasp how you do the math (in getEquation), and the effect is good enough as it is now, I think.

In order NOT to pollute this thread with endless copies of code I send you my version as PM, maybe you can have a look to see if it is any good.
Waze jezelf!
600K+ edits
AM for some 25.000 km² around Maastricht, the Netherlands
iPhone 3Gs / iOS 6.0.1
fvwazing
Waze Champs
 
Posts: 2923
Joined: Sat Nov 14, 2009 2:48 pm
Has thanked: 138 times
Been thanked: 102 times

Re: Greasemonkey script for easy river drawing

Postby gerben » Thu Dec 29, 2011 2:50 am

I don't get the street-to-river button, or I don't see it. Where should it be?
Back to my G1 (HTC Heart) - Froyo by Laszlo ROM - Waze 3.7.x (beta). Soon to be the owner of a Nokia Lumia 920 (WP8 Beta client)
Waze Champ, Mega Mapper/Driver
Countrymanager The Netherlands
gerben
Waze Champs
 
Posts: 4285
Joined: Sun Dec 13, 2009 10:42 pm
Location: Almelo
Has thanked: 8 times
Been thanked: 62 times

Re: Greasemonkey script for easy river drawing

Postby gerben » Tue Jan 03, 2012 5:43 pm

This tool might be useable to make railroads visible in the client too. I'll try this tonight (not sure if there is an appropriate landmark type).
Back to my G1 (HTC Heart) - Froyo by Laszlo ROM - Waze 3.7.x (beta). Soon to be the owner of a Nokia Lumia 920 (WP8 Beta client)
Waze Champ, Mega Mapper/Driver
Countrymanager The Netherlands
gerben
Waze Champs
 
Posts: 4285
Joined: Sun Dec 13, 2009 10:42 pm
Location: Almelo
Has thanked: 8 times
Been thanked: 62 times

Re: Greasemonkey script for easy river drawing

Postby gerben » Sun Jan 29, 2012 11:48 pm

This tool has stopped working because the url for the editor has canged.

Working code:

Code: Select all
// ==UserScript==
// @name Papyrus: Street to river
// @description This script create a new river landmark in waze editor papyrus. It transforms the the geometry of a new unsaved street to a polygon.
// @namespace http://www.tay-tec.de/waze-street-to-river
// @match https://world.waze.com/editor/*
// @match https://www.waze.com/editor/*
// ==/UserScript==


// Mini howto:
// 1) install this script as greasemonkey script or chrome extension
// 2) draw a new street but do not save the street
// 3) add and apply a street name to define the rivers name and the the width of the river
//    Example: "20m Spree" creates a 20 meters width river named "Spree"
// 4) Select the helper street
// 5) Click the "Street to river" button
// 4) Delete the helper street
// 5) Edit the new landmark as you like


if ('undefined' == typeof __RTLM_PAGE_SCOPE_RUN__) {
  (function page_scope_runner() {
    // If we're _not_ already running in the page, grab the full source
    // of this script.
    var my_src = "(" + page_scope_runner.caller.toString() + ")();";

    // Create a script node holding this script, plus a marker that lets us
    // know we are running in the page scope (not the Greasemonkey sandbox).
    // Note that we are intentionally *not* scope-wrapping here.
    var script = document.createElement('script');
    script.setAttribute("type", "text/javascript");
    script.textContent = "var __RTLM_PAGE_SCOPE_RUN__ = true;\n" + my_src;

    // Insert the script node into the page, so it will run, and immediately
    // remove it to clean up.  Use setTimeout to force execution "outside" of
    // the user script scope completely.
    setTimeout(function() {
          document.body.appendChild(script);
          document.body.removeChild(script);
        }, 0);
  })();

  // Stop running, because we know Greasemonkey actually runs us in
  // an anonymous wrapper.
  return;
}


function streetToRiver() {
 
 var defaultWidth = 20;

  insertButton();

  function insertButton() {
    var btn = $('<button title="create a new street, select and click this button">Street to river</button>');
    btn.click(start);
    var cnt = $('<div style="padding:0.5em 15px; background:#333; color:#fff"/>');
    cnt.append(btn);
    $("div.contents","#editPanel").after(cnt);
    console_log("Street to river initialized");
  }

  function start(ev) {
    var foundSelectedSegment = false;
    for (var s=selectionManager.selectedItems.length-1; s>=0; s--) {
      var sel = selectionManager.selectedItems[s];
      if (sel.type == "segment" && sel.state == "Insert") {
   // found segment
   foundSelectedSegment = true;
   if (convertToLandmark(sel))
   {
     alert("Successfully created new river landmark");
   }
      }
    }
    if (! foundSelectedSegment) {
   alert("No unsaved and selected new street found!");
      }
  }

  function convertToLandmark(sel) {
   
    var leftPa, rightPa, leftPb, rightPb;
    var prevLeftEq, prevRightEq;
    var street = getStreet(sel);
   
    var displacement = getDisplacement(street);
   
    var polyPoints = null;
    var vertices = sel.geometry.getVertices();
    for (var i=vertices.length-1; i>0; i--)
    {
      var pa = vertices[i];
      var pb = vertices[i-1];
      var scale = (pa.distanceTo(pb) + displacement) / pa.distanceTo(pb);
     
      leftPa = pa.clone();
      leftPa.resize(scale, pb, 1);
      rightPa = leftPa.clone();
      leftPa.rotate(90,pa);
      rightPa.rotate(-90,pa);
     
      leftPb = pb.clone();
      leftPb.resize(scale, pa, 1);
      rightPb = leftPb.clone();
      leftPb.rotate(-90,pb);
      rightPb.rotate(90,pb);
     
      var leftEq = getEquation({ 'x1': leftPa.x, 'y1': leftPa.y, 'x2': leftPb.x, 'y2': leftPb.y });
      var rightEq = getEquation({ 'x1': rightPa.x, 'y1': rightPa.y, 'x2': rightPb.x, 'y2': rightPb.y });
      if (polyPoints == null) {
   polyPoints = [ leftPa, rightPa ];
      }
      else {
   var li = intersectX(leftEq, prevLeftEq);
   var ri = intersectX(rightEq, prevRightEq);
   if (li && ri) {
     polyPoints.unshift(li);   
     polyPoints.push(ri);
   }
   else {
     polyPoints.unshift(leftPb.clone());
     polyPoints.push(rightPb.clone());
   }
      }

      prevLeftEq = leftEq;
      prevRightEq = rightEq;
    }
   
    polyPoints.push(rightPb);
    polyPoints.push(leftPb);
   
    var polygon = new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(polyPoints));
   
    var landmark = new Waze.Feature.Vector.Landmark(polygon);
    landmark.attributes.mtfcc = "H3010";
    if (street) {
      landmark.attributes.name = street.name.replace(/^\d+(m|ft)\s*/, '');
    }
    var what = wazeModel.actionManager.add(new Waze.Action.AddLandmark(landmark));
   
    return true;
  }

 
  function getEquation(segment) {
    if (segment.x2 == segment.x1)
      return { 'x': segment.x1 };
   
    var slope =  (segment.y2 - segment.y1) / (segment.x2 - segment.x1);
    var offset = segment.y1 - (slope  * segment.x1)
    return { 'slope': slope, 'offset': offset };
  }

  //
  // line A: y = ax + b
  // line B: y = cx + b
  //
  // x = (d - b) / (a - c)
  function intersectX(eqa,eqb,defaultPoint) {
    if ("number" == typeof eqa.slope && "number" == typeof eqb.slope) {
      if (eqa.slope == eqb.slope)
   return null;
     
      var ix = (eqb.offset - eqa.offset) / (eqa.slope - eqb.slope);
      var iy = eqa.slope * ix + eqa.offset;
      return new OpenLayers.Geometry.Point(ix, iy);
    }
    else if ("number" == typeof eqa.x) {
      return new OpenLayers.Geometry.Point(eqa.x, eqb.slope * eqa.x + eqb.offset);
    }
    else if ("number" == typeof eqb.y) {
      return new OpenLayers.Geometry.Point(eqb.x, eqa.slope * eqb.x + eqa.offset);
    }
    return null;
  }
 

  function getStreet(segment) {
    if (! segment.attributes.primaryStreetID)
      return null;
    var street = segment.model.streets.get(segment.attributes.primaryStreetID)
    return street;
  }
 
  function getDisplacement(street) {
    if (! street)
      return defaultWidth;
    if (street.name.match(/^(\d+)m\b/))
      return parseInt(RegExp.$1);
    if (street.name.match(/^(\d+)ft\b/))
      return parseInt(RegExp.$1) * 0.3048;
    return defaultWidth;
  }
 
  function console_log(msg) {
    if (console.log)
      console.log(msg);
  }
}

   


streetToRiver();
Back to my G1 (HTC Heart) - Froyo by Laszlo ROM - Waze 3.7.x (beta). Soon to be the owner of a Nokia Lumia 920 (WP8 Beta client)
Waze Champ, Mega Mapper/Driver
Countrymanager The Netherlands
gerben
Waze Champs
 
Posts: 4285
Joined: Sun Dec 13, 2009 10:42 pm
Location: Almelo
Has thanked: 8 times
Been thanked: 62 times

PreviousNext

Return to Waze Map Editor

Who is online

Users browsing this forum: bardhono, Google [Bot]