Page 3 of 6

Re: Greasemonkey script for easy river drawing

Posted: Mon Feb 10, 2014 2:25 pm
by EduardoCarvajal
shomgoon wrote:Thank you for good job
I use this script for a long time
Version: WME Street to River PLUS 1.0 in your link does not work in Chrome

Please help
Hi Shomgoon:

Street to River PLUS Version 14.2.1 solves some compatibility problems with the latest version of Waze Map Editor.

Tampermonkey for Chrome is the easy way to install or upgrade the script. Please follow this simple steps:

1. If you manually install the script on Chrome, go to Tools -> Extensions and manually delete Street to River or Street to River Plus script.

2. Install Tampermonkey for Chrome from Chrome Web Store (it's free). Here it is the link: Tampermonkey

3. Once you install Tampermonkey, go to UserScripts.org using the following link: Street to River Plus

4. Press Install button (upper right corner of your screen)

Please note that Tampermonkey automatically upgrade the Street to River PLUS script every time a new version is released.

Re: Greasemonkey script for easy river drawing

Posted: Mon Feb 10, 2014 5:48 pm
by EduardoCarvajal
shomgoon wrote:Thank you very much!
I tried to install it without Tampermonkey :mrgreen:
All works perfectly
Great!!!

Re: Greasemonkey script for easy river drawing

Posted: Sat May 31, 2014 12:50 pm
by EduardoCarvajal
Please notice that this topic is inactive. This is the new topic for Street to River

Re: Greasemonkey script for easy river drawing

Posted: Sat Apr 05, 2014 7:02 am
by estebanflow
Good job friend Eduardo.

I had been looking for this script for a long time. I was looking for it as Street to River :lol:

Re: Street to River PLUS

Posted: Fri Jul 12, 2013 12:42 pm
by foxitrot
EduardoCarvajal wrote:This is a modified version of Street to River Script that I call Street to River PLUS.
[...] To expand an existing river: [...]
I've drawn maybe a 1 km long street and then pressed the STR button. Just the first hundred meters of my river were created. Then I've deleted the corresponding first few hundred meters of my helper street and pressed it again - another hundred meters of river were created (actually, my river landmark got correctly extended by the length). And so on and so on... until the end of my segment was reached.
Did it behave as expected?

Additionally, I've tried to extend an existing river landmark, but it often got the river sides twisted at my extension pont, possibly because of the not matching order of points around the two polygons. Could this be taken into account when extending an existing polygon?

Re: Street to River PLUS

Posted: Mon Oct 14, 2013 6:03 am
by foxitrot
EduardoCarvajal wrote: Waze editor is limit to 40 changes between savings. If you draw a very long and complex street, the river will be truncated to the first 40 points (changes). This is by design, and it’s imposed by Waze editor (if you don’t believe me, manually draw a very complex river, with more the 50 changes, and try to save it).
Your description sounds pretty reasonably, just... where have you got the "at most 40 changes between savings" limit in the editor? To check it, I've just manually drawn a river landmark polygon with over 100 nodes and it immediately saved - flawlessly. Whenever I'm modifying any forest's landmark, you can bet I make a couple of hundreds of changes between saves...

Either the system works (exceptionally :lol: it does happen) and you can make nearly any number of changes between saves, or you constantly get save errors...

[edit]OK, Now I see the culprit: :roll:

Code: Select all

    // 2013-06-03: Reach waze limit?
    if(polyPoints.length > 40){         
        break;
    }
Extending it to e.g. 440 solves the problem. I recommend you discarding the code block completely, WME does not have such limit. If the Save fails, then the problem is somewhere else (unfortunately it is mostly impossible :( to guess, where).
EduardoCarvajal wrote:To expand an existing river:
This seems to sometimes work correctly, but occasionally (after one or two modifications and saves?) incorrect two nodes are chosen for landmark continuation, not these two, where the segment crosses the landmark borderline between them.

Re: Greasemonkey script for easy river drawing

Posted: Fri Jan 06, 2012 9:13 pm
by fvwazing
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"
(90.65 KiB) Downloaded 4134 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.

Re: Greasemonkey script for easy river drawing

Posted: Thu Dec 29, 2011 2:50 am
by gerben
I don't get the street-to-river button, or I don't see it. Where should it be?

Re: Greasemonkey script for easy river drawing

Posted: Tue Jan 03, 2012 5:43 pm
by gerben
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).

Re: Greasemonkey script for easy river drawing

Posted: Sun Jan 29, 2012 11:48 pm
by gerben
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();