summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2018-07-03 03:19:30 -0700
committerMinh Nguyễn <mxn@1ec5.org>2018-07-10 10:17:56 -0700
commita93dca349d4768e0a6a763332e636e389e2b9f2d (patch)
tree438bc2a99b3b586174ff0b17cec18563fb8aa696
parent192c61146847eda5b62cf78b0987aeb59a17ef0b (diff)
downloadqtlocation-mapboxgl-a93dca349d4768e0a6a763332e636e389e2b9f2d.tar.gz
[macos] Import GeoJSON
Added an Import command to the File menu for adding the contents of a GeoJSON file to the map. simplestyle-spec formatting is applied to layers via a handful of expressions. Dropped pins include any details provided through simplestyle-spec properties.
-rw-r--r--platform/macos/app/Base.lproj/MainMenu.xib32
-rw-r--r--platform/macos/app/DroppedPinAnnotation.h5
-rw-r--r--platform/macos/app/DroppedPinAnnotation.m9
-rw-r--r--platform/macos/app/MapDocument.m80
4 files changed, 111 insertions, 15 deletions
diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib
index 8f0aeaf69c..6f8f24ce99 100644
--- a/platform/macos/app/Base.lproj/MainMenu.xib
+++ b/platform/macos/app/Base.lproj/MainMenu.xib
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14269.14" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
- <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14269.14"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -129,6 +129,14 @@
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
</connections>
</menuItem>
+ <menuItem isSeparatorItem="YES" id="VwR-Dd-ah9"/>
+ <menuItem title="Import…" id="DJk-k8-14Y">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="import:" target="-1" id="1Qm-l8-9Rn"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="w4w-CJ-fv2"/>
<menuItem title="Export Image…" id="vjX-0E-kLO">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
@@ -666,7 +674,7 @@ CA
</menuItem>
</items>
</menu>
- <window title="Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="Preferences" animationBehavior="default" id="UWc-yQ-qda">
+ <window title="Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Preferences" animationBehavior="default" id="UWc-yQ-qda">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="109" y="131" width="350" height="84"/>
@@ -690,7 +698,7 @@ CA
<rect key="frame" x="113" y="42" width="197" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="jlV-TC-NUv">
<font key="font" metaFont="system"/>
- <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -742,7 +750,7 @@ CA
<point key="canvasLocation" x="754" y="221"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="45S-yT-WUN"/>
- <window title="Offline Packs" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="MBXOfflinePacksPanel" animationBehavior="default" id="Jjv-gs-Tx6" customClass="NSPanel">
+ <window title="Offline Packs" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="MBXOfflinePacksPanel" animationBehavior="default" id="Jjv-gs-Tx6" customClass="NSPanel">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" utility="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="830" y="430" width="400" height="300"/>
@@ -764,7 +772,7 @@ CA
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
- <tableColumn identifier="" editable="NO" width="16" minWidth="10" maxWidth="3.4028234663852886e+38" id="xtw-hQ-8C5" userLabel="State">
+ <tableColumn editable="NO" width="16" minWidth="10" maxWidth="3.4028234663852886e+38" id="xtw-hQ-8C5" userLabel="State">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -776,7 +784,7 @@ CA
<binding destination="dWe-R6-sRz" name="value" keyPath="arrangedObjects.stateImage" id="2wd-1J-TZt"/>
</connections>
</tableColumn>
- <tableColumn identifier="" editable="NO" width="116" minWidth="40" maxWidth="1000" id="2hD-LN-h0L">
+ <tableColumn editable="NO" width="116" minWidth="40" maxWidth="1000" id="2hD-LN-h0L">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Name">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -796,7 +804,7 @@ CA
</binding>
</connections>
</tableColumn>
- <tableColumn identifier="" editable="NO" width="50" minWidth="40" maxWidth="1000" id="pkI-c7-xoD">
+ <tableColumn editable="NO" width="50" minWidth="40" maxWidth="1000" id="pkI-c7-xoD">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Downloaded Resources">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -813,7 +821,7 @@ CA
<binding destination="dWe-R6-sRz" name="value" keyPath="arrangedObjects.countOfResourcesCompleted" id="mu6-Jg-GiU"/>
</connections>
</tableColumn>
- <tableColumn identifier="" editable="NO" width="50" minWidth="10" maxWidth="3.4028234663852886e+38" id="Rrd-A9-jqc">
+ <tableColumn editable="NO" width="50" minWidth="10" maxWidth="3.4028234663852886e+38" id="Rrd-A9-jqc">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Total Resources">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -830,7 +838,7 @@ CA
<binding destination="dWe-R6-sRz" name="value" keyPath="arrangedObjects.countOfResourcesExpected" id="mh2-k0-vvB"/>
</connections>
</tableColumn>
- <tableColumn identifier="" editable="NO" width="50" minWidth="40" maxWidth="1000" id="kCO-Cd-bQt">
+ <tableColumn editable="NO" width="50" minWidth="40" maxWidth="1000" id="kCO-Cd-bQt">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Downloaded Tiles">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -851,7 +859,7 @@ CA
</binding>
</connections>
</tableColumn>
- <tableColumn identifier="" editable="NO" width="60" minWidth="10" maxWidth="3.4028234663852886e+38" id="WO5-Ci-HgG">
+ <tableColumn editable="NO" width="60" minWidth="10" maxWidth="3.4028234663852886e+38" id="WO5-Ci-HgG">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Downloaded Tiles Size">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -872,7 +880,7 @@ CA
</binding>
</connections>
</tableColumn>
- <tableColumn identifier="" editable="NO" width="60" minWidth="10" maxWidth="3.4028234663852886e+38" id="h7m-6l-KaS">
+ <tableColumn editable="NO" width="60" minWidth="10" maxWidth="3.4028234663852886e+38" id="h7m-6l-KaS">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Downloaded Resources Size">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
diff --git a/platform/macos/app/DroppedPinAnnotation.h b/platform/macos/app/DroppedPinAnnotation.h
index 435a56738b..0897219b13 100644
--- a/platform/macos/app/DroppedPinAnnotation.h
+++ b/platform/macos/app/DroppedPinAnnotation.h
@@ -1,10 +1,15 @@
#import <Mapbox/Mapbox.h>
+NS_ASSUME_NONNULL_BEGIN
+
@interface DroppedPinAnnotation : MGLPointAnnotation
+@property (nonatomic, copy, nullable) NSString *note;
@property (nonatomic, readonly) NSTimeInterval elapsedShownTime;
- (void)resume;
- (void)pause;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/macos/app/DroppedPinAnnotation.m b/platform/macos/app/DroppedPinAnnotation.m
index d7bd4068dc..b601405095 100644
--- a/platform/macos/app/DroppedPinAnnotation.m
+++ b/platform/macos/app/DroppedPinAnnotation.m
@@ -61,8 +61,13 @@ static MGLCoordinateFormatter *DroppedPinCoordinateFormatter;
- (void)update:(NSTimer *)timer {
NSString *coordinate = [DroppedPinCoordinateFormatter stringFromCoordinate:self.coordinate];
- NSString *elapsedTime = [_timeIntervalTransformer transformedValue:@(self.elapsedShownTime)];
- self.subtitle = [NSString stringWithFormat:@"%@\nSelected for %@", coordinate, elapsedTime];
+ if (self.note) {
+ self.subtitle = [@[self.note, coordinate] componentsJoinedByString:@"\n"];
+ } else {
+ NSString *elapsedTime = [_timeIntervalTransformer transformedValue:@(self.elapsedShownTime)];
+ NSString *elapsedString = [NSString stringWithFormat:@"Selected for %@", elapsedTime];
+ self.subtitle = [@[coordinate, elapsedString] componentsJoinedByString:@"\n"];
+ }
}
@end
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index 4ee6050565..9ba28f3b37 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -177,6 +177,66 @@ NSArray<id <MGLAnnotation>> *MBXFlattenedShapes(NSArray<id <MGLAnnotation>> *sha
#pragma mark File methods
+- (IBAction)import:(id)sender {
+ NSOpenPanel *panel = [NSOpenPanel openPanel];
+ panel.allowedFileTypes = @[@"public.json", @"json", @"geojson"];
+ panel.allowsMultipleSelection = YES;
+
+ __weak __typeof__(self) weakSelf = self;
+ [panel beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse result) {
+ if (result != NSFileHandlingPanelOKButton) {
+ return;
+ }
+
+ for (NSURL *url in panel.URLs) {
+ [weakSelf importFromURL:url];
+ }
+ }];
+}
+
+/**
+ Adds the contents of the GeoJSON file at the given URL to the map.
+
+ GeoJSON features are styled according to
+ [simplestyle-spec](https://github.com/mapbox/simplestyle-spec/tree/master/1.1.0/).
+ */
+- (void)importFromURL:(NSURL *)url {
+ MGLStyle *style = self.mapView.style;
+ if (!style) {
+ return;
+ }
+
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:[NSUUID UUID].UUIDString URL:url options:nil];
+ [self.mapView.style addSource:source];
+
+ NSString *pointIdentifier = [NSString stringWithFormat:@"%@ marker", source.identifier];
+ MGLSymbolStyleLayer *pointLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:pointIdentifier source:source];
+ pointLayer.iconImageName =
+ [NSExpression expressionWithFormat:@"mgl_join({%K, '-', CAST(TERNARY(%K = 'small', 11, 15), 'NSString')})",
+ @"marker-symbol", @"marker-size"];
+ pointLayer.iconScale = [NSExpression expressionForConstantValue:@1];
+ pointLayer.iconColor = [NSExpression expressionWithFormat:@"CAST(mgl_coalesce({%K, '#7e7e7e'}), 'NSColor')",
+ @"marker-color"];
+ pointLayer.iconAllowsOverlap = [NSExpression expressionForConstantValue:@YES];
+ [style addLayer:pointLayer];
+
+ NSString *fillIdentifier = [NSString stringWithFormat:@"%@ fill", source.identifier];
+ MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:fillIdentifier source:source];
+ fillLayer.predicate = [NSPredicate predicateWithFormat:@"fill != nil OR %K != nil", @"fill-opacity"];
+ fillLayer.fillColor = [NSExpression expressionWithFormat:@"CAST(mgl_coalesce({fill, '#555555'}), 'NSColor')"];
+ fillLayer.fillOpacity = [NSExpression expressionWithFormat:@"mgl_coalesce({%K, 0.5})", @"fill-opacity"];
+ [style addLayer:fillLayer];
+
+ NSString *lineIdentifier = [NSString stringWithFormat:@"%@ stroke", source.identifier];
+ MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:lineIdentifier source:source];
+ lineLayer.lineColor = [NSExpression expressionWithFormat:@"CAST(mgl_coalesce({stroke, '#555555'}), 'NSColor')"];
+ lineLayer.lineOpacity = [NSExpression expressionWithFormat:@"mgl_coalesce({%K, 1.0})", @"stroke-opacity"];
+ lineLayer.lineWidth = [NSExpression expressionWithFormat:@"mgl_coalesce({%K, 2})", @"stroke-width"];
+ lineLayer.lineCap = [NSExpression expressionForConstantValue:@"round"];
+ lineLayer.lineJoin = [NSExpression expressionForConstantValue:@"bevel"];
+ [style addLayer:lineLayer];
+}
+
- (IBAction)takeSnapshot:(id)sender {
MGLMapCamera *camera = self.mapView.camera;
@@ -966,15 +1026,30 @@ NSArray<id <MGLAnnotation>> *MBXFlattenedShapes(NSArray<id <MGLAnnotation>> *sha
- (DroppedPinAnnotation *)pinAtPoint:(NSPoint)point {
NSArray *features = [self.mapView visibleFeaturesAtPoint:point];
NSString *title;
+ NSString *description;
for (id <MGLFeature> feature in features) {
if (!title) {
- title = [feature attributeForKey:@"name_en"] ?: [feature attributeForKey:@"name"];
+ title = [feature attributeForKey:@"title"] ?: [feature attributeForKey:@"name_en"] ?: [feature attributeForKey:@"name"];
+
+ // simplestyle-spec defines a “description” attribute in HTML format.
+ NSString *featureDescription = [feature attributeForKey:@"description"];
+ if (featureDescription) {
+ // Convert HTML to plain text, because the default popover is
+ // bound to an NSString-typed property.
+ NSData *data = [featureDescription dataUsingEncoding:NSUTF8StringEncoding];
+ description = [[NSAttributedString alloc] initWithHTML:data options:@{} documentAttributes:nil].string;
+ }
+
+ if (title) {
+ break;
+ }
}
}
DroppedPinAnnotation *annotation = [[DroppedPinAnnotation alloc] init];
annotation.coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
annotation.title = title ?: @"Dropped Pin";
+ annotation.note = description;
_spellOutNumberFormatter.numberStyle = NSNumberFormatterSpellOutStyle;
if (_showsToolTipsOnDroppedPins) {
NSString *formattedNumber = [_spellOutNumberFormatter stringFromNumber:@(++_droppedPinCounter)];
@@ -1184,6 +1259,9 @@ NSArray<id <MGLAnnotation>> *MBXFlattenedShapes(NSArray<id <MGLAnnotation>> *sha
if (menuItem.action == @selector(giveFeedback:)) {
return YES;
}
+ if (menuItem.action == @selector(import:)) {
+ return YES;
+ }
if (menuItem.action == @selector(takeSnapshot:)) {
return !(_snapshotter && [_snapshotter isLoading]);
}