-
-
Notifications
You must be signed in to change notification settings - Fork 65
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
Proposal: Support registering external functions to be used in expressions in the style #516
Comments
I see the need, but I wonder if just catching the data as it's being parsed might be simpler. |
I agree with @sjg-wdw that it would be better to add way for the user to get all attributes of a point/line/polygon after parsing, and then being able to freely modify the attributes with a user-defined function. This means one can update/add/delete properties... |
I can see that modifying the attribute data could be quite interesting as well, it has some challenges such as how to define which objects to modify, how to update the previous modification when the users locale changes and how to track when the data with the relevant properties is loaded. In particular considering clusters, where the data is generated on the fly using the style rules, I don't think this approach will be easy to implement but feel free to prove me wrong. As for this approach being less logical on natives I would like to give some counter arguments:
In summary, the evaluation inside maplibre is already dynamic and takes into account many global and runtime variables, the handler for custom code would just be another one. I would also argue that from a developer/library user point of view, setting a handler/delegate/provider is a common pattern on all platform. |
I guess the next question, assuming this is possible, might be the API signature. |
For Native I'd run this by the team and see what they think. Might be something really easy to do, but at least they're familiar with that part of the system. |
It would be great if we could modify the GeoJSON shapes too, in addition to properties. This got me thinking about a potentially related use case that I am going to have to support soon: creating ellipses on the fly. Basically I have a set of points with semi-major and semi-minor axes, but I need to render them as ellipses (or polygonal approximations of them, given GeoJSON constraints). These will be delivered to the front-end as features in vector tiles. I have control over the vector tiles, but the size of the (potentially many) features coming across the wire would dramatically increase if I have to create the polygon approximations on the server. It would be ideal if I could handle this transformation client-side. |
This idea has been explored before in maplibre/maplibre-gl-js#1295 and there is a bit of a summary in a comment about the challenges. |
@neodescis if we allow geometry-on-the-fly we could also do bezier curves for rounded lines... |
I was referenced here to discuss a feature request for MapLibre GL JS, written in maplibre/maplibre-gl-js#4964. In summary, I would like to have a way to specify (global) map state that can somehow be used in the style. The use case is to define a map theme, and allow the style to dynamically change the rendering of the style based on the chosen user theme. My feature request would be satisfied if I could define custom functions to be used in the style specification, such that I can make some values in the style dynamic based on the map configuration in the client application. If it makes it easier to discuss, I could also write a separate proposal just for the MapLibre style specification to allow defining and using map state in a style. There is a proposal for syntax in maplibre/maplibre-gl-js#4964, similar to how Seeing that this proposal has been open for more than 10 months, what is the best way to move this forward? |
I'm pretty sure I've seen something similar related to dark theme and light theme that can benefit from "global" variables, but I can't find it... :-( |
Thanks, I split off this proposal into #886 where it can be discussed in depth. |
Design Proposal: External style functions
Motivation
Some things, such as converting unix timestamps to be shown in a human readable way in for the end users locale can be extremely complex to accomplish using style expressions. Another case is implementing for example thousands separator for numbers. These things depend on the app user's locale settings and potentially even timezones.
While it could be theoretically possible to extend the style specification with every helper function app developers would need, or write extremely long and complex expressions, in many cases it would be much more convenient for everyone if there was a standard way for applications to register their own utility functions that could be used from the style.
Another example in the past was that I would have liked to use regular expressions in the string handling in the style. This proposal and js implementation were never accepted, because regular expression engines are different on different platforms, and there was a risk of introducing cross platform incompatibilities in the spec (iirc). Meanwhile, as a developer, I had no reasonable route forward (except forking the entire project, on 3 platforms), even if I was willing to accept minor differences between platforms.
The feature could also be used for prototyping new functionality and showcasing possibilities of functionality that could be included in the specification. For example one could hack together a function which returns the
icon-offset
based on the camera transformation matrix, to correctly place the POI in 3d space, even though this feature is not yet available.If the value of the parameter could be updated based on animation frames, it would even be possible to make icons bounce by returning a different value for
icon-offset
each frame.Proposed Change
Extend the style specification with a new expressions
exec
which takes two parameters, a string type parameter for the name of the external function to execute, and an array type parameter with the the parameters passed to the external function.Examples:
["exec", "formatDate", [ ["get", "timestamp"], ["get", "poi_timezone"]] ]
API Modifications
Define a new type that is a catch all for all
exec
functions.Add a new API function to the
maplibre
programmatic api to set and unset the catch all handler.The new types and API could be:
Internally the engine would keep a map of the exec functions used, the previous value and
Migration Plan and Compatibility
This does not replace existing functionality but allows easy prototyping of new style expressions prior to rolling them into the spec.
Rejected Alternatives
The reason for a catch all function rather than registering individual handlers are:
registerFunction(funcName, funcImpl)
on top of this single handler, but if maplibre implements this friendlier api, it is not possible to implement a catchall api.The reason for passing params in a single array rather than passing params indivdually:
The reason why the catch all cannot just return the value:
until-animattion-frame
and then once the fetch has resolved, the final value can be returned with a cacheHint offorever
.The text was updated successfully, but these errors were encountered: