You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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")
            }
        })
    }
}

关键说明

  1. 图层管理:单独使用MSMapElementLayer存放边界多边形,与标记点图层分离,便于维护和清空旧元素。
  2. 边界绘制:通过boundingBox的四个顶点构建闭合多边形,设置填充色、边框色等样式以区分地图其他元素。
  3. 初始化操作:边界图层只需添加到地图一次,建议在viewDidLoad中完成初始化,避免重复添加。

内容的提问来源于stack exchange,提问作者Dhananjay Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:42:09