如何使用carto-mobile SDK验证地图位置是否在地图边界内

时间:2017-11-24 15:21:18

标签: ios swift3 maps carto-mobile

我想要实现的是,当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)

但总是输出是假的,我做错了,请帮忙。

2 个答案:

答案 0 :(得分:1)

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

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

所以你绝对不能在viewDidLoadviewWillAppear中执行此操作,但目前也不能在layoutSubviews之后执行此操作。您需要在地图渲染后进行计算,这可以使用mapRenderer的{​​{1}}事件来实现。

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

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

其次,如果您要求CartoMobileSDK方法的坐标,则已在我们的内部坐标系中返回坐标,这意味着您无需进行任何其他转换。要求界限和位置的正确方法是:

onMapRendered

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

第三次let markerCenter = userMarker!.getBounds().getCenter() 在屏幕上以及地图上从左向右增加 ,但X增加”,但地图上的从下到上,因此您必须初始化min和max:

Y

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

最后,iOS使用缩放坐标,但Carto的Mobile SDK需要真正的坐标。所以你需要按比例乘以你的值:

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)

答案 1 :(得分: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

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