xcode 向 MKMapView 添加多个叠加层
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10924874/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding multiple overlays to MKMapView
提问by random
I am having some trouble understanding how to add multiple overlays to MKMapView.
我在理解如何向 MKMapView 添加多个叠加层时遇到了一些麻烦。
I have an array routes tracked. The routes tracked are arrays of CLLocations. So I have an array of arrays.
我跟踪了一个数组路由。跟踪的路线是 CLLocations 数组。所以我有一个数组数组。
I am able to take one route and draw it on the map view. However, I need to draw ALL the routes onto the map view.
我可以选择一条路线并将其绘制在地图视图上。但是,我需要将所有路线绘制到地图视图上。
So here is how I go about creating the MKPolyline for 1 route:
下面是我为 1 条路线创建 MKPolyline 的方法:
-(void) loadRoute
{
//So we grab an array that holds all the locations of one route.
NSArray *locations = [[NSArray alloc] initWithArray:[routesArray objectAtIndex:0]];
// while we create the route points, we will also be calculating the bounding box of our route
// so we can easily zoom in on it.
MKMapPoint northEastPoint;
MKMapPoint southWestPoint;
// create a c array of points.
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) *[locations count]);
for(int idx = 0; idx < [locations count]; idx++)
{
CLLocation *tempLoc = (CLLocation*)[locations objectAtIndex:idx];
CLLocationDegrees latitude = tempLoc.coordinate.latitude;
CLLocationDegrees longitude = tempLoc.coordinate.longitude;
// create our coordinate and add it to the correct spot in the array
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
MKMapPoint point = MKMapPointForCoordinate(coordinate);
// if it is the first point, just use them, since we have nothing to compare to yet.
if (idx == 0) {
northEastPoint = point;
southWestPoint = point;
}
else
{
if (point.x > northEastPoint.x)
northEastPoint.x = point.x;
if(point.y > northEastPoint.y)
northEastPoint.y = point.y;
if (point.x < southWestPoint.x)
southWestPoint.x = point.x;
if (point.y < southWestPoint.y)
southWestPoint.y = point.y;
}
pointArr[idx] = point;
}
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:[locations count]];
//Zoom in to fit route on screen
_routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);
// clear the memory allocated earlier for the points
free(pointArr);
}
Here is the MapKit delegate call that returns the overlay:
这是返回叠加层的 MapKit 委托调用:
#pragma mark MKMapViewDelegate
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKOverlayView* overlayView = nil;
if(overlay == self.routeLine)
{
//if we have not yet created an overlay view for this overlay, create it now.
if(nil == self.routeLineView)
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.fillColor = [UIColor redColor];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 3;
}
overlayView = self.routeLineView;
}
return overlayView;
}
So all the code given above works fine. I can't figure out how to load more overlays to show the other routes.
所以上面给出的所有代码都可以正常工作。我不知道如何加载更多叠加层以显示其他路线。
I thought that maybe in loadRoute method, running through all the routes and creating a MKOverlayView for each one. Storing all those MKOverlayView in an array then doing: [self.mapView addOverlays:array];
我认为可能在 loadRoute 方法中,遍历所有路由并为每个路由创建一个 MKOverlayView。将所有这些 MKOverlayView 存储在一个数组中,然后执行: [self.mapView addOverlays:array];
But it doesn't work. The problem is that in the delegate method I somehow need to know which overlay to return.
但它不起作用。问题是在委托方法中,我需要知道要返回哪个叠加层。
So if I could do something along the lines of:
所以,如果我可以做一些类似的事情:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
int tag = overlay.tag;
return (MKOverlayView*)[arrayOfViews objectAtIndex:tag];
}
it would work fine. But unfortunately it doesn't work like that :(
它会正常工作。但不幸的是它不能那样工作:(
Any help would be very much appreciated!
任何帮助将不胜感激!
EDIT:
编辑:
I use this in ViewDidLoad to add the overlay:
我在 ViewDidLoad 中使用它来添加叠加层:
[self loadRoute];
// add the overlay to the map
if (nil != self.routeLine) {
[self.mapView addOverlay:self.routeLine];
}
// zoom in on the route.
[self zoomInOnRoute];
This is in the header:
这是在标题中:
// the data representing the route points.
MKPolyline* _routeLine;
// the view we create for the line on the map
MKPolylineView* _routeLineView;
// the rect that bounds the loaded points
MKMapRect _routeRect;
采纳答案by random
The routeLine
and routeLineView
variables can only point to one overlay and overlay view at a time so you would theoretically need an array of such variables.
该routeLine
和routeLineView
变量只能指向一个覆盖和叠加视图在一个时间,所以你在理论上需要这样的数组变量。
However, based on the code shown, you don't need to keep references to these in the first place.
但是,根据显示的代码,您不需要首先保留对这些的引用。
I suggest removing the routeLine
and routeLineView
variables.
我建议删除routeLine
和routeLineView
变量。
Then you just create an overlay object locally and in viewForOverlay
return a view for the requested overlay
parameter.
然后,您只需在本地创建一个覆盖对象,并viewForOverlay
返回请求overlay
参数的视图。
In the loadRoute
method, you can loop through the routesArray
and for each route, create a local overlay object, and call addOverlay
on it.
在该loadRoute
方法中,您可以遍历routesArray
每个路由的和 ,创建一个本地覆盖对象,并对其进行调用addOverlay
。
There's also an easier way to construct a map rect that bounds all the routes so you can set the map's region to show them all.
还有一种更简单的方法来构建一个地图矩形,它限制了所有的路线,这样你就可以设置地图的区域来显示它们。
Example:
例子:
-(void) loadRoute
{
_routeRect = MKMapRectNull;
for (int raIndex = 0; raIndex < routesArray.count; raIndex++)
{
//So we grab an array that holds all the locations of one route.
NSArray *locations = [[NSArray alloc] initWithArray:
[routesArray objectAtIndex:raIndex]];
//note we are getting object at raIndex (not 0) above
//...no change to existing code here...
//self.routeLine = [MKPolyline polylineWithPoints:pointArr count:[locations count]];
//replace above line with this...
MKPolyline *pl = [MKPolyline polylineWithPoints:pointArr count:[locations count]];
[mapView addOverlay:pl];
//Zoom in to fit route on screen
//_routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);
//replace above line with this to create a rect around ALL routes...
if (MKMapRectIsNull(_routeRect))
_routeRect = pl.boundingMapRect;
else
_routeRect = MKMapRectUnion(_routeRect, pl.boundingMapRect);
// clear the memory allocated earlier for the points
free(pointArr);
}
}
In viewDidLoad
, just call loadRoute
and don't call addOverlay
.
在 中viewDidLoad
,只打电话loadRoute
,不要打电话addOverlay
。
The viewForOverlay
method becomes much simpler:
该viewForOverlay
方法变得简单多了:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *pv = [[MKPolylineView alloc] initWithPolyline:overlay];
pv.fillColor = [UIColor redColor];
pv.strokeColor = [UIColor redColor];
pv.lineWidth = 3;
return pv;
}
By the way, in loadRoute
, this line:
顺便说一句,在loadRoute
,这一行:
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) *[locations count]);
should be:
应该:
MKMapPoint* pointArr = malloc(sizeof(MKMapPoint) *[locations count]);
It should use the size of MKMapPoint
(not CLLocationCoordinate2D
).
They are not the same thing (even though the structs happen to be the same byte size).
它应该使用MKMapPoint
(not CLLocationCoordinate2D
)的大小。
它们不是一回事(即使结构恰好是相同的字节大小)。