老规矩先上效果图(北京的朝阳区):


此图是从https://lbs.amap.com/api/javascript-api/example/district-search/draw-district-boundaries这个网站截得,手机真机测试的效果和颜色和这个一样,另外就是再加上点击蓝色区域内和蓝色区域外会有toast弹窗提示。
先描述一下情况: 这几天正好做实验室的一个小项目app(也就是仅供学习那种。。。)需要的一个功能是在地图上进行填充需要的行政区域,也就是行政区划填充,并且要实现能够区分点击填充区域内外的动作。但是从网上大多是画轮廓线的,少有的还是oc写的,折腾了好久好久终于出效果了,特此来记录一下,看看能不能帮助需要的朋友少走弯路。
一开始看到这个博主的代码和思路:

https://blog.csdn.net/Felicity294250051/article/details/82801137

无奈本人太菜,给的程序不全,并且好多函数功能没讲清楚(反正我是没看懂),但是对理解代码还是帮助蛮大的(此处表示感谢博主
于是还是得又从官方给的demo下手,倒是有画轮廓线的,也有画多边形面的,记得网上就有一些根据现成的几个经纬度点来画多边形面,给几个链接:(反正当时搜了很多到处看,现在能找到可能有帮助的就这俩了。。。)

https://www.jianshu.com/p/fb1177cac1ec
https://blog.csdn.net/sinat_30162391/article/details/52765414

提示一下:完整的swift代码官方demo里面有,可以在那工程里搜相关的关键代码应该就能找到了,就是MAMapKit_2D_Demo这个文件夹里面InsideTestViewController.swift是填充区域的主要就是搜画轮廓线的polyline和多边形的polygon这俩参数(变量)。
其他关于怎么配置高德地图api啥的就不在这里讲了。
下面给出我的全部代码,注释都比较详细,还有包括点击填充区域内外屏幕给出的toast效果。有部分的标注掉的是用来只画轮廓线的:
注意的是,我用的是朝阳区的,但是搜索出来除了北京还有吉林也有一个朝阳。。。。所以在pointLinesArr变量这里做了说明,北京的朝阳有两个多边形构成,所以这样实际上前面的response.districts这里面应该是有两个行政区域(两个朝阳区),这里我走了不少弯路。高德给出的行政划分先是北京朝阳的再是吉林朝阳,所以我在循环让他执行完北京的后就break了。

//
//  pollution_sourceController.swift
//  污染源地图界面
//
//  Created by zhy on 2020/1/19.
//  Copyright © 2020年 zhy. All rights reserved.
//
import UIKit
import MapKit
import CoreLocation
import Toast
class pollution_sourceController: UIViewController, MAMapViewDelegate, AMapSearchDelegate {var search: AMapSearchAPI!var mapView: MAMapView!var currentLocation:CLLocation?//定位var polygon:MAPolygon!//var polygon_struct: UnsafeMutablePointer<CLLocationCoordinate2D>//var polygonview:MAPolygonViewvar overlays: Array<MAOverlay>!var select_longtitude : String = ""var select_latitude : String = ""override func viewDidLoad() {super.viewDidLoad()AMapServices.shared().enableHTTPS = truemapView = MAMapView(frame: self.view.bounds)mapView.delegate = selfmapView.isShowsUserLocation = truemapView.userTrackingMode = .followWithHeading// 设置跟随定位模式,将定位点设置成地图中心点self.view.addSubview(mapView)let r = MAUserLocationRepresentation()//初始化 MAUserLocationRepresentation 对象r.showsHeadingIndicator = truemapView.showsCompass = truemapView.showsScale = truemapView.update(r)mapView.distanceFilter = 1000mapView.zoomLevel = 14initSearch()overlays = Array()//地图覆盖物数组初始化// 发起一次请求searchDistrict(withKeyword: "朝阳区")}override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)}func initSearch() {search = AMapSearchAPI()search.delegate = self}//MARK: - Actionfunc searchDistrict(withKeyword keyword: String?) {if keyword == nil || keyword! == "" {return}let request = AMapDistrictSearchRequest()request.keywords = keyword// 显示商圈,而不是街道request.requireExtension = truesearch.aMapDistrictSearch(request)}func addAnnotation(_ coordinate: CLLocationCoordinate2D, title: String, subTitle: String) -> TGAnnotation {let annotation: TGAnnotation = TGAnnotation()annotation.coordinate = coordinateannotation.title = titleannotation.subtitle = subTitlemapView.addAnnotation(annotation as? MAAnnotation)return annotation}//MARK: - MAMapViewDelegatefunc mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {if annotation.isKind(of: MAPointAnnotation.self) {let pointReuseIndetifier = "pointReuseIndetifier"var annotationView: MAPinAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: pointReuseIndetifier) as! MAPinAnnotationView?if annotationView == nil {annotationView = MAPinAnnotationView(annotation: annotation, reuseIdentifier: pointReuseIndetifier)}annotationView!.canShowCallout = trueannotationView!.isDraggable = falseannotationView!.rightCalloutAccessoryView = UIButton(type: UIButtonType.detailDisclosure)return annotationView!}return nil}//只画轮廓/*func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {if overlay.isKind(of: MAPolyline.self) {let renderer: MAPolylineRenderer = MAPolylineRenderer(overlay: overlay)renderer.lineWidth = 8.0renderer.strokeColor = UIColor.cyan//青色return renderer}return nil}*///填充行政区域func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {if overlay.isKind(of: SelectableOverlay.self) {let selectableOverlay: SelectableOverlay = overlay as! SelectableOverlay;let actualOverlay: MAOverlay! = selectableOverlay.overlayif actualOverlay.isKind(of: MAPolygon.self) {let renderer: MAPolygonRenderer = MAPolygonRenderer(overlay: actualOverlay)renderer.strokeColor = UIColor.cyan//轮廓颜色renderer.lineWidth = 6.0//轮廓粗细renderer.fillColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 0.3)return renderer}}return nil;}//点击地图操作(判断是否在填充区域内)func mapView(_ mapView: MAMapView!, didSingleTappedAt coordinate: CLLocationCoordinate2D) {print("centerCoordinate:\(self.mapView.centerCoordinate.latitude)")var judge = falsefor (index, overlay) in mapView.overlays.enumerated().reversed() {if (overlay as AnyObject).isKind(of: SelectableOverlay.self) {let selectableOverlay: SelectableOverlay = overlay as! SelectableOverlaylet mapPoint = MAMapPointForCoordinate(coordinate)//print("mapPoint:\(mapPoint)")let distance = self.mapPointsPerPointInViewAtCurrentZoomLevel()// 判断是否选中了overlayif isOverlayWithLineWidthContainsPoint(selectableOverlay.overlay, distance, mapPoint){judge = true}}}if judge{//选中了填充区域self.view.makeToast(String.init(format: "coordinate =  {%f, %f}", coordinate.latitude,coordinate.longitude))}else{//没选中填充区域self.view.makeToast("您无权限访问")}}//MARK: - Utilityfunc mapPointsPerPointInViewAtCurrentZoomLevel() -> Double {return Double(self.mapView.metersPerPointForCurrentZoomLevel) * MAMapPointsPerMeterAtLatitude(self.mapView.centerCoordinate.latitude)}//MARK: - AMapSearchDelegatefunc aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {print("Error:\(String(describing: error))")}func onDistrictSearchDone(_ request: AMapDistrictSearchRequest!, response: AMapDistrictSearchResponse!) {mapView.removeAnnotations(mapView.annotations)mapView.removeOverlays(mapView.overlays)if response.count == 0 {print(print("规划失败,区域规划结果不存在!"))return}for aDistrict in response.districts {//aDistrict:在搜索到的每个行政区域循环var subAnnotations = Array<MAPointAnnotation>()//标注点for subDistrict in aDistrict.districts {//返回该行政区划下级的区划对象let coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(subDistrict.center.latitude), longitude: CLLocationDegrees(subDistrict.center.longitude))let anno = MAPointAnnotation()anno.coordinate = coordinate//经纬度anno.title = subDistrict.namesubAnnotations.append(anno)//边界点//print("coordinate:\(coordinate)")}print("aDistrict:\(aDistrict)")var pointLinesArr = [String]()//所有属于该区域的经纬度坐标集合(数组中每个""代表一个小区域),如朝阳区有2个//mapView.addAnnotations(subAnnotations)if aDistrict.polylines != nil {//所有坐标集合//var polylines = Array<MAPolyline>()//将坐标整合后的区域(0x开头)for polylineString in aDistrict.polylines {//从每个小区域的经纬度坐标字符串数组遍历var polygon_array = coordinatesForString(polylineString,separatorIn: ",", separatorOut: ";")//将字符串中“;”转换为”,“后的小区域数组//let polyline = CommonUtility.polyline(forCoordinateString: polylineString)//polylines.append(polyline!)polygon = MAPolygon(coordinates:&polygon_array, count: UInt(polygon_array.count))//将每个小区域进行填充,构造多边形//print("polygon_array:\(polygon_array)")let selectablePolygon: SelectableOverlay = SelectableOverlay(overlay: polygon)pointLinesArr.append(polylineString)overlays.append(selectablePolygon)mapView.add(polygon)}print("pointLinesArr.count:\(pointLinesArr.count)")//小区域个数//print(pointLinesArr)//mapView.addOverlays(polylines)mapView.addOverlays(overlays)}break}if mapView.overlays.count > 0 {mapView.showOverlays(mapView.overlays, animated: true)//立马展示所画区域print("mapView.overlays:\(String(describing: mapView.overlays))")}else {mapView.showAnnotations(mapView.annotations, edgePadding: UIEdgeInsetsMake(100, 40, 40, 40), animated: true)print("else")}}/// - Parameters:///   - pathStr: 经纬度字符串(示例:114.036217,22.524128;114.036079,22.52401;114.036011,22.523979)///   - separatorIn: 一组经纬度 经度和纬度 之间的分隔符///   - separatorOut: 每 两组经纬度 之间的间隔符/// - Returns: [CLLocationCoordinate2D]func coordinatesForString(_ pathStr: String?, separatorIn: Character = ",", separatorOut: Character = ";") -> [CLLocationCoordinate2D] {guard let pathStr = pathStr else { return [] }let coorStrs = pathStr.split(separator: separatorOut)var results = [CLLocationCoordinate2D]()for coorStr in coorStrs {let coordinate = coorStr.split(separator: separatorIn)guard coordinate.count == 2, let lng = Double(coordinate[0]), let lat = Double(coordinate[1]) else { continue }let point = CLLocationCoordinate2D(latitude: lat, longitude: lng)results.append(point)}return results}// 点击定位小蓝点进行逆地理编码查询func reverseGeocoding(){let coordinate = currentLocation?.coordinate// 构造 AMapReGeocodeSearchRequest 对象,配置查询参数(中心点坐标)let regeo: AMapReGeocodeSearchRequest = AMapReGeocodeSearchRequest()regeo.location = AMapGeoPoint.location(withLatitude: CGFloat(coordinate!.latitude), longitude: CGFloat(coordinate!.longitude))// 进行逆地理编码查询self.search!.aMapReGoecodeSearch(regeo)}// 定位回调func mapView(_ mapView: MAMapView!, didUpdate userLocation: MAUserLocation!, updatingLocation: Bool) {if updatingLocation {currentLocation = userLocation.locationlet coordinate = currentLocation?.coordinatelet circle_radius :MACircle = MACircle(center:CLLocationCoordinate2D(latitude: coordinate!.latitude, longitude: coordinate!.longitude), radius: 500)mapView.add(circle_radius)}}// 点击Annoation回调func mapView(_ mapView: MAMapView!, didSelect view: MAAnnotationView!) {// 若点击的是定位标注,则执行逆地理编码if view.annotation.isKind(of: MAUserLocation.self){reverseGeocoding()}}// 逆地理编码回调func onReGeocodeSearchDone(_ request: AMapReGeocodeSearchRequest!, response: AMapReGeocodeSearchResponse!) {if (response.regeocode != nil) {var title = response.regeocode.addressComponent.citytitle = response.regeocode.addressComponent.province//给定位标注的title和subtitle赋值,在气泡中显示定位点的地址信息mapView?.userLocation.title = titlemapView?.userLocation.subtitle = response.regeocode.formattedAddress}}deinit {print("释放")}
}

swift-调用高德sdk填充行政区域,并实现区分填充区域内外点击动作相关推荐

  1. 解决高德地图锁屏黑屏定位不更新,高德地图绘制定位轨迹,高德定位判断定位停留点,高德地图将所有坐标绘制在可视区域内

    本文章主要介绍 高德定位锁屏黑屏定位不更新的问题. 实现流程是:程序开始阶段正常执行定位,注册监听锁屏监听,唤醒cpu监听,当锁屏 广播每2秒发起一起单次定位唤醒.源码如下: package net. ...

  2. iOS——调用高德地图SDK

    当今的app中,地图随处可见.不管是美团.饿了吗的骑手位置,还是共享单车的扫车.还车,都少不了地图的使用.小组的项目计划也有地图部分,这里记录一下调用高德地图sdk的过程. 官方指南 通过CocoaP ...

  3. iOS—— 调用高德地图SDK

    iOS-- 调用高德地图SDK 我们在许多App中可以发现关于地图的调用以及定位等等功能都是什么重要的,比如滴滴打车,美团外卖等等都是十分依赖于地图的.所以我们就应该学会如和去调用地图.本周我就学习了 ...

  4. 调用高德地图,百度地图,腾讯地图,苹果地图路线规划(无需集成SDK)

    1.调用百度地图 baidumap if ([[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@"baidu ...

  5. 高德地图api调用demo_一 (1)高德SDK的使用

    1 申请高德SDK 需要填写SHA1安全码&包名 文档解决方案 https://lbs.amap.com/faq/top/hot-questions/249 package name 获取bu ...

  6. Swift基础 - - 高德地图实践

    高德地图开发需要自己到官网http://lbs.amap.com/console/ 注册一个ak,新建一个swift工程,然后在Info.plist中添加一个NSLocationAlwaysUsage ...

  7. uniapp微信小程序获取位置(高德SDK)

    效果图: 在uniapp官网给出了一个全局api用来获取用户位置 uni.getLocation 成功的回调函数会返回相关的用户信息 但是仔细参考,就会发现就address参数返回的很直接,但是也仅限 ...

  8. 高德地图导航和标注,通过调用高德APP实现呢

    在调用高德地图APP提供坐标定位位置,若果是需要导航的话可以参考下面1,如果还想知道路线.周边.导航请调用标注来实现,标注包含导航功能. 1 导航(调用显示导航图) 一种是通过高德提供的SDK实现,另 ...

  9. Android接入高德地图SDK,Android高德SDK 地图篇一:集成高德SDK

    Android高德SDK 地图篇一:集成高德SDK 大家好,这是系列博文的第一篇: 系列博文会完成以下功能 一. 地图篇:利用高德SDK实现滴滴出行的效 二. 导航篇:利用高德SDK实现滴滴司机端的效 ...

最新文章

  1. python元类深入理解
  2. 目标感太弱怎么办?如何做目标管理?
  3. *.tar.bz2文件解压
  4. MySQL 高级 - 存储过程 - 语法 - while循环
  5. c++ lambda基本语法
  6. 在现有项目中使用AspNet Identity 2.0 实战
  7. python读取mysql中表内数据_Python读取MySQL表数据的方法介绍
  8. 【Spring MVC 中 HandlerInterceptorAdapter的使用】
  9. 手机端适配rem计算方法
  10. 如何在用例之间传递值_如何从0搭建自己的自动化测试体系
  11. 编译安装mysql5.5.39_编译安装MySQL5.5
  12. 数据中心那些常见的问题
  13. 关于GBK编码及C语言中文输出问题
  14. Axure RP--快捷键大全(常用快捷键)
  15. 直流无刷电机的一些介绍
  16. 思科网络实验3.5.3 vlan配置故障排除
  17. SharePoint传出电子邮件配置
  18. lombook插件安装
  19. macos high sierra
  20. emlog模板-蓝叶博客模板源码-清新大气模板,适合做博客和资源一体!亲测

热门文章

  1. es怎么实现master选举
  2. 小程序实现狼人杀游戏会员管理、展示和数据修改
  3. Propertynbsp;#039;XXX#039;amp;nb…
  4. matlab2020a安装失败License Manager Error -8的解决方法
  5. Add python.exe to path(环境变量)
  6. java 获取词典单词_调用有道词典查询单词
  7. 财务数字化转型怎么转?从哪几个方面出发
  8. 财务数字化在企业数字化转型中起到什么作用?
  9. 卷积神经网络实战二 电机轴承故障分类
  10. 电子地图--MapABC研究(一)