目标是在 map 上放置注释 (MGLPointAnnotation
),并在放置的位置检测它是否在另一个要素内(初始测试是它是否在 MGLPolygon< 的实例内
)。
我从以下问题中得到了一些见解: Mapbox iOS SDK - visibleFeaturesAtPoint returns empty array
该代码按预期运行,将代码移动到 mapView(:didFinishLoadingMap:)
,如他们自己的回答/评论中所述。我也尝试过其他 GPS 坐标,例如温布利大球场。
我的场景的不同之处在于使用我自己的自定义 GeoJSON 数据,这些数据是我在 map 上绘制的一组特定多边形(在 Mapbox 的 Studio 数据集中创建,但已下载且未作为样式发布),我将其与应用程序。这些功能在 mapView 上按预期加载。
所以我正在尝试使用替代方法 visibleFeatures(at: styleLayerIdentifiers:)
方法,但我返回的是空/无结果。
这是我当前的 ViewController:
import UIKit
import Mapbox
class ViewController: UIViewController {
@IBOutlet weak var mapView: MGLMapView!
// 3 points to check. 3rd not inside airport boundaries
var locations = [CLLocationCoordinate2D(latitude: 53.865841, longitude: -1.655929),
CLLocationCoordinate2D(latitude: 53.866524, longitude: -1.661572),
CLLocationCoordinate2D(latitude: 53.863542, longitude: -1.672380)]
override func viewDidLoad() {
super.viewDidLoad()
mapView.styleURL = MGLStyle.satelliteStyleURL()
// LBIA - 53.866524, -1.661572
let coord = CLLocationCoordinate2D(latitude: 53.866524, longitude: -1.661572)
mapView.setCenter(coord, zoomLevel: 17, animated: true)
}
func addAnnotations() {
let layerIdentifiers : Set = ["features"]
for shot in shotLocations {
let annotation = MGLPointAnnotation()
annotation.coordinate = shot
mapView.addAnnotation(annotation)
let ptTest = mapView.convert(annotation.coordinate, toPointTo: mapView)
print("features: \(mapView.visibleFeatures(at: ptTest, styleLayerIdentifiers: layerIdentifiers))")
//print("vis features: \(mapView.visibleFeatures(at: ptTest))")
}
}
}
extension ViewController: MGLMapViewDelegate {
func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
let url = URL(fileURLWithPath: Bundle.main.path(forResource: "features", ofType: "geojson")!)
guard let shape = try? MGLShape(data: Data(contentsOf: url), encoding: String.Encoding.utf8.rawValue) else { return }
let source = MGLShapeSource(identifier: "features", shape: shape, options: nil)
//let source = MGLShapeSource(identifier: "features", url: url, options: nil)
style.addSource(source)
print(source)
let layer = MGLFillStyleLayer(identifier: "features", source: source)
layer.sourceLayerIdentifier = "features"
layer.fillColor = MGLStyleValue(rawValue: .green)
// If just want to show "airports"...
//layer.predicate = NSPredicate(format: "feature == %@", "airport")
style.addLayer(layer)
addAnnotations()
}
func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
// Always allow callouts to popup when annotations are tapped.
return true
}
func mapView(_ mapView: MGLMapView, fillColorForPolygonAnnotation annotation: MGLPolygon) -> UIColor {
return .green
}
}
任何帮助将不胜感激...
最佳答案
基本上我自己解决了。足够解决下一个问题了...
使用 Mapbox 网站上其他已发布的示例,我使用了此处的内容: https://www.mapbox.com/ios-sdk/examples/select-layer/
我在 viewDidLoad()
中添加了一个 UITapGestureRecognizer
,这样我就可以在点击屏幕的地方放置新注释。
let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
mapView.addGestureRecognizer(gesture)
为点击处理程序添加了新的 Obj-C 函数,并将 layerIdentifiers 变量移至类内的全局范围:
@objc func handleTap(_ gesture: UITapGestureRecognizer) {
// User tapped location
let spot = gesture.location(in: mapView)
print("spot: \(spot)")
let features = mapView.visibleFeatures(at: spot, styleLayerIdentifiers: layerIdentifiers)
print("features: \(features)")
}
这成功了!它显示了 GeoJSON 数据集文件中我的自定义功能。
我在编码注释旁边放置了更多(手动点击)注释,并且 CGPoint 位置完全不同。进一步调查,它与 iPhone 屏幕上当前可见的 map 有关,这就是它没有返回任何内容的原因。使用我自己的代码,我实际上将中心 GPS 设置为稍微偏左,因此总是需要稍微滚动才能看到我的自定义功能/MGLPolygon,因此它们最初位于屏幕外。
此后,出于测试目的,我更改了代码,以便它可以在按钮单击时运行。
第一个按钮使用 setVisibleCooperativeBounds(bounds:animated:)
函数将 map 的可见部分移动到具有我的自定义功能的位置。
第二个按钮是我放置之前编码注释的位置(包含在一个简单的函数中)。现在,随着 map 的移动和更新/重新加载,注释可以检查它们是否位于我指定图层的要素上。
关于ios - Mapbox 可见功能(位于 : styleLayerIdentifiers:) - No results,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48559667/