<commit_before>
#import "MapBaseController.h"

@interface ClusteredMarkersController : MapBaseController

@end

@interface MyMarkerClusterElementBuilder : NTClusterElementBuilder

@end

@implementation ClusteredMarkersController

-(void)viewDidLoad
{
    [super viewDidLoad];
    
    [self.contentView addBaseLayer: NT_CARTO_BASEMAP_STYLE_POSITRON];
    
    // Initialize a local vector data source
    NTProjection* projection = [[self.contentView.mapView getOptions] getBaseProjection];
    NTLocalVectorDataSource* vectorDataSource = [[NTLocalVectorDataSource alloc] initWithProjection:projection];

    // Create element builder
    MyMarkerClusterElementBuilder* clusterElementBuilder = [[MyMarkerClusterElementBuilder alloc] init];
    
    // Initialize a vector layer with the previous data source
    NTClusteredVectorLayer* vectorLayer = [[NTClusteredVectorLayer alloc] initWithDataSource:vectorDataSource clusterElementBuilder:clusterElementBuilder];
    
    // Add the previous vector layer to the map
    [[self.contentView.mapView getLayers] add:vectorLayer];
    
    // Read .geojson
    NSString* fullpath = [[NSBundle mainBundle] pathForResource:@"cities15000" ofType:@"geojson"];
    NSString* json = [NSString stringWithContentsOfFile:fullpath encoding:NSUTF8StringEncoding error:nil];
    
    // .geojson parsing
    NTGeoJSONGeometryReader* geoJsonReader = [[NTGeoJSONGeometryReader alloc] init];
    [geoJsonReader setTargetProjection:projection];
    
    NTFeatureCollection* features = [geoJsonReader readFeatureCollection:json];
    
    // Initialize basic style, as it will later be overridden anyway
    NTMarkerStyle *style = [[[NTMarkerStyleBuilder alloc] init] buildStyle];
    
    NTVectorElementVector *elements = [[NTVectorElementVector alloc]init];
    
    for (int i = 0; i < [features getFeatureCount]; i++) {
        NTPointGeometry *geometry = (NTPointGeometry *)[[features getFeature:i] getGeometry];
        
        NTMarker *marker = [[NTMarker alloc] initWithGeometry:geometry style:style];
        [elements add:marker];
    }
    
    // Add them all at once to avoid flickering
    [vectorDataSource addAll:elements];
}

@end

@interface MyMarkerClusterElementBuilder ()

@property NSMutableDictionary* markerStyles;

@end

@implementation MyMarkerClusterElementBuilder

-(NTVectorElement*)buildClusterElement:(NTMapPos *)mapPos elements:(NTVectorElementVector *)elements
{
    if (!self.markerStyles) {
        self.markerStyles = [NSMutableDictionary new];
    }
    
    NSString* styleKey = [NSString stringWithFormat:@"%d",(int)[elements size]];
    
    NTMarkerStyle* markerStyle = [self.markerStyles valueForKey:styleKey];
    
    if ([elements size] == 1) {
        markerStyle = [(NTMarker*)[elements get:0] getStyle];
    }
    
    if (!markerStyle) {
        
        UIImage* image = [UIImage imageNamed:@"marker_black.png"];
        
        UIGraphicsBeginImageContext(image.size);
        [image drawAtPoint:CGPointMake(0, 0)];
        
        CGRect rect = CGRectMake(0, 15, image.size.width, image.size.height);
        [[UIColor blackColor] set];
        
        NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
        [style setAlignment:NSTextAlignmentCenter];
        
        NSDictionary *attr = [NSDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName];
        [styleKey drawInRect:CGRectIntegral(rect) withAttributes:attr];
        
        UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        NTBitmap* markerBitmap = [NTBitmapUtils createBitmapFromUIImage:newImage];
        NTMarkerStyleBuilder* markerStyleBuilder = [[NTMarkerStyleBuilder alloc] init];
        
        [markerStyleBuilder setBitmap:markerBitmap];
        [markerStyleBuilder setSize:30];
        [markerStyleBuilder setHideIfOverlapped:NO];
        [markerStyleBuilder setPlacementPriority:-(int)[elements size]];
        
        markerStyle = [markerStyleBuilder buildStyle];
        [self.markerStyles setValue:markerStyle forKey:styleKey];
    }
    
    NTMarker* marker = [[NTMarker alloc] initWithPos:mapPos style:markerStyle];
    [marker setMetaDataElement:@"elements" element:[[NTVariant alloc] initWithLongVal:[elements size]]];
    
    return marker;
}

@end
<commit_msg>Simplified and optimized clustering sample<commit_after>
#import "MapBaseController.h"

@interface ClusteredMarkersController : MapBaseController

@end

@interface MyMarkerClusterElementBuilder : NTClusterElementBuilder

@end

@implementation ClusteredMarkersController

-(void)viewDidLoad
{
    [super viewDidLoad];
    
    [self.contentView addBaseLayer: NT_CARTO_BASEMAP_STYLE_POSITRON];
    
    // Initialize a local vector data source
    NTProjection* projection = [[self.contentView.mapView getOptions] getBaseProjection];
    NTLocalVectorDataSource* vectorDataSource = [[NTLocalVectorDataSource alloc] initWithProjection:projection];

    // Create element builder
    MyMarkerClusterElementBuilder* clusterElementBuilder = [[MyMarkerClusterElementBuilder alloc] init];
    
    // Initialize a vector layer with the previous data source
    NTClusteredVectorLayer* vectorLayer = [[NTClusteredVectorLayer alloc] initWithDataSource:vectorDataSource clusterElementBuilder:clusterElementBuilder];
    
    // Add the previous vector layer to the map
    [[self.contentView.mapView getLayers] add:vectorLayer];
    
    // Read .geojson
    NSString* fullpath = [[NSBundle mainBundle] pathForResource:@"cities15000" ofType:@"geojson"];
    NSString* json = [NSString stringWithContentsOfFile:fullpath encoding:NSUTF8StringEncoding error:nil];
    
    // .geojson parsing
    NTGeoJSONGeometryReader* geoJsonReader = [[NTGeoJSONGeometryReader alloc] init];
    [geoJsonReader setTargetProjection:projection];
    
    NTFeatureCollection* features = [geoJsonReader readFeatureCollection:json];

    // Create style for markers
    NTMarkerStyle* style = [[[NTMarkerStyleBuilder alloc] init] buildStyle];

    // Add the loaded feature collection to the data source
    [vectorDataSource addFeatureCollection:features style:style];
}

@end

@interface MyMarkerClusterElementBuilder ()

@property NSMutableDictionary* markerStyles;
@property UIImage* markerImage;

@end

@implementation MyMarkerClusterElementBuilder

-(NTVectorElement*)buildClusterElement:(NTMapPos *)mapPos elements:(NTVectorElementVector *)elements
{
    if (!self.markerStyles) {
        self.markerStyles = [NSMutableDictionary new];
    }
    
    NSString* styleKey = [NSString stringWithFormat:@"%d",(int)[elements size]];
    
    NTMarkerStyle* markerStyle = [self.markerStyles valueForKey:styleKey];
    
    if ([elements size] == 1) {
        markerStyle = [(NTMarker*)[elements get:0] getStyle];
    }
    
    if (!markerStyle) {
        
        if (!self.markerImage) {
            self.markerImage = [UIImage imageNamed:@"marker_black.png"];
        }
        
        UIGraphicsBeginImageContext(self.markerImage.size);
        [self.markerImage drawAtPoint:CGPointMake(0, 0)];
        
        CGRect rect = CGRectMake(0, 15, self.markerImage.size.width, self.markerImage.size.height);
        [[UIColor blackColor] set];
        
        NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
        [style setAlignment:NSTextAlignmentCenter];
        
        NSDictionary *attr = [NSDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName];
        [styleKey drawInRect:CGRectIntegral(rect) withAttributes:attr];
        
        UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        NTBitmap* markerBitmap = [NTBitmapUtils createBitmapFromUIImage:newImage];
        NTMarkerStyleBuilder* markerStyleBuilder = [[NTMarkerStyleBuilder alloc] init];
        
        [markerStyleBuilder setBitmap:markerBitmap];
        [markerStyleBuilder setSize:30];
        [markerStyleBuilder setHideIfOverlapped:NO];
        [markerStyleBuilder setPlacementPriority:-(int)[elements size]];
        
        markerStyle = [markerStyleBuilder buildStyle];
        [self.markerStyles setValue:markerStyle forKey:styleKey];
    }
    
    NTMarker* marker = [[NTMarker alloc] initWithPos:mapPos style:markerStyle];
    [marker setMetaDataElement:@"elements" element:[[NTVariant alloc] initWithLongVal:[elements size]]];
    
    return marker;
}

@end

{'fraction_non_alphanumeric': 0.09086640056351256, 'fraction_numerical': 0.0036393519605541205, 'mean_word_length': 4.0617944147355916, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6202266', 'n_tokens_mistral': 2370, 'n_tokens_neox': 2273, 'n_words': 498}