Skip to content

Conversation

@AtlasProgramming
Copy link
Collaborator

Style Preprocessor

This will add the ability to latch into the style loading and modify the style before it gets to the actual style parsing. There are two parts to this functionality. The first is a C++ based latch into the actual style that will allow a lambda to be assigned to each filter that will receive (in order of add) the data after it's loaded from the source (e.g. http/file/etc). Each filter is passed the output of the previous filter.

The second part is a platform implementation of this for iOS that creates a base filter class that the user can descend from, override a single method and then get the input data and return the data to pass along the filter chain. Since the filters are added at runtime, this will allow run-time filter plugins to be registered and utilized.

Potential uses for this are libraries of different filter types (e.g. uncompressing a compressed/encrypted format, filtering or translating layer properties before they are parsed, injecting specific layer types for all styles, etc).

An example implementation is included in the PR. This filter gets the style passed to it before it's parsed and it adjusts the style to remove some layer types. Since the plug-in receives the style before it goes to the parser, any transformation of the style could happen in the filter.

@implementation StyleFilterExample

// This will filter the data passed in
-(NSData *)filterData:(NSData *)data {
    // Don't call super

    // This example will remove any layer that has "metal-rendering-layer" in the id

    // Parse the JSON: Make the containers mutable
    NSError *error = nil;
    NSMutableDictionary *styleDictionary = [NSJSONSerialization JSONObjectWithData:data
                                                                          options:NSJSONReadingMutableContainers
                                                                            error:&error];

    NSData *tempResult = data;
    if (styleDictionary) {

        // Get the layer array
        NSMutableArray *layerArray = [styleDictionary objectForKey:@"layers"];

        // Create an array to hold which objects to remove since we can't remove them in the loop
        NSMutableArray *removedLayers = [NSMutableArray array];

        // Loop the layers and look for any layers that have the search string in them
        for (NSMutableDictionary *layer in layerArray) {
            NSString *layerID = [layer objectForKey:@"id"];

            // If we find the layers we're looking for, add them to the list of layers to remove
            if ([layerID containsString:@"metal-rendering-layer"]) {
                [removedLayers addObject:layer];
            }
        }

        // Go through and remove any layers that were found
        for (NSMutableDictionary *l in removedLayers) {
            [layerArray removeObject:l];
        }

        // Re-create the JSON, this time the layers we filtered out won't be there
        NSData *filteredStyleJSON = [NSJSONSerialization dataWithJSONObject:styleDictionary
                                                                    options:0
                                                                      error:&error];

        // If the JSON write is successful, then set the output to the new json style
        if (filteredStyleJSON) {
            tempResult = filteredStyleJSON;
        }

    }

    // Return the data
    return tempResult;

}

The style preprocessors are coupled to the engine at runtime using the addStyleFilter method on the map view.

    [self.mapView addStyleFilter:[[StyleFilterExample alloc] init]];

@github-actions github-actions bot added build Related to build, configuration or CI/CD iOS cpp-core labels Nov 19, 2025
@AtlasProgramming AtlasProgramming changed the title Adds Style Preprocessor Plugin Adds Style Preprocessor Plugin Capability Nov 19, 2025
@sjg-wdw
Copy link
Collaborator

sjg-wdw commented Nov 19, 2025

That seems pretty straightforward to me. Thoughts on naming @TimSylvester ?
And @louwers maybe hit up the guy who was interested in this to at least get feedback?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Related to build, configuration or CI/CD cpp-core iOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants