Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 8 additions & 19 deletions Sources/MapConductorForOpenMobileMaps/OpenMobileMapsGestures.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CoreGraphics
import Foundation
import MapCore
import MapConductorCore
@_spi(MapConductorDriver) import MapConductorCore
import UIKit

/// 実装点 E / F。SDK のタッチをコアの受け口へつなぐ。
Expand Down Expand Up @@ -214,26 +214,15 @@ extension OpenMobileMapsMapViewController {
emitMapClick(position)
}

/// strategy 側マーカーの当たり判定と配送。重なっているときはアンカーが近いほうを選ぶ。
/// strategy 側マーカーの当たり判定と配送。選び方はコアの ``MarkerHitTest/pick`` と同じ。
private func handleStrategyTap(at point: CGPoint) -> Bool {
guard let strategyController = strategyManager.controller else { return false }
let defaultIcon = DefaultMarkerIcon()
var bestState: MarkerState?
var bestDistance = CGFloat.infinity
for entity in strategyController.markerManager.allEntities() where entity.state.clickable {
guard let screen = ommHolder.toScreenOffset(position: entity.state.position) else { continue }
guard MarkerHitTest.hitsIcon(
touchScreen: point,
markerScreen: screen,
state: entity.state,
defaultIcon: defaultIcon
) else { continue }
let distance = hypot(point.x - screen.x, point.y - screen.y)
if distance < bestDistance {
bestDistance = distance
bestState = entity.state
}
}
let bestState = MarkerHitTest.pick(
touchScreen: point,
candidates: strategyController.markerManager.allEntities().map(\.state).filter(\.clickable),
state: { $0 },
project: { ommHolder.toScreenOffset(position: $0) }
)
guard let state = bestState else { return false }
strategyController.dispatchClick(state)
return true
Expand Down
29 changes: 10 additions & 19 deletions Sources/MapConductorForOpenMobileMaps/OpenMobileMapsMarkers.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CoreGraphics
import Foundation
import MapCore
import MapConductorCore
@_spi(MapConductorDriver) import MapConductorCore
import UIKit

/*
Expand Down Expand Up @@ -560,29 +560,20 @@ final class OpenMobileMapsMarkerController:
markerManager.getEntity(id)?.state
}

/// 画面座標にあるマーカー。重なっているときはアンカーが近いほうを選ぶ。
/// 画面座標にあるマーカー。選び方はコアの ``MarkerHitTest/pick`` と同じで、指の下にアイコン
/// (ラベル込み)が描かれているマーカーを、アンカーの近い別のマーカーより優先する。
///
/// 受け取るのは**入れ物(`OpenMobileMapsMapSurface`)の座標**。ホルダーの
/// `toScreenOffset` も入れ物の座標へ畳んで返すので、両者は同じ系で比べられる。
func markerId(atScreenPoint point: CGPoint, where isEligible: (MarkerState) -> Bool) -> String? {
guard let holder else { return nil }
var bestId: String?
var bestDistance = CGFloat.infinity
for entity in markerManager.allEntities() where isEligible(entity.state) {
guard let screen = holder.toScreenOffset(position: entity.state.position) else { continue }
guard MarkerHitTest.hitsIcon(
touchScreen: point,
markerScreen: screen,
state: entity.state,
defaultIcon: defaultIcon
) else { continue }
let distance = hypot(point.x - screen.x, point.y - screen.y)
if distance < bestDistance {
bestDistance = distance
bestId = entity.state.id
}
}
return bestId
return MarkerHitTest.pick(
touchScreen: point,
candidates: markerManager.allEntities().map(\.state).filter(isEligible),
state: { $0 },
project: { holder.toScreenOffset(position: $0) },
defaultIcon: defaultIcon
)?.id
}

func unbind() {
Expand Down