Files
MapLibreParticleLab/design-proposals/2025-05-08-plugin-layers.md
Mike Taves fba652eb72 fix: typos (#4202)
Co-authored-by: Bart Louwers <bart@emeel.net>
2026-07-13 15:08:27 +00:00

3.2 KiB

Plug-In Layer Architecture Design Proposal

Motivation

This project is to add the ability to "register" additional layer types at runtime and have them integrated into the standard parameter/rendering pipeline.

Proposed Change

For the initial implementation, the following functionality is proposed:

  • At the platform level, be able to register a plug-in layer that is then parseable by the style parser
  • The plug-in layer will be limited to simple rendering (via handing off the rendering context to the plug-in layer) and will not include the ability to define drawables/etc
  • The "paint" properties will be parseable, support expressions and passed in frame by frame
  • A custom set of "plugin-propeties" will also be available at the same level as the "paint" properties
  • The plug-in layer will be notified about lifecycle events (creation, addition to the mapview, removal, destruction/etc) and be expected to manage it's own resources

Future features:

  • Placeholder for ideas that could be implemented in the future

Example IOS Utilization

An example implementation is shown in the PR: https://github.com/maplibre/maplibre-native/pull/3430 The platform/darwin/app/PluginLayerExampleMetalRendering.h/mm class shows how the layer manages it's own rendering and how properties from the style are passed to it. In platform/ios/app/MBXViewController.mm there's a single line where the plug-in layer class is registered with the map view

    [self.mapView addPluginLayerType:[PluginLayerExampleMetalRendering class]];

The layer is then added to the style in the platform/darwin/app/PluginLayerTestStyleSimple.json file and an expression based scale property is added

 {   "id": "metal-rendering-layer-1",
            "type": "plugin-layer-metal-rendering",
            "properties": {
                "color1":"#FFAADD",
                "offset-x": -300
            },
            "paint": {
                "scale": [
                    "interpolate",
                    ["linear"],
                    ["zoom"],
                    5,
                    0.5,
                    15,
                    3.0
                ]
            }
        },

That scale property is then evaluated by the internal implementation and passed back to the plug-in layer via the onUpdateLayerProperties virtual method where it's incorporated by the rendering.

-(void)onUpdateLayerProperties:(NSDictionary *)layerProperties {
    NSLog(@"Metal Layer Rendering Properties: %@", layerProperties);

    NSNumber *offsetX = [layerProperties objectForKey:@"offset-x"];
    if (offsetX) {
        _offsetX = [[layerProperties objectForKey:@"offset-x"] floatValue];
    }

    NSNumber *scale = [layerProperties objectForKey:@"scale"];
    if (scale) {
        if ([scale isKindOfClass:[NSNumber class]]) {
            _scale = [scale floatValue];
        }
    }

}

API Modifications

The platform layer would provide a base class for implementing the plug-in layer. The mapview would have a new method for registering the plug-in layer class.

Migration Plan and Compatibility

All API changes are additive, so, no backwards compatibility issues should be present.

Rejected Alternatives

N/A