summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjmkiley <jordan.kiley@mapbox.com>2017-06-13 15:21:50 -0700
committerjmkiley <jordan.kiley@mapbox.com>2017-06-13 15:21:50 -0700
commit04a0c64482c045bd622a8d1c4ad6ca1baace2c34 (patch)
tree9c978aa3e4850f71fa26fb033f2cb3c81c58b555
parent17ccd0100ceff3ab7d4dd6eb58e3345745dff117 (diff)
downloadqtlocation-mapboxgl-upstream/jk-nb-pod-try.tar.gz
[ios] added demo projectupstream/jk-nb-pod-try
-rw-r--r--platform/ios/demo/.github/ISSUE_TEMPLATE.md7
-rw-r--r--platform/ios/demo/.gitignore7
-rw-r--r--platform/ios/demo/Examples.xcodeproj/project.pbxproj1220
-rw-r--r--platform/ios/demo/Examples.xcodeproj/xcshareddata/xcschemes/Examples.xcscheme116
-rw-r--r--platform/ios/demo/Examples/AppDelegate.h16
-rw-r--r--platform/ios/demo/Examples/AppDelegate.m25
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Contents.json191
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.pngbin0 -> 1185 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.pngbin0 -> 1382 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76.pngbin0 -> 809 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.pngbin0 -> 1373 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small-1.pngbin0 -> 380 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small.pngbin0 -> 380 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.pngbin0 -> 663 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-2.pngbin0 -> 663 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.pngbin0 -> 663 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x-1.pngbin0 -> 782 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.pngbin0 -> 782 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.pngbin0 -> 459 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.pngbin0 -> 848 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.pngbin0 -> 848 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.pngbin0 -> 1018 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.pngbin0 -> 1893 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/Contents.json6
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Contents.json23
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube.pngbin0 -> 663 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@2x.pngbin0 -> 1363 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@3x.pngbin0 -> 2268 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/Contents.json21
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/attraction.pngbin0 -> 1567 bytes
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/Contents.json21
-rw-r--r--platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/lighthouse.pngbin0 -> 1465 bytes
-rw-r--r--platform/ios/demo/Examples/Base.lproj/LaunchScreen.storyboard39
-rw-r--r--platform/ios/demo/Examples/Examples-Bridging-Header.h4
-rw-r--r--platform/ios/demo/Examples/Examples.h57
-rw-r--r--platform/ios/demo/Examples/Examples.m64
-rw-r--r--platform/ios/demo/Examples/ExamplesContainerViewController.h15
-rw-r--r--platform/ios/demo/Examples/ExamplesContainerViewController.m41
-rw-r--r--platform/ios/demo/Examples/ExamplesTableViewController.h13
-rw-r--r--platform/ios/demo/Examples/ExamplesTableViewController.m76
-rw-r--r--platform/ios/demo/Examples/Files/camera.xcassets/Contents.json6
-rw-r--r--platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/Contents.json21
-rw-r--r--platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/camera.pdfbin0 -> 4228 bytes
-rw-r--r--platform/ios/demo/Examples/Files/clustering.xcassets/Contents.json6
-rw-r--r--platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/Contents.json23
-rw-r--r--platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port.pngbin0 -> 1783 bytes
-rw-r--r--platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@2x.pngbin0 -> 3971 bytes
-rw-r--r--platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@3x.pngbin0 -> 8830 bytes
-rw-r--r--platform/ios/demo/Examples/Files/example.geojson308
-rw-r--r--platform/ios/demo/Examples/Files/metro-line.geojson4370
-rw-r--r--platform/ios/demo/Examples/Files/pisavector.xcassets/Contents.json6
-rw-r--r--platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/Contents.json12
-rw-r--r--platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/pisa.pdfbin0 -> 7636 bytes
-rw-r--r--platform/ios/demo/Examples/Files/ports.geojson18382
-rw-r--r--platform/ios/demo/Examples/Files/third_party_vector_style.json25
-rw-r--r--platform/ios/demo/Examples/Info.plist49
-rw-r--r--platform/ios/demo/Examples/Main.storyboard117
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.m109
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.m119
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.m64
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.m84
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.m40
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.h14
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.m39
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/ClusteringExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/ClusteringExample.m143
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.m122
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModels.h29
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.h14
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.m158
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.m63
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.m20
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.m27
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.m66
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.m97
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.m27
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.m143
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.m67
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.m80
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.m48
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.m77
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.m56
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.m113
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/PointConversionExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/PointConversionExample.m64
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.m94
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.m181
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.m77
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.m216
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.m92
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.m28
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.m71
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.m68
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.m23
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.m58
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.m24
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.h13
-rw-r--r--platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.m25
-rw-r--r--platform/ios/demo/Examples/Swift/AnnotationViewExample.swift95
-rw-r--r--platform/ios/demo/Examples/Swift/AnnotationViewMultipleExample.swift105
-rw-r--r--platform/ios/demo/Examples/Swift/BlockingGesturesDelegateExample.swift60
-rw-r--r--platform/ios/demo/Examples/Swift/CalloutDelegateUsageExample.swift69
-rw-r--r--platform/ios/demo/Examples/Swift/CameraAnimationExample.swift34
-rw-r--r--platform/ios/demo/Examples/Swift/CameraFlyToExample.swift40
-rw-r--r--platform/ios/demo/Examples/Swift/ClusteringExample.swift134
-rw-r--r--platform/ios/demo/Examples/Swift/CustomAnnotationModelExample.swift114
-rw-r--r--platform/ios/demo/Examples/Swift/CustomAnnotationModels.swift28
-rw-r--r--platform/ios/demo/Examples/Swift/CustomCalloutView.swift127
-rw-r--r--platform/ios/demo/Examples/Swift/CustomCalloutViewExample.swift51
-rw-r--r--platform/ios/demo/Examples/Swift/CustomRasterStyleExample.swift17
-rw-r--r--platform/ios/demo/Examples/Swift/CustomStyleExample.swift22
-rw-r--r--platform/ios/demo/Examples/Swift/DDSCircleLayerExample.swift59
-rw-r--r--platform/ios/demo/Examples/Swift/DDSLayerSelectionExample.swift77
-rw-r--r--platform/ios/demo/Examples/Swift/DefaultStylesExample.swift23
-rw-r--r--platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift127
-rw-r--r--platform/ios/demo/Examples/Swift/DrawingACustomMarkerExample.swift59
-rw-r--r--platform/ios/demo/Examples/Swift/DrawingAGeoJSONLineExample.swift79
-rw-r--r--platform/ios/demo/Examples/Swift/DrawingAMarkerExample.swift38
-rw-r--r--platform/ios/demo/Examples/Swift/DrawingAPolygonExample.swift59
-rw-r--r--platform/ios/demo/Examples/Swift/ExtrusionsExample.swift53
-rw-r--r--platform/ios/demo/Examples/Swift/OfflinePackExample.swift113
-rw-r--r--platform/ios/demo/Examples/Swift/PointConversionExample.swift50
-rw-r--r--platform/ios/demo/Examples/Swift/RuntimeAddLineExample.swift90
-rw-r--r--platform/ios/demo/Examples/Swift/RuntimeAnimateLineExample.swift162
-rw-r--r--platform/ios/demo/Examples/Swift/RuntimeCircleStylesExample.swift69
-rw-r--r--platform/ios/demo/Examples/Swift/RuntimeMultipleAnnotationsExample.swift207
-rw-r--r--platform/ios/demo/Examples/Swift/RuntimeToggleLayerExample.swift80
-rw-r--r--platform/ios/demo/Examples/Swift/SatelliteStyleExample.swift25
-rw-r--r--platform/ios/demo/Examples/Swift/SelectFeatureExample.swift64
-rw-r--r--platform/ios/demo/Examples/Swift/ShapeCollectionFeatureExample.swift69
-rw-r--r--platform/ios/demo/Examples/Swift/SimpleMapViewExample.swift16
-rw-r--r--platform/ios/demo/Examples/Swift/SourceCustomRasterExample.swift50
-rw-r--r--platform/ios/demo/Examples/Swift/SourceCustomVectorExample.swift24
-rw-r--r--platform/ios/demo/Examples/Swift/UserTrackingModesExample.swift141
-rwxr-xr-xplatform/ios/demo/Examples/insert-mapbox-token.sh14
-rw-r--r--platform/ios/demo/Examples/main.m16
-rw-r--r--platform/ios/demo/ExamplesTests/ExamplesTests.m38
-rw-r--r--platform/ios/demo/ExamplesTests/Info.plist24
-rw-r--r--platform/ios/demo/ExamplesUITests/ExamplesUITests.m45
-rw-r--r--platform/ios/demo/ExamplesUITests/Info.plist24
-rw-r--r--platform/ios/demo/Files/AppIcon.sketchbin0 -> 40960 bytes
-rw-r--r--platform/ios/demo/Files/Icon-128.pngbin0 -> 700 bytes
-rw-r--r--platform/ios/demo/Files/Icon-48.pngbin0 -> 363 bytes
-rw-r--r--platform/ios/demo/Files/iTunesArtwork.pngbin0 -> 13786 bytes
-rw-r--r--platform/ios/demo/LICENSE.md5
-rw-r--r--platform/ios/demo/Podfile16
-rw-r--r--platform/ios/demo/Podfile.lock16
-rw-r--r--platform/ios/demo/README.md18
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj2
-rwxr-xr-xplatform/ios/scripts/publish.sh24
180 files changed, 31415 insertions, 13 deletions
diff --git a/platform/ios/demo/.github/ISSUE_TEMPLATE.md b/platform/ios/demo/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000000..e75d3ddf06
--- /dev/null
+++ b/platform/ios/demo/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,7 @@
+<!--
+Hello and thanks for contributing!
+
+We are not able to answer support questions in this repository — we use these issues to plan new examples and improve existing examples.
+
+If you have a question about how to use the Mapbox iOS SDK, see: https://github.com/mapbox/ios-sdk-examples/#how-to-receive-help
+--> \ No newline at end of file
diff --git a/platform/ios/demo/.gitignore b/platform/ios/demo/.gitignore
new file mode 100644
index 0000000000..0ec84717ce
--- /dev/null
+++ b/platform/ios/demo/.gitignore
@@ -0,0 +1,7 @@
+# Ignore the file containing your Mapbox access token, to keep it out of public repos.
+mapbox_access_token
+
+xcuserdata
+DerivedData/
+Pods
+*.xcworkspace
diff --git a/platform/ios/demo/Examples.xcodeproj/project.pbxproj b/platform/ios/demo/Examples.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..3f1d3ca72a
--- /dev/null
+++ b/platform/ios/demo/Examples.xcodeproj/project.pbxproj
@@ -0,0 +1,1220 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 079E77C51E1C4E2100F92FA8 /* camera.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 079E77C41E1C4E2100F92FA8 /* camera.xcassets */; };
+ 07C138C01E6F646F00D6F678 /* ShapeCollectionFeatureExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 07C138BF1E6F646F00D6F678 /* ShapeCollectionFeatureExample.m */; };
+ 07C138C21E6F65D000D6F678 /* ShapeCollectionFeatureExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C138C11E6F65D000D6F678 /* ShapeCollectionFeatureExample.swift */; };
+ 07C138C41E721C8F00D6F678 /* DDSCircleLayerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C138C31E721C8F00D6F678 /* DDSCircleLayerExample.swift */; };
+ 07C138C71E72216E00D6F678 /* DDSCircleLayerExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 07C138C61E72216E00D6F678 /* DDSCircleLayerExample.m */; };
+ 07F53B851E00D02100B58DB3 /* AnnotationViewMultipleExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 07F53B841E00D02100B58DB3 /* AnnotationViewMultipleExample.m */; };
+ 1F1F84751E538ABB00332CC3 /* BlockingGesturesDelegateExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F1F84741E538ABB00332CC3 /* BlockingGesturesDelegateExample.m */; };
+ 1F1F84771E53A3B700332CC3 /* BlockingGesturesDelegateExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1F84761E53A3B700332CC3 /* BlockingGesturesDelegateExample.swift */; };
+ 3E085B801EC526C500163C99 /* ExtrusionsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E085B7F1EC526C500163C99 /* ExtrusionsExample.swift */; };
+ 3E085B831EC526E500163C99 /* ExtrusionsExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E085B821EC526E500163C99 /* ExtrusionsExample.m */; };
+ 3E3BFAD91E81D7A300D0BEA1 /* DDSLayerSelectionExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E3BFAD81E81D7A300D0BEA1 /* DDSLayerSelectionExample.swift */; };
+ 3E3BFADC1E81D7BB00D0BEA1 /* DDSLayerSelectionExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E3BFADB1E81D7BB00D0BEA1 /* DDSLayerSelectionExample.m */; };
+ 3EBCD7161DC28240001E342F /* AnnotationViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7021DC28240001E342F /* AnnotationViewExample.swift */; };
+ 3EBCD7171DC28240001E342F /* CalloutDelegateUsageExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7031DC28240001E342F /* CalloutDelegateUsageExample.swift */; };
+ 3EBCD7181DC28240001E342F /* CameraAnimationExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7041DC28240001E342F /* CameraAnimationExample.swift */; };
+ 3EBCD7191DC28240001E342F /* CustomAnnotationModelExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7051DC28240001E342F /* CustomAnnotationModelExample.swift */; };
+ 3EBCD71A1DC28240001E342F /* CustomAnnotationModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7061DC28240001E342F /* CustomAnnotationModels.swift */; };
+ 3EBCD71B1DC28240001E342F /* CustomCalloutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7071DC28240001E342F /* CustomCalloutView.swift */; };
+ 3EBCD71C1DC28240001E342F /* CustomCalloutViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7081DC28240001E342F /* CustomCalloutViewExample.swift */; };
+ 3EBCD71D1DC28240001E342F /* CustomRasterStyleExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7091DC28240001E342F /* CustomRasterStyleExample.swift */; };
+ 3EBCD71E1DC28240001E342F /* CustomStyleExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD70A1DC28240001E342F /* CustomStyleExample.swift */; };
+ 3EBCD71F1DC28240001E342F /* DefaultStylesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD70B1DC28240001E342F /* DefaultStylesExample.swift */; };
+ 3EBCD7201DC28240001E342F /* DraggableAnnotationViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD70C1DC28240001E342F /* DraggableAnnotationViewExample.swift */; };
+ 3EBCD7211DC28240001E342F /* DrawingACustomMarkerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD70D1DC28240001E342F /* DrawingACustomMarkerExample.swift */; };
+ 3EBCD7221DC28240001E342F /* DrawingAGeoJSONLineExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD70E1DC28240001E342F /* DrawingAGeoJSONLineExample.swift */; };
+ 3EBCD7231DC28240001E342F /* DrawingAMarkerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD70F1DC28240001E342F /* DrawingAMarkerExample.swift */; };
+ 3EBCD7241DC28240001E342F /* DrawingAPolygonExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7101DC28240001E342F /* DrawingAPolygonExample.swift */; };
+ 3EBCD7251DC28240001E342F /* OfflinePackExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7111DC28240001E342F /* OfflinePackExample.swift */; };
+ 3EBCD7261DC28240001E342F /* PointConversionExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7121DC28240001E342F /* PointConversionExample.swift */; };
+ 3EBCD7271DC28240001E342F /* SatelliteStyleExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7131DC28240001E342F /* SatelliteStyleExample.swift */; };
+ 3EBCD7281DC28240001E342F /* SimpleMapViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7141DC28240001E342F /* SimpleMapViewExample.swift */; };
+ 3EBCD7291DC28240001E342F /* UserTrackingModesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBCD7151DC28240001E342F /* UserTrackingModesExample.swift */; };
+ 3EC92DB71E78C431001D0503 /* metro-line.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 3EC92DB61E78C431001D0503 /* metro-line.geojson */; };
+ 3ED403411E006B5200230C95 /* CameraFlyToExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ED403401E006B5200230C95 /* CameraFlyToExample.swift */; };
+ 3ED403481E006BE800230C95 /* CameraFlyToExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ED403471E006BE800230C95 /* CameraFlyToExample.m */; };
+ 4F1B1A74F32EB5E8C46C9A12 /* Pods_Examples.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EC12D8F1A97963D68BFA871 /* Pods_Examples.framework */; };
+ 646B62971DEF6DAF000AA523 /* RuntimeToggleLayerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646B62961DEF6DAF000AA523 /* RuntimeToggleLayerExample.swift */; };
+ 646B629C1DEF6DF1000AA523 /* RuntimeToggleLayerExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 646B629B1DEF6DF1000AA523 /* RuntimeToggleLayerExample.m */; };
+ 646B62A41DEF7115000AA523 /* RuntimeAddLineExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 646B62A31DEF7115000AA523 /* RuntimeAddLineExample.m */; };
+ 646B62A61DEF7121000AA523 /* RuntimeAnimateLineExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 646B62A51DEF7121000AA523 /* RuntimeAnimateLineExample.m */; };
+ 646B62AE1DEF7155000AA523 /* RuntimeAddLineExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646B62AD1DEF7155000AA523 /* RuntimeAddLineExample.swift */; };
+ 646B62B01DEF7161000AA523 /* RuntimeAnimateLineExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646B62AF1DEF7161000AA523 /* RuntimeAnimateLineExample.swift */; };
+ 646B62B41DEF9613000AA523 /* RuntimeCircleStylesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646B62B31DEF9613000AA523 /* RuntimeCircleStylesExample.swift */; };
+ 646B62BD1DEF965A000AA523 /* RuntimeCircleStylesExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 646B62BC1DEF965A000AA523 /* RuntimeCircleStylesExample.m */; };
+ 64BBDAF01DF22D9600BB705D /* third_party_vector_style.json in Resources */ = {isa = PBXBuildFile; fileRef = 64BBDAEF1DF22D9600BB705D /* third_party_vector_style.json */; };
+ 64BBDAF61DF232FD00BB705D /* SelectFeatureExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BBDAF51DF232FD00BB705D /* SelectFeatureExample.swift */; };
+ 64BBDAF81DF2330B00BB705D /* SelectFeatureExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 64BBDAF71DF2330B00BB705D /* SelectFeatureExample.m */; };
+ 64BBDAFD1DF24DEB00BB705D /* RuntimeMultipleAnnotationsExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 64BBDAFC1DF24DEB00BB705D /* RuntimeMultipleAnnotationsExample.m */; };
+ 64BBDB031DF24E0900BB705D /* RuntimeMultipleAnnotationsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BBDB021DF24E0900BB705D /* RuntimeMultipleAnnotationsExample.swift */; };
+ 64CF970C1DF224C500C3C27B /* SourceCustomVectorExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 64CF970B1DF224C500C3C27B /* SourceCustomVectorExample.m */; };
+ 64CF97101DF224E400C3C27B /* SourceCustomVectorExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64CF970F1DF224E400C3C27B /* SourceCustomVectorExample.swift */; };
+ 64CF97121DF224F600C3C27B /* SourceCustomRasterExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64CF97111DF224F600C3C27B /* SourceCustomRasterExample.swift */; };
+ 64CF97171DF2251500C3C27B /* SourceCustomRasterExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 64CF97161DF2251500C3C27B /* SourceCustomRasterExample.m */; };
+ 960A21611D344F9F00BB348B /* DraggableAnnotationViewExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 960A21601D344F9F00BB348B /* DraggableAnnotationViewExample.m */; };
+ 96115A681CAD4E1C000963B8 /* OfflinePackExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 96115A671CAD4E1C000963B8 /* OfflinePackExample.m */; };
+ 961962911C581700002D3DAB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 961962901C581700002D3DAB /* main.m */; };
+ 961962941C581700002D3DAB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 961962931C581700002D3DAB /* AppDelegate.m */; };
+ 9619629C1C581700002D3DAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9619629B1C581700002D3DAB /* Assets.xcassets */; };
+ 9619629F1C581700002D3DAB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9619629D1C581700002D3DAB /* LaunchScreen.storyboard */; };
+ 961962AA1C581700002D3DAB /* ExamplesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 961962A91C581700002D3DAB /* ExamplesTests.m */; };
+ 961962B51C581700002D3DAB /* ExamplesUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 961962B41C581700002D3DAB /* ExamplesUITests.m */; };
+ 961962CF1C581FBC002D3DAB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 961962CE1C581FBC002D3DAB /* Main.storyboard */; };
+ 961962D21C5821A9002D3DAB /* ExamplesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 961962D11C5821A9002D3DAB /* ExamplesTableViewController.m */; };
+ 961962D51C583FDC002D3DAB /* ExamplesContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 961962D41C583FDC002D3DAB /* ExamplesContainerViewController.m */; };
+ 962B450F1D1C8520007B7454 /* AnnotationViewExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 962B450E1D1C8520007B7454 /* AnnotationViewExample.m */; };
+ 964CB5111E42A0A3004549EA /* AnnotationViewMultipleExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CB5101E42A0A3004549EA /* AnnotationViewMultipleExample.swift */; };
+ 9678E3EE1CEF58DA00F21AE2 /* CustomAnnotationModelExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 9678E3ED1CEF58DA00F21AE2 /* CustomAnnotationModelExample.m */; };
+ 968247031C5BDCBB00494AB8 /* CustomRasterStyleExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 968247021C5BDCBB00494AB8 /* CustomRasterStyleExample.m */; };
+ 968247081C5BEBDC00494AB8 /* SatelliteStyleExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 968247071C5BEBDC00494AB8 /* SatelliteStyleExample.m */; };
+ 9682470F1C5BF12700494AB8 /* DrawingAMarkerExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 9682470E1C5BF12700494AB8 /* DrawingAMarkerExample.m */; };
+ 968247131C5C0F0F00494AB8 /* CalloutDelegateUsageExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 968247121C5C0F0F00494AB8 /* CalloutDelegateUsageExample.m */; };
+ 9682471A1C5C115000494AB8 /* DrawingAGeoJSONLineExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 968247191C5C115000494AB8 /* DrawingAGeoJSONLineExample.m */; };
+ 9682471D1C5C123B00494AB8 /* example.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 9682471C1C5C123B00494AB8 /* example.geojson */; };
+ 968247201C5C1C0400494AB8 /* DrawingAPolygonExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 9682471F1C5C1C0400494AB8 /* DrawingAPolygonExample.m */; };
+ 968247271C5C1DC700494AB8 /* CameraAnimationExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 968247261C5C1DC700494AB8 /* CameraAnimationExample.m */; };
+ 9682472A1C5C1FF800494AB8 /* PointConversionExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 968247291C5C1FF800494AB8 /* PointConversionExample.m */; };
+ 9691AA941C5AA702006A58C6 /* Examples.m in Sources */ = {isa = PBXBuildFile; fileRef = 9691AA931C5AA702006A58C6 /* Examples.m */; };
+ 9691AAA71C5AAD8F006A58C6 /* CustomStyleExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 9691AAA21C5AAD8F006A58C6 /* CustomStyleExample.m */; };
+ 9691AAA81C5AAD8F006A58C6 /* DefaultStylesExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 9691AAA41C5AAD8F006A58C6 /* DefaultStylesExample.m */; };
+ 9691AAA91C5AAD8F006A58C6 /* SimpleMapViewExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 9691AAA61C5AAD8F006A58C6 /* SimpleMapViewExample.m */; };
+ 969E7FDD1D25C31700663F84 /* UserTrackingModesExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 969E7FDC1D25C31700663F84 /* UserTrackingModesExample.m */; };
+ 96A2A1CF1C8CA16C0059441E /* CustomCalloutViewExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A2A1CE1C8CA16C0059441E /* CustomCalloutViewExample.m */; };
+ 96A2A1D21C8CA74B0059441E /* CustomCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A2A1D11C8CA74B0059441E /* CustomCalloutView.m */; };
+ 96D431FC1C84B4F7007D09D1 /* DrawingACustomMarkerExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 96D431FB1C84B4F7007D09D1 /* DrawingACustomMarkerExample.m */; };
+ 96D432061C84B9CF007D09D1 /* pisavector.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96D432051C84B9CF007D09D1 /* pisavector.xcassets */; };
+ BBD05676206B24335DEA52C4 /* Pods_ExamplesUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7692D1D792EB3849E8754E6B /* Pods_ExamplesUITests.framework */; };
+ DD5939E41E6639BA0009BEB2 /* ClusteringExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5939E31E6639BA0009BEB2 /* ClusteringExample.swift */; };
+ DD5939E61E6778480009BEB2 /* clustering.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DD5939E51E6778480009BEB2 /* clustering.xcassets */; };
+ DDF943291E5DE63300545D0F /* ClusteringExample.m in Sources */ = {isa = PBXBuildFile; fileRef = DDF943281E5DE63300545D0F /* ClusteringExample.m */; };
+ DDF9432B1E5DEACC00545D0F /* ports.geojson in Resources */ = {isa = PBXBuildFile; fileRef = DDF9432A1E5DEACC00545D0F /* ports.geojson */; };
+ F9C1D0F8EE832A1D242930D2 /* Pods_ExamplesTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8EE2FB6BE39BB48832DA94C /* Pods_ExamplesTests.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 961962A61C581700002D3DAB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 961962841C581700002D3DAB /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 9619628B1C581700002D3DAB;
+ remoteInfo = Examples;
+ };
+ 961962B11C581700002D3DAB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 961962841C581700002D3DAB /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 9619628B1C581700002D3DAB;
+ remoteInfo = Examples;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 961962C71C5818EB002D3DAB /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 03CC5D45DBD04AB716469E7B /* Pods-Examples.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Examples.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Examples/Pods-Examples.debug.xcconfig"; sourceTree = "<group>"; };
+ 079E77C41E1C4E2100F92FA8 /* camera.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = camera.xcassets; sourceTree = "<group>"; };
+ 07C138BE1E6F646F00D6F678 /* ShapeCollectionFeatureExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShapeCollectionFeatureExample.h; sourceTree = "<group>"; };
+ 07C138BF1E6F646F00D6F678 /* ShapeCollectionFeatureExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShapeCollectionFeatureExample.m; sourceTree = "<group>"; };
+ 07C138C11E6F65D000D6F678 /* ShapeCollectionFeatureExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShapeCollectionFeatureExample.swift; sourceTree = "<group>"; };
+ 07C138C31E721C8F00D6F678 /* DDSCircleLayerExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DDSCircleLayerExample.swift; sourceTree = "<group>"; };
+ 07C138C51E72216D00D6F678 /* DDSCircleLayerExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDSCircleLayerExample.h; sourceTree = "<group>"; };
+ 07C138C61E72216E00D6F678 /* DDSCircleLayerExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDSCircleLayerExample.m; sourceTree = "<group>"; };
+ 07F53B841E00D02100B58DB3 /* AnnotationViewMultipleExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnnotationViewMultipleExample.m; sourceTree = "<group>"; };
+ 07F53B861E00D08600B58DB3 /* AnnotationViewMultipleExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnnotationViewMultipleExample.h; sourceTree = "<group>"; };
+ 0A4917D6B62E749D739044A4 /* Pods-ExamplesUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamplesUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExamplesUITests/Pods-ExamplesUITests.debug.xcconfig"; sourceTree = "<group>"; };
+ 1F1F84731E538ABB00332CC3 /* BlockingGesturesDelegateExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockingGesturesDelegateExample.h; sourceTree = "<group>"; };
+ 1F1F84741E538ABB00332CC3 /* BlockingGesturesDelegateExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockingGesturesDelegateExample.m; sourceTree = "<group>"; };
+ 1F1F84761E53A3B700332CC3 /* BlockingGesturesDelegateExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockingGesturesDelegateExample.swift; sourceTree = "<group>"; };
+ 29A0D7C8DCD539DCA5DA1BAC /* Pods-Examples.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Examples.release.xcconfig"; path = "Pods/Target Support Files/Pods-Examples/Pods-Examples.release.xcconfig"; sourceTree = "<group>"; };
+ 3E085B7F1EC526C500163C99 /* ExtrusionsExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtrusionsExample.swift; sourceTree = "<group>"; };
+ 3E085B811EC526E500163C99 /* ExtrusionsExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtrusionsExample.h; sourceTree = "<group>"; };
+ 3E085B821EC526E500163C99 /* ExtrusionsExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExtrusionsExample.m; sourceTree = "<group>"; };
+ 3E3BFAD81E81D7A300D0BEA1 /* DDSLayerSelectionExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DDSLayerSelectionExample.swift; sourceTree = "<group>"; };
+ 3E3BFADA1E81D7BB00D0BEA1 /* DDSLayerSelectionExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDSLayerSelectionExample.h; sourceTree = "<group>"; };
+ 3E3BFADB1E81D7BB00D0BEA1 /* DDSLayerSelectionExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDSLayerSelectionExample.m; sourceTree = "<group>"; };
+ 3EBCD7021DC28240001E342F /* AnnotationViewExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnnotationViewExample.swift; sourceTree = "<group>"; };
+ 3EBCD7031DC28240001E342F /* CalloutDelegateUsageExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalloutDelegateUsageExample.swift; sourceTree = "<group>"; };
+ 3EBCD7041DC28240001E342F /* CameraAnimationExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraAnimationExample.swift; sourceTree = "<group>"; };
+ 3EBCD7051DC28240001E342F /* CustomAnnotationModelExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomAnnotationModelExample.swift; sourceTree = "<group>"; };
+ 3EBCD7061DC28240001E342F /* CustomAnnotationModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomAnnotationModels.swift; sourceTree = "<group>"; };
+ 3EBCD7071DC28240001E342F /* CustomCalloutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomCalloutView.swift; sourceTree = "<group>"; };
+ 3EBCD7081DC28240001E342F /* CustomCalloutViewExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomCalloutViewExample.swift; sourceTree = "<group>"; };
+ 3EBCD7091DC28240001E342F /* CustomRasterStyleExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomRasterStyleExample.swift; sourceTree = "<group>"; };
+ 3EBCD70A1DC28240001E342F /* CustomStyleExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomStyleExample.swift; sourceTree = "<group>"; };
+ 3EBCD70B1DC28240001E342F /* DefaultStylesExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultStylesExample.swift; sourceTree = "<group>"; };
+ 3EBCD70C1DC28240001E342F /* DraggableAnnotationViewExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DraggableAnnotationViewExample.swift; sourceTree = "<group>"; };
+ 3EBCD70D1DC28240001E342F /* DrawingACustomMarkerExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DrawingACustomMarkerExample.swift; sourceTree = "<group>"; };
+ 3EBCD70E1DC28240001E342F /* DrawingAGeoJSONLineExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DrawingAGeoJSONLineExample.swift; sourceTree = "<group>"; };
+ 3EBCD70F1DC28240001E342F /* DrawingAMarkerExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DrawingAMarkerExample.swift; sourceTree = "<group>"; };
+ 3EBCD7101DC28240001E342F /* DrawingAPolygonExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DrawingAPolygonExample.swift; sourceTree = "<group>"; };
+ 3EBCD7111DC28240001E342F /* OfflinePackExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OfflinePackExample.swift; sourceTree = "<group>"; };
+ 3EBCD7121DC28240001E342F /* PointConversionExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PointConversionExample.swift; sourceTree = "<group>"; };
+ 3EBCD7131DC28240001E342F /* SatelliteStyleExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SatelliteStyleExample.swift; sourceTree = "<group>"; };
+ 3EBCD7141DC28240001E342F /* SimpleMapViewExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimpleMapViewExample.swift; sourceTree = "<group>"; };
+ 3EBCD7151DC28240001E342F /* UserTrackingModesExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserTrackingModesExample.swift; sourceTree = "<group>"; };
+ 3EC92DB61E78C431001D0503 /* metro-line.geojson */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "metro-line.geojson"; sourceTree = "<group>"; };
+ 3ED403401E006B5200230C95 /* CameraFlyToExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraFlyToExample.swift; sourceTree = "<group>"; };
+ 3ED403461E006BE800230C95 /* CameraFlyToExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CameraFlyToExample.h; sourceTree = "<group>"; };
+ 3ED403471E006BE800230C95 /* CameraFlyToExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CameraFlyToExample.m; sourceTree = "<group>"; };
+ 589ABF8859560819F8B431C7 /* Pods-ExamplesTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamplesTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExamplesTests/Pods-ExamplesTests.debug.xcconfig"; sourceTree = "<group>"; };
+ 646B62961DEF6DAF000AA523 /* RuntimeToggleLayerExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeToggleLayerExample.swift; sourceTree = "<group>"; };
+ 646B629B1DEF6DF1000AA523 /* RuntimeToggleLayerExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RuntimeToggleLayerExample.m; sourceTree = "<group>"; };
+ 646B629E1DEF6DFD000AA523 /* RuntimeToggleLayerExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RuntimeToggleLayerExample.h; sourceTree = "<group>"; };
+ 646B62A11DEF70DD000AA523 /* RuntimeAnimateLineExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RuntimeAnimateLineExample.h; sourceTree = "<group>"; };
+ 646B62A21DEF7106000AA523 /* RuntimeAddLineExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RuntimeAddLineExample.h; sourceTree = "<group>"; };
+ 646B62A31DEF7115000AA523 /* RuntimeAddLineExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RuntimeAddLineExample.m; sourceTree = "<group>"; };
+ 646B62A51DEF7121000AA523 /* RuntimeAnimateLineExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RuntimeAnimateLineExample.m; sourceTree = "<group>"; };
+ 646B62AD1DEF7155000AA523 /* RuntimeAddLineExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeAddLineExample.swift; sourceTree = "<group>"; };
+ 646B62AF1DEF7161000AA523 /* RuntimeAnimateLineExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeAnimateLineExample.swift; sourceTree = "<group>"; };
+ 646B62B31DEF9613000AA523 /* RuntimeCircleStylesExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeCircleStylesExample.swift; sourceTree = "<group>"; };
+ 646B62BB1DEF964A000AA523 /* RuntimeCircleStylesExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RuntimeCircleStylesExample.h; sourceTree = "<group>"; };
+ 646B62BC1DEF965A000AA523 /* RuntimeCircleStylesExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RuntimeCircleStylesExample.m; sourceTree = "<group>"; };
+ 64BBDAEF1DF22D9600BB705D /* third_party_vector_style.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = third_party_vector_style.json; sourceTree = "<group>"; };
+ 64BBDAF51DF232FD00BB705D /* SelectFeatureExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectFeatureExample.swift; sourceTree = "<group>"; };
+ 64BBDAF71DF2330B00BB705D /* SelectFeatureExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectFeatureExample.m; sourceTree = "<group>"; };
+ 64BBDAFA1DF2331600BB705D /* SelectFeatureExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SelectFeatureExample.h; sourceTree = "<group>"; };
+ 64BBDAFB1DF24DD700BB705D /* RuntimeMultipleAnnotationsExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RuntimeMultipleAnnotationsExample.h; sourceTree = "<group>"; };
+ 64BBDAFC1DF24DEB00BB705D /* RuntimeMultipleAnnotationsExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RuntimeMultipleAnnotationsExample.m; sourceTree = "<group>"; };
+ 64BBDB021DF24E0900BB705D /* RuntimeMultipleAnnotationsExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeMultipleAnnotationsExample.swift; sourceTree = "<group>"; };
+ 64CF970B1DF224C500C3C27B /* SourceCustomVectorExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SourceCustomVectorExample.m; sourceTree = "<group>"; };
+ 64CF970E1DF224D400C3C27B /* SourceCustomVectorExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceCustomVectorExample.h; sourceTree = "<group>"; };
+ 64CF970F1DF224E400C3C27B /* SourceCustomVectorExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceCustomVectorExample.swift; sourceTree = "<group>"; };
+ 64CF97111DF224F600C3C27B /* SourceCustomRasterExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceCustomRasterExample.swift; sourceTree = "<group>"; };
+ 64CF97161DF2251500C3C27B /* SourceCustomRasterExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SourceCustomRasterExample.m; sourceTree = "<group>"; };
+ 64CF97191DF2252C00C3C27B /* SourceCustomRasterExample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceCustomRasterExample.h; sourceTree = "<group>"; };
+ 7556D44879C1E2866B0355B8 /* Pods-ExamplesTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamplesTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExamplesTests/Pods-ExamplesTests.release.xcconfig"; sourceTree = "<group>"; };
+ 7692D1D792EB3849E8754E6B /* Pods_ExamplesUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExamplesUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 960A215F1D344F9F00BB348B /* DraggableAnnotationViewExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DraggableAnnotationViewExample.h; sourceTree = "<group>"; };
+ 960A21601D344F9F00BB348B /* DraggableAnnotationViewExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DraggableAnnotationViewExample.m; sourceTree = "<group>"; };
+ 96115A661CAD4E1C000963B8 /* OfflinePackExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OfflinePackExample.h; path = Examples/ObjectiveC/OfflinePackExample.h; sourceTree = SOURCE_ROOT; };
+ 96115A671CAD4E1C000963B8 /* OfflinePackExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OfflinePackExample.m; path = Examples/ObjectiveC/OfflinePackExample.m; sourceTree = SOURCE_ROOT; };
+ 9619628C1C581700002D3DAB /* Examples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Examples.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 961962901C581700002D3DAB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 961962921C581700002D3DAB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 961962931C581700002D3DAB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 9619629B1C581700002D3DAB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ 9619629E1C581700002D3DAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+ 961962A01C581700002D3DAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 961962A51C581700002D3DAB /* ExamplesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExamplesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 961962A91C581700002D3DAB /* ExamplesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExamplesTests.m; sourceTree = "<group>"; };
+ 961962AB1C581700002D3DAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 961962B01C581700002D3DAB /* ExamplesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExamplesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 961962B41C581700002D3DAB /* ExamplesUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExamplesUITests.m; sourceTree = "<group>"; };
+ 961962B61C581700002D3DAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 961962CE1C581FBC002D3DAB /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
+ 961962D01C5821A9002D3DAB /* ExamplesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExamplesTableViewController.h; sourceTree = "<group>"; };
+ 961962D11C5821A9002D3DAB /* ExamplesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExamplesTableViewController.m; sourceTree = "<group>"; };
+ 961962D31C583FDC002D3DAB /* ExamplesContainerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExamplesContainerViewController.h; sourceTree = "<group>"; };
+ 961962D41C583FDC002D3DAB /* ExamplesContainerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExamplesContainerViewController.m; sourceTree = "<group>"; };
+ 962B450D1D1C8520007B7454 /* AnnotationViewExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnnotationViewExample.h; sourceTree = "<group>"; };
+ 962B450E1D1C8520007B7454 /* AnnotationViewExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnnotationViewExample.m; sourceTree = "<group>"; };
+ 964CB5101E42A0A3004549EA /* AnnotationViewMultipleExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnnotationViewMultipleExample.swift; sourceTree = "<group>"; };
+ 964CB5171E445AE1004549EA /* mapbox_access_token */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mapbox_access_token; sourceTree = SOURCE_ROOT; };
+ 9678E3EC1CEF58DA00F21AE2 /* CustomAnnotationModelExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomAnnotationModelExample.h; sourceTree = "<group>"; };
+ 9678E3ED1CEF58DA00F21AE2 /* CustomAnnotationModelExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomAnnotationModelExample.m; sourceTree = "<group>"; };
+ 9678E3F21CEF616700F21AE2 /* CustomAnnotationModels.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomAnnotationModels.h; sourceTree = "<group>"; };
+ 968247011C5BDCBB00494AB8 /* CustomRasterStyleExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomRasterStyleExample.h; path = Examples/ObjectiveC/CustomRasterStyleExample.h; sourceTree = SOURCE_ROOT; };
+ 968247021C5BDCBB00494AB8 /* CustomRasterStyleExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CustomRasterStyleExample.m; path = Examples/ObjectiveC/CustomRasterStyleExample.m; sourceTree = SOURCE_ROOT; };
+ 968247061C5BEBDC00494AB8 /* SatelliteStyleExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SatelliteStyleExample.h; path = Examples/ObjectiveC/SatelliteStyleExample.h; sourceTree = SOURCE_ROOT; };
+ 968247071C5BEBDC00494AB8 /* SatelliteStyleExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SatelliteStyleExample.m; path = Examples/ObjectiveC/SatelliteStyleExample.m; sourceTree = SOURCE_ROOT; };
+ 9682470D1C5BF12700494AB8 /* DrawingAMarkerExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DrawingAMarkerExample.h; path = Examples/ObjectiveC/DrawingAMarkerExample.h; sourceTree = SOURCE_ROOT; };
+ 9682470E1C5BF12700494AB8 /* DrawingAMarkerExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DrawingAMarkerExample.m; path = Examples/ObjectiveC/DrawingAMarkerExample.m; sourceTree = SOURCE_ROOT; };
+ 968247111C5C0F0F00494AB8 /* CalloutDelegateUsageExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CalloutDelegateUsageExample.h; path = Examples/ObjectiveC/CalloutDelegateUsageExample.h; sourceTree = SOURCE_ROOT; };
+ 968247121C5C0F0F00494AB8 /* CalloutDelegateUsageExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CalloutDelegateUsageExample.m; path = Examples/ObjectiveC/CalloutDelegateUsageExample.m; sourceTree = SOURCE_ROOT; };
+ 968247181C5C115000494AB8 /* DrawingAGeoJSONLineExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DrawingAGeoJSONLineExample.h; path = Examples/ObjectiveC/DrawingAGeoJSONLineExample.h; sourceTree = SOURCE_ROOT; };
+ 968247191C5C115000494AB8 /* DrawingAGeoJSONLineExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DrawingAGeoJSONLineExample.m; path = Examples/ObjectiveC/DrawingAGeoJSONLineExample.m; sourceTree = SOURCE_ROOT; };
+ 9682471C1C5C123B00494AB8 /* example.geojson */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = example.geojson; path = ../Files/example.geojson; sourceTree = "<group>"; };
+ 9682471E1C5C1C0400494AB8 /* DrawingAPolygonExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DrawingAPolygonExample.h; path = Examples/ObjectiveC/DrawingAPolygonExample.h; sourceTree = SOURCE_ROOT; };
+ 9682471F1C5C1C0400494AB8 /* DrawingAPolygonExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DrawingAPolygonExample.m; path = Examples/ObjectiveC/DrawingAPolygonExample.m; sourceTree = SOURCE_ROOT; };
+ 968247251C5C1DC700494AB8 /* CameraAnimationExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CameraAnimationExample.h; path = Examples/ObjectiveC/CameraAnimationExample.h; sourceTree = SOURCE_ROOT; };
+ 968247261C5C1DC700494AB8 /* CameraAnimationExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CameraAnimationExample.m; path = Examples/ObjectiveC/CameraAnimationExample.m; sourceTree = SOURCE_ROOT; };
+ 968247281C5C1FF800494AB8 /* PointConversionExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PointConversionExample.h; path = Examples/ObjectiveC/PointConversionExample.h; sourceTree = SOURCE_ROOT; };
+ 968247291C5C1FF800494AB8 /* PointConversionExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PointConversionExample.m; path = Examples/ObjectiveC/PointConversionExample.m; sourceTree = SOURCE_ROOT; };
+ 9691AA921C5AA702006A58C6 /* Examples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Examples.h; sourceTree = "<group>"; };
+ 9691AA931C5AA702006A58C6 /* Examples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Examples.m; sourceTree = "<group>"; };
+ 9691AAA11C5AAD8F006A58C6 /* CustomStyleExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomStyleExample.h; path = Examples/ObjectiveC/CustomStyleExample.h; sourceTree = SOURCE_ROOT; };
+ 9691AAA21C5AAD8F006A58C6 /* CustomStyleExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CustomStyleExample.m; path = Examples/ObjectiveC/CustomStyleExample.m; sourceTree = SOURCE_ROOT; };
+ 9691AAA31C5AAD8F006A58C6 /* DefaultStylesExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DefaultStylesExample.h; path = Examples/ObjectiveC/DefaultStylesExample.h; sourceTree = SOURCE_ROOT; };
+ 9691AAA41C5AAD8F006A58C6 /* DefaultStylesExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DefaultStylesExample.m; path = Examples/ObjectiveC/DefaultStylesExample.m; sourceTree = SOURCE_ROOT; };
+ 9691AAA51C5AAD8F006A58C6 /* SimpleMapViewExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SimpleMapViewExample.h; path = Examples/ObjectiveC/SimpleMapViewExample.h; sourceTree = SOURCE_ROOT; };
+ 9691AAA61C5AAD8F006A58C6 /* SimpleMapViewExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SimpleMapViewExample.m; path = Examples/ObjectiveC/SimpleMapViewExample.m; sourceTree = SOURCE_ROOT; };
+ 9691AAAA1C5AB546006A58C6 /* Examples-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Examples-Bridging-Header.h"; sourceTree = "<group>"; };
+ 969E7FDB1D25C31700663F84 /* UserTrackingModesExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserTrackingModesExample.h; sourceTree = "<group>"; };
+ 969E7FDC1D25C31700663F84 /* UserTrackingModesExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserTrackingModesExample.m; sourceTree = "<group>"; };
+ 96A2A1CD1C8CA16C0059441E /* CustomCalloutViewExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomCalloutViewExample.h; path = Examples/ObjectiveC/CustomCalloutViewExample.h; sourceTree = SOURCE_ROOT; };
+ 96A2A1CE1C8CA16C0059441E /* CustomCalloutViewExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CustomCalloutViewExample.m; path = Examples/ObjectiveC/CustomCalloutViewExample.m; sourceTree = SOURCE_ROOT; };
+ 96A2A1D01C8CA74B0059441E /* CustomCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomCalloutView.h; path = Examples/ObjectiveC/CustomCalloutView.h; sourceTree = SOURCE_ROOT; };
+ 96A2A1D11C8CA74B0059441E /* CustomCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CustomCalloutView.m; path = Examples/ObjectiveC/CustomCalloutView.m; sourceTree = SOURCE_ROOT; };
+ 96D431FA1C84B4F7007D09D1 /* DrawingACustomMarkerExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DrawingACustomMarkerExample.h; path = Examples/ObjectiveC/DrawingACustomMarkerExample.h; sourceTree = SOURCE_ROOT; };
+ 96D431FB1C84B4F7007D09D1 /* DrawingACustomMarkerExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DrawingACustomMarkerExample.m; path = Examples/ObjectiveC/DrawingACustomMarkerExample.m; sourceTree = SOURCE_ROOT; };
+ 96D432051C84B9CF007D09D1 /* pisavector.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = pisavector.xcassets; sourceTree = "<group>"; };
+ 9EC12D8F1A97963D68BFA871 /* Pods_Examples.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Examples.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ DD5939E31E6639BA0009BEB2 /* ClusteringExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClusteringExample.swift; sourceTree = "<group>"; };
+ DD5939E51E6778480009BEB2 /* clustering.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = clustering.xcassets; sourceTree = "<group>"; };
+ DDF943271E5DE63300545D0F /* ClusteringExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClusteringExample.h; sourceTree = "<group>"; };
+ DDF943281E5DE63300545D0F /* ClusteringExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ClusteringExample.m; sourceTree = "<group>"; };
+ DDF9432A1E5DEACC00545D0F /* ports.geojson */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ports.geojson; sourceTree = "<group>"; };
+ E0520BEE090DE0364897BAF3 /* Pods-ExamplesUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamplesUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExamplesUITests/Pods-ExamplesUITests.release.xcconfig"; sourceTree = "<group>"; };
+ F8EE2FB6BE39BB48832DA94C /* Pods_ExamplesTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExamplesTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 961962891C581700002D3DAB /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4F1B1A74F32EB5E8C46C9A12 /* Pods_Examples.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 961962A21C581700002D3DAB /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F9C1D0F8EE832A1D242930D2 /* Pods_ExamplesTests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 961962AD1C581700002D3DAB /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BBD05676206B24335DEA52C4 /* Pods_ExamplesUITests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 3EBCD6FA1DC26355001E342F /* Objective-C */ = {
+ isa = PBXGroup;
+ children = (
+ 962B450E1D1C8520007B7454 /* AnnotationViewExample.m */,
+ 07F53B841E00D02100B58DB3 /* AnnotationViewMultipleExample.m */,
+ 1F1F84741E538ABB00332CC3 /* BlockingGesturesDelegateExample.m */,
+ 968247121C5C0F0F00494AB8 /* CalloutDelegateUsageExample.m */,
+ 968247261C5C1DC700494AB8 /* CameraAnimationExample.m */,
+ 3ED403471E006BE800230C95 /* CameraFlyToExample.m */,
+ DDF943281E5DE63300545D0F /* ClusteringExample.m */,
+ 9678E3ED1CEF58DA00F21AE2 /* CustomAnnotationModelExample.m */,
+ 9678E3F21CEF616700F21AE2 /* CustomAnnotationModels.h */,
+ 96A2A1D11C8CA74B0059441E /* CustomCalloutView.m */,
+ 96A2A1CE1C8CA16C0059441E /* CustomCalloutViewExample.m */,
+ 968247021C5BDCBB00494AB8 /* CustomRasterStyleExample.m */,
+ 9691AAA21C5AAD8F006A58C6 /* CustomStyleExample.m */,
+ 07C138C61E72216E00D6F678 /* DDSCircleLayerExample.m */,
+ 3E3BFADB1E81D7BB00D0BEA1 /* DDSLayerSelectionExample.m */,
+ 9691AAA41C5AAD8F006A58C6 /* DefaultStylesExample.m */,
+ 960A21601D344F9F00BB348B /* DraggableAnnotationViewExample.m */,
+ 96D431FB1C84B4F7007D09D1 /* DrawingACustomMarkerExample.m */,
+ 968247191C5C115000494AB8 /* DrawingAGeoJSONLineExample.m */,
+ 9682470E1C5BF12700494AB8 /* DrawingAMarkerExample.m */,
+ 9682471F1C5C1C0400494AB8 /* DrawingAPolygonExample.m */,
+ 3E085B821EC526E500163C99 /* ExtrusionsExample.m */,
+ 646B62A31DEF7115000AA523 /* RuntimeAddLineExample.m */,
+ 646B62A51DEF7121000AA523 /* RuntimeAnimateLineExample.m */,
+ 646B62BC1DEF965A000AA523 /* RuntimeCircleStylesExample.m */,
+ 646B629B1DEF6DF1000AA523 /* RuntimeToggleLayerExample.m */,
+ 64BBDAFC1DF24DEB00BB705D /* RuntimeMultipleAnnotationsExample.m */,
+ 96115A671CAD4E1C000963B8 /* OfflinePackExample.m */,
+ 968247291C5C1FF800494AB8 /* PointConversionExample.m */,
+ 968247071C5BEBDC00494AB8 /* SatelliteStyleExample.m */,
+ 64BBDAF71DF2330B00BB705D /* SelectFeatureExample.m */,
+ 07C138BF1E6F646F00D6F678 /* ShapeCollectionFeatureExample.m */,
+ 9691AAA61C5AAD8F006A58C6 /* SimpleMapViewExample.m */,
+ 64CF970B1DF224C500C3C27B /* SourceCustomVectorExample.m */,
+ 64CF97161DF2251500C3C27B /* SourceCustomRasterExample.m */,
+ 969E7FDC1D25C31700663F84 /* UserTrackingModesExample.m */,
+ );
+ name = "Objective-C";
+ sourceTree = "<group>";
+ };
+ 3EBCD6FC1DC26364001E342F /* Swift */ = {
+ isa = PBXGroup;
+ children = (
+ 3EBCD7021DC28240001E342F /* AnnotationViewExample.swift */,
+ 964CB5101E42A0A3004549EA /* AnnotationViewMultipleExample.swift */,
+ 1F1F84761E53A3B700332CC3 /* BlockingGesturesDelegateExample.swift */,
+ 3EBCD7031DC28240001E342F /* CalloutDelegateUsageExample.swift */,
+ 3EBCD7041DC28240001E342F /* CameraAnimationExample.swift */,
+ 3ED403401E006B5200230C95 /* CameraFlyToExample.swift */,
+ DD5939E31E6639BA0009BEB2 /* ClusteringExample.swift */,
+ 3EBCD7051DC28240001E342F /* CustomAnnotationModelExample.swift */,
+ 3EBCD7061DC28240001E342F /* CustomAnnotationModels.swift */,
+ 3EBCD7071DC28240001E342F /* CustomCalloutView.swift */,
+ 3EBCD7081DC28240001E342F /* CustomCalloutViewExample.swift */,
+ 3EBCD7091DC28240001E342F /* CustomRasterStyleExample.swift */,
+ 3EBCD70A1DC28240001E342F /* CustomStyleExample.swift */,
+ 07C138C31E721C8F00D6F678 /* DDSCircleLayerExample.swift */,
+ 3E3BFAD81E81D7A300D0BEA1 /* DDSLayerSelectionExample.swift */,
+ 3EBCD70B1DC28240001E342F /* DefaultStylesExample.swift */,
+ 3EBCD70C1DC28240001E342F /* DraggableAnnotationViewExample.swift */,
+ 3EBCD70D1DC28240001E342F /* DrawingACustomMarkerExample.swift */,
+ 3EBCD70E1DC28240001E342F /* DrawingAGeoJSONLineExample.swift */,
+ 3EBCD70F1DC28240001E342F /* DrawingAMarkerExample.swift */,
+ 3EBCD7101DC28240001E342F /* DrawingAPolygonExample.swift */,
+ 3E085B7F1EC526C500163C99 /* ExtrusionsExample.swift */,
+ 3EBCD7111DC28240001E342F /* OfflinePackExample.swift */,
+ 3EBCD7121DC28240001E342F /* PointConversionExample.swift */,
+ 646B62AD1DEF7155000AA523 /* RuntimeAddLineExample.swift */,
+ 646B62AF1DEF7161000AA523 /* RuntimeAnimateLineExample.swift */,
+ 646B62B31DEF9613000AA523 /* RuntimeCircleStylesExample.swift */,
+ 646B62961DEF6DAF000AA523 /* RuntimeToggleLayerExample.swift */,
+ 64BBDB021DF24E0900BB705D /* RuntimeMultipleAnnotationsExample.swift */,
+ 3EBCD7131DC28240001E342F /* SatelliteStyleExample.swift */,
+ 64BBDAF51DF232FD00BB705D /* SelectFeatureExample.swift */,
+ 07C138C11E6F65D000D6F678 /* ShapeCollectionFeatureExample.swift */,
+ 3EBCD7141DC28240001E342F /* SimpleMapViewExample.swift */,
+ 64CF970F1DF224E400C3C27B /* SourceCustomVectorExample.swift */,
+ 64CF97111DF224F600C3C27B /* SourceCustomRasterExample.swift */,
+ 3EBCD7151DC28240001E342F /* UserTrackingModesExample.swift */,
+ );
+ name = Swift;
+ path = ../Swift;
+ sourceTree = "<group>";
+ };
+ 961962831C581700002D3DAB = {
+ isa = PBXGroup;
+ children = (
+ 9619628E1C581700002D3DAB /* Examples */,
+ 961962A81C581700002D3DAB /* ExamplesTests */,
+ 961962B31C581700002D3DAB /* ExamplesUITests */,
+ 9619628D1C581700002D3DAB /* Products */,
+ C977D0AF4A14922071F96B9B /* Pods */,
+ CBAD5BE154F4126883B2A6DC /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ 9619628D1C581700002D3DAB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 9619628C1C581700002D3DAB /* Examples.app */,
+ 961962A51C581700002D3DAB /* ExamplesTests.xctest */,
+ 961962B01C581700002D3DAB /* ExamplesUITests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 9619628E1C581700002D3DAB /* Examples */ = {
+ isa = PBXGroup;
+ children = (
+ 9691AAA01C5AAD8F006A58C6 /* Code */,
+ 9682471B1C5C123B00494AB8 /* Files */,
+ 961962921C581700002D3DAB /* AppDelegate.h */,
+ 961962931C581700002D3DAB /* AppDelegate.m */,
+ 9691AA921C5AA702006A58C6 /* Examples.h */,
+ 9691AA931C5AA702006A58C6 /* Examples.m */,
+ 961962D31C583FDC002D3DAB /* ExamplesContainerViewController.h */,
+ 961962D41C583FDC002D3DAB /* ExamplesContainerViewController.m */,
+ 961962D01C5821A9002D3DAB /* ExamplesTableViewController.h */,
+ 961962D11C5821A9002D3DAB /* ExamplesTableViewController.m */,
+ 9619629B1C581700002D3DAB /* Assets.xcassets */,
+ 961962CE1C581FBC002D3DAB /* Main.storyboard */,
+ 9619629D1C581700002D3DAB /* LaunchScreen.storyboard */,
+ 961962A01C581700002D3DAB /* Info.plist */,
+ 9619628F1C581700002D3DAB /* Supporting Files */,
+ );
+ path = Examples;
+ sourceTree = "<group>";
+ };
+ 9619628F1C581700002D3DAB /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 9691AAAA1C5AB546006A58C6 /* Examples-Bridging-Header.h */,
+ 961962901C581700002D3DAB /* main.m */,
+ 964CB5171E445AE1004549EA /* mapbox_access_token */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ 961962A81C581700002D3DAB /* ExamplesTests */ = {
+ isa = PBXGroup;
+ children = (
+ 961962A91C581700002D3DAB /* ExamplesTests.m */,
+ 961962AB1C581700002D3DAB /* Info.plist */,
+ );
+ path = ExamplesTests;
+ sourceTree = "<group>";
+ };
+ 961962B31C581700002D3DAB /* ExamplesUITests */ = {
+ isa = PBXGroup;
+ children = (
+ 961962B41C581700002D3DAB /* ExamplesUITests.m */,
+ 961962B61C581700002D3DAB /* Info.plist */,
+ );
+ path = ExamplesUITests;
+ sourceTree = "<group>";
+ };
+ 9682471B1C5C123B00494AB8 /* Files */ = {
+ isa = PBXGroup;
+ children = (
+ 3EC92DB61E78C431001D0503 /* metro-line.geojson */,
+ 9682471C1C5C123B00494AB8 /* example.geojson */,
+ 64BBDAEF1DF22D9600BB705D /* third_party_vector_style.json */,
+ 96D432051C84B9CF007D09D1 /* pisavector.xcassets */,
+ 079E77C41E1C4E2100F92FA8 /* camera.xcassets */,
+ DD5939E51E6778480009BEB2 /* clustering.xcassets */,
+ DDF9432A1E5DEACC00545D0F /* ports.geojson */,
+ );
+ path = Files;
+ sourceTree = "<group>";
+ };
+ 9682472D1C5C226D00494AB8 /* Headers */ = {
+ isa = PBXGroup;
+ children = (
+ 07F53B861E00D08600B58DB3 /* AnnotationViewMultipleExample.h */,
+ 962B450D1D1C8520007B7454 /* AnnotationViewExample.h */,
+ 1F1F84731E538ABB00332CC3 /* BlockingGesturesDelegateExample.h */,
+ 968247111C5C0F0F00494AB8 /* CalloutDelegateUsageExample.h */,
+ 968247251C5C1DC700494AB8 /* CameraAnimationExample.h */,
+ 3ED403461E006BE800230C95 /* CameraFlyToExample.h */,
+ DDF943271E5DE63300545D0F /* ClusteringExample.h */,
+ 9678E3EC1CEF58DA00F21AE2 /* CustomAnnotationModelExample.h */,
+ 96A2A1D01C8CA74B0059441E /* CustomCalloutView.h */,
+ 96A2A1CD1C8CA16C0059441E /* CustomCalloutViewExample.h */,
+ 968247011C5BDCBB00494AB8 /* CustomRasterStyleExample.h */,
+ 9691AAA11C5AAD8F006A58C6 /* CustomStyleExample.h */,
+ 07C138C51E72216D00D6F678 /* DDSCircleLayerExample.h */,
+ 3E3BFADA1E81D7BB00D0BEA1 /* DDSLayerSelectionExample.h */,
+ 9691AAA31C5AAD8F006A58C6 /* DefaultStylesExample.h */,
+ 960A215F1D344F9F00BB348B /* DraggableAnnotationViewExample.h */,
+ 96D431FA1C84B4F7007D09D1 /* DrawingACustomMarkerExample.h */,
+ 968247181C5C115000494AB8 /* DrawingAGeoJSONLineExample.h */,
+ 9682470D1C5BF12700494AB8 /* DrawingAMarkerExample.h */,
+ 9682471E1C5C1C0400494AB8 /* DrawingAPolygonExample.h */,
+ 3E085B811EC526E500163C99 /* ExtrusionsExample.h */,
+ 96115A661CAD4E1C000963B8 /* OfflinePackExample.h */,
+ 968247281C5C1FF800494AB8 /* PointConversionExample.h */,
+ 646B62A21DEF7106000AA523 /* RuntimeAddLineExample.h */,
+ 646B62A11DEF70DD000AA523 /* RuntimeAnimateLineExample.h */,
+ 646B62BB1DEF964A000AA523 /* RuntimeCircleStylesExample.h */,
+ 646B629E1DEF6DFD000AA523 /* RuntimeToggleLayerExample.h */,
+ 64BBDAFB1DF24DD700BB705D /* RuntimeMultipleAnnotationsExample.h */,
+ 968247061C5BEBDC00494AB8 /* SatelliteStyleExample.h */,
+ 64BBDAFA1DF2331600BB705D /* SelectFeatureExample.h */,
+ 07C138BE1E6F646F00D6F678 /* ShapeCollectionFeatureExample.h */,
+ 9691AAA51C5AAD8F006A58C6 /* SimpleMapViewExample.h */,
+ 64CF970E1DF224D400C3C27B /* SourceCustomVectorExample.h */,
+ 64CF97191DF2252C00C3C27B /* SourceCustomRasterExample.h */,
+ 969E7FDB1D25C31700663F84 /* UserTrackingModesExample.h */,
+ );
+ name = Headers;
+ path = Examples/ObjectiveC;
+ sourceTree = SOURCE_ROOT;
+ };
+ 9691AAA01C5AAD8F006A58C6 /* Code */ = {
+ isa = PBXGroup;
+ children = (
+ 3EBCD6FC1DC26364001E342F /* Swift */,
+ 3EBCD6FA1DC26355001E342F /* Objective-C */,
+ 9682472D1C5C226D00494AB8 /* Headers */,
+ );
+ name = Code;
+ path = ObjectiveC;
+ sourceTree = "<group>";
+ };
+ C977D0AF4A14922071F96B9B /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 03CC5D45DBD04AB716469E7B /* Pods-Examples.debug.xcconfig */,
+ 29A0D7C8DCD539DCA5DA1BAC /* Pods-Examples.release.xcconfig */,
+ 589ABF8859560819F8B431C7 /* Pods-ExamplesTests.debug.xcconfig */,
+ 7556D44879C1E2866B0355B8 /* Pods-ExamplesTests.release.xcconfig */,
+ 0A4917D6B62E749D739044A4 /* Pods-ExamplesUITests.debug.xcconfig */,
+ E0520BEE090DE0364897BAF3 /* Pods-ExamplesUITests.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+ CBAD5BE154F4126883B2A6DC /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 9EC12D8F1A97963D68BFA871 /* Pods_Examples.framework */,
+ F8EE2FB6BE39BB48832DA94C /* Pods_ExamplesTests.framework */,
+ 7692D1D792EB3849E8754E6B /* Pods_ExamplesUITests.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 9619628B1C581700002D3DAB /* Examples */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 961962B91C581700002D3DAB /* Build configuration list for PBXNativeTarget "Examples" */;
+ buildPhases = (
+ E8773E0E765E2B04318A4906 /* [CP] Check Pods Manifest.lock */,
+ 961962881C581700002D3DAB /* Sources */,
+ 961962891C581700002D3DAB /* Frameworks */,
+ 9619628A1C581700002D3DAB /* Resources */,
+ 961962C71C5818EB002D3DAB /* Embed Frameworks */,
+ 964CB5161E445964004549EA /* Insert Mapbox Access Token */,
+ 68B044275FAAD94BEB604ADD /* [CP] Embed Pods Frameworks */,
+ AFCD70701CA828429FE683F5 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Examples;
+ productName = Examples;
+ productReference = 9619628C1C581700002D3DAB /* Examples.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 961962A41C581700002D3DAB /* ExamplesTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 961962BC1C581700002D3DAB /* Build configuration list for PBXNativeTarget "ExamplesTests" */;
+ buildPhases = (
+ 227ED455385772D85979EFDA /* [CP] Check Pods Manifest.lock */,
+ 961962A11C581700002D3DAB /* Sources */,
+ 961962A21C581700002D3DAB /* Frameworks */,
+ 961962A31C581700002D3DAB /* Resources */,
+ 62886E6EC1BFD0C753782703 /* [CP] Embed Pods Frameworks */,
+ 22AEEA788A5D2A11DF9F9032 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 961962A71C581700002D3DAB /* PBXTargetDependency */,
+ );
+ name = ExamplesTests;
+ productName = ExamplesTests;
+ productReference = 961962A51C581700002D3DAB /* ExamplesTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 961962AF1C581700002D3DAB /* ExamplesUITests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 961962BF1C581700002D3DAB /* Build configuration list for PBXNativeTarget "ExamplesUITests" */;
+ buildPhases = (
+ 86411F4AADC7F6D3F4B54A6C /* [CP] Check Pods Manifest.lock */,
+ 961962AC1C581700002D3DAB /* Sources */,
+ 961962AD1C581700002D3DAB /* Frameworks */,
+ 961962AE1C581700002D3DAB /* Resources */,
+ BC5D06A971EDB0EA19738436 /* [CP] Embed Pods Frameworks */,
+ 5EB77C15F6FACA271F7F81D5 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 961962B21C581700002D3DAB /* PBXTargetDependency */,
+ );
+ name = ExamplesUITests;
+ productName = ExamplesUITests;
+ productReference = 961962B01C581700002D3DAB /* ExamplesUITests.xctest */;
+ productType = "com.apple.product-type.bundle.ui-testing";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 961962841C581700002D3DAB /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0810;
+ ORGANIZATIONNAME = Mapbox;
+ TargetAttributes = {
+ 9619628B1C581700002D3DAB = {
+ CreatedOnToolsVersion = 7.3;
+ DevelopmentTeam = GJZR2MEM28;
+ LastSwiftMigration = 0800;
+ ProvisioningStyle = Automatic;
+ };
+ 961962A41C581700002D3DAB = {
+ CreatedOnToolsVersion = 7.3;
+ DevelopmentTeam = GJZR2MEM28;
+ TestTargetID = 9619628B1C581700002D3DAB;
+ };
+ 961962AF1C581700002D3DAB = {
+ CreatedOnToolsVersion = 7.3;
+ DevelopmentTeam = GJZR2MEM28;
+ TestTargetID = 9619628B1C581700002D3DAB;
+ };
+ };
+ };
+ buildConfigurationList = 961962871C581700002D3DAB /* Build configuration list for PBXProject "Examples" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 961962831C581700002D3DAB;
+ productRefGroup = 9619628D1C581700002D3DAB /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 9619628B1C581700002D3DAB /* Examples */,
+ 961962A41C581700002D3DAB /* ExamplesTests */,
+ 961962AF1C581700002D3DAB /* ExamplesUITests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 9619628A1C581700002D3DAB /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DDF9432B1E5DEACC00545D0F /* ports.geojson in Resources */,
+ 3EC92DB71E78C431001D0503 /* metro-line.geojson in Resources */,
+ 9619629F1C581700002D3DAB /* LaunchScreen.storyboard in Resources */,
+ DD5939E61E6778480009BEB2 /* clustering.xcassets in Resources */,
+ 079E77C51E1C4E2100F92FA8 /* camera.xcassets in Resources */,
+ 9619629C1C581700002D3DAB /* Assets.xcassets in Resources */,
+ 9682471D1C5C123B00494AB8 /* example.geojson in Resources */,
+ 64BBDAF01DF22D9600BB705D /* third_party_vector_style.json in Resources */,
+ 961962CF1C581FBC002D3DAB /* Main.storyboard in Resources */,
+ 96D432061C84B9CF007D09D1 /* pisavector.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 961962A31C581700002D3DAB /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 961962AE1C581700002D3DAB /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 227ED455385772D85979EFDA /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 22AEEA788A5D2A11DF9F9032 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExamplesTests/Pods-ExamplesTests-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 5EB77C15F6FACA271F7F81D5 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExamplesUITests/Pods-ExamplesUITests-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 62886E6EC1BFD0C753782703 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExamplesTests/Pods-ExamplesTests-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 68B044275FAAD94BEB604ADD /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Examples/Pods-Examples-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 86411F4AADC7F6D3F4B54A6C /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 964CB5161E445964004549EA /* Insert Mapbox Access Token */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Insert Mapbox Access Token";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SRCROOT/Examples/insert-mapbox-token.sh";
+ };
+ AFCD70701CA828429FE683F5 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Examples/Pods-Examples-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ BC5D06A971EDB0EA19738436 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExamplesUITests/Pods-ExamplesUITests-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ E8773E0E765E2B04318A4906 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 961962881C581700002D3DAB /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 07C138C71E72216E00D6F678 /* DDSCircleLayerExample.m in Sources */,
+ 3EBCD7191DC28240001E342F /* CustomAnnotationModelExample.swift in Sources */,
+ 962B450F1D1C8520007B7454 /* AnnotationViewExample.m in Sources */,
+ 1F1F84771E53A3B700332CC3 /* BlockingGesturesDelegateExample.swift in Sources */,
+ 3ED403411E006B5200230C95 /* CameraFlyToExample.swift in Sources */,
+ 9691AAA91C5AAD8F006A58C6 /* SimpleMapViewExample.m in Sources */,
+ 960A21611D344F9F00BB348B /* DraggableAnnotationViewExample.m in Sources */,
+ 1F1F84751E538ABB00332CC3 /* BlockingGesturesDelegateExample.m in Sources */,
+ 646B62B41DEF9613000AA523 /* RuntimeCircleStylesExample.swift in Sources */,
+ 07C138C41E721C8F00D6F678 /* DDSCircleLayerExample.swift in Sources */,
+ 646B62BD1DEF965A000AA523 /* RuntimeCircleStylesExample.m in Sources */,
+ 646B629C1DEF6DF1000AA523 /* RuntimeToggleLayerExample.m in Sources */,
+ 96A2A1CF1C8CA16C0059441E /* CustomCalloutViewExample.m in Sources */,
+ 07C138C21E6F65D000D6F678 /* ShapeCollectionFeatureExample.swift in Sources */,
+ 3EBCD7161DC28240001E342F /* AnnotationViewExample.swift in Sources */,
+ 9682470F1C5BF12700494AB8 /* DrawingAMarkerExample.m in Sources */,
+ 961962941C581700002D3DAB /* AppDelegate.m in Sources */,
+ 3EBCD71B1DC28240001E342F /* CustomCalloutView.swift in Sources */,
+ 07C138C01E6F646F00D6F678 /* ShapeCollectionFeatureExample.m in Sources */,
+ 3EBCD7291DC28240001E342F /* UserTrackingModesExample.swift in Sources */,
+ 646B62A61DEF7121000AA523 /* RuntimeAnimateLineExample.m in Sources */,
+ 9691AAA71C5AAD8F006A58C6 /* CustomStyleExample.m in Sources */,
+ 9678E3EE1CEF58DA00F21AE2 /* CustomAnnotationModelExample.m in Sources */,
+ 3EBCD7261DC28240001E342F /* PointConversionExample.swift in Sources */,
+ 961962D21C5821A9002D3DAB /* ExamplesTableViewController.m in Sources */,
+ 64BBDB031DF24E0900BB705D /* RuntimeMultipleAnnotationsExample.swift in Sources */,
+ 646B62971DEF6DAF000AA523 /* RuntimeToggleLayerExample.swift in Sources */,
+ 968247201C5C1C0400494AB8 /* DrawingAPolygonExample.m in Sources */,
+ 3EBCD7221DC28240001E342F /* DrawingAGeoJSONLineExample.swift in Sources */,
+ 96A2A1D21C8CA74B0059441E /* CustomCalloutView.m in Sources */,
+ 3E085B831EC526E500163C99 /* ExtrusionsExample.m in Sources */,
+ 64BBDAF61DF232FD00BB705D /* SelectFeatureExample.swift in Sources */,
+ 64BBDAF81DF2330B00BB705D /* SelectFeatureExample.m in Sources */,
+ 96D431FC1C84B4F7007D09D1 /* DrawingACustomMarkerExample.m in Sources */,
+ 968247031C5BDCBB00494AB8 /* CustomRasterStyleExample.m in Sources */,
+ 64CF97121DF224F600C3C27B /* SourceCustomRasterExample.swift in Sources */,
+ 3E3BFADC1E81D7BB00D0BEA1 /* DDSLayerSelectionExample.m in Sources */,
+ 9682472A1C5C1FF800494AB8 /* PointConversionExample.m in Sources */,
+ 3ED403481E006BE800230C95 /* CameraFlyToExample.m in Sources */,
+ 3EBCD71D1DC28240001E342F /* CustomRasterStyleExample.swift in Sources */,
+ 646B62B01DEF7161000AA523 /* RuntimeAnimateLineExample.swift in Sources */,
+ 07F53B851E00D02100B58DB3 /* AnnotationViewMultipleExample.m in Sources */,
+ 3E085B801EC526C500163C99 /* ExtrusionsExample.swift in Sources */,
+ 3EBCD7231DC28240001E342F /* DrawingAMarkerExample.swift in Sources */,
+ 961962911C581700002D3DAB /* main.m in Sources */,
+ 968247131C5C0F0F00494AB8 /* CalloutDelegateUsageExample.m in Sources */,
+ 3EBCD7251DC28240001E342F /* OfflinePackExample.swift in Sources */,
+ 3EBCD71A1DC28240001E342F /* CustomAnnotationModels.swift in Sources */,
+ 3E3BFAD91E81D7A300D0BEA1 /* DDSLayerSelectionExample.swift in Sources */,
+ 3EBCD7181DC28240001E342F /* CameraAnimationExample.swift in Sources */,
+ 9691AA941C5AA702006A58C6 /* Examples.m in Sources */,
+ 3EBCD7201DC28240001E342F /* DraggableAnnotationViewExample.swift in Sources */,
+ 3EBCD7281DC28240001E342F /* SimpleMapViewExample.swift in Sources */,
+ 3EBCD7241DC28240001E342F /* DrawingAPolygonExample.swift in Sources */,
+ 964CB5111E42A0A3004549EA /* AnnotationViewMultipleExample.swift in Sources */,
+ 9691AAA81C5AAD8F006A58C6 /* DefaultStylesExample.m in Sources */,
+ 64CF97101DF224E400C3C27B /* SourceCustomVectorExample.swift in Sources */,
+ 3EBCD7211DC28240001E342F /* DrawingACustomMarkerExample.swift in Sources */,
+ 3EBCD71E1DC28240001E342F /* CustomStyleExample.swift in Sources */,
+ 968247081C5BEBDC00494AB8 /* SatelliteStyleExample.m in Sources */,
+ 64CF97171DF2251500C3C27B /* SourceCustomRasterExample.m in Sources */,
+ 3EBCD7271DC28240001E342F /* SatelliteStyleExample.swift in Sources */,
+ 96115A681CAD4E1C000963B8 /* OfflinePackExample.m in Sources */,
+ 3EBCD71C1DC28240001E342F /* CustomCalloutViewExample.swift in Sources */,
+ DDF943291E5DE63300545D0F /* ClusteringExample.m in Sources */,
+ 3EBCD7171DC28240001E342F /* CalloutDelegateUsageExample.swift in Sources */,
+ 64BBDAFD1DF24DEB00BB705D /* RuntimeMultipleAnnotationsExample.m in Sources */,
+ 646B62AE1DEF7155000AA523 /* RuntimeAddLineExample.swift in Sources */,
+ 3EBCD71F1DC28240001E342F /* DefaultStylesExample.swift in Sources */,
+ DD5939E41E6639BA0009BEB2 /* ClusteringExample.swift in Sources */,
+ 9682471A1C5C115000494AB8 /* DrawingAGeoJSONLineExample.m in Sources */,
+ 64CF970C1DF224C500C3C27B /* SourceCustomVectorExample.m in Sources */,
+ 969E7FDD1D25C31700663F84 /* UserTrackingModesExample.m in Sources */,
+ 646B62A41DEF7115000AA523 /* RuntimeAddLineExample.m in Sources */,
+ 968247271C5C1DC700494AB8 /* CameraAnimationExample.m in Sources */,
+ 961962D51C583FDC002D3DAB /* ExamplesContainerViewController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 961962A11C581700002D3DAB /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 961962AA1C581700002D3DAB /* ExamplesTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 961962AC1C581700002D3DAB /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 961962B51C581700002D3DAB /* ExamplesUITests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 961962A71C581700002D3DAB /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 9619628B1C581700002D3DAB /* Examples */;
+ targetProxy = 961962A61C581700002D3DAB /* PBXContainerItemProxy */;
+ };
+ 961962B21C581700002D3DAB /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 9619628B1C581700002D3DAB /* Examples */;
+ targetProxy = 961962B11C581700002D3DAB /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 9619629D1C581700002D3DAB /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 9619629E1C581700002D3DAB /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 961962B71C581700002D3DAB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 961962B81C581700002D3DAB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 961962BA1C581700002D3DAB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 03CC5D45DBD04AB716469E7B /* Pods-Examples.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ DEVELOPMENT_TEAM = GJZR2MEM28;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)",
+ );
+ INFOPLIST_FILE = Examples/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.Examples;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "Examples/Examples-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ 961962BB1C581700002D3DAB /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 29A0D7C8DCD539DCA5DA1BAC /* Pods-Examples.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ DEVELOPMENT_TEAM = GJZR2MEM28;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)",
+ );
+ INFOPLIST_FILE = Examples/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.Examples;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "Examples/Examples-Bridging-Header.h";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+ 961962BD1C581700002D3DAB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 589ABF8859560819F8B431C7 /* Pods-ExamplesTests.debug.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ DEVELOPMENT_TEAM = GJZR2MEM28;
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = ExamplesTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.ExamplesTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Examples.app/Examples";
+ };
+ name = Debug;
+ };
+ 961962BE1C581700002D3DAB /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7556D44879C1E2866B0355B8 /* Pods-ExamplesTests.release.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ DEVELOPMENT_TEAM = GJZR2MEM28;
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = ExamplesTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.ExamplesTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Examples.app/Examples";
+ };
+ name = Release;
+ };
+ 961962C01C581700002D3DAB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0A4917D6B62E749D739044A4 /* Pods-ExamplesUITests.debug.xcconfig */;
+ buildSettings = {
+ DEVELOPMENT_TEAM = GJZR2MEM28;
+ INFOPLIST_FILE = ExamplesUITests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.ExamplesUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_TARGET_NAME = Examples;
+ };
+ name = Debug;
+ };
+ 961962C11C581700002D3DAB /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = E0520BEE090DE0364897BAF3 /* Pods-ExamplesUITests.release.xcconfig */;
+ buildSettings = {
+ DEVELOPMENT_TEAM = GJZR2MEM28;
+ INFOPLIST_FILE = ExamplesUITests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.ExamplesUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_TARGET_NAME = Examples;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 961962871C581700002D3DAB /* Build configuration list for PBXProject "Examples" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 961962B71C581700002D3DAB /* Debug */,
+ 961962B81C581700002D3DAB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 961962B91C581700002D3DAB /* Build configuration list for PBXNativeTarget "Examples" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 961962BA1C581700002D3DAB /* Debug */,
+ 961962BB1C581700002D3DAB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 961962BC1C581700002D3DAB /* Build configuration list for PBXNativeTarget "ExamplesTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 961962BD1C581700002D3DAB /* Debug */,
+ 961962BE1C581700002D3DAB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 961962BF1C581700002D3DAB /* Build configuration list for PBXNativeTarget "ExamplesUITests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 961962C01C581700002D3DAB /* Debug */,
+ 961962C11C581700002D3DAB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 961962841C581700002D3DAB /* Project object */;
+}
diff --git a/platform/ios/demo/Examples.xcodeproj/xcshareddata/xcschemes/Examples.xcscheme b/platform/ios/demo/Examples.xcodeproj/xcshareddata/xcschemes/Examples.xcscheme
new file mode 100644
index 0000000000..0c979263bd
--- /dev/null
+++ b/platform/ios/demo/Examples.xcodeproj/xcshareddata/xcschemes/Examples.xcscheme
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0820"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "9619628B1C581700002D3DAB"
+ BuildableName = "Examples.app"
+ BlueprintName = "Examples"
+ ReferencedContainer = "container:Examples.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "961962A41C581700002D3DAB"
+ BuildableName = "ExamplesTests.xctest"
+ BlueprintName = "ExamplesTests"
+ ReferencedContainer = "container:Examples.xcodeproj">
+ </BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "ExamplesTests">
+ </Test>
+ </SkippedTests>
+ </TestableReference>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "961962AF1C581700002D3DAB"
+ BuildableName = "ExamplesUITests.xctest"
+ BlueprintName = "ExamplesUITests"
+ ReferencedContainer = "container:Examples.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "9619628B1C581700002D3DAB"
+ BuildableName = "Examples.app"
+ BlueprintName = "Examples"
+ ReferencedContainer = "container:Examples.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "9619628B1C581700002D3DAB"
+ BuildableName = "Examples.app"
+ BlueprintName = "Examples"
+ ReferencedContainer = "container:Examples.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "9619628B1C581700002D3DAB"
+ BuildableName = "Examples.app"
+ BlueprintName = "Examples"
+ ReferencedContainer = "container:Examples.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/platform/ios/demo/Examples/AppDelegate.h b/platform/ios/demo/Examples/AppDelegate.h
new file mode 100644
index 0000000000..b47f3333b7
--- /dev/null
+++ b/platform/ios/demo/Examples/AppDelegate.h
@@ -0,0 +1,16 @@
+//
+// AppDelegate.h
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
diff --git a/platform/ios/demo/Examples/AppDelegate.m b/platform/ios/demo/Examples/AppDelegate.m
new file mode 100644
index 0000000000..09fe73a4b6
--- /dev/null
+++ b/platform/ios/demo/Examples/AppDelegate.m
@@ -0,0 +1,25 @@
+//
+// AppDelegate.m
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Speed-up Core Animation-based animations in testing scenarios.
+ if ([[NSProcessInfo processInfo].arguments containsObject:@"useFastAnimations"]) {
+ self.window.layer.speed = 100;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Contents.json b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..012da9b7c9
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,191 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-Small-1.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-Small@2x-1.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-Small@3x-1.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-Spotlight-40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-Spotlight-40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "57x57",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "57x57",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-Small.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-Small@2x-2.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-Spotlight-40.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-Spotlight-40@2x-1.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "50x50",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "50x50",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "72x72",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "72x72",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-76.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-iPadPro@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "24x24",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "notificationCenter",
+ "subtype" : "38mm"
+ },
+ {
+ "size" : "27.5x27.5",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "notificationCenter",
+ "subtype" : "42mm"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "watch",
+ "filename" : "Icon-Small@2x.png",
+ "role" : "companionSettings",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "watch",
+ "filename" : "Icon-Small@3x.png",
+ "role" : "companionSettings",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "appLauncher",
+ "subtype" : "38mm"
+ },
+ {
+ "size" : "86x86",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "quickLook",
+ "subtype" : "38mm"
+ },
+ {
+ "size" : "98x98",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "quickLook",
+ "subtype" : "42mm"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
new file mode 100644
index 0000000000..aefb928104
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
new file mode 100644
index 0000000000..4011249fb9
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76.png
new file mode 100644
index 0000000000..5a1e0ff326
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
new file mode 100644
index 0000000000..4a30b02e38
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small-1.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small-1.png
new file mode 100644
index 0000000000..2511fc0a91
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small-1.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
new file mode 100644
index 0000000000..2511fc0a91
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
new file mode 100644
index 0000000000..3321cc8258
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-2.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-2.png
new file mode 100644
index 0000000000..3321cc8258
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x-2.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
new file mode 100644
index 0000000000..3321cc8258
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x-1.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x-1.png
new file mode 100644
index 0000000000..0bf7e1dfa7
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x-1.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
new file mode 100644
index 0000000000..0bf7e1dfa7
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png
new file mode 100644
index 0000000000..5d63f4a7d8
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png
new file mode 100644
index 0000000000..d757ece31b
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png
new file mode 100644
index 0000000000..d757ece31b
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png
new file mode 100644
index 0000000000..2aaba74c0c
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png
new file mode 100644
index 0000000000..097919f85b
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/Contents.json b/platform/ios/demo/Examples/Assets.xcassets/Contents.json
new file mode 100644
index 0000000000..da4a164c91
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Contents.json b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Contents.json
new file mode 100644
index 0000000000..3180889574
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "Test Tube.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "Test Tube@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "Test Tube@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube.png b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube.png
new file mode 100644
index 0000000000..3a9d9650f9
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@2x.png b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@2x.png
new file mode 100644
index 0000000000..cd14e35c80
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@2x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@3x.png b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@3x.png
new file mode 100644
index 0000000000..3688ad20dc
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/Test Tube.imageset/Test Tube@3x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/Contents.json b/platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/Contents.json
new file mode 100644
index 0000000000..827eeebc86
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "attraction.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/attraction.png b/platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/attraction.png
new file mode 100644
index 0000000000..cc2f314989
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/attraction.imageset/attraction.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/Contents.json b/platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/Contents.json
new file mode 100644
index 0000000000..c6d31dea4c
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "lighthouse.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/lighthouse.png b/platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/lighthouse.png
new file mode 100644
index 0000000000..1c253e7599
--- /dev/null
+++ b/platform/ios/demo/Examples/Assets.xcassets/lighthouse.imageset/lighthouse.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Base.lproj/LaunchScreen.storyboard b/platform/ios/demo/Examples/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000000..7afa0a6096
--- /dev/null
+++ b/platform/ios/demo/Examples/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10102" systemVersion="15E33e" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10080"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+ <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Test Tube" translatesAutoresizingMaskIntoConstraints="NO" id="AbD-sU-4bw">
+ <rect key="frame" x="280" y="233" width="41" height="133"/>
+ </imageView>
+ </subviews>
+ <color key="backgroundColor" red="0.23137254901960785" green="0.69803921568627447" blue="0.81568627450980391" alpha="1" colorSpace="calibratedRGB"/>
+ <constraints>
+ <constraint firstItem="AbD-sU-4bw" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="BSX-0I-k9C"/>
+ <constraint firstItem="AbD-sU-4bw" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="P10-1k-0uJ"/>
+ </constraints>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+ <resources>
+ <image name="Test Tube" width="41" height="133"/>
+ </resources>
+</document>
diff --git a/platform/ios/demo/Examples/Examples-Bridging-Header.h b/platform/ios/demo/Examples/Examples-Bridging-Header.h
new file mode 100644
index 0000000000..1b2cb5d6d0
--- /dev/null
+++ b/platform/ios/demo/Examples/Examples-Bridging-Header.h
@@ -0,0 +1,4 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
diff --git a/platform/ios/demo/Examples/Examples.h b/platform/ios/demo/Examples/Examples.h
new file mode 100644
index 0000000000..1774d45291
--- /dev/null
+++ b/platform/ios/demo/Examples/Examples.h
@@ -0,0 +1,57 @@
+//
+// Examples.h
+// Examples
+//
+// Created by Jason Wray on 1/28/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+// Steps to add a new example:
+// 1. Add `MBXExample...` string constant in NewExample.m, defined as the name of the example view controller's class
+// 2. Add matching external string constant below
+// 3. Add this constant to +list in Examples.m
+// 4. Create NewExample.swift (otherwise Swift is handled automatically)
+
+extern NSString *const MBXExampleAnnotationView;
+extern NSString *const MBXExampleAnnotationViewMultiple;
+extern NSString *const MBXExampleAnnotationViewMultiple;
+extern NSString *const MBXExampleBlockingGesturesDelegate;
+extern NSString *const MBXExampleCalloutDelegateUsage;
+extern NSString *const MBXExampleCameraAnimation;
+extern NSString *const MBXExampleCameraFlyTo;
+extern NSString *const MBXExampleCustomAnnotationModel;
+extern NSString *const MBXExampleCustomCalloutView;
+extern NSString *const MBXExampleClustering;
+extern NSString *const MBXExampleCustomRasterStyle;
+extern NSString *const MBXExampleCustomStyle;
+extern NSString *const MBXExampleDDSCircleLayer;
+extern NSString *const MBXExampleDDSLayerSelection;
+extern NSString *const MBXExampleDefaultStyles;
+extern NSString *const MBXExampleDraggableAnnotationView;
+extern NSString *const MBXExampleDrawingAGeoJSONLine;
+extern NSString *const MBXExampleDrawingACustomMarker;
+extern NSString *const MBXExampleDrawingAMarker;
+extern NSString *const MBXExampleDrawingAPolygon;
+extern NSString *const MBXExample3DExtrusions;
+extern NSString *const MBXExampleOfflinePack;
+extern NSString *const MBXExamplePointConversion;
+extern NSString *const MBXExampleRuntimeAddLine;
+extern NSString *const MBXExampleRuntimeAnimateLine;
+extern NSString *const MBXExampleRuntimeCircleStyles;
+extern NSString *const MBXExampleRuntimeToggleLayer;
+extern NSString *const MBXExampleRuntimeMultipleAnnotations;
+extern NSString *const MBXExampleSatelliteStyle;
+extern NSString *const MBXExampleSelectFeature;
+extern NSString *const MBXExampleShapeCollectionFeature;
+extern NSString *const MBXExampleSimpleMapView;
+extern NSString *const MBXExampleSourceCustomRaster;
+extern NSString *const MBXExampleSourceCustomVector;
+extern NSString *const MBXExampleUserTrackingModes;
+
+@interface Examples : NSObject
+
++ (NSArray *)list;
+
+@end
diff --git a/platform/ios/demo/Examples/Examples.m b/platform/ios/demo/Examples/Examples.m
new file mode 100644
index 0000000000..73a833401a
--- /dev/null
+++ b/platform/ios/demo/Examples/Examples.m
@@ -0,0 +1,64 @@
+//
+// Examples.m
+// Examples
+//
+// Created by Jason Wray on 1/28/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import "Examples.h"
+
+@implementation Examples
+
++ (NSArray *)list {
+
+ NSArray *initialList = [[NSMutableArray alloc] initWithArray:@[
+ MBXExampleAnnotationView,
+ MBXExampleAnnotationViewMultiple,
+ MBXExampleBlockingGesturesDelegate,
+ MBXExampleCalloutDelegateUsage,
+ MBXExampleCameraAnimation,
+ MBXExampleCameraFlyTo,
+ MBXExampleCustomAnnotationModel,
+ MBXExampleCustomCalloutView,
+ MBXExampleClustering,
+ MBXExampleCustomRasterStyle,
+ MBXExampleCustomStyle,
+ MBXExampleDDSCircleLayer,
+ MBXExampleDDSLayerSelection,
+ MBXExampleDefaultStyles,
+ MBXExampleDraggableAnnotationView,
+ MBXExampleDrawingAGeoJSONLine,
+ MBXExampleDrawingACustomMarker,
+ MBXExampleDrawingAMarker,
+ MBXExampleDrawingAPolygon,
+ MBXExample3DExtrusions,
+ MBXExampleOfflinePack,
+ MBXExamplePointConversion,
+ MBXExampleRuntimeAddLine,
+ MBXExampleRuntimeAnimateLine,
+ MBXExampleRuntimeCircleStyles,
+ MBXExampleRuntimeToggleLayer,
+ MBXExampleRuntimeMultipleAnnotations,
+ MBXExampleSatelliteStyle,
+ MBXExampleSelectFeature,
+ MBXExampleShapeCollectionFeature,
+ MBXExampleSimpleMapView,
+ MBXExampleSourceCustomRaster,
+ MBXExampleSourceCustomVector,
+ MBXExampleUserTrackingModes,
+ ]];
+
+ NSMutableArray *meh = [[NSMutableArray alloc] init];
+
+ [initialList enumerateObjectsUsingBlock:^(NSString *objcName, NSUInteger index, BOOL *stop) {
+ NSString *swiftName = [NSString stringWithFormat:@"%@_Swift", objcName];
+
+ [meh insertObject:swiftName atIndex:index*2];
+ [meh insertObject:objcName atIndex:index*2];
+ }];
+
+ return [meh copy];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ExamplesContainerViewController.h b/platform/ios/demo/Examples/ExamplesContainerViewController.h
new file mode 100644
index 0000000000..1567039410
--- /dev/null
+++ b/platform/ios/demo/Examples/ExamplesContainerViewController.h
@@ -0,0 +1,15 @@
+//
+// ExamplesContainerViewController.h
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ExamplesContainerViewController : UIViewController
+
+@property (nonatomic) NSString *exampleToLoad;
+
+@end
diff --git a/platform/ios/demo/Examples/ExamplesContainerViewController.m b/platform/ios/demo/Examples/ExamplesContainerViewController.m
new file mode 100644
index 0000000000..3f1361b316
--- /dev/null
+++ b/platform/ios/demo/Examples/ExamplesContainerViewController.m
@@ -0,0 +1,41 @@
+//
+// ExamplesContainerViewController.m
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import "ExamplesContainerViewController.h"
+
+@interface ExamplesContainerViewController ()
+
+@end
+@implementation ExamplesContainerViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.title = self.exampleToLoad ?: @"Example Not Specified";
+
+ if (NSClassFromString(self.exampleToLoad)) {
+ UIViewController *childViewController = [[NSClassFromString(self.exampleToLoad) alloc] init];
+ [self addChildViewController:childViewController];
+ [self.view addSubview:childViewController.view];
+ [childViewController didMoveToParentViewController:self];
+ } else {
+ UILabel *exampleNotFoundLabel = [[UILabel alloc] initWithFrame:self.view.frame];
+ exampleNotFoundLabel.text = @"Example not found";
+ exampleNotFoundLabel.font = [UIFont systemFontOfSize:72.f];
+ exampleNotFoundLabel.adjustsFontSizeToFitWidth = YES;
+ exampleNotFoundLabel.textAlignment = NSTextAlignmentCenter;
+ exampleNotFoundLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ exampleNotFoundLabel.backgroundColor = [UIColor redColor];
+ [self.view addSubview:exampleNotFoundLabel];
+ }
+
+ self.navigationController.hidesBarsOnSwipe = YES;
+ self.navigationController.hidesBarsWhenVerticallyCompact = YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ExamplesTableViewController.h b/platform/ios/demo/Examples/ExamplesTableViewController.h
new file mode 100644
index 0000000000..5b3255e228
--- /dev/null
+++ b/platform/ios/demo/Examples/ExamplesTableViewController.h
@@ -0,0 +1,13 @@
+//
+// ExamplesTableViewController.h
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ExamplesTableViewController : UITableViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ExamplesTableViewController.m b/platform/ios/demo/Examples/ExamplesTableViewController.m
new file mode 100644
index 0000000000..210357050a
--- /dev/null
+++ b/platform/ios/demo/Examples/ExamplesTableViewController.m
@@ -0,0 +1,76 @@
+//
+// ExamplesTableViewController.m
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import "ExamplesTableViewController.h"
+#import "Examples.h"
+#import "ExamplesContainerViewController.h"
+
+NSString *const MBXSegueTableToExample = @"TableToExampleSegue";
+
+@interface ExamplesTableViewController ()
+
+@property (nonatomic) NSArray *examples;
+
+@end
+@implementation ExamplesTableViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil];
+
+ // do this ourselves, as automatic doesn't work with fast swipes
+ self.clearsSelectionOnViewWillAppear = NO;
+
+ // testing: explicitly jump to an example, later defined in prepareForSegue
+ //[self performSegueWithIdentifier:MBXSegueTableToExample sender:self];
+}
+
+-(void)viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+ [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (!self.examples) {
+ self.examples = [Examples list];
+ }
+
+ return self.examples.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ExampleCell" forIndexPath:indexPath];
+
+ cell.textLabel.text = self.examples[indexPath.row];
+
+ return cell;
+}
+
+#pragma mark - Navigation
+
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+ if ([segue.identifier isEqualToString:MBXSegueTableToExample]) {
+ if ([sender isKindOfClass:[UITableViewCell class]]) {
+ UITableViewCell *senderCell = sender;
+ ExamplesContainerViewController *destinationVC = [segue destinationViewController];
+ destinationVC.exampleToLoad = senderCell.textLabel.text;
+ } /* else {
+ ExamplesContainerViewController *destinationVC = [segue destinationViewController];
+ destinationVC.exampleToLoad = MBXExampleOfflinePack;
+ } */
+ }
+}
+
+@end
diff --git a/platform/ios/demo/Examples/Files/camera.xcassets/Contents.json b/platform/ios/demo/Examples/Files/camera.xcassets/Contents.json
new file mode 100644
index 0000000000..da4a164c91
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/camera.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/Contents.json b/platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/Contents.json
new file mode 100644
index 0000000000..086a6371b6
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "camera.pdf",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/camera.pdf b/platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/camera.pdf
new file mode 100644
index 0000000000..af12e79a28
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/camera.xcassets/camera.imageset/camera.pdf
Binary files differ
diff --git a/platform/ios/demo/Examples/Files/clustering.xcassets/Contents.json b/platform/ios/demo/Examples/Files/clustering.xcassets/Contents.json
new file mode 100644
index 0000000000..da4a164c91
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/clustering.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/Contents.json b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/Contents.json
new file mode 100644
index 0000000000..fb2c623d9b
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "port.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "port@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "port@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port.png b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port.png
new file mode 100644
index 0000000000..6f62cf6544
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@2x.png b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@2x.png
new file mode 100644
index 0000000000..fb18777a17
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@2x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@3x.png b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@3x.png
new file mode 100644
index 0000000000..a50512cd59
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/clustering.xcassets/port.imageset/port@3x.png
Binary files differ
diff --git a/platform/ios/demo/Examples/Files/example.geojson b/platform/ios/demo/Examples/Files/example.geojson
new file mode 100644
index 0000000000..a8df362ba3
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/example.geojson
@@ -0,0 +1,308 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Crema to Council Crest"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -122.63748,
+ 45.52214
+ ],
+ [
+ -122.64855,
+ 45.52218
+ ],
+ [
+ -122.6545,
+ 45.52219
+ ],
+ [
+ -122.65497,
+ 45.52196
+ ],
+ [
+ -122.65631,
+ 45.52104
+ ],
+ [
+ -122.6578,
+ 45.51935
+ ],
+ [
+ -122.65867,
+ 45.51848
+ ],
+ [
+ -122.65872,
+ 45.51293
+ ],
+ [
+ -122.66576,
+ 45.51295
+ ],
+ [
+ -122.66745,
+ 45.51252
+ ],
+ [
+ -122.66813,
+ 45.51244
+ ],
+ [
+ -122.67359,
+ 45.51385
+ ],
+ [
+ -122.67415,
+ 45.51406
+ ],
+ [
+ -122.67481,
+ 45.51484
+ ],
+ [
+ -122.676,
+ 45.51532
+ ],
+ [
+ -122.68106,
+ 45.51668
+ ],
+ [
+ -122.68503,
+ 45.50934
+ ],
+ [
+ -122.68546,
+ 45.50858
+ ],
+ [
+ -122.6852,
+ 45.50783
+ ],
+ [
+ -122.68424,
+ 45.50714
+ ],
+ [
+ -122.68433,
+ 45.50585
+ ],
+ [
+ -122.68429,
+ 45.50521
+ ],
+ [
+ -122.68456,
+ 45.50445
+ ],
+ [
+ -122.68538,
+ 45.50371
+ ],
+ [
+ -122.68653,
+ 45.50311
+ ],
+ [
+ -122.68731,
+ 45.50292
+ ],
+ [
+ -122.68742,
+ 45.50253
+ ],
+ [
+ -122.6867,
+ 45.50239
+ ],
+ [
+ -122.68545,
+ 45.5026
+ ],
+ [
+ -122.68407,
+ 45.50294
+ ],
+ [
+ -122.68357,
+ 45.50271
+ ],
+ [
+ -122.68236,
+ 45.50055
+ ],
+ [
+ -122.68233,
+ 45.49994
+ ],
+ [
+ -122.68267,
+ 45.49955
+ ],
+ [
+ -122.68257,
+ 45.49919
+ ],
+ [
+ -122.68376,
+ 45.49842
+ ],
+ [
+ -122.68428,
+ 45.49821
+ ],
+ [
+ -122.68573,
+ 45.49798
+ ],
+ [
+ -122.68923,
+ 45.49805
+ ],
+ [
+ -122.68926,
+ 45.49857
+ ],
+ [
+ -122.68814,
+ 45.49911
+ ],
+ [
+ -122.68865,
+ 45.49921
+ ],
+ [
+ -122.6897,
+ 45.49905
+ ],
+ [
+ -122.69346,
+ 45.49917
+ ],
+ [
+ -122.69404,
+ 45.49902
+ ],
+ [
+ -122.69438,
+ 45.49796
+ ],
+ [
+ -122.69504,
+ 45.49697
+ ],
+ [
+ -122.69624,
+ 45.49661
+ ],
+ [
+ -122.69781,
+ 45.4955
+ ],
+ [
+ -122.69803,
+ 45.49517
+ ],
+ [
+ -122.69711,
+ 45.49508
+ ],
+ [
+ -122.69688,
+ 45.4948
+ ],
+ [
+ -122.69744,
+ 45.49368
+ ],
+ [
+ -122.69702,
+ 45.49311
+ ],
+ [
+ -122.69665,
+ 45.49294
+ ],
+ [
+ -122.69788,
+ 45.49212
+ ],
+ [
+ -122.69771,
+ 45.49264
+ ],
+ [
+ -122.69835,
+ 45.49332
+ ],
+ [
+ -122.7007,
+ 45.49334
+ ],
+ [
+ -122.70167,
+ 45.49358
+ ],
+ [
+ -122.70215,
+ 45.49401
+ ],
+ [
+ -122.70229,
+ 45.49439
+ ],
+ [
+ -122.70185,
+ 45.49566
+ ],
+ [
+ -122.70215,
+ 45.49635
+ ],
+ [
+ -122.70346,
+ 45.49674
+ ],
+ [
+ -122.70517,
+ 45.49758
+ ],
+ [
+ -122.70614,
+ 45.49736
+ ],
+ [
+ -122.70663,
+ 45.49736
+ ],
+ [
+ -122.70807,
+ 45.49767
+ ],
+ [
+ -122.70807,
+ 45.49798
+ ],
+ [
+ -122.70717,
+ 45.49798
+ ],
+ [
+ -122.70713,
+ 45.4984
+ ],
+ [
+ -122.70774,
+ 45.49893
+ ]
+ ]
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/metro-line.geojson b/platform/ios/demo/Examples/Files/metro-line.geojson
new file mode 100644
index 0000000000..0eebea726f
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/metro-line.geojson
@@ -0,0 +1,4370 @@
+{
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Takoma",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.018178,
+ 38.976086
+ ],
+ "type": "Point"
+ },
+ "id": "0ae7fd895624cc8f53d8d7a7e1266d26"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Brookland-CUA",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -76.994536,
+ 38.933218
+ ],
+ "type": "Point"
+ },
+ "id": "186e133e182f046b1e23b742b52000c4"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Friendship Heights",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.084998,
+ 38.959491
+ ],
+ "type": "Point"
+ },
+ "id": "2d9e49375605d7e80bb5fe0184f57421"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Fort Totten",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.002205,
+ 38.951854
+ ],
+ "type": "Point"
+ },
+ "id": "4d8934c588b5b3a49df98e8b405ffa92"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Tenleytown-AU",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.079589,
+ 38.948859
+ ],
+ "type": "Point"
+ },
+ "id": "5a8b14c4fd539a8a04713264f1d3a5eb"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Judiciary Sq",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.016641,
+ 38.896098
+ ],
+ "type": "Point"
+ },
+ "id": "5d0ef0a0bcd98b436545bbdc83c95c8c"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Woodley Park-Zoo Adams Morgan",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.05242,
+ 38.925092
+ ],
+ "type": "Point"
+ },
+ "id": "6d570a86a953fb761551644cfb21b2a4"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Rhode Island Ave",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -76.995939,
+ 38.921067
+ ],
+ "type": "Point"
+ },
+ "id": "7da63d4a9af4cf3f7ab04f36a26a0aa5"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Union Station",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.007416,
+ 38.897773
+ ],
+ "type": "Point"
+ },
+ "id": "8a43ffb29f3e1146e19e15d3291ab840"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Van Ness-UDC",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.062988,
+ 38.943273
+ ],
+ "type": "Point"
+ },
+ "id": "96a659edc000c1267f5f44c36b87b201"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Dupont Circle",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.043416,
+ 38.909605
+ ],
+ "type": "Point"
+ },
+ "id": "994446c244acadeb15d3f9fc18278c73"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Metro Center",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.02808,
+ 38.898322
+ ],
+ "type": "Point"
+ },
+ "id": "b82be4037a512e9ca43335ec6c0caf44"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Farragut North",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.039703,
+ 38.903209
+ ],
+ "type": "Point"
+ },
+ "id": "ba844cf983f766faeebd9dd35950be57"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Cleveland Park",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.058044,
+ 38.93477
+ ],
+ "type": "Point"
+ },
+ "id": "c2274c3347ca230ab96afbc7021e3192"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Gallery Pl-Chinatown",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.021917,
+ 38.898324
+ ],
+ "type": "Point"
+ },
+ "id": "ca44b6b9141375e291b1fd9bc243b4e3"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "NoMa - Gallaudet U",
+ "TYPE": "Station"
+ },
+ "geometry": {
+ "coordinates": [
+ -77.003022,
+ 38.907024
+ ],
+ "type": "Point"
+ },
+ "id": "d0d9099ecafaf63d973e88b635998815"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "NAME": "Red",
+ "TYPE": "Rail line"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ -77.020294,
+ 38.979839
+ ],
+ [
+ -77.020057,
+ 38.979409
+ ],
+ [
+ -77.019948,
+ 38.979213
+ ],
+ [
+ -77.019934,
+ 38.979188
+ ],
+ [
+ -77.01992,
+ 38.979163
+ ],
+ [
+ -77.019906,
+ 38.979138
+ ],
+ [
+ -77.019893,
+ 38.979112
+ ],
+ [
+ -77.019879,
+ 38.979087
+ ],
+ [
+ -77.019865,
+ 38.979062
+ ],
+ [
+ -77.019851,
+ 38.979037
+ ],
+ [
+ -77.019837,
+ 38.979012
+ ],
+ [
+ -77.019823,
+ 38.978986
+ ],
+ [
+ -77.019809,
+ 38.978961
+ ],
+ [
+ -77.019708,
+ 38.978774
+ ],
+ [
+ -77.019695,
+ 38.978749
+ ],
+ [
+ -77.019681,
+ 38.978723
+ ],
+ [
+ -77.019667,
+ 38.978698
+ ],
+ [
+ -77.019654,
+ 38.978673
+ ],
+ [
+ -77.01964,
+ 38.978647
+ ],
+ [
+ -77.019627,
+ 38.978622
+ ],
+ [
+ -77.019614,
+ 38.978597
+ ],
+ [
+ -77.0196,
+ 38.978571
+ ],
+ [
+ -77.019587,
+ 38.978546
+ ],
+ [
+ -77.019573,
+ 38.97852
+ ],
+ [
+ -77.019238,
+ 38.977889
+ ],
+ [
+ -77.019225,
+ 38.977863
+ ],
+ [
+ -77.019211,
+ 38.977838
+ ],
+ [
+ -77.019198,
+ 38.977813
+ ],
+ [
+ -77.019185,
+ 38.977787
+ ],
+ [
+ -77.019171,
+ 38.977762
+ ],
+ [
+ -77.019158,
+ 38.977737
+ ],
+ [
+ -77.019144,
+ 38.977711
+ ],
+ [
+ -77.019131,
+ 38.977686
+ ],
+ [
+ -77.019117,
+ 38.977661
+ ],
+ [
+ -77.019103,
+ 38.977635
+ ],
+ [
+ -77.018905,
+ 38.977272
+ ],
+ [
+ -77.018891,
+ 38.977246
+ ],
+ [
+ -77.018877,
+ 38.977221
+ ],
+ [
+ -77.018863,
+ 38.977196
+ ],
+ [
+ -77.018849,
+ 38.977171
+ ],
+ [
+ -77.018835,
+ 38.977146
+ ],
+ [
+ -77.018821,
+ 38.977121
+ ],
+ [
+ -77.018806,
+ 38.977096
+ ],
+ [
+ -77.018792,
+ 38.97707
+ ],
+ [
+ -77.018778,
+ 38.977045
+ ],
+ [
+ -77.018764,
+ 38.97702
+ ],
+ [
+ -77.018614,
+ 38.976753
+ ],
+ [
+ -77.017765,
+ 38.975244
+ ],
+ [
+ -77.01768,
+ 38.975092
+ ],
+ [
+ -77.017666,
+ 38.975067
+ ],
+ [
+ -77.017652,
+ 38.975042
+ ],
+ [
+ -77.017638,
+ 38.975017
+ ],
+ [
+ -77.017624,
+ 38.974992
+ ],
+ [
+ -77.017609,
+ 38.974967
+ ],
+ [
+ -77.017595,
+ 38.974942
+ ],
+ [
+ -77.017581,
+ 38.974916
+ ],
+ [
+ -77.017567,
+ 38.974891
+ ],
+ [
+ -77.017553,
+ 38.974866
+ ],
+ [
+ -77.017538,
+ 38.974841
+ ],
+ [
+ -77.017248,
+ 38.974343
+ ],
+ [
+ -77.017233,
+ 38.974318
+ ],
+ [
+ -77.017218,
+ 38.974293
+ ],
+ [
+ -77.017204,
+ 38.974268
+ ],
+ [
+ -77.017189,
+ 38.974243
+ ],
+ [
+ -77.017174,
+ 38.974218
+ ],
+ [
+ -77.017159,
+ 38.974193
+ ],
+ [
+ -77.017144,
+ 38.974169
+ ],
+ [
+ -77.017129,
+ 38.974144
+ ],
+ [
+ -77.017114,
+ 38.974119
+ ],
+ [
+ -77.017099,
+ 38.974094
+ ],
+ [
+ -77.01694,
+ 38.97383
+ ],
+ [
+ -77.016925,
+ 38.973805
+ ],
+ [
+ -77.01691,
+ 38.97378
+ ],
+ [
+ -77.016895,
+ 38.973755
+ ],
+ [
+ -77.01688,
+ 38.973731
+ ],
+ [
+ -77.016865,
+ 38.973706
+ ],
+ [
+ -77.01685,
+ 38.973681
+ ],
+ [
+ -77.016835,
+ 38.973656
+ ],
+ [
+ -77.01682,
+ 38.973631
+ ],
+ [
+ -77.016805,
+ 38.973606
+ ],
+ [
+ -77.01679,
+ 38.973581
+ ],
+ [
+ -77.016499,
+ 38.97308
+ ],
+ [
+ -77.016484,
+ 38.973055
+ ],
+ [
+ -77.01647,
+ 38.97303
+ ],
+ [
+ -77.016456,
+ 38.973005
+ ],
+ [
+ -77.016442,
+ 38.97298
+ ],
+ [
+ -77.016428,
+ 38.972955
+ ],
+ [
+ -77.016413,
+ 38.97293
+ ],
+ [
+ -77.016399,
+ 38.972904
+ ],
+ [
+ -77.016385,
+ 38.972879
+ ],
+ [
+ -77.016371,
+ 38.972854
+ ],
+ [
+ -77.016357,
+ 38.972829
+ ],
+ [
+ -77.014078,
+ 38.968776
+ ],
+ [
+ -77.014036,
+ 38.9687
+ ],
+ [
+ -77.013993,
+ 38.968625
+ ],
+ [
+ -77.013951,
+ 38.968549
+ ],
+ [
+ -77.013908,
+ 38.968474
+ ],
+ [
+ -77.013864,
+ 38.968399
+ ],
+ [
+ -77.013821,
+ 38.968323
+ ],
+ [
+ -77.013777,
+ 38.968248
+ ],
+ [
+ -77.013732,
+ 38.968174
+ ],
+ [
+ -77.013687,
+ 38.968099
+ ],
+ [
+ -77.013641,
+ 38.968024
+ ],
+ [
+ -77.013447,
+ 38.967726
+ ],
+ [
+ -77.013242,
+ 38.967432
+ ],
+ [
+ -77.013024,
+ 38.967143
+ ],
+ [
+ -77.012795,
+ 38.96686
+ ],
+ [
+ -77.012555,
+ 38.966583
+ ],
+ [
+ -77.012304,
+ 38.966312
+ ],
+ [
+ -77.012041,
+ 38.966047
+ ],
+ [
+ -77.011769,
+ 38.965789
+ ],
+ [
+ -77.0117,
+ 38.965726
+ ],
+ [
+ -77.01163,
+ 38.965664
+ ],
+ [
+ -77.01156,
+ 38.965602
+ ],
+ [
+ -77.01149,
+ 38.96554
+ ],
+ [
+ -77.011419,
+ 38.965479
+ ],
+ [
+ -77.011348,
+ 38.965418
+ ],
+ [
+ -77.011277,
+ 38.965357
+ ],
+ [
+ -77.011205,
+ 38.965296
+ ],
+ [
+ -77.011134,
+ 38.965236
+ ],
+ [
+ -77.011062,
+ 38.965175
+ ],
+ [
+ -77.008385,
+ 38.962908
+ ],
+ [
+ -77.008326,
+ 38.962857
+ ],
+ [
+ -77.008266,
+ 38.962807
+ ],
+ [
+ -77.008207,
+ 38.962756
+ ],
+ [
+ -77.008148,
+ 38.962706
+ ],
+ [
+ -77.008089,
+ 38.962655
+ ],
+ [
+ -77.00803,
+ 38.962604
+ ],
+ [
+ -77.007971,
+ 38.962553
+ ],
+ [
+ -77.007912,
+ 38.962502
+ ],
+ [
+ -77.007854,
+ 38.962451
+ ],
+ [
+ -77.007796,
+ 38.9624
+ ],
+ [
+ -77.007463,
+ 38.962091
+ ],
+ [
+ -77.007143,
+ 38.961775
+ ],
+ [
+ -77.006835,
+ 38.96145
+ ],
+ [
+ -77.006542,
+ 38.961118
+ ],
+ [
+ -77.006262,
+ 38.960779
+ ],
+ [
+ -77.005996,
+ 38.960433
+ ],
+ [
+ -77.005745,
+ 38.96008
+ ],
+ [
+ -77.005509,
+ 38.959721
+ ],
+ [
+ -77.005288,
+ 38.959356
+ ],
+ [
+ -77.005081,
+ 38.958986
+ ],
+ [
+ -77.004891,
+ 38.958611
+ ],
+ [
+ -77.004716,
+ 38.958232
+ ],
+ [
+ -77.004687,
+ 38.958167
+ ],
+ [
+ -77.00466,
+ 38.958102
+ ],
+ [
+ -77.004632,
+ 38.958037
+ ],
+ [
+ -77.004605,
+ 38.957972
+ ],
+ [
+ -77.004578,
+ 38.957906
+ ],
+ [
+ -77.004552,
+ 38.957841
+ ],
+ [
+ -77.004525,
+ 38.957776
+ ],
+ [
+ -77.004499,
+ 38.95771
+ ],
+ [
+ -77.004473,
+ 38.957645
+ ],
+ [
+ -77.004447,
+ 38.957579
+ ],
+ [
+ -77.003667,
+ 38.955625
+ ],
+ [
+ -77.003651,
+ 38.955586
+ ],
+ [
+ -77.003635,
+ 38.955547
+ ],
+ [
+ -77.00362,
+ 38.955507
+ ],
+ [
+ -77.003604,
+ 38.955468
+ ],
+ [
+ -77.003588,
+ 38.955429
+ ],
+ [
+ -77.003573,
+ 38.955389
+ ],
+ [
+ -77.003557,
+ 38.95535
+ ],
+ [
+ -77.003542,
+ 38.955311
+ ],
+ [
+ -77.003526,
+ 38.955271
+ ],
+ [
+ -77.003511,
+ 38.955232
+ ],
+ [
+ -77.003332,
+ 38.954746
+ ],
+ [
+ -77.003318,
+ 38.954706
+ ],
+ [
+ -77.003304,
+ 38.954666
+ ],
+ [
+ -77.00329,
+ 38.954627
+ ],
+ [
+ -77.003277,
+ 38.954587
+ ],
+ [
+ -77.003263,
+ 38.954547
+ ],
+ [
+ -77.00325,
+ 38.954507
+ ],
+ [
+ -77.003236,
+ 38.954468
+ ],
+ [
+ -77.003222,
+ 38.954428
+ ],
+ [
+ -77.003209,
+ 38.954388
+ ],
+ [
+ -77.003195,
+ 38.954348
+ ],
+ [
+ -77.003084,
+ 38.954019
+ ],
+ [
+ -77.00307,
+ 38.953979
+ ],
+ [
+ -77.003057,
+ 38.953939
+ ],
+ [
+ -77.003043,
+ 38.953899
+ ],
+ [
+ -77.00303,
+ 38.953859
+ ],
+ [
+ -77.003016,
+ 38.95382
+ ],
+ [
+ -77.003003,
+ 38.95378
+ ],
+ [
+ -77.002989,
+ 38.95374
+ ],
+ [
+ -77.002975,
+ 38.9537
+ ],
+ [
+ -77.002961,
+ 38.953661
+ ],
+ [
+ -77.002947,
+ 38.953621
+ ],
+ [
+ -77.00277,
+ 38.953139
+ ],
+ [
+ -77.002755,
+ 38.9531
+ ],
+ [
+ -77.002739,
+ 38.953061
+ ],
+ [
+ -77.002724,
+ 38.953021
+ ],
+ [
+ -77.002708,
+ 38.952982
+ ],
+ [
+ -77.002693,
+ 38.952942
+ ],
+ [
+ -77.002677,
+ 38.952903
+ ],
+ [
+ -77.002662,
+ 38.952864
+ ],
+ [
+ -77.002646,
+ 38.952824
+ ],
+ [
+ -77.00263,
+ 38.952785
+ ],
+ [
+ -77.002614,
+ 38.952746
+ ],
+ [
+ -77.002614,
+ 38.952745
+ ],
+ [
+ -77.002545,
+ 38.952572
+ ],
+ [
+ -77.001925,
+ 38.951018
+ ],
+ [
+ -77.001917,
+ 38.950998
+ ],
+ [
+ -77.001914,
+ 38.950992
+ ],
+ [
+ -77.001904,
+ 38.950966
+ ],
+ [
+ -77.001893,
+ 38.950939
+ ],
+ [
+ -77.001883,
+ 38.950913
+ ],
+ [
+ -77.001872,
+ 38.950887
+ ],
+ [
+ -77.001862,
+ 38.950861
+ ],
+ [
+ -77.001851,
+ 38.950835
+ ],
+ [
+ -77.001841,
+ 38.950808
+ ],
+ [
+ -77.00183,
+ 38.950782
+ ],
+ [
+ -77.00182,
+ 38.950756
+ ],
+ [
+ -77.001661,
+ 38.950366
+ ],
+ [
+ -77.001651,
+ 38.95034
+ ],
+ [
+ -77.00164,
+ 38.950314
+ ],
+ [
+ -77.001629,
+ 38.950288
+ ],
+ [
+ -77.001618,
+ 38.950262
+ ],
+ [
+ -77.001607,
+ 38.950236
+ ],
+ [
+ -77.001597,
+ 38.95021
+ ],
+ [
+ -77.001586,
+ 38.950184
+ ],
+ [
+ -77.001575,
+ 38.950157
+ ],
+ [
+ -77.001564,
+ 38.950131
+ ],
+ [
+ -77.001553,
+ 38.950105
+ ],
+ [
+ -76.999744,
+ 38.94574
+ ],
+ [
+ -76.999734,
+ 38.945714
+ ],
+ [
+ -76.999723,
+ 38.945688
+ ],
+ [
+ -76.999712,
+ 38.945662
+ ],
+ [
+ -76.999701,
+ 38.945636
+ ],
+ [
+ -76.99969,
+ 38.94561
+ ],
+ [
+ -76.999679,
+ 38.945584
+ ],
+ [
+ -76.999668,
+ 38.945558
+ ],
+ [
+ -76.999658,
+ 38.945532
+ ],
+ [
+ -76.999647,
+ 38.945505
+ ],
+ [
+ -76.999636,
+ 38.945479
+ ],
+ [
+ -76.999202,
+ 38.944488
+ ],
+ [
+ -76.999191,
+ 38.944462
+ ],
+ [
+ -76.999179,
+ 38.944436
+ ],
+ [
+ -76.999167,
+ 38.94441
+ ],
+ [
+ -76.999155,
+ 38.944384
+ ],
+ [
+ -76.999143,
+ 38.944359
+ ],
+ [
+ -76.999131,
+ 38.944333
+ ],
+ [
+ -76.999119,
+ 38.944307
+ ],
+ [
+ -76.999108,
+ 38.944281
+ ],
+ [
+ -76.999096,
+ 38.944255
+ ],
+ [
+ -76.999084,
+ 38.944229
+ ],
+ [
+ -76.99879,
+ 38.943592
+ ],
+ [
+ -76.998779,
+ 38.943566
+ ],
+ [
+ -76.998767,
+ 38.94354
+ ],
+ [
+ -76.998755,
+ 38.943514
+ ],
+ [
+ -76.998743,
+ 38.943489
+ ],
+ [
+ -76.998731,
+ 38.943463
+ ],
+ [
+ -76.998719,
+ 38.943437
+ ],
+ [
+ -76.998707,
+ 38.943411
+ ],
+ [
+ -76.998696,
+ 38.943385
+ ],
+ [
+ -76.998684,
+ 38.943359
+ ],
+ [
+ -76.998672,
+ 38.943333
+ ],
+ [
+ -76.998239,
+ 38.942342
+ ],
+ [
+ -76.998228,
+ 38.942316
+ ],
+ [
+ -76.998217,
+ 38.94229
+ ],
+ [
+ -76.998206,
+ 38.942264
+ ],
+ [
+ -76.998195,
+ 38.942238
+ ],
+ [
+ -76.998184,
+ 38.942212
+ ],
+ [
+ -76.998173,
+ 38.942185
+ ],
+ [
+ -76.998162,
+ 38.942159
+ ],
+ [
+ -76.998152,
+ 38.942133
+ ],
+ [
+ -76.998141,
+ 38.942107
+ ],
+ [
+ -76.99813,
+ 38.942081
+ ],
+ [
+ -76.996692,
+ 38.93861
+ ],
+ [
+ -76.995351,
+ 38.935374
+ ],
+ [
+ -76.995338,
+ 38.935343
+ ],
+ [
+ -76.995325,
+ 38.935312
+ ],
+ [
+ -76.995312,
+ 38.93528
+ ],
+ [
+ -76.995299,
+ 38.935249
+ ],
+ [
+ -76.995286,
+ 38.935218
+ ],
+ [
+ -76.995273,
+ 38.935186
+ ],
+ [
+ -76.995261,
+ 38.935155
+ ],
+ [
+ -76.995248,
+ 38.935123
+ ],
+ [
+ -76.995235,
+ 38.935092
+ ],
+ [
+ -76.995222,
+ 38.935061
+ ],
+ [
+ -76.995018,
+ 38.934521
+ ],
+ [
+ -76.994835,
+ 38.933977
+ ],
+ [
+ -76.994817,
+ 38.933915
+ ],
+ [
+ -76.994674,
+ 38.933429
+ ],
+ [
+ -76.994535,
+ 38.932877
+ ],
+ [
+ -76.994418,
+ 38.932322
+ ],
+ [
+ -76.994415,
+ 38.932308
+ ],
+ [
+ -76.994412,
+ 38.932289
+ ],
+ [
+ -76.994405,
+ 38.932256
+ ],
+ [
+ -76.994399,
+ 38.932224
+ ],
+ [
+ -76.994393,
+ 38.932191
+ ],
+ [
+ -76.994388,
+ 38.932159
+ ],
+ [
+ -76.994382,
+ 38.932126
+ ],
+ [
+ -76.994376,
+ 38.932093
+ ],
+ [
+ -76.99437,
+ 38.932061
+ ],
+ [
+ -76.994364,
+ 38.932028
+ ],
+ [
+ -76.994358,
+ 38.931996
+ ],
+ [
+ -76.994189,
+ 38.931045
+ ],
+ [
+ -76.994179,
+ 38.93099
+ ],
+ [
+ -76.99417,
+ 38.930936
+ ],
+ [
+ -76.99416,
+ 38.930882
+ ],
+ [
+ -76.994151,
+ 38.930827
+ ],
+ [
+ -76.994141,
+ 38.930773
+ ],
+ [
+ -76.994132,
+ 38.930718
+ ],
+ [
+ -76.994123,
+ 38.930664
+ ],
+ [
+ -76.994114,
+ 38.930609
+ ],
+ [
+ -76.994106,
+ 38.930555
+ ],
+ [
+ -76.994098,
+ 38.9305
+ ],
+ [
+ -76.994079,
+ 38.930364
+ ],
+ [
+ -76.994072,
+ 38.930309
+ ],
+ [
+ -76.994065,
+ 38.930255
+ ],
+ [
+ -76.994059,
+ 38.9302
+ ],
+ [
+ -76.994053,
+ 38.930145
+ ],
+ [
+ -76.994047,
+ 38.93009
+ ],
+ [
+ -76.994041,
+ 38.930036
+ ],
+ [
+ -76.994035,
+ 38.929981
+ ],
+ [
+ -76.99403,
+ 38.929926
+ ],
+ [
+ -76.994024,
+ 38.929872
+ ],
+ [
+ -76.994019,
+ 38.929817
+ ],
+ [
+ -76.993868,
+ 38.928292
+ ],
+ [
+ -76.99386,
+ 38.928209
+ ],
+ [
+ -76.993852,
+ 38.928127
+ ],
+ [
+ -76.993844,
+ 38.928045
+ ],
+ [
+ -76.993837,
+ 38.927963
+ ],
+ [
+ -76.99383,
+ 38.927881
+ ],
+ [
+ -76.993824,
+ 38.927799
+ ],
+ [
+ -76.993818,
+ 38.927717
+ ],
+ [
+ -76.993814,
+ 38.927636
+ ],
+ [
+ -76.99381,
+ 38.927554
+ ],
+ [
+ -76.993808,
+ 38.927472
+ ],
+ [
+ -76.993808,
+ 38.927241
+ ],
+ [
+ -76.993817,
+ 38.92701
+ ],
+ [
+ -76.993837,
+ 38.926779
+ ],
+ [
+ -76.993867,
+ 38.926549
+ ],
+ [
+ -76.993906,
+ 38.926321
+ ],
+ [
+ -76.993956,
+ 38.926093
+ ],
+ [
+ -76.994015,
+ 38.925866
+ ],
+ [
+ -76.994084,
+ 38.925642
+ ],
+ [
+ -76.994111,
+ 38.925563
+ ],
+ [
+ -76.994139,
+ 38.925484
+ ],
+ [
+ -76.994168,
+ 38.925405
+ ],
+ [
+ -76.994198,
+ 38.925326
+ ],
+ [
+ -76.994228,
+ 38.925247
+ ],
+ [
+ -76.994259,
+ 38.925169
+ ],
+ [
+ -76.994291,
+ 38.925091
+ ],
+ [
+ -76.994323,
+ 38.925012
+ ],
+ [
+ -76.994355,
+ 38.924934
+ ],
+ [
+ -76.994387,
+ 38.924855
+ ],
+ [
+ -76.995684,
+ 38.921716
+ ],
+ [
+ -76.996332,
+ 38.920148
+ ],
+ [
+ -76.996518,
+ 38.919699
+ ],
+ [
+ -76.996612,
+ 38.919472
+ ],
+ [
+ -76.996634,
+ 38.91942
+ ],
+ [
+ -76.996655,
+ 38.919368
+ ],
+ [
+ -76.996677,
+ 38.919315
+ ],
+ [
+ -76.996699,
+ 38.919263
+ ],
+ [
+ -76.996722,
+ 38.919211
+ ],
+ [
+ -76.996745,
+ 38.919159
+ ],
+ [
+ -76.996768,
+ 38.919107
+ ],
+ [
+ -76.996791,
+ 38.919056
+ ],
+ [
+ -76.996816,
+ 38.919004
+ ],
+ [
+ -76.996841,
+ 38.918953
+ ],
+ [
+ -76.996918,
+ 38.918806
+ ],
+ [
+ -76.997001,
+ 38.91866
+ ],
+ [
+ -76.99709,
+ 38.918517
+ ],
+ [
+ -76.997122,
+ 38.918468
+ ],
+ [
+ -76.997155,
+ 38.91842
+ ],
+ [
+ -76.997188,
+ 38.918371
+ ],
+ [
+ -76.997222,
+ 38.918323
+ ],
+ [
+ -76.997256,
+ 38.918275
+ ],
+ [
+ -76.997291,
+ 38.918228
+ ],
+ [
+ -76.997326,
+ 38.91818
+ ],
+ [
+ -76.997361,
+ 38.918132
+ ],
+ [
+ -76.997396,
+ 38.918085
+ ],
+ [
+ -76.997432,
+ 38.918037
+ ],
+ [
+ -76.997642,
+ 38.917755
+ ],
+ [
+ -76.997687,
+ 38.917695
+ ],
+ [
+ -76.997731,
+ 38.917636
+ ],
+ [
+ -76.997775,
+ 38.917576
+ ],
+ [
+ -76.997819,
+ 38.917517
+ ],
+ [
+ -76.997862,
+ 38.917457
+ ],
+ [
+ -76.997905,
+ 38.917398
+ ],
+ [
+ -76.997948,
+ 38.917338
+ ],
+ [
+ -76.997991,
+ 38.917277
+ ],
+ [
+ -76.998032,
+ 38.917217
+ ],
+ [
+ -76.998074,
+ 38.917157
+ ],
+ [
+ -76.998227,
+ 38.916919
+ ],
+ [
+ -76.998371,
+ 38.916677
+ ],
+ [
+ -76.998406,
+ 38.916615
+ ],
+ [
+ -76.998441,
+ 38.916551
+ ],
+ [
+ -76.998475,
+ 38.916488
+ ],
+ [
+ -76.998509,
+ 38.916425
+ ],
+ [
+ -76.998542,
+ 38.916361
+ ],
+ [
+ -76.998575,
+ 38.916298
+ ],
+ [
+ -76.998608,
+ 38.916234
+ ],
+ [
+ -76.99864,
+ 38.91617
+ ],
+ [
+ -76.998672,
+ 38.916106
+ ],
+ [
+ -76.998705,
+ 38.916042
+ ],
+ [
+ -76.999284,
+ 38.914894
+ ],
+ [
+ -77.002237,
+ 38.909038
+ ],
+ [
+ -77.002269,
+ 38.908975
+ ],
+ [
+ -77.0023,
+ 38.908912
+ ],
+ [
+ -77.002332,
+ 38.90885
+ ],
+ [
+ -77.002363,
+ 38.908787
+ ],
+ [
+ -77.002394,
+ 38.908724
+ ],
+ [
+ -77.002424,
+ 38.908661
+ ],
+ [
+ -77.002455,
+ 38.908598
+ ],
+ [
+ -77.002484,
+ 38.908535
+ ],
+ [
+ -77.002513,
+ 38.908472
+ ],
+ [
+ -77.002542,
+ 38.908409
+ ],
+ [
+ -77.002618,
+ 38.908231
+ ],
+ [
+ -77.002689,
+ 38.908053
+ ],
+ [
+ -77.002713,
+ 38.907988
+ ],
+ [
+ -77.002737,
+ 38.907924
+ ],
+ [
+ -77.00276,
+ 38.907859
+ ],
+ [
+ -77.002782,
+ 38.907794
+ ],
+ [
+ -77.002804,
+ 38.907729
+ ],
+ [
+ -77.002826,
+ 38.907664
+ ],
+ [
+ -77.002848,
+ 38.907599
+ ],
+ [
+ -77.002869,
+ 38.907534
+ ],
+ [
+ -77.00289,
+ 38.907468
+ ],
+ [
+ -77.002912,
+ 38.907403
+ ],
+ [
+ -77.003043,
+ 38.906997
+ ],
+ [
+ -77.003052,
+ 38.906971
+ ],
+ [
+ -77.003061,
+ 38.906944
+ ],
+ [
+ -77.003069,
+ 38.906917
+ ],
+ [
+ -77.003078,
+ 38.906891
+ ],
+ [
+ -77.003087,
+ 38.906864
+ ],
+ [
+ -77.003095,
+ 38.906838
+ ],
+ [
+ -77.003104,
+ 38.906811
+ ],
+ [
+ -77.003113,
+ 38.906784
+ ],
+ [
+ -77.003122,
+ 38.906758
+ ],
+ [
+ -77.00313,
+ 38.906731
+ ],
+ [
+ -77.003213,
+ 38.90649
+ ],
+ [
+ -77.003222,
+ 38.906463
+ ],
+ [
+ -77.003232,
+ 38.906437
+ ],
+ [
+ -77.003241,
+ 38.90641
+ ],
+ [
+ -77.003251,
+ 38.906384
+ ],
+ [
+ -77.00326,
+ 38.906357
+ ],
+ [
+ -77.00327,
+ 38.906331
+ ],
+ [
+ -77.003279,
+ 38.906305
+ ],
+ [
+ -77.003289,
+ 38.906278
+ ],
+ [
+ -77.003298,
+ 38.906252
+ ],
+ [
+ -77.003308,
+ 38.906225
+ ],
+ [
+ -77.003863,
+ 38.904683
+ ],
+ [
+ -77.003892,
+ 38.904604
+ ],
+ [
+ -77.003921,
+ 38.904525
+ ],
+ [
+ -77.00395,
+ 38.904446
+ ],
+ [
+ -77.003979,
+ 38.904367
+ ],
+ [
+ -77.004009,
+ 38.904289
+ ],
+ [
+ -77.00404,
+ 38.90421
+ ],
+ [
+ -77.004073,
+ 38.904132
+ ],
+ [
+ -77.004106,
+ 38.904055
+ ],
+ [
+ -77.00414,
+ 38.903977
+ ],
+ [
+ -77.004176,
+ 38.903901
+ ],
+ [
+ -77.004246,
+ 38.903763
+ ],
+ [
+ -77.00432,
+ 38.903628
+ ],
+ [
+ -77.0044,
+ 38.903494
+ ],
+ [
+ -77.004485,
+ 38.903363
+ ],
+ [
+ -77.004535,
+ 38.903291
+ ],
+ [
+ -77.004586,
+ 38.903219
+ ],
+ [
+ -77.004638,
+ 38.903148
+ ],
+ [
+ -77.004691,
+ 38.903078
+ ],
+ [
+ -77.004745,
+ 38.903008
+ ],
+ [
+ -77.004801,
+ 38.902938
+ ],
+ [
+ -77.004856,
+ 38.902868
+ ],
+ [
+ -77.004913,
+ 38.902799
+ ],
+ [
+ -77.004969,
+ 38.902729
+ ],
+ [
+ -77.005026,
+ 38.90266
+ ],
+ [
+ -77.005336,
+ 38.902282
+ ],
+ [
+ -77.005404,
+ 38.902199
+ ],
+ [
+ -77.005469,
+ 38.902119
+ ],
+ [
+ -77.005534,
+ 38.902039
+ ],
+ [
+ -77.005599,
+ 38.901959
+ ],
+ [
+ -77.005663,
+ 38.901879
+ ],
+ [
+ -77.005726,
+ 38.901798
+ ],
+ [
+ -77.005788,
+ 38.901716
+ ],
+ [
+ -77.005849,
+ 38.901634
+ ],
+ [
+ -77.005908,
+ 38.901552
+ ],
+ [
+ -77.005966,
+ 38.901468
+ ],
+ [
+ -77.006021,
+ 38.901384
+ ],
+ [
+ -77.006092,
+ 38.90127
+ ],
+ [
+ -77.006158,
+ 38.901154
+ ],
+ [
+ -77.006221,
+ 38.901037
+ ],
+ [
+ -77.006264,
+ 38.900948
+ ],
+ [
+ -77.006306,
+ 38.900859
+ ],
+ [
+ -77.006346,
+ 38.90077
+ ],
+ [
+ -77.006384,
+ 38.90068
+ ],
+ [
+ -77.00642,
+ 38.900589
+ ],
+ [
+ -77.006456,
+ 38.900499
+ ],
+ [
+ -77.00649,
+ 38.900408
+ ],
+ [
+ -77.006523,
+ 38.900317
+ ],
+ [
+ -77.006557,
+ 38.900226
+ ],
+ [
+ -77.006589,
+ 38.900135
+ ],
+ [
+ -77.007249,
+ 38.898302
+ ],
+ [
+ -77.007819,
+ 38.896718
+ ],
+ [
+ -77.007874,
+ 38.896565
+ ],
+ [
+ -77.007894,
+ 38.896507
+ ],
+ [
+ -77.007916,
+ 38.896449
+ ],
+ [
+ -77.007937,
+ 38.896391
+ ],
+ [
+ -77.007959,
+ 38.896333
+ ],
+ [
+ -77.007983,
+ 38.896275
+ ],
+ [
+ -77.008007,
+ 38.896218
+ ],
+ [
+ -77.008032,
+ 38.896161
+ ],
+ [
+ -77.008059,
+ 38.896104
+ ],
+ [
+ -77.008088,
+ 38.896048
+ ],
+ [
+ -77.008118,
+ 38.895993
+ ],
+ [
+ -77.008157,
+ 38.895928
+ ],
+ [
+ -77.008199,
+ 38.895864
+ ],
+ [
+ -77.008243,
+ 38.895802
+ ],
+ [
+ -77.00829,
+ 38.895741
+ ],
+ [
+ -77.008339,
+ 38.895681
+ ],
+ [
+ -77.008392,
+ 38.895622
+ ],
+ [
+ -77.008447,
+ 38.895565
+ ],
+ [
+ -77.008504,
+ 38.89551
+ ],
+ [
+ -77.008564,
+ 38.895455
+ ],
+ [
+ -77.008626,
+ 38.895403
+ ],
+ [
+ -77.00869,
+ 38.895352
+ ],
+ [
+ -77.008757,
+ 38.895303
+ ],
+ [
+ -77.008825,
+ 38.895256
+ ],
+ [
+ -77.008896,
+ 38.895211
+ ],
+ [
+ -77.008969,
+ 38.895168
+ ],
+ [
+ -77.009043,
+ 38.895126
+ ],
+ [
+ -77.00912,
+ 38.895087
+ ],
+ [
+ -77.009198,
+ 38.89505
+ ],
+ [
+ -77.009277,
+ 38.895015
+ ],
+ [
+ -77.009358,
+ 38.894982
+ ],
+ [
+ -77.009441,
+ 38.894951
+ ],
+ [
+ -77.009525,
+ 38.894923
+ ],
+ [
+ -77.00961,
+ 38.894896
+ ],
+ [
+ -77.009696,
+ 38.894873
+ ],
+ [
+ -77.009783,
+ 38.894851
+ ],
+ [
+ -77.009871,
+ 38.894832
+ ],
+ [
+ -77.00996,
+ 38.894815
+ ],
+ [
+ -77.010049,
+ 38.894801
+ ],
+ [
+ -77.010139,
+ 38.894788
+ ],
+ [
+ -77.01023,
+ 38.894779
+ ],
+ [
+ -77.010307,
+ 38.894773
+ ],
+ [
+ -77.010384,
+ 38.894768
+ ],
+ [
+ -77.010461,
+ 38.894765
+ ],
+ [
+ -77.010538,
+ 38.894763
+ ],
+ [
+ -77.010616,
+ 38.894762
+ ],
+ [
+ -77.010693,
+ 38.894762
+ ],
+ [
+ -77.01077,
+ 38.894762
+ ],
+ [
+ -77.010847,
+ 38.894763
+ ],
+ [
+ -77.010925,
+ 38.894765
+ ],
+ [
+ -77.011002,
+ 38.894767
+ ],
+ [
+ -77.013428,
+ 38.89482
+ ],
+ [
+ -77.013512,
+ 38.894822
+ ],
+ [
+ -77.013595,
+ 38.894824
+ ],
+ [
+ -77.013679,
+ 38.894827
+ ],
+ [
+ -77.013762,
+ 38.89483
+ ],
+ [
+ -77.013846,
+ 38.894834
+ ],
+ [
+ -77.013929,
+ 38.894839
+ ],
+ [
+ -77.014012,
+ 38.894845
+ ],
+ [
+ -77.014095,
+ 38.894852
+ ],
+ [
+ -77.014178,
+ 38.894862
+ ],
+ [
+ -77.01426,
+ 38.894873
+ ],
+ [
+ -77.014345,
+ 38.894886
+ ],
+ [
+ -77.014429,
+ 38.894902
+ ],
+ [
+ -77.014512,
+ 38.89492
+ ],
+ [
+ -77.014594,
+ 38.89494
+ ],
+ [
+ -77.014676,
+ 38.894962
+ ],
+ [
+ -77.014756,
+ 38.894986
+ ],
+ [
+ -77.014836,
+ 38.895012
+ ],
+ [
+ -77.014914,
+ 38.89504
+ ],
+ [
+ -77.014991,
+ 38.89507
+ ],
+ [
+ -77.015067,
+ 38.895102
+ ],
+ [
+ -77.015142,
+ 38.895136
+ ],
+ [
+ -77.015215,
+ 38.895172
+ ],
+ [
+ -77.015284,
+ 38.895208
+ ],
+ [
+ -77.015352,
+ 38.895246
+ ],
+ [
+ -77.015419,
+ 38.895285
+ ],
+ [
+ -77.015485,
+ 38.895326
+ ],
+ [
+ -77.01555,
+ 38.895367
+ ],
+ [
+ -77.015613,
+ 38.895409
+ ],
+ [
+ -77.015677,
+ 38.895452
+ ],
+ [
+ -77.015739,
+ 38.895495
+ ],
+ [
+ -77.015801,
+ 38.895539
+ ],
+ [
+ -77.015864,
+ 38.895582
+ ],
+ [
+ -77.016004,
+ 38.89568
+ ],
+ [
+ -77.017569,
+ 38.896783
+ ],
+ [
+ -77.018529,
+ 38.89746
+ ],
+ [
+ -77.018551,
+ 38.897475
+ ],
+ [
+ -77.018617,
+ 38.897521
+ ],
+ [
+ -77.018682,
+ 38.897567
+ ],
+ [
+ -77.018748,
+ 38.897612
+ ],
+ [
+ -77.018814,
+ 38.897657
+ ],
+ [
+ -77.018881,
+ 38.897702
+ ],
+ [
+ -77.018948,
+ 38.897746
+ ],
+ [
+ -77.019017,
+ 38.897789
+ ],
+ [
+ -77.019086,
+ 38.897831
+ ],
+ [
+ -77.019156,
+ 38.897872
+ ],
+ [
+ -77.019228,
+ 38.897912
+ ],
+ [
+ -77.019324,
+ 38.897962
+ ],
+ [
+ -77.019423,
+ 38.89801
+ ],
+ [
+ -77.019523,
+ 38.898055
+ ],
+ [
+ -77.019626,
+ 38.898097
+ ],
+ [
+ -77.01973,
+ 38.898136
+ ],
+ [
+ -77.019836,
+ 38.898173
+ ],
+ [
+ -77.019943,
+ 38.898207
+ ],
+ [
+ -77.020052,
+ 38.898238
+ ],
+ [
+ -77.020162,
+ 38.898266
+ ],
+ [
+ -77.020273,
+ 38.898291
+ ],
+ [
+ -77.020385,
+ 38.898313
+ ],
+ [
+ -77.020498,
+ 38.898333
+ ],
+ [
+ -77.020612,
+ 38.898349
+ ],
+ [
+ -77.020727,
+ 38.898362
+ ],
+ [
+ -77.020814,
+ 38.89837
+ ],
+ [
+ -77.020901,
+ 38.898376
+ ],
+ [
+ -77.020989,
+ 38.898381
+ ],
+ [
+ -77.021077,
+ 38.898385
+ ],
+ [
+ -77.021165,
+ 38.898388
+ ],
+ [
+ -77.021252,
+ 38.89839
+ ],
+ [
+ -77.02134,
+ 38.898391
+ ],
+ [
+ -77.021428,
+ 38.898391
+ ],
+ [
+ -77.021516,
+ 38.898392
+ ],
+ [
+ -77.021604,
+ 38.898392
+ ],
+ [
+ -77.021744,
+ 38.898392
+ ],
+ [
+ -77.023852,
+ 38.898393
+ ],
+ [
+ -77.02415,
+ 38.898393
+ ],
+ [
+ -77.024185,
+ 38.898393
+ ],
+ [
+ -77.02422,
+ 38.898393
+ ],
+ [
+ -77.024255,
+ 38.898393
+ ],
+ [
+ -77.02429,
+ 38.898392
+ ],
+ [
+ -77.024325,
+ 38.898392
+ ],
+ [
+ -77.02436,
+ 38.898392
+ ],
+ [
+ -77.024395,
+ 38.898392
+ ],
+ [
+ -77.024431,
+ 38.898392
+ ],
+ [
+ -77.024466,
+ 38.898392
+ ],
+ [
+ -77.024501,
+ 38.898392
+ ],
+ [
+ -77.024918,
+ 38.898385
+ ],
+ [
+ -77.024953,
+ 38.898384
+ ],
+ [
+ -77.024988,
+ 38.898383
+ ],
+ [
+ -77.025023,
+ 38.898382
+ ],
+ [
+ -77.025059,
+ 38.898381
+ ],
+ [
+ -77.025094,
+ 38.89838
+ ],
+ [
+ -77.025129,
+ 38.898378
+ ],
+ [
+ -77.025164,
+ 38.898377
+ ],
+ [
+ -77.025199,
+ 38.898376
+ ],
+ [
+ -77.025234,
+ 38.898375
+ ],
+ [
+ -77.025269,
+ 38.898374
+ ],
+ [
+ -77.02562,
+ 38.898362
+ ],
+ [
+ -77.025655,
+ 38.898361
+ ],
+ [
+ -77.02569,
+ 38.898359
+ ],
+ [
+ -77.025725,
+ 38.898358
+ ],
+ [
+ -77.02576,
+ 38.898357
+ ],
+ [
+ -77.025795,
+ 38.898356
+ ],
+ [
+ -77.02583,
+ 38.898355
+ ],
+ [
+ -77.025865,
+ 38.898354
+ ],
+ [
+ -77.025901,
+ 38.898353
+ ],
+ [
+ -77.025936,
+ 38.898352
+ ],
+ [
+ -77.025971,
+ 38.898351
+ ],
+ [
+ -77.026386,
+ 38.898344
+ ],
+ [
+ -77.026421,
+ 38.898344
+ ],
+ [
+ -77.026456,
+ 38.898343
+ ],
+ [
+ -77.026491,
+ 38.898343
+ ],
+ [
+ -77.026527,
+ 38.898343
+ ],
+ [
+ -77.026562,
+ 38.898343
+ ],
+ [
+ -77.026597,
+ 38.898343
+ ],
+ [
+ -77.026632,
+ 38.898343
+ ],
+ [
+ -77.026667,
+ 38.898343
+ ],
+ [
+ -77.026702,
+ 38.898343
+ ],
+ [
+ -77.026737,
+ 38.898343
+ ],
+ [
+ -77.027031,
+ 38.898343
+ ],
+ [
+ -77.028085,
+ 38.898343
+ ],
+ [
+ -77.029139,
+ 38.898343
+ ],
+ [
+ -77.032279,
+ 38.898344
+ ],
+ [
+ -77.032374,
+ 38.898345
+ ],
+ [
+ -77.032469,
+ 38.898345
+ ],
+ [
+ -77.032563,
+ 38.898345
+ ],
+ [
+ -77.032658,
+ 38.898346
+ ],
+ [
+ -77.032753,
+ 38.898348
+ ],
+ [
+ -77.032848,
+ 38.898351
+ ],
+ [
+ -77.032943,
+ 38.898354
+ ],
+ [
+ -77.033037,
+ 38.898359
+ ],
+ [
+ -77.033132,
+ 38.898365
+ ],
+ [
+ -77.033226,
+ 38.898372
+ ],
+ [
+ -77.033368,
+ 38.898387
+ ],
+ [
+ -77.033509,
+ 38.898405
+ ],
+ [
+ -77.033649,
+ 38.898427
+ ],
+ [
+ -77.033789,
+ 38.898453
+ ],
+ [
+ -77.033927,
+ 38.898482
+ ],
+ [
+ -77.034063,
+ 38.898515
+ ],
+ [
+ -77.034199,
+ 38.898552
+ ],
+ [
+ -77.034287,
+ 38.898578
+ ],
+ [
+ -77.034375,
+ 38.898605
+ ],
+ [
+ -77.034463,
+ 38.898634
+ ],
+ [
+ -77.03455,
+ 38.898664
+ ],
+ [
+ -77.034636,
+ 38.898695
+ ],
+ [
+ -77.034722,
+ 38.898726
+ ],
+ [
+ -77.034807,
+ 38.898759
+ ],
+ [
+ -77.034892,
+ 38.898791
+ ],
+ [
+ -77.034977,
+ 38.898824
+ ],
+ [
+ -77.035062,
+ 38.898857
+ ],
+ [
+ -77.035928,
+ 38.899195
+ ],
+ [
+ -77.036013,
+ 38.899228
+ ],
+ [
+ -77.036097,
+ 38.899261
+ ],
+ [
+ -77.036182,
+ 38.899295
+ ],
+ [
+ -77.036266,
+ 38.899329
+ ],
+ [
+ -77.03635,
+ 38.899363
+ ],
+ [
+ -77.036434,
+ 38.899399
+ ],
+ [
+ -77.036516,
+ 38.899435
+ ],
+ [
+ -77.036598,
+ 38.899472
+ ],
+ [
+ -77.03668,
+ 38.89951
+ ],
+ [
+ -77.03676,
+ 38.89955
+ ],
+ [
+ -77.036883,
+ 38.899615
+ ],
+ [
+ -77.037003,
+ 38.899683
+ ],
+ [
+ -77.037119,
+ 38.899754
+ ],
+ [
+ -77.037233,
+ 38.899829
+ ],
+ [
+ -77.037343,
+ 38.899906
+ ],
+ [
+ -77.03745,
+ 38.899987
+ ],
+ [
+ -77.037553,
+ 38.90007
+ ],
+ [
+ -77.037652,
+ 38.900156
+ ],
+ [
+ -77.037747,
+ 38.900245
+ ],
+ [
+ -77.037838,
+ 38.900336
+ ],
+ [
+ -77.037925,
+ 38.90043
+ ],
+ [
+ -77.038007,
+ 38.900526
+ ],
+ [
+ -77.038086,
+ 38.900625
+ ],
+ [
+ -77.038133,
+ 38.900689
+ ],
+ [
+ -77.038179,
+ 38.900754
+ ],
+ [
+ -77.038224,
+ 38.900819
+ ],
+ [
+ -77.038267,
+ 38.900885
+ ],
+ [
+ -77.038309,
+ 38.900951
+ ],
+ [
+ -77.038351,
+ 38.901018
+ ],
+ [
+ -77.038391,
+ 38.901085
+ ],
+ [
+ -77.038431,
+ 38.901153
+ ],
+ [
+ -77.03847,
+ 38.90122
+ ],
+ [
+ -77.038509,
+ 38.901287
+ ],
+ [
+ -77.039166,
+ 38.902418
+ ],
+ [
+ -77.040038,
+ 38.903919
+ ],
+ [
+ -77.041722,
+ 38.906819
+ ],
+ [
+ -77.04186,
+ 38.907056
+ ],
+ [
+ -77.041875,
+ 38.907081
+ ],
+ [
+ -77.041889,
+ 38.907106
+ ],
+ [
+ -77.041904,
+ 38.907131
+ ],
+ [
+ -77.041918,
+ 38.907156
+ ],
+ [
+ -77.041933,
+ 38.907181
+ ],
+ [
+ -77.041948,
+ 38.907206
+ ],
+ [
+ -77.041962,
+ 38.907231
+ ],
+ [
+ -77.041977,
+ 38.907256
+ ],
+ [
+ -77.041992,
+ 38.907281
+ ],
+ [
+ -77.042006,
+ 38.907306
+ ],
+ [
+ -77.042163,
+ 38.907564
+ ],
+ [
+ -77.042178,
+ 38.907589
+ ],
+ [
+ -77.042194,
+ 38.907613
+ ],
+ [
+ -77.042209,
+ 38.907638
+ ],
+ [
+ -77.042225,
+ 38.907663
+ ],
+ [
+ -77.04224,
+ 38.907687
+ ],
+ [
+ -77.042256,
+ 38.907712
+ ],
+ [
+ -77.042271,
+ 38.907737
+ ],
+ [
+ -77.042287,
+ 38.907761
+ ],
+ [
+ -77.042302,
+ 38.907786
+ ],
+ [
+ -77.042318,
+ 38.90781
+ ],
+ [
+ -77.042462,
+ 38.908037
+ ],
+ [
+ -77.042477,
+ 38.908062
+ ],
+ [
+ -77.042493,
+ 38.908086
+ ],
+ [
+ -77.042508,
+ 38.908111
+ ],
+ [
+ -77.042524,
+ 38.908136
+ ],
+ [
+ -77.042539,
+ 38.90816
+ ],
+ [
+ -77.042555,
+ 38.908185
+ ],
+ [
+ -77.04257,
+ 38.908209
+ ],
+ [
+ -77.042586,
+ 38.908234
+ ],
+ [
+ -77.042601,
+ 38.908259
+ ],
+ [
+ -77.042617,
+ 38.908284
+ ],
+ [
+ -77.042773,
+ 38.908542
+ ],
+ [
+ -77.042788,
+ 38.908567
+ ],
+ [
+ -77.042803,
+ 38.908591
+ ],
+ [
+ -77.042817,
+ 38.908616
+ ],
+ [
+ -77.042832,
+ 38.908641
+ ],
+ [
+ -77.042847,
+ 38.908666
+ ],
+ [
+ -77.042861,
+ 38.908691
+ ],
+ [
+ -77.042876,
+ 38.908716
+ ],
+ [
+ -77.04289,
+ 38.908741
+ ],
+ [
+ -77.042905,
+ 38.908766
+ ],
+ [
+ -77.042919,
+ 38.908791
+ ],
+ [
+ -77.043137,
+ 38.909168
+ ],
+ [
+ -77.044009,
+ 38.910667
+ ],
+ [
+ -77.045291,
+ 38.912873
+ ],
+ [
+ -77.045326,
+ 38.912934
+ ],
+ [
+ -77.045362,
+ 38.912996
+ ],
+ [
+ -77.045398,
+ 38.913058
+ ],
+ [
+ -77.045433,
+ 38.913119
+ ],
+ [
+ -77.045468,
+ 38.913181
+ ],
+ [
+ -77.045502,
+ 38.913243
+ ],
+ [
+ -77.045537,
+ 38.913305
+ ],
+ [
+ -77.04557,
+ 38.913367
+ ],
+ [
+ -77.045603,
+ 38.91343
+ ],
+ [
+ -77.045636,
+ 38.913493
+ ],
+ [
+ -77.04575,
+ 38.91373
+ ],
+ [
+ -77.045854,
+ 38.91397
+ ],
+ [
+ -77.045947,
+ 38.914213
+ ],
+ [
+ -77.046029,
+ 38.914459
+ ],
+ [
+ -77.046049,
+ 38.914525
+ ],
+ [
+ -77.046068,
+ 38.914591
+ ],
+ [
+ -77.046086,
+ 38.914657
+ ],
+ [
+ -77.046104,
+ 38.914723
+ ],
+ [
+ -77.046122,
+ 38.914789
+ ],
+ [
+ -77.046139,
+ 38.914855
+ ],
+ [
+ -77.046156,
+ 38.914921
+ ],
+ [
+ -77.046172,
+ 38.914988
+ ],
+ [
+ -77.046189,
+ 38.915054
+ ],
+ [
+ -77.046205,
+ 38.915121
+ ],
+ [
+ -77.046275,
+ 38.915407
+ ],
+ [
+ -77.046289,
+ 38.915461
+ ],
+ [
+ -77.046302,
+ 38.915515
+ ],
+ [
+ -77.046315,
+ 38.915569
+ ],
+ [
+ -77.046329,
+ 38.915623
+ ],
+ [
+ -77.046342,
+ 38.915677
+ ],
+ [
+ -77.046356,
+ 38.915731
+ ],
+ [
+ -77.04637,
+ 38.915784
+ ],
+ [
+ -77.046385,
+ 38.915838
+ ],
+ [
+ -77.0464,
+ 38.915892
+ ],
+ [
+ -77.046415,
+ 38.915945
+ ],
+ [
+ -77.046494,
+ 38.916202
+ ],
+ [
+ -77.046584,
+ 38.916456
+ ],
+ [
+ -77.046683,
+ 38.916709
+ ],
+ [
+ -77.046792,
+ 38.916958
+ ],
+ [
+ -77.046816,
+ 38.91701
+ ],
+ [
+ -77.046841,
+ 38.917061
+ ],
+ [
+ -77.046865,
+ 38.917113
+ ],
+ [
+ -77.04689,
+ 38.917164
+ ],
+ [
+ -77.046915,
+ 38.917215
+ ],
+ [
+ -77.046941,
+ 38.917267
+ ],
+ [
+ -77.046967,
+ 38.917318
+ ],
+ [
+ -77.046992,
+ 38.917369
+ ],
+ [
+ -77.047018,
+ 38.91742
+ ],
+ [
+ -77.047044,
+ 38.917471
+ ],
+ [
+ -77.047683,
+ 38.918732
+ ],
+ [
+ -77.047709,
+ 38.918783
+ ],
+ [
+ -77.047735,
+ 38.918834
+ ],
+ [
+ -77.047761,
+ 38.918885
+ ],
+ [
+ -77.047787,
+ 38.918936
+ ],
+ [
+ -77.047813,
+ 38.918987
+ ],
+ [
+ -77.04784,
+ 38.919038
+ ],
+ [
+ -77.047866,
+ 38.919089
+ ],
+ [
+ -77.047893,
+ 38.919139
+ ],
+ [
+ -77.04792,
+ 38.91919
+ ],
+ [
+ -77.047948,
+ 38.91924
+ ],
+ [
+ -77.048111,
+ 38.919524
+ ],
+ [
+ -77.048285,
+ 38.919803
+ ],
+ [
+ -77.048471,
+ 38.920078
+ ],
+ [
+ -77.048669,
+ 38.920348
+ ],
+ [
+ -77.048877,
+ 38.920613
+ ],
+ [
+ -77.048915,
+ 38.920659
+ ],
+ [
+ -77.048953,
+ 38.920705
+ ],
+ [
+ -77.048992,
+ 38.920751
+ ],
+ [
+ -77.04903,
+ 38.920797
+ ],
+ [
+ -77.049069,
+ 38.920843
+ ],
+ [
+ -77.049109,
+ 38.920888
+ ],
+ [
+ -77.049148,
+ 38.920934
+ ],
+ [
+ -77.049187,
+ 38.920979
+ ],
+ [
+ -77.049227,
+ 38.921025
+ ],
+ [
+ -77.049266,
+ 38.92107
+ ],
+ [
+ -77.049319,
+ 38.921131
+ ],
+ [
+ -77.050728,
+ 38.922755
+ ],
+ [
+ -77.050777,
+ 38.922812
+ ],
+ [
+ -77.050827,
+ 38.922868
+ ],
+ [
+ -77.050876,
+ 38.922925
+ ],
+ [
+ -77.050925,
+ 38.922982
+ ],
+ [
+ -77.050974,
+ 38.923039
+ ],
+ [
+ -77.051022,
+ 38.923097
+ ],
+ [
+ -77.05107,
+ 38.923154
+ ],
+ [
+ -77.051118,
+ 38.923212
+ ],
+ [
+ -77.051165,
+ 38.92327
+ ],
+ [
+ -77.051212,
+ 38.923328
+ ],
+ [
+ -77.051392,
+ 38.923562
+ ],
+ [
+ -77.051563,
+ 38.9238
+ ],
+ [
+ -77.051724,
+ 38.924042
+ ],
+ [
+ -77.051763,
+ 38.924103
+ ],
+ [
+ -77.051802,
+ 38.924165
+ ],
+ [
+ -77.05184,
+ 38.924227
+ ],
+ [
+ -77.051878,
+ 38.924289
+ ],
+ [
+ -77.051915,
+ 38.924351
+ ],
+ [
+ -77.051952,
+ 38.924413
+ ],
+ [
+ -77.051989,
+ 38.924475
+ ],
+ [
+ -77.052025,
+ 38.924538
+ ],
+ [
+ -77.052062,
+ 38.9246
+ ],
+ [
+ -77.052098,
+ 38.924663
+ ],
+ [
+ -77.052196,
+ 38.924832
+ ],
+ [
+ -77.053067,
+ 38.926332
+ ],
+ [
+ -77.057631,
+ 38.934182
+ ],
+ [
+ -77.058503,
+ 38.935682
+ ],
+ [
+ -77.062457,
+ 38.942481
+ ],
+ [
+ -77.063329,
+ 38.943981
+ ],
+ [
+ -77.063564,
+ 38.944385
+ ],
+ [
+ -77.063601,
+ 38.944448
+ ],
+ [
+ -77.063638,
+ 38.944512
+ ],
+ [
+ -77.063676,
+ 38.944575
+ ],
+ [
+ -77.063714,
+ 38.944639
+ ],
+ [
+ -77.063754,
+ 38.944701
+ ],
+ [
+ -77.063794,
+ 38.944764
+ ],
+ [
+ -77.063835,
+ 38.944826
+ ],
+ [
+ -77.063878,
+ 38.944887
+ ],
+ [
+ -77.063922,
+ 38.944948
+ ],
+ [
+ -77.063968,
+ 38.945008
+ ],
+ [
+ -77.064034,
+ 38.945088
+ ],
+ [
+ -77.064103,
+ 38.945166
+ ],
+ [
+ -77.064175,
+ 38.945243
+ ],
+ [
+ -77.064251,
+ 38.945317
+ ],
+ [
+ -77.06433,
+ 38.94539
+ ],
+ [
+ -77.064412,
+ 38.94546
+ ],
+ [
+ -77.064498,
+ 38.945528
+ ],
+ [
+ -77.064586,
+ 38.945593
+ ],
+ [
+ -77.064677,
+ 38.945656
+ ],
+ [
+ -77.06477,
+ 38.945717
+ ],
+ [
+ -77.064867,
+ 38.945775
+ ],
+ [
+ -77.064966,
+ 38.945831
+ ],
+ [
+ -77.065067,
+ 38.945884
+ ],
+ [
+ -77.06517,
+ 38.945934
+ ],
+ [
+ -77.065276,
+ 38.945981
+ ],
+ [
+ -77.065383,
+ 38.946026
+ ],
+ [
+ -77.065493,
+ 38.946067
+ ],
+ [
+ -77.065604,
+ 38.946106
+ ],
+ [
+ -77.065717,
+ 38.946142
+ ],
+ [
+ -77.065831,
+ 38.946174
+ ],
+ [
+ -77.065947,
+ 38.946204
+ ],
+ [
+ -77.066064,
+ 38.94623
+ ],
+ [
+ -77.066182,
+ 38.946253
+ ],
+ [
+ -77.066301,
+ 38.946273
+ ],
+ [
+ -77.066421,
+ 38.94629
+ ],
+ [
+ -77.066542,
+ 38.946304
+ ],
+ [
+ -77.066631,
+ 38.946312
+ ],
+ [
+ -77.06672,
+ 38.946318
+ ],
+ [
+ -77.066809,
+ 38.946323
+ ],
+ [
+ -77.066898,
+ 38.946327
+ ],
+ [
+ -77.066988,
+ 38.94633
+ ],
+ [
+ -77.067077,
+ 38.946332
+ ],
+ [
+ -77.067167,
+ 38.946333
+ ],
+ [
+ -77.067256,
+ 38.946333
+ ],
+ [
+ -77.067346,
+ 38.946334
+ ],
+ [
+ -77.067436,
+ 38.946334
+ ],
+ [
+ -77.076112,
+ 38.946339
+ ],
+ [
+ -77.076189,
+ 38.946339
+ ],
+ [
+ -77.076266,
+ 38.946339
+ ],
+ [
+ -77.076344,
+ 38.94634
+ ],
+ [
+ -77.076421,
+ 38.946341
+ ],
+ [
+ -77.076498,
+ 38.946343
+ ],
+ [
+ -77.076576,
+ 38.946346
+ ],
+ [
+ -77.076653,
+ 38.946349
+ ],
+ [
+ -77.07673,
+ 38.946354
+ ],
+ [
+ -77.076807,
+ 38.946361
+ ],
+ [
+ -77.076884,
+ 38.946369
+ ],
+ [
+ -77.076974,
+ 38.94638
+ ],
+ [
+ -77.077064,
+ 38.946395
+ ],
+ [
+ -77.077154,
+ 38.946411
+ ],
+ [
+ -77.077242,
+ 38.94643
+ ],
+ [
+ -77.07733,
+ 38.946451
+ ],
+ [
+ -77.077417,
+ 38.946475
+ ],
+ [
+ -77.077502,
+ 38.946501
+ ],
+ [
+ -77.077587,
+ 38.946529
+ ],
+ [
+ -77.07767,
+ 38.94656
+ ],
+ [
+ -77.077751,
+ 38.946593
+ ],
+ [
+ -77.077831,
+ 38.946628
+ ],
+ [
+ -77.07791,
+ 38.946665
+ ],
+ [
+ -77.077987,
+ 38.946704
+ ],
+ [
+ -77.078062,
+ 38.946745
+ ],
+ [
+ -77.078135,
+ 38.946789
+ ],
+ [
+ -77.078206,
+ 38.946834
+ ],
+ [
+ -77.078276,
+ 38.946881
+ ],
+ [
+ -77.078343,
+ 38.94693
+ ],
+ [
+ -77.078408,
+ 38.946981
+ ],
+ [
+ -77.07847,
+ 38.947033
+ ],
+ [
+ -77.07853,
+ 38.947088
+ ],
+ [
+ -77.078588,
+ 38.947143
+ ],
+ [
+ -77.078643,
+ 38.947201
+ ],
+ [
+ -77.078696,
+ 38.947259
+ ],
+ [
+ -77.078746,
+ 38.947319
+ ],
+ [
+ -77.078794,
+ 38.947381
+ ],
+ [
+ -77.078831,
+ 38.947434
+ ],
+ [
+ -77.078867,
+ 38.947487
+ ],
+ [
+ -77.078902,
+ 38.947541
+ ],
+ [
+ -77.078935,
+ 38.947596
+ ],
+ [
+ -77.078967,
+ 38.947651
+ ],
+ [
+ -77.078997,
+ 38.947706
+ ],
+ [
+ -77.079027,
+ 38.947762
+ ],
+ [
+ -77.079057,
+ 38.947818
+ ],
+ [
+ -77.079085,
+ 38.947874
+ ],
+ [
+ -77.079114,
+ 38.94793
+ ],
+ [
+ -77.079221,
+ 38.94814
+ ],
+ [
+ -77.080002,
+ 38.949669
+ ],
+ [
+ -77.080269,
+ 38.950194
+ ],
+ [
+ -77.080301,
+ 38.950257
+ ],
+ [
+ -77.080334,
+ 38.950321
+ ],
+ [
+ -77.080367,
+ 38.950385
+ ],
+ [
+ -77.080399,
+ 38.950449
+ ],
+ [
+ -77.080432,
+ 38.950512
+ ],
+ [
+ -77.080464,
+ 38.950576
+ ],
+ [
+ -77.080497,
+ 38.95064
+ ],
+ [
+ -77.080529,
+ 38.950704
+ ],
+ [
+ -77.080562,
+ 38.950767
+ ],
+ [
+ -77.080594,
+ 38.950831
+ ],
+ [
+ -77.081763,
+ 38.95313
+ ],
+ [
+ -77.081795,
+ 38.953194
+ ],
+ [
+ -77.081828,
+ 38.953258
+ ],
+ [
+ -77.08186,
+ 38.953321
+ ],
+ [
+ -77.081892,
+ 38.953385
+ ],
+ [
+ -77.081925,
+ 38.953449
+ ],
+ [
+ -77.081957,
+ 38.953513
+ ],
+ [
+ -77.081989,
+ 38.953577
+ ],
+ [
+ -77.082022,
+ 38.953641
+ ],
+ [
+ -77.082054,
+ 38.953704
+ ],
+ [
+ -77.082086,
+ 38.953768
+ ],
+ [
+ -77.082213,
+ 38.954018
+ ],
+ [
+ -77.082245,
+ 38.954082
+ ],
+ [
+ -77.082278,
+ 38.954146
+ ],
+ [
+ -77.08231,
+ 38.95421
+ ],
+ [
+ -77.082342,
+ 38.954273
+ ],
+ [
+ -77.082375,
+ 38.954337
+ ],
+ [
+ -77.082407,
+ 38.954401
+ ],
+ [
+ -77.082439,
+ 38.954465
+ ],
+ [
+ -77.082472,
+ 38.954529
+ ],
+ [
+ -77.082504,
+ 38.954593
+ ],
+ [
+ -77.082536,
+ 38.954656
+ ],
+ [
+ -77.083705,
+ 38.956955
+ ],
+ [
+ -77.083738,
+ 38.957019
+ ],
+ [
+ -77.08377,
+ 38.957083
+ ],
+ [
+ -77.083803,
+ 38.957146
+ ],
+ [
+ -77.083835,
+ 38.95721
+ ],
+ [
+ -77.083868,
+ 38.957274
+ ],
+ [
+ -77.0839,
+ 38.957338
+ ],
+ [
+ -77.083933,
+ 38.957401
+ ],
+ [
+ -77.083965,
+ 38.957465
+ ],
+ [
+ -77.083998,
+ 38.957529
+ ],
+ [
+ -77.08403,
+ 38.957593
+ ],
+ [
+ -77.084545,
+ 38.9586
+ ],
+ [
+ -77.084565,
+ 38.958638
+ ],
+ [
+ -77.085346,
+ 38.960169
+ ],
+ [
+ -77.085757,
+ 38.960976
+ ]
+ ],
+ "type": "LineString"
+ },
+ "id": "e0369f23e7e33d9f11a695f0bf6a2498"
+ }
+ ],
+ "type": "FeatureCollection"
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/pisavector.xcassets/Contents.json b/platform/ios/demo/Examples/Files/pisavector.xcassets/Contents.json
new file mode 100644
index 0000000000..da4a164c91
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/pisavector.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/Contents.json b/platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/Contents.json
new file mode 100644
index 0000000000..8e904e7fde
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "pisa.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/pisa.pdf b/platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/pisa.pdf
new file mode 100644
index 0000000000..2fbe203c70
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/pisavector.xcassets/pisavector.imageset/pisa.pdf
Binary files differ
diff --git a/platform/ios/demo/Examples/Files/ports.geojson b/platform/ios/demo/Examples/Files/ports.geojson
new file mode 100644
index 0000000000..4579432963
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/ports.geojson
@@ -0,0 +1,18382 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sint Nicolaas",
+ "website": "www.rocargo.com/SanNicolas.html",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -69.92355713,
+ 12.4375
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Campana",
+ "website": "www.consejoportuario.com.ar",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -58.95141343,
+ -34.15333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Zarate",
+ "website": "www.consejoportuario.com.ar",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -59.004947,
+ -34.09888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Puerto Belgrano/Bahia Blanca",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -62.10088339,
+ -38.89444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Puerto Galvan/Bahia Blanca",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -62.30053004,
+ -38.78305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Ingeniero White/Bahia Blanca",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -62.25989399,
+ -38.79194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Saint John's",
+ "website": "www.ab.gov.ag",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.85229682,
+ 17.12277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Fremantle",
+ "website": "www.fremantleports.com.au",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 115.7381037,
+ -32.0475
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Botany Bay",
+ "website": "www.sydneyports.com.au",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 151.2095406,
+ -33.97305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Rockhampton",
+ "website": "www.gpcl.com.au",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 151.2842167,
+ -23.85111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Oostende (Ostend)",
+ "website": "www.portofoostende.be",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 2.93368669,
+ 51.23
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Zeebrugge",
+ "website": "www.zeebruggeport.be",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 3.20459364,
+ 51.33638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Burgas",
+ "website": "www.port-burgas.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.45830389,
+ 42.47
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Mina Sulman Port",
+ "website": "www.bahrainports.gov.bh",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 50.60759717,
+ 26.19861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sitrah",
+ "website": "www.bahrainports.gov.bh",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 50.65883392,
+ 26.15861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Saint George",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.67302709,
+ 32.37944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Mucuripe",
+ "website": "www.docasdoceara.com.br",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -38.47320377,
+ -3.7075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Niteroi",
+ "website": "www.portosrio.gov.br",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -43.1246172,
+ -22.87916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sao Francisco do Sul",
+ "website": "www.apsfs.sc.gov.br",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -48.63545347,
+ -26.23805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Chatham",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -65.46772674,
+ 47.03444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Clarenville",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -53.95689046,
+ 48.16333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Comox",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -124.9244405,
+ 49.67083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Esquimalt",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -123.4343934,
+ 48.43638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Grand Bank",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -55.75106007,
+ 47.10027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "North Sydney",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -60.2393404,
+ 46.20888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Caraquet",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.9246172,
+ 47.79638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Chicoutimi",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.05265018,
+ 48.43
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Corner Brook",
+ "website": "www.cornerbrookport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -57.93633687,
+ 48.96055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Digby",
+ "website": "www.portofdigby.ns.ca",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -65.75229682,
+ 44.62527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Harbour Grace",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -53.21702002,
+ 47.69027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Pictou",
+ "website": "www.pictoumarineterminals.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -62.70441696,
+ 45.67472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Shelburne",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -65.31772674,
+ 43.74972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sorel",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.11808009,
+ 46.04111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Springdale",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -56.05989399,
+ 49.49972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Saint-John's",
+ "website": "www.sjpa.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -52.69234393,
+ 47.5625
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Coronel",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.15335689,
+ -37.02833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Lota",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.15848057,
+ -37.09805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Talcahuano",
+ "website": "www.puertotalcahuano.cl",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.10229682,
+ -36.70527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "San Antonio",
+ "website": "www.sanantonioport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.61808009,
+ -33.5875
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Haimen",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.4418139,
+ 28.69027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Qinhuangdao",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 119.5859835,
+ 39.90666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Yantian",
+ "website": "www.yantian-port.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 114.26702,
+ 22.57416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Yingkou",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 122.2351001,
+ 40.69583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Moin",
+ "website": "www.japdeva.go.cr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.07408716,
+ 10.00555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Banes",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.70335689,
+ 20.91916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Caibarien",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.46931684,
+ 22.52916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Isabela de Sagua",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.00759717,
+ 22.94027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nuevitas",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.23951708,
+ 21.56305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Famagusta",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 33.94004711,
+ 35.12777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Cuxhaven",
+ "website": "www.cuxport.de",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.707243816,
+ 53.86472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Eckernforde",
+ "website": "www.stadtwerke-eckernfoerde.de",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.835806832,
+ 54.47361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nordenham",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.489517079,
+ 53.4875
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Papenburg",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.368963486,
+ 53.09638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Wismar",
+ "website": "www.hafen-wismar.de",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.43916372,
+ 53.90638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nyborg",
+ "website": "www.adp-as.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.80689046,
+ 55.29888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Helsingor",
+ "website": "www.helsingoerhavn.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.61702002,
+ 56.03444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Odense",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.52497055,
+ 55.46638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nyborg",
+ "website": "www.nyborg.dk/Engelsk/Tourism/NyborgsHarbours",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.78810365,
+ 55.30694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Frederikshavn",
+ "website": "www.frederikshavnhavn.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.54146054,
+ 57.43777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Haderslev",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.504416961,
+ 55.25111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Horsens",
+ "website": "www.horsenshavn.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.868433451,
+ 55.85416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kalundborg",
+ "website": "www.portofkalundborg.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.08598351,
+ 55.66944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kolding",
+ "website": "www.koldingport.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.493404005,
+ 55.49277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nakskov",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.12108363,
+ 54.83222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nykobing Falster",
+ "website": "www.guldborgsundhavne.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.85706714,
+ 54.77083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Randers",
+ "website": "www.randershavn.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.05265018,
+ 56.46027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Rudkobing",
+ "website": "www.langelandkommune.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.704947,
+ 54.93972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Svendborg",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.61702002,
+ 55.05861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Vejle",
+ "website": "www.vejleport.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.551943463,
+ 55.70555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Skagen",
+ "website": "www.skagenhavn.dk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.58881037,
+ 57.71861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Puerto Plata",
+ "website": "www.apordom.gov.do",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.70053004,
+ 19.80361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Rio Haina",
+ "website": "www.apordom.gov.do",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.01808009,
+ 18.42027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Mostaganem",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0.071260306,
+ 35.93444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Damietta",
+ "website": "www.dam-port.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 31.75918728,
+ 31.46666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Safaga",
+ "website": "www.mts.gov.eg",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 33.94128386,
+ 26.74222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Algeciras",
+ "website": "www.apba.es",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.400353357,
+ 36.14777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Aviles",
+ "website": "www.avilesport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.920023557,
+ 43.57861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Ferrol",
+ "website": "www.apfsc.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.250883392,
+ 43.47972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Huelva",
+ "website": "www.puertohuelva.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.935806832,
+ 37.19277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Pasajes",
+ "website": "www.puertopasajes.net",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.918786808,
+ 43.32333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Rota",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.334570082,
+ 36.61944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Cadiz",
+ "website": "www.puertocadiz.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.258833922,
+ 36.52
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kotka",
+ "website": "www.portofkotka.fi",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 26.9418139,
+ 60.46111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Veitsiluoto",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.61666667,
+ 65.68305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Arcachon",
+ "website": "www.arcachon.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.142343934,
+ 44.65916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Deauville",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0.073380448,
+ 49.36583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Fecamp",
+ "website": "www.fecamp.cci.fr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0.369493522,
+ 49.76194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "La Pallice",
+ "website": "www.larochelle.port.fr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.223910483,
+ 46.15722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Saint-Malo",
+ "website": "www.saint-malo.cci.fr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.022850412,
+ 48.64444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sete",
+ "website": "www.sete.port.fr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 3.71024735,
+ 43.40472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Greenock",
+ "website": "www.clydeport.co.uk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.756713781,
+ 55.95472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Poole",
+ "website": "www.phc.co.uk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.986513545,
+ 50.71444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Falmouth",
+ "website": "www.falmouthport.co.uk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.053533569,
+ 50.15277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Leith",
+ "website": "www.forthports.co.uk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.171790342,
+ 55.9825
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Montrose",
+ "website": "www.montroseport.co.uk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.467903416,
+ 56.70444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Newport",
+ "website": "www.abports.co.uk/custinfo/ports/newport.htm",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.984746761,
+ 51.55888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sunderland",
+ "website": "www.portofsunderland.org.uk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.356183746,
+ 54.90694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Teesport",
+ "website": "www.pdports.co.uk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.157067138,
+ 54.60805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Poti",
+ "website": "www.potiseaport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 41.65282686,
+ 42.155
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Piraeus",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 23.6565371,
+ 37.93722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Piraeus",
+ "website": "www.olp.gr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 23.63368669,
+ 37.94111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Piraeus",
+ "website": "www.medmarinas.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 23.64305065,
+ 37.93444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Saint George's",
+ "website": "www.grenadacruiseport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.75053004,
+ 12.04722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Cayenne",
+ "website": "www.guyane.cci.fr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -52.27196702,
+ 4.853055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Bakar",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.54075383,
+ 45.29972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Rovinj",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.63492344,
+ 45.08055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sibenik",
+ "website": "www.portauthority-sibenik.hr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.89163722,
+ 43.72638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Gonaives",
+ "website": "www.apn.gouv.ht",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.70371025,
+ 19.44833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sorong",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 131.2425206,
+ -0.876944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Alleppey",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 76.31042403,
+ 9.491944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kakinada",
+ "website": "www.kakinadaseaports.in",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 82.2746172,
+ 16.97777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Tuticorin",
+ "website": "tuticorinport.gov.in",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 78.18704358,
+ 8.758333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sligo",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.471260306,
+ 54.27166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Licata",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.93828033,
+ 37.09027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Alghero",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.30795053,
+ 40.56277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Bagnoli",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.16007067,
+ 40.80333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Barletta",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.28775029,
+ 41.32555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Brindisi",
+ "website": "www.porto.br.it",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.95600707,
+ 40.64638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Crotone",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.12338045,
+ 39.08611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Gallipoli",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.97567727,
+ 40.05583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Imperia",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.026914016,
+ 43.88277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "La Maddalena",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.409363958,
+ 41.21333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "La Spezia",
+ "website": "www.portolaspezia.it",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.850353357,
+ 44.08722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Marsala",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.43545347,
+ 37.78972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Messina",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.55918728,
+ 38.20027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Molfetta",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.58775029,
+ 41.20833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Monfalcone",
+ "website": "www.porto.monfalcone.gorizia.it",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.55265018,
+ 45.78861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Monopoli",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.30035336,
+ 40.95611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Pesaro",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.9024735,
+ 43.92083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Porto Torres",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.392167256,
+ 40.84361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Ravenna",
+ "website": "www.port.ravenna.it",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.25035336,
+ 44.46222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Siracusa",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.28757362,
+ 37.06611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Taranto",
+ "website": "www.port.taranto.it",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.18898704,
+ 40.48805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Torre Annunziata",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.44287397,
+ 40.75
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Omura",
+ "website": "www.city.omura.nagasaki.jp",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 129.9503534,
+ 32.90166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Amagasaki",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.3833333,
+ 34.69138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Fushiki",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 137.1084806,
+ 36.77583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Imabari",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 133.0061837,
+ 34.06805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Iwakuni",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 132.2352768,
+ 34.17694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kainan",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.188457,
+ 34.15305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kanazawa",
+ "website": "www.pref.ishikawa.jp",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 136.6065371,
+ 36.61694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kawasaki",
+ "website": "www.city.kawasaki.jp/58/58yuuti/home/etop.html",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 139.7437574,
+ 35.50638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kokura",
+ "website": "www.kitaqport.or.jp",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 130.8735571,
+ 33.90833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Maizuru",
+ "website": "www.port.maizuru.kyoto.jp",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.3852768,
+ 35.48166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Matsusaka",
+ "website": "www.info.city.tsu.mie.jp",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 136.5533569,
+ 34.60805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Miyazu",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.1934,
+ 35.54333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Muroran",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 140.9540636,
+ 42.33583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Niigata",
+ "website": "www.pref.niigata.lg.jp/kowanshinko/1208883684365.html",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 139.1247939,
+ 37.955
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Saganoseki",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 131.8693168,
+ 33.25138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sasebo",
+ "website": "www.city.sasebo.nagasaki.jp",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 129.7077739,
+ 33.15694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Shimizu",
+ "website": "www.portofshimizu.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 138.509894,
+ 35.01444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Shimotsu",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.1333333,
+ 34.11638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Wakayama",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.1270907,
+ 34.22305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Yokosuka",
+ "website": "www.city.yokosuka.kanagawa.jp/minato",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 139.654417,
+ 35.30444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Galle",
+ "website": "www.slpa.lk",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 80.22497055,
+ 6.033333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Ventspils",
+ "website": "www.portofventspils.lv",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.53704358,
+ 57.40305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Frontera",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -92.65212014,
+ 18.53027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Minatitlan",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -94.53457008,
+ 17.97583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Pajaritos",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -94.40053004,
+ 18.1275
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Santa Rosalia",
+ "website": "www.bajaport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -112.2584806,
+ 27.33916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Progreso",
+ "website": "www.puertosyucatan.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -89.67055359,
+ 21.31361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Tuxpan",
+ "website": "www.puerto-de-tuxpan.com.mx",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -97.37055359,
+ 20.94055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kemaman",
+ "website": "www.portsworld.com/Ports/kemamanport.htm",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 103.4591873,
+ 4.249444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Den Helder",
+ "website": "www.havendenhelder.nl",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 4.78368669,
+ 52.95805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Dordrecht",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 4.651413428,
+ 51.80583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Delfzijl",
+ "website": "www.groningen-seaports.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 6.955477032,
+ 53.32055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Arendal",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.757420495,
+ 58.45416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Drammen",
+ "website": "www.drammenhavn.no",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.22497055,
+ 59.73666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Halden",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.37532391,
+ 59.11805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Harstad",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.54163722,
+ 68.78916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Larvik",
+ "website": "www.larvikhavn.vf.no",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.02550059,
+ 59.04527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Moss",
+ "website": "www.moss-havn.no",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.65282686,
+ 59.43222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sandefjord",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.22497055,
+ 59.12361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Tonsberg",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.404947,
+ 59.265
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Lyttelton",
+ "website": "www.lpc.co.nz",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 172.7102473,
+ -43.60611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Qalhat",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 59.42055359,
+ 22.65666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sohar",
+ "website": "portofsohar.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 56.73792697,
+ 24.37833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Balboa",
+ "website": "www.ppc.com.pa",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.56878681,
+ 8.955555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Cristobal",
+ "website": "www.ppc.com.pa",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.90477032,
+ 9.350277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Pedregal",
+ "website": "www.cocatram.org.ni/puertosca/pto_pedregal_panama.html",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -82.43457008,
+ 8.365
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Callao",
+ "website": "www.enapu.com.pe",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.1418139,
+ -12.04527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Matarani",
+ "website": "www.ultramarnetwork.com/TextosPeru/Marc-024.html",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.10424028,
+ -16.99777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Swinoujscie",
+ "website": "www.phs.com.pl",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.26861013,
+ 53.905
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Leixoes",
+ "website": "www.apdl.pt",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.692873969,
+ 41.185
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Setubal",
+ "website": "www.portodesetubal.pt",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.821436985,
+ 38.48972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Aveiro",
+ "website": "www.portodeaveiro.pt",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.7196702,
+ 40.64361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Viana do Castelo",
+ "website": "www.ipnorte.pt",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.823027091,
+ 41.68638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Galati",
+ "website": "apdm.galati.ro",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 28.08386337,
+ 45.44166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nakhodka",
+ "website": "www.port-livadia.ru",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 132.9075972,
+ 42.80472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kandalaksha",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 32.404947,
+ 67.135
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kholmsk",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 142.0400471,
+ 47.05055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Korsakov",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 142.7584806,
+ 46.62666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kronshtadt",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 29.76737338,
+ 59.98694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nakhodka",
+ "website": "www.ncsp.ru",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 132.8861602,
+ 42.8
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Novorossiysk",
+ "website": "www.nle.ru",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 37.80441696,
+ 44.715
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Tuapse",
+ "website": "www.tuapseport.ru",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.06666667,
+ 44.09194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Jubail",
+ "website": "www.ports.gov.sa",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 49.67090695,
+ 27.02861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Jubail",
+ "website": "www.ports.gov.sa",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 49.67302709,
+ 27.08777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Ras al Khafji",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 48.52249706,
+ 28.415
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Falkenberg",
+ "website": "www.falkenbergs-terminal.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.47638398,
+ 56.88944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Ahus",
+ "website": "www.ahushamn.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.30547703,
+ 55.92555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Harnosand",
+ "website": "www.harnosand.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.93881037,
+ 62.64083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Hoganas",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.54146054,
+ 56.19861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Karlshamn",
+ "website": "www.karlshamnshamn.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.85830389,
+ 56.1625
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Karlskrona",
+ "website": "www.karlskrona.se/hamn",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.58598351,
+ 56.16
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nynashamn",
+ "website": "www.stoports.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.95812721,
+ 58.91333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Oskarshamn",
+ "website": "www.port.oskarshamn.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.47073027,
+ 57.265
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Oxelosund",
+ "website": "www.oxhamn.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.10795053,
+ 58.66166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Pitea",
+ "website": "www.bottenvikens-stuveri.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.47037691,
+ 65.30888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sodertalje",
+ "website": "www.soeport.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.65918728,
+ 59.16972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Trelleborg",
+ "website": "www.trelleborgshamn.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.15159011,
+ 55.36805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Uddevalla",
+ "website": "www.uddevalla-hamn.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.90477032,
+ 58.34805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Ystad",
+ "website": "www.ystad.se",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.82073027,
+ 55.42138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Bangkok",
+ "website": "www.bkp.port.co.th",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 100.5849234,
+ 13.69583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Laem Chabang",
+ "website": "www.port.co.th",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 100.8909305,
+ 13.07388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sriracha",
+ "website": "www.srirachaport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 100.9186101,
+ 13.17138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Point Lisas",
+ "website": "www.plipdeco.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.48951708,
+ 10.38833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Mersin",
+ "website": "www.tcdd.gov.tr",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 34.64057715,
+ 36.79694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Berdyansk",
+ "website": "www.ukrport.org.ua",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 36.77320377,
+ 46.75138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Kerch",
+ "website": "www.ukrport.org.ua",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 36.48563015,
+ 45.355
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Richmond",
+ "website": "www.ci.richmond.ca.us/index.asp?NID=102",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.3590106,
+ 37.91388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Wilmington",
+ "website": "www.portofwilmingtonde.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.51984688,
+ 39.71666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Quincy",
+ "website": "www.forerivershipyard.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.96896349,
+ 42.24138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Nawiliwili",
+ "website": "www.state.hi.us/dot/harbors",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -159.3530035,
+ 21.95388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Monterey",
+ "website": "www.monterey.org/harbor",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -121.888987,
+ 36.60555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Wilmington",
+ "website": "www.ncports.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.95265018,
+ 34.19194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Gloucester City",
+ "website": "www.holtoversight.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.12267373,
+ 39.90361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Bayonne",
+ "website": "www.bayonnenj.org",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -74.1024735,
+ 40.6625
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Baltimore",
+ "website": "www.mpa.state.md.us",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.55565371,
+ 39.2325
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Jacksonville",
+ "website": "www.jaxport.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -81.55918728,
+ 30.38083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Newport News",
+ "website": "www.vaports.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.4262073,
+ 36.98055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Port Arthur",
+ "website": "www.portofportarthur.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -93.95706714,
+ 29.84305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Portsmouth",
+ "website": "www.vaports.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.28828033,
+ 36.81666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Wilmington",
+ "website": "www.ncports.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.95265018,
+ 34.19194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Port Arthur",
+ "website": "www.portofportarthur.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -93.95706714,
+ 29.84305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Alexandria",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.03722026,
+ 38.80111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Newport News",
+ "website": "www.vaports.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.4262073,
+ 36.98055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Brownsville",
+ "website": "www.portofbrownsville.org",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.6086572,
+ 47.65138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Vancouver",
+ "website": "www.portvanusa.com",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.7038869,
+ 45.63472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Guanta",
+ "website": "www.puertodeguanta.gob.ve",
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.59040047,
+ 10.24916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Keelung",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.72583696694346,
+ 25.220760141757456
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Arrecife",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -13.623954376704255,
+ 28.948964844057482
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "St Thomas",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.92841530036452,
+ 18.332123222010704
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Basseterre",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -62.750002499299285,
+ 17.27882702118545
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "New Orleans",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -90.05637124381114,
+ 29.93419996813862
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Freeport",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -78.72766361581795,
+ 26.5384106344139
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Trenton",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.56,
+ 44.1
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Goderich",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -81.73,
+ 43.75
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Midland",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.91,
+ 44.75
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "St Joseph",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -86.48,
+ 42.11
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Racine",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.78,
+ 42.73
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Menominee",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.6,
+ 45.1
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Escanaba",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.05,
+ 45.76
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Sacramento",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -121.5,
+ 38.58
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Great Yarmouth",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.73,
+ 52.61
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Dundee",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.96,
+ 56.46
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Portmahomack Harbor",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.83,
+ 57.83
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Wick",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.08,
+ 58.43
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Oban",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.46,
+ 56.41
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Douglas",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.46,
+ 54.15
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Londonderry",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -7.31,
+ 55
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 8,
+ "name": "Silloth",
+ "website": null,
+ "natlscale": 5,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.4,
+ 54.86
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ambriz",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.09375736,
+ -7.833055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cabinda",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.19022379,
+ -5.55
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Soyo",
+ "website": "www.otal.com/angola",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.32037691,
+ -6.121388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Durres",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 19.45300353,
+ 41.30777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Curacao",
+ "website": "www.curports.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -68.91825677,
+ 12.11916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Al Fujayrah",
+ "website": "www.fujairahport.ae",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 56.3565371,
+ 25.17833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Caleta Olivia",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.50848057,
+ -46.43305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Puerto Deseado",
+ "website": "www.scruz.gov.ar/puertos",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -65.9040636,
+ -47.75555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Rio Gallegos",
+ "website": "www.scruz.gov.ar/puertos",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -69.21825677,
+ -51.61166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Rio Grande",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.7024735,
+ -53.79444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "San Julian",
+ "website": "www.scruz.gov.ar/puertos",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.71896349,
+ -49.29972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Coffs Harbour",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 153.1414605,
+ -30.3075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Esperance",
+ "website": "www.esperanceport.com.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.893404,
+ -33.87194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Port Augusta",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 137.7567138,
+ -32.48861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bowen",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 148.25053,
+ -20.02083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bundaberg",
+ "website": "www.portofbundaberg.com.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 152.38846,
+ -24.76722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Burketown",
+ "website": "www.cairnsports.com.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 139.737927,
+ -17.55361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Carnarvon",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 113.642874,
+ -24.895
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cooktown",
+ "website": "www.cairnsports.com.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 145.2437574,
+ -15.45972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Derby",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 123.6051237,
+ -17.29222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Eden",
+ "website": "www.eden.nsw.gov.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 149.9053004,
+ -37.07194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "George Town",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 146.8202002,
+ -41.10972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Geraldton",
+ "website": "www.gpa.wa.gov.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 114.6007067,
+ -28.77277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Karumba",
+ "website": "www.cairnsports.com.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 140.8333333,
+ -17.48944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kingscote",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 137.6395171,
+ -35.655
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Maryborough",
+ "website": "www.nqbp.com.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 152.9060071,
+ -25.295
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Strahan",
+ "website": "www.tasports.com.au",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 145.3205536,
+ -42.15833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Mongla",
+ "website": "www.monglaport.com.bd",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 89.58598351,
+ 22.48694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Aracaju",
+ "website": "www.ibritto.com.br",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -37.03951708,
+ -10.92527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Fortaleza",
+ "website": "www.docasdoceara.com.br",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -38.52143698,
+ -3.7175
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Macapa",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -51.04269729,
+ 0.032222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Navegantes",
+ "website": "www.portonave.com.br",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -48.65424028,
+ -26.89888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pelotas",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -52.3237338,
+ -31.78194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Campbell River",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -125.2386337,
+ 50.03194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Goose Bay",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -60.34234393,
+ 53.38444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Masset",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -132.1411072,
+ 54.00666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Matane",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.57126031,
+ 48.84194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nanisivik",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -84.54305065,
+ 73.06861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "New Richmond",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -65.83492344,
+ 48.13861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Port Hardy",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -127.4836867,
+ 50.72111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Port Hawkesbury",
+ "website": "www.straitsuperport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.35565371,
+ 45.61
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Squamish",
+ "website": "www.sqterminals.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -123.1666667,
+ 49.68305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Stephenville",
+ "website": "www.portharmonauthority.ca",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -58.54075383,
+ 48.53527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Stewart",
+ "website": "www.stewart-hyder.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -129.9895171,
+ 55.92861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tahsis",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -126.6540636,
+ 49.9175
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sandspit",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -131.8196702,
+ 53.25527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tuktoyaktuk",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -132.9858068,
+ 69.43138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ancud",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.82567727,
+ -41.86861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Castro",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.76684335,
+ -42.48277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Chanaral",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.6343934,
+ -26.35055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Puerto Natales",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.50936396,
+ -51.73111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Taltal",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.48457008,
+ -25.39722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Guangzhou",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 113.6710836,
+ 22.64027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Jiangyin",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 120.2212603,
+ 31.93194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Lianyungang",
+ "website": "www.lygport.com.cn",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 119.4084806,
+ 34.74527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sanya",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 109.50053,
+ 18.23972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Zhanjiang",
+ "website": "www.zjport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 110.4063604,
+ 21.16972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Zhoushan",
+ "website": "www.zsport.com.cn",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 122.1026502,
+ 30.00333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "San-Pedro",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.617020024,
+ 4.743055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cartagena",
+ "website": "www.sprc.com.co",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.52567727,
+ 10.40333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tolu",
+ "website": "www.navescolombia.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.5852768,
+ 9.520277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tumaco",
+ "website": "www.navescolombia.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -78.75954064,
+ 1.813055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Turbo",
+ "website": "www.navescolombia.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.73386337,
+ 8.087777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Baracoa",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -74.50229682,
+ 20.35305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nicaro",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.55088339,
+ 20.71333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nueva Gerona",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -82.79322733,
+ 21.90333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Helgoland",
+ "website": "www.helgoland.de",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.891283863,
+ 54.1775
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Travemunde",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.86825677,
+ 53.95222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Thisted",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.692167256,
+ 56.95277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Manta",
+ "website": "www.apmanta.gov.ec",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.72090695,
+ -0.935555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Esmeraldas",
+ "website": "www.puertoesmeraldas.gov.ec",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.64269729,
+ 0.989444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Corralejo",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -13.85883392,
+ 28.74138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ceuta",
+ "website": "www.puertodeceuta.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.310424028,
+ 35.89027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Melilla",
+ "website": "www.puertodemelilla.es",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.922850412,
+ 35.28
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "San Sebastian de la Gomera",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -17.10512367,
+ 28.08805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Santa Cruz de La Palma",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -17.76666667,
+ 28.67583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Parnu",
+ "website": "www.transcom.ee",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.4746172,
+ 58.38111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kuopio",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.68987044,
+ 62.88833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Joensuu",
+ "website": "www.jns.fi",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 29.77709069,
+ 62.60444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Varkaus",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.87479388,
+ 62.3125
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Savusavu",
+ "website": "www.fijiports.com.fj",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 179.30936,
+ -16.81777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cherbourg",
+ "website": "www.ville-cherbourg.fr/fr/ville_maritime/port_de_plaisance/",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.620376914,
+ 49.64638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Caen",
+ "website": "www.caen.port.fr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.326383981,
+ 49.19055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Calvi",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.755300353,
+ 42.56583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Propriano",
+ "website": "www.corse-du-sud.cci.fr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.900353357,
+ 41.67694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Quimper",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.108127208,
+ 47.98944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Vannes",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.756360424,
+ 47.64388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Yap",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 138.1194935,
+ 9.513333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bristol",
+ "website": "www.bristolport.co.uk",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.707773852,
+ 51.49888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Hull",
+ "website": "www.abports.co.uk/custinfo/ports/hull.htm",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.285100118,
+ 53.74361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Newcastle upon Tyne",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.590930506,
+ 54.965
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tyne",
+ "website": "www.portoftyne.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.440930506,
+ 54.99444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Rochester",
+ "website": "www.thamesport.co.uk",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0.685806832,
+ 51.43472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tema",
+ "website": "www.ghanaports.gov.gh",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0.007420495,
+ 5.631944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Alexandroupolis",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 25.88916372,
+ 40.84138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kos",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.28987044,
+ 36.89444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Paros",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 25.15070671,
+ 37.08777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Samos",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 26.96666667,
+ 37.75444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nanortalik",
+ "website": "www.ral.gl",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -45.23810365,
+ 60.13972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Qaanaaq",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -69.23510012,
+ 77.46694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "New Amsterdam",
+ "website": "www.gnsc.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -57.52179034,
+ 6.237777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "La Ceiba",
+ "website": "www.enp.hn",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -86.75689046,
+ 15.79388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tela",
+ "website": "www.enp.hn",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.45583039,
+ 15.78388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Mali Losinj",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.45759717,
+ 44.53833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Jacmel",
+ "website": "www.apn.gouv.ht",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.53598351,
+ 18.23166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Jeremie",
+ "website": "www.apn.gouv.ht",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -74.10706714,
+ 18.64361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sorong",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 131.0203769,
+ -1.3075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Lhokseumawe",
+ "website": "www.inaport1.co.id",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 97.14287397,
+ 5.166666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nunukan",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 117.654947,
+ 4.145555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Panjang",
+ "website": "portal.inaport2.co.id",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 105.3070671,
+ -5.460277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tanjung Priok",
+ "website": "www.priokport.co.id",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 106.8904005,
+ -6.101388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Mangalore",
+ "website": "www.newmangalore-port.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 74.80742049,
+ 12.92694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Porbandar",
+ "website": "www.gmbports.org",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 69.58739694,
+ 21.63944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ratnagiri",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 73.27179034,
+ 17.00194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bantry",
+ "website": "bantrybayport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -9.456183746,
+ 51.68055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Wexford",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.456183746,
+ 52.34111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Khorramshahr",
+ "website": "www.khport.ir",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 48.18545347,
+ 30.4325
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Djupivogur",
+ "website": "www.djupivogur.is",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -14.28651355,
+ 64.66055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Faskrudsfjordur",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -14.00883392,
+ 64.92972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Raufarhofn",
+ "website": "www.raufarhofn.is",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -15.94146054,
+ 66.45638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pantelleria",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.93792697,
+ 36.83333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Catania",
+ "website": "www.porto.catania.it",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.09093051,
+ 37.49583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Fiumicino",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.23545347,
+ 41.75583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Lampedusa",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.6024735,
+ 35.49916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Manfredonia",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.92532391,
+ 41.62416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ocho Rios",
+ "website": "www.portjam.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.10671378,
+ 18.41027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Port Antonio",
+ "website": "www.portjam.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.45176678,
+ 18.18111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nishinoomote",
+ "website": "www.city.nishinoomote.kagoshima.jp",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 130.9856302,
+ 30.73166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Akita",
+ "website": "www.city.akita.akita.jp/city/in/hb/port",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 140.0398704,
+ 39.76222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Hachinohe",
+ "website": "www.pref.aomori.lg.jp/kowankuko/english/minato/hachinohe/hachinohe.htm",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 141.5235571,
+ 40.54583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ishigaki",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 124.1512367,
+ 24.33555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Matsuyama",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 132.6934,
+ 33.85527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sakata",
+ "website": "www.port-of-sakata.jp",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 139.8035336,
+ 38.93944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Takamatsu",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 134.0533569,
+ 34.35527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Wakkanai",
+ "website": "www.city.wakkanai.hokkaido.jp",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 141.6891637,
+ 45.41055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tottori",
+ "website": "www.city.tottori.lg.jp",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 134.187927,
+ 35.54027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Lamu",
+ "website": "www.kpa.co.ke",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 40.90159011,
+ -2.268055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Gunsan",
+ "website": "gunsan.mltm.go.kr/eng",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 126.5881037,
+ 35.95972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pohang",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 129.4028269,
+ 36.01972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Samcheok",
+ "website": "donghae.momaf.go.kr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 129.1882803,
+ 37.43361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sokcho",
+ "website": "donghae.momaf.go.kr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 128.5923439,
+ 38.20694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ulsan",
+ "website": "ulsan.mltm.go.kr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 129.3856302,
+ 35.48777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tripoli",
+ "website": "www.tripoliport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 35.81914016,
+ 34.45527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Buchanan",
+ "website": "www.nationalportauthorityliberia.org",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -10.05265018,
+ 5.858055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tripoli",
+ "website": "www.lpclibya.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.19358068,
+ 32.9075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Agadir",
+ "website": "www.marsamaroc.co.ma",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -9.634923439,
+ 30.42388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Al Hoceima",
+ "website": "http://www.marsamaroc.co.ma",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.919846879,
+ 35.24777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Dakhla",
+ "website": "www.marsamaroc.co.ma",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -15.93386337,
+ 23.68222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Antalaha",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 50.2762073,
+ -14.9
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Manakara",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 48.01878681,
+ -22.1425
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Mananjary",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 48.3262073,
+ -21.24916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Morondava",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 44.27196702,
+ -20.28861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Toamasina",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 49.42196702,
+ -18.15722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Loreto",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -111.3368669,
+ 26.01472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Campeche",
+ "website": "www.fis.com/campeche",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -90.59040047,
+ 19.8125
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cozumel",
+ "website": "www.apiqroo.com.mx",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -86.95742049,
+ 20.495
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "La Paz",
+ "website": "www.bajaport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -110.310424,
+ 24.16944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Playa del Carmen",
+ "website": "www.apiqroo.com.mx",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.06772674,
+ 20.62444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Puerto Penasco",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -113.5423439,
+ 31.30611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Puerto Vallarta",
+ "website": "www.apivta.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -105.2409305,
+ 20.65916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Coatzacoalcos",
+ "website": "www.apicoatza.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -94.41896349,
+ 18.12972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bassein",
+ "website": "www.mot.gov.mm/mpa/index.html",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 94.72338045,
+ 16.77972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nacala",
+ "website": "www.cfmnet.co.mz",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 40.6671967,
+ -14.54138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pemba",
+ "website": "www.cfmnet.co.mz",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 40.48492344,
+ -12.96666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Quelimane",
+ "website": "www.cfmnet.co.mz",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 36.87709069,
+ -17.88166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Port Louis",
+ "website": "www.mauport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 57.48987044,
+ -20.14805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Malacca",
+ "website": "www.portsworld.com/Ports/mallacaport.htm",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 102.1233804,
+ 2.248888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Port Dickson",
+ "website": "www.portsworld.com/Ports/portdickson.htm",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 101.7886337,
+ 2.536111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Walvis Bay",
+ "website": "www.namport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.50053004,
+ -22.94055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Calabar",
+ "website": "www.nigerianports.org",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.316843345,
+ 4.986388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Groningen",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 6.586866902,
+ 53.21833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Alta",
+ "website": "www.altahavn.no",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 23.23704358,
+ 69.96777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Andenes",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.1237338,
+ 69.32416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bronnoysund",
+ "website": "www.bronnoyhavn.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.20194346,
+ 65.4725
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Farsund",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 6.789870436,
+ 58.08861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Floro",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.002826855,
+ 61.59777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kristiansand",
+ "website": "www.kristiansandhavn.no",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.986336867,
+ 58.14194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Namsos",
+ "website": "www.namsos.kommune.no",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.49004711,
+ 64.46416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Rorvik",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.22691402,
+ 64.86055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sandnessjoen",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.61878681,
+ 66.02166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Stokmarknes",
+ "website": "www.hadselhavnevesen.no",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.90989399,
+ 68.56833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Stord",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.501413428,
+ 59.78
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Picton",
+ "website": "portmarlborough.co.nz",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 174.00442,
+ -41.28555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Dunedin",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 170.5193168,
+ -45.87583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Salalah",
+ "website": "www.salalahport.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 54.00318021,
+ 16.94166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Gwadar",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 62.33863369,
+ 25.11222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bocas del Toro",
+ "website": "www.cocatram.org.ni/puertosca/pto_bocasdeltoro_panama.html",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -82.23757362,
+ 9.34
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "La Palma",
+ "website": "www.cocatram.org.ni/puertosca/pto_lapalma_panama.html",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -78.15106007,
+ 8.413611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Chimbote",
+ "website": "www.enapu.com.pe",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -78.60777385,
+ -9.076666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ilo",
+ "website": "www.enapu.com.pe",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.34375736,
+ -17.64694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Mollendo",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.01024735,
+ -17.03111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pisco",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.22196702,
+ -13.73305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Dumaguete",
+ "website": "www.ppa.com.ph",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 123.3081272,
+ 9.311944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "General Santos",
+ "website": "www.ppa.com.ph",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 125.1542403,
+ 6.086111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Buka",
+ "website": "www.pngports.com.pg",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 154.671967,
+ -5.431944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Daru",
+ "website": "www.pngports.com.pg",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 143.2065371,
+ -9.068333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Lae",
+ "website": "www.pngports.com.pg",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 146.9847468,
+ -6.741111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Madang",
+ "website": "www.pngports.com.pg",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 145.8003534,
+ -5.213333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Gdansk",
+ "website": "www.portgdansk.pl",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.66878681,
+ 54.39333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Gdynia",
+ "website": "www.port.gdynia.pl",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.53845701,
+ 54.53333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Aguadilla",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.15706714,
+ 18.42944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Arecibo",
+ "website": "www.prpa.gobierno.pr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -66.70035336,
+ 18.48138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Mayaguez",
+ "website": "www.prpa.gobierno.pr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.15689046,
+ 18.21388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Faro",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -7.926030624,
+ 37.01055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bora-Bora",
+ "website": "www.portdepapeete.pf",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -151.75,
+ -16.51666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tulcea",
+ "website": "apdm.galati.ro",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 28.81684335,
+ 45.19111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Amderma",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 61.55918728,
+ 69.75611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Anadyr",
+ "website": "morport.chukotnet.ru",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 177.5386337,
+ 64.74416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pevek",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 170.2770907,
+ 69.70166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kaolack",
+ "website": "www.portdakar.sn",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -16.07196702,
+ 14.12944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ziguinchor",
+ "website": "www.portdakar.sn",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -16.26808009,
+ 12.58972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Longyearbyen",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.6237338,
+ 78.22611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Gizo",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 156.8388104,
+ -8.101388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Viru Harbour",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 157.7260306,
+ -8.499722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kismayu",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 42.54110718,
+ -0.374166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Karlstad",
+ "website": "www.vanerhamn.se",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.52020024,
+ 59.37527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Lidkoping",
+ "website": "www.vanerhamn.se",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.15936396,
+ 58.50916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Skelleftea",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.25176678,
+ 64.67833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Umea",
+ "website": "www.umeahamn.se",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 20.26772674,
+ 63.81666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Providenciales",
+ "website": "www.turksandcaicosislands.gov.tc",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.25600707,
+ 21.76277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Songkhla",
+ "website": "www.md.go.th",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 100.5696702,
+ 7.228611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bandirma",
+ "website": "www.tcdd.gov.tr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.95724382,
+ 40.35416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Samsun",
+ "website": "www.tcdd.gov.tr",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 36.34040047,
+ 41.29972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sinop",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 35.14287397,
+ 42.02333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Trabzon",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.73651355,
+ 41.00555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sevastopol",
+ "website": "ukrport.org.ua",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 33.54146054,
+ 44.61888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Skagway",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -135.3223204,
+ 59.45083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Valdez",
+ "website": "www.ci.valdez.ak.us/port",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -146.3570671,
+ 61.10361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Apalachicola",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -84.98669022,
+ 29.7275
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Annapolis",
+ "website": "www.portannapolis.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.47426384,
+ 38.965
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cambridge",
+ "website": "www.ci.cambridge.md.us",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.07108363,
+ 38.57416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Portland",
+ "website": "www.portofportlandor.com",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.7836867,
+ 45.60583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bremerton",
+ "website": "www.portofbremerton.org",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.6377503,
+ 47.5625
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Rockland",
+ "website": "www.ci.rockland.me.us",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -69.10212014,
+ 44.10305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Santa Cruz",
+ "website": "www.santacruzharbor.org",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.0014134,
+ 36.96638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Chesapeake",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.23951708,
+ 36.7225
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cumana",
+ "website": "www.selinger.com/cumana.htm",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.18775029,
+ 10.47416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Hai Phong",
+ "website": "www.haiphongport.com.vn",
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 106.6751472,
+ 20.86722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Corfu",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 19.910572060487087,
+ 39.621950140387334
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Alexandria",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 30.16765718634613,
+ 31.334923292880035
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tangier",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.824954241841614,
+ 35.79611353569427
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Hamilton",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.85,
+ 43.25
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Windsor",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.03,
+ 42.31
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Rouge River",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.11,
+ 42.28
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Owen Sound",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.93,
+ 44.58
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sault Ste Marie",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -84.35,
+ 46.51
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Saginaw",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.93,
+ 43.43
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cheboygan",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -84.46,
+ 45.65
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Sault Ste Marie",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -84.35,
+ 46.5
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Muskegon",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -86.26,
+ 43.23
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Gary",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.33,
+ 41.61
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Waukegan",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.81,
+ 42.36
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Houghton",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -88.56,
+ 47.11
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Wrangell",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -132.38,
+ 56.46
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Petersburg",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -132.95,
+ 56.81
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kemi",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.56,
+ 65.73
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Vaasa",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.58,
+ 63.1
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Turku",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 22.23,
+ 60.45
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Liepaja",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.01,
+ 56.51
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Europoort",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 4.11,
+ 51.95
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Stornoway Harbor",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.36,
+ 58.18
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Lisboa",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -9.16,
+ 38.7
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bonanza",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.33,
+ 36.8
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ibiza",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.45,
+ 38.9
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Rostov-Na-Donu",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.71,
+ 47.16
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tel Aviv Yafo",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 34.76,
+ 32.06
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tunis",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.25,
+ 36.8
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bejaia",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.08,
+ 36.75
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Alger",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 3.06,
+ 36.76
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "St Louis",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -16.51,
+ 16.01
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Tin Can Island",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 3.3,
+ 6.41
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Mocambique",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 40.73,
+ -15.03
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Assab",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 42.75,
+ 13
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Massawa",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.46,
+ 15.61
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Elat",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 34.95,
+ 29.55
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Al Kuwayt",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 47.96,
+ 29.38
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Bombay",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 72.83,
+ 18.83
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Jawaharlal Nehru Port",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 72.93,
+ 18.95
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Cochin",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 76.23,
+ 9.96
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Madras",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 80.3,
+ 13.1
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Calcutta",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 88.31,
+ 22.55
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Phuket",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 98.4,
+ 7.83
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pulau Pinang",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 100.35,
+ 5.41
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Belawan",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 98.68,
+ 3.78
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Semarang",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 110.41,
+ -6.95
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kupang",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 123.58,
+ -10.16
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kuching",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 110.35,
+ 1.56
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Miri",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 113.96,
+ 4.38
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Kota Kinabalu",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 116.06,
+ 5.98
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Pelabuhan Sandakan",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 118.11,
+ 5.83
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Ujungpandang",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 119.4,
+ -5.13
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Davao",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 125.61,
+ 7.06
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Nanjing",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 118.75,
+ 32.08
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Hankow",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 114.28,
+ 30.58
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Chang Sha",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 112.98,
+ 28.2
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Khabarovsk",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.16,
+ 48.5
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 7,
+ "name": "Petropavlovsk",
+ "website": null,
+ "natlscale": 10,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 158.65,
+ 53.05
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Namibe",
+ "website": "www.otal.com/angola",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.13545347,
+ -15.19361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bahia Blanca",
+ "website": "www.puertobahiablanca.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -62.27090695,
+ -38.79138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "La Plata",
+ "website": "www.laplataport.com.ar",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -57.89022379,
+ -34.85527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ushuaia",
+ "website": "www.puertoushuaia.gov.ar",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -68.30088339,
+ -54.80944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Puerto Madryn",
+ "website": "www.appm.com.ar",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -65.03333333,
+ -42.73611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Pago Pago",
+ "website": "americansamoa.gov",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -170.687927,
+ -14.27416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Mackay",
+ "website": "www.nqbp.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 149.2237338,
+ -21.10833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Lincoln",
+ "website": "www.flindersports.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.8694935,
+ -34.71833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Pirie",
+ "website": "www.flindersports.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 138.0072438,
+ -33.17694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Albany",
+ "website": "www.albanyport.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 117.8866902,
+ -35.03166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Barrow Island",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 115.4709069,
+ -20.72583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bunbury",
+ "website": "www.byport.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 115.6512367,
+ -33.31527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Burnie",
+ "website": "www.tasports.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 145.9081272,
+ -41.05277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Geelong",
+ "website": "www.geelongport.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 144.3873969,
+ -38.12666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Gladstone",
+ "website": "www.gpcl.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 151.2517668,
+ -23.83
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Newcastle",
+ "website": "www.newportcorp.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 151.7691402,
+ -32.9075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Kembla",
+ "website": "www.kemblaport.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 150.8935807,
+ -34.4625
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Portland",
+ "website": "www.portofportland.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 141.609364,
+ -38.34916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Thursday Island",
+ "website": "www.cairnsports.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 142.2189635,
+ -10.58555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Townsville",
+ "website": "www.townsville-port.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 146.8247939,
+ -19.25083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Weipa",
+ "website": "www.nqbp.com.au",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 141.8666667,
+ -12.67
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Whyalla",
+ "website": "www.onesteel.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 137.5907538,
+ -33.03833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Wyndham",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 128.1008834,
+ -15.45138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Brussel (Bruxelles)",
+ "website": "www.portdebruxelles.irisnet.be",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 4.386160188,
+ 50.88611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Gent (Ghent)",
+ "website": "www.havengent.be",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 3.76737338,
+ 51.11444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ilheus",
+ "website": "www.codeba.com.br",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -39.02567727,
+ -14.78027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Maceio",
+ "website": "www.portodemaceio.com.br",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -35.72232038,
+ -9.678888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Natal",
+ "website": "www.codern.com.br",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -35.2,
+ -5.783055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Rio Grande",
+ "website": "www.portoriogrande.com.br",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -52.0762073,
+ -32.05611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Vitoria",
+ "website": "www.portodevitoria.com.br",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -40.33510012,
+ -20.32333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ocean Falls",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -127.6888104,
+ 52.35083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Argentia",
+ "website": "www.argentia.ca/port.html",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -53.9868669,
+ 47.29305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bathurst",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -65.65,
+ 47.61666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Gaspe",
+ "website": "www.tc.gc.ca/quebec/en/port/gaspe.htm",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.43722026,
+ 48.82444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Alberni",
+ "website": "www.portalberniportauthority.ca",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -124.8193168,
+ 49.23
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Powell River",
+ "website": "www.powellriver.ca",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -124.5247939,
+ 49.835
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Sept-Iles",
+ "website": "www.portsi.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -66.38386337,
+ 50.20638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Sydney",
+ "website": "www.portofsydney.ca",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -60.20300353,
+ 46.14194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Trois-Rivieres (Three Rivers)",
+ "website": "www.porttr.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.53898704,
+ 46.33583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Yarmouth",
+ "website": "www.portofyarmouth.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -66.12090695,
+ 43.83555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Rimouski",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -68.50812721,
+ 48.47777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Riviere-du-Loup",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -69.56808009,
+ 47.84666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Saint-Anthony",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -55.57709069,
+ 51.36666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Summerside",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -63.78704358,
+ 46.38861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Arica",
+ "website": "www.puertoarica.cl",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.32196702,
+ -18.47305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tocopilla",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.20565371,
+ -22.08611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Beihai",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 109.0705536,
+ 21.45861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Jiangmen",
+ "website": "www.jmct.com.cn",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 113.0019435,
+ 22.5025
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Wenzhou",
+ "website": "www.wzport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 120.8847468,
+ 27.99833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Yantai",
+ "website": "www.yantaiport.com.cn",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.388987,
+ 37.57111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Zhuhai",
+ "website": "www.zhuhai-port.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 113.5842167,
+ 22.23972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Santa Marta",
+ "website": "www.spsm.com.co",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -74.21702002,
+ 11.25194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Buenaventura",
+ "website": "www.puertobuenaventura.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.05335689,
+ 3.883055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Praia",
+ "website": "www.enapor.cv",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -23.50318021,
+ 14.94472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Golfito",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.16666667,
+ 8.637777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Cienfuegos",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.45371025,
+ 22.14
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Manzanillo",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.13351001,
+ 20.3375
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Matanzas",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -81.53704358,
+ 23.05138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Santiago de Cuba",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.85671378,
+ 20.00166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Emden",
+ "website": "www.seaport-emden.de",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.192873969,
+ 53.34611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Flensburg",
+ "website": "www.flensburg-tourismus.de",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.436866902,
+ 54.80333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Wilhelmshaven",
+ "website": "www.wilhelmshaven-port.de",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.122143698,
+ 53.53
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Esbjerg",
+ "website": "www.port-of-esbjerg.dk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.433863369,
+ 55.46555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Odense",
+ "website": "www.odensehavn.dk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.3868669,
+ 55.4175
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Sonderborg",
+ "website": "www.sonderborg-kommune.dk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.776737338,
+ 54.90694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ronne",
+ "website": "www.roennehavn.dk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.68775029,
+ 55.09611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Barahona",
+ "website": "www.apordom.gov.do",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.08651355,
+ 18.21222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Cabo Rojo",
+ "website": "www.apordom.gov.do",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.654947,
+ 17.92527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Oran",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.636690224,
+ 35.7125
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "A Coruna",
+ "website": "www.puertocoruna.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.387926973,
+ 43.36305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Almeria",
+ "website": "www.apalmeriamotril.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.471260306,
+ 36.83222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Gijon",
+ "website": "www.puertogijon.es",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.688633687,
+ 43.55861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "San Sebastian",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.986866902,
+ 43.32277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Santander",
+ "website": "www.puertosantander.es",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.804946996,
+ 43.44222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tarragona",
+ "website": "www.porttarragona.es",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.220200236,
+ 41.09611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Oulu",
+ "website": "www.ouluport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 25.45459364,
+ 65.01583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bayonne",
+ "website": "www.bayonne.cci.fr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.493757362,
+ 43.51972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Boulogne-sur-Mer",
+ "website": "www.portboulogne.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.575500589,
+ 50.72361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Brest",
+ "website": "www.brest.port.fr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.471436985,
+ 48.38055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Cannes",
+ "website": "www.riviera-ports.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.009187279,
+ 43.54805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Cherbourg",
+ "website": "www.port-cherbourg.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.617550059,
+ 49.65222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Dieppe",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.08598351,
+ 49.92638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Granville",
+ "website": "www.granville.cci.fr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.601060071,
+ 48.83472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "La Rochelle",
+ "website": "www.larochelle.port.fr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.157773852,
+ 46.14666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Lorient",
+ "website": "www.lorient.port.fr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.352120141,
+ 47.73416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Morlaix",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.834923439,
+ 48.58527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Rochefort",
+ "website": "www.rochefort.port.fr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.953003534,
+ 45.94916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Toulon",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.904770318,
+ 43.11055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Owendo",
+ "website": "www.ports-gabon.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.500883392,
+ 0.288333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Aberdeen",
+ "website": "www.aberdeen-harbour.co.uk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -2.074617197,
+ 57.14222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Liverpool",
+ "website": "www.merseydocks.co.uk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.007243816,
+ 53.43638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Plymouth",
+ "website": "www.abports.co.uk/custinfo/ports/plym.htm",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.154063604,
+ 50.36472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Portsmouth",
+ "website": "www.portsmouth-port.co.uk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.1,
+ 50.8075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Batumi",
+ "website": "www.batumiport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 41.65053004,
+ 41.64888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kavala",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.40194346,
+ 40.93138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Chios",
+ "website": "www.chiosport.gr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 26.13775029,
+ 38.37722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kalamata",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 22.10812721,
+ 37.02277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Patras",
+ "website": "www.patrasport.gr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.73492344,
+ 38.25444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Volos",
+ "website": "www.port-volos.gr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 22.93669022,
+ 39.35277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Uummannaq",
+ "website": "www.ral.gl",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -52.11914016,
+ 70.67472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Puerto Barrios",
+ "website": "www.puertobarriosonline.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -88.6040636,
+ 15.72833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Pula",
+ "website": "www.luckauprava-pula.hr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.83474676,
+ 44.87166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Rijeka",
+ "website": "www.portauthority.hr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.42232038,
+ 45.3275
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Split",
+ "website": "www.portsplit.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.42550059,
+ 43.515
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Banjarmasin",
+ "website": "www.pp3.co.id",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 114.5553004,
+ -3.321944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tanjung Pandan",
+ "website": "portal.inaport2.co.id",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 107.6270907,
+ -2.75
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Blair",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 92.72391048,
+ 11.67222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kandla",
+ "website": "www.kandlaport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 70.22232038,
+ 23.01361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Pondicherry",
+ "website": "port.pon.nic.in",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 79.82232038,
+ 11.91416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Cork",
+ "website": "www.portofcork.ie",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.424440518,
+ 51.90111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Galway",
+ "website": "www.galwayharbour.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -9.043757362,
+ 53.27
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bushehr",
+ "website": "www.pso.ir",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 50.8368669,
+ 28.98472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ancona",
+ "website": "www.autoritaportuale.ancona.it",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.49234393,
+ 43.61833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bari",
+ "website": "www.porto.bari.it",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.85530035,
+ 41.13694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Cagliari",
+ "website": "www.porto.cagliari.it",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.107597173,
+ 39.20416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Olbia",
+ "website": "www.olbiagolfoaranci.it",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.517903416,
+ 40.92277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Pescara",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.2237338,
+ 42.46777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Reggio Calabria",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.64375736,
+ 38.12444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Trapani",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.50388693,
+ 38.01361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Aomori",
+ "website": "www.pref.aomori.lg.jp/kowankuko/english/minato/aomori/aomori.htm",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 140.742874,
+ 40.83138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Hakodate",
+ "website": "www.hakodate-port.jp",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 140.7090106,
+ 41.78777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kagoshima",
+ "website": "www.pref.kagoshima.jp/home/kowanka/cruise-net/english/01kagoshima",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 130.5687868,
+ 31.5925
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kochi",
+ "website": "www.pref.kochi.lg.jp",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 133.5570671,
+ 33.52416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kushiro",
+ "website": "www.city.kushiro.hokkaido.jp",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 144.3522968,
+ 42.98861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Niihama",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 133.2595406,
+ 33.97083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Oita",
+ "website": "www.pref.oita.jp/14300/faz/faz1/english/faz_en.html",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 131.6760306,
+ 33.27222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Shimonoseki",
+ "website": "www.shimonoseki-port.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 130.9010601,
+ 33.93444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tomakomai",
+ "website": "www.jptmk.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 141.6533569,
+ 42.6375
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Toyama",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 137.2226737,
+ 36.75722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ube",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 131.2377503,
+ 33.93833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Malindi",
+ "website": "www.kpa.co.ke",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 40.12302709,
+ -3.213611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Trincomalee",
+ "website": "www.slpa.lk",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 81.20388693,
+ 8.558333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Klaipeda",
+ "website": "www.portofklaipeda.lt",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.13421673,
+ 55.68722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Safi",
+ "website": "www.sodep.co.ma",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -9.242697291,
+ 32.3075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ensenada",
+ "website": "www.puertoensenada.com.mx",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -116.6228504,
+ 31.85083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Guaymas",
+ "website": "www.puertodeguaymas.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -110.8687868,
+ 27.91916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Manzanillo",
+ "website": "www.puerto-de-manzanillo.com.mx",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -104.3008834,
+ 19.07055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Salina Cruz",
+ "website": "www.apisal.com.mx",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -95.20194346,
+ 16.15722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Saipan",
+ "website": "www.cpa.gov.mp",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 145.7349234,
+ 15.22583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Nouadhibou",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -17.0418139,
+ 20.9075
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Luderitz",
+ "website": "www.namport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.15371025,
+ -26.63777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bluefields",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.75689046,
+ 12.01194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Alesund",
+ "website": "www.alesund.havn.no",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 6.171613663,
+ 62.4725
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Batsfjord",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 29.71772674,
+ 70.63416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bodo",
+ "website": "www.bodohavn.no",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.37267373,
+ 67.28888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Hammerfest",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 23.67108363,
+ 70.66722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Haugesund",
+ "website": "www.karmsund-havn.no",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.25565371,
+ 59.41222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kirkenes",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 30.05565371,
+ 69.72833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kristiansund",
+ "website": "www.knhavn.no",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.733333333,
+ 63.115
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Mo i Rana",
+ "website": "www.portofmoirana.no",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.1237338,
+ 66.315
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Molde",
+ "website": "www.moldehavn.no",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.157420495,
+ 62.73638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Mosjoen",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.1868669,
+ 65.85194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Narvik",
+ "website": "www.portofnarvik.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.41861013,
+ 68.43861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Stavanger",
+ "website": "www.stavanger-havn.no",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.737220259,
+ 58.97888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Vadso",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 29.73757362,
+ 70.07111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Vardo",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 31.10388693,
+ 70.37333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "New Plymouth",
+ "website": "www.porttaranaki.co.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 174.0377503,
+ -39.05722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Gisborne",
+ "website": "www.eastland.co.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 178.0224971,
+ -38.6725
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Greymouth",
+ "website": "www.greydc.govt.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 171.20053,
+ -42.44472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Napier",
+ "website": "www.portofnapier.co.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 176.9180801,
+ -39.475
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tauranga",
+ "website": "www.port-tauranga.co.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 176.1740872,
+ -37.65944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Wanganui",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 174.9895171,
+ -39.94416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Westport",
+ "website": "www.westportharbour.co.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 171.5912839,
+ -41.75027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Whangarei",
+ "website": "www.nrc.govt.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 174.3426973,
+ -35.75111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Timaru",
+ "website": "www.primeport.co.nz",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 171.2542403,
+ -44.38916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Talara",
+ "website": "www.ultramarnetwork.com/TextosPeru/Marc-014.html",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -81.2746172,
+ -4.573055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Masbate",
+ "website": "www.ppa.com.ph",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 123.6198469,
+ 12.36805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Subic Bay",
+ "website": "www.sbma.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 120.2747939,
+ 14.80833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Alotau",
+ "website": "www.pngports.com.pg",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 150.4510601,
+ -10.31277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kavieng",
+ "website": "www.pngports.com.pg",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 150.7866902,
+ -2.584722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kieta",
+ "website": "www.pngports.com.pg",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 155.626914,
+ -6.215277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Rabaul",
+ "website": "www.pngports.com.pg",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 152.1851001,
+ -4.241111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Vanimo",
+ "website": "www.pngports.com.pg",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 141.2923439,
+ -2.683611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ponce",
+ "website": "www.puertodelasamericaspr.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -66.61024735,
+ 17.96805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Sines",
+ "website": "www.portodesines.pt",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.867020024,
+ 37.94277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Horta",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -28.62196702,
+ 38.53
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Arkhangelsk",
+ "website": "www.ascp.ru",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 40.55636042,
+ 64.5425
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Murmansk",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 33.04146054,
+ 68.9725
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tiksi",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 128.8728504,
+ 71.64305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Jizan",
+ "website": "www.ports.gov.sa",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 42.5352768,
+ 16.89027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Berbera",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 45,
+ 10.44083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Nieuw Nickerie",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -57.00176678,
+ 5.951666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Malmo",
+ "website": "www.cmport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.00159011,
+ 55.62555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Gavle",
+ "website": "www.gavle.se",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.19269729,
+ 60.68444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Halmstad",
+ "website": "www.halmstadharbour.se",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.85,
+ 56.655
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Helsingborg",
+ "website": "www.port.helsingborg.se",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.68757362,
+ 56.03333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Hudiksvall",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.11861013,
+ 61.72166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kalmar",
+ "website": "www.kalmar.se/kalmarhamn",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.36914016,
+ 56.65916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ornskoldsvik",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.72585395,
+ 63.27611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ronneby",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.3,
+ 56.17472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Soderhamn",
+ "website": "www.sshab.se",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 17.0893404,
+ 61.30833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Vastervik",
+ "website": "www.osterstroms.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.65194346,
+ 57.75583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Visby",
+ "website": "www.visbyport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.2746172,
+ 57.63555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tekirdag",
+ "website": "www.akport.com.tr",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.50795053,
+ 40.9675
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tanga",
+ "website": "www.tanzaniaports.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.10318021,
+ -5.065555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kherson",
+ "website": "www.ukrport.org.ua",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 32.60742049,
+ 46.61861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Colonia",
+ "website": "www.anp.com.uy",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -57.84216726,
+ -34.47166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Cordova",
+ "website": "www.cityofcordova.net",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -145.7563604,
+ 60.55
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Ketchikan",
+ "website": "www.city.ketchikan.ak.us",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -131.6712603,
+ 55.34694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bangor",
+ "website": "www.bangormaine.gov/cs_inf_harbor.php",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -68.76984688,
+ 44.79194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Stockton",
+ "website": "www.portofstockton.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -121.3230271,
+ 37.95055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bridgeport",
+ "website": "www.portofbridgeport.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.17638398,
+ 41.1725
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "New Haven",
+ "website": "www.cityofnewhaven.com/PortAuthority",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.90954064,
+ 41.28638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Everglades",
+ "website": "www.broward.org/port",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.10865724,
+ 26.08444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Savannah",
+ "website": "www.gaports.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -81.12249706,
+ 32.11083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Portland",
+ "website": "www.portofportlandmaine.org",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.23951708,
+ 43.65333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Gulfport",
+ "website": "www.shipmspa.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -89.08845701,
+ 30.35861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Portsmouth",
+ "website": "www.portofnh.org",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.76861013,
+ 43.0875
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Newark",
+ "website": "www.panynj.gov",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -74.13722026,
+ 40.7
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Astoria",
+ "website": "www.portofastoria.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -123.8262073,
+ 46.18944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Everglades",
+ "website": "www.broward.org/port",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.10865724,
+ 26.08444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Corpus Christi",
+ "website": "www.portofcorpuschristi.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -97.40459364,
+ 27.81277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Pascagoula",
+ "website": "www.portofpascagoula.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -88.53722026,
+ 30.35138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Tacoma",
+ "website": "www.portoftacoma.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.4042403,
+ 47.26722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Beaumont",
+ "website": "www.portofbeaumont.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -94.08421673,
+ 30.07777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Olympia",
+ "website": "www.portolympia.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.9007067,
+ 47.05333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Angeles",
+ "website": "www.portofpa.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -123.4351001,
+ 48.13083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Port Townsend",
+ "website": "www.portofpt.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.7531802,
+ 48.11444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Puerto Cabello",
+ "website": "www.ipapc.gov.ve",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.99305065,
+ 10.47722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Mukalla",
+ "website": "www.portofaden.com",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 49.14375736,
+ 14.52222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "East London",
+ "website": "http://www.transnetnationalportsauthority.net",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.90477032,
+ -33.02527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Mossel Bay",
+ "website": "www.transnetnationalportsauthority.net",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.41825677,
+ -34.37527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Richards Bay",
+ "website": "www.transnetnationalportsauthority.net",
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 32.05618375,
+ -28.80472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Erie",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.1,
+ 42.15
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Bay City",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.86,
+ 43.6
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Milwaukee",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.88,
+ 43.03
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Coos Bay",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -124.21,
+ 43.36
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Sitka",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -135.33,
+ 57.05
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 6,
+ "name": "Kodiak",
+ "website": null,
+ "natlscale": 20,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -152.4,
+ 57.78
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Lobito",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.56931684,
+ -12.33694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Abu Dhabi",
+ "website": "www.portzayed.gov.ae",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 54.37267373,
+ 24.525
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Comodoro Rivadavia",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -67.45989399,
+ -45.85583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Mar del Plata",
+ "website": "www.consejoportuario.com.ar",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -57.53333333,
+ -38.04277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Cairns",
+ "website": "www.cairnsport.com.au",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 145.7755006,
+ -16.92972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Broome",
+ "website": "www.broomeport.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 122.2091873,
+ -18.0025
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Devonport",
+ "website": "www.tasports.com.au",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 146.3675501,
+ -41.16777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Hobart",
+ "website": "www.tasports.com.au",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 147.3358068,
+ -42.88027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Antwerpen",
+ "website": "www.portofantwerp.be",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 4.293757362,
+ 51.29777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Varna",
+ "website": "www.port-varna.bg",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.88863369,
+ 43.19444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Belize City",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -88.20194346,
+ 17.47972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Hamilton",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.77638398,
+ 32.29111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Belem",
+ "website": "www.cdp.com.br",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -48.48474676,
+ -1.451666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Paranagua",
+ "website": "www.portosdoparana.pr.gov.br",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -48.51914016,
+ -25.50083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Porto Alegre",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -51.22408716,
+ -30.0175
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Recife",
+ "website": "www.portodorecife.pe.gov.br",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -34.86896349,
+ -8.053611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Salvador",
+ "website": "www.codeba.com.br",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -38.50477032,
+ -12.95861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Santos",
+ "website": "www.portodesantos.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -46.30053004,
+ -23.96888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Charlottetown",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -63.11896349,
+ 46.23166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Halifax",
+ "website": "www.portofhalifax.ca",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -63.57444052,
+ 44.65694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Nanaimo",
+ "website": "www.npa.ca",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -123.926384,
+ 49.16944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Quebec",
+ "website": "www.portquebec.ca",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.2090106,
+ 46.80583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Victoria",
+ "website": "www.victoriaharbour.org",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -123.4065371,
+ 48.43111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Prince Rupert",
+ "website": "www.rupertport.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -130.3370436,
+ 54.30972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Saint-John",
+ "website": "www.sjport.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -66.05989399,
+ 45.26777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Antofagasta",
+ "website": "www.puertoantofagasta.cl",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.40371025,
+ -23.65027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Iquique",
+ "website": "www.epi.cl",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.15176678,
+ -20.20277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Puerto Montt",
+ "website": "www.empormontt.cl",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.95441696,
+ -41.48361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Haikou",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 110.2749706,
+ 20.02777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Ningbo",
+ "website": "www.nbport.com.cn/wps/portal",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.5533569,
+ 29.86666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Xiamen",
+ "website": "www.portxiamen.com.cn",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 118.0200236,
+ 24.45
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Abidjan",
+ "website": "www.paa-ci.org",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.966666667,
+ 5.233055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Douala",
+ "website": "www.otal.com/cameroon/index.htm",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.685630153,
+ 4.055
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Pointe Noire",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.82691402,
+ -4.784444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Barranquilla",
+ "website": "www.spdelnorte.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -74.75618375,
+ 10.96722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Moroni",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 43.24322733,
+ -11.70138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Mariel",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -82.75600707,
+ 23.00638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Larnaca",
+ "website": "www.cpa.gov.cy",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 33.6393404,
+ 34.92416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Limassol",
+ "website": "www.cpa.gov.cy",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 33.01772674,
+ 34.65
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bremen",
+ "website": "www.bremen-ports.de",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.751060071,
+ 53.0975
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Hamburg",
+ "website": "www.hafen-hamburg.de",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.958480565,
+ 53.52472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Djibouti",
+ "website": "www.dpworld-djiboutiport.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 43.13563015,
+ 11.60194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Aalborg",
+ "website": "www.aalborghavn.dk",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.00530035,
+ 57.06111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Fredericia",
+ "website": "www.adp-as.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.74057715,
+ 55.55805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Alicante",
+ "website": "www.puertoalicante.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.48828033,
+ 38.33527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bilbao",
+ "website": "www.bilbaoport.es",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -3.026914016,
+ 43.3425
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Valencia",
+ "website": "www.valenciaport.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.318433451,
+ 39.44416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Fox Bay",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -60.07073027,
+ -51.95555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Ajaccio",
+ "website": "www.corse-du-sud.cci.fr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.738810365,
+ 41.92
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bastia",
+ "website": "www.port-de-bastia.net",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.451943463,
+ 42.7
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bordeaux",
+ "website": "www.bordeaux-port.fr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.553180212,
+ 44.86527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Calais",
+ "website": "www.calais-port.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.850176678,
+ 50.96583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Dunkerque",
+ "website": "www.portdedunkerque.fr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 2.170906949,
+ 51.02166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Honfleur",
+ "website": "www.pays-auge.cci.fr/port/index.html",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0.235100118,
+ 49.42222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Libreville",
+ "website": "www.ports-gabon.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.43368669,
+ 0.400833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Port Gentil",
+ "website": "www.ports-gabon.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.785276796,
+ -0.711944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Belfast",
+ "website": "www.belfast-harbour.co.uk",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.891107185,
+ 54.62055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Dover",
+ "website": "www.doverport.co.uk",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.322143698,
+ 51.12083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Inverness",
+ "website": "www.invernessharbour.co.uk",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.234746761,
+ 57.48666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Takoradi",
+ "website": "www.ghanaports.gov.gh",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.738457008,
+ 4.884166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Basse-Terre",
+ "website": "www.port-guadeloupe.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.72709069,
+ 15.99638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Pointe-a-Pitre",
+ "website": "www.port-guadeloupe.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.53845701,
+ 16.23388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Banjul",
+ "website": "www.gambiaports.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -16.57037691,
+ 13.44444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bata",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 9.738103651,
+ 1.824166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Iraklion",
+ "website": "www.portheraklion.gr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 25.14110718,
+ 35.34555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Thessaloniki",
+ "website": "www.thpa.gr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 22.91772674,
+ 40.635
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Cayenne",
+ "website": "www.guyane.cci.fr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -52.33616019,
+ 4.935277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Kourou",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -52.62426384,
+ 5.158888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Georgetown",
+ "website": "www.gnsc.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -58.1671967,
+ 6.819444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Puerto Cortes",
+ "website": "www.enp.hn",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.94022379,
+ 15.83333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Zadar",
+ "website": "www.port-authority-zadar.hr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 15.21931684,
+ 44.1175
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Surabaya",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 113.9166667,
+ -7.616666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Manado",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 124.8258539,
+ 1.481944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Senipah",
+ "website": "www.pertamina.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 117.2166667,
+ -1.05
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bhavnagar",
+ "website": "www.gmbports.org",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 72.20600707,
+ 21.77
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Visakhapatnam",
+ "website": "www.vizagport.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 83.28722026,
+ 17.69333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Limerick",
+ "website": "www.sfpc.ie",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.633333333,
+ 52.66277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bandar Abbas",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 56.20424028,
+ 27.14083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Reykjavik",
+ "website": "www.reykjavik.is",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -21.83792697,
+ 64.14833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Seydisfjordur",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -14.00424028,
+ 65.26277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Trieste",
+ "website": "www.porto.trieste.it",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.75424028,
+ 45.645
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Hiroshima",
+ "website": "www.pref.hiroshima.lg.jp",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 132.421437,
+ 34.36527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Kobe",
+ "website": "www.kptc.or.jp",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.2381037,
+ 34.68416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Nagasaki",
+ "website": "www.doboku.pref.nagasaki.jp/~rinkai/kakukou/nagasaki.htm",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 129.8595406,
+ 32.74027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Otaru",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 141.0166667,
+ 43.19694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Tokyo",
+ "website": "www.kouwan.metro.tokyo.jp",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 139.788457,
+ 35.62472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Monrovia",
+ "website": "www.nationalportauthorityliberia.org",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -10.79375736,
+ 6.345555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Colombo",
+ "website": "www.slpa.lk",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 79.85017668,
+ 6.951388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Casablanca",
+ "website": "www.marsamaroc.co.ma",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -7.600176678,
+ 33.60888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Monaco",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.420906949,
+ 43.73194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Acapulco",
+ "website": "www.apiacapulcoport.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -99.9024735,
+ 16.84444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Mazatlan",
+ "website": "www.apimazatlan.com.mx",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -106.393404,
+ 23.19222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Tampico",
+ "website": "www.puertodetampico.com.mx",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -97.83368669,
+ 22.23694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Beira",
+ "website": "www.cfmnet.co.mz",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 34.83351001,
+ -19.81916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Maputo",
+ "website": "www.portmaputo.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 32.55706714,
+ -25.97277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Nouakchott",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -16.02143698,
+ 18.03527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Plymouth",
+ "website": "www.giu.gov.ms",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -62.21984688,
+ 16.70333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Fort-de-France",
+ "website": "www.martinique.cci.fr/port.asp",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.05689046,
+ 14.59916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Noumea",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 166.4258539,
+ -22.25972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Port Harcourt",
+ "website": "www.nigerianports.org",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.003180212,
+ 4.769166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Corinto",
+ "website": "www.epn.com.ni",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.16914016,
+ 12.48194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Rotterdam",
+ "website": "www.portofrotterdam.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 4.292873969,
+ 51.92722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bergen",
+ "website": "www.bergenhavn.no",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.3196702,
+ 60.39694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Tromso",
+ "website": "www.tromso.havn.no",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.96878681,
+ 69.65583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Trondheim",
+ "website": "www.trondheim.havn.no",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.38898704,
+ 63.43777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Nelson",
+ "website": "www.portnelson.co.nz",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 173.27197,
+ -41.25972222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Muscat",
+ "website": "www.pscoman.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 58.4090106,
+ 23.60666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Cebu",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 123.9226737,
+ 10.30638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Zamboanga",
+ "website": "www.ppa.com.ph",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 122.071437,
+ 6.902777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Port Moresby",
+ "website": "www.pngports.com.pg",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 147.1510601,
+ -9.467222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Wewak",
+ "website": "www.pngports.com.pg",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 143.65053,
+ -3.57
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Porto",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.61861013,
+ 41.14111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Ponta Delgada",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -25.65883392,
+ 37.73694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Papeete",
+ "website": "www.portdepapeete.pf",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -149.5696702,
+ -17.53111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Doha",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 51.55565371,
+ 25.29805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Kaliningrad",
+ "website": "www.transmarine.ru/PORTINFO.HTM",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 20.45547703,
+ 54.7
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Vladivostok",
+ "website": "www.vmtp.ru",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 131.8877503,
+ 43.09444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Vyborg",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 28.72638398,
+ 60.705
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Port Sudan",
+ "website": "www.sudanports.gov.sd",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 37.22161366,
+ 19.61583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Mogadishu",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 45.34093051,
+ 2.028888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Paramaribo",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -55.13898704,
+ 5.82
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Goteborg",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.87002356,
+ 57.68916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Lulea",
+ "website": "www.lulea.se/hamnen",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 22.15830389,
+ 65.57888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Norrkoping",
+ "website": "www.norrkoping-port.se",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 16.22567727,
+ 58.61027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Lome",
+ "website": "www.togoport.tg",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1.284923439,
+ 6.139166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Izmir",
+ "website": "www.tcdd.gov.tr",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 27.15388693,
+ 38.44388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Kaohsiung",
+ "website": "www.khb.gov.tw",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 120.3070671,
+ 22.56527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Taichung",
+ "website": "www.tchb.gov.tw",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 120.5038869,
+ 24.25833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Odessa",
+ "website": "www.port.odessa.ua",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 30.73704358,
+ 46.50111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Montevideo",
+ "website": "www.anp.com.uy",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -56.20424028,
+ -34.90055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Juneau",
+ "website": "www.juneau.org",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -134.6700236,
+ 58.37916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Nome",
+ "website": "www.nomealaska.org/port",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -165.4251472,
+ 64.49833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Hilo",
+ "website": "www.state.hi.us/dot/harbors",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -155.0686101,
+ 19.73333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Bellingham",
+ "website": "www.portofbellingham.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.5003534,
+ 48.74055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Houston",
+ "website": "www.portofhouston.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -95.20212014,
+ 29.73916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Brownsville",
+ "website": "www.portofbrownsville.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -97.38457008,
+ 25.95722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Longview",
+ "website": "www.portoflongview.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.96702,
+ 46.11277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Kingstown",
+ "website": "www.svgpa.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.24287397,
+ 13.16916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "La Guaira",
+ "website": "www.plcsa.gob.ve",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -66.94022379,
+ 10.60277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Maracaibo",
+ "website": "www.puertodemaracaibo.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.58828033,
+ 10.68361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Da Nang",
+ "website": "www.danangportvn.com",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 108.2232038,
+ 16.08222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Port Vila",
+ "website": "www.vanuatugovernment.gov.vu",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 168.3058304,
+ -17.74722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Apia",
+ "website": "www.spasamoa.ws",
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -171.7579505,
+ -13.82833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Hodeidah",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 42.9352768,
+ 14.83361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Ottawa",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.7,
+ 45.43
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Buffalo",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -78.88,
+ 42.88
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Cleveland",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -81.71,
+ 41.5
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Green Bay",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -88.01,
+ 44.51
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Duluth",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -92.1,
+ 46.76
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 5,
+ "name": "Eureka",
+ "website": null,
+ "natlscale": 30,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -124.18,
+ 40.8
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Luanda",
+ "website": "www.otal.com/angola",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.25088339,
+ -8.783888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Kralendijk, Bonaire",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -68.27355713,
+ 12.14833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Philipsburg",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -63.04375736,
+ 18.01444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Adelaide",
+ "website": "www.flindersports.com.au",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 138.5079505,
+ -34.79916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Brisbane",
+ "website": "www.portbris.com.au",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 153.1684335,
+ -27.3825
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Port Hedland",
+ "website": "www.phpa.com.au",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 118.5732038,
+ -20.3175
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Chittagong",
+ "website": "www.cpa.gov.bd",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 91.82585395,
+ 22.26888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Bridgetown",
+ "website": "www.barbadosport.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -59.62408716,
+ 13.10694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Montreal",
+ "website": "www.port-montreal.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.5246172,
+ 45.54361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Punta Arenas",
+ "website": "www.epa.co.cl",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.90477032,
+ -53.16833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Valdivia",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -73.22656066,
+ -39.81666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Dalian",
+ "website": "www.portdalian.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.6503534,
+ 38.93361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Fuzhou",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 119.30053,
+ 26.0475
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Qingdao",
+ "website": "www.qdport.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 120.31702,
+ 36.09583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Shanghai",
+ "website": "www.portshanghai.com.cn",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.4872203,
+ 31.22194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Shantou",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 116.7040636,
+ 23.35472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Puntarenas",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -84.80424028,
+ 9.981666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Kiel",
+ "website": "www.port-of-kiel.de",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.15689046,
+ 54.33083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Roseau",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -61.38598351,
+ 15.29638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Santo Domingo",
+ "website": "www.apordom.gov.do",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -69.87585395,
+ 18.47527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Cartagena",
+ "website": "www.apc.es",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.98598351,
+ 37.58944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Vigo",
+ "website": "www.apvigo.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -8.726207303,
+ 42.2425
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Santa Cruz de Tenerife",
+ "website": "www.puertosdetenerife.org",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -16.22656066,
+ 28.47472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Tallinn",
+ "website": "www.portoftallinn.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.69075383,
+ 59.46
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Suva",
+ "website": "www.fijiports.com.fj",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 178.4210836,
+ -18.1325
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Saint-Tropez",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 6.633333333,
+ 43.27055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Glasgow",
+ "website": "www.glasgowharbour.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.303180212,
+ 55.86305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Southampton",
+ "website": "www.abports.co.uk/custinfo/ports/soton.htm",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -1.424440518,
+ 50.9025
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Gibraltar",
+ "website": "www.gibraltarport.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -5.357243816,
+ 36.13694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Conakry",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -13.70989399,
+ 9.516388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Bissau",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -15.57267373,
+ 11.85833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Canea",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.00971731,
+ 35.51805556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Katakolon",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 21.31861013,
+ 37.64638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "San Jose",
+ "website": "www.cocatram.org.ni/puertosca/pto_sanjose_guatemala.html",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -90.84128386,
+ 13.91555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Hong Kong",
+ "website": "www.mardep.gov.hk",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 114.1561837,
+ 22.32111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Port-au-Prince",
+ "website": "www.apn.gouv.ht",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -72.33969376,
+ 18.56583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Surabaya",
+ "website": "www.tps.co.id",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 112.7239105,
+ -7.206388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Dublin",
+ "website": "www.dublinport.ie",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -6.206007067,
+ 53.34444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Waterford",
+ "website": "www.portofwaterford.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -7.118786808,
+ 52.26638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Haifa",
+ "website": "www.haifaport.org.il",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 35.01825677,
+ 32.8225
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Livorno",
+ "website": "www.porto.livorno.it",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.30194346,
+ 43.55583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Ischia",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.93810365,
+ 40.74527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Kingston",
+ "website": "www.portjam.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.82479388,
+ 17.98166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Kitakyushu",
+ "website": "www.kitaqport.or.jp",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 130.8542403,
+ 33.9225
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Mombasa",
+ "website": "www.kpa.co.ke",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.6221437,
+ -4.053055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Phnom Penh",
+ "website": "www.ppap.com.kh",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 104.9209069,
+ 11.58305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Beirut",
+ "website": "www.portdebeyrouth.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 35.51949352,
+ 33.905
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Male",
+ "website": "www.maldport.com.mv",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 73.50706714,
+ 4.175
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Veracruz",
+ "website": "www.puertodeveracruz.com.mx",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -96.13368669,
+ 19.20833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Yangon",
+ "website": "www.mot.gov.mm/mpa/index.html",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 96.16878681,
+ 16.76583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Wellington",
+ "website": "www.centreport.co.nz",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 174.7898704,
+ -41.2775
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Szczecin",
+ "website": "www.port.szczecin.pl",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.58580683,
+ 53.43055556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Jeddah",
+ "website": "www.ports.gov.sa",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.1590106,
+ 21.45861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Dakar",
+ "website": "www.portdakar.sn",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -17.42514723,
+ 14.68222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Singapore",
+ "website": "www.mpa.gov.sg",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 103.7221437,
+ 1.292777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Freetown",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -13.20795053,
+ 8.494166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Stockholm",
+ "website": "www.stoports.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.10936396,
+ 59.335
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Bangkok",
+ "website": "www.bmt.co.th",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 100.5691402,
+ 13.60694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Canakkale",
+ "website": "www.canakkale.gov.tr",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 26.52196702,
+ 40.26472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Anchorage",
+ "website": "www.muni.org",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -149.8877503,
+ 61.23555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Long Beach",
+ "website": "www.polb.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -118.2007067,
+ 33.74888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Oakland",
+ "website": "www.portofoakland.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.3012367,
+ 37.79944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Jacksonville",
+ "website": "www.jaxport.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -81.55918728,
+ 30.38083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Philadelphia",
+ "website": "www.philaport.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -75.13457008,
+ 39.89527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Charleston",
+ "website": "www.scspa.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.92355713,
+ 32.82222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Newport",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.32444052,
+ 41.4825
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Ho Chi Minh City",
+ "website": "www.vpa.org.vn/english/members/south/saigonnew.htm",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 106.7217903,
+ 10.79388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Aden",
+ "website": "www.portofaden.com",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 44.98969376,
+ 12.79555556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Durban",
+ "website": "www.transnetnationalportsauthority.net",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 31.02338045,
+ -29.88111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Port Elizabeth",
+ "website": "www.transnetnationalportsauthority.net",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 25.6352768,
+ -33.96138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Port Elizabeth",
+ "website": "www.transnetnationalportsauthority.net",
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 25.6352768,
+ -33.96138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Detroit",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -83.03,
+ 42.33
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Port Of Memphis",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -90.16,
+ 35.06
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Tri-City Port",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -90.2,
+ 38.71
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Helsinki",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.96,
+ 60.16
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 4,
+ "name": "Sankt-Peterburg",
+ "website": null,
+ "natlscale": 50,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 30.3,
+ 59.93
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Oranjestad",
+ "website": "www.arubaports.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -70.03881037,
+ 12.52
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Dubai",
+ "website": "www.dpa.ae",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 55.26931684,
+ 25.26722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Buenos Aires",
+ "website": "www.puertobuenosaires.gov.ar",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -58.3696702,
+ -34.59916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Darwin",
+ "website": "www.darwinport.nt.gov.au",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 130.854947,
+ -12.47027778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Melbourne",
+ "website": "www.portofmelbourne.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 144.9171967,
+ -37.83277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Perth",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 115.855477,
+ -31.96527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Sydney",
+ "website": "www.sydneyports.com.au",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 151.1891637,
+ -33.86222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Cotonou",
+ "website": "www.portdecotonou.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 2.422320377,
+ 6.346666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Nassau",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.32126031,
+ 25.07666667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Rio de Janeiro",
+ "website": "www.portosrio.gov.br",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -43.1918139,
+ -22.88305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Vancouver",
+ "website": "www.portmetrovancouver.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -123.071437,
+ 49.29777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Liverpool",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -64.70371025,
+ 44.04333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Valparaiso",
+ "website": "www.portvalparaiso.cl",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.61914016,
+ -33.03527778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Guangzhou",
+ "website": "www.gzport.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 113.409364,
+ 23.09416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Tianjin",
+ "website": "www.ptacn.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 117.4565371,
+ 39.00944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Abidjan",
+ "website": "www.paa-ci.org",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.021260306,
+ 5.283333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Bremerhaven",
+ "website": "www.bremen-ports.de",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.553003534,
+ 53.56361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Rostock",
+ "website": "www.rostock-port.de",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.11790342,
+ 54.1525
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Tuborg",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.58404005,
+ 55.72611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Guayaquil",
+ "website": "www.puertodeguayaquil.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.9024735,
+ -2.284166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Port Said",
+ "website": "www.psdports.org",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 32.30600707,
+ 31.25333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Barcelona",
+ "website": "www.apb.es",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 2.168786808,
+ 41.35472222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Malaga",
+ "website": "www.puertomalaga.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -4.418256773,
+ 36.70944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Palma de Mallorca",
+ "website": "www.portdemallorca.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 2.62532391,
+ 39.55111111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Le Havre",
+ "website": "www.havre-port.net",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0.173733804,
+ 49.46694444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Marseille",
+ "website": "www.marseille-port.fr",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.341283863,
+ 43.32944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Nice",
+ "website": "www.riviera-ports.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 7.285630153,
+ 43.69388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "London",
+ "website": "www.pla.co.uk",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.067196702,
+ 51.50277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Gythion",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 22.56755006,
+ 36.76
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Rhodes",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 28.23351001,
+ 36.44361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Dubrovnik",
+ "website": "www.portdubrovnik.hr",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.07638398,
+ 42.66
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Civitavecchia",
+ "website": "www.portidiroma.it",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 11.77567727,
+ 42.09888889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Palermo",
+ "website": "www.autport.pa.it",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 13.36984688,
+ 38.13083333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Savona",
+ "website": "www.porto.sv.it",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 8.489517079,
+ 44.31166667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Marghera",
+ "website": "www.port.venice.it",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 12.24057715,
+ 45.45305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Montego Bay",
+ "website": "www.portjam.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -77.93545347,
+ 18.4675
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Osaka",
+ "website": "www.optc.or.jp",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 135.4338634,
+ 34.63583333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Yokohama",
+ "website": "www.city.yokohama.jp/me/port/en/index.html",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 139.6673734,
+ 35.43638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Riga",
+ "website": "www.rop.lv",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.08810365,
+ 57.00777778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Cabo San Lucas",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -109.9007067,
+ 22.88388889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Marsaxlokk",
+ "website": "www.maltafreeport.com.mt",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.54128386,
+ 35.82611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Amsterdam",
+ "website": "www.amsterdamports.nl",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 4.824087161,
+ 52.41305556
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Oslo",
+ "website": "www.ohv.oslo.no",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 10.73457008,
+ 59.89722222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Auckland",
+ "website": "www.poal.co.nz",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 174.7694935,
+ -36.83638889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Karachi",
+ "website": "www.kpt.gov.pk",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 66.9737338,
+ 24.835
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Colon",
+ "website": "www.cct-pa.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.88510012,
+ 9.373333333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Manila",
+ "website": "www.ppa.com.ph",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 120.943404,
+ 14.52416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "San Juan",
+ "website": "www.prpa.gobierno.pr",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -66.09128386,
+ 18.43611111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Istanbul",
+ "website": "www.tdi.com.tr",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 28.993404,
+ 41.01277778
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Taipei",
+ "website": "www.tpport.gov.tw",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 121.3746172,
+ 25.15194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Dar es Salaam",
+ "website": "www.tanzaniaports.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 39.293404,
+ -6.834444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Mobile",
+ "website": "www.asdd.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -88.03775029,
+ 30.71138889
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Los Angeles",
+ "website": "www.portoflosangeles.org",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -118.2597173,
+ 33.73194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "San Diego",
+ "website": "www.portofsandiego.org",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -117.1572438,
+ 32.68444444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "San Francisco",
+ "website": "www.sfport.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.4008834,
+ 37.78861111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Miami",
+ "website": "www.miamidade.gov/portofmiami",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -80.16702002,
+ 25.775
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Tampa",
+ "website": "www.tampaport.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -82.43616019,
+ 27.93
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Honolulu",
+ "website": "www.state.hi.us/dot/harbors",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -157.8737338,
+ 21.30944444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Boston",
+ "website": "www.massport.com/ports",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -71.03545347,
+ 42.36361111
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Baltimore",
+ "website": "www.mpa.state.md.us",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.55565371,
+ 39.2325
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "New York",
+ "website": "www.panynj.gov",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -74.02426384,
+ 40.68833333
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Galveston",
+ "website": "www.portofgalveston.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -94.81790342,
+ 29.30416667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Norfolk",
+ "website": "www.vaports.com",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -76.29252061,
+ 36.90194444
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Seattle",
+ "website": "www.portseattle.org",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -122.3597173,
+ 47.60222222
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Cape Town",
+ "website": "www.transnetnationalportsauthority.net",
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 18.4352768,
+ -33.90916667
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Toronto",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -79.38,
+ 43.61
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "scalerank": 3,
+ "name": "Chicago",
+ "website": null,
+ "natlscale": 75,
+ "featureclass": "Port"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -87.6,
+ 41.88
+ ]
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/platform/ios/demo/Examples/Files/third_party_vector_style.json b/platform/ios/demo/Examples/Files/third_party_vector_style.json
new file mode 100644
index 0000000000..0c27190773
--- /dev/null
+++ b/platform/ios/demo/Examples/Files/third_party_vector_style.json
@@ -0,0 +1,25 @@
+{
+ "version": 8,
+ "sources": {
+ "osm": {
+ "type": "vector",
+ "tiles": ["https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-LM25tq4"]
+ }
+ },
+ "layers": [{
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "#41afa5"
+ }
+ }, {
+ "id": "water",
+ "type": "fill",
+ "source": "osm",
+ "source-layer": "water",
+ "filter": ["==", "$type", "Polygon"],
+ "paint": {
+ "fill-color": "#3887be"
+ }
+ }]
+}
diff --git a/platform/ios/demo/Examples/Info.plist b/platform/ios/demo/Examples/Info.plist
new file mode 100644
index 0000000000..1803c046fc
--- /dev/null
+++ b/platform/ios/demo/Examples/Info.plist
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSLocationWhenInUseUsageDescription</key>
+ <string>🥑🍋🍉</string>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/platform/ios/demo/Examples/Main.storyboard b/platform/ios/demo/Examples/Main.storyboard
new file mode 100644
index 0000000000..902ed9a92a
--- /dev/null
+++ b/platform/ios/demo/Examples/Main.storyboard
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="icM-J6-7Ve">
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--Mapbox Examples Table-->
+ <scene sceneID="Z8w-ct-53h">
+ <objects>
+ <tableViewController title="Mapbox Examples Table" id="rYw-fr-DVv" customClass="ExamplesTableViewController" sceneMemberID="viewController">
+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="jqC-bf-Q1D">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <prototypes>
+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ExampleCell" textLabel="2OV-ag-M78" style="IBUITableViewCellStyleDefault" id="uOq-7b-YXm">
+ <rect key="frame" x="0.0" y="92" width="375" height="44"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="uOq-7b-YXm" id="Y0e-IA-9M7">
+ <frame key="frameInset" width="375" height="43"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2OV-ag-M78">
+ <frame key="frameInset" minX="15" width="345" height="43"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <fontDescription key="fontDescription" type="system" pointSize="16"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ </tableViewCellContentView>
+ <connections>
+ <segue destination="oQt-8u-Dyx" kind="show" identifier="TableToExampleSegue" id="deO-jp-W4D"/>
+ </connections>
+ </tableViewCell>
+ </prototypes>
+ <connections>
+ <outlet property="dataSource" destination="rYw-fr-DVv" id="7vF-6e-Aeu"/>
+ <outlet property="delegate" destination="rYw-fr-DVv" id="ogv-hd-5k9"/>
+ </connections>
+ </tableView>
+ <navigationItem key="navigationItem" title="Examples" id="ZMB-ZX-tvd"/>
+ </tableViewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="de0-fx-nhX" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="872" y="644"/>
+ </scene>
+ <!--Examples Container View Controller-->
+ <scene sceneID="aeJ-m4-BQz">
+ <objects>
+ <viewController id="oQt-8u-Dyx" customClass="ExamplesContainerViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="5Vb-ZX-fBD"/>
+ <viewControllerLayoutGuide type="bottom" id="Gia-78-0rw"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="ySG-gy-6RJ">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <containerView opaque="NO" contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aWc-it-OfW">
+ <frame key="frameInset" width="600" height="600"/>
+ <connections>
+ <segue destination="198-d0-SS2" kind="embed" id="RV5-UC-Iwr"/>
+ </connections>
+ </containerView>
+ </subviews>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <constraints>
+ <constraint firstItem="aWc-it-OfW" firstAttribute="top" secondItem="ySG-gy-6RJ" secondAttribute="top" id="CUW-TL-Tdy"/>
+ <constraint firstItem="aWc-it-OfW" firstAttribute="leading" secondItem="ySG-gy-6RJ" secondAttribute="leading" id="Rvt-2P-AM6"/>
+ <constraint firstItem="aWc-it-OfW" firstAttribute="bottom" secondItem="Gia-78-0rw" secondAttribute="top" id="cfc-ir-t3J"/>
+ <constraint firstAttribute="trailing" secondItem="aWc-it-OfW" secondAttribute="trailing" id="oS9-6L-YKS"/>
+ </constraints>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="4XO-te-Nbg" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="1558" y="644"/>
+ </scene>
+ <!--Navigation Controller-->
+ <scene sceneID="NqE-wE-f7O">
+ <objects>
+ <navigationController id="icM-J6-7Ve" sceneMemberID="viewController">
+ <navigationBar key="navigationBar" contentMode="scaleToFill" id="62O-Wd-YC9">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </navigationBar>
+ <connections>
+ <segue destination="rYw-fr-DVv" kind="relationship" relationship="rootViewController" id="p4h-0g-frx"/>
+ </connections>
+ </navigationController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="SiO-Mn-QjY" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="52" y="644"/>
+ </scene>
+ <!--View Controller-->
+ <scene sceneID="4An-rM-Cs9">
+ <objects>
+ <viewController id="198-d0-SS2" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="YmV-qb-Ipx"/>
+ <viewControllerLayoutGuide type="bottom" id="WZJ-QZ-QO4"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="23Q-aT-BkF">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="Eur-mY-Rlz" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="1558" y="1345"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.h b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.h
new file mode 100644
index 0000000000..104b203926
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.h
@@ -0,0 +1,13 @@
+//
+// AnnotationViewExample.h
+// Examples
+//
+// Created by Jason Wray on 6/23/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface AnnotationViewExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.m b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.m
new file mode 100644
index 0000000000..18d309ed7b
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewExample.m
@@ -0,0 +1,109 @@
+#import "AnnotationViewExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleAnnotationView = @"AnnotationViewExample";
+
+// MGLAnnotationView subclass
+@interface CustomAnnotationView : MGLAnnotationView
+@end
+
+@implementation CustomAnnotationView
+
+- (void)layoutSubviews {
+ [super layoutSubviews];
+
+ // Force the annotation view to maintain a constant size when the map is tilted.
+ self.scalesWithViewingDistance = false;
+
+ // Use CALayer’s corner radius to turn this view into a circle.
+ self.layer.cornerRadius = self.frame.size.width / 2;
+ self.layer.borderWidth = 2;
+ self.layer.borderColor = [UIColor whiteColor].CGColor;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+ [super setSelected:selected animated:animated];
+
+ // Animate the border width in/out, creating an iris effect.
+ CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
+ animation.duration = 0.1;
+ self.layer.borderWidth = selected ? self.frame.size.width / 4 : 2;
+ [self.layer addAnimation:animation forKey:@"borderWidth"];
+}
+
+@end
+
+
+//
+// Example view controller
+@interface AnnotationViewExample () <MGLMapViewDelegate>
+@end
+
+@implementation AnnotationViewExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.styleURL = [MGLStyle darkStyleURLWithVersion:9];
+ mapView.tintColor = [UIColor lightGrayColor];
+ mapView.centerCoordinate = CLLocationCoordinate2DMake(0, 66);
+ mapView.zoomLevel = 2;
+ mapView.delegate = self;
+ [self.view addSubview:mapView];
+
+ // Specify coordinates for our annotations.
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(0, 33),
+ CLLocationCoordinate2DMake(0, 66),
+ CLLocationCoordinate2DMake(0, 99),
+ };
+ NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
+
+ // Fill an array with point annotations and add it to the map.
+ NSMutableArray *pointAnnotations = [NSMutableArray arrayWithCapacity:numberOfCoordinates];
+ for (NSUInteger i = 0; i < numberOfCoordinates; i++) {
+ CLLocationCoordinate2D coordinate = coordinates[i];
+ MGLPointAnnotation *point = [[MGLPointAnnotation alloc] init];
+ point.coordinate = coordinate;
+ point.title = [NSString stringWithFormat:@"%.f, %.f", coordinate.latitude, coordinate.longitude];
+ [pointAnnotations addObject:point];
+ }
+
+ [mapView addAnnotations:pointAnnotations];
+}
+
+#pragma mark - MGLMapViewDelegate methods
+
+// This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
+- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
+ // This example is only concerned with point annotations.
+ if (![annotation isKindOfClass:[MGLPointAnnotation class]]) {
+ return nil;
+ }
+
+ // Use the point annotation’s longitude value (as a string) as the reuse identifier for its view.
+ NSString *reuseIdentifier = [NSString stringWithFormat:@"%f", annotation.coordinate.longitude];
+
+ // For better performance, always try to reuse existing annotations.
+ CustomAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
+
+ // If there’s no reusable annotation view available, initialize a new one.
+ if (!annotationView) {
+ annotationView = [[CustomAnnotationView alloc] initWithReuseIdentifier:reuseIdentifier];
+ annotationView.frame = CGRectMake(0, 0, 40, 40);
+
+ // Set the annotation view’s background color to a value determined by its longitude.
+ CGFloat hue = (CGFloat)annotation.coordinate.longitude / 100;
+ annotationView.backgroundColor = [UIColor colorWithHue:hue saturation:0.5 brightness:1 alpha:1];
+ }
+
+ return annotationView;
+}
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation {
+ return YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.h b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.h
new file mode 100644
index 0000000000..2e2d32ab18
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.h
@@ -0,0 +1,13 @@
+//
+// AnnotationViewMultipleExample.h
+// Examples
+//
+// Created by Nadia Barbosa on 12/13/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface AnnotationViewMultipleExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.m b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.m
new file mode 100644
index 0000000000..ee6622fd4e
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/AnnotationViewMultipleExample.m
@@ -0,0 +1,119 @@
+#import "AnnotationViewMultipleExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleAnnotationViewMultiple = @"AnnotationViewMultipleExample";
+
+// MGLPointAnnotation subclass
+@interface MyCustomPointAnnotation : MGLPointAnnotation
+@property (nonatomic, assign) BOOL willUseImage;
+@end
+
+@implementation MyCustomPointAnnotation
+@end
+// end MGLPointAnnotation subclass
+
+@interface AnnotationViewMultipleExample () <MGLMapViewDelegate>
+@end
+
+@implementation AnnotationViewMultipleExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Create a new map view using the Mapbox Light style.
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds
+ styleURL:[MGLStyle lightStyleURLWithVersion:9]];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map's center coordinate and zoom level.
+ mapView.centerCoordinate = CLLocationCoordinate2DMake(36.54,-116.97);
+ mapView.zoomLevel = 9;
+ mapView.delegate = self;
+ [self.view addSubview:mapView];
+
+ // Create four new point annotations with specified coordinates and titles.
+ MyCustomPointAnnotation *pointA = [[MyCustomPointAnnotation alloc] init];
+ pointA.title = @"Stovepipe Wells";
+ pointA.coordinate = CLLocationCoordinate2DMake(36.4623,-116.8656);
+ pointA.willUseImage = YES;
+
+ MyCustomPointAnnotation *pointB = [[MyCustomPointAnnotation alloc] init];
+ pointB.title = @"Furnace Creek";
+ pointB.coordinate = CLLocationCoordinate2DMake(36.6071,-117.1458);
+ pointB.willUseImage = YES;
+
+ MyCustomPointAnnotation *pointC = [[MyCustomPointAnnotation alloc] init];
+ pointC.title = @"Zabriskie Point";
+ pointC.coordinate = CLLocationCoordinate2DMake(36.4208,-116.8101);
+
+ MyCustomPointAnnotation *pointD = [[MyCustomPointAnnotation alloc] init];
+ pointD.title = @"Mesquite Flat Sand Dunes";
+ pointD.coordinate = CLLocationCoordinate2DMake(36.6836,-117.1005);
+
+ // Fill an array with four point annotations.
+ NSArray *myPlaces = @[pointA, pointB, pointC, pointD];
+
+ // Add all annotations to the map all at once, instead of individually.
+ [mapView addAnnotations:myPlaces];
+}
+
+// This delegate method is where you tell the map to load a view for a specific annotation based on the willUseImage property of the custom subclass.
+- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
+ if ([annotation isKindOfClass:[MyCustomPointAnnotation class]]) {
+ MyCustomPointAnnotation *castAnnotation = (MyCustomPointAnnotation *)annotation;
+
+ if (castAnnotation.willUseImage) {
+ return nil;
+ }
+ }
+
+ // Assign a reuse identifier to be used by both of the annotation views, taking advantage of their similarities.
+ NSString *reuseIdentifier = @"reusableDotView";
+
+ // For better performance, always try to reuse existing annotations.
+ MGLAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
+
+ // If there’s no reusable annotation view available, initialize a new one.
+ if (!annotationView) {
+ annotationView = [[MGLAnnotationView alloc] initWithReuseIdentifier:reuseIdentifier];
+ annotationView.frame = CGRectMake(0, 0, 30, 30);
+ annotationView.layer.cornerRadius = annotationView.frame.size.width / 2;
+ annotationView.layer.borderColor = [UIColor whiteColor].CGColor;
+ annotationView.layer.borderWidth = 4.0;
+ annotationView.backgroundColor = [UIColor colorWithRed:0.03 green:0.80 blue:0.69 alpha:1.0];
+ }
+
+ return annotationView;
+}
+
+// This delegate method is where you tell the map to load an image for a specific annotation based on the willUseImage property of the custom subclass.
+- (MGLAnnotationImage *)mapView:(MGLMapView *)mapView imageForAnnotation:(id <MGLAnnotation>)annotation {
+
+ if ([annotation isKindOfClass:[MyCustomPointAnnotation class]]) {
+ MyCustomPointAnnotation *castAnnotation = (MyCustomPointAnnotation *)annotation;
+
+ if (!castAnnotation.willUseImage) {
+ return nil;
+ }
+ }
+
+ // For better performance, always try to reuse existing annotations.
+ MGLAnnotationImage *annotationImage = [mapView dequeueReusableAnnotationImageWithIdentifier:@"camera"];
+
+ // If there is no reusable annotation image available, initialize a new one.
+ if (!annotationImage) {
+ UIImage *image = [UIImage imageNamed:@"camera"];
+ image = [image imageWithAlignmentRectInsets:UIEdgeInsetsMake(0, 0, image.size.height/2, 0)];
+ annotationImage = [MGLAnnotationImage annotationImageWithImage:image reuseIdentifier:@"camera"];
+ }
+
+ return annotationImage;
+}
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation {
+ // Always allow callouts to popup when annotations are tapped.
+ return YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.h b/platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.h
new file mode 100644
index 0000000000..27f4ff4d72
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.h
@@ -0,0 +1,13 @@
+//
+// BlockingGesturesDelegateExample.h
+// Examples
+//
+// Created by Fabian Guerra Soto on 2/14/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface BlockingGesturesDelegateExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.m b/platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.m
new file mode 100644
index 0000000000..2ac90fdc67
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/BlockingGesturesDelegateExample.m
@@ -0,0 +1,64 @@
+#import "BlockingGesturesDelegateExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleBlockingGesturesDelegate = @"BlockingGesturesDelegateExample";
+
+@interface BlockingGesturesDelegateExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLCoordinateBounds colorado;
+@end
+
+@implementation BlockingGesturesDelegateExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.delegate = self;
+ mapView.styleURL = [MGLStyle outdoorsStyleURLWithVersion:9];
+
+ // Denver, Colorado
+ CLLocationCoordinate2D center = CLLocationCoordinate2DMake(39.748947, -104.995882);
+
+ // Starting point
+ [mapView setCenterCoordinate:center zoomLevel:10 direction:0 animated:NO];
+
+ // Colorado's bounds
+ CLLocationCoordinate2D ne = CLLocationCoordinate2DMake(40.989329, -102.062592);
+ CLLocationCoordinate2D sw = CLLocationCoordinate2DMake(36.986207, -109.049896);
+ self.colorado = MGLCoordinateBoundsMake(sw, ne);
+
+ [self.view addSubview:mapView];
+}
+
+// This example uses Colorado's boundaries to restrict
+// the camera movement.
+
+- (BOOL)mapView:(MGLMapView *)mapView shouldChangeFromCamera:(MGLMapCamera *)oldCamera toCamera:(MGLMapCamera *)newCamera
+{
+ // Get the current camera to restore it after
+ MGLMapCamera *currentCamera = mapView.camera;
+
+ // From the new camera obtain the center to test
+ // if it's inside the boundaries
+ CLLocationCoordinate2D newCameraCenter = newCamera.centerCoordinate;
+
+
+ // Set mapView to newCamera to project the
+ // new boundaries
+ mapView.camera = newCamera;
+ MGLCoordinateBounds newVisibleCoordinates = mapView.visibleCoordinateBounds;
+
+ // Revert the camera
+ mapView.camera = currentCamera;
+
+ // Test if the newCameraCenter and newVisibleCoordinates
+ // are inside self.colorado
+ BOOL inside = MGLCoordinateInCoordinateBounds(newCameraCenter, self.colorado);
+ BOOL intersects = MGLCoordinateInCoordinateBounds(newVisibleCoordinates.ne, self.colorado) && MGLCoordinateInCoordinateBounds(newVisibleCoordinates.sw, self.colorado);
+
+ return inside && intersects;
+
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.h b/platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.h
new file mode 100644
index 0000000000..a10c402c9e
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.h
@@ -0,0 +1,13 @@
+//
+// CalloutDelegateUsageExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CalloutDelegateUsageExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.m b/platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.m
new file mode 100644
index 0000000000..ed7e54e080
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CalloutDelegateUsageExample.m
@@ -0,0 +1,84 @@
+#import "CalloutDelegateUsageExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleCalloutDelegateUsage = @"CalloutDelegateUsageExample";
+
+@interface CalloutDelegateUsageExample () <MGLMapViewDelegate>
+@property MGLMapView *mapView;
+@end
+
+@implementation CalloutDelegateUsageExample
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view addSubview:self.mapView];
+
+ // Remember to set the delegate.
+ self.mapView.delegate = self;
+
+ [self addAnnotation];
+}
+
+- (void)addAnnotation
+{
+ MGLPointAnnotation *annotation = [[MGLPointAnnotation alloc] init];
+ annotation.coordinate = CLLocationCoordinate2DMake(35.03946, 135.72956);
+ annotation.title = @"Kinkaku-ji";
+ annotation.subtitle = [NSString stringWithFormat:@"%.5f, %.5f", annotation.coordinate.latitude, annotation.coordinate.longitude];
+
+ [self.mapView addAnnotation:annotation];
+
+ // Center the map on the annotation.
+ [self.mapView setCenterCoordinate:annotation.coordinate zoomLevel:17 animated:NO];
+
+ // Pop-up the callout view.
+ [self.mapView selectAnnotation:annotation animated:YES];
+}
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation
+{
+ return true;
+}
+
+- (UIView *)mapView:(MGLMapView *)mapView leftCalloutAccessoryViewForAnnotation:(id<MGLAnnotation>)annotation
+{
+ if ([annotation.title isEqualToString:@"Kinkaku-ji"])
+ {
+ // Callout height is fixed; width expands to fit its content.
+ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60.f, 50.f)];
+ label.textAlignment = NSTextAlignmentRight;
+ label.textColor = [UIColor colorWithRed:0.81f green:0.71f blue:0.23f alpha:1.f];
+ label.text = @"金閣寺";
+
+ return label;
+ }
+
+ return nil;
+}
+
+- (UIView *)mapView:(MGLMapView *)mapView rightCalloutAccessoryViewForAnnotation:(id<MGLAnnotation>)annotation
+{
+ return [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
+}
+
+- (void)mapView:(MGLMapView *)mapView annotation:(id<MGLAnnotation>)annotation calloutAccessoryControlTapped:(UIControl *)control
+{
+ // Hide the callout view.
+ [self.mapView deselectAnnotation:annotation animated:NO];
+
+ // Show an alert containing the annotation's details
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:annotation.title
+ message:@"A lovely (if touristy) place."
+ preferredStyle:UIAlertControllerStyleAlert];
+
+ [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
+
+ [self presentViewController:alert animated:YES completion:nil];
+
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.h b/platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.h
new file mode 100644
index 0000000000..45b0ab9732
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.h
@@ -0,0 +1,13 @@
+//
+// CameraAnimationExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CameraAnimationExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.m b/platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.m
new file mode 100644
index 0000000000..2e32826e0b
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CameraAnimationExample.m
@@ -0,0 +1,40 @@
+#import "CameraAnimationExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleCameraAnimation = @"CameraAnimationExample";
+
+@interface CameraAnimationExample () <MGLMapViewDelegate>
+@end
+
+@implementation CameraAnimationExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.delegate = self;
+
+ mapView.styleURL = [MGLStyle outdoorsStyleURLWithVersion:9];
+
+ // Mauna Kea, Hawaii
+ CLLocationCoordinate2D center = CLLocationCoordinate2DMake(19.820689, -155.468038);
+
+ // Optionally set a starting point.
+ [mapView setCenterCoordinate:center zoomLevel:7 direction:0 animated:NO];
+
+ [self.view addSubview:mapView];
+}
+
+-(void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {
+ // Wait for the map to load before initiating the first camera movement.
+
+ // Create a camera that rotates around the same center point, rotating 180°.
+ // `fromDistance:` is meters above mean sea level that an eye would have to be in order to see what the map view is showing.
+ MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:mapView.centerCoordinate fromDistance:4500 pitch:15 heading:180];
+
+ // Animate the camera movement over 5 seconds.
+ [mapView setCamera:camera withDuration:5 animationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.h b/platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.h
new file mode 100644
index 0000000000..b3ceba8b75
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.h
@@ -0,0 +1,14 @@
+//
+// CameraFlyToViewController.h
+// Examples
+//
+// Created by Jordan Kiley on 12/13/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+@import Mapbox;
+
+@interface CameraFlyToExample : UIViewController <MGLMapViewDelegate>
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.m b/platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.m
new file mode 100644
index 0000000000..a97d7058a0
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CameraFlyToExample.m
@@ -0,0 +1,39 @@
+@import Mapbox;
+#import "CameraFlyToExample.h"
+
+NSString const *MBXExampleCameraFlyTo = @"CameraFlyToExample";
+
+@interface CameraFlyToExample ()
+@end
+
+@implementation CameraFlyToExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Sets Honolulu, Hawaii as the camera's starting point.
+ CLLocation *honolulu = [[CLLocation alloc] initWithLatitude:21.3069 longitude:-157.8583];
+ [mapView setCenterCoordinate:honolulu.coordinate
+ zoomLevel:14 animated:NO];
+
+ mapView.delegate = self;
+ [self.view addSubview:mapView];
+}
+
+- (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {
+
+ // Waits for the mapView to finish loading before setting up the camera.
+ // Defines the destination camera as Hawaii Island.
+ MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:CLLocationCoordinate2DMake(19.784213, -155.784605) fromDistance:35000 pitch:70 heading:90];
+
+ // Goes from Honolulu to destination camera.
+ [mapView flyToCamera:camera withDuration:4.0 peakAltitude:3000 completionHandler:nil];
+ // To use default duration and peak altitudes:
+ // [mapView flyToCamera:camera completionHandler:nil];
+ // To use default peak altitude:
+ // [mapView flyToCamera:camera withDuration:4 completionHandler:nil];
+}
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/ClusteringExample.h b/platform/ios/demo/Examples/ObjectiveC/ClusteringExample.h
new file mode 100644
index 0000000000..5cca378062
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/ClusteringExample.h
@@ -0,0 +1,13 @@
+//
+// ClusteringExample.h
+// Examples
+//
+// Created by Justin R. Miller on 2/22/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ClusteringExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/ClusteringExample.m b/platform/ios/demo/Examples/ObjectiveC/ClusteringExample.m
new file mode 100644
index 0000000000..cd2182b2ca
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/ClusteringExample.m
@@ -0,0 +1,143 @@
+#import "ClusteringExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleClustering = @"ClusteringExample";
+
+@interface ClusteringExample () <MGLMapViewDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) UIImage *icon;
+@property (nonatomic) UILabel *popup;
+
+@end
+
+@implementation ClusteringExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[MGLStyle lightStyleURLWithVersion:9]];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.mapView.tintColor = [UIColor darkGrayColor];
+ self.mapView.delegate = self;
+ [self.view addSubview:self.mapView];
+
+ self.icon = [UIImage imageNamed:@"port"];
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"ports" ofType:@"geojson"]];
+
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"clusteredPorts" URL:url options:@{
+ MGLShapeSourceOptionClustered: @(YES),
+ MGLShapeSourceOptionClusterRadius: @(self.icon.size.width)
+ }];
+ [style addSource:source];
+
+ // Use a template image so that we can tint it with the `iconColor` runtime styling property.
+ [style setImage:[self.icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forName:@"icon"];
+
+ // Show unclustered features as icons. The `cluster` attribute is built into clustering-enabled source features.
+ MGLSymbolStyleLayer *ports = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"ports" source:source];
+ ports.iconImageName = [MGLStyleValue valueWithRawValue:@"icon"];
+ ports.iconColor = [MGLStyleValue valueWithRawValue:[[UIColor darkGrayColor] colorWithAlphaComponent:0.9]];
+ ports.predicate = [NSPredicate predicateWithFormat:@"%K != YES", @"cluster"];
+ [style addLayer:ports];
+
+ // Color clustered features based on clustered point counts.
+ NSDictionary *stops = @{ @20: [MGLStyleValue valueWithRawValue:[UIColor lightGrayColor]],
+ @50: [MGLStyleValue valueWithRawValue:[UIColor orangeColor]],
+ @100: [MGLStyleValue valueWithRawValue:[UIColor redColor]],
+ @200: [MGLStyleValue valueWithRawValue:[UIColor purpleColor]] };
+
+ // Show clustered features as circles. The `point_count` attribute is built into clustering-enabled source features.
+ MGLCircleStyleLayer *circlesLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"clusteredPorts" source:source];
+ circlesLayer.circleRadius = [MGLStyleValue valueWithRawValue:@(self.icon.size.width / 2)];
+ circlesLayer.circleOpacity = [MGLStyleValue valueWithRawValue:@0.75];
+ circlesLayer.circleStrokeColor = [MGLStyleValue valueWithRawValue:[[UIColor whiteColor] colorWithAlphaComponent:0.75]];
+ circlesLayer.circleStrokeWidth = [MGLStyleValue valueWithRawValue:@2];
+ circlesLayer.circleColor = [MGLSourceStyleFunction
+ functionWithInterpolationMode:MGLInterpolationModeInterval
+ stops:stops
+ attributeName:@"point_count"
+ options:nil];
+ circlesLayer.predicate = [NSPredicate predicateWithFormat:@"%K == YES", @"cluster"];
+ [style addLayer:circlesLayer];
+
+ // Label cluster circles with a layer of text indicating feature count. Per text token convention, wrap the attribute in {}.
+ MGLSymbolStyleLayer *numbersLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"clusteredPortsNumbers" source:source];
+ numbersLayer.textColor = [MGLStyleValue valueWithRawValue:[UIColor whiteColor]];
+ numbersLayer.textFontSize = [MGLStyleValue valueWithRawValue:@(self.icon.size.width / 2)];
+ numbersLayer.iconAllowsOverlap = [MGLStyleValue valueWithRawValue:@(YES)];
+ numbersLayer.text = [MGLStyleValue valueWithRawValue:@"{point_count}"];
+ numbersLayer.predicate = [NSPredicate predicateWithFormat:@"%K == YES", @"cluster"];
+ [style addLayer:numbersLayer];
+
+ // Add a tap gesture for zooming in to clusters or showing popups on individual features.
+ [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]];
+}
+
+- (void)mapViewRegionIsChanging:(MGLMapView *)mapView {
+ [self showPopup:NO animated:NO];
+}
+
+- (void)handleTap:(UITapGestureRecognizer *)tap {
+ if (tap.state == UIGestureRecognizerStateEnded) {
+ CGPoint point = [tap locationInView:tap.view];
+ CGFloat width = self.icon.size.width;
+ CGRect rect = CGRectMake(point.x - width / 2, point.y - width / 2, width, width);
+
+ // Find cluster circles and/or individual port icons in a touch-sized region around the tap.
+ // In theory, we should only find either one cluster (since they don't overlap) or one port
+ // (since overlapping ones would be clustered).
+ NSArray *clusters = [self.mapView visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:[NSSet setWithObject:@"clusteredPorts"]];
+ NSArray *ports = [self.mapView visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:[NSSet setWithObject:@"ports"]];
+
+ if (clusters.count) {
+ [self showPopup:NO animated:YES];
+ MGLPointFeature *cluster = (MGLPointFeature *)clusters.firstObject;
+ [self.mapView setCenterCoordinate:cluster.coordinate zoomLevel:(self.mapView.zoomLevel + 1) animated:YES];
+ } else if (ports.count) {
+ MGLPointFeature *port = ((MGLPointFeature *)ports.firstObject);
+
+ if (!self.popup) {
+ self.popup = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
+ self.popup.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
+ self.popup.layer.cornerRadius = 4;
+ self.popup.layer.masksToBounds = YES;
+ self.popup.textAlignment = NSTextAlignmentCenter;
+ self.popup.lineBreakMode = NSLineBreakByTruncatingTail;
+ self.popup.font = [UIFont systemFontOfSize:16];
+ self.popup.textColor = [UIColor blackColor];
+ self.popup.alpha = 0;
+ [self.view addSubview:self.popup];
+ }
+
+ self.popup.text = [NSString stringWithFormat:@"%@", [port attributeForKey:@"name"]];
+ CGSize size = [self.popup.text sizeWithAttributes:@{ NSFontAttributeName: self.popup.font }];
+ self.popup.bounds = CGRectInset(CGRectMake(0, 0, size.width, size.height), -10, -10);
+ point = [self.mapView convertCoordinate:port.coordinate toPointToView:self.mapView];
+ self.popup.center = CGPointMake(point.x, point.y - 50);
+
+ if (self.popup.alpha < 1) {
+ [self showPopup:YES animated:YES];
+ }
+ } else {
+ [self showPopup:NO animated:YES];
+ }
+ }
+}
+
+- (void)showPopup:(BOOL)shouldShow animated:(BOOL)animated {
+ CGFloat alpha = (shouldShow ? 1 : 0);
+ if (animated) {
+ __typeof__(self) __weak weakSelf = self;
+ [UIView animateWithDuration:0.25 animations:^{
+ weakSelf.popup.alpha = alpha;
+ }];
+ } else {
+ self.popup.alpha = alpha;
+ }
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.h b/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.h
new file mode 100644
index 0000000000..e2d90f48b6
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.h
@@ -0,0 +1,13 @@
+//
+// CustomAnnotationModelExample.h
+// Examples
+//
+// Created by Jason Wray on 5/20/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CustomAnnotationModelExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.m b/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.m
new file mode 100644
index 0000000000..5cccaaf0ef
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModelExample.m
@@ -0,0 +1,122 @@
+#import "CustomAnnotationModelExample.h"
+#import "CustomAnnotationModels.h"
+@import Mapbox;
+
+NSString *const MBXExampleCustomAnnotationModel = @"CustomAnnotationModelExample";
+
+@interface CustomAnnotationModelExample () <MGLMapViewDelegate>
+@end
+
+@implementation CustomAnnotationModelExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.styleURL = [MGLStyle lightStyleURLWithVersion:9];
+ mapView.tintColor = [UIColor darkGrayColor];
+ mapView.zoomLevel = 1;
+ mapView.delegate = self;
+ [self.view addSubview:mapView];
+
+ // Polyline
+ // Create a coordinates array with all of the coordinates for our polyline.
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(35, -25),
+ CLLocationCoordinate2DMake(20, -30),
+ CLLocationCoordinate2DMake( 0, -25),
+ CLLocationCoordinate2DMake(-15, 0),
+ CLLocationCoordinate2DMake(-45, 10),
+ CLLocationCoordinate2DMake(-45, 40),
+ };
+ NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
+
+ CustomPolyline *polyline = [CustomPolyline polylineWithCoordinates:coordinates count:numberOfCoordinates];//
+ // Set the custom `color` property, later used in the `mapView:strokeColorForShapeAnnotation:` delegate method.
+ polyline.color = [UIColor darkGrayColor];
+
+ // Add the polyline to the map. Note that this method name is singular.
+ [mapView addAnnotation:polyline];
+
+ // Point Annotations
+ // Add a custom point annotation for every coordinate (vertex) in the polyline.
+ NSMutableArray *pointAnnotations = [NSMutableArray arrayWithCapacity:numberOfCoordinates];
+ for (NSUInteger i = 0; i < numberOfCoordinates; i++) {
+ NSUInteger count = pointAnnotations.count + 1;
+ CustomPointAnnotation *point = [[CustomPointAnnotation alloc] init];
+
+ point.coordinate = coordinates[i];
+ point.title = [NSString stringWithFormat:@"Custom Point Annotation %lu", (unsigned long)count];
+
+ // Set the custom `image` and `reuseIdentifier` properties, later used in the `mapView:imageForAnnotation:` delegate method.
+ // Create a unique reuse identifier for each new annotation image.
+ point.reuseIdentifier = [NSString stringWithFormat:@"customAnnotation%lu", (unsigned long)count];
+ // This dot image grows in size as more annotations are added to the array.
+ point.image = [self dotWithSize:(5 * count)];
+
+ // Append each annotation to the array, which will be added to the map all at once.
+ [pointAnnotations addObject:point];
+ }
+
+ // Add the point annotations to the map. This time the method name is plural.
+ // If you have multiple annotations to add, batching their addition to the map is more efficient.
+ [mapView addAnnotations:pointAnnotations];
+}
+
+- (UIImage *)dotWithSize:(NSUInteger)size {
+ size = (CGFloat)size;
+ CGRect rect = CGRectMake(0, 0, size, size);
+ CGFloat strokeWidth = 1;
+
+ UIGraphicsBeginImageContextWithOptions(rect.size, NO, [[UIScreen mainScreen] scale]);
+
+ UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(rect, strokeWidth, strokeWidth)];
+ [UIColor.darkGrayColor setFill];
+ [ovalPath fill];
+
+ [UIColor.whiteColor setStroke];
+ ovalPath.lineWidth = strokeWidth;
+ [ovalPath stroke];
+
+ UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+
+ return image;
+}
+
+#pragma mark - MGLMapViewDelegate methods
+
+- (MGLAnnotationImage *)mapView:(MGLMapView *)mapView imageForAnnotation:(id<MGLAnnotation>)annotation {
+ if ([annotation isKindOfClass:[CustomPointAnnotation class]]) {
+ CustomPointAnnotation *point = (CustomPointAnnotation *)annotation;
+ MGLAnnotationImage *annotationImage = [mapView dequeueReusableAnnotationImageWithIdentifier:point.reuseIdentifier];
+
+ if (annotationImage) {
+ // The annotatation image has already been cached, just reuse it.
+ return annotationImage;
+ } else if (point.image && point.reuseIdentifier) {
+ // Create a new annotation image.
+ return [MGLAnnotationImage annotationImageWithImage:point.image reuseIdentifier:point.reuseIdentifier];
+ }
+ }
+
+ // Fallback to the default marker image.
+ return nil;
+}
+
+- (UIColor *)mapView:(MGLMapView *)mapView strokeColorForShapeAnnotation:(MGLShape *)annotation {
+ if ([annotation isKindOfClass:[CustomPolyline class]]) {
+ // Return orange if the polyline does not have a custom color.
+ return [(CustomPolyline *)annotation color] ?: [UIColor orangeColor];
+ }
+
+ // Fallback to the default tint color.
+ return mapView.tintColor;
+}
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation {
+ return YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModels.h b/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModels.h
new file mode 100644
index 0000000000..4c5db3c51e
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomAnnotationModels.h
@@ -0,0 +1,29 @@
+@import Mapbox;
+
+// MGLAnnotation protocol reimplementation
+@interface CustomPointAnnotation : NSObject <MGLAnnotation>
+
+// As a reimplementation of the MGLAnnotation protocol, we have to add mutable coordinate and (sub)title properties ourselves.
+@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
+@property (nonatomic, copy, nullable) NSString *title;
+@property (nonatomic, copy, nullable) NSString *subtitle;
+
+// Custom properties that we will use to customize the annotation's image.
+@property (nonatomic, copy, nonnull) UIImage *image;
+@property (nonatomic, copy, nonnull) NSString *reuseIdentifier;
+
+@end
+@implementation CustomPointAnnotation
+@end
+
+// MGLPolyline subclass
+@interface CustomPolyline : MGLPolyline
+
+// Because this is a subclass of MGLPolyline, there is no need to redeclare its properties.
+
+// Custom property that we will use when drawing the polyline.
+@property (nonatomic, strong, nullable) UIColor *color;
+
+@end
+@implementation CustomPolyline
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.h b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.h
new file mode 100644
index 0000000000..2a5440cdd7
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.h
@@ -0,0 +1,14 @@
+//
+// CustomCalloutView.h
+// Examples
+//
+// Created by Jason Wray on 3/6/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+@import Mapbox;
+
+@interface CustomCalloutView : UIView <MGLCalloutView>
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.m b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.m
new file mode 100644
index 0000000000..07a7033379
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutView.m
@@ -0,0 +1,158 @@
+#import "CustomCalloutView.h"
+
+// Set defaults for custom tip drawing
+static CGFloat const tipHeight = 10.0;
+static CGFloat const tipWidth = 20.0;
+
+@interface CustomCalloutView ()
+@property (strong, nonatomic) UIButton *mainBody;
+@end
+
+@implementation CustomCalloutView {
+ id <MGLAnnotation> _representedObject;
+ __unused UIView *_leftAccessoryView;/* unused */
+ __unused UIView *_rightAccessoryView;/* unused */
+ __weak id <MGLCalloutViewDelegate> _delegate;
+}
+
+@synthesize representedObject = _representedObject;
+@synthesize leftAccessoryView = _leftAccessoryView;/* unused */
+@synthesize rightAccessoryView = _rightAccessoryView;/* unused */
+@synthesize delegate = _delegate;
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self)
+ {
+ self.backgroundColor = [UIColor clearColor];
+
+ // Create and add a subview to hold the callout’s text
+ UIButton *mainBody = [UIButton buttonWithType:UIButtonTypeSystem];
+ mainBody.backgroundColor = [self backgroundColorForCallout];
+ mainBody.tintColor = [UIColor whiteColor];
+ mainBody.contentEdgeInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
+ mainBody.layer.cornerRadius = 4.0;
+ self.mainBody = mainBody;
+
+ [self addSubview:self.mainBody];
+ }
+
+ return self;
+}
+
+
+#pragma mark - MGLCalloutView API
+
+- (void)presentCalloutFromRect:(CGRect)rect inView:(UIView *)view constrainedToView:(UIView *)constrainedView animated:(BOOL)animated
+{
+ // Do not show a callout if there is no title set for the annotation
+ if (![self.representedObject respondsToSelector:@selector(title)])
+ {
+ return;
+ }
+
+ [view addSubview:self];
+
+ // Prepare title label
+ [self.mainBody setTitle:self.representedObject.title forState:UIControlStateNormal];
+ [self.mainBody sizeToFit];
+
+ if ([self isCalloutTappable])
+ {
+ // Handle taps and eventually try to send them to the delegate (usually the map view)
+ [self.mainBody addTarget:self action:@selector(calloutTapped) forControlEvents:UIControlEventTouchUpInside];
+ }
+ else
+ {
+ // Disable tapping and highlighting
+ self.mainBody.userInteractionEnabled = NO;
+ }
+
+ // Prepare our frame, adding extra space at the bottom for the tip
+ CGFloat frameWidth = self.mainBody.bounds.size.width;
+ CGFloat frameHeight = self.mainBody.bounds.size.height + tipHeight;
+ CGFloat frameOriginX = rect.origin.x + (rect.size.width/2.0) - (frameWidth/2.0);
+ CGFloat frameOriginY = rect.origin.y - frameHeight;
+ self.frame = CGRectMake(frameOriginX, frameOriginY,
+ frameWidth, frameHeight);
+
+ if (animated)
+ {
+ self.alpha = 0.0;
+
+ [UIView animateWithDuration:0.2 animations:^{
+ self.alpha = 1.0;
+ }];
+ }
+}
+
+- (void)dismissCalloutAnimated:(BOOL)animated
+{
+ if (self.superview)
+ {
+ if (animated)
+ {
+ [UIView animateWithDuration:0.2 animations:^{
+ self.alpha = 0.0;
+ } completion:^(BOOL finished) {
+ [self removeFromSuperview];
+ }];
+ }
+ else
+ {
+ [self removeFromSuperview];
+ }
+ }
+}
+
+#pragma mark - Callout interaction handlers
+
+- (BOOL)isCalloutTappable
+{
+ if ([self.delegate respondsToSelector:@selector(calloutViewShouldHighlight:)]) {
+ return [self.delegate performSelector:@selector(calloutViewShouldHighlight:) withObject:self];
+ }
+
+ return NO;
+}
+
+- (void)calloutTapped
+{
+ if ([self isCalloutTappable] && [self.delegate respondsToSelector:@selector(calloutViewTapped:)])
+ {
+ [self.delegate performSelector:@selector(calloutViewTapped:) withObject:self];
+ }
+}
+
+#pragma mark - Custom view styling
+
+- (UIColor *)backgroundColorForCallout
+{
+ return [UIColor darkGrayColor];
+}
+
+- (void)drawRect:(CGRect)rect
+{
+ // Draw the pointed tip at the bottom
+ UIColor *fillColor = [self backgroundColorForCallout];
+
+ CGFloat tipLeft = rect.origin.x + (rect.size.width / 2.0) - (tipWidth / 2.0);
+ CGPoint tipBottom = CGPointMake(rect.origin.x + (rect.size.width / 2.0), rect.origin.y + rect.size.height);
+ CGFloat heightWithoutTip = rect.size.height - tipHeight;
+
+ CGContextRef currentContext = UIGraphicsGetCurrentContext();
+
+ CGMutablePathRef tipPath = CGPathCreateMutable();
+ CGPathMoveToPoint(tipPath, NULL, tipLeft, heightWithoutTip);
+ CGPathAddLineToPoint(tipPath, NULL, tipBottom.x, tipBottom.y);
+ CGPathAddLineToPoint(tipPath, NULL, tipLeft + tipWidth, heightWithoutTip);
+ CGPathCloseSubpath(tipPath);
+
+ [fillColor setFill];
+ CGContextAddPath(currentContext, tipPath);
+ CGContextFillPath(currentContext);
+ CGPathRelease(tipPath);
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.h b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.h
new file mode 100644
index 0000000000..ad6501e057
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.h
@@ -0,0 +1,13 @@
+//
+// CustomCalloutViewExample.h
+// Examples
+//
+// Created by Jason Wray on 3/6/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CustomCalloutViewExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.m b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.m
new file mode 100644
index 0000000000..680c5cc3ea
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomCalloutViewExample.m
@@ -0,0 +1,63 @@
+#import "CustomCalloutViewExample.h"
+#import "CustomCalloutView.h"
+@import Mapbox;
+
+NSString *const MBXExampleCustomCalloutView = @"CustomCalloutViewExample";
+
+@interface CustomCalloutViewExample () <MGLMapViewDelegate>
+@end
+
+@implementation CustomCalloutViewExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[MGLStyle lightStyleURLWithVersion:9]];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.tintColor = [UIColor darkGrayColor];
+ [self.view addSubview:mapView];
+
+ // Set the map view‘s delegate property
+ mapView.delegate = self;
+
+ // Initialize and add the marker annotation
+ MGLPointAnnotation *marker = [[MGLPointAnnotation alloc] init];
+ marker.coordinate = CLLocationCoordinate2DMake(0, 0);
+ marker.title = @"Hello world!";
+
+ // This custom callout example does not implement subtitles
+ //marker.subtitle = @"Welcome to my marker";
+
+ // Add marker to the map
+ [mapView addAnnotation:marker];
+}
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id <MGLAnnotation>)annotation {
+ // Always allow callouts to popup when annotations are tapped
+ return YES;
+}
+
+- (UIView<MGLCalloutView> *)mapView:(__unused MGLMapView *)mapView calloutViewForAnnotation:(id<MGLAnnotation>)annotation
+{
+ // Only show callouts for `Hello world!` annotation
+ if ([annotation respondsToSelector:@selector(title)]
+ && [annotation.title isEqualToString:@"Hello world!"])
+ {
+ // Instantiate and return our custom callout view
+ CustomCalloutView *calloutView = [[CustomCalloutView alloc] init];
+ calloutView.representedObject = annotation;
+ return calloutView;
+ }
+ return nil;
+}
+
+- (void)mapView:(MGLMapView *)mapView tapOnCalloutForAnnotation:(id<MGLAnnotation>)annotation
+{
+ // Optionally handle taps on the callout
+ NSLog(@"Tapped the callout for: %@", annotation);
+
+ // Hide the callout
+ [mapView deselectAnnotation:annotation animated:YES];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.h b/platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.h
new file mode 100644
index 0000000000..c6dc901abd
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.h
@@ -0,0 +1,13 @@
+//
+// CustomRasterStyleExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CustomRasterStyleExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.m b/platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.m
new file mode 100644
index 0000000000..5b5be9d3c0
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomRasterStyleExample.m
@@ -0,0 +1,20 @@
+#import "CustomRasterStyleExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleCustomRasterStyle = @"CustomRasterStyleExample";
+
+@implementation CustomRasterStyleExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ NSURL *styleURL = [NSURL URLWithString:@"https://www.mapbox.com/ios-sdk/files/mapbox-raster-v8.json"];
+ // Local paths are also acceptable.
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:styleURL];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [self.view addSubview:mapView];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.h b/platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.h
new file mode 100644
index 0000000000..2eb52122a0
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.h
@@ -0,0 +1,13 @@
+//
+// CustomStyleExample.h
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CustomStyleExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.m b/platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.m
new file mode 100644
index 0000000000..3793ec5797
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/CustomStyleExample.m
@@ -0,0 +1,27 @@
+#import "CustomStyleExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleCustomStyle = @"CustomStyleExample";
+
+@implementation CustomStyleExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Fill in the next line with your style URL from Mapbox Studio.
+ // <#mapbox://styles/userName/styleHash#>
+ NSURL *styleURL = [NSURL URLWithString:@"mapbox://styles/mapbox/outdoors-v9"];
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds
+ styleURL:styleURL];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map’s center coordinate and zoom level.
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.52954, -122.72317)
+ zoomLevel:14
+ animated:NO];
+
+ [self.view addSubview:mapView];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.h b/platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.h
new file mode 100644
index 0000000000..2eba3362fe
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.h
@@ -0,0 +1,13 @@
+//
+// DDSCircleLayerExample.h
+// Examples
+//
+// Created by Nadia Barbosa on 3/9/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DDSCircleLayerExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.m b/platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.m
new file mode 100644
index 0000000000..6d946d8571
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DDSCircleLayerExample.m
@@ -0,0 +1,66 @@
+#import "DDSCircleLayerExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleDDSCircleLayer = @"DDSCircleLayerExample";
+
+@interface DDSCircleLayerExample () <MGLMapViewDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+
+@end
+
+@implementation DDSCircleLayerExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Create a new map view using the Mapbox Light style.
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds
+ styleURL:[MGLStyle lightStyleURLWithVersion:9]];
+
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.mapView.tintColor = [UIColor darkGrayColor];
+
+ // Set the map’s center coordinate and zoom level.
+ self.mapView.centerCoordinate = CLLocationCoordinate2DMake(38.897,-77.039);
+ self.mapView.zoomLevel = 10.5;
+
+ self.mapView.delegate = self;
+ [self.view addSubview: self.mapView];
+}
+
+// Wait until the style is loaded before modifying the map style.
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+
+ // "mapbox://examples.2uf7qges" is a map ID referencing a tileset. For more
+ // more information, see mapbox.com/help/define-map-id/
+ MGLSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"trees" configurationURL:[NSURL URLWithString:@"mapbox://examples.2uf7qges"]];
+
+ [self.mapView.style addSource:source];
+
+ MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithIdentifier: @"tree-style" source:source];
+
+ // The source name from the source's TileJSON metadata: mapbox.com/api-documentation/#retrieve-tilejson-metadata
+ layer.sourceLayerIdentifier = @"yoshino-trees-a0puw5";
+
+ // Stops based on age of tree in years.
+ NSDictionary *stops = @{
+ @0: [MGLStyleValue valueWithRawValue:[UIColor colorWithRed:1.00 green:0.72 blue:0.85 alpha:1.0]],
+ @2: [MGLStyleValue valueWithRawValue:[UIColor colorWithRed:0.69 green:0.48 blue:0.73 alpha:1.0]],
+ @4: [MGLStyleValue valueWithRawValue:[UIColor colorWithRed:0.61 green:0.31 blue:0.47 alpha:1.0]],
+ @7: [MGLStyleValue valueWithRawValue:[UIColor colorWithRed:0.43 green:0.20 blue:0.38 alpha:1.0]],
+ @16: [MGLStyleValue valueWithRawValue:[UIColor colorWithRed:0.33 green:0.17 blue:0.25 alpha:1.0]]
+ };
+
+ // Style the circle layer color based on the above categorical stops.
+ layer.circleColor = [MGLStyleValue valueWithInterpolationMode: MGLInterpolationModeInterval
+ sourceStops: stops
+ attributeName: @"AGE"
+ options: nil];
+
+ layer.circleRadius = [MGLStyleValue valueWithRawValue:@3];
+
+ [self.mapView.style addLayer:layer];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.h b/platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.h
new file mode 100644
index 0000000000..ea87633168
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.h
@@ -0,0 +1,13 @@
+//
+// DDSLayerSelectionExample.h
+// Examples
+//
+// Created by Jordan Kiley on 3/21/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DDSLayerSelectionExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.m b/platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.m
new file mode 100644
index 0000000000..d28a47a7f0
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DDSLayerSelectionExample.m
@@ -0,0 +1,97 @@
+
+#import "DDSLayerSelectionExample.h"
+@import Mapbox;
+
+NSString const *MBXExampleDDSLayerSelection = @"DDSLayerSelectionExample";
+
+@interface DDSLayerSelectionExample () <MGLMapViewDelegate, UIGestureRecognizerDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+
+@end
+
+@implementation DDSLayerSelectionExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.delegate = self;
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(39.23225,-97.91015)];
+
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
+ [self.view addSubview:self.mapView];
+
+ // Add a tap gesture recognizer to the map view.
+ UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
+ gesture.delegate = self;
+ gesture.numberOfTapsRequired = 1;
+ [self.mapView addGestureRecognizer:gesture];
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+
+ // Load a tileset containing U.S. states and their population density. For more information about working with tilesets, see: https://www.mapbox.com/help/studio-manual-tilesets/
+ NSURL *url = [NSURL URLWithString:@"mapbox://examples.69ytlgls"];
+
+ MGLVectorSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"state-source" configurationURL:url];
+ [style addSource:source];
+
+ MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"state-layer" source:source];
+
+ // Access the tileset layer.
+ layer.sourceLayerIdentifier = @"stateData_2-dx853g";
+
+ // Create a stops dictionary. This defines the relationship between population density and a UIColor.
+ NSDictionary *stops = @{
+ @0: [MGLStyleValue valueWithRawValue:[UIColor yellowColor]],
+ @600: [MGLStyleValue valueWithRawValue:[UIColor redColor]],
+ @1200: [MGLStyleValue valueWithRawValue:[UIColor blueColor]]
+ };
+
+ // Style the fill color using the stops dictionary, exponential interpolation mode, and the feature attribute name.
+ layer.fillColor = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ sourceStops:stops
+ attributeName:@"density"
+ options:@{MGLStyleFunctionOptionDefaultValue: [MGLStyleValue valueWithRawValue:[UIColor whiteColor]]}];
+
+ // Insert the new layer below the Mapbox Streets layer that contains state border lines. See the layer reference for more information about layer names: https://www.mapbox.com/vector-tiles/mapbox-streets-v7/
+ MGLStyleLayer *symbolLayer = [style layerWithIdentifier:@"admin-3-4-boundaries"];
+
+ [style insertLayer:layer belowLayer:symbolLayer];
+}
+
+- (void)handleTap:(UITapGestureRecognizer *)gesture {
+
+ // Get the CGPoint where the user tapped.
+ CGPoint spot = [gesture locationInView:self.mapView];
+
+ // Access the features at that point within the state layer.
+ NSArray *features = [self.mapView visibleFeaturesAtPoint:spot
+ inStyleLayersWithIdentifiers:[NSSet setWithObject:@"state-layer"]];
+
+ MGLPolygonFeature *feature = features.firstObject;
+
+ // Get the name of the selected state.
+ NSString *state = [feature attributeForKey:@"name"];
+
+ [self changeOpacityBasedOn:state];
+}
+
+- (void)changeOpacityBasedOn:(NSString*)name {
+
+ MGLFillStyleLayer *layer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"state-layer"];
+
+ // Check if a state was selected, then change the opacity of the states that were not selected.
+ if (name.length > 0) {
+ layer.fillOpacity = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeCategorical
+ sourceStops:@{name: [MGLStyleValue valueWithRawValue:@1]}
+ attributeName:@"name"
+ options:@{MGLStyleFunctionOptionDefaultValue: [MGLStyleValue valueWithRawValue:@0]}];
+ } else {
+ // Reset the opacity for all states if the user did not tap on a state.
+ layer.fillOpacity = [MGLStyleValue valueWithRawValue:@1];
+ }
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.h b/platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.h
new file mode 100644
index 0000000000..49af5d7b9c
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.h
@@ -0,0 +1,13 @@
+//
+// DefaultStylesExample.h
+// Examples
+//
+// Created by Jason Wray on 1/28/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DefaultStylesExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.m b/platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.m
new file mode 100644
index 0000000000..e6e5771f94
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DefaultStylesExample.m
@@ -0,0 +1,27 @@
+#import "DefaultStylesExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleDefaultStyles = @"DefaultStylesExample";
+
+@implementation DefaultStylesExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds
+ styleURL:[MGLStyle outdoorsStyleURLWithVersion:9]];
+
+ // Tint the ℹ️ button and the user location annotation.
+ mapView.tintColor = [UIColor darkGrayColor];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map’s center coordinate and zoom level.
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(51.50713, -0.10957)
+ zoomLevel:13
+ animated:NO];
+
+ [self.view addSubview:mapView];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.h b/platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.h
new file mode 100644
index 0000000000..5b0e571ad7
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.h
@@ -0,0 +1,13 @@
+//
+// DraggableAnnotationViewExample.h
+// Examples
+//
+// Created by Jason Wray on 7/11/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DraggableAnnotationViewExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.m b/platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.m
new file mode 100644
index 0000000000..17b2e552a7
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DraggableAnnotationViewExample.m
@@ -0,0 +1,143 @@
+#import "DraggableAnnotationViewExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleDraggableAnnotationView = @"DraggableAnnotationViewExample";
+
+// MGLAnnotationView subclass
+@interface DraggableAnnotationView : MGLAnnotationView
+@end
+@implementation DraggableAnnotationView
+
+- (instancetype)initWithReuseIdentifier:(nullable NSString *)reuseIdentifier size:(CGFloat)size {
+ self = [self initWithReuseIdentifier:reuseIdentifier];
+ if (self)
+ {
+ // `draggable` is a property of MGLAnnotationView, disabled by default.
+ self.draggable = true;
+
+ // This property prevents the annotation from changing size when the map is tilted.
+ self.scalesWithViewingDistance = false;
+
+ // Begin setting up the view.
+ self.frame = CGRectMake(0, 0, size, size);
+
+ self.backgroundColor = [UIColor darkGrayColor];
+
+ // Use CALayer’s corner radius to turn this view into a circle.
+ self.layer.cornerRadius = size / 2;
+ self.layer.borderWidth = 1;
+ self.layer.borderColor = [UIColor whiteColor].CGColor;
+ self.layer.shadowColor = [UIColor blackColor].CGColor;
+ self.layer.shadowOpacity = 0.1;
+ }
+ return self;
+}
+
+- (void)setDragState:(MGLAnnotationViewDragState)dragState animated:(BOOL)animated {
+ [super setDragState:dragState animated:animated];
+
+ switch (dragState) {
+ case MGLAnnotationViewDragStateStarting:
+ printf("Starting");
+ [self startDragging];
+ break;
+
+ case MGLAnnotationViewDragStateDragging:
+ printf(".");
+ break;
+
+ case MGLAnnotationViewDragStateEnding:
+ case MGLAnnotationViewDragStateCanceling:
+ printf("Ending\n");
+ [self endDragging];
+ break;
+
+ case MGLAnnotationViewDragStateNone:
+ return;
+ }
+}
+
+// When the user interacts with an annotation, animate opacity and scale changes.
+- (void)startDragging {
+ [UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:0 animations:^{
+ self.layer.opacity = 0.8;
+ self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.5, 1.5);
+ } completion:nil];
+}
+
+- (void)endDragging {
+ self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.5, 1.5);
+ [UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:0 animations:^{
+ self.layer.opacity = 1;
+ self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
+ } completion:nil];
+}
+
+@end
+
+
+//
+// Example view controller
+@interface DraggableAnnotationViewExample () <MGLMapViewDelegate>
+@end
+@implementation DraggableAnnotationViewExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.styleURL = [MGLStyle lightStyleURLWithVersion:9];
+ mapView.tintColor = [UIColor darkGrayColor];
+ mapView.zoomLevel = 1;
+ mapView.delegate = self;
+ [self.view addSubview:mapView];
+
+ // Specify coordinates for our annotations.
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(0, -70),
+ CLLocationCoordinate2DMake(0, -35),
+ CLLocationCoordinate2DMake(0, 0),
+ CLLocationCoordinate2DMake(0, 35),
+ CLLocationCoordinate2DMake(0, 70),
+ };
+ NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
+
+ // Fill an array with point annotations and add it to the map.
+ NSMutableArray *pointAnnotations = [NSMutableArray arrayWithCapacity:numberOfCoordinates];
+ for (NSUInteger i = 0; i < numberOfCoordinates; i++) {
+ CLLocationCoordinate2D coordinate = coordinates[i];
+ MGLPointAnnotation *point = [[MGLPointAnnotation alloc] init];
+ point.coordinate = coordinate;
+ point.title = @"To drag this annotation, first tap and hold.";
+ [pointAnnotations addObject:point];
+ }
+
+ [mapView addAnnotations:pointAnnotations];
+}
+
+#pragma mark - MGLMapViewDelegate methods
+
+// This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
+- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
+ // This example is only concerned with point annotations.
+ if (![annotation isKindOfClass:[MGLPointAnnotation class]]) {
+ return nil;
+ }
+
+ // For better performance, always try to reuse existing annotations. To use multiple different annotation views, change the reuse identifier for each.
+ DraggableAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"draggablePoint"];
+
+ // If there’s no reusable annotation view available, initialize a new one.
+ if (!annotationView) {
+ annotationView = [[DraggableAnnotationView alloc] initWithReuseIdentifier:@"draggablePoint" size:50];
+ }
+
+ return annotationView;
+}
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation {
+ return YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.h b/platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.h
new file mode 100644
index 0000000000..8a16ca91bb
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.h
@@ -0,0 +1,13 @@
+//
+// DrawingACustomMarkerExample.h
+// Examples
+//
+// Created by Jason Wray on 2/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DrawingACustomMarkerExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.m b/platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.m
new file mode 100644
index 0000000000..ad80b49efc
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingACustomMarkerExample.m
@@ -0,0 +1,67 @@
+#import "DrawingACustomMarkerExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleDrawingACustomMarker = @"DrawingACustomMarkerExample";
+
+@interface DrawingACustomMarkerExample () <MGLMapViewDelegate>
+@end
+
+@implementation DrawingACustomMarkerExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ NSURL *styleURL = [MGLStyle lightStyleURLWithVersion:9];
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:styleURL];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.tintColor = [UIColor darkGrayColor];
+
+ // Set the map‘s bounds to Pisa, Italy.
+ MGLCoordinateBounds bounds = MGLCoordinateBoundsMake(
+ CLLocationCoordinate2DMake(43.7115, 10.3725),
+ CLLocationCoordinate2DMake(43.7318, 10.4222));
+ [mapView setVisibleCoordinateBounds:bounds];
+
+ [self.view addSubview:mapView];
+
+ // Set the map view‘s delegate property.
+ mapView.delegate = self;
+
+ // Initialize and add the point annotation.
+ MGLPointAnnotation *pisa = [[MGLPointAnnotation alloc] init];
+ pisa.coordinate = CLLocationCoordinate2DMake(43.723, 10.396633);
+ pisa.title = @"Leaning Tower of Pisa";
+ [mapView addAnnotation:pisa];
+}
+
+- (MGLAnnotationImage *)mapView:(MGLMapView *)mapView imageForAnnotation:(id <MGLAnnotation>)annotation {
+ // Try to reuse the existing ‘pisa’ annotation image, if it exists.
+ MGLAnnotationImage *annotationImage = [mapView dequeueReusableAnnotationImageWithIdentifier:@"pisa"];
+
+ // If the ‘pisa’ annotation image hasn‘t been set yet, initialize it here.
+ if (!annotationImage) {
+ // Leaning Tower of Pisa by Stefan Spieler from the Noun Project.
+ UIImage *image = [UIImage imageNamed:@"pisavector"];
+
+ // The anchor point of an annotation is currently always the center. To
+ // shift the anchor point to the bottom of the annotation, the image
+ // asset includes transparent bottom padding equal to the original image
+ // height.
+ //
+ // To make this padding non-interactive, we create another image object
+ // with a custom alignment rect that excludes the padding.
+ image = [image imageWithAlignmentRectInsets:UIEdgeInsetsMake(0, 0, image.size.height/2, 0)];
+
+ // Initialize the ‘pisa’ annotation image with the UIImage we just loaded.
+ annotationImage = [MGLAnnotationImage annotationImageWithImage:image reuseIdentifier:@"pisa"];
+ }
+
+ return annotationImage;
+}
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id <MGLAnnotation>)annotation {
+ // Always allow callouts to popup when annotations are tapped.
+ return YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.h b/platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.h
new file mode 100644
index 0000000000..afc23b4ee6
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.h
@@ -0,0 +1,13 @@
+//
+// DrawingAGeoJSONLineExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DrawingAGeoJSONLineExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.m b/platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.m
new file mode 100644
index 0000000000..2b6cd88f47
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingAGeoJSONLineExample.m
@@ -0,0 +1,80 @@
+#import "DrawingAGeoJSONLineExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleDrawingAGeoJSONLine = @"DrawingAGeoJSONLineExample";
+
+@interface DrawingAGeoJSONLineExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@end
+
+@implementation DrawingAGeoJSONLineExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map's center coordinate
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.5076, -122.6736)
+ zoomLevel:11
+ animated:NO];
+
+ [self.view addSubview:self.mapView];
+
+ // Set the delegate property of our map view to self after instantiating it.
+ self.mapView.delegate = self;
+
+ [self drawPolyline];
+}
+
+- (void)drawPolyline {
+ // Perform GeoJSON parsing on a background thread
+ dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+ dispatch_async(backgroundQueue, ^(void) {
+ // Get the path for example.geojson in the app's bundle
+ NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"geojson"];
+
+ // Convert the file contents to a shape collection feature object
+ NSData *data = [[NSData alloc] initWithContentsOfFile:jsonPath];
+ MGLShapeCollectionFeature *shapeCollectionFeature = (MGLShapeCollectionFeature *)[MGLShape shapeWithData:data encoding:NSUTF8StringEncoding error:NULL];
+
+ MGLPolylineFeature *polyline = (MGLPolylineFeature *)shapeCollectionFeature.shapes.firstObject;
+
+ // Optionally set the title of the polyline, which can be used for:
+ // - Callout view
+ // - Object identification
+ // In this case, set it to the name included in the GeoJSON
+ polyline.title = polyline.attributes[@"name"]; // "Crema to Council Crest"
+
+ // Add the polyline to the map, back on the main thread
+ // Use weak reference to self to prevent retain cycle
+ __weak typeof(self) weakSelf = self;
+ dispatch_async(dispatch_get_main_queue(), ^(void) {
+ [weakSelf.mapView addAnnotation:polyline];
+ });
+ });
+}
+
+- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation {
+ // Set the alpha for all shape annotations to 1 (full opacity)
+ return 1.0f;
+}
+
+- (CGFloat)mapView:(MGLMapView *)mapView lineWidthForPolylineAnnotation:(MGLPolyline *)annotation {
+ // Set the line width for polyline annotations
+ return 2.0f;
+}
+
+- (UIColor *)mapView:(MGLMapView *)mapView strokeColorForShapeAnnotation:(MGLShape *)annotation {
+ // Set the stroke color for shape annotations
+ // ... but give our polyline a unique color by checking for its `title` property
+ if ([annotation.title isEqualToString:@"Crema to Council Crest"]) {
+ // Mapbox cyan
+ return [UIColor colorWithRed:59.0f/255.0f green:178.0f/255.0f blue:208.0f/255.0f alpha:1.0f];
+ } else {
+ return [UIColor redColor];
+ }
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.h b/platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.h
new file mode 100644
index 0000000000..a3c478bab6
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.h
@@ -0,0 +1,13 @@
+//
+// DrawingAMarkerExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DrawingAMarkerExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.m b/platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.m
new file mode 100644
index 0000000000..6aacdf2caa
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingAMarkerExample.m
@@ -0,0 +1,48 @@
+#import "DrawingAMarkerExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleDrawingAMarker = @"DrawingAMarkerExample";
+
+@interface DrawingAMarkerExample () <MGLMapViewDelegate>
+@end
+
+@implementation DrawingAMarkerExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map’s center coordinates and zoom level.
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(40.7326808, -73.9843407)
+ zoomLevel:12
+ animated:NO];
+
+ [self.view addSubview:mapView];
+
+ // Set the delegate property of our map view to `self` after instantiating it.
+ mapView.delegate = self;
+
+ // Declare the marker `hello` and set its coordinates, title, and subtitle.
+ MGLPointAnnotation *hello = [[MGLPointAnnotation alloc] init];
+ hello.coordinate = CLLocationCoordinate2DMake(40.7326808, -73.9843407);
+ hello.title = @"Hello world!";
+ hello.subtitle = @"Welcome to my marker";
+
+ // Add marker `hello` to the map
+ [mapView addAnnotation:hello];
+}
+
+// Use the default marker. See also: our view annotation or custom marker examples.
+- (MGLAnnotationImage *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
+ return nil;
+}
+
+// Allow callout view to appear when an annotation is tapped.
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id <MGLAnnotation>)annotation {
+ return YES;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.h b/platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.h
new file mode 100644
index 0000000000..29487ea8c2
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.h
@@ -0,0 +1,13 @@
+//
+// DrawingAPolygonExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface DrawingAPolygonExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.m b/platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.m
new file mode 100644
index 0000000000..eb304a5c00
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/DrawingAPolygonExample.m
@@ -0,0 +1,77 @@
+#import "DrawingAPolygonExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleDrawingAPolygon = @"DrawingAPolygonExample";
+
+@interface DrawingAPolygonExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@end
+
+@implementation DrawingAPolygonExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map's center coordinate
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.520486, -122.673541)
+ zoomLevel:11
+ animated:NO];
+
+ [self.view addSubview:self.mapView];
+
+ // Set the delegate property of our map view to self after instantiating it
+ self.mapView.delegate = self;
+}
+
+- (void)viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+
+ // Draw the polygon after the map has initialized
+ [self drawShape];
+}
+
+- (void)drawShape {
+ // Create a coordinates array to hold all of the coordinates for our shape.
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(45.522585, -122.685699),
+ CLLocationCoordinate2DMake(45.534611, -122.708873),
+ CLLocationCoordinate2DMake(45.530883, -122.678833),
+ CLLocationCoordinate2DMake(45.547115, -122.667503),
+ CLLocationCoordinate2DMake(45.530643, -122.660121),
+ CLLocationCoordinate2DMake(45.533529, -122.636260),
+ CLLocationCoordinate2DMake(45.521743, -122.659091),
+ CLLocationCoordinate2DMake(45.510677, -122.648792),
+ CLLocationCoordinate2DMake(45.515008, -122.664070),
+ CLLocationCoordinate2DMake(45.502496, -122.669048),
+ CLLocationCoordinate2DMake(45.515369, -122.678489),
+ CLLocationCoordinate2DMake(45.506346, -122.702007),
+ CLLocationCoordinate2DMake(45.522585, -122.685699),
+ };
+ NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
+
+ // Create our shape with the formatted coordinates array
+ MGLPolygon *shape = [MGLPolygon polygonWithCoordinates:coordinates count:numberOfCoordinates];
+
+ // Add the shape to the map
+ [self.mapView addAnnotation:shape];
+}
+
+- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation {
+ // Set the alpha for shape annotations to 0.5 (half opacity)
+ return 0.5f;
+}
+
+- (UIColor *)mapView:(MGLMapView *)mapView strokeColorForShapeAnnotation:(MGLShape *)annotation {
+ // Set the stroke color for shape annotations
+ return [UIColor whiteColor];
+}
+
+- (UIColor *)mapView:(MGLMapView *)mapView fillColorForPolygonAnnotation:(MGLPolygon *)annotation {
+ // Mapbox cyan fill color
+ return [UIColor colorWithRed:59.0f/255.0f green:178.0f/255.0f blue:208.0f/255.0f alpha:1.0f];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.h b/platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.h
new file mode 100644
index 0000000000..a7ca638729
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.h
@@ -0,0 +1,13 @@
+//
+// ExtrusionsExample.h
+// Examples
+//
+// Created by Jordan Kiley on 5/11/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ExtrusionsExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.m b/platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.m
new file mode 100644
index 0000000000..c87449fb12
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/ExtrusionsExample.m
@@ -0,0 +1,56 @@
+//
+// ExtrusionsExample.m
+// Examples
+//
+// Created by Jordan Kiley on 5/11/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+#import "ExtrusionsExample.h"
+
+@import Mapbox;
+
+NSString *const MBXExample3DExtrusions = @"ExtrusionsExample";
+
+@interface ExtrusionsExample () <MGLMapViewDelegate>
+
+@end
+
+@implementation ExtrusionsExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[MGLStyle lightStyleURLWithVersion:9]];
+
+ // Center the map on the Colosseum in Rome, Italy.
+
+ // Center the map view on the Colosseum in Rome, Italy and set the camera's pitch and distance.
+ mapView.camera = [MGLMapCamera cameraLookingAtCenterCoordinate:CLLocationCoordinate2DMake(41.8902, 12.4922) fromDistance:600 pitch:60 heading:0];
+ mapView.delegate = self;
+
+ [self.view addSubview:mapView];
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+
+ // Access the Mapbox Streets source and use it to create a `MGLFillExtrusionStyleLayer`. The source identifier is `composite`. Use the `sources` property on a style to verify source identifiers.
+ MGLSource *source = [style sourceWithIdentifier:@"composite"];
+ MGLFillExtrusionStyleLayer *layer = [[MGLFillExtrusionStyleLayer alloc] initWithIdentifier:@"buildings" source:source];
+ layer.sourceLayerIdentifier = @"building";
+
+ // Filter out buildings that should not extrude.
+ layer.predicate = [NSPredicate predicateWithFormat:@"extrude == 'true' AND height >= 0"];
+
+ // Set the fill extrusion height to the value for the building height attribute.
+ layer.fillExtrusionHeight = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"height" options:nil];
+ layer.fillExtrusionBase =[MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"min_height" options:nil];
+ layer.fillExtrusionOpacity = [MGLStyleValue valueWithRawValue:@0.75];
+ layer.fillExtrusionColor = [MGLStyleValue valueWithRawValue:[UIColor whiteColor]];
+
+ // Insert the fill extrusion layer below a POI label layer. If you aren’t sure what the layer is called, you can view the style in Mapbox Studio or iterate over the style’s layers property, printing out each layer’s identifier.
+ MGLStyleLayer *symbolLayer = [style layerWithIdentifier:@"poi-scalerank3"];
+ [style insertLayer:layer belowLayer:symbolLayer];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.h b/platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.h
new file mode 100644
index 0000000000..291b7b328f
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.h
@@ -0,0 +1,13 @@
+//
+// OfflinePackExample.h
+// Examples
+//
+// Created by Jason Wray on 3/31/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface OfflinePackExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.m b/platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.m
new file mode 100644
index 0000000000..7640d6439f
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/OfflinePackExample.m
@@ -0,0 +1,113 @@
+#import "OfflinePackExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleOfflinePack = @"OfflinePackExample";
+
+@interface OfflinePackExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) UIProgressView *progressView;
+@end
+
+@implementation OfflinePackExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[MGLStyle darkStyleURLWithVersion:9]];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.mapView.tintColor = [UIColor lightGrayColor];
+ self.mapView.delegate = self;
+ [self.view addSubview:self.mapView];
+
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(22.27933, 114.16281)
+ zoomLevel:13
+ animated:NO];
+
+ // Setup offline pack notification handlers.
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackProgressDidChange:) name:MGLOfflinePackProgressChangedNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackDidReceiveError:) name:MGLOfflinePackErrorNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackDidReceiveMaximumAllowedMapboxTiles:) name:MGLOfflinePackMaximumMapboxTilesReachedNotification object:nil];
+}
+
+- (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {
+ // Start downloading tiles and resources for z13-16.
+ [self startOfflinePackDownload];
+}
+
+- (void)dealloc {
+ // Remove offline pack observers.
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)startOfflinePackDownload {
+ // Create a region that includes the current viewport and any tiles needed to view it when zoomed further in.
+ // Because tile count grows exponentially with the maximum zoom level, you should be conservative with your `toZoomLevel` setting.
+ id <MGLOfflineRegion> region = [[MGLTilePyramidOfflineRegion alloc] initWithStyleURL:self.mapView.styleURL bounds:self.mapView.visibleCoordinateBounds fromZoomLevel:self.mapView.zoomLevel toZoomLevel:16];
+
+ // Store some data for identification purposes alongside the downloaded resources.
+ NSDictionary *userInfo = @{ @"name": @"My Offline Pack" };
+ NSData *context = [NSKeyedArchiver archivedDataWithRootObject:userInfo];
+
+ // Create and register an offline pack with the shared offline storage object.
+ [[MGLOfflineStorage sharedOfflineStorage] addPackForRegion:region withContext:context completionHandler:^(MGLOfflinePack *pack, NSError *error) {
+ if (error != nil) {
+ // The pack couldn’t be created for some reason.
+ NSLog(@"Error: %@", error.localizedFailureReason);
+ } else {
+ // Start downloading.
+ [pack resume];
+ }
+ }];
+}
+
+#pragma mark - MGLOfflinePack notification handlers
+
+- (void)offlinePackProgressDidChange:(NSNotification *)notification {
+ MGLOfflinePack *pack = notification.object;
+
+ // Get the associated user info for the pack; in this case, `name = My Offline Pack`
+ NSDictionary *userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:pack.context];
+
+ MGLOfflinePackProgress progress = pack.progress;
+ // or [notification.userInfo[MGLOfflinePackProgressUserInfoKey] MGLOfflinePackProgressValue]
+ uint64_t completedResources = progress.countOfResourcesCompleted;
+ uint64_t expectedResources = progress.countOfResourcesExpected;
+
+ // Calculate current progress percentage.
+ float progressPercentage = (float)completedResources / expectedResources;
+
+ // Setup the progress bar.
+ if (!self.progressView) {
+ self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
+ CGSize frame = self.view.bounds.size;
+ self.progressView.frame = CGRectMake(frame.width / 4, frame.height * 0.75, frame.width / 2, 10);
+ [self.view addSubview:self.progressView];
+ }
+
+ [self.progressView setProgress:progressPercentage animated:YES];
+
+ // If this pack has finished, print its size and resource count.
+ if (completedResources == expectedResources) {
+ NSString *byteCount = [NSByteCountFormatter stringFromByteCount:progress.countOfBytesCompleted countStyle:NSByteCountFormatterCountStyleMemory];
+ NSLog(@"Offline pack “%@” completed: %@, %llu resources", userInfo[@"name"], byteCount, completedResources);
+ } else {
+ // Otherwise, print download/verification progress.
+ NSLog(@"Offline pack “%@” has %llu of %llu resources — %.2f%%.", userInfo[@"name"], completedResources, expectedResources, progressPercentage * 100);
+ }
+}
+
+- (void)offlinePackDidReceiveError:(NSNotification *)notification {
+ MGLOfflinePack *pack = notification.object;
+ NSDictionary *userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:pack.context];
+ NSError *error = notification.userInfo[MGLOfflinePackUserInfoKeyError];
+ NSLog(@"Offline pack “%@” received error: %@", userInfo[@"name"], error.localizedFailureReason);
+}
+
+- (void)offlinePackDidReceiveMaximumAllowedMapboxTiles:(NSNotification *)notification {
+ MGLOfflinePack *pack = notification.object;
+ NSDictionary *userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:pack.context];
+ uint64_t maximumCount = [notification.userInfo[MGLOfflinePackUserInfoKeyMaximumCount] unsignedLongLongValue];
+ NSLog(@"Offline pack “%@” reached limit of %llu tiles.", userInfo[@"name"], maximumCount);
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/PointConversionExample.h b/platform/ios/demo/Examples/ObjectiveC/PointConversionExample.h
new file mode 100644
index 0000000000..1a8cbdf302
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/PointConversionExample.h
@@ -0,0 +1,13 @@
+//
+// PointConversionExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface PointConversionExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/PointConversionExample.m b/platform/ios/demo/Examples/ObjectiveC/PointConversionExample.m
new file mode 100644
index 0000000000..a5156e64fc
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/PointConversionExample.m
@@ -0,0 +1,64 @@
+#import "PointConversionExample.h"
+@import Mapbox;
+
+NSString *const MBXExamplePointConversion = @"PointConversionExample";
+
+@interface PointConversionExample ()
+@property (nonatomic) MGLMapView *mapView;
+@end
+
+@implementation PointConversionExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [self.view addSubview:self.mapView];
+
+ // Double tapping zooms the map, so ensure that can still happen.
+ UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:nil];
+ doubleTap.numberOfTapsRequired = 2;
+ [self.mapView addGestureRecognizer:doubleTap];
+
+ // Delay single tap recognition until it is clearly not a double.
+ UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
+ [singleTap requireGestureRecognizerToFail:doubleTap];
+ [self.mapView addGestureRecognizer:singleTap];
+
+ // Convert `mapView.centerCoordinate` (CLLocationCoordinate2D)
+ // to screen location (CGPoint).
+ CGPoint centerScreenPoint = [self.mapView convertCoordinate:self.mapView.centerCoordinate
+ toPointToView:self.mapView];
+
+ NSLog(@"Screen center: %@ = %@",
+ NSStringFromCGPoint(centerScreenPoint),
+ NSStringFromCGPoint(self.mapView.center));
+}
+
+- (void)handleSingleTap:(UITapGestureRecognizer *)tap {
+ // Convert tap location (CGPoint)
+ // to geographic coordinates (CLLocationCoordinate2D).
+ CLLocationCoordinate2D location = [self.mapView convertPoint:[tap locationInView:self.mapView]
+ toCoordinateFromView:self.mapView];
+
+ NSLog(@"You tapped at: %.5f, %.5f", location.latitude, location.longitude);
+
+ // Create an array of coordinates for our polyline.
+ CLLocationCoordinate2D coordinates[] = {
+ self.mapView.centerCoordinate,
+ location
+ };
+ NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
+
+ // Remove existing polyline from the map, (re)add polyline with coordinates.
+ if (self.mapView.annotations.count) {
+ [self.mapView removeAnnotations:self.mapView.annotations];
+ }
+ MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:coordinates
+ count:numberOfCoordinates];
+ [self.mapView addAnnotation:polyline];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.h b/platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.h
new file mode 100644
index 0000000000..551dc20e8a
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.h
@@ -0,0 +1,13 @@
+//
+// RuntimeAddLineExample.h
+// Examples
+//
+// Created by Eric Wolfe on 11/30/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RuntimeAddLineExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.m b/platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.m
new file mode 100644
index 0000000000..6cc80b002e
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeAddLineExample.m
@@ -0,0 +1,94 @@
+#import "RuntimeAddLineExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleRuntimeAddLine = @"RuntimeAddLineExample";
+
+@interface RuntimeAddLineExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@end
+
+@implementation RuntimeAddLineExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.5076, -122.6736)
+ zoomLevel:11
+ animated:NO];
+
+ [self.view addSubview:self.mapView];
+
+ self.mapView.delegate = self;
+}
+
+// Wait until the map is loaded before adding to the map.
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ [self loadGeoJSON];
+}
+
+- (void)loadGeoJSON {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ NSString *path = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"geojson"];
+ NSData *jsonData = [NSData dataWithContentsOfFile:path];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self drawPolyline:jsonData];
+ });
+ });
+}
+
+- (void)drawPolyline:(NSData *)geoJson {
+ // Add our GeoJSON data to the map as an MGLShapeSource.
+ // We can then reference this data from an MGLStyleLayer.
+ MGLShape *shape = [MGLShape shapeWithData:geoJson encoding:NSUTF8StringEncoding error:nil];
+ MGLSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"polyline" shape:shape options:nil];
+ [self.mapView.style addSource:source];
+
+ // Create new layer for the line
+ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"polyline" source:source];
+ layer.lineJoin = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLineJoin:MGLLineJoinRound]];
+ layer.lineCap = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLineCap:MGLLineCapRound]];
+ layer.lineColor = [MGLStyleValue valueWithRawValue:[UIColor colorWithRed:59/255.0 green:178/255.0 blue:208/255.0 alpha:1]];
+ // Use a style function to smoothly adjust the line width from 2pt to 20pt between zoom levels 14 and 18. The `interpolationBase` parameter allows the values to interpolate along an exponential curve.
+ layer.lineWidth = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ cameraStops:@{
+ @14: [MGLStyleValue valueWithRawValue:@2],
+ @18: [MGLStyleValue valueWithRawValue:@20]
+ }
+ options:@{MGLStyleFunctionOptionDefaultValue:@1.5}];
+
+ // We can also add a second layer that will draw a stroke around the original line.
+ MGLLineStyleLayer *casingLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"polyline-case" source:source];
+ // Copy these attributes from the main line layer.
+ casingLayer.lineJoin = layer.lineJoin;
+ casingLayer.lineCap = layer.lineCap;
+ // Line gap width represents the space before the outline begins, so should match the main line’s line width exactly.
+ casingLayer.lineGapWidth = layer.lineWidth;
+ // Stroke color slightly darker than the line color.
+ casingLayer.lineColor = [MGLStyleValue valueWithRawValue:[UIColor colorWithRed:41/255.0 green:145/255.0 blue:171/255.0 alpha:1]];
+ // Use a style function to gradually increase the stroke width between zoom levels 14 and 18.
+ casingLayer.lineWidth = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ cameraStops:@{
+ @14: [MGLStyleValue valueWithRawValue:@1],
+ @18: [MGLStyleValue valueWithRawValue:@4]
+ }
+ options:@{MGLStyleFunctionOptionDefaultValue:@1.5}];
+
+ // Just for fun, let’s add another copy of the line with a dash pattern.
+ MGLLineStyleLayer *dashedLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"polyline-dash" source:source];
+ dashedLayer.lineJoin = layer.lineJoin;
+ dashedLayer.lineCap = layer.lineCap;
+ dashedLayer.lineWidth = layer.lineWidth;
+ dashedLayer.lineColor = [MGLStyleValue valueWithRawValue:[UIColor whiteColor]];
+ dashedLayer.lineOpacity = [MGLStyleValue valueWithRawValue:@0.5];
+ // Dash pattern in the format [dash, gap, dash, gap, ...]. You’ll want to adjust these values based on the line cap style.
+ dashedLayer.lineDashPattern = [MGLStyleValue valueWithRawValue:@[@0, @1.5]];
+
+ [self.mapView.style addLayer:layer];
+ [self.mapView.style addLayer:dashedLayer];
+ [self.mapView.style insertLayer:casingLayer belowLayer:layer];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.h b/platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.h
new file mode 100644
index 0000000000..bd55ce2efc
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.h
@@ -0,0 +1,13 @@
+//
+// RuntimeAnimateLineExample.h
+// Examples
+//
+// Created by Eric Wolfe on 11/30/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RuntimeAnimateLineExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.m b/platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.m
new file mode 100644
index 0000000000..a9a44a97e7
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeAnimateLineExample.m
@@ -0,0 +1,181 @@
+#import "RuntimeAnimateLineExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleRuntimeAnimateLine = @"RuntimeAnimateLineExample";
+
+@interface RuntimeAnimateLineExample () <MGLMapViewDelegate> {
+ int _currentIndex;
+ NSTimer *_timer;
+}
+
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) MGLShapeSource *polylineSource;
+@property (nonatomic) NSArray<CLLocation *> *locations;
+
+@end
+
+@implementation RuntimeAnimateLineExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.5076, -122.6736)
+ zoomLevel:11
+ animated:NO];
+
+ [self.view addSubview:self.mapView];
+
+ self.mapView.delegate = self;
+}
+
+// Wait until the map is loaded before adding to the map.
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ [self addLayer];
+ [self animatePolyline];
+}
+
+- (void)addLayer {
+ // Add an empty MGLShapeSource, we’ll keep a reference to this and add points to this later.
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"polyline" features:@[] options:nil];
+ [self.mapView.style addSource:source];
+ self.polylineSource = source;
+
+ // Add a layer to style our polyline.
+ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"polyline" source:source];
+ layer.lineJoin = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLineJoin:MGLLineJoinRound]];
+ layer.lineCap = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLineCap:MGLLineCapRound]];
+ layer.lineColor = [MGLStyleValue valueWithRawValue:[UIColor redColor]];
+ layer.lineWidth = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ cameraStops: @{
+ @14: [MGLStyleValue valueWithRawValue:@5],
+ @18: [MGLStyleValue valueWithRawValue:@20]
+ }
+ options:@{MGLStyleFunctionOptionDefaultValue:@1.75}];
+
+ [self.mapView.style addLayer:layer];
+}
+
+- (void)animatePolyline {
+ _currentIndex = 1;
+
+ // Start a timer that will simulate adding points to our polyline. This could also represent coordinates being added to our polyline from another source, such as a CLLocationManagerDelegate.
+ _timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(tick) userInfo:nil repeats:YES];
+}
+
+- (void)tick {
+ if (_currentIndex > self.locations.count) {
+ [_timer invalidate];
+ _timer = nil;
+ return;
+ }
+
+ // Create a subarray of locations up to the current index.
+ NSArray *currentLocations = [self.locations subarrayWithRange:NSMakeRange(0, _currentIndex)];
+
+ // Update our MGLShapeSource with the current locations.
+ [self updatePolylineWithLocations:currentLocations];
+
+ _currentIndex++;
+}
+
+- (void)updatePolylineWithLocations:(NSArray<CLLocation *> *)locations {
+ CLLocationCoordinate2D coordinates[locations.count];
+
+ for (NSUInteger i = 0; i < locations.count; i++) {
+ coordinates[i] = locations[i].coordinate;
+ }
+
+ MGLPolylineFeature *polyline = [MGLPolylineFeature polylineWithCoordinates:coordinates count:locations.count];
+
+ // Updating the MGLShapeSource’s shape will have the map redraw our polyline with the current coordinates.
+ self.polylineSource.shape = polyline;
+}
+
+- (NSArray<CLLocation *> *)locations {
+ NSArray *coordinates = @[
+ @[@(-122.63748), @45.52214],
+ @[@(-122.64855), @45.52218],
+ @[@(-122.6545), @45.52219],
+ @[@(-122.65497), @45.52196],
+ @[@(-122.65631), @45.52104],
+ @[@(-122.6578), @45.51935],
+ @[@(-122.65867), @45.51848],
+ @[@(-122.65872), @45.51293],
+ @[@(-122.66576), @45.51295],
+ @[@(-122.66745), @45.51252],
+ @[@(-122.66813), @45.51244],
+ @[@(-122.67359), @45.51385],
+ @[@(-122.67415), @45.51406],
+ @[@(-122.67481), @45.51484],
+ @[@(-122.676), @45.51532],
+ @[@(-122.68106), @45.51668],
+ @[@(-122.68503), @45.50934],
+ @[@(-122.68546), @45.50858],
+ @[@(-122.6852), @45.50783],
+ @[@(-122.68424), @45.50714],
+ @[@(-122.68433), @45.50585],
+ @[@(-122.68429), @45.50521],
+ @[@(-122.68456), @45.50445],
+ @[@(-122.68538), @45.50371],
+ @[@(-122.68653), @45.50311],
+ @[@(-122.68731), @45.50292],
+ @[@(-122.68742), @45.50253],
+ @[@(-122.6867), @45.50239],
+ @[@(-122.68545), @45.5026],
+ @[@(-122.68407), @45.50294],
+ @[@(-122.68357), @45.50271],
+ @[@(-122.68236), @45.50055],
+ @[@(-122.68233), @45.49994],
+ @[@(-122.68267), @45.49955],
+ @[@(-122.68257), @45.49919],
+ @[@(-122.68376), @45.49842],
+ @[@(-122.68428), @45.49821],
+ @[@(-122.68573), @45.49798],
+ @[@(-122.68923), @45.49805],
+ @[@(-122.68926), @45.49857],
+ @[@(-122.68814), @45.49911],
+ @[@(-122.68865), @45.49921],
+ @[@(-122.6897), @45.49905],
+ @[@(-122.69346), @45.49917],
+ @[@(-122.69404), @45.49902],
+ @[@(-122.69438), @45.49796],
+ @[@(-122.69504), @45.49697],
+ @[@(-122.69624), @45.49661],
+ @[@(-122.69781), @45.4955],
+ @[@(-122.69803), @45.49517],
+ @[@(-122.69711), @45.49508],
+ @[@(-122.69688), @45.4948],
+ @[@(-122.69744), @45.49368],
+ @[@(-122.69702), @45.49311],
+ @[@(-122.69665), @45.49294],
+ @[@(-122.69788), @45.49212],
+ @[@(-122.69771), @45.49264],
+ @[@(-122.69835), @45.49332],
+ @[@(-122.7007), @45.49334],
+ @[@(-122.70167), @45.49358],
+ @[@(-122.70215), @45.49401],
+ @[@(-122.70229), @45.49439],
+ @[@(-122.70185), @45.49566],
+ @[@(-122.70215), @45.49635],
+ @[@(-122.70346), @45.49674],
+ @[@(-122.70517), @45.49758],
+ @[@(-122.70614), @45.49736],
+ @[@(-122.70663), @45.49736],
+ @[@(-122.70807), @45.49767],
+ @[@(-122.70807), @45.49798],
+ @[@(-122.70717), @45.49798],
+ @[@(-122.70713), @45.4984],
+ @[@(-122.70774), @45.49893],
+ ];
+
+ NSMutableArray<CLLocation *> *locations = [NSMutableArray array];
+ for (NSArray<NSNumber *> *c in coordinates) {
+ [locations addObject:[[CLLocation alloc] initWithLatitude:[c[1] doubleValue] longitude:[c[0] doubleValue]]];
+ }
+ return locations;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.h b/platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.h
new file mode 100644
index 0000000000..8bf17738ee
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.h
@@ -0,0 +1,13 @@
+//
+// RuntimeCircleStylesExample.h
+// Examples
+//
+// Created by Eric Wolfe on 11/30/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RuntimeCircleStylesExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.m b/platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.m
new file mode 100644
index 0000000000..7d01692e6d
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeCircleStylesExample.m
@@ -0,0 +1,77 @@
+#import "RuntimeCircleStylesExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleRuntimeCircleStyles = @"RuntimeCircleStylesExample";
+
+@interface RuntimeCircleStylesExample () <MGLMapViewDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+
+@end
+
+@implementation RuntimeCircleStylesExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ [self.mapView setStyleURL:[MGLStyle lightStyleURLWithVersion:9]];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.mapView.tintColor = [UIColor darkGrayColor];
+
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(37.753574, -122.447303)
+ zoomLevel:10
+ animated:NO];
+
+ [self.view addSubview:self.mapView];
+
+ self.mapView.delegate = self;
+}
+
+// Wait until the style is loaded before modifying the map style.
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ [self addLayer];
+}
+
+- (void)addLayer {
+ MGLSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"population" configurationURL:[NSURL URLWithString:@"mapbox://examples.8fgz4egr"]];
+
+ NSDictionary *ethnicities = @{
+ @"White": [UIColor colorWithRed: 251/255.0 green: 176/255.0 blue: 59/255.0 alpha: 1.0],
+ @"Black": [UIColor colorWithRed: 34/255.0 green: 59/255.0 blue: 83/255.0 alpha: 1.0],
+ @"Hispanic": [UIColor colorWithRed: 229/255.0 green: 94/255.0 blue: 94/255.0 alpha: 1.0],
+ @"Asian": [UIColor colorWithRed: 59/255.0 green: 178/255.0 blue: 208/255.0 alpha: 1.0],
+ @"Other": [UIColor colorWithRed: 204/255.0 green: 204/255.0 blue: 204/255.0 alpha: 1.0],
+ };
+
+
+ [self.mapView.style addSource:source];
+
+ // Create a new layer for each ethnicity/circle color.
+ for (NSString *key in [ethnicities allKeys]) {
+ // Each layer should have a unique identifier.
+ MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithIdentifier:[NSString stringWithFormat:@"population-%@", key] source:source];
+
+ // Specifying the `sourceLayerIdentifier` is required for a vector tile source. This is the json attribute that wraps the data in the source.
+ layer.sourceLayerIdentifier = @"sf2010";
+
+ // Use a style function to smoothly adjust the circle radius from 2pt to 180pt between zoom levels 12 and 22. The `interpolationBase` parameter allows the values to interpolate along an exponential curve.
+ layer.circleRadius = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ cameraStops:@{
+ @12: [MGLStyleValue valueWithRawValue:@2],
+ @22: [MGLStyleValue valueWithRawValue:@180]
+ }
+ options: @{MGLStyleFunctionOptionDefaultValue:@1.75}];
+ layer.circleOpacity = [MGLStyleValue valueWithRawValue:@0.7];
+
+ // Set the circle color to match the ethnicity.
+ layer.circleColor = [MGLStyleValue valueWithRawValue:ethnicities[key]];
+
+ // Use an NSPredicate to filter to just one ethnicity for this layer.
+ layer.predicate = [NSPredicate predicateWithFormat:@"ethnicity == %@", key];
+
+ [self.mapView.style addLayer:layer];
+ }
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.h b/platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.h
new file mode 100644
index 0000000000..306c6f107a
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.h
@@ -0,0 +1,13 @@
+//
+// RuntimeMultipleAnnotationsExample.h
+// Examples
+//
+// Created by Eric Wolfe on 12/2/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RuntimeMultipleAnnotationsExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.m b/platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.m
new file mode 100644
index 0000000000..4c4308cd3c
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeMultipleAnnotationsExample.m
@@ -0,0 +1,216 @@
+#import "RuntimeMultipleAnnotationsExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleRuntimeMultipleAnnotations = @"RuntimeMultipleAnnotationsExample";
+
+@interface RuntimeMultipleAnnotationsExample ()<MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@end
+
+@implementation RuntimeMultipleAnnotationsExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(37.090240, -95.712891) zoomLevel:2 animated:NO];
+
+ mapView.delegate = self;
+
+ // Add our own gesture recognizer to handle taps on our custom map features.
+ [mapView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleMapTap:)]];
+
+ [self.view addSubview:mapView];
+
+ self.mapView = mapView;
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ [self fetchPoints:^(NSArray *features) {
+ [self addItemsToMap:features];
+ }];
+}
+
+- (void)addItemsToMap:(NSArray *)features {
+ // You can add custom UIImages to the map style.
+ // These can be referenced by an MGLSymbolStyleLayer’s iconImage property.
+ [self.mapView.style setImage:[UIImage imageNamed:@"lighthouse"] forName:@"lighthouse"];
+
+ // Add the features to the map as a MGLShapeSource.
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"lighthouses" features:features options:nil];
+ [self.mapView.style addSource:source];
+
+ UIColor *lighthouseColor = [UIColor colorWithRed:0.08 green:0.44 blue:0.96 alpha:1.0];
+
+ // Use MGLCircleStyleLayer to represent the points with simple circles.
+ // In this case, we can use style functions to gradually change properties between zoom level 2 and 7: the circle opacity from 50% to 100% and the circle radius from 2pt to 3pt.
+ MGLCircleStyleLayer *circles = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"lighthouse-circles" source:source];
+ circles.circleColor = [MGLStyleValue valueWithRawValue:lighthouseColor];
+ circles.circleOpacity = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ cameraStops:@{
+ @2: [MGLStyleValue valueWithRawValue:@0.5],
+ @7: [MGLStyleValue valueWithRawValue:@1.0]
+ }
+ options:@{MGLStyleFunctionOptionDefaultValue:[MGLStyleValue valueWithRawValue:@0.75]}];
+
+ circles.circleRadius = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeInterval
+ cameraStops:@{
+ @2: [MGLStyleValue valueWithRawValue:@2],
+ @7: [MGLStyleValue valueWithRawValue:@3]
+ }
+ options:@{MGLStyleFunctionOptionDefaultValue:@1}];
+
+ // Use MGLSymbolStyleLayer for more complex styling of points including custom icons and text rendering.
+ MGLSymbolStyleLayer *symbols = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"lighthouse-symbols" source:source];
+ symbols.iconImageName = [MGLStyleValue valueWithRawValue:@"lighthouse"];
+ symbols.iconScale = [MGLStyleValue valueWithRawValue:@0.5];
+ symbols.iconOpacity = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ cameraStops:@{
+ @5.9: [MGLStyleValue valueWithRawValue:@0],
+ @6: [MGLStyleValue valueWithRawValue:@1],
+ }
+ options:nil];
+ symbols.iconHaloColor = [MGLStyleValue valueWithRawValue:[[UIColor whiteColor] colorWithAlphaComponent:0.5]];
+ symbols.iconHaloWidth = [MGLStyleValue valueWithRawValue:@1];
+ // {name} references the "name" key in an MGLPointFeature’s attributes dictionary.
+ symbols.text = [MGLStyleValue valueWithRawValue:@"{name}"];
+ symbols.textColor = symbols.iconColor;
+ symbols.textFontSize = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
+ cameraStops:@{
+ @10: [MGLStyleValue valueWithRawValue:@10],
+ @16: [MGLStyleValue valueWithRawValue:@16],
+ }
+ options:nil];
+ symbols.textTranslation = [MGLStyleValue valueWithRawValue:[NSValue valueWithCGVector:CGVectorMake(10, 0)]];
+ symbols.textOpacity = symbols.iconOpacity;
+ symbols.textHaloColor = symbols.iconHaloColor;
+ symbols.textHaloWidth = symbols.iconHaloWidth;
+ symbols.textJustification = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLTextJustification:MGLTextJustificationLeft]];
+ symbols.textAnchor = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLTextAnchor:MGLTextAnchorLeft]];
+
+ [self.mapView.style addLayer:circles];
+ [self.mapView.style addLayer:symbols];
+}
+
+#pragma mark - Feature interaction
+
+- (void)handleMapTap:(UITapGestureRecognizer *)sender {
+ if (sender.state == UIGestureRecognizerStateEnded) {
+ // Limit feature selection to just the following layer identifiers.
+ NSArray *layerIdentifiers = @[@"lighthouse-symbols", @"lighthouse-circles"];
+
+ CGPoint point = [sender locationInView:sender.view];
+
+ // Try matching the exact point first
+ for (id f in [self.mapView visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:[NSSet setWithArray:layerIdentifiers]]) {
+ if ([f isKindOfClass:[MGLPointFeature class]]) {
+ [self showCallout:f];
+ return;
+ }
+ }
+
+ // Otherwise, get first features within a rect the size of a touch (44x44).
+ CGRect pointRect = {point, CGSizeZero};
+ CGRect touchRect = CGRectInset(pointRect, -22.0, -22.0);
+ for (id f in [self.mapView visibleFeaturesInRect:touchRect inStyleLayersWithIdentifiers:[NSSet setWithArray:layerIdentifiers]]) {
+ if ([f isKindOfClass:[MGLPointFeature class]]) {
+ [self showCallout:f];
+ return;
+ }
+ }
+
+ // If no features were found, deselect the selected annotation, if any.
+ [self.mapView deselectAnnotation:[[self.mapView selectedAnnotations] firstObject] animated:YES];
+ }
+}
+
+- (void)showCallout:(MGLPointFeature *)feature {
+ MGLPointFeature *point = [[MGLPointFeature alloc] init];
+ point.title = feature.attributes[@"name"];
+ point.coordinate = feature.coordinate;
+
+ // Selecting an feature that doesn’t already exist on the map will add a new annotation view.
+ // We’ll need to use the map’s delegate methods to add an empty annotation view and remove it when we’re done selecting it.
+ [self.mapView selectAnnotation:point animated:YES];
+}
+
+#pragma mark - MGLMapViewDelegate
+
+- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id <MGLAnnotation>)annotation {
+ return YES;
+}
+
+- (void)mapView:(MGLMapView *)mapView didDeselectAnnotation:(id <MGLAnnotation>)annotation {
+ [mapView removeAnnotation:annotation];
+}
+
+- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
+ // Create an empty view annotation. Set a frame to offset the callout.
+ return [[MGLAnnotationView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
+}
+
+#pragma mark - Data fetching and parsing
+
+- (void)fetchPoints:(void (^)(NSArray *))completion {
+ // Wikidata query for all lighthouses in the United States: http://tinyurl.com/zrl2jc4
+ NSString *query = @"SELECT DISTINCT ?item "
+ "?itemLabel ?coor ?image "
+ "WHERE "
+ "{ "
+ "?item wdt:P31 wd:Q39715 . "
+ "?item wdt:P17 wd:Q30 . "
+ "?item wdt:P625 ?coor . "
+ "OPTIONAL { ?item wdt:P18 ?image } . "
+ "SERVICE wikibase:label { bd:serviceParam wikibase:language \"en\" } "
+ "} "
+ "ORDER BY ?itemLabel";
+
+ NSMutableCharacterSet *characterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
+ [characterSet removeCharactersInString:@"?"];
+ [characterSet removeCharactersInString:@"&"];
+ [characterSet removeCharactersInString:@":"];
+
+ NSString *encodedQuery = [query stringByAddingPercentEncodingWithAllowedCharacters:characterSet];
+
+ NSString *urlString = [NSString stringWithFormat:@"https://query.wikidata.org/sparql?query=%@&format=json", encodedQuery];
+
+ [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:urlString] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
+ if (!data) return;
+
+ NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
+ NSArray *items = json[@"results"][@"bindings"];
+
+ if (!items) return;
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completion([self parseJSONItems:items]);
+ });
+ }] resume];
+}
+
+- (NSArray *)parseJSONItems:(NSArray *)items {
+ NSMutableArray *features = [NSMutableArray array];
+ for (NSDictionary *item in items) {
+ NSString *title = item[@"itemLabel"][@"value"];
+ NSString *point = item[@"coor"][@"value"];
+ if (!item || !point) continue;
+
+ NSString *parsedPoint = [[point stringByReplacingOccurrencesOfString:@"Point(" withString:@""] stringByReplacingOccurrencesOfString:@")" withString:@""];
+ NSArray *pointComponents = [parsedPoint componentsSeparatedByString:@" "];
+
+ MGLPointFeature *feature = [[MGLPointFeature alloc] init];
+ feature.coordinate = CLLocationCoordinate2DMake([pointComponents[1] doubleValue], [pointComponents[0] doubleValue]);
+ feature.title = title;
+ // A feature’s attributes can used by runtime styling for things like text labels.
+ feature.attributes = @{
+ @"name": title,
+ };
+ [features addObject:feature];
+ }
+ return features;
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.h b/platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.h
new file mode 100644
index 0000000000..d5b8b61bf9
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.h
@@ -0,0 +1,13 @@
+//
+// RuntimeToggleLayerExample.h
+// Examples
+//
+// Created by Eric Wolfe on 11/30/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RuntimeToggleLayerExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.m b/platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.m
new file mode 100644
index 0000000000..9f61c11d7a
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/RuntimeToggleLayerExample.m
@@ -0,0 +1,92 @@
+#import "RuntimeToggleLayerExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleRuntimeToggleLayer = @"RuntimeToggleLayerExample";
+
+@interface RuntimeToggleLayerExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) MGLStyleLayer *contoursLayer;
+@end
+
+@implementation RuntimeToggleLayerExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map's center coordinate
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(37.745395, -119.594421)
+ zoomLevel:11
+ animated:NO];
+
+ [self.view addSubview:self.mapView];
+
+ [self addToggleButton];
+
+ // Set the delegate property of our map view to self after instantiating it
+ self.mapView.delegate = self;
+}
+
+// Wait until the style is loaded before modifying the map style
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ [self addLayer];
+}
+
+- (void)addLayer {
+ MGLSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"contours" configurationURL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]];
+
+ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"contours" source:source];
+ layer.sourceLayerIdentifier = @"contour";
+ layer.lineJoin = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLineJoin:MGLLineJoinRound]];
+ layer.lineCap = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLineCap:MGLLineCapRound]];
+ layer.lineColor = [MGLStyleValue valueWithRawValue:[UIColor brownColor]];
+ layer.lineWidth = [MGLStyleValue valueWithRawValue:@1];
+
+ [self.mapView.style addSource:source];
+
+ MGLStyleLayer *waterLayer = [self.mapView.style layerWithIdentifier:@"water"];
+ if (waterLayer != nil) {
+ // You can insert a layer below an existing style layer
+ [self.mapView.style insertLayer:layer belowLayer:waterLayer];
+ } else {
+ // or you can simply add it above all layers
+ [self.mapView.style addLayer:layer];
+ }
+
+ self.contoursLayer = layer;
+
+ [self showContours];
+}
+
+- (void)toggleLayer:(UIButton *)sender {
+ sender.selected = !sender.selected;
+ if (sender.selected) {
+ [self showContours];
+ } else {
+ [self hideContours];
+ }
+}
+
+- (void)showContours {
+ [self.contoursLayer setVisible:YES];
+}
+
+- (void)hideContours {
+ [self.contoursLayer setVisible:NO];
+}
+
+- (void)addToggleButton {
+ UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
+ button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ [button setTitle:@"Toggle Contours" forState:UIControlStateNormal];
+ [button setSelected:YES];
+ [button sizeToFit];
+ button.center = CGPointMake(self.view.center.x, 0);
+ button.frame = CGRectMake(button.frame.origin.x, self.view.frame.size.height - button.frame.size.height - 5, button.frame.size.width, button.frame.size.height);
+ [button addTarget:self action:@selector(toggleLayer:) forControlEvents:UIControlEventTouchUpInside];
+ [self.view addSubview:button];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.h b/platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.h
new file mode 100644
index 0000000000..1aa0390bc8
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.h
@@ -0,0 +1,13 @@
+//
+// SatelliteStyleExample.h
+// Examples
+//
+// Created by Jason Wray on 1/29/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface SatelliteStyleExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.m b/platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.m
new file mode 100644
index 0000000000..dee1b0ab5d
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SatelliteStyleExample.m
@@ -0,0 +1,28 @@
+#import "SatelliteStyleExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleSatelliteStyle = @"SatelliteStyleExample";
+
+@implementation SatelliteStyleExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // A hybrid style with unobtrusive labels is also available via +satelliteStreetsStyleURLWithVersion:.
+ NSURL *styleURL = [MGLStyle satelliteStyleURLWithVersion:9];
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:styleURL];
+
+ // Tint the ℹ️ button.
+ mapView.attributionButton.tintColor = [UIColor whiteColor];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map’s center coordinate and zoom level.
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.5188, -122.6748)
+ zoomLevel:13
+ animated:NO];
+
+ [self.view addSubview:mapView];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.h b/platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.h
new file mode 100644
index 0000000000..b441514711
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.h
@@ -0,0 +1,13 @@
+//
+// SelectFeatureExample.h
+// Examples
+//
+// Created by Eric Wolfe on 12/2/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface SelectFeatureExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.m b/platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.m
new file mode 100644
index 0000000000..c3f5dd971d
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SelectFeatureExample.m
@@ -0,0 +1,71 @@
+#import "SelectFeatureExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleSelectFeature = @"SelectFeatureExample";
+
+@interface SelectFeatureExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) MGLShapeSource *selectedFeaturesSource;
+@end
+
+@implementation SelectFeatureExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.5076, -122.6736)
+ zoomLevel:11
+ animated:NO];
+
+ // Add our own gesture recognizer to handle taps on our custom map features
+ [mapView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapMap:)]];
+
+ mapView.delegate = self;
+
+ [self.view addSubview:mapView];
+
+ self.mapView = mapView;
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ // Create a placeholder MGLShapeSource that will hold copies of any features we’ve selected.
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"selected-features" features:@[] options:nil];
+ [style addSource:source];
+
+ // Keep a reference to the source so we can update it when the map is tapped.
+ self.selectedFeaturesSource = source;
+
+ // Color any selected features red on the map.
+ MGLFillStyleLayer *selectedFeaturesLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"selected-features" source:source];
+ selectedFeaturesLayer.fillColor = [MGLStyleValue valueWithRawValue:[UIColor redColor]];
+
+ [style addLayer:selectedFeaturesLayer];
+}
+
+- (void)didTapMap:(UITapGestureRecognizer *)recognizer {
+ if (recognizer.state == UIGestureRecognizerStateEnded) {
+ // A tap’s center coordinate may not intersect a feature exactly, so let’s make a 44x44 rect that represents a touch and select all features that interesect.
+ CGRect pointRect = { [recognizer locationInView:recognizer.view], CGSizeZero };
+ CGRect touchRect = CGRectInset(pointRect, -22.0, -22.0);
+
+ // Let’s only select parks near the rect. There’s a layer within the Mapbox Streets style with "id" = "park". You can see all of the layers used within the default mapbox styles by creating a new style using Mapbox Studio.
+ NSSet *layerIdentifiers = [NSSet setWithObject:@"park"];
+
+ // Query the current mapview for any features that intersect our rect.
+ NSMutableArray *features = [NSMutableArray array];
+ for (id f in [self.mapView visibleFeaturesInRect:touchRect inStyleLayersWithIdentifiers:layerIdentifiers]) {
+ [features addObject:f];
+ }
+
+ MGLShapeCollectionFeature *shapes = [MGLShapeCollectionFeature shapeCollectionWithShapes:features];
+
+ // Update our MGLShapeSource to match our selected features.
+ self.selectedFeaturesSource.shape = shapes;
+ }
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.h b/platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.h
new file mode 100644
index 0000000000..ea6f9b46c1
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.h
@@ -0,0 +1,13 @@
+//
+// ShapeCollectionFeatureExample.h
+// Examples
+//
+// Created by Nadia Barbosa on 3/7/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ShapeCollectionFeatureExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.m b/platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.m
new file mode 100644
index 0000000000..3ca7467f9c
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/ShapeCollectionFeatureExample.m
@@ -0,0 +1,68 @@
+#import "ShapeCollectionFeatureExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleShapeCollectionFeature = @"ShapeCollectionFeatureExample";
+
+@interface ShapeCollectionFeatureExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLMapView *mapView;
+@end
+
+@implementation ShapeCollectionFeatureExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[MGLStyle lightStyleURLWithVersion:9]];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.mapView.tintColor = [UIColor darkGrayColor];
+
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(38.897435, -77.039679) zoomLevel:12 animated:NO];
+ self.mapView.delegate = self;
+
+ [self.view addSubview:self.mapView];
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+
+ // Parse the GeoJSON data.
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ NSString *path = [[NSBundle mainBundle] pathForResource:@"metro-line" ofType:@"geojson"];
+
+ NSData *data = [NSData dataWithContentsOfFile:path];
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self drawShapeCollection:data];
+ });
+ });
+}
+
+- (void)drawShapeCollection:(NSData *)data {
+
+ // Use [MGLShape shapeWithData:encoding:error:] to create a MGLShapeCollectionFeature from GeoJSON data.
+ MGLShape *feature = [MGLShape shapeWithData:data encoding:NSUTF8StringEncoding error:NULL];
+
+ // Create source and add it to the map style.
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"transit" shape:feature options:nil];
+ [self.mapView.style addSource:source];
+
+ // Create station style layer.
+ MGLCircleStyleLayer *circleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"stations" source:source];
+ circleLayer.predicate = [NSPredicate predicateWithFormat:@"TYPE = 'Station'"];
+ circleLayer.circleColor = [MGLStyleValue valueWithRawValue:[UIColor redColor]];
+ circleLayer.circleRadius = [MGLStyleValue valueWithRawValue:@6];
+ circleLayer.circleStrokeWidth = [MGLStyleValue valueWithRawValue:@2];
+ circleLayer.circleStrokeColor = [MGLStyleValue valueWithRawValue:[UIColor blackColor]];
+
+ // Create line style layer.
+ MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"rail-line" source: source];
+ lineLayer.predicate = [NSPredicate predicateWithFormat:@"TYPE = 'Rail line'"];
+ lineLayer.lineColor = [MGLStyleValue valueWithRawValue:[UIColor redColor]];
+ lineLayer.lineWidth = [MGLStyleValue valueWithRawValue:@2];
+
+ // Add style layers to the map view's style.
+ [self.mapView.style addLayer:circleLayer];
+ [self.mapView.style insertLayer:lineLayer belowLayer:circleLayer];
+}
+
+@end
+
diff --git a/platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.h b/platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.h
new file mode 100644
index 0000000000..b137216a1c
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.h
@@ -0,0 +1,13 @@
+//
+// SimpleMapViewExample.h
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface SimpleMapViewExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.m b/platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.m
new file mode 100644
index 0000000000..9d16978baa
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SimpleMapViewExample.m
@@ -0,0 +1,23 @@
+#import "SimpleMapViewExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleSimpleMapView = @"SimpleMapViewExample";
+
+@implementation SimpleMapViewExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ // Set the map’s center coordinate and zoom level.
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(59.31, 18.06)
+ zoomLevel:9
+ animated:NO];
+
+ [self.view addSubview:mapView];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.h b/platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.h
new file mode 100644
index 0000000000..d82f39a791
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.h
@@ -0,0 +1,13 @@
+//
+// SourceCustomRasterExample.h
+// Examples
+//
+// Created by Eric Wolfe on 12/2/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface SourceCustomRasterExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.m b/platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.m
new file mode 100644
index 0000000000..b17bac3282
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SourceCustomRasterExample.m
@@ -0,0 +1,58 @@
+#import "SourceCustomRasterExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleSourceCustomRaster = @"SourceCustomRasterExample";
+
+@interface SourceCustomRasterExample () <MGLMapViewDelegate>
+@property (nonatomic) MGLRasterStyleLayer *rasterLayer;
+@end
+
+@implementation SourceCustomRasterExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [mapView setCenterCoordinate:CLLocationCoordinate2DMake(45.5188, -122.6748)
+ zoomLevel:13
+ animated:NO];
+
+ mapView.delegate = self;
+
+ [self.view addSubview:mapView];
+
+ // Add a UISlider that will control the raster layer’s opacity.
+ [self addSlider];
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ // Add a new raster source and layer.
+ MGLRasterSource *source = [[MGLRasterSource alloc] initWithIdentifier:@"stamen-watercolor"
+ tileURLTemplates:@[@"https://stamen-tiles.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg"]
+ options:@{ MGLTileSourceOptionTileSize: @256}];
+ MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"stamen-watercolor" source:source];
+
+ [mapView.style addSource:source];
+ [mapView.style addLayer:rasterLayer];
+
+ self.rasterLayer = rasterLayer;
+}
+
+- (void)updateLayerOpacity:(UISlider *)sender {
+ [self.rasterLayer setRasterOpacity:[MGLStyleValue valueWithRawValue:@(sender.value)]];
+}
+
+- (void)addSlider {
+ CGFloat padding = 10.0;
+ UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(padding, self.view.frame.size.height - 44 - 30, self.view.frame.size.width - padding * 2, 44)];
+ slider.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ slider.minimumValue = 0;
+ slider.maximumValue = 1;
+ slider.value = 1;
+ [slider addTarget:self action:@selector(updateLayerOpacity:) forControlEvents:UIControlEventValueChanged];
+ [self.view addSubview:slider];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.h b/platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.h
new file mode 100644
index 0000000000..26af594a0b
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.h
@@ -0,0 +1,13 @@
+//
+// SourceCustomVectorExample.h
+// Examples
+//
+// Created by Eric Wolfe on 12/2/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface SourceCustomVectorExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.m b/platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.m
new file mode 100644
index 0000000000..069aa4ee26
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/SourceCustomVectorExample.m
@@ -0,0 +1,24 @@
+#import "SourceCustomVectorExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleSourceCustomVector = @"SourceCustomVectorExample";
+
+@implementation SourceCustomVectorExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Third party vector tile sources can be added.
+
+ // In this case we're using custom style JSON (https://www.mapbox.com/mapbox-gl-style-spec/) to add a third party tile source: <https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt>
+ NSURL *customStyleURL = [[NSBundle mainBundle] URLForResource:@"third_party_vector_style" withExtension:@"json"];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:customStyleURL];
+
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ mapView.tintColor = [UIColor whiteColor];
+
+ [self.view addSubview:mapView];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.h b/platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.h
new file mode 100644
index 0000000000..bde94c6a13
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.h
@@ -0,0 +1,13 @@
+//
+// UserTrackingModesExample.h
+// Examples
+//
+// Created by Jason Wray on 6/30/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface UserTrackingModesExample : UIViewController
+
+@end
diff --git a/platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.m b/platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.m
new file mode 100644
index 0000000000..621727128a
--- /dev/null
+++ b/platform/ios/demo/Examples/ObjectiveC/UserTrackingModesExample.m
@@ -0,0 +1,25 @@
+#import "UserTrackingModesExample.h"
+@import Mapbox;
+
+NSString *const MBXExampleUserTrackingModes = @"UserTrackingModesExample";
+
+@implementation UserTrackingModesExample
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[MGLStyle darkStyleURLWithVersion:9]];
+ mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ mapView.userTrackingMode = MGLUserTrackingModeFollowWithHeading;
+
+ // The user location annotation takes its color from the map view tint.
+ mapView.tintColor = [UIColor redColor];
+
+ // You can set the attribution button tint separately.
+ mapView.attributionButton.tintColor = [UIColor lightGrayColor];
+
+ [self.view addSubview:mapView];
+}
+
+@end
diff --git a/platform/ios/demo/Examples/Swift/AnnotationViewExample.swift b/platform/ios/demo/Examples/Swift/AnnotationViewExample.swift
new file mode 100644
index 0000000000..d818387861
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/AnnotationViewExample.swift
@@ -0,0 +1,95 @@
+import Mapbox
+
+@objc(AnnotationViewExample_Swift)
+
+// Example view controller
+class AnnotationViewExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.styleURL = MGLStyle.darkStyleURL(withVersion: 9)
+ mapView.tintColor = .lightGray
+ mapView.centerCoordinate = CLLocationCoordinate2D(latitude: 0, longitude: 66)
+ mapView.zoomLevel = 2
+ mapView.delegate = self
+ view.addSubview(mapView)
+
+ // Specify coordinates for our annotations.
+ let coordinates = [
+ CLLocationCoordinate2D(latitude: 0, longitude: 33),
+ CLLocationCoordinate2D(latitude: 0, longitude: 66),
+ CLLocationCoordinate2D(latitude: 0, longitude: 99),
+ ]
+
+ // Fill an array with point annotations and add it to the map.
+ var pointAnnotations = [MGLPointAnnotation]()
+ for coordinate in coordinates {
+ let point = MGLPointAnnotation()
+ point.coordinate = coordinate
+ point.title = "\(coordinate.latitude), \(coordinate.longitude)"
+ pointAnnotations.append(point)
+ }
+
+ mapView.addAnnotations(pointAnnotations)
+ }
+
+ // MARK: - MGLMapViewDelegate methods
+
+ // This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
+ func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
+ // This example is only concerned with point annotations.
+ guard annotation is MGLPointAnnotation else {
+ return nil
+ }
+
+ // Use the point annotation’s longitude value (as a string) as the reuse identifier for its view.
+ let reuseIdentifier = "\(annotation.coordinate.longitude)"
+
+ // For better performance, always try to reuse existing annotations.
+ var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
+
+ // If there’s no reusable annotation view available, initialize a new one.
+ if annotationView == nil {
+ annotationView = CustomAnnotationView(reuseIdentifier: reuseIdentifier)
+ annotationView!.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
+
+ // Set the annotation view’s background color to a value determined by its longitude.
+ let hue = CGFloat(annotation.coordinate.longitude) / 100
+ annotationView!.backgroundColor = UIColor(hue: hue, saturation: 0.5, brightness: 1, alpha: 1)
+ }
+
+ return annotationView
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ return true
+ }
+}
+
+//
+// MGLAnnotationView subclass
+class CustomAnnotationView: MGLAnnotationView {
+ override func layoutSubviews() {
+ super.layoutSubviews()
+
+ // Force the annotation view to maintain a constant size when the map is tilted.
+ scalesWithViewingDistance = false
+
+ // Use CALayer’s corner radius to turn this view into a circle.
+ layer.cornerRadius = frame.width / 2
+ layer.borderWidth = 2
+ layer.borderColor = UIColor.white.cgColor
+ }
+
+ override func setSelected(_ selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+
+ // Animate the border width in/out, creating an iris effect.
+ let animation = CABasicAnimation(keyPath: "borderWidth")
+ animation.duration = 0.1
+ layer.borderWidth = selected ? frame.width / 4 : 2
+ layer.add(animation, forKey: "borderWidth")
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/AnnotationViewMultipleExample.swift b/platform/ios/demo/Examples/Swift/AnnotationViewMultipleExample.swift
new file mode 100644
index 0000000000..2ba74c0385
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/AnnotationViewMultipleExample.swift
@@ -0,0 +1,105 @@
+import Mapbox
+
+// MGLPointAnnotation subclass
+class MyCustomPointAnnotation: MGLPointAnnotation {
+ var willUseImage: Bool = false
+}
+// end MGLPointAnnotation subclass
+
+@objc(AnnotationViewMultipleExample_Swift)
+
+class AnnotationViewMultipleExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Create a new map view using the Mapbox Light style.
+ let mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.lightStyleURL(withVersion: 9))
+
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ // Set the map’s center coordinate and zoom level.
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 36.54, longitude: -116.97), zoomLevel: 9, animated: false)
+ view.addSubview(mapView)
+ mapView.delegate = self
+
+ // Create four new point annotations with specified coordinates and titles.
+ let pointA = MyCustomPointAnnotation()
+ pointA.coordinate = CLLocationCoordinate2D(latitude: 36.4623, longitude: -116.8656)
+ pointA.title = "Stovepipe Wells"
+ pointA.willUseImage = true
+
+ let pointB = MyCustomPointAnnotation()
+ pointB.coordinate = CLLocationCoordinate2D(latitude: 36.6071, longitude: -117.1458)
+ pointB.title = "Furnace Creek"
+ pointB.willUseImage = true
+
+ let pointC = MyCustomPointAnnotation()
+ pointC.title = "Zabriskie Point"
+ pointC.coordinate = CLLocationCoordinate2D(latitude: 36.4208, longitude: -116.8101)
+
+ let pointD = MyCustomPointAnnotation()
+ pointD.title = "Mesquite Flat Sand Dunes"
+ pointD.coordinate = CLLocationCoordinate2D(latitude: 36.6836, longitude: -117.1005)
+
+ // Fill an array with four point annotations.
+ let myPlaces = [pointA, pointB, pointC, pointD]
+
+ // Add all annotations to the map all at once, instead of individually.
+ mapView.addAnnotations(myPlaces)
+
+ }
+
+ // This delegate method is where you tell the map to load a view for a specific annotation based on the willUseImage property of the custom subclass.
+ func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
+
+ if let castAnnotation = annotation as? MyCustomPointAnnotation {
+ if (castAnnotation.willUseImage) {
+ return nil;
+ }
+ }
+
+ // Assign a reuse identifier to be used by both of the annotation views, taking advantage of their similarities.
+ let reuseIdentifier = "reusableDotView"
+
+ // For better performance, always try to reuse existing annotations.
+ var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
+
+ // If there’s no reusable annotation view available, initialize a new one.
+ if annotationView == nil {
+ annotationView = MGLAnnotationView(reuseIdentifier: reuseIdentifier)
+ annotationView?.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
+ annotationView?.layer.cornerRadius = (annotationView?.frame.size.width)! / 2
+ annotationView?.layer.borderWidth = 4.0
+ annotationView?.layer.borderColor = UIColor.white.cgColor
+ annotationView!.backgroundColor = UIColor(red:0.03, green:0.80, blue:0.69, alpha:1.0)
+ }
+
+ return annotationView
+ }
+
+ // This delegate method is where you tell the map to load an image for a specific annotation based on the willUseImage property of the custom subclass.
+ func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
+
+ if let castAnnotation = annotation as? MyCustomPointAnnotation {
+ if (!castAnnotation.willUseImage) {
+ return nil;
+ }
+ }
+
+ // For better performance, always try to reuse existing annotations.
+ var annotationImage = mapView.dequeueReusableAnnotationImage(withIdentifier: "camera")
+
+ // If there is no reusable annotation image available, initialize a new one.
+ if(annotationImage == nil) {
+ annotationImage = MGLAnnotationImage(image: UIImage(named: "camera")!, reuseIdentifier: "camera")
+ }
+
+ return annotationImage
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ // Always allow callouts to popup when annotations are tapped.
+ return true
+ }
+
+}
diff --git a/platform/ios/demo/Examples/Swift/BlockingGesturesDelegateExample.swift b/platform/ios/demo/Examples/Swift/BlockingGesturesDelegateExample.swift
new file mode 100644
index 0000000000..45fb2ef340
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/BlockingGesturesDelegateExample.swift
@@ -0,0 +1,60 @@
+import Mapbox
+
+@objc(BlockingGesturesDelegateExample_Swift)
+
+class BlockingGesturesDelegateExample_Swift: UIViewController, MGLMapViewDelegate {
+
+ private var colorado: MGLCoordinateBounds!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.delegate = self
+
+ // Denver, Colorado
+ let center = CLLocationCoordinate2D(latitude: 39.748947, longitude: -104.995882)
+
+ // Starting point
+ mapView.setCenter(center, zoomLevel: 10, direction: 0, animated: false)
+
+ // Colorado's bounds
+ let ne = CLLocationCoordinate2D(latitude: 40.989329, longitude: -102.062592)
+ let sw = CLLocationCoordinate2D(latitude: 36.986207, longitude: -109.049896)
+ colorado = MGLCoordinateBounds(sw: sw, ne: ne)
+
+ view.addSubview(mapView)
+
+ }
+
+ // This example uses Colorado's boundaries to restrict
+ // the camera movement.
+
+ func mapView(_ mapView: MGLMapView, shouldChangeFrom oldCamera: MGLMapCamera, to newCamera: MGLMapCamera) -> Bool {
+
+ // Get the current camera to restore it after
+ let currentCamera = mapView.camera
+
+ // From the new camera obtain the center to test
+ // if it's inside the boundaries
+ let newCameraCenter = newCamera.centerCoordinate
+
+
+ // Set mapView to newCamera to project the
+ // new boundaries
+ mapView.camera = newCamera
+ let newVisibleCoordinates = mapView.visibleCoordinateBounds
+
+ // Revert the camera
+ mapView.camera = currentCamera
+
+ // Test if the newCameraCenter and newVisibleCoordinates
+ // are inside self.colorado
+ let inside = MGLCoordinateInCoordinateBounds(newCameraCenter, self.colorado)
+ let intersects = MGLCoordinateInCoordinateBounds(newVisibleCoordinates.ne, self.colorado) && MGLCoordinateInCoordinateBounds(newVisibleCoordinates.sw, self.colorado)
+
+ return inside && intersects
+
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/CalloutDelegateUsageExample.swift b/platform/ios/demo/Examples/Swift/CalloutDelegateUsageExample.swift
new file mode 100644
index 0000000000..e8ccc22db0
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CalloutDelegateUsageExample.swift
@@ -0,0 +1,69 @@
+import Mapbox
+
+@objc(CalloutDelegateUsageExample_Swift)
+
+class CalloutDelegateUsageExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ view.addSubview(mapView)
+
+ // Remember to set the delegate.
+ mapView.delegate = self
+
+ addAnnotation()
+ }
+
+ func addAnnotation() {
+ let annotation = MGLPointAnnotation()
+ annotation.coordinate = CLLocationCoordinate2D(latitude: 35.03946, longitude: 135.72956)
+ annotation.title = "Kinkaku-ji"
+ annotation.subtitle = "\(annotation.coordinate.latitude), \(annotation.coordinate.longitude)"
+
+ mapView.addAnnotation(annotation)
+
+ // Center the map on the annotation.
+ mapView.setCenter(annotation.coordinate, zoomLevel: 17, animated: false)
+
+ // Pop-up the callout view.
+ mapView.selectAnnotation(annotation, animated: true)
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ return true
+ }
+
+ func mapView(_ mapView: MGLMapView, leftCalloutAccessoryViewFor annotation: MGLAnnotation) -> UIView? {
+ if (annotation.title! == "Kinkaku-ji") {
+ // Callout height is fixed; width expands to fit its content.
+ let label = UILabel(frame: CGRect(x: 0, y: 0, width: 60, height: 50))
+ label.textAlignment = .right
+ label.textColor = UIColor(red: 0.81, green: 0.71, blue: 0.23, alpha: 1)
+ label.text = "金閣寺"
+
+ return label
+ }
+
+ return nil
+ }
+
+ func mapView(_ mapView: MGLMapView, rightCalloutAccessoryViewFor annotation: MGLAnnotation) -> UIView? {
+ return UIButton(type: .detailDisclosure)
+ }
+
+ func mapView(_ mapView: MGLMapView, annotation: MGLAnnotation, calloutAccessoryControlTapped control: UIControl) {
+ // Hide the callout view.
+ mapView.deselectAnnotation(annotation, animated: false)
+
+ // Show an alert containing the annotation's details
+ let alert = UIAlertController(title: annotation.title!!, message: "A lovely (if touristy) place.", preferredStyle: .alert)
+ alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
+ self.present(alert, animated: true, completion: nil)
+
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/CameraAnimationExample.swift b/platform/ios/demo/Examples/Swift/CameraAnimationExample.swift
new file mode 100644
index 0000000000..1fefa4940e
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CameraAnimationExample.swift
@@ -0,0 +1,34 @@
+import Mapbox
+
+@objc(CameraAnimationExample_Swift)
+
+class CameraAnimationExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.delegate = self
+
+ mapView.styleURL = MGLStyle.outdoorsStyleURL(withVersion: 9);
+
+ // Mauna Kea, Hawaii
+ let center = CLLocationCoordinate2D(latitude: 19.820689, longitude: -155.468038)
+
+ // Optionally set a starting point.
+ mapView.setCenter(center, zoomLevel: 7, direction: 0, animated: false)
+
+ view.addSubview(mapView)
+ }
+
+ func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
+ // Wait for the map to load before initiating the first camera movement.
+
+ // Create a camera that rotates around the same center point, rotating 180°.
+ // `fromDistance:` is meters above mean sea level that an eye would have to be in order to see what the map view is showing.
+ let camera = MGLMapCamera(lookingAtCenter: mapView.centerCoordinate, fromDistance: 4500, pitch: 15, heading: 180)
+
+ // Animate the camera movement over 5 seconds.
+ mapView.setCamera(camera, withDuration: 5, animationTimingFunction: CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut))
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/CameraFlyToExample.swift b/platform/ios/demo/Examples/Swift/CameraFlyToExample.swift
new file mode 100644
index 0000000000..4af319d43d
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CameraFlyToExample.swift
@@ -0,0 +1,40 @@
+import Mapbox
+
+@objc(CameraFlyToExample_Swift)
+
+class CameraFlyToExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ // Sets Honolulu, Hawaii as the camera's starting point.
+ let honolulu = CLLocationCoordinate2D(latitude: 21.3069,
+ longitude: -157.8583)
+ mapView.setCenter(honolulu,
+ zoomLevel:14, animated: false)
+
+ mapView.delegate = self
+ view.addSubview(mapView)
+ }
+
+ func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
+
+ // Waits for the mapView to finish loading before setting up the camera.
+ // Defines the destination camera as Hawaii Island.
+ let camera = MGLMapCamera(lookingAtCenter:
+ CLLocationCoordinate2D(latitude: 19.784213, longitude: -155.784605),
+ fromDistance: 35000, pitch: 70, heading: 90)
+
+ // Goes from Honolulu to destination camera.
+ mapView.fly(to: camera, withDuration: 4,
+ peakAltitude: 3000, completionHandler: nil)
+ // To use default duration and peak altitudes:
+ // mapView.fly(to: camera, completionHandler: nil)
+ // To use default peak altitude:
+ // mapView.fly(to: camera, withDuration: 4, completionHandler: nil)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/ClusteringExample.swift b/platform/ios/demo/Examples/Swift/ClusteringExample.swift
new file mode 100644
index 0000000000..2d181aa7bf
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/ClusteringExample.swift
@@ -0,0 +1,134 @@
+import Mapbox
+
+@objc(ClusteringExample_Swift)
+
+class ClusteringExample_Swift: UIViewController, MGLMapViewDelegate {
+
+ var mapView: MGLMapView!
+ var icon: UIImage!
+ var popup: UILabel?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.lightStyleURL(withVersion: 9))
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .darkGray
+ mapView.delegate = self
+ view.addSubview(mapView)
+
+ icon = UIImage(named: "port")
+ }
+
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ let url = URL(fileURLWithPath: Bundle.main.path(forResource: "ports", ofType: "geojson")!)
+
+ let source = MGLShapeSource(identifier: "clusteredPorts",
+ url: url,
+ options: [.clustered: true, .clusterRadius: icon.size.width])
+ style.addSource(source)
+
+ // Use a template image so that we can tint it with the `iconColor` runtime styling property.
+ style.setImage(icon.withRenderingMode(.alwaysTemplate), forName: "icon")
+
+ // Show unclustered features as icons. The `cluster` attribute is built into clustering-enabled source features.
+ let ports = MGLSymbolStyleLayer(identifier: "ports", source: source)
+ ports.iconImageName = MGLStyleValue(rawValue: "icon")
+ ports.iconColor = MGLStyleValue(rawValue: UIColor.darkGray.withAlphaComponent(0.9))
+ ports.predicate = NSPredicate(format: "%K != YES", "cluster")
+ style.addLayer(ports)
+
+ // Color clustered features based on clustered point counts.
+ let stops = [
+ 20: MGLStyleValue(rawValue: UIColor.lightGray),
+ 50: MGLStyleValue(rawValue: UIColor.orange),
+ 100: MGLStyleValue(rawValue: UIColor.red),
+ 200: MGLStyleValue(rawValue: UIColor.purple)
+ ]
+
+ // Show clustered features as circles. The `point_count` attribute is built into clustering-enabled source features.
+ let circlesLayer = MGLCircleStyleLayer(identifier: "clusteredPorts", source: source)
+ circlesLayer.circleRadius = MGLStyleValue(rawValue: NSNumber(value: Double(icon.size.width) / 2))
+ circlesLayer.circleOpacity = MGLStyleValue(rawValue: 0.75)
+ circlesLayer.circleStrokeColor = MGLStyleValue(rawValue: UIColor.white.withAlphaComponent(0.75))
+ circlesLayer.circleStrokeWidth = MGLStyleValue(rawValue: 2)
+ circlesLayer.circleColor = MGLSourceStyleFunction(interpolationMode: .interval,
+ stops: stops,
+ attributeName: "point_count",
+ options: nil)
+ circlesLayer.predicate = NSPredicate(format: "%K == YES", "cluster")
+ style.addLayer(circlesLayer)
+
+ // Label cluster circles with a layer of text indicating feature count. Per text token convention, wrap the attribute in {}.
+ let numbersLayer = MGLSymbolStyleLayer(identifier: "clusteredPortsNumbers", source: source)
+ numbersLayer.textColor = MGLStyleValue(rawValue: UIColor.white)
+ numbersLayer.textFontSize = MGLStyleValue(rawValue: NSNumber(value: Double(icon.size.width) / 2))
+ numbersLayer.iconAllowsOverlap = MGLStyleValue(rawValue: true)
+ numbersLayer.text = MGLStyleValue(rawValue: "{point_count}")
+ numbersLayer.predicate = NSPredicate(format: "%K == YES", "cluster")
+ style.addLayer(numbersLayer)
+
+ // Add a tap gesture for zooming in to clusters or showing popups on individual features.
+ view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))))
+ }
+
+ func mapViewRegionIsChanging(_ mapView: MGLMapView) {
+ showPopup(false, animated: false)
+ }
+
+ func handleTap(_ tap: UITapGestureRecognizer) {
+ if tap.state == .ended {
+ let point = tap.location(in: tap.view)
+ let width = icon.size.width
+ let rect = CGRect(x: point.x - width / 2, y: point.y - width / 2, width: width, height: width)
+
+ let clusters = mapView.visibleFeatures(in: rect, styleLayerIdentifiers: ["clusteredPorts"])
+ let ports = mapView.visibleFeatures(in: rect, styleLayerIdentifiers: ["ports"])
+
+ if clusters.count > 0 {
+ showPopup(false, animated: true)
+ let cluster = clusters.first!
+ mapView.setCenter(cluster.coordinate, zoomLevel: (mapView.zoomLevel + 1), animated: true)
+ } else if ports.count > 0 {
+ let port = ports.first!
+
+ if popup == nil {
+ popup = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
+ popup!.backgroundColor = UIColor.white.withAlphaComponent(0.9)
+ popup!.layer.cornerRadius = 4
+ popup!.layer.masksToBounds = true
+ popup!.textAlignment = .center
+ popup!.lineBreakMode = .byTruncatingTail
+ popup!.font = UIFont.systemFont(ofSize: 16)
+ popup!.textColor = UIColor.black
+ popup!.alpha = 0
+ view.addSubview(popup!)
+ }
+
+ popup!.text = (port.attribute(forKey: "name")! as! String)
+ let size = (popup!.text! as NSString).size(attributes: [NSFontAttributeName: popup!.font])
+ popup!.bounds = CGRect(x: 0, y: 0, width: size.width, height: size.height).insetBy(dx: -10, dy: -10)
+ let point = mapView.convert(port.coordinate, toPointTo: mapView)
+ popup!.center = CGPoint(x: point.x, y: point.y - 50)
+
+ if popup!.alpha < 1 {
+ showPopup(true, animated: true)
+ }
+ } else {
+ showPopup(false, animated: true)
+ }
+ }
+ }
+
+ func showPopup(_ shouldShow: Bool, animated: Bool) {
+ let alpha: CGFloat = (shouldShow ? 1 : 0)
+ if animated {
+ UIView.animate(withDuration: 0.25) { [unowned self] in
+ self.popup?.alpha = alpha
+ }
+ } else {
+ popup?.alpha = alpha
+ }
+ }
+
+}
diff --git a/platform/ios/demo/Examples/Swift/CustomAnnotationModelExample.swift b/platform/ios/demo/Examples/Swift/CustomAnnotationModelExample.swift
new file mode 100644
index 0000000000..fab7abdee8
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CustomAnnotationModelExample.swift
@@ -0,0 +1,114 @@
+import Mapbox
+
+@objc(CustomAnnotationModelExample_Swift)
+
+class CustomAnnotationModelExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.styleURL = MGLStyle.lightStyleURL(withVersion: 9)
+ mapView.tintColor = .darkGray
+ mapView.zoomLevel = 1
+ mapView.delegate = self
+ view.addSubview(mapView)
+
+ // Polyline
+ // Create a coordinates array with all of the coordinates for our polyline.
+ var coordinates = [
+ CLLocationCoordinate2D(latitude: 35, longitude: -25),
+ CLLocationCoordinate2D(latitude: 20, longitude: -30),
+ CLLocationCoordinate2D(latitude: 0, longitude: -25),
+ CLLocationCoordinate2D(latitude: -15, longitude: 0),
+ CLLocationCoordinate2D(latitude: -45, longitude: 10),
+ CLLocationCoordinate2D(latitude: -45, longitude: 40),
+ ]
+
+ let polyline = CustomPolyline(coordinates: &coordinates, count: UInt(coordinates.count))
+
+ // Set the custom `color` property, later used in the `mapView:strokeColorForShapeAnnotation:` delegate method.
+ polyline.color = .darkGray
+
+ // Add the polyline to the map. Note that this method name is singular.
+ mapView.addAnnotation(polyline)
+
+ // Point Annotations
+ // Add a custom point annotation for every coordinate (vertex) in the polyline.
+ var pointAnnotations = [CustomPointAnnotation]()
+ for coordinate in coordinates {
+ let count = pointAnnotations.count + 1
+ let point = CustomPointAnnotation(coordinate: coordinate,
+ title: "Custom Point Annotation \(count)",
+ subtitle: nil)
+
+ // Set the custom `image` and `reuseIdentifier` properties, later used in the `mapView:imageForAnnotation:` delegate method.
+ // Create a unique reuse identifier for each new annotation image.
+ point.reuseIdentifier = "customAnnotation\(count)"
+ // This dot image grows in size as more annotations are added to the array.
+ point.image = dot(size:5 * count)
+
+ // Append each annotation to the array, which will be added to the map all at once.
+ pointAnnotations.append(point)
+ }
+
+ // Add the point annotations to the map. This time the method name is plural.
+ // If you have multiple annotations to add, batching their addition to the map is more efficient.
+ mapView.addAnnotations(pointAnnotations)
+ }
+
+ func dot(size: Int) -> UIImage {
+ let floatSize = CGFloat(size)
+ let rect = CGRect(x: 0, y: 0, width: floatSize, height: floatSize)
+ let strokeWidth: CGFloat = 1
+
+ UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale)
+
+ let ovalPath = UIBezierPath(ovalIn: rect.insetBy(dx: strokeWidth, dy: strokeWidth))
+ UIColor.darkGray.setFill()
+ ovalPath.fill()
+
+ UIColor.white.setStroke()
+ ovalPath.lineWidth = strokeWidth
+ ovalPath.stroke()
+
+ let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
+ UIGraphicsEndImageContext()
+
+ return image
+ }
+
+ // MARK: - MGLMapViewDelegate methods
+
+ func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
+ if let point = annotation as? CustomPointAnnotation,
+ let image = point.image,
+ let reuseIdentifier = point.reuseIdentifier {
+
+ if let annotationImage = mapView.dequeueReusableAnnotationImage(withIdentifier: reuseIdentifier) {
+ // The annotatation image has already been cached, just reuse it.
+ return annotationImage
+ } else {
+ // Create a new annotation image.
+ return MGLAnnotationImage(image: image, reuseIdentifier: reuseIdentifier)
+ }
+ }
+
+ // Fallback to the default marker image.
+ return nil
+ }
+
+ func mapView(_ mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor {
+ if let annotation = annotation as? CustomPolyline {
+ // Return orange if the polyline does not have a custom color.
+ return annotation.color ?? .orange
+ }
+
+ // Fallback to the default tint color.
+ return mapView.tintColor
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ return true
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/CustomAnnotationModels.swift b/platform/ios/demo/Examples/Swift/CustomAnnotationModels.swift
new file mode 100644
index 0000000000..fba168d29b
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CustomAnnotationModels.swift
@@ -0,0 +1,28 @@
+import Mapbox
+
+// MGLAnnotation protocol reimplementation
+
+class CustomPointAnnotation: NSObject, MGLAnnotation {
+ // As a reimplementation of the MGLAnnotation protocol, we have to add mutable coordinate and (sub)title properties ourselves.
+ var coordinate: CLLocationCoordinate2D
+ var title: String?
+ var subtitle: String?
+
+ // Custom properties that we will use to customize the annotation's image.
+ var image: UIImage?
+ var reuseIdentifier: String?
+
+ init(coordinate: CLLocationCoordinate2D, title: String?, subtitle: String?) {
+ self.coordinate = coordinate
+ self.title = title
+ self.subtitle = subtitle
+ }
+}
+
+// MGLPolyline subclass
+class CustomPolyline: MGLPolyline {
+ // Because this is a subclass of MGLPolyline, there is no need to redeclare its properties.
+
+ // Custom property that we will use when drawing the polyline.
+ var color: UIColor?
+}
diff --git a/platform/ios/demo/Examples/Swift/CustomCalloutView.swift b/platform/ios/demo/Examples/Swift/CustomCalloutView.swift
new file mode 100644
index 0000000000..41483d41b4
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CustomCalloutView.swift
@@ -0,0 +1,127 @@
+import Mapbox
+
+class CustomCalloutView: UIView, MGLCalloutView {
+ var representedObject: MGLAnnotation
+
+ // Lazy initialization of optional vars for protocols causes segmentation fault: 11s in Swift 3.0. https://bugs.swift.org/browse/SR-1825
+
+ var leftAccessoryView = UIView() /* unused */
+ var rightAccessoryView = UIView() /* unused */
+
+ weak var delegate: MGLCalloutViewDelegate?
+
+ let tipHeight: CGFloat = 10.0
+ let tipWidth: CGFloat = 20.0
+
+ let mainBody: UIButton
+
+ required init(representedObject: MGLAnnotation) {
+ self.representedObject = representedObject
+ self.mainBody = UIButton(type: .system)
+
+ super.init(frame: .zero)
+
+ backgroundColor = .clear
+
+ mainBody.backgroundColor = .darkGray
+ mainBody.tintColor = .white
+ mainBody.contentEdgeInsets = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0)
+ mainBody.layer.cornerRadius = 4.0
+
+ addSubview(mainBody)
+ }
+
+ required init?(coder decoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ // MARK: - MGLCalloutView API
+ func presentCallout(from rect: CGRect, in view: UIView, constrainedTo constrainedView: UIView, animated: Bool) {
+ if !representedObject.responds(to: #selector(getter: MGLAnnotation.title)) {
+ return
+ }
+
+ view.addSubview(self)
+
+ // Prepare title label
+ mainBody.setTitle(representedObject.title!, for: .normal)
+ mainBody.sizeToFit()
+
+ if isCalloutTappable() {
+ // Handle taps and eventually try to send them to the delegate (usually the map view)
+ mainBody.addTarget(self, action: #selector(CustomCalloutView.calloutTapped), for: .touchUpInside)
+ } else {
+ // Disable tapping and highlighting
+ mainBody.isUserInteractionEnabled = false
+ }
+
+ // Prepare our frame, adding extra space at the bottom for the tip
+ let frameWidth = mainBody.bounds.size.width
+ let frameHeight = mainBody.bounds.size.height + tipHeight
+ let frameOriginX = rect.origin.x + (rect.size.width/2.0) - (frameWidth/2.0)
+ let frameOriginY = rect.origin.y - frameHeight
+ frame = CGRect(x: frameOriginX, y: frameOriginY, width: frameWidth, height: frameHeight)
+
+ if animated {
+ alpha = 0
+
+ UIView.animate(withDuration: 0.2) { [weak self] in
+ self?.alpha = 1
+ }
+ }
+ }
+
+ func dismissCallout(animated: Bool) {
+ if (superview != nil) {
+ if animated {
+ UIView.animate(withDuration: 0.2, animations: { [weak self] in
+ self?.alpha = 0
+ }, completion: { [weak self] _ in
+ self?.removeFromSuperview()
+ })
+ } else {
+ removeFromSuperview()
+ }
+ }
+ }
+
+ // MARK: - Callout interaction handlers
+
+ func isCalloutTappable() -> Bool {
+ if let delegate = delegate {
+ if delegate.responds(to: #selector(MGLCalloutViewDelegate.calloutViewShouldHighlight)) {
+ return delegate.calloutViewShouldHighlight!(self)
+ }
+ }
+ return false
+ }
+
+ func calloutTapped() {
+ if isCalloutTappable() && delegate!.responds(to: #selector(MGLCalloutViewDelegate.calloutViewTapped)) {
+ delegate!.calloutViewTapped!(self)
+ }
+ }
+
+ // MARK: - Custom view styling
+
+ override func draw(_ rect: CGRect) {
+ // Draw the pointed tip at the bottom
+ let fillColor : UIColor = .darkGray
+
+ let tipLeft = rect.origin.x + (rect.size.width / 2.0) - (tipWidth / 2.0)
+ let tipBottom = CGPoint(x: rect.origin.x + (rect.size.width / 2.0), y: rect.origin.y + rect.size.height)
+ let heightWithoutTip = rect.size.height - tipHeight
+
+ let currentContext = UIGraphicsGetCurrentContext()!
+
+ let tipPath = CGMutablePath()
+ tipPath.move(to: CGPoint(x: tipLeft, y: heightWithoutTip))
+ tipPath.addLine(to: CGPoint(x: tipBottom.x, y: tipBottom.y))
+ tipPath.addLine(to: CGPoint(x: tipLeft + tipWidth, y: heightWithoutTip))
+ tipPath.closeSubpath()
+
+ fillColor.setFill()
+ currentContext.addPath(tipPath)
+ currentContext.fillPath()
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/CustomCalloutViewExample.swift b/platform/ios/demo/Examples/Swift/CustomCalloutViewExample.swift
new file mode 100644
index 0000000000..e74fb9702b
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CustomCalloutViewExample.swift
@@ -0,0 +1,51 @@
+import Mapbox
+
+@objc(CustomCalloutViewExample_Swift)
+
+class CustomCalloutViewExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.lightStyleURL(withVersion: 9))
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .darkGray
+ view.addSubview(mapView)
+
+ // Set the map view‘s delegate property.
+ mapView.delegate = self
+
+ // Initialize and add the marker annotation.
+ let marker = MGLPointAnnotation()
+ marker.coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0)
+ marker.title = "Hello world!"
+
+ // This custom callout example does not implement subtitles.
+ //marker.subtitle = "Welcome to my marker"
+
+ // Add marker to the map.
+ mapView.addAnnotation(marker)
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ // Always allow callouts to popup when annotations are tapped.
+ return true
+ }
+
+ func mapView(_ mapView: MGLMapView, calloutViewFor annotation: MGLAnnotation) -> MGLCalloutView? {
+ // Only show callouts for `Hello world!` annotation.
+ if annotation.responds(to: #selector(getter: MGLAnnotation.title)) && annotation.title! == "Hello world!" {
+ // Instantiate and return our custom callout view.
+ return CustomCalloutView(representedObject: annotation)
+ }
+
+ return nil
+ }
+
+ func mapView(_ mapView: MGLMapView, tapOnCalloutFor annotation: MGLAnnotation) {
+ // Optionally handle taps on the callout.
+ print("Tapped the callout for: \(annotation)")
+
+ // Hide the callout.
+ mapView.deselectAnnotation(annotation, animated: true)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/CustomRasterStyleExample.swift b/platform/ios/demo/Examples/Swift/CustomRasterStyleExample.swift
new file mode 100644
index 0000000000..2940f6fd0d
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CustomRasterStyleExample.swift
@@ -0,0 +1,17 @@
+import Mapbox
+
+@objc(CustomRasterStyleExample_Swift)
+
+class CustomRasterStyleExample_Swift: UIViewController {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let styleURL = URL(string: "https://www.mapbox.com/ios-sdk/files/mapbox-raster-v8.json")
+ // Local paths are also acceptable.
+
+ let mapView = MGLMapView(frame: view.bounds, styleURL: styleURL)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ view.addSubview(mapView)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/CustomStyleExample.swift b/platform/ios/demo/Examples/Swift/CustomStyleExample.swift
new file mode 100644
index 0000000000..ff48344eb7
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/CustomStyleExample.swift
@@ -0,0 +1,22 @@
+import Mapbox
+
+@objc(CustomStyleExample_Swift)
+
+class CustomStyleExample_Swift: UIViewController {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Fill in the next line with your style URL from Mapbox Studio.
+ // <#mapbox://styles/userName/styleHash#>
+ let styleURL = URL(string: "mapbox://styles/mapbox/outdoors-v9")
+ let mapView = MGLMapView(frame: view.bounds,
+ styleURL: styleURL)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ // Set the map’s center coordinate and zoom level.
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 45.52954,
+ longitude: -122.72317),
+ zoomLevel: 14, animated: false)
+ view.addSubview(mapView)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DDSCircleLayerExample.swift b/platform/ios/demo/Examples/Swift/DDSCircleLayerExample.swift
new file mode 100644
index 0000000000..dc8a7066d9
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DDSCircleLayerExample.swift
@@ -0,0 +1,59 @@
+import Mapbox
+
+@objc(DDSCircleLayerExample_Swift)
+
+class DDSCircleLayerExample_Swift: UIViewController, MGLMapViewDelegate {
+
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Create a new map view using the Mapbox Light style.
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.styleURL = MGLStyle.lightStyleURL(withVersion: 9)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .darkGray
+
+ // Set the map’s center coordinate and zoom level.
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 38.897, longitude: -77.039), animated: false)
+ mapView.zoomLevel = 10.5
+
+ mapView.delegate = self
+ view.addSubview(mapView)
+ }
+
+ // Wait until the style is loaded before modifying the map style.
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+
+ // "mapbox://examples.2uf7qges" is a map ID referencing a tileset. For more
+ // more information, see mapbox.com/help/define-map-id/
+ let source = MGLVectorSource(identifier: "trees", configurationURL: URL(string: "mapbox://examples.2uf7qges")!)
+
+ style.addSource(source)
+
+ let layer = MGLCircleStyleLayer(identifier: "tree-style", source: source)
+
+ // The source name from the source's TileJSON metadata: mapbox.com/api-documentation/#retrieve-tilejson-metadata
+ layer.sourceLayerIdentifier = "yoshino-trees-a0puw5"
+
+ // Stops based on age of tree in years.
+ let stops = [
+ 0: MGLStyleValue(rawValue: UIColor(red:1.00, green:0.72, blue:0.85, alpha:1.0)),
+ 2: MGLStyleValue(rawValue: UIColor(red:0.69, green:0.48, blue:0.73, alpha:1.0)),
+ 4: MGLStyleValue(rawValue: UIColor(red:0.61, green:0.31, blue:0.47, alpha:1.0)),
+ 7: MGLStyleValue(rawValue: UIColor(red:0.43, green:0.20, blue:0.38, alpha:1.0)),
+ 16: MGLStyleValue(rawValue: UIColor(red:0.33, green:0.17, blue:0.25, alpha:1.0))
+ ]
+
+ // Style the circle layer color based on the above categorical stops
+ layer.circleColor = MGLStyleValue<UIColor>(interpolationMode: .interval,
+ sourceStops: stops,
+ attributeName: "AGE",
+ options: nil)
+
+ layer.circleRadius = MGLStyleValue(rawValue: 3)
+
+ style.addLayer(layer)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DDSLayerSelectionExample.swift b/platform/ios/demo/Examples/Swift/DDSLayerSelectionExample.swift
new file mode 100644
index 0000000000..4b67300c7f
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DDSLayerSelectionExample.swift
@@ -0,0 +1,77 @@
+
+import Mapbox
+
+@objc(DDSLayerSelectionExample_Swift)
+
+class DDSLayerSelectionExample_Swift: UIViewController, MGLMapViewDelegate, UIGestureRecognizerDelegate {
+
+ var mapView : MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.delegate = self
+ mapView.setCenter(CLLocationCoordinate2D(latitude:39.23225, longitude:-97.91015), animated: false)
+ mapView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+ view.addSubview(mapView)
+
+ // Add a tap gesture recognizer to the map view.
+ let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
+ gesture.delegate = self
+ mapView.addGestureRecognizer(gesture)
+ }
+
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+
+ // Load a tileset containing U.S. states and their population density. For more information about working with tilesets, see: https://www.mapbox.com/help/studio-manual-tilesets/
+ let url = URL(string: "mapbox://examples.69ytlgls")!
+ let source = MGLVectorSource(identifier: "state-source", configurationURL: url)
+ style.addSource(source)
+
+ let layer = MGLFillStyleLayer(identifier: "state-layer", source: source)
+
+ // Access the tileset layer.
+ layer.sourceLayerIdentifier = "stateData_2-dx853g"
+
+ // Create a stops dictionary. This defines the relationship between population density and a UIColor.
+ let stops = [0: MGLStyleValue(rawValue: UIColor.yellow),
+ 600: MGLStyleValue(rawValue: UIColor.red),
+ 1200: MGLStyleValue(rawValue: UIColor.blue)]
+
+ // Style the fill color using the stops dictionary, exponential interpolation mode, and the feature attribute name.
+ layer.fillColor = MGLStyleValue(interpolationMode: .exponential, sourceStops: stops, attributeName: "density", options: [.defaultValue: MGLStyleValue(rawValue: UIColor.white)])
+
+ // Insert the new layer below the Mapbox Streets layer that contains state border lines. See the layer reference for more information about layer names: https://www.mapbox.com/vector-tiles/mapbox-streets-v7/
+ let symbolLayer = style.layer(withIdentifier: "admin-3-4-boundaries")
+ style.insertLayer(layer, below: symbolLayer!)
+ }
+
+ func handleTap(_ gesture: UITapGestureRecognizer) {
+
+ // Get the CGPoint where the user tapped.
+ let spot = gesture.location(in: mapView)
+
+ // Access the features at that point within the state layer.
+ let features = mapView.visibleFeatures(at: spot, styleLayerIdentifiers: Set(["state-layer"]))
+
+ // Get the name of the selected state.
+ if let feature = features.first, let state = feature.attribute(forKey: "name") as? String{
+ changeOpacity(name: state)
+ } else {
+ changeOpacity(name: "")
+ }
+ }
+
+ func changeOpacity(name: String) {
+ let layer = mapView.style?.layer(withIdentifier: "state-layer") as! MGLFillStyleLayer
+
+ // Check if a state was selected, then change the opacity of the states that were not selected.
+ if name.characters.count > 0 {
+ layer.fillOpacity = MGLStyleValue(interpolationMode: .categorical, sourceStops: [name: MGLStyleValue<NSNumber>(rawValue: 1)], attributeName: "name", options: [.defaultValue: MGLStyleValue<NSNumber>(rawValue: 0)])
+ } else {
+ // Reset the opacity for all states if the user did not tap on a state.
+ layer.fillOpacity = MGLStyleValue(rawValue: 1)
+ }
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DefaultStylesExample.swift b/platform/ios/demo/Examples/Swift/DefaultStylesExample.swift
new file mode 100644
index 0000000000..2c1eb6e390
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DefaultStylesExample.swift
@@ -0,0 +1,23 @@
+import Mapbox
+
+@objc(DefaultStylesExample_Swift)
+
+class DefaultStylesExample_Swift: UIViewController {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds,
+ styleURL: MGLStyle.outdoorsStyleURL(withVersion: 9))
+
+ // Tint the ℹ️ button and the user location annotation.
+ mapView.tintColor = .darkGray
+
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ // Set the map’s center coordinate and zoom level.
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 51.50713,
+ longitude: -0.10957),
+ zoomLevel: 13, animated: false)
+ view.addSubview(mapView)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift b/platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift
new file mode 100644
index 0000000000..54d4fa6a06
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift
@@ -0,0 +1,127 @@
+import Mapbox
+
+@objc(DraggableAnnotationViewExample_Swift)
+
+// Example view controller
+class DraggableAnnotationViewExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.styleURL = MGLStyle.lightStyleURL(withVersion: 9)
+ mapView.tintColor = .darkGray
+ mapView.zoomLevel = 1
+ mapView.delegate = self
+ view.addSubview(mapView)
+
+ // Specify coordinates for our annotations.
+ let coordinates = [
+ CLLocationCoordinate2D(latitude: 0, longitude: -70),
+ CLLocationCoordinate2D(latitude: 0, longitude: -35),
+ CLLocationCoordinate2D(latitude: 0, longitude: 0),
+ CLLocationCoordinate2D(latitude: 0, longitude: 35),
+ CLLocationCoordinate2D(latitude: 0, longitude: 70)
+ ]
+
+ // Fill an array with point annotations and add it to the map.
+ var pointAnnotations = [MGLPointAnnotation]()
+ for coordinate in coordinates {
+ let point = MGLPointAnnotation()
+ point.coordinate = coordinate
+ point.title = "To drag this annotation, first tap and hold."
+ pointAnnotations.append(point)
+ }
+
+ mapView.addAnnotations(pointAnnotations)
+ }
+
+ // MARK: - MGLMapViewDelegate methods
+
+ // This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
+ func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
+ // This example is only concerned with point annotations.
+ guard annotation is MGLPointAnnotation else {
+ return nil
+ }
+
+ // For better performance, always try to reuse existing annotations. To use multiple different annotation views, change the reuse identifier for each.
+ if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "draggablePoint") {
+ return annotationView
+ } else {
+ return DraggableAnnotationView(reuseIdentifier: "draggablePoint", size: 50)
+ }
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ return true
+ }
+}
+
+// MGLAnnotationView subclass
+class DraggableAnnotationView: MGLAnnotationView {
+ init(reuseIdentifier: String, size: CGFloat) {
+ super.init(reuseIdentifier: reuseIdentifier)
+
+ // `isDraggable` is a property of MGLAnnotationView, disabled by default.
+ isDraggable = true
+
+ // This property prevents the annotation from changing size when the map is tilted.
+ scalesWithViewingDistance = false
+
+ // Begin setting up the view.
+ frame = CGRect(x: 0, y: 0, width: size, height: size)
+
+ backgroundColor = .darkGray
+
+ // Use CALayer’s corner radius to turn this view into a circle.
+ layer.cornerRadius = size / 2
+ layer.borderWidth = 1
+ layer.borderColor = UIColor.white.cgColor
+ layer.shadowColor = UIColor.black.cgColor
+ layer.shadowOpacity = 0.1
+ }
+
+ // These two initializers are forced upon us by Swift.
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ // Custom handler for changes in the annotation’s drag state.
+ override func setDragState(_ dragState: MGLAnnotationViewDragState, animated: Bool) {
+ super.setDragState(dragState, animated: animated)
+
+ switch dragState {
+ case .starting:
+ print("Starting", terminator: "")
+ startDragging()
+ case .dragging:
+ print(".", terminator: "")
+ case .ending, .canceling:
+ print("Ending")
+ endDragging()
+ case .none:
+ return
+ }
+ }
+
+ // When the user interacts with an annotation, animate opacity and scale changes.
+ func startDragging() {
+ UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
+ self.layer.opacity = 0.8
+ self.transform = CGAffineTransform.identity.scaledBy(x: 1.5, y: 1.5)
+ }, completion: nil)
+ }
+
+ func endDragging() {
+ transform = CGAffineTransform.identity.scaledBy(x: 1.5, y: 1.5)
+ UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
+ self.layer.opacity = 1
+ self.transform = CGAffineTransform.identity.scaledBy(x: 1, y: 1)
+ }, completion: nil)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DrawingACustomMarkerExample.swift b/platform/ios/demo/Examples/Swift/DrawingACustomMarkerExample.swift
new file mode 100644
index 0000000000..85be0436f4
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DrawingACustomMarkerExample.swift
@@ -0,0 +1,59 @@
+import Mapbox
+
+@objc(DrawingACustomMarkerExample_Swift)
+
+class DrawingACustomMarkerExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.lightStyleURL(withVersion: 9))
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .darkGray
+
+ // Set the map's bounds to Pisa, Italy.
+ let bounds = MGLCoordinateBounds(
+ sw: CLLocationCoordinate2D(latitude: 43.7115, longitude: 10.3725),
+ ne: CLLocationCoordinate2D(latitude: 43.7318, longitude: 10.4222))
+ mapView.setVisibleCoordinateBounds(bounds, animated: false)
+
+ view.addSubview(mapView)
+
+ // Set the map view‘s delegate property.
+ mapView.delegate = self
+
+ // Initialize and add the point annotation.
+ let pisa = MGLPointAnnotation()
+ pisa.coordinate = CLLocationCoordinate2D(latitude: 43.72305, longitude: 10.396633)
+ pisa.title = "Leaning Tower of Pisa"
+ mapView.addAnnotation(pisa)
+ }
+
+ func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
+ // Try to reuse the existing ‘pisa’ annotation image, if it exists.
+ var annotationImage = mapView.dequeueReusableAnnotationImage(withIdentifier: "pisa")
+
+ if annotationImage == nil {
+ // Leaning Tower of Pisa by Stefan Spieler from the Noun Project.
+ var image = UIImage(named: "pisavector")!
+
+ // The anchor point of an annotation is currently always the center. To
+ // shift the anchor point to the bottom of the annotation, the image
+ // asset includes transparent bottom padding equal to the original image
+ // height.
+ //
+ // To make this padding non-interactive, we create another image object
+ // with a custom alignment rect that excludes the padding.
+ image = image.withAlignmentRectInsets(UIEdgeInsets(top: 0, left: 0, bottom: image.size.height/2, right: 0))
+
+ // Initialize the ‘pisa’ annotation image with the UIImage we just loaded.
+ annotationImage = MGLAnnotationImage(image: image, reuseIdentifier: "pisa")
+ }
+
+ return annotationImage
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ // Always allow callouts to popup when annotations are tapped.
+ return true
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DrawingAGeoJSONLineExample.swift b/platform/ios/demo/Examples/Swift/DrawingAGeoJSONLineExample.swift
new file mode 100644
index 0000000000..3b132186f5
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DrawingAGeoJSONLineExample.swift
@@ -0,0 +1,79 @@
+import Mapbox
+
+@objc(DrawingAGeoJSONLineExample_Swift)
+
+class DrawingAGeoJSONLineExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 45.5076, longitude: -122.6736),
+ zoomLevel: 11, animated: false)
+ view.addSubview(self.mapView)
+
+ mapView.delegate = self
+
+ drawPolyline()
+ }
+
+ func drawPolyline() {
+ // Parsing GeoJSON can be CPU intensive, do it on a background thread
+
+ DispatchQueue.global(qos: .background).async(execute: {
+ // Get the path for example.geojson in the app's bundle
+ let jsonPath = Bundle.main.path(forResource: "example", ofType: "geojson")
+ let url = URL(fileURLWithPath: jsonPath!)
+
+ do {
+ // Convert the file contents to a shape collection feature object
+ let data = try Data(contentsOf: url)
+ let shapeCollectionFeature = try MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as! MGLShapeCollectionFeature
+
+ if let polyline = shapeCollectionFeature.shapes.first as? MGLPolylineFeature {
+ // Optionally set the title of the polyline, which can be used for:
+ // - Callout view
+ // - Object identification
+ polyline.title = polyline.attributes["name"] as? String
+
+ // Add the annotation on the main thread
+ DispatchQueue.main.async(execute: {
+ // Unowned reference to self to prevent retain cycle
+ [unowned self] in
+ self.mapView.addAnnotation(polyline)
+ })
+ }
+ }
+ catch {
+ print("GeoJSON parsing failed")
+ }
+
+ })
+
+ }
+
+ func mapView(_ mapView: MGLMapView, alphaForShapeAnnotation annotation: MGLShape) -> CGFloat {
+ // Set the alpha for all shape annotations to 1 (full opacity)
+ return 1
+ }
+
+ func mapView(_ mapView: MGLMapView, lineWidthForPolylineAnnotation annotation: MGLPolyline) -> CGFloat {
+ // Set the line width for polyline annotations
+ return 2.0
+ }
+
+ func mapView(_ mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor {
+ // Give our polyline a unique color by checking for its `title` property
+ if (annotation.title == "Crema to Council Crest" && annotation is MGLPolyline) {
+ // Mapbox cyan
+ return UIColor(red: 59/255, green:178/255, blue:208/255, alpha:1)
+ }
+ else
+ {
+ return .red
+ }
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DrawingAMarkerExample.swift b/platform/ios/demo/Examples/Swift/DrawingAMarkerExample.swift
new file mode 100644
index 0000000000..5868460061
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DrawingAMarkerExample.swift
@@ -0,0 +1,38 @@
+import Mapbox
+
+@objc(DrawingAMarkerExample_Swift)
+
+class DrawingAMarkerExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ // Set the map’s center coordinate and zoom level.
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407), zoomLevel: 12, animated: false)
+ view.addSubview(mapView)
+
+ // Set the delegate property of our map view to `self` after instantiating it.
+ mapView.delegate = self
+
+ // Declare the marker `hello` and set its coordinates, title, and subtitle.
+ let hello = MGLPointAnnotation()
+ hello.coordinate = CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407)
+ hello.title = "Hello world!"
+ hello.subtitle = "Welcome to my marker"
+
+ // Add marker `hello` to the map.
+ mapView.addAnnotation(hello)
+ }
+
+ // Use the default marker. See also: our view annotation or custom marker examples.
+ func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
+ return nil
+ }
+
+ // Allow callout view to appear when an annotation is tapped.
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ return true
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/DrawingAPolygonExample.swift b/platform/ios/demo/Examples/Swift/DrawingAPolygonExample.swift
new file mode 100644
index 0000000000..e25678f8c6
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DrawingAPolygonExample.swift
@@ -0,0 +1,59 @@
+import Mapbox
+
+@objc(DrawingAPolygonExample_Swift)
+
+class DrawingAPolygonExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 45.520486, longitude: -122.673541), zoomLevel: 11, animated: false)
+ view.addSubview(mapView)
+
+ mapView.delegate = self
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ // Draw the polygon after the map has initialized
+ drawShape()
+ }
+
+ func drawShape() {
+ // Create a coordinates array to hold all of the coordinates for our shape.
+ var coordinates = [
+ CLLocationCoordinate2D(latitude: 45.522585, longitude: -122.685699),
+ CLLocationCoordinate2D(latitude: 45.534611, longitude: -122.708873),
+ CLLocationCoordinate2D(latitude: 45.530883, longitude: -122.678833),
+ CLLocationCoordinate2D(latitude: 45.547115, longitude: -122.667503),
+ CLLocationCoordinate2D(latitude: 45.530643, longitude: -122.660121),
+ CLLocationCoordinate2D(latitude: 45.533529, longitude: -122.636260),
+ CLLocationCoordinate2D(latitude: 45.521743, longitude: -122.659091),
+ CLLocationCoordinate2D(latitude: 45.510677, longitude: -122.648792),
+ CLLocationCoordinate2D(latitude: 45.515008, longitude: -122.664070),
+ CLLocationCoordinate2D(latitude: 45.502496, longitude: -122.669048),
+ CLLocationCoordinate2D(latitude: 45.515369, longitude: -122.678489),
+ CLLocationCoordinate2D(latitude: 45.506346, longitude: -122.702007),
+ CLLocationCoordinate2D(latitude: 45.522585, longitude: -122.685699)
+ ]
+
+ let shape = MGLPolygon(coordinates: &coordinates, count: UInt(coordinates.count))
+
+ mapView.addAnnotation(shape)
+ }
+
+ func mapView(_ mapView: MGLMapView, alphaForShapeAnnotation annotation: MGLShape) -> CGFloat {
+ return 0.5
+ }
+ func mapView(_ mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor {
+ return .white
+ }
+
+ func mapView(_ mapView: MGLMapView, fillColorForPolygonAnnotation annotation: MGLPolygon) -> UIColor {
+ return UIColor(red: 59/255, green: 178/255, blue: 208/255, alpha: 1)
+ }
+
+}
diff --git a/platform/ios/demo/Examples/Swift/ExtrusionsExample.swift b/platform/ios/demo/Examples/Swift/ExtrusionsExample.swift
new file mode 100644
index 0000000000..596fcbbd0e
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/ExtrusionsExample.swift
@@ -0,0 +1,53 @@
+//
+// ExtrusionsExample.swift
+// Examples
+//
+// Created by Jordan Kiley on 5/10/17.
+// Copyright © 2017 Mapbox. All rights reserved.
+//
+
+import Mapbox
+
+@objc(ExtrusionsExample_Swift)
+
+class ExtrusionsExample: UIViewController, MGLMapViewDelegate {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.lightStyleURL(withVersion: 9))
+
+ // Center the map view on the Colosseum in Rome, Italy and set the camera's pitch and distance.
+ mapView.camera = MGLMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 41.8902, longitude: 12.4922), fromDistance: 600, pitch: 60, heading: 0)
+ mapView.delegate = self
+ self.navigationController?.isNavigationBarHidden = true
+
+ view.addSubview(mapView)
+ }
+
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+
+ let array = [1, 2, 4, 6]
+ // Access the Mapbox Streets source and use it to create a `MGLFillExtrusionStyleLayer`. The source identifier is `composite`. Use the `sources` property on a style to verify source identifiers.
+ if let source = style.source(withIdentifier: "composite") {
+ let layer = MGLFillExtrusionStyleLayer(identifier: "buildings", source: source)
+ layer.sourceLayerIdentifier = "building"
+
+ // Filter out buildings that should not extrude.
+ layer.predicate = NSPredicate(format: "extrude == 'true' AND height >= 0")
+
+ // Set the fill extrusion height to the value for the building height attribute.
+ layer.fillExtrusionHeight = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "height", options: nil)
+ layer.fillExtrusionBase = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "min_height", options: nil)
+ layer.fillExtrusionOpacity = MGLStyleValue(rawValue: 0.75)
+ layer.fillExtrusionColor = MGLStyleValue(rawValue: .white)
+
+ // Insert the fill extrusion layer below a POI label layer. If you aren’t sure what the layer is called, you can view the style in Mapbox Studio or iterate over the style’s layers property, printing out each layer’s identifier.
+ if let symbolLayer = style.layer(withIdentifier: "poi-scalerank3") {
+ style.insertLayer(layer, below: symbolLayer)
+ } else {
+ style.addLayer(layer)
+ }
+ }
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/OfflinePackExample.swift b/platform/ios/demo/Examples/Swift/OfflinePackExample.swift
new file mode 100644
index 0000000000..a1229aa366
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/OfflinePackExample.swift
@@ -0,0 +1,113 @@
+import Mapbox
+
+@objc(OfflinePackExample_Swift)
+
+class OfflinePackExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+ var progressView: UIProgressView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.darkStyleURL(withVersion: 9))
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .gray
+ mapView.delegate = self
+ view.addSubview(mapView)
+
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 22.27933, longitude: 114.16281),
+ zoomLevel: 13, animated: false)
+
+ // Setup offline pack notification handlers.
+ NotificationCenter.default.addObserver(self, selector: #selector(offlinePackProgressDidChange), name: NSNotification.Name.MGLOfflinePackProgressChanged, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(offlinePackDidReceiveError), name: NSNotification.Name.MGLOfflinePackError, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(offlinePackDidReceiveMaximumAllowedMapboxTiles), name: NSNotification.Name.MGLOfflinePackMaximumMapboxTilesReached, object: nil)
+ }
+
+ func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
+ // Start downloading tiles and resources for z13-16.
+ startOfflinePackDownload()
+ }
+
+ deinit {
+ // Remove offline pack observers.
+ NotificationCenter.default.removeObserver(self)
+ }
+
+ func startOfflinePackDownload() {
+ // Create a region that includes the current viewport and any tiles needed to view it when zoomed further in.
+ // Because tile count grows exponentially with the maximum zoom level, you should be conservative with your `toZoomLevel` setting.
+ let region = MGLTilePyramidOfflineRegion(styleURL: mapView.styleURL, bounds: mapView.visibleCoordinateBounds, fromZoomLevel: mapView.zoomLevel, toZoomLevel: 16)
+
+ // Store some data for identification purposes alongside the downloaded resources.
+ let userInfo = ["name": "My Offline Pack"]
+ let context = NSKeyedArchiver.archivedData(withRootObject: userInfo)
+
+ // Create and register an offline pack with the shared offline storage object.
+
+ MGLOfflineStorage.shared().addPack(for: region, withContext: context) { (pack, error) in
+ guard error == nil else {
+ // The pack couldn’t be created for some reason.
+ print("Error: \(error?.localizedDescription ?? "unknown error")")
+ return
+ }
+
+ // Start downloading.
+ pack!.resume()
+ }
+
+ }
+
+ // MARK: - MGLOfflinePack notification handlers
+
+ func offlinePackProgressDidChange(notification: NSNotification) {
+ // Get the offline pack this notification is regarding,
+ // and the associated user info for the pack; in this case, `name = My Offline Pack`
+ if let pack = notification.object as? MGLOfflinePack,
+ let userInfo = NSKeyedUnarchiver.unarchiveObject(with: pack.context) as? [String: String] {
+ let progress = pack.progress
+ // or notification.userInfo![MGLOfflinePackProgressUserInfoKey]!.MGLOfflinePackProgressValue
+ let completedResources = progress.countOfResourcesCompleted
+ let expectedResources = progress.countOfResourcesExpected
+
+ // Calculate current progress percentage.
+ let progressPercentage = Float(completedResources) / Float(expectedResources)
+
+ // Setup the progress bar.
+ if progressView == nil {
+ progressView = UIProgressView(progressViewStyle: .default)
+ let frame = view.bounds.size
+ progressView.frame = CGRect(x: frame.width / 4, y: frame.height * 0.75, width: frame.width / 2, height: 10)
+ view.addSubview(progressView)
+ }
+
+ progressView.progress = progressPercentage
+
+ // If this pack has finished, print its size and resource count.
+ if completedResources == expectedResources {
+ let byteCount = ByteCountFormatter.string(fromByteCount: Int64(pack.progress.countOfBytesCompleted), countStyle: ByteCountFormatter.CountStyle.memory)
+ print("Offline pack “\(userInfo["name"] ?? "unknown")” completed: \(byteCount), \(completedResources) resources")
+ } else {
+ // Otherwise, print download/verification progress.
+ print("Offline pack “\(userInfo["name"] ?? "unknown")” has \(completedResources) of \(expectedResources) resources — \(progressPercentage * 100)%.")
+ }
+ }
+ }
+
+ func offlinePackDidReceiveError(notification: NSNotification) {
+ if let pack = notification.object as? MGLOfflinePack,
+ let userInfo = NSKeyedUnarchiver.unarchiveObject(with: pack.context) as? [String: String],
+ let error = notification.userInfo?[MGLOfflinePackUserInfoKey.error] as? NSError {
+ print("Offline pack “\(userInfo["name"] ?? "unknown")” received error: \(error.localizedFailureReason ?? "unknown error")")
+ }
+ }
+
+ func offlinePackDidReceiveMaximumAllowedMapboxTiles(notification: NSNotification) {
+ if let pack = notification.object as? MGLOfflinePack,
+ let userInfo = NSKeyedUnarchiver.unarchiveObject(with: pack.context) as? [String: String],
+ let maximumCount = (notification.userInfo?[MGLOfflinePackUserInfoKey.maximumCount] as AnyObject).uint64Value {
+ print("Offline pack “\(userInfo["name"] ?? "unknown")” reached limit of \(maximumCount) tiles.")
+ }
+ }
+
+}
diff --git a/platform/ios/demo/Examples/Swift/PointConversionExample.swift b/platform/ios/demo/Examples/Swift/PointConversionExample.swift
new file mode 100644
index 0000000000..79199aeeda
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/PointConversionExample.swift
@@ -0,0 +1,50 @@
+import Mapbox
+
+@objc(PointConversionExample_Swift)
+
+class PointConversionExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ view.addSubview(mapView)
+
+ // double tapping zooms the map, so ensure that can still happen
+ let doubleTap = UITapGestureRecognizer(target: self, action: nil)
+ doubleTap.numberOfTapsRequired = 2
+ mapView.addGestureRecognizer(doubleTap)
+
+ // delay single tap recognition until it is clearly not a double
+ let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
+ singleTap.require(toFail: doubleTap)
+ mapView.addGestureRecognizer(singleTap)
+
+ // convert `mapView.centerCoordinate` (CLLocationCoordinate2D)
+ // to screen location (CGPoint)
+ let centerScreenPoint: CGPoint = mapView.convert(mapView.centerCoordinate, toPointTo: mapView)
+ print("Screen center: \(centerScreenPoint) = \(mapView.center)")
+ }
+
+ func handleSingleTap(tap: UITapGestureRecognizer) {
+ // convert tap location (CGPoint)
+ // to geographic coordinates (CLLocationCoordinate2D)
+ let location: CLLocationCoordinate2D = mapView.convert(tap.location(in: mapView), toCoordinateFrom: mapView)
+ print("You tapped at: \(location.latitude), \(location.longitude)")
+
+ // create an array of coordinates for our polyline
+ var coordinates: [CLLocationCoordinate2D] = [mapView.centerCoordinate, location]
+
+ // remove existing polyline from the map, (re)add polyline with coordinates
+ if (mapView.annotations?.count != nil) {
+ mapView.removeAnnotations(mapView.annotations!)
+ }
+
+ let polyline = MGLPolyline(coordinates: &coordinates, count: UInt(coordinates.count))
+
+ mapView.addAnnotation(polyline)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/RuntimeAddLineExample.swift b/platform/ios/demo/Examples/Swift/RuntimeAddLineExample.swift
new file mode 100644
index 0000000000..62b3d869c1
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/RuntimeAddLineExample.swift
@@ -0,0 +1,90 @@
+import Mapbox
+
+@objc(RuntimeAddLineExample_Swift)
+
+class RuntimeAddLineExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(
+ CLLocationCoordinate2D(latitude: 45.5076, longitude: -122.6736),
+ zoomLevel: 11,
+ animated: false)
+ view.addSubview(mapView)
+
+ mapView.delegate = self
+ }
+
+ // Wait until the map is loaded before adding to the map.
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ loadGeoJson()
+ }
+
+ func loadGeoJson() {
+ DispatchQueue.global().async {
+ // Get the path for example.geojson in the app’s bundle.
+ guard let jsonUrl = Bundle.main.url(forResource: "example", withExtension: "geojson") else { return }
+ guard let jsonData = try? Data(contentsOf: jsonUrl) else { return }
+ DispatchQueue.main.async {
+ self.drawPolyline(geoJson: jsonData)
+ }
+ }
+ }
+
+ func drawPolyline(geoJson: Data) {
+ // Add our GeoJSON data to the map as an MGLGeoJSONSource.
+ // We can then reference this data from an MGLStyleLayer.
+
+ // MGLMapView.style is optional, so you must guard against it not being set.
+ guard let style = self.mapView.style else { return }
+
+ let shapeFromGeoJSON = try! MGLShape(data: geoJson, encoding: String.Encoding.utf8.rawValue)
+ let source = MGLShapeSource(identifier: "polyline", shape: shapeFromGeoJSON, options: nil)
+ style.addSource(source)
+
+ // Create new layer for the line
+ let layer = MGLLineStyleLayer(identifier: "polyline", source: source)
+ layer.lineJoin = MGLStyleValue(rawValue: NSValue(mglLineJoin: .round))
+ layer.lineCap = MGLStyleValue(rawValue: NSValue(mglLineCap: .round))
+ layer.lineColor = MGLStyleValue(rawValue: UIColor(red: 59/255, green:178/255, blue:208/255, alpha:1))
+ // Use a style function to smoothly adjust the line width from 2pt to 20pt between zoom levels 14 and 18. The `interpolationBase` parameter allows the values to interpolate along an exponential curve.
+ layer.lineWidth = MGLStyleValue(interpolationMode: .exponential,
+ cameraStops: [14: MGLStyleValue<NSNumber>(rawValue: 2),
+ 18: MGLStyleValue<NSNumber>(rawValue: 20)],
+ options: [.defaultValue : MGLConstantStyleValue<NSNumber>(rawValue: 1.5)])
+
+ // We can also add a second layer that will draw a stroke around the original line.
+ let casingLayer = MGLLineStyleLayer(identifier: "polyline-case", source: source)
+ // Copy these attributes from the main line layer.
+ casingLayer.lineJoin = layer.lineJoin
+ casingLayer.lineCap = layer.lineCap
+ // Line gap width represents the space before the outline begins, so should match the main line’s line width exactly.
+ casingLayer.lineGapWidth = layer.lineWidth
+ // Stroke color slightly darker than the line color.
+ casingLayer.lineColor = MGLStyleValue(rawValue: UIColor(red: 41/255, green:145/255, blue:171/255, alpha:1))
+ // Use a style function to gradually increase the stroke width between zoom levels 14 and 18.
+ casingLayer.lineWidth = MGLStyleValue(interpolationMode: .exponential,
+ cameraStops: [14: MGLStyleValue(rawValue: 1),
+ 18: MGLStyleValue(rawValue: 4)],
+ options: [.defaultValue : MGLConstantStyleValue<NSNumber>(rawValue: 1.5)])
+
+ // Just for fun, let’s add another copy of the line with a dash pattern.
+ let dashedLayer = MGLLineStyleLayer(identifier: "polyline-dash", source: source)
+ dashedLayer.lineJoin = layer.lineJoin
+ dashedLayer.lineCap = layer.lineCap
+ dashedLayer.lineColor = MGLStyleValue(rawValue: .white)
+ dashedLayer.lineOpacity = MGLStyleValue(rawValue: 0.5)
+ dashedLayer.lineWidth = layer.lineWidth
+ // Dash pattern in the format [dash, gap, dash, gap, ...]. You’ll want to adjust these values based on the line cap style.
+ dashedLayer.lineDashPattern = MGLStyleValue(rawValue: [0, 1.5])
+
+ style.addLayer(layer)
+ style.addLayer(dashedLayer)
+ style.insertLayer(casingLayer, below: layer)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/RuntimeAnimateLineExample.swift b/platform/ios/demo/Examples/Swift/RuntimeAnimateLineExample.swift
new file mode 100644
index 0000000000..46280bd891
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/RuntimeAnimateLineExample.swift
@@ -0,0 +1,162 @@
+import Mapbox
+
+@objc(RuntimeAnimateLineExample_Swift)
+
+class RuntimeAnimateLineExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+ var timer: Timer?
+ var polylineSource: MGLShapeSource?
+ var currentIndex = 1
+ var allCoordinates: [CLLocationCoordinate2D]!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(
+ CLLocationCoordinate2D(latitude: 45.5076, longitude: -122.6736),
+ zoomLevel: 11,
+ animated: false)
+ view.addSubview(mapView)
+
+ mapView.delegate = self
+
+ allCoordinates = coordinates()
+ }
+
+ // Wait until the map is loaded before adding to the map.
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ addLayer(to: style)
+ animatePolyline()
+ }
+
+ func addLayer(to style: MGLStyle) {
+ // Add an empty MGLShapeSource, we’ll keep a reference to this and add points to this later.
+ let source = MGLShapeSource(identifier: "polyline", shape: nil, options: nil)
+ style.addSource(source)
+ polylineSource = source
+
+ // Add a layer to style our polyline.
+ let layer = MGLLineStyleLayer(identifier: "polyline", source: source)
+ layer.lineJoin = MGLStyleValue(rawValue: NSValue(mglLineJoin: .round))
+ layer.lineCap = MGLStyleValue(rawValue: NSValue(mglLineCap: .round))
+ layer.lineColor = MGLStyleValue(rawValue: UIColor.red)
+ layer.lineWidth = MGLStyleFunction(interpolationMode: .exponential,
+ cameraStops: [14: MGLConstantStyleValue<NSNumber>(rawValue: 5),
+ 18: MGLConstantStyleValue<NSNumber>(rawValue: 20)],
+ options: [.defaultValue : MGLConstantStyleValue<NSNumber>(rawValue: 1.5)])
+ style.addLayer(layer)
+ }
+
+ func animatePolyline() {
+ currentIndex = 1
+
+ // Start a timer that will simulate adding points to our polyline. This could also represent coordinates being added to our polyline from another source, such as a CLLocationManagerDelegate.
+ timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(tick), userInfo: nil, repeats: true)
+ }
+
+ func tick() {
+ if currentIndex > allCoordinates.count {
+ timer?.invalidate()
+ timer = nil
+ return
+ }
+
+ // Create a subarray of locations up to the current index.
+ let coordinates = Array(allCoordinates[0..<currentIndex])
+
+ // Update our MGLShapeSource with the current locations.
+ updatePolylineWithCoordinates(coordinates: coordinates)
+
+ currentIndex += 1
+ }
+
+ func updatePolylineWithCoordinates(coordinates: [CLLocationCoordinate2D]) {
+ var mutableCoordinates = coordinates
+
+ let polyline = MGLPolylineFeature(coordinates: &mutableCoordinates, count: UInt(mutableCoordinates.count))
+
+ // Updating the MGLShapeSource’s shape will have the map redraw our polyline with the current coordinates.
+ polylineSource?.shape = polyline
+ }
+
+ func coordinates() -> [CLLocationCoordinate2D] {
+ return [
+ (-122.63748, 45.52214),
+ (-122.64855, 45.52218),
+ (-122.6545, 45.52219),
+ (-122.65497, 45.52196),
+ (-122.65631, 45.52104),
+ (-122.6578, 45.51935),
+ (-122.65867, 45.51848),
+ (-122.65872, 45.51293),
+ (-122.66576, 45.51295),
+ (-122.66745, 45.51252),
+ (-122.66813, 45.51244),
+ (-122.67359, 45.51385),
+ (-122.67415, 45.51406),
+ (-122.67481, 45.51484),
+ (-122.676, 45.51532),
+ (-122.68106, 45.51668),
+ (-122.68503, 45.50934),
+ (-122.68546, 45.50858),
+ (-122.6852, 45.50783),
+ (-122.68424, 45.50714),
+ (-122.68433, 45.50585),
+ (-122.68429, 45.50521),
+ (-122.68456, 45.50445),
+ (-122.68538, 45.50371),
+ (-122.68653, 45.50311),
+ (-122.68731, 45.50292),
+ (-122.68742, 45.50253),
+ (-122.6867, 45.50239),
+ (-122.68545, 45.5026),
+ (-122.68407, 45.50294),
+ (-122.68357, 45.50271),
+ (-122.68236, 45.50055),
+ (-122.68233, 45.49994),
+ (-122.68267, 45.49955),
+ (-122.68257, 45.49919),
+ (-122.68376, 45.49842),
+ (-122.68428, 45.49821),
+ (-122.68573, 45.49798),
+ (-122.68923, 45.49805),
+ (-122.68926, 45.49857),
+ (-122.68814, 45.49911),
+ (-122.68865, 45.49921),
+ (-122.6897, 45.49905),
+ (-122.69346, 45.49917),
+ (-122.69404, 45.49902),
+ (-122.69438, 45.49796),
+ (-122.69504, 45.49697),
+ (-122.69624, 45.49661),
+ (-122.69781, 45.4955),
+ (-122.69803, 45.49517),
+ (-122.69711, 45.49508),
+ (-122.69688, 45.4948),
+ (-122.69744, 45.49368),
+ (-122.69702, 45.49311),
+ (-122.69665, 45.49294),
+ (-122.69788, 45.49212),
+ (-122.69771, 45.49264),
+ (-122.69835, 45.49332),
+ (-122.7007, 45.49334),
+ (-122.70167, 45.49358),
+ (-122.70215, 45.49401),
+ (-122.70229, 45.49439),
+ (-122.70185, 45.49566),
+ (-122.70215, 45.49635),
+ (-122.70346, 45.49674),
+ (-122.70517, 45.49758),
+ (-122.70614, 45.49736),
+ (-122.70663, 45.49736),
+ (-122.70807, 45.49767),
+ (-122.70807, 45.49798),
+ (-122.70717, 45.49798),
+ (-122.70713, 45.4984),
+ (-122.70774, 45.49893)
+ ].map({CLLocationCoordinate2D(latitude: $0.1, longitude: $0.0)})
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/RuntimeCircleStylesExample.swift b/platform/ios/demo/Examples/Swift/RuntimeCircleStylesExample.swift
new file mode 100644
index 0000000000..14dc2a81f9
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/RuntimeCircleStylesExample.swift
@@ -0,0 +1,69 @@
+import Mapbox
+
+@objc(RuntimeCircleStylesExample_Swift)
+
+class RuntimeCircleStylesExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.styleURL = MGLStyle.lightStyleURL(withVersion: 9)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .darkGray
+
+ mapView.setCenter(
+ CLLocationCoordinate2D(latitude: 37.753574, longitude: -122.447303),
+ zoomLevel: 10,
+ animated: false)
+ view.addSubview(mapView)
+
+ mapView.delegate = self
+ }
+
+ // Wait until the style is loaded before modifying the map style.
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ addLayer(to: style)
+ }
+
+ func addLayer(to style: MGLStyle) {
+ let source = MGLVectorSource(identifier: "population", configurationURL: URL(string: "mapbox://examples.8fgz4egr")!)
+
+ let ethnicities = [
+ "White": UIColor(red: 251/255.0, green: 176/255.0, blue: 59/255.0, alpha: 1.0),
+ "Black": UIColor(red: 34/255.0, green: 59/255.0, blue: 83/255.0, alpha: 1.0),
+ "Hispanic": UIColor(red: 229/255.0, green: 94/255.0, blue: 94/255.0, alpha: 1.0),
+ "Asian": UIColor(red: 59/255.0, green: 178/255.0, blue: 208/255.0, alpha: 1.0),
+ "Other": UIColor(red: 204/255.0, green: 204/255.0, blue: 204/255.0, alpha: 1.0),
+ ]
+
+ style.addSource(source)
+
+ // Create a new layer for each ethnicity/circle color.
+ for (ethnicity, color) in ethnicities {
+ // Each layer should have a unique identifier.
+ let layer = MGLCircleStyleLayer(identifier: "population-\(ethnicity)", source: source)
+
+ // Specifying the `sourceLayerIdentifier` is required for a vector tile source. This is the json attribute that wraps the data in the source.
+ layer.sourceLayerIdentifier = "sf2010"
+
+ // Use a style function to smoothly adjust the circle radius from 2pt to 180pt between zoom levels 12 and 22. The `interpolationBase` parameter allows the values to interpolate along an exponential curve.
+ layer.circleRadius = MGLStyleValue(interpolationMode: .exponential,
+ cameraStops: [12: MGLStyleValue(rawValue: 2),
+ 22: MGLStyleValue(rawValue: 180)],
+ options: [.defaultValue : 1.75])
+
+// (interpolationBase: 1.75, stops: )
+ layer.circleOpacity = MGLStyleValue(rawValue: 0.7)
+
+ // Set the circle color to match the ethnicity.
+ layer.circleColor = MGLStyleValue(rawValue: color)
+
+ // Use an NSPredicate to filter to just one ethnicity for this layer.
+ layer.predicate = NSPredicate(format: "ethnicity == %@", ethnicity)
+
+ style.addLayer(layer)
+ }
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/RuntimeMultipleAnnotationsExample.swift b/platform/ios/demo/Examples/Swift/RuntimeMultipleAnnotationsExample.swift
new file mode 100644
index 0000000000..46a244b268
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/RuntimeMultipleAnnotationsExample.swift
@@ -0,0 +1,207 @@
+import Mapbox
+
+@objc(RuntimeMultipleAnnotationsExample_Swift)
+
+class RuntimeMultipleAnnotationsExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 37.090240, longitude: -95.712891), zoomLevel: 2, animated: false)
+
+ mapView.delegate = self
+
+ view.addSubview(mapView)
+
+ // Add our own gesture recognizer to handle taps on our custom map features.
+ mapView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleMapTap(sender:))))
+
+ self.mapView = mapView
+ }
+
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ fetchPoints() { [weak self] (features) in
+ self?.addItemsToMap(features: features)
+ }
+ }
+
+ func addItemsToMap(features: [MGLPointFeature]) {
+ // MGLMapView.style is optional, so you must guard against it not being set.
+ guard let style = mapView.style else { return }
+
+ // You can add custom UIImages to the map style.
+ // These can be referenced by an MGLSymbolStyleLayer’s iconImage property.
+ style.setImage(UIImage(named: "lighthouse")!, forName: "lighthouse")
+
+ // Add the features to the map as a shape source.
+ let source = MGLShapeSource(identifier: "lighthouses", features: features, options: nil)
+ style.addSource(source)
+
+ let lighthouseColor = UIColor(red: 0.08, green: 0.44, blue: 0.96, alpha: 1.0)
+
+ // Use MGLCircleStyleLayer to represent the points with simple circles.
+ // In this case, we can use style functions to gradually change properties between zoom level 2 and 7: the circle opacity from 50% to 100% and the circle radius from 2pt to 3pt.
+ let circles = MGLCircleStyleLayer(identifier: "lighthouse-circles", source: source)
+ circles.circleColor = MGLStyleValue(rawValue: lighthouseColor)
+ circles.circleOpacity = MGLStyleValue(interpolationMode: .exponential,
+ cameraStops: [2: MGLStyleValue(rawValue: 0.5),
+ 7: MGLStyleValue(rawValue: 1)],
+ options: nil)
+ circles.circleRadius = MGLStyleValue(interpolationMode: .exponential,
+ cameraStops: [2: MGLStyleValue(rawValue: 2),
+ 7: MGLStyleValue(rawValue: 3)],
+ options: nil)
+
+ // Use MGLSymbolStyleLayer for more complex styling of points including custom icons and text rendering.
+ let symbols = MGLSymbolStyleLayer(identifier: "lighthouse-symbols", source: source)
+ symbols.iconImageName = MGLStyleValue(rawValue: "lighthouse")
+ symbols.iconColor = MGLStyleValue(rawValue: lighthouseColor)
+ symbols.iconScale = MGLStyleValue(rawValue: 0.5)
+ symbols.iconOpacity = MGLStyleValue(interpolationMode: .exponential,
+ cameraStops: [5.9: MGLStyleValue(rawValue: 0),
+ 6: MGLStyleValue(rawValue: 1)],
+ options: nil)
+ symbols.iconHaloColor = MGLStyleValue(rawValue: UIColor.white.withAlphaComponent(0.5))
+ symbols.iconHaloWidth = MGLStyleValue(rawValue: 1)
+ // {name} references the "name" key in an MGLPointFeature’s attributes dictionary.
+ symbols.text = MGLStyleValue(rawValue: "{name}")
+ symbols.textColor = symbols.iconColor
+ symbols.textFontSize = MGLStyleValue(interpolationMode: .exponential,
+ cameraStops: [10: MGLStyleValue(rawValue: 10),
+ 16: MGLStyleValue(rawValue: 16)],
+ options: nil)
+ symbols.textTranslation = MGLStyleValue(rawValue: NSValue(cgVector: CGVector(dx: 10, dy: 0)))
+ symbols.textOpacity = symbols.iconOpacity
+ symbols.textHaloColor = symbols.iconHaloColor
+ symbols.textHaloWidth = symbols.iconHaloWidth
+ symbols.textJustification = MGLStyleValue(rawValue: NSValue(mglTextJustification: .left))
+ symbols.textAnchor = MGLStyleValue(rawValue: NSValue(mglTextAnchor: .left))
+
+ style.addLayer(circles)
+ style.addLayer(symbols)
+ }
+
+ // MARK: - Feature interaction
+ func handleMapTap(sender: UITapGestureRecognizer) {
+ if sender.state == .ended {
+ // Limit feature selection to just the following layer identifiers.
+ let layerIdentifiers: Set = ["lighthouse-symbols", "lighthouse-circles"]
+
+ // Try matching the exact point first.
+ let point = sender.location(in: sender.view!)
+ for f in mapView.visibleFeatures(at: point, styleLayerIdentifiers:layerIdentifiers)
+ where f is MGLPointFeature {
+ showCallout(feature: f as! MGLPointFeature)
+ return
+ }
+
+ let touchCoordinate = mapView.convert(point, toCoordinateFrom: sender.view!)
+ let touchLocation = CLLocation(latitude: touchCoordinate.latitude, longitude: touchCoordinate.longitude)
+
+ // Otherwise, get all features within a rect the size of a touch (44x44).
+ let touchRect = CGRect(origin: point, size: .zero).insetBy(dx: -22.0, dy: -22.0)
+ let possibleFeatures = mapView.visibleFeatures(in: touchRect, styleLayerIdentifiers: Set(layerIdentifiers)).filter { $0 is MGLPointFeature }
+
+ // Select the closest feature to the touch center.
+ let closestFeatures = possibleFeatures.sorted(by: {
+ return CLLocation(latitude: $0.coordinate.latitude, longitude: $0.coordinate.longitude).distance(from: touchLocation) < CLLocation(latitude: $1.coordinate.latitude, longitude: $1.coordinate.longitude).distance(from: touchLocation)
+ })
+ if let f = closestFeatures.first {
+ showCallout(feature: f as! MGLPointFeature)
+ return
+ }
+
+ // If no features were found, deselect the selected annotation, if any.
+ mapView.deselectAnnotation(mapView.selectedAnnotations.first, animated: true)
+ }
+ }
+
+ func showCallout(feature: MGLPointFeature) {
+ let point = MGLPointFeature()
+ point.title = feature.attributes["name"] as? String
+ point.coordinate = feature.coordinate
+
+ // Selecting an feature that doesn’t already exist on the map will add a new annotation view.
+ // We’ll need to use the map’s delegate methods to add an empty annotation view and remove it when we’re done selecting it.
+ mapView.selectAnnotation(point, animated: true)
+ }
+
+ // MARK: - MGLMapViewDelegate
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ return true
+ }
+
+ func mapView(_ mapView: MGLMapView, didDeselect annotation: MGLAnnotation) {
+ mapView.removeAnnotations([annotation])
+ }
+
+ func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
+ // Create an empty view annotation. Set a frame to offset the callout.
+ return MGLAnnotationView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
+ }
+
+ // MARK: - Data fetching and parsing
+
+ func fetchPoints(withCompletion completion: @escaping (([MGLPointFeature]) -> Void)) {
+ // Wikidata query for all lighthouses in the United States: http://tinyurl.com/zrl2jc4
+ let query = "SELECT DISTINCT ?item " +
+ "?itemLabel ?coor ?image " +
+ "WHERE " +
+ "{ " +
+ "?item wdt:P31 wd:Q39715 . " +
+ "?item wdt:P17 wd:Q30 . " +
+ "?item wdt:P625 ?coor . " +
+ "OPTIONAL { ?item wdt:P18 ?image } . " +
+ "SERVICE wikibase:label { bd:serviceParam wikibase:language \"en\" } " +
+ "} " +
+ "ORDER BY ?itemLabel"
+
+ let characterSet = NSMutableCharacterSet()
+ characterSet.formUnion(with: CharacterSet.urlQueryAllowed)
+ characterSet.removeCharacters(in: "?")
+ characterSet.removeCharacters(in: "&")
+ characterSet.removeCharacters(in: ":")
+
+ let encodedQuery = query.addingPercentEncoding(withAllowedCharacters: characterSet as CharacterSet)!
+
+ let request = URLRequest(url: URL(string: "https://query.wikidata.org/sparql?query=\(encodedQuery)&format=json")!)
+
+ URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
+ guard let data = data else { return }
+ guard let json = try? JSONSerialization.jsonObject(with: data, options:[]) as? [String: AnyObject] else { return }
+ guard let results = json?["results"] as? [String: AnyObject] else { return }
+ guard let items = results["bindings"] as? [[String: AnyObject]] else { return }
+ DispatchQueue.main.async {
+ completion(self.parseJSONItems(items: items))
+ }
+ }).resume()
+ }
+
+ func parseJSONItems(items: [[String: AnyObject]]) -> [MGLPointFeature] {
+ var features = [MGLPointFeature]()
+ for item in items {
+ guard let label = item["itemLabel"] as? [String: AnyObject],
+ let title = label["value"] as? String else { continue }
+ guard let coor = item["coor"] as? [String: AnyObject],
+ let point = coor["value"] as? String else { continue }
+
+ let parsedPoint = point.replacingOccurrences(of: "Point(", with: "").replacingOccurrences(of: ")", with: "")
+ let pointComponents = parsedPoint.components(separatedBy: " ")
+ let coordinate = CLLocationCoordinate2D(latitude: Double(pointComponents[1])!, longitude: Double(pointComponents[0])!)
+ let feature = MGLPointFeature()
+ feature.coordinate = coordinate
+ feature.title = title
+ // A feature’s attributes can used by runtime styling for things like text labels.
+ feature.attributes = [
+ "name": title
+ ]
+ features.append(feature)
+ }
+ return features
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/RuntimeToggleLayerExample.swift b/platform/ios/demo/Examples/Swift/RuntimeToggleLayerExample.swift
new file mode 100644
index 0000000000..d6b6776f2a
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/RuntimeToggleLayerExample.swift
@@ -0,0 +1,80 @@
+import Mapbox
+
+@objc(RuntimeToggleLayerExample_Swift)
+
+class RuntimeToggleLayerExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+ var contoursLayer: MGLStyleLayer?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 37.745395, longitude: -119.594421), zoomLevel: 11, animated: false)
+ view.addSubview(mapView)
+
+ addToggleButton()
+
+ mapView.delegate = self
+ }
+
+ // Wait until the style is loaded before modifying the map style
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ addLayer(to: style)
+ }
+
+ func addLayer(to style: MGLStyle) {
+ let source = MGLVectorSource(identifier: "contours", configurationURL: NSURL(string: "mapbox://mapbox.mapbox-terrain-v2")! as URL)
+
+ let layer = MGLLineStyleLayer(identifier: "contours", source: source)
+ layer.sourceLayerIdentifier = "contour"
+ layer.lineJoin = MGLStyleValue(rawValue: NSValue(mglLineJoin: .round))
+ layer.lineCap = MGLStyleValue(rawValue: NSValue(mglLineCap: .round))
+ layer.lineColor = MGLStyleValue(rawValue: UIColor.brown)
+ layer.lineWidth = MGLStyleValue(rawValue: 1.0)
+
+ style.addSource(source)
+ if let water = style.layer(withIdentifier: "water") {
+ // You can insert a layer below an existing style layer
+ style.insertLayer(layer, below: water)
+ } else {
+ // or you can simply add it above all layers
+ style.addLayer(layer)
+ }
+
+ self.contoursLayer = layer
+
+ showContours()
+ }
+
+ func toggleLayer(sender: UIButton) {
+ sender.isSelected = !sender.isSelected
+ if sender.isSelected {
+ showContours()
+ } else {
+ hideContours()
+ }
+ }
+
+ func showContours() {
+ self.contoursLayer?.isVisible = true
+ }
+
+ func hideContours() {
+ self.contoursLayer?.isVisible = false
+ }
+
+ func addToggleButton() {
+ let button = UIButton(type: .system)
+ button.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin]
+ button.setTitle("Toggle Contours", for: .normal)
+ button.isSelected = true
+ button.sizeToFit()
+ button.center.x = self.view.center.x
+ button.frame = CGRect(origin: CGPoint(x: button.frame.origin.x, y: self.view.frame.size.height - button.frame.size.height - 5), size: button.frame.size)
+ button.addTarget(self, action: #selector(RuntimeToggleLayerExample_Swift.toggleLayer(sender:)), for: .touchUpInside)
+ self.view.addSubview(button)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/SatelliteStyleExample.swift b/platform/ios/demo/Examples/Swift/SatelliteStyleExample.swift
new file mode 100644
index 0000000000..ddf04d5ce3
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/SatelliteStyleExample.swift
@@ -0,0 +1,25 @@
+import Mapbox
+
+@objc(SatelliteStyleExample_Swift)
+
+class SatelliteStyleExample_Swift: UIViewController {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // A hybrid style with unobtrusive labels is also available via satelliteStreetsStyleURL(withVersion:).
+ mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.satelliteStyleURL(withVersion: 9))
+
+ // Tint the ℹ️ button.
+ mapView.attributionButton.tintColor = .white
+
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ // Set the map’s center coordinate and zoom level.
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 45.5188, longitude: -122.6748), zoomLevel: 13, animated: false)
+
+ view.addSubview(mapView)
+ }
+
+}
diff --git a/platform/ios/demo/Examples/Swift/SelectFeatureExample.swift b/platform/ios/demo/Examples/Swift/SelectFeatureExample.swift
new file mode 100644
index 0000000000..b0e4f85674
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/SelectFeatureExample.swift
@@ -0,0 +1,64 @@
+import Mapbox
+
+@objc(SelectFeatureExample_Swift)
+
+class SelectFeatureExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+ var selectedFeaturesSource: MGLShapeSource?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(
+ CLLocationCoordinate2D(latitude: 45.5076, longitude: -122.6736),
+ zoomLevel: 11,
+ animated: false)
+ view.addSubview(mapView)
+
+ // Add our own gesture recognizer to handle taps on our custom map features.
+ mapView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapMap(tapGestureRecognizer:))))
+
+ mapView.delegate = self
+
+ self.mapView = mapView
+ }
+
+ func mapView(_ didFinishLoadingmapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ // Create a placeholder MGLShapeSource that will hold copies of any features we’ve selected.
+ let selectedFeaturesSource = MGLShapeSource(identifier: "selected-features", features: [], options: nil)
+ style.addSource(selectedFeaturesSource)
+
+ // Keep a reference to the source so we can update it when the map is tapped.
+ self.selectedFeaturesSource = selectedFeaturesSource
+
+ // Color any selected features red on the map.
+ let selectedFeaturesLayer = MGLFillStyleLayer(identifier: "selected-features", source: selectedFeaturesSource)
+ selectedFeaturesLayer.fillColor = MGLStyleValue(rawValue: UIColor.red)
+
+ style.addLayer(selectedFeaturesLayer)
+ }
+
+ func didTapMap(tapGestureRecognizer: UITapGestureRecognizer) {
+ if tapGestureRecognizer.state == .ended {
+ // A tap’s center coordinate may not intersect a feature exactly, so let’s make a 44x44 rect that represents a touch and select all features that intersect.
+ let point = tapGestureRecognizer.location(in: tapGestureRecognizer.view!)
+ let touchRect = CGRect(origin: point, size: .zero).insetBy(dx: -22.0, dy: -22.0)
+
+ // Let’s only select parks near the rect. There’s a layer within the Mapbox Streets style with "id" = "park". You can see all of the layers used within the default mapbox styles by creating a new style using Mapbox Studio.
+ let layerIdentifiers = Set(["park"])
+
+ // Query the map view for any visible features that intersect our rect.
+ let features = mapView.visibleFeatures(in: touchRect, styleLayerIdentifiers: layerIdentifiers).map { $0 as! MGLShape }
+
+ let shapes = MGLShapeCollectionFeature(shapes: features)
+
+ // Update our MGLShapeSource to match our selected features.
+ selectedFeaturesSource?.shape = shapes
+ }
+ }
+
+
+}
diff --git a/platform/ios/demo/Examples/Swift/ShapeCollectionFeatureExample.swift b/platform/ios/demo/Examples/Swift/ShapeCollectionFeatureExample.swift
new file mode 100644
index 0000000000..4ab5ff6ab6
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/ShapeCollectionFeatureExample.swift
@@ -0,0 +1,69 @@
+import Mapbox;
+
+@objc(ShapeCollectionFeatureExample_Swift)
+
+class ShapeCollectionFeatureExample_Swift: UIViewController, MGLMapViewDelegate {
+
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.styleURL = MGLStyle.lightStyleURL(withVersion: 9)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .darkGray
+
+ mapView.setCenter(CLLocationCoordinate2D(latitude:38.897435, longitude: -77.039679), zoomLevel: 12, animated: false)
+
+ mapView.delegate = self
+ view.addSubview(mapView)
+ }
+
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+
+ // Parse the GeoJSON data.
+ DispatchQueue.global().async {
+ guard let url = Bundle.main.url(forResource: "metro-line", withExtension: "geojson") else { return }
+
+ let data = try! Data(contentsOf: url)
+
+ DispatchQueue.main.async {
+ self.drawShapeCollection(data: data)
+ }
+ }
+ }
+
+ func drawShapeCollection(data: Data) {
+ guard let style = self.mapView.style else { return }
+
+ // Use [MGLShape shapeWithData:encoding:error:] to create a MGLShapeCollectionFeature from GeoJSON data.
+ let feature = try! MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as! MGLShapeCollectionFeature
+
+ // Create source and add it to the map style.
+ let source = MGLShapeSource(identifier: "transit", shape: feature, options: nil)
+ style.addSource(source)
+
+ // Create station style layer.
+ let circleLayer = MGLCircleStyleLayer(identifier: "stations", source: source)
+
+ // Use a predicate to filter out non-points.
+ circleLayer.predicate = NSPredicate(format: "TYPE = 'Station'")
+ circleLayer.circleColor = MGLStyleValue(rawValue: .red)
+ circleLayer.circleRadius = MGLStyleValue(rawValue: 6)
+ circleLayer.circleStrokeWidth = MGLStyleValue(rawValue: 2)
+ circleLayer.circleStrokeColor = MGLStyleValue(rawValue: .black)
+
+ // Create line style layer.
+ let lineLayer = MGLLineStyleLayer(identifier: "rail-line", source: source)
+
+ // Use a predicate to filter out the stations.
+ lineLayer.predicate = NSPredicate(format: "TYPE = 'Rail line'")
+ lineLayer.lineColor = MGLStyleValue(rawValue: .red)
+ lineLayer.lineWidth = MGLStyleValue(rawValue: 2)
+
+ // Add style layers to the map view's style.
+ style.addLayer(circleLayer)
+ style.insertLayer(lineLayer, below: circleLayer)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/SimpleMapViewExample.swift b/platform/ios/demo/Examples/Swift/SimpleMapViewExample.swift
new file mode 100644
index 0000000000..924474c7c2
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/SimpleMapViewExample.swift
@@ -0,0 +1,16 @@
+import Mapbox
+
+@objc(SimpleMapViewExample_Swift)
+
+class SimpleMapViewExample_Swift: UIViewController {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ // Set the map’s center coordinate and zoom level.
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 59.31, longitude: 18.06), zoomLevel: 9, animated: false)
+ view.addSubview(mapView)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/SourceCustomRasterExample.swift b/platform/ios/demo/Examples/Swift/SourceCustomRasterExample.swift
new file mode 100644
index 0000000000..fcac98c65e
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/SourceCustomRasterExample.swift
@@ -0,0 +1,50 @@
+import Mapbox
+
+@objc(SourceCustomRasterExample_Swift)
+
+class SourceCustomRasterExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+ var rasterLayer: MGLRasterStyleLayer?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ mapView.setCenter(CLLocationCoordinate2D(latitude: 45.5188, longitude: -122.6748), zoomLevel: 13, animated: false)
+
+ mapView.delegate = self
+
+ view.addSubview(mapView)
+
+ // Add a UISlider that will control the raster layer’s opacity.
+ addSlider()
+ }
+
+ func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
+ // Add a new raster source and layer.
+ let source = MGLRasterSource(identifier: "stamen-watercolor", tileURLTemplates: ["https://stamen-tiles.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg"], options: [ .tileSize: 256 ])
+ let rasterLayer = MGLRasterStyleLayer(identifier: "stamen-watercolor", source: source)
+
+ style.addSource(source)
+ style.addLayer(rasterLayer)
+
+ self.rasterLayer = rasterLayer
+ }
+
+ func updateLayerOpacity(_ sender: UISlider) {
+ rasterLayer?.rasterOpacity = MGLStyleValue(rawValue: NSNumber(value: sender.value))
+ }
+
+ func addSlider() {
+ let padding: CGFloat = 10
+ let slider = UISlider(frame: CGRect(x: padding, y: self.view.frame.size.height - 44 - 30, width: self.view.frame.size.width - padding * 2, height: 44))
+ slider.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin]
+ slider.minimumValue = 0
+ slider.maximumValue = 1
+ slider.value = 1
+ slider.addTarget(self, action: #selector(updateLayerOpacity), for: .valueChanged)
+ view.addSubview(slider)
+ }
+}
diff --git a/platform/ios/demo/Examples/Swift/SourceCustomVectorExample.swift b/platform/ios/demo/Examples/Swift/SourceCustomVectorExample.swift
new file mode 100644
index 0000000000..8c36f3471c
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/SourceCustomVectorExample.swift
@@ -0,0 +1,24 @@
+import Mapbox
+
+@objc(SourceCustomVectorExample_Swift)
+
+class SourceCustomVectorExample_Swift: UIViewController {
+ var mapView: MGLMapView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Third party vector tile sources can be added.
+
+ // In this case we're using custom style JSON (https://www.mapbox.com/mapbox-gl-style-spec/) to add a third party tile source: <https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt>
+ let customStyleURL = Bundle.main.url(forResource: "third_party_vector_style", withExtension: "json")!
+
+ mapView = MGLMapView(frame: view.bounds, styleURL: customStyleURL)
+
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.tintColor = .white
+
+ view.addSubview(mapView)
+ }
+}
+
diff --git a/platform/ios/demo/Examples/Swift/UserTrackingModesExample.swift b/platform/ios/demo/Examples/Swift/UserTrackingModesExample.swift
new file mode 100644
index 0000000000..66ba7c0481
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/UserTrackingModesExample.swift
@@ -0,0 +1,141 @@
+import Mapbox
+
+@objc(UserTrackingModesExample_Swift)
+
+class UserTrackingModesExample_Swift: UIViewController, MGLMapViewDelegate {
+ var mapView: MGLMapView!
+ @IBOutlet var button: UserLocationButton!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.darkStyleURL(withVersion: 9))
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.delegate = self
+
+ mapView.tintColor = .red
+ mapView.attributionButton.tintColor = .lightGray
+
+ view.addSubview(mapView)
+
+ setupLocationButton()
+ }
+
+ func mapView(_ mapView: MGLMapView, didChange mode: MGLUserTrackingMode, animated: Bool) {
+ button.updateArrow(for: mode)
+ }
+
+ @IBAction func locationButtonTapped() {
+ var mode: MGLUserTrackingMode
+
+ switch (mapView.userTrackingMode) {
+ case .none:
+ mode = .follow
+ break
+ case .follow:
+ mode = .followWithHeading
+ break
+ case .followWithHeading:
+ mode = .followWithCourse
+ break
+ case .followWithCourse:
+ mode = .none
+ break
+ }
+
+ mapView.userTrackingMode = mode
+ }
+
+ func setupLocationButton() {
+ button = UserLocationButton()
+ button.addTarget(self, action: #selector(locationButtonTapped), for: .touchUpInside)
+ button.tintColor = mapView.tintColor
+ view.addSubview(button)
+
+ // Do some basic auto layout.
+ button.translatesAutoresizingMaskIntoConstraints = false
+
+ let constraints = [
+ NSLayoutConstraint(item: button, attribute: .top, relatedBy: .greaterThanOrEqual, toItem: topLayoutGuide, attribute: .bottom, multiplier: 1, constant: 10),
+ NSLayoutConstraint(item: button, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 10),
+ NSLayoutConstraint(item: button, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: button.frame.size.height),
+ NSLayoutConstraint(item: button, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: button.frame.size.width)
+ ]
+
+ view.addConstraints(constraints)
+ }
+
+}
+
+class UserLocationButton : UIButton {
+ private let size: CGFloat = 80
+ private var arrow: CAShapeLayer?
+
+ required init() {
+ super.init(frame: CGRect(x: 0, y: 0, width: size, height: size))
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func layoutSubviews() {
+ backgroundColor = UIColor.black.withAlphaComponent(0.5)
+ layer.cornerRadius = 4
+
+ layoutArrow()
+ }
+
+ private func layoutArrow() {
+ if arrow == nil {
+ let arrow = CAShapeLayer()
+ arrow.path = arrowPath()
+ arrow.bounds = CGRect(x: 0, y: 0, width: size / 2, height: size / 2)
+ arrow.position = CGPoint(x: size / 2, y: size / 2)
+ arrow.shouldRasterize = true
+ arrow.rasterizationScale = UIScreen.main.scale
+ arrow.drawsAsynchronously = true
+
+ self.arrow = arrow
+ updateArrow(for: .none)
+ layer.addSublayer(self.arrow!)
+ }
+ }
+
+ private func arrowPath() -> CGPath {
+ let max: CGFloat = size / 2
+
+ let bezierPath = UIBezierPath()
+ bezierPath.move(to: CGPoint(x: max * 0.5, y: 0))
+ bezierPath.addLine(to: CGPoint(x: max * 0.1, y: max))
+ bezierPath.addLine(to: CGPoint(x: max * 0.5, y: max * 0.65))
+ bezierPath.addLine(to: CGPoint(x: max * 0.9, y: max))
+ bezierPath.addLine(to: CGPoint(x: max * 0.5, y: 0))
+ bezierPath.close()
+
+ return bezierPath.cgPath
+ }
+
+ func updateArrow(for mode: MGLUserTrackingMode) {
+ var stroke: CGColor
+ switch (mode) {
+ case .none:
+ stroke = UIColor.white.cgColor
+ case .follow:
+ stroke = tintColor.cgColor
+ case .followWithHeading, .followWithCourse:
+ stroke = UIColor.clear.cgColor
+ }
+ arrow!.strokeColor = stroke
+
+ // Re-center the arrow, based on its current orientation.
+ arrow!.position = (mode == .none || mode == .followWithCourse) ? CGPoint(x: size / 2, y: size / 2) : CGPoint(x: size / 2 + 2, y: size / 2 - 2)
+
+ arrow!.fillColor = (mode == .none || mode == .follow) ? UIColor.clear.cgColor : tintColor.cgColor
+
+ let rotation: CGFloat = (mode == .follow || mode == .followWithHeading) ? 0.66 : 0
+ arrow!.setAffineTransform(CGAffineTransform.identity.rotated(by: rotation))
+
+ layoutIfNeeded()
+ }
+}
diff --git a/platform/ios/demo/Examples/insert-mapbox-token.sh b/platform/ios/demo/Examples/insert-mapbox-token.sh
new file mode 100755
index 0000000000..a65f686b1a
--- /dev/null
+++ b/platform/ios/demo/Examples/insert-mapbox-token.sh
@@ -0,0 +1,14 @@
+token_file=$SRCROOT/mapbox_access_token
+
+# First check the above path, then the user directory.
+# Ignore exit codes from `cat`.
+token="$(cat $token_file 2> /dev/null)" || token="$(cat ~/.mapbox 2> /dev/null)"
+
+if [ "$token" ]; then
+ plutil -replace MGLMapboxAccessToken -string $token "$TARGET_BUILD_DIR/$INFOPLIST_PATH"
+else
+ echo 'error: Missing Mapbox access token'
+ open 'https://www.mapbox.com/studio/account/tokens/'
+ echo "error: Get an access token from <https://www.mapbox.com/studio/account/tokens/>, then create a new file at $token_file that contains the access token."
+ exit 1
+fi
diff --git a/platform/ios/demo/Examples/main.m b/platform/ios/demo/Examples/main.m
new file mode 100644
index 0000000000..b696b599b6
--- /dev/null
+++ b/platform/ios/demo/Examples/main.m
@@ -0,0 +1,16 @@
+//
+// main.m
+// Examples
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/platform/ios/demo/ExamplesTests/ExamplesTests.m b/platform/ios/demo/ExamplesTests/ExamplesTests.m
new file mode 100644
index 0000000000..4d7d222b3d
--- /dev/null
+++ b/platform/ios/demo/ExamplesTests/ExamplesTests.m
@@ -0,0 +1,38 @@
+//
+// ExamplesTests.m
+// ExamplesTests
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <XCTest/XCTest.h>
+
+@interface ExamplesTests : XCTestCase
+
+@end
+@implementation ExamplesTests
+
+- (void)setUp {
+ [super setUp];
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+}
+
+- (void)tearDown {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ [super tearDown];
+}
+
+- (void)testExample {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
+}
+
+- (void)testPerformanceExample {
+ // This is an example of a performance test case.
+ [self measureBlock:^{
+ // Put the code you want to measure the time of here.
+ }];
+}
+
+@end
diff --git a/platform/ios/demo/ExamplesTests/Info.plist b/platform/ios/demo/ExamplesTests/Info.plist
new file mode 100644
index 0000000000..ba72822e87
--- /dev/null
+++ b/platform/ios/demo/ExamplesTests/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/platform/ios/demo/ExamplesUITests/ExamplesUITests.m b/platform/ios/demo/ExamplesUITests/ExamplesUITests.m
new file mode 100644
index 0000000000..3b08cb3fc8
--- /dev/null
+++ b/platform/ios/demo/ExamplesUITests/ExamplesUITests.m
@@ -0,0 +1,45 @@
+//
+// ExamplesUITests.m
+// ExamplesUITests
+//
+// Created by Jason Wray on 1/26/16.
+// Copyright © 2016 Mapbox. All rights reserved.
+//
+
+#import <XCTest/XCTest.h>
+#import "Examples.h"
+
+@interface ExamplesUITests : XCTestCase
+
+@end
+@implementation ExamplesUITests
+
+- (void)setUp {
+ [super setUp];
+
+ // In UI tests it is usually best to stop immediately when a failure occurs.
+ self.continueAfterFailure = NO;
+
+ // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
+ XCUIApplication *app = [[XCUIApplication alloc] init];
+ app.launchArguments = [app.launchArguments arrayByAddingObject:@"useFastAnimations"];
+ [app launch];
+}
+
+- (void)tearDown {
+ [super tearDown];
+}
+
+- (void)testEveryExample {
+ XCUIApplication *app = [[XCUIApplication alloc] init];
+
+ for (int i = 0; i < app.tables.cells.count; i++) {
+ [app.tables.cells.allElementsBoundByIndex[i] tap];
+
+ // XCTest waits for the app to idle before continuing.
+
+ [app.navigationBars.buttons[@"Back"] tap];
+ }
+}
+
+@end
diff --git a/platform/ios/demo/ExamplesUITests/Info.plist b/platform/ios/demo/ExamplesUITests/Info.plist
new file mode 100644
index 0000000000..ba72822e87
--- /dev/null
+++ b/platform/ios/demo/ExamplesUITests/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/platform/ios/demo/Files/AppIcon.sketch b/platform/ios/demo/Files/AppIcon.sketch
new file mode 100644
index 0000000000..f388753b88
--- /dev/null
+++ b/platform/ios/demo/Files/AppIcon.sketch
Binary files differ
diff --git a/platform/ios/demo/Files/Icon-128.png b/platform/ios/demo/Files/Icon-128.png
new file mode 100644
index 0000000000..059f34b37c
--- /dev/null
+++ b/platform/ios/demo/Files/Icon-128.png
Binary files differ
diff --git a/platform/ios/demo/Files/Icon-48.png b/platform/ios/demo/Files/Icon-48.png
new file mode 100644
index 0000000000..4957939e3e
--- /dev/null
+++ b/platform/ios/demo/Files/Icon-48.png
Binary files differ
diff --git a/platform/ios/demo/Files/iTunesArtwork.png b/platform/ios/demo/Files/iTunesArtwork.png
new file mode 100644
index 0000000000..8976fbdc15
--- /dev/null
+++ b/platform/ios/demo/Files/iTunesArtwork.png
Binary files differ
diff --git a/platform/ios/demo/LICENSE.md b/platform/ios/demo/LICENSE.md
new file mode 100644
index 0000000000..ed95ef5f67
--- /dev/null
+++ b/platform/ios/demo/LICENSE.md
@@ -0,0 +1,5 @@
+To the extent possible under law, Mapbox has waived all copyright and related or neighboring rights to Mapbox iOS SDK Examples. This work is published from the United States.
+
+CC0 1.0 Universal (CC0 1.0)
+Public Domain Dedication
+https://creativecommons.org/publicdomain/zero/1.0/
diff --git a/platform/ios/demo/Podfile b/platform/ios/demo/Podfile
new file mode 100644
index 0000000000..56d1816b1a
--- /dev/null
+++ b/platform/ios/demo/Podfile
@@ -0,0 +1,16 @@
+platform :ios, '8.0'
+use_frameworks!
+
+target 'Examples' do
+ # Pods for Examples
+ pod 'Mapbox-iOS-SDK-symbols', :podspec => 'https://raw.githubusercontent.com/mapbox/mapbox-gl-native/ios-v3.6.0-beta.2/platform/ios/Mapbox-iOS-SDK-symbols.podspec'
+
+end
+
+target 'ExamplesTests' do
+ # Pods for testing
+end
+
+target 'ExamplesUITests' do
+ # Pods for testing
+end
diff --git a/platform/ios/demo/Podfile.lock b/platform/ios/demo/Podfile.lock
new file mode 100644
index 0000000000..444c129ae0
--- /dev/null
+++ b/platform/ios/demo/Podfile.lock
@@ -0,0 +1,16 @@
+PODS:
+ - Mapbox-iOS-SDK-symbols (3.6.0-beta.2-symbols)
+
+DEPENDENCIES:
+ - Mapbox-iOS-SDK-symbols (from `https://raw.githubusercontent.com/mapbox/mapbox-gl-native/ios-v3.6.0-beta.2/platform/ios/Mapbox-iOS-SDK-symbols.podspec`)
+
+EXTERNAL SOURCES:
+ Mapbox-iOS-SDK-symbols:
+ :podspec: https://raw.githubusercontent.com/mapbox/mapbox-gl-native/ios-v3.6.0-beta.2/platform/ios/Mapbox-iOS-SDK-symbols.podspec
+
+SPEC CHECKSUMS:
+ Mapbox-iOS-SDK-symbols: 64f82739d062491d56627880a2851fd355b367f3
+
+PODFILE CHECKSUM: e0fd4e004213e9d20beced091a11f3df7d14bb50
+
+COCOAPODS: 1.2.0
diff --git a/platform/ios/demo/README.md b/platform/ios/demo/README.md
new file mode 100644
index 0000000000..74e2bca474
--- /dev/null
+++ b/platform/ios/demo/README.md
@@ -0,0 +1,18 @@
+# Mapbox iOS SDK Examples
+
+A live Xcode project/app that provides the Mapbox iOS SDK's [public examples](https://www.mapbox.com/ios-sdk/examples/).
+
+## How to receive help
+We are not able to answer support questions in this repository — it is intended to show examples of what is possible with the Mapbox iOS SDK. If you have questions about how to use the Mapbox iOS SDK, please see our excellent [documentation](https://www.mapbox.com/help/) or ask the community at [Stack Overflow](http://stackoverflow.com/questions/tagged/mapbox+ios)
+
+### Other helpful links
+- [Mapbox iOS SDK API documentation](https://www.mapbox.com/ios-sdk/api/)
+- [First steps with the Mapbox iOS SDK](https://www.mapbox.com/help/first-steps-ios-sdk/)
+
+## Getting started
+1. Run `pod install` to download and integrate dependencies using [CocoaPods](https://cocoapods.org).
+1. Create the `mapbox_access_token` file in the base directory and insert your Mapbox access token.
+1. Open `Examples.xcworkspace`.
+
+## Adding a new example
+See the instructions in [`Examples.h`](Examples/Examples.h) for how to add new examples.
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index b6d422d0fc..6b110d2569 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -625,7 +625,7 @@
4018B1C31CDC277F00F666AF /* MGLAnnotationView_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationView_Private.h; sourceTree = "<group>"; };
4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLAnnotationView.mm; sourceTree = "<group>"; };
4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationView.h; sourceTree = "<group>"; };
- 402E9DE01CD2C76200FD4519 /* Mapbox.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Mapbox.playground; sourceTree = "<group>"; };
+ 402E9DE01CD2C76200FD4519 /* Mapbox.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Mapbox.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
4031ACFE1E9FD29F00A3EA26 /* MGLSDKTestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MGLSDKTestHelpers.swift; path = ../../darwin/test/MGLSDKTestHelpers.swift; sourceTree = "<group>"; };
404326881D5B9B1A007111BD /* MGLAnnotationContainerView_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView_Private.h; sourceTree = "<group>"; };
4049C29B1DB6CD6C00B3F799 /* MGLPointCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPointCollection.h; sourceTree = "<group>"; };
diff --git a/platform/ios/scripts/publish.sh b/platform/ios/scripts/publish.sh
index 80ae1ff4e0..23e6101a1e 100755
--- a/platform/ios/scripts/publish.sh
+++ b/platform/ios/scripts/publish.sh
@@ -12,7 +12,7 @@ trap finish EXIT
# iOS release tag format is `vX.Y.Z`; `X.Y.Z` gets passed in
# In the case of symbolicated builds, we also append the `-symbols`.
#
-PUBLISH_VERSION="$1"
+PUBLISH_VERSION="1"
if [[ ${#} -eq 2 ]]; then
PUBLISH_STYLE="-$2"
@@ -32,18 +32,18 @@ zip -yr ../${ZIP} *
#
# upload
#
-step "Uploading ${ZIP} to s3…"
-REPO_NAME=$(basename $TRAVIS_REPO_SLUG)
-aws s3 cp ../${ZIP} s3://mapbox/$REPO_NAME/ios/builds/ --acl public-read
-echo "URL: https://mapbox.s3.amazonaws.com/$REPO_NAME/ios/builds/${ZIP}"
+#step "Uploading ${ZIP} to s3…"
+#REPO_NAME=$(basename $TRAVIS_REPO_SLUG)
+#aws s3 cp ../${ZIP} s3://mapbox/$REPO_NAME/ios/builds/ --acl public-read
+#echo "URL: https://mapbox.s3.amazonaws.com/$REPO_NAME/ios/builds/${ZIP}"
#
# update nightly
#
-if [[ ${PUBLISH_VERSION} =~ "nightly" ]]; then
- step "Updating ${PUBLISH_VERSION} to ${PUBLISH_STYLE}…"
- GENERIC_NIGHTLY_FILENAME="mapbox-ios-sdk-${PUBLISH_VERSION}.zip"
- aws s3 cp \
- s3://mapbox/$REPO_NAME/ios/builds/${ZIP} \
- s3://mapbox/$REPO_NAME/ios/builds/${GENERIC_NIGHTLY_FILENAME} --acl public-read
-fi
+#if [[ ${PUBLISH_VERSION} =~ "nightly" ]]; then
+# step "Updating ${PUBLISH_VERSION} to ${PUBLISH_STYLE}…"
+# GENERIC_NIGHTLY_FILENAME="mapbox-ios-sdk-${PUBLISH_VERSION}.zip"
+# aws s3 cp \
+# s3://mapbox/$REPO_NAME/ios/builds/${ZIP} \
+# s3://mapbox/$REPO_NAME/ios/builds/${GENERIC_NIGHTLY_FILENAME} --acl public-read
+#fi