Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Mapbox Maps SDKでスマートフォンアプリ開発
Search
Taro Matsuzawa aka. btm
October 13, 2019
Programming
1
1.9k
Mapbox Maps SDKでスマートフォンアプリ開発
FOSS4G 2019 Kobe KANSAIにて発表したプレゼンテーションを実験的にPDF化したものです
Taro Matsuzawa aka. btm
October 13, 2019
Tweet
Share
More Decks by Taro Matsuzawa aka. btm
See All by Taro Matsuzawa aka. btm
OpenLayers ext TypeScript declarationの開発
smellman
0
600
平成生まれのためのUNIX&IT歴 史講座 ~番外編~
smellman
2
540
掛川城の点群データをiTownsで表示しよう
smellman
0
330
そのJavascript、全部TypeScriptにしちゃえ
smellman
1
240
大容量SSDとOpenStreetMap
smellman
0
160
MapLibreとtile.openstretmap.jpで始めるベクトル地図プログラミング
smellman
1
620
国内向けタイルサーバの構築と運用について
smellman
0
1.6k
Python/Javascriptで読む点群
smellman
1
5.3k
日本のCommunity向け タイルサーバの現状
smellman
0
2.7k
Other Decks in Programming
See All in Programming
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
410
実はマルチモーダルだった。ブラウザの組み込みAI🧠でWebの未来を感じてみよう #jsfes #gemini
n0bisuke2
3
1.3k
Cap'n Webについて
yusukebe
0
150
AIの誤りが許されない業務システムにおいて“信頼されるAI” を目指す / building-trusted-ai-systems
yuya4
6
4k
20251212 AI 時代的 Legacy Code 營救術 2025 WebConf
mouson
0
230
perlをWebAssembly上で動かすと何が嬉しいの??? / Where does Perl-on-Wasm actually make sense?
mackee
0
230
Giselleで作るAI QAアシスタント 〜 Pull Requestレビューに継続的QAを
codenote
0
320
実は歴史的なアップデートだと思う AWS Interconnect - multicloud
maroon1st
0
270
モデル駆動設計をやってみようワークショップ開催報告(Modeling Forum2025) / model driven design workshop report
haru860
0
290
AI時代を生き抜く 新卒エンジニアの生きる道
coconala_engineer
1
470
これならできる!個人開発のすゝめ
tinykitten
PRO
0
140
複雑なUI設計への銀の弾丸 「オブジェクト指向UIデザイン」
teamlab
PRO
2
110
Featured
See All Featured
A Tale of Four Properties
chriscoyier
162
23k
The Language of Interfaces
destraynor
162
26k
Crafting Experiences
bethany
0
23
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
140
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Context Engineering - Making Every Token Count
addyosmani
9
560
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
410
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
29
Exploring anti-patterns in Rails
aemeredith
2
210
Heart Work Chapter 1 - Part 1
lfama
PRO
3
35k
Why Our Code Smells
bkeepers
PRO
340
58k
How to Talk to Developers About Accessibility
jct
1
87
Transcript
Mapbox Maps SDK Mapbox Maps SDK ͰεϚʔτϑΥϯΞ ͰεϚʔτϑΥϯΞ ϓϦ։ൃ ϓϦ։ൃ
দᖒଠ @ Georepublic slide: https://hackmd.io/@smellman/foss4g-2019- kobe 1
ࣗݾհ ࣗݾհ γχΞΤϯδχΞ @ Georepublic ίϛϡχςΟ͍Ζ͍Ζͬͯ·͢ OSGeoຊࢧ෦ཧࣄ ຊUNIXϢʔβձཧࣄ OpenStreetMap Foundation
Japanϝϯόʔ ϒϨΠΫίΞΫϥελ 2
FOSS4G 2019 NiigataͰYoutube৴୲ΛΓ· ͨ͠ɻ 3
৴෩ܠ ৴෩ܠ 4
Youtube৴֓ཁ Youtube৴֓ཁ ϏσΦΧϝϥ HDMI to USB Thinkpad X220 ffmpeg (৴ιϑτ)
htop (ࢹ) 5
ຊ ຊ 6
MapboxͷεϚʔτϑΥϯ͚ͷϥΠϒϥϦͷհ Ͱ͢ɻ ҙ: ࠓճ mapbox gl js ͷͰ͋Γ·ͤ Μɻ ҙ:
SlideʹऩΊΔͨΊΠϯσϯτ͕গ่͠Ε͍ͯ Δͷ͕͋Γ·͢ɻ 7
Mapbox Maps SDK Mapbox Maps SDK Mapbox͕ग़͍ͯ͠ΔωΠςΟϒ͚SDK Maps SDKͱུ͍ͯ͠Δ ެࣜαΠτͰiOS/Android/UnityʹରԠ
ࠓճiOSͱAndroidʹ͍͓ͭͯ Github্ʹXamarin/ReactNative/Node.jsͳͲ Node.jsαʔόαΠυϨϯμϦϯάʹར༻ ίΞ෦C++Ͱ࡞ 8
Overview Overview Platform Development Languages iOS Swift/Objective-C Android Kotlin/Java Unity
C# Xamarin C# React Native JavaScript Node.js JavaScript 9
Mapbox GL Ecosystem Mapbox GL Ecosystem 10
macOS͚ʹAppleScriptରԠͱ͔Γ͗͢ 11
جຊػೳ جຊػೳ ʹରԠ ͨ·ʹରԠ͍ͯ͠ͳ͍༷͋Δ ϓϥοτϑΥʔϜ͝ͱʹ࣮͞Ε͍ͯΔػೳ͕ ҧ͏ MapboxҎ֎Ͱ͍ͯ͠ΔStyle͑Δ Smartphone͚ʹࣄલμϯϩʔυػೳ͕͋ Δ iOSʹϑΝΠϧͷ্ݶ͕͋ͬͨΓ͢Δ
MapboxͷαʔϏεΛ͏߹AccessToken͕ ඞཁ Mapbox Style Specification 12
ࠓճiOS/Android/React Nativeͷ࣮Λݟ͍ͯ͘ React Nativeؒʹ߹͍·ͤΜͰͨ͠(ޙड़) 13
Mapbox Maps SDK Mapbox Maps SDK for iOS for iOS
Swift/Objective-CʹରԠͨ͠SDK StoryBoardͳͲͷGUI։ൃʹରԠ Πϯετʔϧํ๏͕͍͔ͭ͋͘Δ खಈ CocoaPad Carthage 14
खಈͰߏங खಈͰߏங Mapbox.frameworkΛϓϩδΣΫτʹՃ Build phaseʹshellΛՃ Info.plistʹҎԼΛՃ MGLMapboxAccessToken ϩάΠϯͨ͠ঢ়ଶͰνϡʔτϦΞϧΛݟΔ ͱ͜ΕΛ͑ͬͯग़ͯ͘Δ NSLocationWhenInUseUsageDescription
15
ҙ ҙ MapboxެࣜͷυΩϡϝϯτهड़͕ݹ͘ɺ Mapbox.frameworkͷՃͷํ͕ݹ͍XCodeͷ Γํʹͳ͍ͬͯΔ 16
StoryboardʹՃ StoryboardʹՃ Main.storyboardʹViewΛՃ͢Δ ΫϥεΛUIView͔ΒMGLMapViewʹมߋ͢Δ styleͷURLΛهड़ ͋ͱ࠲ඪͱ͔ೖΕ͓ͯ͘ͱࣗಈతʹͦͷ ॴ 17
18
19
20
Marker(Annotation)ΛՃ Marker(Annotation)ΛՃ AnnotationΛԠͰ͖ΔΑ͏ʹDelegateΛՃ ViewControllerͰself.view.subviews͔Β MGLMapViewΛ୳ͯ͋ͬͨ͠ΒAnnotationΛՃ ͢Δ storyboardΛ͏ͱExampleͱҧ͏ͷʹͳΓ ͕ͪͳͷͰҙ ϢʔςΟϦςΟؔΛ࡞Δͱྑ͍͔ 21
import UIKit import Mapbox class ViewController: UIViewController, MGLMapViewDelegate { ...
} 22
override func viewDidLoad() { super.viewDidLoad() for v in self.view.subviews {
if let item = v as? MGLMapView { item.delegate = self let hello = MGLPointAnnotation() hello.coordinate = CLLocationCoordinate2D(...) hello.title = "..." hello.subtitle = "..." item.addAnnotation(hello) } } } 23
// delegate func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) ->
MGLAnnotationView? { return nil } func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool { return true } 24
25
Mapbox Maps SDK Mapbox Maps SDK for Android for Android
Java/KotlinʹରԠ جຊతʹίʔυΛॻ͘ελΠϧ ΠϯετʔϧGradleͰΔͷͰָ 26
ڥߏங ڥߏங GradleͷઃఆΛapp/build.gradleʹॻ͖ࠐΉ build.gradle͕̎ͭ͋ΔͷͰҙ permissionͷઃఆΛAndroidManifest.xmlʹՃ ίʔυΛॻ͍࣮ͯΛ͢Δ 27
28
29
30
SymbolLayerΛՃ SymbolLayerΛՃ 8.x͔ΒMapView.addMarker͕depricatedʹ SymbolLayerͰ༻͢Δ MapboxMap.OnMapClickListenerͰΫϦοΫΠϕ ϯτΛϋϯυϦϯά͢Δ Ҏલͷmarkerͱ͔ͳΓҧ͏ߟ͑ํ 31
ิ ิ LayerΛ͏ΓํࣗମϕʔεϚοϓͱॲཧΛ ڞ௨Խ͢Δͱ͍͏ߟ͑ํͱࢥΘΕΔ Mapboxతʹਖ਼͍͠Γํ iOSAndroidͱಉ࣮͕͡Ͱ͖Δ͕ͬͪ͜· ͩmarkerͷॲཧdepricatedʹͳ͍ͬͯͳ͍ ͍ͣΕͳΔͱࢥΘΕΔ ͜ͷ༷ΛௐΔͨΊʹReact Nativeͷ࣮ௐ
͖Ε·ͤΜͰͨ͠ 32
public void onMapReady(@NonNull final MapboxMap mapboxMap) { this.mapboxMap = mapboxMap;
this.features = new ArrayList<>(); Feature f = Feature.fromGeometry( Point.fromLngLat(135.19890, 34.68505)); f.addStringProperty(TITLE_PROP, "KITTO"); f.addStringProperty(DESCRIPTION_PROP, "Welcome to FOSS4G 2019 Kansai/Kobe"); this.features.add(f); ... 1 2 3 4 5 6 7 8 9 10 11 33
mapboxMap.setStyle( new Style.Builder().fromUri("...") .withImage(ICON_ID, BitmapFactory.decodeResource( MainActivity.this.getResources(), R.drawable.red_marker)) .withSource(new GeoJsonSource(SOURCE_ID, FeatureCollection.fromFeatures(this.features)))
.withLayer(new SymbolLayer(LAYER_ID, SOURCE_ID) .withProperties(PropertyFactory.iconImage(ICON_ID), PropertyFactory.iconAllowOverlap(true), PropertyFactory.iconOffset(new Float[]{0f, -9f})) ), new Style.OnStyleLoaded() {...}); mapboxMap.addOnMapClickListener(this); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 34
ߟ͑ํͱͯ͠Mapbox StudioͰSymbolLayerΛ ొ͢ΔྲྀΕʹ͍ۙ a. ΞΠίϯΛొ b. ιʔεΛొ c. SymbolLayerΛొͯ͠ɺͦͷଐੑʹ iconImageΛ͚ͭΔ
ݩͷΞΠίϯը૾͕ແ͍ͷͰࣗͰ༻ҙ͢Δඞ ཁ͕͋Δ 35
@Override public boolean onMapClick(@NonNull LatLng point) { PointF screenPoint =
mapboxMap.getProjection() .toScreenLocation(point); List<Feature> features = mapboxMap .queryRenderedFeatures(screenPoint, LAYER_ID); if (!features.isEmpty()) { // ͜͜ʹ۩ମతͳॲཧΛॻ͘ return true; } return false; } 1 2 3 4 5 6 7 8 9 10 11 12 36
ॲཧͷதͷྫ Feature f = features.get(0); AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder .setMessage(f.getStringProperty(DESCRIPTION_PROP)) .setTitle(f.getStringProperty(TITLE_PROP)); AlertDialog dialog = builder.create(); dialog.show(); 1 2 3 4 5 6 7 8 37
38
39
ͰiOSͰ͜ͷॻ͖ํͲ͏͢Δͷʁ 40
func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) { let markerImage
= #imageLiteral(resourceName: "marker") mapView.style?.setImage(markerImage, forName: "marker-icon") let coordinate = CLLocationCoordinate2D(latitude: 34.68505, longitude: 135.19890) 41
let hello = MGLPointFeature() hello.coordinate = coordinate hello.attributes = [
"name": "KITTO", "description": "Welcome to FOSS4G 2019 Kansai/Kobe" ] let source = MGLShapeSource( identifier: "kobe_source", features: [hello], options: nil) mapView.style?.addSource(source) 42
let symbols = MGLSymbolStyleLayer( identifier: "kobe_layer", source: source) symbols.iconImageName =
NSExpression( forConstantValue: "marker-icon") symbols.iconAllowsOverlap = NSExpression( forConstantValue: true) symbols.iconOffset = NSExpression( forConstantValue: CGVector(dx: 0, dy: -9)) mapView.style?.addLayer(symbols) } 43
if let item = v as? MGLMapView { item.delegate =
self mapView = item let singleTap = UITapGestureRecognizer( target: self, action: #selector(handleMapTap(sender:))) for recognizer in mapView.gestureRecognizers! where recognizer is UITapGestureRecognizer { singleTap.require(toFail: recognizer) } mapView.addGestureRecognizer(singleTap) } 44
@objc @IBAction func handleMapTap( sender: UITapGestureRecognizer) { if sender.state ==
.ended { let point = sender.location(in: sender.view!) let layerIdentifiers: Set = ["kobe_layer"] 45
for feature in mapView.visibleFeatures( at: point, styleLayerIdentifiers: layerIdentifiers) where feature
is MGLPointFeature { guard let selectedFeature = feature as? MGLPointFeature else { fatalError("...") } showCallout(feature: selectedFeature) return } } } 46
func showCallout(feature: MGLPointFeature) { let dialog: UIAlertController = UIAlertController( title:
feature.attributes["name"] as? String, message: feature.attributes["description"] as? String, preferredStyle: UIAlertController.Style.alert) let action = UIAlertAction(title: "ด͡Δ", style: UIAlertAction.Style.default, handler: nil) dialog.addAction(action) self.present(dialog, animated: true, completion: nil) } 47
48
49
·ͱΊ ·ͱΊ AndroidͷMapbox Maps SDK 8.x͔ΒmarkerΛ Ճ͢Δͷ͕͑ͳ͘ͳͬͨ LayerΛ͓͏ͱ͍͏ํੑ iOS·ͩଘࡏ͢Δ͕ɺLayerΛ͏ํ๏͋Δ ࠓޙLayerΛҙࣝͨ͠ϓϩάϥϛϯά͕ඞཁ
ReactNativeͰਪ͞Ε͍ͯΔ 50
͓ΘΓ ͓ΘΓ GitHub Twitter 51