在MKMapView上绘制Great Circle叠加线

如何解决在MKMapView上绘制Great Circle叠加线

| 我正在尝试在MKMapView的两个纬度/经度点之间绘制大圆线。这条线将显示为圆形(地球仪上的“直线”线),并在此处最好地显示。实际上,这个非常奇怪的WordPress网站似乎开始确切地描述了如何执行此操作,但是在最初的几个步骤后突然终止了。 阅读苹果的文档,我看到了   在iOS 4.0及更高版本中,您也可以使用投影地图坐标代替区域来指定一些值。将地球仪的弯曲表面投影到平坦表面上时,会得到地图的二维版本,其中经度线看起来是平行的。使用MKMapPoint,MKMapSize和MKMapRect数据类型指定此地图上的位置和距离。您可以使用这些数据类型来指定地图的可见区域以及指定叠加层的位置。 我不确定如何将其应用于Great Circle叠加层。有人可以帮忙吗?     

解决方法

我已经实现了此目的,以便使用MKPolyline为在两个机场之间飞行的飞机绘制一条大的环形路线。
+ (void)createGreatCircleMKPolylineFromPoint:(CLLocationCoordinate2D)point1 
                                     toPoint:(CLLocationCoordinate2D)point2
                                  forMapView:(MKMapView*)mapView
{
double lat1 = point1.latitude;
double lon1 = point1.longitude;
double lat2 = point2.latitude;
double lon2 = point2.longitude;
lat1 = lat1 * (PI/180);
lon1 = lon1 * (PI/180);
lat2 = lat2 * (PI/180);
lon2 = lon2 * (PI/180);
double d = 2 * asin( sqrt(pow(( sin( (lat1-lat2)/2) ),2) + cos(lat1) * cos(lat2) * pow(( sin( (lon1-lon2)/2) ),2)));
int numsegs = 100;
CLLocationCoordinate2D *coords = malloc(sizeof(CLLocationCoordinate2D) * numsegs);
double f = 0.0;
for(int i=1; i<=numsegs; i++)
{
    f += 1.0 / (float)numsegs;
    double A=sin((1-f)*d)/sin(d);
    double B=sin(f*d)/sin(d);
    double x = A*cos(lat1) * cos(lon1) +  B * cos(lat2) * cos(lon2);
    double y = A*cos(lat1) * sin(lon1) +  B * cos(lat2) * sin(lon2);
    double z = A*sin(lat1)           +  B*sin(lat2);
    double latr=atan2(z,sqrt(pow(x,2) + pow(y,2) ));
    double lonr=atan2(y,x);
    double lat = latr * (180/PI);
    double lon = lonr * (180/PI);
    //        NSLog(@\"lat: %f lon: %f\",lat,lon);
    CLLocationCoordinate2D loc = CLLocationCoordinate2DMake(lat,lon);
    coords[i - 1] = loc;
}

//check for circling west to east. If the plane is crossing 180,we need
//to draw two lines or else the polyline connects the dots and draws a straight
//line all the way across the map.
CLLocationCoordinate2D prevCoord;
BOOL twoLines = NO;
int numsegs2 = 0;
CLLocationCoordinate2D *coords2;

for(int i=0; i<numsegs; i++)
{
    CLLocationCoordinate2D coord = coords[i];
    if(prevCoord.longitude < -170 && prevCoord.longitude > -180  && prevCoord.longitude < 0 
       && coord.longitude > 170 && coord.longitude < 180 && coord.longitude > 0)
    {
        twoLines = YES;
        coords2 = malloc(sizeof(CLLocationCoordinate2D) * (numsegs - i));
        numsegs2 = numsegs - i;
        for(int j=0; j<numsegs2; j++)
        {
            coords2[j] = coords[i + j];
        }
        break;
    }
    prevCoord = coord;
}

//remove any previously added overlays
[mapView removeOverlays:mapView.overlays];

if(twoLines)
{
    MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:numsegs - numsegs2];
    free(coords);
    [mapView addOverlay:polyline];

    MKPolyline *polyline2 = [MKPolyline polylineWithCoordinates:coords2 count:numsegs2];
    free(coords2);
    [mapView addOverlay:polyline2];
}
else
{
    MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:numsegs];
    free(coords);
    [mapView addOverlay:polyline];
}

}
您现在已经创建了叠加层,现在只需要在mapView:viewForOverlay中提供MKOverlayView。
- (MKOverlayView*)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
    MKPolyline *polyline = (MKPolyline*)overlay;
    MKPolylineView *view = [[[MKPolylineView alloc] initWithPolyline:polyline] autorelease];
    //choose your line params here
    view.lineWidth = 2;
    view.fillColor = [UIColor blueColor];
    return view;
}
希望这可以帮助。 截图http://s1-03.twitpicproxy.com/photos/large/489178500.png     ,这是游戏的后期,但值得一提的是
MKGeodesicPolyline
,它是iOS 7.0以来的新功能,“可追踪沿着地球表面的最短路径”。 有了它,创建和添加Geodesic Polyline类型的
MKPolylineOverlay
变得很简单。
points = [CLLocationCoordinate2DMake(27.123,85.765),CLLocationCoordinate2DMake(41.444,106.987)]
geodesic = MKGeodesicPolyline(coordinates: points,count: 2)
mapView.add(geodesic)
记住要包括渲染器并给mapView委托:
//MARK: - MKMapView Delegate Method
func mapView(_ mapView: MKMapView,rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKGeodesicPolyline {
        let polylineRenderer = MKPolylineRenderer(overlay: overlay)
        polylineRenderer.strokeColor = UIColor.white
        polylineRenderer.lineWidth = 2.5
        return polylineRenderer
    }
}
    ,这可以通过创建MKOverlayPathView类的子类来完成。您需要重写(void)createPath方法,并且基本上可以使用UIBezierPath创建弧,或直接将弧创建为路径,这是可行的,但我还没有完成。 在方法上定义路径后,需要使用新创建的路径设置类的path属性。这样,路径的渲染将自动完成。 希望这可以帮助。     ,numsegs参数应根据地图缩放级别和两点的距离而改变。两点的经/纬坐标可以转换为像素坐标。因此,可以将numsegs参数视为像素差异的函数。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?