-
Notifications
You must be signed in to change notification settings - Fork 24
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
Mapbox expressions #2
Mapbox expressions #2
Conversation
@mvarendorff thanks for the contribution, this looks like some great work! great to see some tests in there too. I can see that this is a draft, but perhaps I can give some early feedback on things that I'll be looking for:
Great to see these improvements coming together! |
Thanks for the quick feedback already! I will try to move the text rotation out; it won't be of much use on its own because it also depends on the expressions introduced in the rest of the PR but should indeed be easier to review then! The rest of the commits I planned to either squash into one or commit batches of files separately eventually because pretty much everything (be it file location, or content) can change and the single commits mostly represent end of work days or me trying to clean up a bit before jumping into the next feature to receive expressions. I would update commit messages accordingly when doing that! The rest of the feedback I will incorporate into the "final" state of the PR! |
Sounds great! Thanks!
…On Mon, Sep 6, 2021 at 10:27 PM mvarendorff ***@***.***> wrote:
Thanks for the quick feedback already! I will try to move the text
rotation out; it won't be of much use on its own because it also depends on
the expressions introduced in the rest of the PR but should indeed be
easier to review then!
The rest of the commits I planned to either squash into one or commit
batches of files separately eventually because pretty much everything (be
it file location, or content) can change and the single commits mostly
represent end of work days or me trying to clean up a bit before jumping
into the next feature to receive expressions. I would update commit
messages accordingly when doing that!
The rest of the feedback I will incorporate into the "final" state of the
PR!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEKDQ7STJCFWAWOTSFGO3STUAWPENANCNFSM5DQQZBNA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
55539d5
to
4b17e73
Compare
I finally found some time to work on this again and clean things up a bit. I moved keeping the text upright to mvarendorff#1 for now so you can have a look at the isolated diff if you want. It does depend on this PR though so it merges into the branch this PR is made from. Let me know what you think! |
Michael,
The change looks very good. So great that you split it out, it makes a big
difference. I'll hold off on a thorough code review since it's dependent on
this PR, but I didn't notice any issues so it should be good to go.
David
…On Tue, Sep 21, 2021 at 7:59 AM Michel v. Varendorff < ***@***.***> wrote:
I finally found some time to work on this again and clean things up a bit.
I moved keeping the text upright to mvarendorff#1
<mvarendorff#1> for now
so you can have a look at the isolated diff if you want. It does depend on
this PR though so it merges into the branch this PR is made from.
Let me know what you think!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEKDQ7TKLCABEFRQDXTRMDDUDCMUZANCNFSM5DQQZBNA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Sounds good! Just to make sure this doesn't end up stale after a misunderstanding: This PR would be ready to check as well :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have a more thorough look later, but have a question regarding dependencies.
lib/src/expressions/interpolate/cubic_bezier_interpolation_expression.dart
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is 1286 lines of code, much of it new - so it's very hard to do a proper code review.
Could you split this into a few smaller PRs, ideally 3-400 lines of code each? For example, you could start with a PR to introduce the concept of expressions for existing functionality before introducing various new parsers and expressions. That makes the implications of various changes much easier to reason about. It will also reduce back-and-forth since with a smaller initial PR, you'll be able to avoid rework on subsequent changes.
Overall this looks quite good. I've added some comments and questions below.
import 'theme_function_model.dart'; | ||
|
||
abstract class ThemeFunction<T> { | ||
Map<FunctionModel, _ZoomValue> _cache = {}; | ||
|
||
T? exponential(FunctionModel<T> model, double zoom) { | ||
T? exponential(FunctionModel<T> model, Map<String, dynamic> args) { | ||
final zoom = args['zoom'] as double; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that we're passing args
and not just a zoom, the cached value could be incorrect depending on the arguments used by the function, right? in other words, is this cache now broken?
The idea behind the cache is to optimize rendering, i.e. only calculate expensive expressions once when rendering. I found that this made a big difference in the profiler, since tiles can result in evaluating expressions 1000s of times, and some expressions are expensive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point and honestly, I am not sure. The arguments passed to the function are just the properties of the VectorTileFeature that's currently being rendered which by my understanding stay identical per feature regardless of the zoom making the zoom level the only relevant property from the args for caching. I am just uncertain whether my assumption of the properties of VectorTileFeatures remaining identical is accurate or not (if it was accurate, maybe it's still enough because the properties are still tied to the zoom level meaning the zoom level would still be sufficient as cache key).
What's your take on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the properties of the VectorTileFeature are used in calculations, then this needs to be reworked since the cache would be broken. If they're not used in calculations, then they should not be passed in because it could lead to future bugs and makes the code more complicated.
Well, that's pretty funny :D
I'm just off on vacation so won't be able to take a look for a week or so.
If the dependency is already used, it's fine.
David
…On Mon, Oct 4, 2021 at 11:41 PM Michel v. Varendorff < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In
lib/src/expressions/interpolate/cubic_bezier_interpolation_expression.dart
<#2 (comment)>
:
> @@ -0,0 +1,26 @@
+import 'package:bezier/bezier.dart';
+import 'package:vector_math/vector_math.dart';
I wasn't aware this would be an issue. I just double checked and
apparently vector_math is already part of the dependency tree on main:
https://github.com/greensopinion/dart-vector-tile-renderer/blob/02dfe1c9c865fde83c4f74f050fafb5e7fd643b5/pubspec.lock#L336-L342
I could have a look for an alternative if so desired but I am not sure
there will be any other suitable packages. The clause itself appears to be
a pretty standard one included in BSD-2- and BSD-3-clause licenses which
flutter itself is published under as well.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEKDQ7TDZ3LPNOOGDPLSR5DUFKM2FANCNFSM5DQQZBNA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
4b17e73
to
da6bcb9
Compare
Don't mind the force push; following your request I will split off a smaller piece of this thing and force push that as sole commit to this PR, then once that is merged, take the next chunk and so on. |
Great, thanks |
@mvarendorff I've done some work on expressions over the past couple of days that has duplicated some of the functionality on this pull request. There's still more to be done but it's a start and addresses the issue around caching. You'll notice that I've skipped generics, which I think helps to simplify the implementation. I'd be interested to know what you think, whether there are any major shortcomings or missing functionality in what I've done. this library now depends on bahung1221/dart-vector-tile#6 which is not yet merged |
Hey there! Thanks for the time you put into that matter and sorry for the hiatus. Sadly the time I had ran out much earlier than I thought and I didn't have a chance to work on this again further than to throw it in our project and hope for it to work :D Your approach looks a tad more extensible with the way you register parsers; I am personally a fan of generics because it avoids a bunch of (usually implicit) I am also not sure whether it's a good idea to keep all parsers in one file; it's already 400+ lines long and there are several expressions still missing (case, coalesce and step for example). Last thing I noticed was the missing Color support in the current expression implementation. Especially in interpolations which are a common usecase for that (fading opacity based on zoom level for example) the expression just returns null if the base is not a number. That was also one of the reasons I kept the generics in there because they allowed for passing an expected type from the place of parsing (e.g. line-color has to be parsed as a color, opacities always have to be double, etc) which is not possible now from what I can tell but required since it can be too late at evaluation time (since you cannot interpolate a string directly but have to make sure it's a Color / double at that time already and know which one it is). Alternatively evaluate would have to take a generics parameter and evaluate would have to contain the respective logic to make sure the values are the correct type. Out of curiosity because I couldn't find the respective section in the code: How did you address caching? |
You're welcome, and not to worry!
Agreed, we can split these out if/when the file gets too big (maybe it is already)
:D I didn't get to everything. I agree that Color is missing, feel free to contribute if you want. I couldn't take it all on at once and didn't have a need just yet. As for type safety, that's an improvement that we could add too if it doesn't clutter the code up too much. I agree with your misgivings about everything dynamic, but also want the code to stay clean and maintainable.
It's a worse-is-better approach: interpolate_expression.dart#L121 |
Closing for now, since some of this is done. Feel free to open an issue if you want to discuss further, or a new pull request if you want to continue improving it. |
Right, this is a minor chaos
and still work in progress.This PR aims to provide support for a variety of expressions (like case, match, step, interpolate and coalesce) in the Mapbox specification (in an effort to close #1)
The process of getting here was taking the theme we got from mapbox and letting the ThemeReader do its best to parse it without running into errors. To allow for different expressions, two new kinds of classes were added;
Parser
andExpression
with the parsers producing expressions from the theme which can then later be evaluated with information from the render context (zoom level, rotation and a feature's properties).Existing typedefs for functions were also replaced with Expressions in an effort to unify the types of information that are passed around.
A central
parse<T>
function may be used to try getting an expression from part of the theme; the type parameter is required to parse for certain types (parse<String>
runs different code thanparse<double>
for example) and the whole system should be reasonably extensible.