[ios,macos] Add MGLComputedShapeSource example to demo apps
This commit is contained in:
committed by
Asheem Mamoowala
parent
246417ef24
commit
7c6ede6bb3
@@ -75,6 +75,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
|
||||
MBXSettingsRuntimeStylingImageSource,
|
||||
MBXSettingsRuntimeStylingRouteLine,
|
||||
MBXSettingsRuntimeStylingDDSPolygon,
|
||||
MBXSettingsRuntimeStylingCustomLatLonGrid,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
|
||||
@@ -111,7 +112,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
|
||||
|
||||
@interface MBXViewController () <UITableViewDelegate,
|
||||
UITableViewDataSource,
|
||||
MGLMapViewDelegate>
|
||||
MGLMapViewDelegate,
|
||||
MGLComputedShapeSourceDataSource>
|
||||
|
||||
|
||||
@property (nonatomic) IBOutlet MGLMapView *mapView;
|
||||
@@ -353,6 +355,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
|
||||
@"Style Image Source",
|
||||
@"Add Route Line",
|
||||
@"Dynamically Style Polygon",
|
||||
@"Add Custom Lat/Lon Grid",
|
||||
]];
|
||||
break;
|
||||
case MBXSettingsMiscellaneous:
|
||||
@@ -529,6 +532,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
|
||||
case MBXSettingsRuntimeStylingDDSPolygon:
|
||||
[self stylePolygonWithDDS];
|
||||
break;
|
||||
case MBXSettingsRuntimeStylingCustomLatLonGrid:
|
||||
[self addLatLonGrid];
|
||||
break;
|
||||
default:
|
||||
NSAssert(NO, @"All runtime styling setting rows should be implemented");
|
||||
break;
|
||||
@@ -1445,6 +1451,54 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
|
||||
[self.mapView.style addLayer:fillStyleLayer];
|
||||
}
|
||||
|
||||
- (void)addLatLonGrid
|
||||
{
|
||||
MGLComputedShapeSource *source = [[MGLComputedShapeSource alloc] initWithIdentifier:@"latlon"
|
||||
options:@{MGLShapeSourceOptionMaximumZoomLevel:@14}];
|
||||
source.dataSource = self;
|
||||
[self.mapView.style addSource:source];
|
||||
MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"latlonlines"
|
||||
source:source];
|
||||
[self.mapView.style addLayer:lineLayer];
|
||||
MGLSymbolStyleLayer *labelLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"latlonlabels"
|
||||
source:source];
|
||||
labelLayer.text = [MGLStyleValue valueWithRawValue:@"{value}"];
|
||||
[self.mapView.style addLayer:labelLayer];
|
||||
}
|
||||
|
||||
- (void)styleLabelLanguageForLayersNamed:(NSArray<NSString *> *)layers
|
||||
{
|
||||
_usingLocaleBasedCountryLabels = !_usingLocaleBasedCountryLabels;
|
||||
NSString *bestLanguageForUser = [NSString stringWithFormat:@"{name_%@}", [self bestLanguageForUser]];
|
||||
NSString *language = _usingLocaleBasedCountryLabels ? bestLanguageForUser : @"{name}";
|
||||
|
||||
for (NSString *layerName in layers) {
|
||||
MGLSymbolStyleLayer *layer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:layerName];
|
||||
|
||||
if ([layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
|
||||
if ([layer.text isKindOfClass:[MGLStyleConstantValue class]]) {
|
||||
MGLStyleConstantValue *label = (MGLStyleConstantValue<NSString *> *)layer.text;
|
||||
if ([label.rawValue hasPrefix:@"{name"]) {
|
||||
layer.text = [MGLStyleValue valueWithRawValue:language];
|
||||
}
|
||||
}
|
||||
else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) {
|
||||
MGLCameraStyleFunction *function = (MGLCameraStyleFunction<NSString *> *)layer.text;
|
||||
NSMutableDictionary *stops = function.stops.mutableCopy;
|
||||
[stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLStyleConstantValue<NSString *> *stop, BOOL *done) {
|
||||
if ([stop.rawValue hasPrefix:@"{name"]) {
|
||||
stops[zoomLevel] = [MGLStyleValue<NSString *> valueWithRawValue:language];
|
||||
}
|
||||
}];
|
||||
function.stops = stops;
|
||||
layer.text = function;
|
||||
}
|
||||
} else {
|
||||
NSLog(@"%@ is not a symbol style layer", layerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)bestLanguageForUser
|
||||
{
|
||||
// https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview
|
||||
@@ -1910,4 +1964,52 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
|
||||
[self.hudLabel setTitle:hudString forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
#pragma mark - MGLComputedShapeSourceDataSource
|
||||
|
||||
- (NSArray<id <MGLFeature>>*)featuresInCoordinateBounds:(MGLCoordinateBounds)bounds zoomLevel:(NSUInteger)zoom {
|
||||
double gridSpacing;
|
||||
if(zoom >= 13) {
|
||||
gridSpacing = 0.01;
|
||||
} else if(zoom >= 11) {
|
||||
gridSpacing = 0.05;
|
||||
} else if(zoom == 10) {
|
||||
gridSpacing = .1;
|
||||
} else if(zoom == 9) {
|
||||
gridSpacing = 0.25;
|
||||
} else if(zoom == 8) {
|
||||
gridSpacing = 0.5;
|
||||
} else if (zoom >= 6) {
|
||||
gridSpacing = 1;
|
||||
} else if(zoom == 5) {
|
||||
gridSpacing = 2;
|
||||
} else if(zoom >= 4) {
|
||||
gridSpacing = 5;
|
||||
} else if(zoom == 2) {
|
||||
gridSpacing = 10;
|
||||
} else {
|
||||
gridSpacing = 20;
|
||||
}
|
||||
|
||||
NSMutableArray <id <MGLFeature>> * features = [NSMutableArray array];
|
||||
CLLocationCoordinate2D coords[2];
|
||||
|
||||
for (double y = ceil(bounds.ne.latitude / gridSpacing) * gridSpacing; y >= floor(bounds.sw.latitude / gridSpacing) * gridSpacing; y -= gridSpacing) {
|
||||
coords[0] = CLLocationCoordinate2DMake(y, bounds.sw.longitude);
|
||||
coords[1] = CLLocationCoordinate2DMake(y, bounds.ne.longitude);
|
||||
MGLPolylineFeature *feature = [MGLPolylineFeature polylineWithCoordinates:coords count:2];
|
||||
feature.attributes = @{@"value": @(y)};
|
||||
[features addObject:feature];
|
||||
}
|
||||
|
||||
for (double x = floor(bounds.sw.longitude / gridSpacing) * gridSpacing; x <= ceil(bounds.ne.longitude / gridSpacing) * gridSpacing; x += gridSpacing) {
|
||||
coords[0] = CLLocationCoordinate2DMake(bounds.sw.latitude, x);
|
||||
coords[1] = CLLocationCoordinate2DMake(bounds.ne.latitude, x);
|
||||
MGLPolylineFeature *feature = [MGLPolylineFeature polylineWithCoordinates:coords count:2];
|
||||
feature.attributes = @{@"value": @(x)};
|
||||
[features addObject:feature];
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -564,6 +564,12 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="addAnimatedImageSource:" target="-1" id="TuN-Pa-hTG"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Add Graticule" id="Msk-p2-Lwt">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="insertGraticuleLayer:" target="-1" id="LE5-lz-kx4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All Annnotations" keyEquivalent="A" id="yMj-uM-8SN">
|
||||
@@ -574,8 +580,8 @@
|
||||
</menuItem>
|
||||
<menuItem title="Remove All Annotations" id="6rC-68-vk0">
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
CA
|
||||
</string>
|
||||
CA
|
||||
</string>
|
||||
<connections>
|
||||
<action selector="removeAllAnnotations:" target="-1" id="6v3-0E-LsR"/>
|
||||
</connections>
|
||||
|
||||
@@ -50,7 +50,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
|
||||
return flattenedShapes;
|
||||
}
|
||||
|
||||
@interface MapDocument () <NSWindowDelegate, NSSharingServicePickerDelegate, NSMenuDelegate, NSSplitViewDelegate, MGLMapViewDelegate>
|
||||
@interface MapDocument () <NSWindowDelegate, NSSharingServicePickerDelegate, NSMenuDelegate, NSSplitViewDelegate, MGLMapViewDelegate, MGLComputedShapeSourceDataSource>
|
||||
|
||||
@property (weak) IBOutlet NSArrayController *styleLayersArrayController;
|
||||
@property (weak) IBOutlet NSTableView *styleLayersTableView;
|
||||
@@ -698,6 +698,47 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
|
||||
[self.mapView.style removeLayer:layer];
|
||||
}
|
||||
|
||||
- (IBAction)insertGraticuleLayer:(id)sender {
|
||||
[self.undoManager registerUndoWithTarget:self handler:^(id _Nonnull target) {
|
||||
[self removeGraticuleLayer:sender];
|
||||
}];
|
||||
|
||||
if (!self.undoManager.isUndoing) {
|
||||
[self.undoManager setActionName:@"Add Graticule"];
|
||||
}
|
||||
|
||||
MGLComputedShapeSource *source = [[MGLComputedShapeSource alloc] initWithIdentifier:@"graticule"
|
||||
options:@{MGLShapeSourceOptionMaximumZoomLevel:@14}];
|
||||
source.dataSource = self;
|
||||
[self.mapView.style addSource:source];
|
||||
MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"graticule.lines"
|
||||
source:source];
|
||||
[self.mapView.style addLayer:lineLayer];
|
||||
MGLSymbolStyleLayer *labelLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"graticule.labels"
|
||||
source:source];
|
||||
labelLayer.text = [MGLStyleValue valueWithRawValue:@"{value}"];
|
||||
[self.mapView.style addLayer:labelLayer];
|
||||
}
|
||||
|
||||
- (IBAction)removeGraticuleLayer:(id)sender {
|
||||
[self.undoManager registerUndoWithTarget:self handler:^(id _Nonnull target) {
|
||||
[self insertGraticuleLayer:sender];
|
||||
}];
|
||||
|
||||
if (!self.undoManager.isUndoing) {
|
||||
[self.undoManager setActionName:@"Delete Graticule"];
|
||||
}
|
||||
|
||||
MGLStyleLayer *layer = [self.mapView.style layerWithIdentifier:@"graticule.lines"];
|
||||
[self.mapView.style removeLayer:layer];
|
||||
|
||||
layer = [self.mapView.style layerWithIdentifier:@"graticule.labels"];
|
||||
[self.mapView.style removeLayer:layer];
|
||||
|
||||
MGLSource *source = [self.mapView.style sourceWithIdentifier:@"graticule"];
|
||||
[self.mapView.style removeSource:source];
|
||||
}
|
||||
|
||||
#pragma mark Offline packs
|
||||
|
||||
- (IBAction)addOfflinePack:(id)sender {
|
||||
@@ -1011,6 +1052,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
|
||||
if (menuItem.action == @selector(insertCustomStyleLayer:)) {
|
||||
return ![self.mapView.style layerWithIdentifier:@"mbx-custom"];
|
||||
}
|
||||
if (menuItem.action == @selector(insertGraticuleLayer:)) {
|
||||
return ![self.mapView.style sourceWithIdentifier:@"graticule"];
|
||||
}
|
||||
if (menuItem.action == @selector(showAllAnnotations:) || menuItem.action == @selector(removeAllAnnotations:)) {
|
||||
return self.mapView.annotations.count > 0;
|
||||
}
|
||||
@@ -1185,6 +1229,53 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
|
||||
return 0.8;
|
||||
}
|
||||
|
||||
#pragma mark - MGLComputedShapeSourceDataSource
|
||||
- (NSArray<id <MGLFeature>>*)featuresInCoordinateBounds:(MGLCoordinateBounds)bounds zoomLevel:(NSUInteger)zoom {
|
||||
double gridSpacing;
|
||||
if(zoom >= 13) {
|
||||
gridSpacing = 0.01;
|
||||
} else if(zoom >= 11) {
|
||||
gridSpacing = 0.05;
|
||||
} else if(zoom == 10) {
|
||||
gridSpacing = .1;
|
||||
} else if(zoom == 9) {
|
||||
gridSpacing = 0.25;
|
||||
} else if(zoom == 8) {
|
||||
gridSpacing = 0.5;
|
||||
} else if (zoom >= 6) {
|
||||
gridSpacing = 1;
|
||||
} else if(zoom == 5) {
|
||||
gridSpacing = 2;
|
||||
} else if(zoom >= 4) {
|
||||
gridSpacing = 5;
|
||||
} else if(zoom == 2) {
|
||||
gridSpacing = 10;
|
||||
} else {
|
||||
gridSpacing = 20;
|
||||
}
|
||||
|
||||
NSMutableArray <id <MGLFeature>> * features = [NSMutableArray array];
|
||||
CLLocationCoordinate2D coords[2];
|
||||
|
||||
for (double y = ceil(bounds.ne.latitude / gridSpacing) * gridSpacing; y >= floor(bounds.sw.latitude / gridSpacing) * gridSpacing; y -= gridSpacing) {
|
||||
coords[0] = CLLocationCoordinate2DMake(y, bounds.sw.longitude);
|
||||
coords[1] = CLLocationCoordinate2DMake(y, bounds.ne.longitude);
|
||||
MGLPolylineFeature *feature = [MGLPolylineFeature polylineWithCoordinates:coords count:2];
|
||||
feature.attributes = @{@"value": @(y)};
|
||||
[features addObject:feature];
|
||||
}
|
||||
|
||||
for (double x = floor(bounds.sw.longitude / gridSpacing) * gridSpacing; x <= ceil(bounds.ne.longitude / gridSpacing) * gridSpacing; x += gridSpacing) {
|
||||
coords[0] = CLLocationCoordinate2DMake(bounds.sw.latitude, x);
|
||||
coords[1] = CLLocationCoordinate2DMake(bounds.ne.latitude, x);
|
||||
MGLPolylineFeature *feature = [MGLPolylineFeature polylineWithCoordinates:coords count:2];
|
||||
feature.attributes = @{@"value": @(x)};
|
||||
[features addObject:feature];
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface ValidatedToolbarItem : NSToolbarItem
|
||||
|
||||
Reference in New Issue
Block a user