我在 MkMapView 上画线,我想以米为单位指定它们的宽度。
我试过这样的事情:
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>) overlay
{
if([overlay isKindOfClass:[MKPolyline class]])
{
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
double ppm = MKMapPointsPerMeterAtLatitude(myLatitude);
renderer.lineWidth = ppm * myMetersValue;
...
这会产生一条比 myMetersValue 宽得多的线,并且在我放大和缩小时它不会缩放。
ppm 保持恒定在大约。9.49 即使我放大和缩小地图。我已经验证 myLatitude 是一个有效的纬度(大约 45 度)。我已经验证 myMetersValue 是一个合理的 #(大约 18m)。
(编辑)
我发现 MKMapPointsPerMeterAtLatitude 返回的 MapPoints 不是屏幕点,所以我不能使用那个函数。
所以我的基本问题是如何将米转换为 mkMapView 中的屏幕点。更简洁地说,如何在我的代码中获得 ppm 的值?我试过这个(在SO的其他地方找到):
MKCoordinateRegion myRegion = MKCoordinateRegionMakeWithDistance(mapView.centerCoordinate, 400, 0);
CGRect myRect = [mapView convertRegion: myRegion toRectToView: nil];
double ppm = myRect.size.width / 400.0;
那没有用。
然后我尝试了这个:
CLLocationCoordinate2D l1 = [mapView convertPoint:CGPointMake(0,0) toCoordinateFromView:mapView];
CLLocation *ll1 = [[CLLocation alloc] initWithLatitude:l1.latitude longitude:l1.longitude];
CLLocationCoordinate2D l2 = [mapView convertPoint:CGPointMake(0,500) toCoordinateFromView:mapView];
CLLocation *ll2 = [[CLLocation alloc] initWithLatitude:l2.latitude longitude:l2.longitude];
double ppm = 500.0 / [ll1 distanceFromLocation:ll2];
这里的想法是获取相隔 500 个屏幕点的两个点的纬度/经度。然后得到它们之间的距离(以米为单位),这样我就可以计算 ppm。这种工作,但看起来结果 ppm 不太正确,所以我不相信这是正确的。此外,当我缩放地图时,地图上的现有线条不会重新渲染,因此缩放后保持相同的宽度(但这是一个不同的问题)。
(编辑)
现在看起来我对 ppm 的计算是正确的。问题是在用户完成缩放之前调用了渲染器,因此线条不会以最终缩放比例渲染。一旦确定了最终缩放比例,当我强制重新渲染时,ppm 是正确的并且我的代码可以工作。