Slide 1

Slide 1 text

ແྉͰ࢖͑ͯҙ֎ͱੌ͍ .BQ,JUͷੈք χϑςΟϥΠϑελΠϧגࣜձࣾ ,FJTVLF4BJUPʢ!TBJLFJʣ ʘࠓ೥΋εϙϯαʔ΍ͬͯ·͢ʂʗ https://github.com/saikei718/iosdc2023-mapkit J04%$+BQBOϧʔΩʔζ-5ʢ%":ʣ

Slide 2

Slide 2 text

๏J1IPOF04ʢJ04ʣ͔Β࢖͑Δ"QQMFඪ ४"1* ๏ຖ೥ͷΑ͏ʹ৽ػೳ͕௥Ճ͞Εʮ.BQ,JUͰग़དྷ Δ͜ͱʯ͕ͲΜͲΜ૿͍͑ͯΔʂ ๏୭Ͱ΋ແྉͰ࢖͑Δʂ .BQ,JUͱ͸ʁ 🙋ࣗݾ঺հʂ

Slide 3

Slide 3 text

🤔 .BQ,JU࢖ͬͯ·͔͢ʁ 🙋ᜊ౻ܓ༞ʢ,FJTVLF4BJUPʣͱ͍͍·͢ʂ

Slide 4

Slide 4 text

஍ਤΞϓϦ͡Όͳ͍͔Β ؔ܎ͳ͍ʁ 🤨 🙋9ʢ5XJUUFSʣ͸!TBJLFJͰ΍ͬͯ·͢ʂ

Slide 5

Slide 5 text

஍ਤ͕ϝΠϯͰ͸ͳͯ͘΋ ิॿػೳͱͯ͠.BQ,JUΛ ׆༻Ͱ͖Δ͔΋͠Ε·ͤΜʂ 🥳🥳🥳 🙋J04%$͸೥͕ॳࢀՃͰɺࠓ೥͕ॳΊͯͷΦϑϥΠϯࢀՃͰ͢ʂ

Slide 6

Slide 6 text

ʮJ04%$ΞϓϦ Ծ ʹ ϨετϥϯΛ୳͢ػೳʯ Λ௥Ճ͍ͨ͠ʂ 🧑💻🧑💻🧑💻 🙋J04ΤϯδχΞྺ͸೥͘Β͍ʹͳΓ·͢ʂ

Slide 7

Slide 7 text

ॅॴͱҢ౓ܦ౓ͷ૬ޓม׵ ʢδΦίʔσΟϯάͱٯδΦίʔσΟϯάʣ ॅॴ FY౦ژ౎৽॓۠େٱอ Ң౓ܦ౓ FY $-(FPDPEFS J04 // 住所 → 緯度経度(を含むCLPlacemark) let address = "東京都新宿区大久保3-4-1" let placemarks: [CLPlacemark] = try await CLGeocoder().geocodeAddressString(address) // 緯度経度 → 住所(を含むCLPlacemark) let location = CLLocation(latitude: 35.70620, longitude: 139.70713) let placemarks: [CLPlacemark] = try await CLGeocoder().reverseGeocodeLocation(location) 🙋ॴଐ͸ʮχϑςΟϥΠϑελΠϧגࣜձࣾγεςϜ։ൃ෦ΞϓϦ։ൃνʔϜʯͰ͢ʂ

Slide 8

Slide 8 text

Ξϊςʔγϣϯʢϐϯʣ Λ஍ਤʹࢗ͢ J04 🙋ฐࣾ͸ࠓ೥΋J04%$ͷεϙϯαʔΛ͍ͯ͠·͢ʂ let annotation = MKPointAnnotation() annotation.title = “早稲田大学" // タイトル(任意) annotation.subtitle = "西早稲田キャンパス" // タイトル(任意) annotation.coordinate = CLLocationCoordinate2D( /* 西早稲田駅 */ ) self.mapView.addAnnotation(annotation)

Slide 9

Slide 9 text

Ξϊςʔγϣϯʢϐϯʣ Λ஍ਤʹࢗ͢ J04 let annotation = MKPointAnnotation() annotation.title = “早稲田大学" // タイトル(任意) annotation.subtitle = "西早稲田キャンパス" // タイトル(任意) annotation.coordinate = CLLocationCoordinate2D( /* 西早稲田駅 */ ) self.mapView.addAnnotation(annotation) func mapView( _ mapView: MKMapView, viewFor annotation: MKAnnotation ) -> MKAnnotationView? { let annotationView = mapView.dequeueReusableAnnotationView( withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation ) as! MKMarkerAnnotationView annotationView.clusteringIdentifier = "group1" return annotationView } ΫϥελϦϯάʹରԠͤ͞Δ 🙋ฐࣾ͸ࠓ೥΋J04%$ͷεϙϯαʔΛ͍ͯ͠·͢ʂ

Slide 10

Slide 10 text

Ξϊςʔγϣϯʢϐϯʣ ͷΧελϚΠζ J04 ΧελϜΞϊςʔγϣϯ ˞ΧελϜΞϊςʔγϣϯ͸ʮχϑςΟෆಈ࢈ʢߪೖ൛J04ΞϓϦʣʯΑΓ σϑΥϧτΞϊςʔγϣϯ 🙋ʮπόϝฑͷϚΠΫϩϑΝΠόʔΫϩεʯΛϊϕϧςΟ#09ʹೖΕ͍ͯͨձࣾͰ͢ʂ

Slide 11

Slide 11 text

εϙοτʢ৔ॴʣݕࡧ Ωʔϫʔυ FYϨετϥϯ ʢ˞ج४஍఺͸೚ҙͰઃఆՄʣ .,-PDBM4FBSDI$PNQMFUFS J04 let searchCompleter = MKLocalSearchCompleter() searchCompleter.delegate = self searchCompleter.queryFragment = "レストラン" searchCompleter.region = MKCoordinateRegion(/* 西早稲田駅 */) // 検索結果は ` MKLocalSearchCompleterDelegate` で受け取る func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { print("result:\(completer.results)") // -> [MKLocalSearchCompletion] } 🙋໌೔ʢ%":ʣͷʲʙʳ5SBDL$Ͱεϙϯαʔηογϣϯ΋ొஃ͠·͢ʂ

Slide 12

Slide 12 text

Ϛοϓ΁ͷਤܗͷΦʔόʔϨΠʢඳըʣ 📝7JFX$POUSPMMFS J04 📝.,.BQ7JFX%FMFHBUF let coordinates: [CLLocationCoordinate2D] = [ .init(latitude: 35.70620, longitude: 139.70713), // 四角形の4点を緯度経度で指定 ] let polygon = MKPolygon( coordinates: coordinates1, count: coordinates1.count ) mapView.addOverlay(polygon1) func mapView( _ mapView: MKMapView, rendererFor overlay: MKOverlay ) -> MKOverlayRenderer { let polygon = overlay as! MKPolygon let polygonRenderer = MKPolygonRenderer(polygon: polygon) polygonRenderer.strokeColor = .systemRed // 枠の色 polygonRenderer.lineWidth = 2.0 // 枠の太さ polygonRenderer.fillColor = .green // 塗りの色 polygonRenderer.alpha = 0.5 // 透明度 return polygonRenderer } ਤܗͷ௖఺ΛҢ౓ܦ౓Ͱࢦఆ .BQ7JFXʹBEE0WFSMBZ͢Δ ਤܗͷσβΠϯ͸ .,.BQ7JFX%FMFHBUFଆͰࢦఆ 🙋Α͚Ε͹εϙϯαʔηογϣϯ΋ݟʹ͖͍ͯͩ͘͞ʂ

Slide 13

Slide 13 text

ܦ࿏୳ࡧ ࢝఺ɾऴ఺ FYʮ੢ૣҴాӺʯ͔Β ʮձ৔ೖΓޱʯ·Ͱ J04 let request = MKDirections.Request() request.source = MKMapItem(placemark: MKPlacemark(coordinate: /* 西早稲田駅 */ )) // 始点緯度経度 request.destination = MKMapItem(placemark: MKPlacemark(coordinate: /* 会場入り口 */ )) // 終点緯度経度 request.transportType = .walking // 移動手段: MKDirectionsTransportType(徒歩、自動車、公共交通機関、全て) let response: MKDirections.Response = try await MKDirections(request: request).calculate() print(response.routes) // -> [MKRoute] 🙋ීஈ͸ϖϯϥΠτৼΔଆͷੜ׆Λ͍ͯ͠ΔΜͰ͕͢ʜ .,%JSFDUJPOT

Slide 14

Slide 14 text

Ϛοϓཁૉʢ10*ʣ ͷϑΟϧλϦϯά σϑΥϧτ J04 ੾Γସ͑ͷ༷ࢠ let filter = MKPointOfInterestFilter(including: [.cafe, .restaurant]) let mapConfiguration = MKStandardMapConfiguration() mapConfiguration.pointOfInterestFilter = filter self.mapView.preferredConfiguration = mapConfiguration 🙋ϖϯϥΠτΛৼΒΕΔଆͷޫܠ΋ѱ͘ͳ͍Ͱ͢Ͷʂਪ͕͠ݟͯΔੈքʂ .,1PJOU0G*OUFSFTU'JMUFS

Slide 15

Slide 15 text

Ϛοϓཁૉʢ10*ʣ ͷ৘ใऔಘ J04 // λοϓՄೳͳཁૉΛࢦఆ mapView.selectableMapFeatures = [.pointsOfInterest, .physicalFeatures, .territories] // λοϓΠϕϯτ͸௨ৗͷΞϊςʔγϣϯͱಉ༷ `MKMapViewDelegate` Ͱड͚औΔ func mapView(_ mapView: MKMapView, didSelect annotation: MKAnnotation) { guard let featureAnnotation = annotation as? MKMapFeatureAnnotation else { return } let featureRequest = MKMapItemRequest(mapFeatureAnnotation: featureAnnotation) Task { let featureMapItem: MKMapItem = try await featureRequest.mapItem print(featureMapItem.name ?? "nil") // => 早稲田大学 西早稲田キャンパス print(featureMapItem.phoneNumber ?? "nil") // => +81 3 3203 4333 print(featureMapItem.url?.absoluteString ?? "nil") // => https://www.waseda.jp/top/ } } TFMFDUBCMF.BQ'FBUVSFTΛࢦఆ .,.BQ7JFX%FMFHBUFͰλοϓΛड͚औΔ .,.BQ*UFN3FRVFTUʹ౉͢ͱʮి࿩൪߸ʯ ΍ʮαΠτͷ63-ʯ͕ฦ٫͞ΕΔ 🙋GPSUFFͰͷϑΟʔυόοΫ΋͓଴ͪͯ͠·͢ʂ

Slide 16

Slide 16 text

๏.BQ,JU͸ແྉͰ࢖͑Δ্ʹɺ༷ʑͳػೳ͕͋ ΓɺΧελϚΠζ΋ग़དྷΔʂ ๏஍ਤΞϓϦҎ֎Ͱ΋.BQ,JUͷ׆༻৔໘͸ଟ਺ʂ ๏J04͔Β.BQ,JUͷ4XJGU6*ͷαϙʔτ͕֦ ு͞ΕΔͳͲɺ·ͩ·ͩਐԽΛ͍ͯ͠Δ ·ͱΊ 🙋ᜊ౻ܓ༞ʢ,FJTVLF4BJUPʣ🏢χϑςΟϥΠϑελΠϧגࣜձࣾ 𝕏 !TBJLFJ

Slide 17

Slide 17 text

https://github.com/saikei718/iosdc2023-mapkit ࠓճͷ-5಺Ͱ͝঺հͨ͠಺༰͸ɺ ύϯϑϨοτ QQ ʹ΋ܝࡌ͞Ε͍ͯ·͢ʂ αϯϓϧΞϓϦ΋(JU)VCͰެ։͍ͯ͠ΔͷͰ ͲͪΒ΋ซͤͯ͝ཡ͍ͩ͘͞ʂ ΋ͬͱৄ͘͠஌Γ͍ͨํ͸ʜʂ 🙋͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ ᜊ౻ܓ༞ʢ,FJTVLF4BJUPʣ

Slide 18

Slide 18 text

"QQFOEJY

Slide 19

Slide 19 text

Ξϊςʔγϣϯʢϐϯʣ ͷΧελϚΠζ J04 ᶃ.,1PJOU"OOPUBUJPO wΞϊςʔγϣϯࣗମͷ৘ใΛ ࣋ͭΫϥε w஍ਤ্ʹ഑ஔ͢Δͷʹ࢖༻͢ Δ ᶄ.,"OOPUBUJPO7JFX wΞϊςʔγϣϯͷ7JFXΛ࣋ͭ Ϋϥε w.BQ7JFX%FMFHBUF಺Ͱᶃͷ Ξϊςʔγϣϯʹରͯ͠7JFXΛ ࢦఆ͢Δ "QQFOEJY // マップ上に表示するアノテーションの指定 let location = CLLocationCoordinate2D(latitude: 35.70620, longitude: 139.70713) let annotation = CustomAnnotation() annotation.coordinate = location mapView.addAnnotation(annotation) // カスタマイズアノテーション & アノテーションView class CustomAnnotation: MKPointAnnotation {} // アノテーションの情報(空でも可) class CustomAnnotationView: MKAnnotationView {} // 実際のアノテーションのView(xibでの実装も可) // ` MapViewDelegate` でアノテーションに対するアノテーションViewを指定する func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { switch annotation { case is CustomAnnotation: // CustomAnnotationで作成されたアノテーション let customAnnotationView = CustomAnnotationView() return customAnnotationView case let annotation as MKClusterAnnotation: // クラスタリングされたアノテーション let clusteringCustomAnnotationView = ClusteringCustomAnnotationView() // クラスタリングされているアノテーションの情報は ` annotation.memberAnnotations` で取得可 // ` ClusteringCustomAnnotationView` のプロパティに渡すことで表示を切り替えられる return customAnnotationView } }

Slide 20

Slide 20 text

BJSQPSU ʢۭߓʣ BNVTFNFOU1BSL ʢ༡Ԃ஍ʣ BRVBSJVN ʢਫ଒ؗʣ BUN ʢ"5.ʣ CBLFSZ ʢύϯ԰ʣ CBOL ʢۜߦʣ CFBDI ʢϏʔνʣ CSFXFSZ ʢৢ଄ॴʣ DBGF ʢΧϑΣʣ DBNQHSPVOE ʢΩϟϯϓ৔ʣ DBS3FOUBM ʢϨϯλΧʔʣ FW$IBSHFS ʢ&7ॆిثʣ fi SF4UBUJPO ʢফ๷ॺʣ fi UOFTT$FOUFS ʢδϜʣ GPPE.BSLFU ʢ৯ྉ඼ళʣ HBT4UBUJPO ʢΨιϦϯελϯυʣ IPTQJUBM ʢපӃʣ IPUFM ʢϗςϧʣ MBVOESZ ʢΫϦʔχϯά԰ʣ MJCSBSZ ʢਤॻؗʣ NBSJOB ʢߓʣ NPWJF5IFBUFS ʢөըؗʣ NVTFVN ʢത෺ؗʣ OBUJPOBM1BSL ʢࠃཱެԂʣ OJHIUMJGF ʢόʔͳͲʣ QBSL ʢެԂʣ QBSLJOH ʢறं৔ʣ QIBSNBDZ ʢༀہʣ QPMJDF ʢܯ࡯ॺʣ QPTU0 ff i DF ʢ༣ศہʣ QVCMJD5SBOTQPSU ʢެڞަ௨ػؔʣ SFTUBVSBOU ʢϨετϥϯʣ SFTUSPPN ʢτΠϨʣ TDIPPM ʢֶߍʣ TUBEJVN ʢελδΞϜʣ TUPSF ʢ͓ళʣ UIFBUFS ʢܶ৔ʣ VOJWFSTJUZ ʢେֶʣ XJOFSZ ʢϫΠφϦʔʣ [PP ʢಈ෺Ԃʣ શछྨ 10*ͷΧςΰϦʔʢ.,1PJOU0G*OUFSFTU$BUFHPSZʣ "QQFOEJY