From ab2a1efa9a2196b45c64dd6eb91fbec17861e34f Mon Sep 17 00:00:00 2001 From: masashi Date: Tue, 1 Sep 2026 11:41:47 +0900 Subject: [PATCH 1/3] Make bearing a clockwise map rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bearing を「値を増やすと地図が時計回りに回る」向きに統一し、ネイティブ SDK との変換をコアの CameraBearing に集約する。 --- .../MapCameraPositionExtensions.swift | 8 ++++---- .../controller/MapKitViewController.swift | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift b/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift index e39a96c..fe52392 100644 --- a/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift +++ b/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift @@ -1,6 +1,6 @@ import Foundation import MapKit -import MapConductorCore +@_spi(MapConductorDriver) import MapConductorCore private let converter = MapKitZoomAltitudeConverter(zoom0Altitude: 171_319_879.0) private let mapKitMaxPitch: Double = 80.9 @@ -30,7 +30,7 @@ public extension MapCameraPosition { ? Spherical.computeOffset( origin: position, distance: distance * tan(pitchRadians), - heading: bearing + heading: CameraBearing.toNativeHeading(bearing) ) : position @@ -42,7 +42,7 @@ public extension MapCameraPosition { ), fromDistance: distance, pitch: nativePitch, - heading: bearing + heading: CameraBearing.toNativeHeading(bearing) ) } } @@ -95,7 +95,7 @@ public extension MKMapView { return MapCameraPosition( position: position, zoom: zoom, - bearing: camera.heading, + bearing: CameraBearing.bearingFromNativeHeading(camera.heading), tilt: logicalTilt, visibleRegion: visibleRegion ) diff --git a/Sources/MapConductorForMapKit/controller/MapKitViewController.swift b/Sources/MapConductorForMapKit/controller/MapKitViewController.swift index dbb0f02..02bdbea 100644 --- a/Sources/MapConductorForMapKit/controller/MapKitViewController.swift +++ b/Sources/MapConductorForMapKit/controller/MapKitViewController.swift @@ -1,7 +1,7 @@ import Foundation import CoreLocation import MapKit -import MapConductorCore +@_spi(MapConductorDriver) import MapConductorCore import QuartzCore import UIKit @@ -228,12 +228,12 @@ final class MapKitViewController: MapViewControllerProtocol { // Use UIView.animate to respect the specified duration UIView.animate(withDuration: duration) { mapView.setVisibleMapRect(rect, edgePadding: .zero, animated: false) - Self.applyHeading(position.bearing, center: centerCoordinate, to: mapView, animated: false) + Self.applyHeading(CameraBearing.toNativeHeading(position.bearing), center: centerCoordinate, to: mapView, animated: false) } } else { // Use MapKit's default animation or no animation mapView.setVisibleMapRect(rect, edgePadding: .zero, animated: animated) - Self.applyHeading(position.bearing, center: centerCoordinate, to: mapView, animated: animated) + Self.applyHeading(CameraBearing.toNativeHeading(position.bearing), center: centerCoordinate, to: mapView, animated: animated) } return true From df51ead5d752d3bc2eaf2b45ad7685da12ed82ae Mon Sep 17 00:00:00 2001 From: masashi Date: Thu, 3 Sep 2026 17:16:23 +0900 Subject: [PATCH 2/3] ci: build MapConductorCore from the matching branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit コアの未リリースな変更に追随する PR を、コアのリリースを待たずに検証できるようにする。Package.swift が元から持っている「隣に ios-sdk-core があればそれを使う」経路に乗せるだけ。 --- .github/workflows/build.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19fd7f2..875c12a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,6 +32,25 @@ jobs: - name: Show toolchain run: xcodebuild -version && swift --version + # Package.swift は `../ios-sdk-core` があればそれを使い、無ければ released 版 + # (`from: "1.1.4"`)へ解決する。CI はこのリポジトリしか checkout しないので + # 常に released 版になり、**コアの未リリースな変更に追随する PR は永久に赤いまま** + # になっていた(CameraBearing をコアへ足したときに踏んだ)。 + # 隣に置いてローカル開発と同じ経路に乗せる。同名ブランチがあればそちらを使う。 + - name: Check out MapConductorCore next to this package + env: + HEAD_REF: ${{ github.head_ref }} + run: | + url=https://github.com/MapConductor/ios-sdk-core.git + if [ -n "$HEAD_REF" ] && git ls-remote --exit-code --heads "$url" "$HEAD_REF" >/dev/null 2>&1; then + echo "ios-sdk-core: matching branch $HEAD_REF" + git clone --depth 1 --branch "$HEAD_REF" "$url" ../ios-sdk-core + else + echo "ios-sdk-core: default branch" + git clone --depth 1 "$url" ../ios-sdk-core + fi + test -f ../ios-sdk-core/Package.swift + - name: Build run: | scheme=$(sed -n 's/^[[:space:]]*name: "\([^"]*\)".*/\1/p' Package.swift | head -1) From d8e7f0b7b0c27feba80a766da815c38f157a6246 Mon Sep 17 00:00:00 2001 From: masashi Date: Thu, 3 Sep 2026 17:28:47 +0900 Subject: [PATCH 3/3] fix: make the CGFloat pitch conversion explicit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MKMapCamera.pitch は CGFloat。暗黙変換に任せると CoreGraphics の cos(CGFloat) と Foundation の cos(Double) が両方候補になり、ツールチェーンによっては ambiguous use of 'cos' で落ちる。 --- .../MapCameraPositionExtensions.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift b/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift index fe52392..b740503 100644 --- a/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift +++ b/Sources/MapConductorForMapKit/MapCameraPositionExtensions.swift @@ -54,7 +54,11 @@ public extension MKMapView { visibleRegion: VisibleRegion? = nil ) -> MapCameraPosition { let cameraAltitude = camera.altitude - let pitchRadians = camera.pitch * .pi / 180.0 + // `MKMapCamera.pitch` は CGFloat。CGFloat と Double の暗黙変換に任せると + // CoreGraphics の `cos(CGFloat)` と Foundation の `cos(Double)` が両方候補になり、 + // ツールチェーンによっては `ambiguous use of 'cos'` で落ちる(CI の macos-15 で踏んだ)。 + // 手元の Xcode では通ってしまうので、Double へ明示的に寄せておく。 + let pitchRadians = Double(camera.pitch) * .pi / 180.0 // Recover the slant distance set via MKMapCamera(fromDistance:) — the inverse of toMKMapCamera(). let slantDistance = cameraAltitude / max(cos(pitchRadians), minCosTilt) var position = GeoPoint( @@ -154,7 +158,11 @@ private extension MKMapView { /// from whatever camera happens to be set and reused to place the next one. func metersPerPointPerDistance() -> Double? { guard let metersPerPoint = measuredMetersPerPointAtCenter() else { return nil } - let pitchRadians = camera.pitch * .pi / 180.0 + // `MKMapCamera.pitch` は CGFloat。CGFloat と Double の暗黙変換に任せると + // CoreGraphics の `cos(CGFloat)` と Foundation の `cos(Double)` が両方候補になり、 + // ツールチェーンによっては `ambiguous use of 'cos'` で落ちる(CI の macos-15 で踏んだ)。 + // 手元の Xcode では通ってしまうので、Double へ明示的に寄せておく。 + let pitchRadians = Double(camera.pitch) * .pi / 180.0 let slantDistance = camera.altitude / max(cos(pitchRadians), minCosTilt) guard slantDistance > 0 else { return nil } let factor = metersPerPoint / slantDistance