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
610
平成生まれのための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
GoLab2025 Recap
kuro_kurorrr
0
3.8k
Pythonではじめるオープンデータ分析〜書籍の紹介と書籍で紹介しきれなかった事例の紹介〜
welliving
3
780
Cap'n Webについて
yusukebe
0
160
例外処理とどう使い分ける?Result型を使ったエラー設計 #burikaigi
kajitack
16
5.2k
AIエージェント、”どう作るか”で差は出るか? / AI Agents: Does the "How" Make a Difference?
rkaga
2
880
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
1
210
インターン生でもAuth0で認証基盤刷新が出来るのか
taku271
0
150
AI時代を生き抜く 新卒エンジニアの生きる道
coconala_engineer
1
520
AIエージェントの設計で注意するべきポイント6選
har1101
6
3.1k
TerraformとStrands AgentsでAmazon Bedrock AgentCoreのSSO認証付きエージェントを量産しよう!
neruneruo
4
2.4k
SQL Server 2025 LT
odashinsuke
0
140
AIによるイベントストーミング図からのコード生成 / AI-powered code generation from Event Storming diagrams
nrslib
2
1.3k
Featured
See All Featured
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
65
35k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Mobile First: as difficult as doing things right
swwweet
225
10k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
410
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
110
How GitHub (no longer) Works
holman
316
140k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
81
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
1.8k
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