Slide 1

Slide 1 text

Mapbox Maps SDK Mapbox Maps SDK ͰεϚʔτϑΥϯΞ ͰεϚʔτϑΥϯΞ ϓϦ։ൃ ϓϦ։ൃ দᖒଠ࿠ @ Georepublic slide: https://hackmd.io/@smellman/foss4g-2019- kobe 1

Slide 2

Slide 2 text

ࣗݾ঺հ ࣗݾ঺հ γχΞΤϯδχΞ @ Georepublic ίϛϡχςΟ͍Ζ͍Ζ΍ͬͯ·͢ OSGeo೔ຊࢧ෦ཧࣄ ೔ຊUNIXϢʔβձཧࣄ OpenStreetMap Foundation Japanϝϯόʔ ϒϨΠΫίΞΫϥελ 2

Slide 3

Slide 3 text

FOSS4G 2019 NiigataͰYoutube഑৴୲౰Λ΍Γ· ͨ͠ɻ 3

Slide 4

Slide 4 text

഑৴෩ܠ ഑৴෩ܠ 4

Slide 5

Slide 5 text

Youtube഑৴֓ཁ Youtube഑৴֓ཁ ϏσΦΧϝϥ HDMI to USB Thinkpad X220 ffmpeg (഑৴ιϑτ) htop (؂ࢹ) 5

Slide 6

Slide 6 text

ຊ୊ ຊ୊ 6

Slide 7

Slide 7 text

MapboxͷεϚʔτϑΥϯ޲͚ͷϥΠϒϥϦͷ঺հ Ͱ͢ɻ ஫ҙ: ࠓճ͸ mapbox gl js ͷ࿩Ͱ͸͋Γ·ͤ Μɻ ஫ҙ: SlideʹऩΊΔͨΊΠϯσϯτ͕গ่͠Ε͍ͯ Δ΋ͷ͕͋Γ·͢ɻ 7

Slide 8

Slide 8 text

Mapbox Maps SDK Mapbox Maps SDK Mapbox͕ग़͍ͯ͠ΔωΠςΟϒ޲͚SDK Maps SDKͱུ͍ͯ͠Δ ެࣜαΠτͰ͸iOS/Android/UnityʹରԠ ࠓճ͸iOSͱAndroidʹ͍͓ͭͯ࿩ Github্ʹ͸Xamarin/ReactNative/Node.jsͳͲ Node.js͸αʔόαΠυϨϯμϦϯάʹར༻ ίΞ෦෼͸C++Ͱ࡞੒ 8

Slide 9

Slide 9 text

Overview Overview Platform Development Languages iOS Swift/Objective-C Android Kotlin/Java Unity C# Xamarin C# React Native JavaScript Node.js JavaScript 9

Slide 10

Slide 10 text

Mapbox GL Ecosystem Mapbox GL Ecosystem 10

Slide 11

Slide 11 text

macOS޲͚ʹAppleScriptରԠͱ͔΍Γ͗͢ 11

Slide 12

Slide 12 text

جຊػೳ جຊػೳ ʹରԠ ͨ·ʹରԠ͍ͯ͠ͳ͍࢓༷΋͋Δ ϓϥοτϑΥʔϜ͝ͱʹ࣮૷͞Ε͍ͯΔػೳ͕ ҧ͏ MapboxҎ֎Ͱ഑෍͍ͯ͠ΔStyle΋࢖͑Δ Smartphone޲͚ʹ͸ࣄલμ΢ϯϩʔυػೳ͕͋ Δ iOSʹ͸ϑΝΠϧͷ্ݶ͕͋ͬͨΓ͢Δ MapboxͷαʔϏεΛ࢖͏৔߹͸AccessToken͕ ඞཁ Mapbox Style Specification 12

Slide 13

Slide 13 text

ࠓճ͸iOS/Android/React Nativeͷ࣮૷Λݟ͍ͯ͘ React Native͸ؒʹ߹͍·ͤΜͰͨ͠(ޙड़) 13

Slide 14

Slide 14 text

Mapbox Maps SDK Mapbox Maps SDK for iOS for iOS Swift/Objective-CʹରԠͨ͠SDK StoryBoardͳͲͷGUI։ൃʹ΋ରԠ Πϯετʔϧํ๏͕͍͔ͭ͋͘Δ खಈ CocoaPad Carthage 14

Slide 15

Slide 15 text

खಈͰߏங खಈͰߏங Mapbox.frameworkΛϓϩδΣΫτʹ௥Ճ Build phaseʹshellΛ௥Ճ Info.plistʹҎԼΛ௥Ճ MGLMapboxAccessToken ϩάΠϯͨ͠ঢ়ଶͰνϡʔτϦΞϧΛݟΔ ͱ͜ΕΛ࢖͑ͬͯग़ͯ͘Δ NSLocationWhenInUseUsageDescription 15

Slide 16

Slide 16 text

஫ҙ఺ ஫ҙ఺ MapboxެࣜͷυΩϡϝϯτ͸هड़͕ݹ͘ɺ Mapbox.frameworkͷ௥Ճͷ࢓ํ͕ݹ͍XCodeͷ΍ Γํʹͳ͍ͬͯΔ 16

Slide 17

Slide 17 text

Storyboardʹ௥Ճ Storyboardʹ௥Ճ Main.storyboardʹViewΛ௥Ճ͢Δ ΫϥεΛUIView͔ΒMGLMapViewʹมߋ͢Δ styleͷURLΛهड़ ͋ͱ͸࠲ඪͱ͔ೖΕ͓ͯ͘ͱࣗಈతʹͦͷ৔ ॴ΁ 17

Slide 18

Slide 18 text

18

Slide 19

Slide 19 text

19

Slide 20

Slide 20 text

20

Slide 21

Slide 21 text

Marker(Annotation)Λ௥Ճ Marker(Annotation)Λ௥Ճ AnnotationΛ൓ԠͰ͖ΔΑ͏ʹDelegateΛ௥Ճ ViewController಺Ͱself.view.subviews͔Β MGLMapViewΛ୳ͯ͋ͬͨ͠ΒAnnotationΛ௥Ճ ͢Δ storyboardΛ࢖͏ͱExampleͱҧ͏΋ͷʹͳΓ ͕ͪͳͷͰ஫ҙ ϢʔςΟϦςΟؔ਺Λ࡞Δͱྑ͍͔΋ 21

Slide 22

Slide 22 text

import UIKit import Mapbox class ViewController: UIViewController, MGLMapViewDelegate { ... } 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

// delegate func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? { return nil } func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool { return true } 24

Slide 25

Slide 25 text

25

Slide 26

Slide 26 text

Mapbox Maps SDK Mapbox Maps SDK for Android for Android Java/KotlinʹରԠ جຊతʹίʔυΛॻ͘ελΠϧ Πϯετʔϧ͸GradleͰ΍ΔͷͰָ 26

Slide 27

Slide 27 text

؀ڥߏங ؀ڥߏங GradleͷઃఆΛapp/build.gradleʹॻ͖ࠐΉ build.gradle͕̎ͭ͋ΔͷͰ஫ҙ permissionͷઃఆΛAndroidManifest.xmlʹ௥Ճ ίʔυΛॻ͍࣮ͯ૷Λ͢Δ 27

Slide 28

Slide 28 text

28

Slide 29

Slide 29 text

29

Slide 30

Slide 30 text

30

Slide 31

Slide 31 text

SymbolLayerΛ௥Ճ SymbolLayerΛ௥Ճ 8.x͔ΒMapView.addMarker͕depricatedʹ SymbolLayerͰ୅༻͢Δ MapboxMap.OnMapClickListenerͰΫϦοΫΠϕ ϯτΛϋϯυϦϯά͢Δ Ҏલͷmarkerͱ͔ͳΓҧ͏ߟ͑ํ 31

Slide 32

Slide 32 text

ิ଍ ิ଍ LayerΛ࢖͏΍Γํࣗମ͸ϕʔεϚοϓͱॲཧΛ ڞ௨Խ͢Δͱ͍͏ߟ͑ํͱࢥΘΕΔ Mapboxతʹ͸ਖ਼͍͠΍Γํ iOS͸Androidͱಉ࣮͡૷͕Ͱ͖Δ͕ͬͪ͜͸· ͩmarkerͷॲཧ͸depricatedʹͳ͍ͬͯͳ͍ ͍ͣΕͳΔͱࢥΘΕΔ ͜ͷ࢓༷Λௐ΂ΔͨΊʹReact Nativeͷ࣮૷ௐ΂ ͖Ε·ͤΜͰͨ͠ 32

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

ߟ͑ํͱͯ͠͸Mapbox StudioͰSymbolLayerΛ ొ࿥͢ΔྲྀΕʹ͍ۙ a. ΞΠίϯΛొ࿥ b. ιʔεΛొ࿥ c. SymbolLayerΛొ࿥ͯ͠ɺͦͷଐੑʹ iconImageΛ͚ͭΔ ݩͷΞΠίϯը૾͕ແ͍ͷͰࣗ෼Ͱ༻ҙ͢Δඞ ཁ͕͋Δ 35

Slide 36

Slide 36 text

@Override public boolean onMapClick(@NonNull LatLng point) { PointF screenPoint = mapboxMap.getProjection() .toScreenLocation(point); List 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

Slide 37

Slide 37 text

ॲཧͷத਎ͷྫ 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

Slide 38

Slide 38 text

38

Slide 39

Slide 39 text

39

Slide 40

Slide 40 text

Ͱ͸iOSͰ͸͜ͷॻ͖ํͲ͏͢Δͷʁ 40

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

@objc @IBAction func handleMapTap( sender: UITapGestureRecognizer) { if sender.state == .ended { let point = sender.location(in: sender.view!) let layerIdentifiers: Set = ["kobe_layer"] 45

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

48

Slide 49

Slide 49 text

49

Slide 50

Slide 50 text

·ͱΊ ·ͱΊ AndroidͷMapbox Maps SDK 8.x͔ΒmarkerΛ௥ Ճ͢Δ΋ͷ͕࢖͑ͳ͘ͳͬͨ LayerΛ࢖͓͏ͱ͍͏ํ޲ੑ iOS͸·ͩଘࡏ͢Δ͕ɺLayerΛ࢖͏ํ๏΋͋Δ ࠓޙ͸LayerΛҙࣝͨ͠ϓϩάϥϛϯά͕ඞཁ ReactNativeͰ΋ਪ঑͞Ε͍ͯΔ 50

Slide 51

Slide 51 text

͓ΘΓ ͓ΘΓ GitHub Twitter 51