Ios 在虚拟地图swift3上放置批注
请帮帮我 第一次参与一个项目,涉及iBeacon,它创建了一个商店内部的虚拟地图 我知道如何使用地图工具包放置图钉,但如果我只有视图上的CG点,我该怎么做呢? 我设法将UIImage(带pin图像)滴到视图上。但当我旋转或挤压时,并不是停留在我掉下来的坐标上。 这里有一个代码:Ios 在虚拟地图swift3上放置批注,ios,swift,ibeacon,Ios,Swift,Ibeacon,请帮帮我 第一次参与一个项目,涉及iBeacon,它创建了一个商店内部的虚拟地图 我知道如何使用地图工具包放置图钉,但如果我只有视图上的CG点,我该怎么做呢? 我设法将UIImage(带pin图像)滴到视图上。但当我旋转或挤压时,并不是停留在我掉下来的坐标上。 这里有一个代码: import UIKit class MapViewController: UIViewController{ private var scaleView: CGFloat = 1 privat
import UIKit
class MapViewController: UIViewController{
private var scaleView: CGFloat = 1
private var rotateView: CGFloat = 0
private var anchorPoint = CGPoint(x: 0.5, y: 0.5)
private let gestureRecognizerDelegate = GestureRecognizerDelegate()
@IBOutlet weak var mapView: MapView!
@IBOutlet var pinchGestureRecognizer: UIPinchGestureRecognizer!
@IBOutlet var panGestureRecognizer: UIPanGestureRecognizer!
@IBOutlet var rotateGestureRecognizer: UIRotationGestureRecognizer!
@IBOutlet weak var pin: UIImageView!
override func viewDidAppear(_ animated: Bool) {
if !cartIsEmpty {
cartBtn.setImage(UIImage(named: "haveitem"), for: .normal)
} else {
cartBtn.setImage(UIImage(named: "2772"), for: .normal)
}
cartBtn.addTarget(self, action: #selector(openCart), for: .touchUpInside)
let item1 = UIBarButtonItem(customView: cartBtn)
self.navigationItem.rightBarButtonItem = item1
}
override func viewDidDisappear(_ animated: Bool) {
cartBtn.removeTarget(self, action: #selector(openCart), for: .touchUpInside)
}
override func viewDidLoad() {
super.viewDidLoad()
ApplicationManager.sharedInstance.onApplicationStart()
NotificationCenter.default.addObserver(self, selector: #selector(self.onOrientationChanged), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
self.panGestureRecognizer.delegate = gestureRecognizerDelegate
self.pinchGestureRecognizer.delegate = gestureRecognizerDelegate
self.rotateGestureRecognizer.delegate = gestureRecognizerDelegate
ApplicationManager.sharedInstance.gotFloorData = drawFloor
ApplicationManager.sharedInstance.currentUserPoint = drawCurrentUserPoint
}
func drawFloor (floor: Floor) {
mapView.setFloor(currentFloor: floor)
mapView.setNeedsDisplay()
}
func drawCurrentUserPoint(currentUserPoint: CurrentUserLocation, beaconRangingData: [BeaconRangingPoint]) {
mapView.setUserPoint(currentUserPoint: currentUserPoint, beaconRangingData: beaconRangingData)
mapView.setNeedsDisplay()
}
@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
let translation = recognizer.translation(in: mapView)
if recognizer.view != nil {
let offsetX = translation.x * CGFloat(cosf(Float(rotateView))) - translation.y * CGFloat(sinf(Float(rotateView)))
let offsetY = translation.x * CGFloat(sinf(Float(rotateView))) + translation.y * CGFloat(cosf(Float(rotateView)))
mapView.center = CGPoint(x:mapView.center.x + offsetX * scaleView,
y:mapView.center.y + offsetY * scaleView)
}
recognizer.setTranslation(CGPoint(x: 0, y: 0), in: mapView)
}
@IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) {
if recognizer.view != nil {
setAnchor(point: recognizer.location(in: mapView))
mapView.transform = mapView.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
scaleView = recognizer.scale * scaleView
recognizer.scale = 1
}
}
@IBAction func handleRotate(recognizer : UIRotationGestureRecognizer) {
if recognizer.view != nil {
setAnchor(point: recognizer.location(in: mapView))
mapView.transform = mapView.transform.rotated(by: recognizer.rotation)
rotateView = rotateView + recognizer.rotation
recognizer.rotation = 0
}
}
private func setAnchor(point : CGPoint) {
let anchor = CGPoint(x: point.x / mapView.bounds.width, y: point.y / mapView.bounds.height)
mapView.layer.anchorPoint = CGPoint(x: anchor.x, y: anchor.y)
let translationX = (mapView.bounds.width * (anchor.x - anchorPoint.x)) * scaleView
let translationY = (mapView.bounds.height * (anchor.y - anchorPoint.y)) * scaleView
let offsetX = translationX * CGFloat(cosf(Float(rotateView))) - translationY * CGFloat(sinf(Float(rotateView)))
let offsetY = translationX * CGFloat(sinf(Float(rotateView))) + translationY * CGFloat(cosf(Float(rotateView)))
mapView.layer.position = CGPoint(x: mapView.layer.position.x + offsetX,
y: mapView.layer.position.y + offsetY)
anchorPoint = anchor
}
private func showAlert(title: String, message: String?, style: UIAlertControllerStyle = .alert) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: style)
let tryAgainAction = UIAlertAction(title: "Try again", style: .default) {
alertAction in
ApplicationManager.sharedInstance.onApplicationStart()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alertController.addAction(tryAgainAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func onOrientationChanged() {
self.mapView.setNeedsDisplay()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
此外,mapView的代码:
import UIKit
类MapView:UIView{
private var floor = Floor(walls: [], doors: [], beacons: [])
private let wallColor = UIColor.black
private let doorColor = UIColor.red
private let triangleColor = UIColor.red
private let perpendicularColor = UIColor.darkGray
private let doorLength = 3.0
private let beaconColor = UIColor.green
private let beaconNoActiveColor = UIColor(red: 20/255.0, green: 154.0/255.0, blue: 53.0/255.0, alpha: 1.0)
private let beaconFrameColor = UIColor.brown
private let lineWidthBeaconFrame:CGFloat = 0.25
private let beaconRadius: CGFloat = 5.0
private let userColor = UIColor.blue
private let userFrameColor = UIColor.brown
private let lineWidthUserFrame:CGFloat = 0.25
private let userRadius: CGFloat = 5.0
private let distanceBeaconColor = UIColor.clear
private let distanceBeaconFrameColor = UIColor.green
private let lineWidthOfDistanceFrame: CGFloat = 0.5
private let userRawRadius: CGFloat = 3.0
private let userRawColor = UIColor.darkGray
private let userRawFrameColor = UIColor.lightGray
private let lineWidthOfuserRawFrame: CGFloat = 0.8
private var beaconText: NSString = ""
private let textColor: UIColor = UIColor.red
private let textFont: UIFont = UIFont(name: "Helvetica Neue", size: 5)!
private var currentUserLocation = CurrentUserLocation()
private var beaconRangingData: [BeaconRangingPoint] = []
func setFloor (currentFloor: Floor) {
floor = currentFloor
}
func setUserPoint(currentUserPoint: CurrentUserLocation, beaconRangingData: [BeaconRangingPoint]) {
self.currentUserLocation = currentUserPoint
self.beaconRangingData = beaconRangingData
}
func dropPin(location: CGPoint) {
}
override func draw(_ rect: CGRect) {
let frameToDraw = CoordinatesConverter(boundsWidth: bounds.width, boundsHeight: bounds.height, paddingX: 5, paddingY: 5)
let mapWithScaleCoordinaates = frameToDraw.getSuitableCoordinates(floor: floor, currentUserLocation: currentUserLocation, beaconRangingData: beaconRangingData)
let lines = mapWithScaleCoordinaates.lines
let circles = mapWithScaleCoordinaates.circles
drawLines(lines: lines)
drawCircles(circles: circles)
}
private func drawLines(lines :[Line]) {
let wallPath = UIBezierPath()
let doorPath = UIBezierPath()
let trianglePath = UIBezierPath()
let perpendicularPath = UIBezierPath()
for line in lines {
if line.type == .wall {
wallPath.move(to: CGPoint(x: line.x1, y: line.y1))
wallPath.addLine(to: CGPoint(x: line.x2, y: line.y2))
wallColor.setStroke()
wallPath.stroke()
}
if line.type == .door {
doorPath.move(to: CGPoint(x: line.x1, y: line.y1))
doorPath.addLine(to: CGPoint(x: line.x2, y: line.y2))
doorPath.lineWidth = CGFloat(doorLength)
doorColor.setStroke()
doorPath.stroke()
}
if line.type == .triangle {
trianglePath.move(to: CGPoint(x: line.x1, y: line.y1))
trianglePath.addLine(to: CGPoint(x: line.x2, y: line.y2))
triangleColor.setStroke()
trianglePath.stroke()
}
if line.type == .perpendicular {
perpendicularPath.move(to: CGPoint(x: line.x1, y: line.y1))
perpendicularPath.addLine(to: CGPoint(x: line.x2, y: line.y2))
perpendicularColor.setStroke()
perpendicularPath.stroke()
}
}
}
private func drawCircles(circles: [Circle]) {
let layerViews = layer.sublayers
if layerViews != nil {
for view in layerViews! {
if type(of: view) === CAShapeLayer.self {
view.removeFromSuperlayer()
}
}
}
for circle in circles {
if type(of: circle) === BeaconCircle.self {
if (circle as! BeaconCircle).correctedDistance == 0 {
infoToDrawCircle(circle: circle, radius: beaconRadius, color: beaconNoActiveColor.cgColor, frameColor: beaconFrameColor.cgColor, frameWidth: lineWidthBeaconFrame)
drawBeaconText(circle: circle as! BeaconCircle)
} else {
infoToDrawCircle(circle: circle, radius: beaconRadius, color: beaconColor.cgColor, frameColor: beaconFrameColor.cgColor, frameWidth: lineWidthBeaconFrame)
drawBeaconText(circle: circle as! BeaconCircle)
}
if type(of: circle) === BeaconCircle.self && (circle as! BeaconCircle).correctedDistance != 0 {
infoToDrawCircle(circle: circle, radius: CGFloat((circle as! BeaconCircle).correctedDistance), color: distanceBeaconColor.cgColor, frameColor: distanceBeaconFrameColor.cgColor, frameWidth: lineWidthOfDistanceFrame)
// infoToDrawCircle(circle: circle, radius: CGFloat((circle as! BeaconCircle).notCorrectedDistance), color: UIColor.gray.cgColor, frameColor: distanceBeaconFrameColor.cgColor, frameWidth: lineWidthOfDistanceFrame)
}
} else if type(of: circle) === UserCircle.self {
infoToDrawCircle(circle: circle, radius: userRadius, color: userColor.cgColor, frameColor: userFrameColor.cgColor, frameWidth: lineWidthUserFrame)
} else if type (of: circle) === UserRawCircle.self {
infoToDrawCircle(circle: circle, radius: userRawRadius, color: userRawColor.cgColor, frameColor: userRawFrameColor.cgColor, frameWidth: lineWidthOfuserRawFrame)
} else {
Logger.logMessage(message: "incorrect circle type", level: .error)
break
}
}
}
private func drawBeaconText (circle: BeaconCircle) {
let attributes: NSDictionary = [
NSForegroundColorAttributeName: textColor,
NSFontAttributeName: textFont
]
let minor = circle.minor
let correctDistance = Int(round(100 * circle.correctDistanceForText) / 100)
let notCorrectDistance = Int(round(100 * circle.notCorrectDistanceForText) / 100)
beaconText = "m: \(minor), cd: \(correctDistance), nd: \(notCorrectDistance)" as NSString
if circle.x > Int((bounds.width - 50)) {
beaconText.draw(at: CGPoint(x: circle.x - 70, y: circle.y + 5), withAttributes: attributes as? [String : Any])
} else if circle.x < 20 {
beaconText.draw(at: CGPoint(x: circle.x + 5, y: circle.y + 5), withAttributes: attributes as? [String : Any])
} else {
beaconText.draw(at: CGPoint(x: circle.x + 6, y: circle.y + 5), withAttributes: attributes as? [String : Any])
}
}
private func infoToDrawCircle (circle: Circle, radius: CGFloat, color: CGColor, frameColor: CGColor, frameWidth: CGFloat) {
let center = CGPoint(x: circle.x, y: circle.y)
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 360, clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.fillColor = color
shapeLayer.lineWidth = frameWidth
shapeLayer.strokeColor = frameColor
layer.addSublayer(shapeLayer)
}
private var floor=floor(墙:[],门:[],信标:[])
私有let wallColor=UIColor.black
私人出租门颜色=UIColor.red
private let triangelecolor=UIColor.red
private let PerpenticalColor=UIColor.darkGray
私人出租门长度=3.0
私人出租beaconColor=UIColor.green
private let beaconNoActiveColor=UIColor(红色:20/255.0,绿色:154.0/255.0,蓝色:53.0/255.0,alpha:1.0)
private let beaconFrameColor=UIColor.brown
专用let线宽beaconframe:CGFloat=0.25
私人出租信标半径:CGFloat=5.0
私有let userColor=UIColor.blue
私有let userFrameColor=UIColor.brown
私有let lineWidthUserFrame:CGFloat=0.25
私有let userRadius:CGFloat=5.0
私人出租距离beaconcolor=UIColor.clear
私有let距离beaconframeColor=UIColor.green
距离框的专用let线宽:CGFloat=0.5
私有let userRawRadius:CGFloat=3.0
private let userRawColor=UIColor.darkGray
private let userRawFrameColor=UIColor.lightGray
素描框的专用let线宽:CGFloat=0.8
private-var-beaconText:NSString=“”
私有let textColor:UIColor=UIColor.red
私人出租文本字体:UIFont=UIFont(名称:“Helvetica Neue”,大小:5)!
私有变量currentUserLocation=currentUserLocation()
专用变量BeaconRangData:[BeaconRangPoint]=[]
功能设置楼层(当前楼层:楼层){
楼层=当前楼层
}
func setUserPoint(currentUserPoint:CurrentUserLocation,BeaconRangData:[BeaconRangPoint]){
self.currentUserLocation=currentUserPoint
self.beacrangingdata=beacrangingdata
}
func dropPin(位置:CGPoint){
}
重写函数绘图(rect:CGRect){
设frameToDraw=坐标变换器(boundsWidth:bounds.width,BoundsHigh:bounds.height,paddingX:5,paddingY:5)
让MapWithScaleCoordinates=frameToDraw.GetSuiteableCoordinates(楼层:楼层,currentUserLocation:currentUserLocation,BeaconRangData:BeaconRangData)
设lines=MapWithScaleCoordinates.lines
设圆=映射为calecordinates.circles
抽绳(线:线)
drawCircles(圆:圆)
}
专用func绘图线(线条:[线条]){
设wallPath=UIBezierPath()
让doorPath=UIBezierPath()
设TriangalPath=UIBezierPath()
设垂直路径=UIBezierPath()
排队{
如果line.type==.wall{
移动(到:CGPoint(x:line.x1,y:line.y1))
wallPath.addLine(到:CGPoint(x:line.x2,y:line.y2))
wallColor.setStroke()
wallPath.stroke()
}
如果line.type==.door{
门路径。移动(到:CGPoint(x:line.x1,y:line.y1))
doorPath.addLine(to:CGPoint(x:line.x2,y:line.y2))
doorPath.lineWidth=CGFloat(门长度)
doorColor.setStroke()
doorPath.stroke()
}
如果line.type==.triangle{
三角形路径移动(到:CGPoint(x:line.x1,y:line.y1))
三角形路径添加线(到:CGPoint(x:line.x2,y:line.y2))
三角形颜色设置行程()
trianglePath.stroke()
}
如果line.type==.vertical{
垂直路径移动(到:CGPoint(x:line.x1,y:line.y1))
垂直路径添加线(到:CGPoint(x:line.x2,y:line.y2))
垂直颜色。设置行程()
垂直路径笔划()
}
}
}
private func drawCircles(圆圈:[圆圈]){
让layerView=layer.sublayers
如果LayerView!=零{
在LayerView中查看{
如果类型(of:view)==CAShapeLayer.self{
view.removeFromSuperlayer()
}
}
}
圆圈中的圆圈{
如果类型(of:circle)==BeaconCircle.self{
if(圈为!BeaconCircle).correctedDistance==0{
infoToDrawCircle(圆:圆,半径:beaconRadius,颜色:beaconNoActiveColor.cgColor,框架颜色:beaconFrameColor.cgColor,框架宽度:线宽BeaConFrame)
drawBeaconText(圆圈:圆圈为!BeaconCircle)
}否则{
infoToDrawCircle(圆:圆,半径:beaconRadius,颜色:beaconColor.cgColor,帧颜色:beaconFrameColor.cgColor,帧宽度:线宽BeaConFrame)
drawBeaconText(圆圈:圆圈为!BeaconCircle)
}
如果类型(of:circle)==BeaconCircle.self&(圆为!BeaconCircle).correctedDistance!=0{
infoToDrawCircle(圆:圆,半径:CGFloat((圆为!BeaconCircle).correctedDistance),颜色:distanceBeaconColor.cgColor,frameColor:distanceBeaconFrameColor.cgColor,frameWidth:DistanceFrame的线宽)
//infoToDrawCircle(圆:圆,半径:CGFloat((圆为!BeaconCircle).notCorrectedDistance),颜色:UIColor.gray.cgColor,frameColor:distanceBeaconFrameColor.cgColor,frameWidth:DistanceFrame的线宽)
}
}如果类型(of:circle)==UserCircle.self,则为else{
infoToDrawCircle(圆:圆,半径:userRadius,颜色:userColor.cgColor,frameColor:userFrameColor.cgColor,frameWidth:lineWidthUserFrame)
}如果类型(of:circle)==UserRawCircle.self,则为else{
infoToDrawCircle(圆:圆,半径:userRawRadius,颜色:userRawColor.cgColor,frameColor:userRawFrameColor.cgColor,frameWidth:UserRawFrame的线宽)
}否则{
Logger.logMessage(消息:“不正确的圆圈类型”,级别:。错误)
打破
}
}
}
私有函数上下文(ci)