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.8k
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
570
平成生まれのためのUNIX&IT歴 史講座 ~番外編~
smellman
2
510
掛川城の点群データをiTownsで表示しよう
smellman
0
300
そのJavascript、全部TypeScriptにしちゃえ
smellman
1
220
大容量SSDとOpenStreetMap
smellman
0
140
MapLibreとtile.openstretmap.jpで始めるベクトル地図プログラミング
smellman
1
590
国内向けタイルサーバの構築と運用について
smellman
0
1.3k
Python/Javascriptで読む点群
smellman
1
5.1k
日本のCommunity向け タイルサーバの現状
smellman
0
2.7k
Other Decks in Programming
See All in Programming
High-Level Programming Languages in AI Era -Human Thought and Mind-
hayat01sh1da
PRO
0
770
Modern Angular with Signals and Signal Store:New Rules for Your Architecture @enterJS Advanced Angular Day 2025
manfredsteyer
PRO
0
220
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
2
800
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
2
640
Quand Symfony, ApiPlatform, OpenAI et LangChain s'allient pour exploiter vos PDF : de la théorie à la production…
ahmedbhs123
0
190
GitHub Copilot and GitHub Codespaces Hands-on
ymd65536
2
150
脱Riverpod?fqueryで考える、TanStack Queryライクなアーキテクチャの可能性
ostk0069
0
120
PostgreSQLのRow Level SecurityをPHPのORMで扱う Eloquent vs Doctrine #phpcon #track2
77web
2
530
Code as Context 〜 1にコードで 2にリンタ 34がなくて 5にルール? 〜
yodakeisuke
0
130
地方に住むエンジニアの残酷な現実とキャリア論
ichimichi
5
1.5k
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
770
テストから始めるAgentic Coding 〜Claude Codeと共に行うTDD〜 / Agentic Coding starts with testing
rkaga
12
4.4k
Featured
See All Featured
How GitHub (no longer) Works
holman
314
140k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
281
13k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
950
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Why Our Code Smells
bkeepers
PRO
336
57k
Become a Pro
speakerdeck
PRO
29
5.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
How to Ace a Technical Interview
jacobian
278
23k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Code Reviewing Like a Champion
maltzj
524
40k
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