简体   繁体   English

iOS MKMapView快速重绘地图上的叠加层

[英]iOS MKMapView quickly redraw overlay on map

I have a triangle polygon on a MKMapView that I would like to redraw very quickly or to anchor in a specific position on the phone. 我在MKMapView上有一个三角形多边形,我想非常快速地重绘或将其锚定在手机上的特定位置。

This polygon will always point to the top of the phone but the map itself will spin to supplied headings. 该多边形将始终指向手机的顶部,但地图本身将旋转至提供的标题。 Currently the only way I have come up with is to remove the overlay and then re-add it. 目前,我想出的唯一方法是删除叠加层,然后重新添加它。 The problem with this is that it is very choppy. 问题在于它非常不连贯。

The next idea I had was to just add a triangle image over the map and resize the map as needed this triangle image be an accurate visualization of what the polygon would be when added as a map overlay. 我的下一个想法是仅在地图上添加一个三角形图像,然后根据需要调整地图的大小。此三角形图像可以准确地可视化多边形作为地图叠加层添加时的外观。 This almost works but it isn't very accurate. 几乎可以工作,但不是很准确。 For some reason it almost never responds to changes in the latitude zoom level and some other issues. 由于某种原因,它几乎永远不会响应纬度缩放级别的变化和其他一些问题。

My method for this is: 我的方法是:

- (void)setMapVisibleRect {
    //we have to mock the heading to 0 so that the distances show up in lat/long correctly
    //create a new instance of the cone model with a fake heading of 0 for calculations
    ConePolygonModel *conePolygonModel = [[ConePolygonModel alloc] init:[self.userLocationModel getLocation].coordinate
                                                            withHeading:0
                                                  withLatLongMultiplier:[self.conePolygonModel getLatLongMultiplier]
                                                 withDistanceMultiplier:[self.conePolygonModel getDistanceMultiplier]];
    //reset the map heading to 0
    [self.mapView.camera setHeading:0];

    //top left setup
    CLLocationCoordinate2D topLeftCoordinate;
    topLeftCoordinate.latitude = [[[conePolygonModel getXCoordinates] objectAtIndex:1] doubleValue];
    topLeftCoordinate.longitude = [[[conePolygonModel getYCoordinates] objectAtIndex:1] doubleValue];

    CLLocation *topLeftLocation = [[CLLocation alloc] initWithLatitude:topLeftCoordinate.latitude longitude:topLeftCoordinate.longitude];

    //top right setup
    CLLocationCoordinate2D topRightCoordinate;
    topRightCoordinate.latitude = [[[conePolygonModel getXCoordinates] objectAtIndex:2] doubleValue];
    topRightCoordinate.longitude = [[[conePolygonModel getYCoordinates] objectAtIndex:2] doubleValue];

    CLLocation *topRightLocation = [[CLLocation alloc] initWithLatitude:topRightCoordinate.latitude longitude:topRightCoordinate.longitude];

    //center setup
    CLLocationCoordinate2D topCenterCoordinate = [conePolygonModel midpointBetweenCoordinate:topLeftCoordinate andCoordinate:topRightCoordinate];

    CLLocation *topCenterLocation = [[CLLocation alloc] initWithLatitude:topCenterCoordinate.latitude longitude:topCenterCoordinate.longitude];

    //set distances
    CLLocationDistance latitudeDistance = [topLeftLocation distanceFromLocation:topRightLocation];
    CLLocationDistance longitudeDistance = [topCenterLocation distanceFromLocation:[self.userLocationModel getLocation]];

    //set the map zoom
    NSLog(@"zoom levels: %f %f", latitudeDistance, longitudeDistance);
    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance([self.userLocationModel getLocation].coordinate, latitudeDistance, longitudeDistance);
    [self.mapView setRegion:viewRegion];

    //move the map to the actual heading
    [self.mapView.camera setHeading:self.currentHeading];
}

Is there a way to keep an overlay always pointing to the top of the screen regardless of the map rotation? 有没有一种方法可以使叠加层始终指向屏幕顶部,而与地图旋转无关? The zooming of the map so that the overlay would always take up the same size on the screen would also be nice but it is not as important as the other point. 缩放地图以使覆盖层始终占据屏幕上相同的大小也是不错的选择,但它不如其他点重要。

Try implementing this as an MKAnnotationView instead of an overlay, since you want the triangle to always have the same size and orientation, but still be attached to a specific point in the map's coordinate system. 尝试将其实现为MKAnnotationView而不是叠加层,因为您希望三角形始终具有相同的大小和方向,但仍要附加到地图坐标系中的特定点。

The simplest way to do this would be to create a PNG file and assign a UIImage of it to the image property of an MKAnnotationView in your mapView:viewForAnnotation: delegate method. 最简单的方法是创建一个PNG文件,并将其UIImage分配给mapView:viewForAnnotation:委托方法中MKAnnotationViewimage属性。 Alternatively, you could use Core Graphics to programmatically draw the triangle and turn it into a UIImage, at runtime. 或者,您可以使用Core Graphics在运行时以编程方式绘制三角形并将其变成UIImage。 You can render the image using Core Graphics once and keep a reference to the UIImage object so you aren't redrawing it every time viewForAnnotation is called. 您可以使用Core Graphics渲染一次图像,并保留对UIImage对象的引用,这样就不必在每次调用viewForAnnotation时都重新绘制它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM