如何在iOS/Android的Bing地图中获取搜索地址的边界?
获取Bing地图中搜索地址的完整边界
问题描述
通过地址名称搜索位置后,目前仅能在Bing地图上显示标记点,需要获取该搜索地址对应的完整地理边界并在地图上绘制。
当前代码
extension ViewController: GeocodeAlertDelegate { func searchButtonTapped(query: String, culture: String, region: String, useLocation: Bool, useBoundingBox: Bool) { guard !query.isEmpty else { return } var referenceLocation: MSGeopoint? if useLocation { referenceLocation = self.mapView.mapCenter } var referenceBoundingBox: MSGeoboundingBox? if useBoundingBox { referenceBoundingBox = self.mapView.mapBounds } let options = MSMapLocationOptions() if !culture.isEmpty { options.setCulture(culture) } if !region.isEmpty { options.setRegion(region) } MSMapLocationFinder.findLocations(query, withReferencePoint: referenceLocation, withReferenceBoundingBox: referenceBoundingBox, with: options, handleResultWith: { (result: MSMapLocationFinderResult) in switch result.status { case MSMapLocationFinderStatus.success: self.pinLayer.elements.clear() let locations = NSMutableArray() for mapLocation in result.locations { let pinLocation = MSGeopoint( latitude: mapLocation.point.position.latitude, longitude: mapLocation.point.position.longitude, altitude: 0, altitudeReferenceSystem: MSMapAltitudeReferenceSystem.terrain) print("AddressName:- \(mapLocation.address)") print("DisplayName:- \(mapLocation.displayName)") self.addPin(atLocation: pinLocation, withTitle: mapLocation.displayName) locations.add(mapLocation.point) } if locations.count > 1 { self.mapView.setScene(MSMapScene(locations: locations as! [MSGeopoint]), with: MSMapAnimationKind.default) } else { self.mapView.setScene(MSMapScene(location: locations[0] as! MSGeopoint), with: MSMapAnimationKind.default) } case MSMapLocationFinderStatus.emptyResponse: self.showMessage("No result was found") default: self.showMessage("Error processing the request") } }) } }
解决方案
核心逻辑
MSMapLocationFinder返回的MSMapLocation对象自带boundingBox属性,该属性包含地址的南北纬度、东西经度范围,即地址的完整地理边界。我们可以基于此边界框的四个顶点创建多边形,在地图上绘制出边界。
修改后的代码
extension ViewController: GeocodeAlertDelegate { // 提前初始化边界图层(建议在ViewController初始化时添加) let boundaryLayer = MSMapElementLayer() func searchButtonTapped(query: String, culture: String, region: String, useLocation: Bool, useBoundingBox: Bool) { guard !query.isEmpty else { return } var referenceLocation: MSGeopoint? if useLocation { referenceLocation = self.mapView.mapCenter } var referenceBoundingBox: MSGeoboundingBox? if useBoundingBox { referenceBoundingBox = self.mapView.mapBounds } let options = MSMapLocationOptions() if !culture.isEmpty { options.setCulture(culture) } if !region.isEmpty { options.setRegion(region) } MSMapLocationFinder.findLocations(query, withReferencePoint: referenceLocation, withReferenceBoundingBox: referenceBoundingBox, with: options, handleResultWith: { (result: MSMapLocationFinderResult) in switch result.status { case MSMapLocationFinderStatus.success: self.pinLayer.elements.clear() // 清空旧的边界元素,避免重复绘制 self.boundaryLayer.elements.clear() let locations = NSMutableArray() for mapLocation in result.locations { let pinLocation = MSGeopoint( latitude: mapLocation.point.position.latitude, longitude: mapLocation.point.position.longitude, altitude: 0, altitudeReferenceSystem: MSMapAltitudeReferenceSystem.terrain) print("AddressName:- \(mapLocation.address)") print("DisplayName:- \(mapLocation.displayName)") self.addPin(atLocation: pinLocation, withTitle: mapLocation.displayName) locations.add(mapLocation.point) // 绘制地址边界 if let boundingBox = mapLocation.boundingBox { // 提取边界框的四个顶点 let topLeft = MSGeopoint(latitude: boundingBox.northLatitude, longitude: boundingBox.westLongitude, altitude: 0, altitudeReferenceSystem: .terrain) let topRight = MSGeopoint(latitude: boundingBox.northLatitude, longitude: boundingBox.eastLongitude, altitude: 0, altitudeReferenceSystem: .terrain) let bottomRight = MSGeopoint(latitude: boundingBox.southLatitude, longitude: boundingBox.eastLongitude, altitude: 0, altitudeReferenceSystem: .terrain) let bottomLeft = MSGeopoint(latitude: boundingBox.southLatitude, longitude: boundingBox.westLongitude, altitude: 0, altitudeReferenceSystem: .terrain) // 按顺序组成多边形顶点数组(闭合路径) let polygonPoints = [topLeft, topRight, bottomRight, bottomLeft, topLeft] // 创建边界多边形 let boundaryPolygon = MSMapPolygon(points: polygonPoints) // 设置多边形样式(可自定义) boundaryPolygon.fillColor = UIColor.blue.withAlphaComponent(0.2) boundaryPolygon.strokeColor = UIColor.blue boundaryPolygon.strokeThickness = 2 // 添加到边界图层 self.boundaryLayer.elements.add(boundaryPolygon) } } // 提前将边界图层添加到地图(仅需执行一次,建议在viewDidLoad中完成) if !self.mapView.layers.contains(self.boundaryLayer) { self.mapView.layers.add(self.boundaryLayer) } if locations.count > 1 { self.mapView.setScene(MSMapScene(locations: locations as! [MSGeopoint]), with: MSMapAnimationKind.default) } else { self.mapView.setScene(MSMapScene(location: locations[0] as! MSGeopoint), with: MSMapAnimationKind.default) } case MSMapLocationFinderStatus.emptyResponse: self.showMessage("No result was found") default: self.showMessage("Error processing the request") } }) } }
关键说明
- 图层管理:单独使用
MSMapElementLayer存放边界多边形,与标记点图层分离,便于维护和清空旧元素。 - 边界绘制:通过
boundingBox的四个顶点构建闭合多边形,设置填充色、边框色等样式以区分地图其他元素。 - 初始化操作:边界图层只需添加到地图一次,建议在
viewDidLoad中完成初始化,避免重复添加。
内容的提问来源于stack exchange,提问作者Dhananjay Kumar
相关产品推荐
相关产品推荐

