Open bcamper opened 8 years ago
Here's the current scene file I was experimenting with, for posterity:
github only allows txt extensions, not yaml :/
(This would also be useful for bike map.)
I'll dust off the test code and try it out again :)
I've been looking at this with @meetar. There are two issues I'm unsure about that are holding back the quality/usefulness:
Here's a demo of current WIP, putting this down again for the moment - white path area is "flat", redder is steeper: https://mapzen.com/tangram/play/?lines=876-911&scene=https%3A%2F%2Fmapzen.com%2Fapi%2Fscenes%2F4%2F372%2Fresources%2Fwalkabout-style.yaml#16.0000/36.0887/-112.1627
Here's a variant showing the surrounding terrain steepness - black is flat, whiter is steeper:
There's a uniform u_show_steepness
on line 999 you can use to toggle that on/off.
This is super rad! Screenshots of San Francisco:
SRTM only terrain data doesn't fair so well (is too radar bumpy), here Munich:
I've made adjustments to the style here:
The key bits are:
Add the slope style to draw block, giving it width and order (this is for quick data exploration, would need to be reworked for final display):
roads:
draw:
slope2:
width: [[13,1px],[15,2px],[17,3m]]
color: red
order: function() { return feature.sort_rank +100; }
path:
draw:
# not clear why this is needed again, and why width isn't
slope2:
width: [[13,1px],[15,6px],[17,3m]] honored
color: red
order: function() { return feature.sort_rank + 0100; }
footway:
# because sidewalks are close to tall buildings, then the slopes are all wonky
sidewalk-crossing:
slope2:
visible: false
The style is defined as:
styles:
slope2:
base: lines
raster: custom
shaders:
blocks:
global: |
varying vec2 v_path;
position: |
v_path = abs(extrude.yx);
color: |
vec2 path = normalize(v_path);
const float pathsegs = 2.;
path = floor(path * pathsegs) / pathsegs;
path = normalize(path);
vec3 terrain = (sampleRaster(0).rgb - .5) * 2.4;
float steepness = clamp(pow(dot(path, terrain.xy) * 16., 1.5), -1., 1.);
const float segs = 5.;
steepness = floor(steepness * segs) / segs;
color.rgb = mix(vec3(1.), vec3(1.,0.,0.), abs(steepness));
@patriciogonzalezvivo has another option that is more performant by removing stepping
and setting the texture
filtering
to nearest
:
here is w a ramp https://mapzen.com/tangram/view/?scene=https://mapzen.com/api/scenes/15/377/resources/walkabout-style.yaml#18.70648/37.76610/-122.44203
The colors on the ramp could be manipulated easily to transition over X number of colors + alpha. In that case is using just this 5 pixels long ramp https://github.com/opentraffic/tangram-viz-experiments/blob/gh-pages/assets/palette-01.png
And some further enhancements from @matteblair:
quote:
Before I forget, here’s what I tried for the road slopes:
base: lines
raster: custom
texcoords: true
shaders:
extensions: OES_standard_derivatives
blocks:
color: |
vec2 path = vec2(dFdy(v_texcoord.x), dFdx(v_texcoord.x));
path = normalize(path);
vec3 terrain = (sampleRaster(0).rgb - .5) * 2.;
float steepness = clamp(abs(dot(path, terrain.xy)) * 8., -1., 1.);
color.rgb = vec3(1., 1. - steepness, 1. - steepness);
It uses screen-space derivatives of a line’s texture coordinates to determine the direction of the line geometry more accurately than with the extrusion vector. The results looked good to me in the few places that I could check, but someone with more knowledge of the terrain should check it. endquote
@nvkelso suggested we could try to show path steepness based on normal/elevation tile data.
We tried any initial prototype using the steepness of the terrain normal; deeper red means steeper terrain:
But, this isn't really right, because the steepness of the terrain does not necessarily equal the steepness of the path, e.g. a steep path could be going up a mountain, but a relatively flat path could also simply be going around a steep mountain. We can see this in the path above N. Valley Trail, where the mountain itself is steep, but the path appears to be going alongside the mountain.
To know how steep the path itself is, we need to take the dot product of path direction and the terrain normal (actually the xy component of the terrain normal since path direction is 2D). That gives something that (on first glance) looks closer to what we might expect: that same path above N. Valley Trail is mostly flat, but you can see steeper red segments that correspond to variations in the terrain itself.
This remains a prototype, however, more experimentation is needed to verify that this behavior is correct, and consider better ways to deal with caps ad joins on lines.
Another approach to consider, that may make more sense overall, is to just sample the raw elevation change of each path segment. There is no way to do that with existing Tangram pipeline though; options could include a) sampling the elevation in the vertex shader to create a custom varying and then measure the screenspace derivative of the elevation change (though there isn't 100% device support for vertex shader texture sampling, particularly on mobile devices), or b) a hook somewhere in the tile build process to do this CPU side (complicated by texture load timing and might imply a lot of new syntax that could be difficult to support cross-platform).