Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line width property based on zoom #5861

Closed
rigoneri opened this issue Dec 14, 2017 · 3 comments
Closed

Line width property based on zoom #5861

rigoneri opened this issue Dec 14, 2017 · 3 comments

Comments

@rigoneri
Copy link

Hey, I'm not sure if this is the right place to post questions like this, but after hours I couldn't find an answer, and this might help someone in the future.

To start, I have the width of a line (in meters) that I want to be able to be correctly adjusted based on zoom level. So I originally had something like this:

paint: {
    "line-width": lineWidth
}

But the line width we have is in meters not pixels and when I adjusted the zoom level it stayed fixed to that size. And after googling around couldn't find a easy solution and we came up with this:

paint: {
    "type": "exponential",
    "base": 2,
    "stops": [
        [0, lineWidth * Math.pow(2, (0 - 16))],
        [24, lineWidth * Math.pow(2, (24 - 16))]
    ]
}

That surprisingly works but seems to me that there's a easier way to achieve that.

However now we've changed to have the line width as a property in the tiles, because the line width can be different based one certain lines and in different line "paths". So we came up with this:

paint: {
    "line-width": {
        "type": "exponential",
        "property": "line_width",
        "base": 2,
        "stops": [
            [{zoom: 10, value: 12}, 12 * Math.pow(2, (10 - 16))],
            [{zoom: 24, value: 12}, 12 * Math.pow(2, (24 - 16))],
        ]    
    }
}

However that only handles if the line width is 12 but the line width can vary between 0 to 50. Which lead me to creating a function that generates the stops to every single possible combination. Which seems way overkill, and I'm seeing some performance issues.

Is there a easier way to achieve this? Be able to draw a line from a property where the width is correctly represented in every zoom level in meters. (If I have to convert it into pixels instead of meters before generating the vector tiles I can do that, but will need some guidance)

Thanks in advance,

Rigo

@jfirebaugh
Copy link
Contributor

You can use expressions to do this. Something like:

["interpolate", ["exponential", 2], 
  0, ["*", ["get", "line_width"], ["^", 2, -16]], 
  24, ["*", ["get", "line_width"], ["^", 2, 8]]]

More documentation here.

@rigoneri
Copy link
Author

Awesome! Thanks for the help!

For future reference I end up with this, had to add the 'zoom' as the input:

paint: {
    'line-width': [
        'interpolate', 
        ['exponential', 2], 
        ['zoom'],
        10, ["*", ["get", "line_width"], ["^", 2, -6]], 
        24, ["*", ["get", "linw_width"], ["^", 2, 8]]
    ],
}

@joedjc
Copy link

joedjc commented Jul 9, 2018

@jfirebaugh @rigoneri This is really useful...i'm also trying to use it to display a circle radius's and line widths in meters. I'm finding the accuracy is affected by the map projection. Would be interested to know if this could also be accounted for using expressions...perhaps if latitude were available as a property? (doesn't need to be perfect - I guess it would be impossible for very large shapes without distorting them?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants