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
590
平成生まれのためのUNIX&IT歴 史講座 ~番外編~
smellman
2
520
掛川城の点群データをiTownsで表示しよう
smellman
0
310
そのJavascript、全部TypeScriptにしちゃえ
smellman
1
230
大容量SSDとOpenStreetMap
smellman
0
150
MapLibreとtile.openstretmap.jpで始めるベクトル地図プログラミング
smellman
1
600
国内向けタイルサーバの構築と運用について
smellman
0
1.5k
Python/Javascriptで読む点群
smellman
1
5.2k
日本のCommunity向け タイルサーバの現状
smellman
0
2.7k
Other Decks in Programming
See All in Programming
Six and a half ridiculous things to do with Quarkus
hollycummins
0
180
uniqueパッケージの内部実装を支えるweak pointerの話
magavel
0
1k
Server Side Kotlin Meetup vol.16: 内部動作を理解して ハイパフォーマンスなサーバサイド Kotlin アプリケーションを書こう
ternbusty
3
210
AI Coding Meetup #3 - 導入セッション / ai-coding-meetup-3
izumin5210
0
3.3k
Writing Better Go: Lessons from 10 Code Reviews
konradreiche
0
1.3k
AI Agent 時代的開發者生存指南
eddie
3
1.8k
非同期jobをtransaction内で 呼ぶなよ!絶対に呼ぶなよ!
alstrocrack
0
980
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
200
フロントエンド開発のためのブラウザ組み込みAI入門
masashi
0
230
CSC305 Lecture 08
javiergs
PRO
0
220
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
200
大規模アプリのDIフレームワーク刷新戦略 ~過去最大規模の並行開発を止めずにアプリ全体に導入するまで~
mot_techtalk
1
460
Featured
See All Featured
KATA
mclloyd
32
15k
How to Think Like a Performance Engineer
csswizardry
27
2k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.2k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
22k
It's Worth the Effort
3n
187
28k
Git: the NoSQL Database
bkeepers
PRO
431
66k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
Rails Girls Zürich Keynote
gr2m
95
14k
Site-Speed That Sticks
csswizardry
13
910
Producing Creativity
orderedlist
PRO
347
40k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.5k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.2k
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