用箭头替换GMSMapView中的蓝点 - Swift [英] Replace blue dot in GMSMapView by an arrow - Swift

查看:299
本文介绍了用箭头替换GMSMapView中的蓝点 - Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将Google SDK用于应用程序iOS8(Swift)。
我想根据智能手机的方向,通过箭头旋转来替换GMSMapView中的蓝点(我的位置)。
我该怎么做?

编辑:

设法看到我的箭头,但我有三个问题:



1:箭头被切掉,我没有找到放大的区域



2:箭头的位置并不在我的位置我通过删除0,5来解决此问题:

  CGContextTranslateCTM(context,size.width,size.height)

3:箭头的方向与原始对称我通过在度数之前添加 - 来解决此问题:

  CGContextRotateCTM(context,CGFloat(DegreesToRadians(Double(-degrees)))))

如何解决这些问题?

解决方案

如果您使用Google映射iOS SDK,似乎有无法替换默认的用户位置图标。然而,默认图标已经有一个箭头来指示用户将要前进的方向(只需调用 mapView.myLocationEnabled = true )。



解决方法是在用户的当前位置放置一个标记,然后根据标题更改标记图像。


示例代码(

  func RadiansToDegrees(弧度:双精度) - > Double {
返回弧度* 180.0 / M_PI
}

func DegreesToRadians(度数:双精度) - > Double {
return degrees * M_PI / 180.0
}

var GeoAngle = 0.0
var locationManager = CLLocationManager()
var marker = GMSMarker()

覆盖func viewDidLoad(){
super.viewDidLoad()
//加载视图后通常从nib执行任何其他设置。

var camera = GMSCameraPosition.cameraWithLatitude(-33.86,
longitude:151.20,zoom:6)
var mapView = GMSMapView.mapWithFrame(CGRectZero,camera:camera)
self.view = mapView

marker.map = mapView
$ b $ locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
}

func locationManager(manager:CLLocationManager !, didUpdateToLocation newLocation:CLLocation !, fromLocation oldLocation:CLLocation!){
var camera = GMSCameraPosition.cameraWithLatitude(newLocation.coordinate.latitude,
longitude:newLocation.coordinate.longitude,zoom:15)
(self.view作为GMSMapView).animateToCameraPosition(camera)

GeoAngle = self.setLatLonForDistanceAndAngle(newLocation)
marker.position = ne wLocation.coordinate
}

func locationManager(manager:CLLocationManager !, didUpdateHeading newHeading:CLHeading!){
var direction = -newHeading.trueHeading as Double
marker。 icon = self.imageRotatedByDegrees(CGFloat(direction),image:UIImage(named:arrow.png)!)
}


func imageRotatedByDegrees(degrees:CGFloat,image :UIImage) - > UIImage {
var size = image.size

UIGraphicsBeginImageContext(size)
var context = UIGraphicsGetCurrentContext()

CGContextTranslateCTM(context,0.5 * size。宽度,0.5 * size.height)
CGContextRotateCTM(context,CGFloat(DegreesToRadians(Double(degrees))))

image.drawInRect(CGRect(origin:CGPoint(x:-size。宽度* 0.5,y:-size.height * 0.5),size:size))
var newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return newImage
}

func setLatLonForDistanceAndAngle(userLocation:CLLocation) - > Double {
var lat1 = DegreesToRadians(userLocation.coordinate.latitude)
var lon1 = DegreesToRadians(userLocation.coordinate.longitude)

var lat2 = DegreesToRadians(37.7833);
var lon2 = DegreesToRadians(-122.4167);

var dLon = lon2 - lon1;

var y = sin(dLon)* cos(lat2);
var x = cos(lat1)* sin(lat2) - sin(lat1)* cos(lat2)* cos(dLon);
var radiansBearing = atan2(y,x);
if(radiansBearing <0.0)
{
radiansBearing + = 2 * M_PI;
}

return radiansBearing;
}

关键步骤是根据来自 func locationManager(manager:CLLocationManager !, didUpdateHeading newHeading:CLHeading!) method。



您还需要确保添加 NSLocationAlwaysUsageDescription NSLocationWhenInUseUsageDescription info.plist 文件中。




I use the Google SDK for an application iOS8 (Swift). I want to replace the blue dot (my location) in a GMSMapView by an arrow witch rotate according to the orientation of the smartphone. How can I do that?

EDIT :

I managed to see my arrow but I have three problems :

1 : The arrow is cut and I do not find as enlarge the area

2 : The position of the arrow is not exactly on my location I solve this problem by delete "0,5" :

CGContextTranslateCTM(context, size.width, size.height)

3 : The direction of the arrow is symmetrical to the original I solve this problem by adding "-" before "degrees" :

CGContextRotateCTM(context, CGFloat(DegreesToRadians(Double(-degrees))))

How to solve these problems ?

解决方案

If you are using Google Maps iOS SDK, seems there is no way to replace the default user location icon. However the default icon already has an arrow to indicate which direction user is going (simply call mapView.myLocationEnabled = true).

A workaround is to put a marker on user's current position, and change the marker image based on heading.

Sample Code (the full source code):

    func RadiansToDegrees(radians: Double) -> Double {
        return radians * 180.0/M_PI
    }

    func DegreesToRadians(degrees: Double) -> Double {
        return degrees * M_PI / 180.0
    }

    var GeoAngle = 0.0
    var locationManager = CLLocationManager()
    var marker = GMSMarker()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var camera = GMSCameraPosition.cameraWithLatitude(-33.86,
            longitude: 151.20, zoom: 6)
        var mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
        self.view = mapView

        marker.map = mapView

        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
        locationManager.startUpdatingLocation()
        locationManager.startUpdatingHeading()
    }

    func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
        var camera = GMSCameraPosition.cameraWithLatitude(newLocation.coordinate.latitude,
            longitude: newLocation.coordinate.longitude, zoom: 15)
        (self.view as GMSMapView).animateToCameraPosition(camera)

        GeoAngle = self.setLatLonForDistanceAndAngle(newLocation)
        marker.position = newLocation.coordinate
    }

    func locationManager(manager: CLLocationManager!, didUpdateHeading newHeading: CLHeading!) {
        var direction = -newHeading.trueHeading as Double
        marker.icon = self.imageRotatedByDegrees(CGFloat(direction), image: UIImage(named: "arrow.png")!)
    }


    func imageRotatedByDegrees(degrees: CGFloat, image: UIImage) -> UIImage{
        var size = image.size

        UIGraphicsBeginImageContext(size)
        var context = UIGraphicsGetCurrentContext()

        CGContextTranslateCTM(context, 0.5*size.width, 0.5*size.height)
        CGContextRotateCTM(context, CGFloat(DegreesToRadians(Double(degrees))))

        image.drawInRect(CGRect(origin: CGPoint(x: -size.width*0.5, y: -size.height*0.5), size: size))
        var newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }

    func setLatLonForDistanceAndAngle(userLocation: CLLocation) -> Double {
        var lat1 = DegreesToRadians(userLocation.coordinate.latitude)
        var lon1 = DegreesToRadians(userLocation.coordinate.longitude)

        var lat2 = DegreesToRadians(37.7833);
        var lon2 = DegreesToRadians(-122.4167);

        var dLon = lon2 - lon1;

        var y = sin(dLon) * cos(lat2);
        var x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
        var radiansBearing = atan2(y, x);
        if(radiansBearing < 0.0)
        {
            radiansBearing += 2*M_PI;
        }

        return radiansBearing;
    }

The key step is to change image based on the degree come from the func locationManager(manager: CLLocationManager!, didUpdateHeading newHeading: CLHeading!) method.

You also need to make sure to add NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription in your info.plist file.

这篇关于用箭头替换GMSMapView中的蓝点 - Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆