1

我想要实现的是,当 userMarker 在可见边界内完成一些操作时,这是我的代码。

let screenWidth: Float = Float((map.frame.size.width))
let screenHeight: Float = Float((map.frame.size.height))
let minScreenPos: NTScreenPos = NTScreenPos(x: 0.0, y: 0.0)
let maxScreenPos: NTScreenPos = NTScreenPos(x: screenWidth, y:screenHeight)

let minPosWGS = projection.fromWgs84(map.screen(toMap: minScreenPos))!
let maxPosWGS = projection.fromWgs84(map.screen(toMap: maxScreenPos))!

let mapBounds = NTMapBounds(min: minPosWGS, max: maxPosWGS)
let markerCenter = projection.fromWgs84(userMarker.getBounds().getCenter())
let markerBounds = userMarker.getBounds()

let containPos = mapBounds!.contains(markerCenter)
let containBounds = mapBounds!.contains(markerBounds)

print(containPos)
print(containBounds)

但总是输出是错误的,我做错了什么,请帮忙。

4

2 回答 2

1

好吧,这里有几件事......

首先,你什么时候做screenToMap计算?mapView当您尚未完全渲染时,它将返回 0 (即使您的 mapView 已经有一个框架)。

所以你绝对不能在我们的viewDidLoador中做到这一点viewWillAppear,但是,目前,也不是 after layoutSubviews。您需要在地图渲染后计算它,这可以使用mapRenderer'onMapRendered事件来实现。

此处提供示例:https ://github.com/CartoDB/mobile-ios-samples/blob/master/AdvancedMap.Objective-C/AdvancedMap/CaptureController.mm

我们为此创建了一个问题:https ://github.com/CartoDB/mobile-sdk/issues/162

其次,如果您从 CartoMobileSDK 的方法中请求坐标,坐标已经返回到我们内部的坐标系中,这意味着您不需要进行任何额外的转换。要求边界和位置的正确方法是:

let minPosWGS = map.screen(toMap: minScreenPos)!
let maxPosWGS = map.screen(toMap: maxScreenPos)!

和:

let markerCenter = userMarker!.getBounds().getCenter()

第三,屏幕上以及地图上从左到右X增加,但是在屏幕上从上到下增加,但在地图上从下到上增加,因此您必须像这样初始化 min 和 max :Y

let screenWidth = Float(map.frame.size.width)
let screenHeight = Float(map.frame.size.height)
let minScreenPos = NTScreenPos(x: 0.0, y: screenHeight)
let maxScreenPos = NTScreenPos(x: screenWidth, y: 0)

请注意,此计算还取决于您的视图方向和地图旋转。目前我们假设您的旋转为 0 并且您的视图处于纵向模式。

最后,iOS 使用缩放坐标,但 Carto 的 Mobile SDK 需要真实坐标。因此,您需要将值乘以比例:

let screenWidth = Float(map.frame.size.width *  UIScreen.main.scale)
let screenHeight = Float(map.frame.size.height *  UIScreen.main.scale)
于 2017-11-28T09:55:15.697 回答
0

嗨@Nikitah我最终得到了这个解决方案

我从 MapEventsListener 实现 onMapMoved 事件并在那里我要求这个

if latestLocation != nil {
    delegate?.hideLocationButton()
}

所以在 mi hideLocationButton 方法中我这样做

let screenWidth: Float = Float(map.frame.width) * 2
let screenHeight: Float = Float(map.frame.height) * 2

let minScreenPos: NTScreenPos = NTScreenPos(x: 0, y: 0)
let maxScreenPos: NTScreenPos = NTScreenPos(x: screenWidth, y: screenHeight)
let screenBounds = NTScreenBounds(min: minScreenPos, max: maxScreenPos)

let contain = screenBounds?.contains(map.map(toScreen: marker.getBounds().getCenter()))

我意识到最好询问位置,然后在 NTScreenPos 中转换 NTMapPos,并询问该屏幕位置是否在实际屏幕边界内。

在最后的建议中,您说我需要乘以比例,所以我认为我将 screenWidht 和 screenHeight 乘以 2 这将是屏幕比例?,我这样做是因为控制台输出中的地图宽度和高度是一半iphone屏幕所以我即兴发挥:),使用 UIScreen.main.scale 会更好

关于第三个建议,我会尝试并回复。

于 2017-11-28T17:10:06.523 回答