是否有 iOS API 用于处理地图上的区域并计算交叉点、面积等?

发布于 2024-10-30 22:21:06 字数 304 浏览 3 评论 0原文

我想在采取困难的方式之前我应该​​先问这个问题。我在 Google 和 StackOverflow 上搜索过,但没有找到任何东西。 MapKit 擅长在 MKMapView 上绘制区域形状,而 CoreLocation 擅长告诉您从 CLLocation 到 CLLocation 的直线距离,但这两者都不是我所需要的。

我基本上希望能够在地图上放置一个半径为 10 米的点,并知道那里是否已有任何东西(半径也为 10m),并且会与第二个放置的东西的区域相交。我希望能够获得所有这些点的总面积(以平方米为单位),这很容易,但需要对重叠圆进行校正。

谢谢你的帮助。

I figured I would ask this before doing it the hard way. I've Googled and StackOverflowed around and can't find anything. MapKit is good at drawing region shapes on an MKMapView, and CoreLocation is good at telling you straight distance from CLLocation to CLLocation, but neither is exactly what I need.

I basically want to be able to drop a point on a map with a 10 meter radius, and know if there's anything already there (which would also have a 10m radius) and would intersect the area of the second dropped thing. I want to be able to get a total area of all of these points in square meters, which is easy, but with correction for overlapping circles.

Thanks for your help SO.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

客…行舟 2024-11-06 22:21:06

您需要查看一些资源。

首先,Mapkit 有一些用于处理 MKMapRect 结构的辅助函数。它们将帮助您在区域和 MKMapRect 等之间进行转换。在这里查看它们:
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKitFunctionsReference/Reference/reference.html%23//apple_ref/doc/uid/TP40008209

二、要做的您想要进行的几何计算(半径、面积等...)您可能需要这样:http://trac.osgeo.org/geos/

很难为 iOS 编译,但可以做到。编译它的一个好地方是 spaceite 项目。 Spatialite 依赖于 geos,人们已经为 iOS 编译了 Spatialite。参见这里:
如何为 iOS 编译 Spatialite

[编辑]
实际上,再次阅读您的问题后,您可能只想使用 Spatialite 而不必担心 geos。您必须将数据存储在设备上的数据库中。这样做将允许您构建类似 SQL 的查询来回答您提出的问题。

There are a couple resources you will want to look at.

First, Mapkit has some helper functions for working with MKMapRect structures. They will help you convert between regions and MKMapRects and so forth. See them here:
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKitFunctionsReference/Reference/reference.html%23//apple_ref/doc/uid/TP40008209

Second, to do the geometry calculations you want to do (radius, area, etc...) you probably want this: http://trac.osgeo.org/geos/

It's hard to get compiled for iOS, but it can be done. A good place to look at getting it compiled would be with the spatialite project. Spatialite depends on geos and people have compiled spatialite for iOS. See here:
how to compile spatialite for iOS

[Edit]
Actually, after reading your question once more, you might just want to use Spatialite and not worry about geos alone. You will have to store your data in a database on the device. Doing so will allow you to construct SQL like queries that will answer the questions you are asking.

神经大条 2024-11-06 22:21:06

我编写了这个函数,它采用两个圆的中心 x、y 和半径并返回相交面积。

public func circlesIntesectionArea(x1 x1: Double, y1: Double, r1: Double, x2: Double, y2: Double, r2: Double) -> Double {

    let d: Double = sqrt( pow(x1 - x2, 2) + pow(y1 - y2, 2) ) // distance between circles center

    let dd: Double = pow(d, 2)
    let rr1: Double = pow(r1, 2)
    let rr2: Double = pow(r2, 2)

    if d > r2 + r1 { return 0.0 } // no overlap
    if d <= abs(r1 - r2) {
        if r1 >= r2 { return M_PI * rr2 } //Circle2 inside circle1
        else { return M_PI * rr1 } //Circle1 inside circle2
    } else {
        let phi: Double = acos((dd + rr1 - rr2) / (2 * r1 * d)) * 2; // circle1 sector angle
        let area1: Double = (phi * rr1)/2 - (rr1 * sin(phi))/2; // sector1 area - triangle1 area

        let theta: Double = acos((dd + rr2 - rr1) / (2 * r2 * d)) * 2; // circle2 sector center angle
        let area2: Double = (theta * rr2)/2 - (rr2 * sin(theta))/2; // sector2 area - triangle2 area

        let intersectionArea: Double = area1 + area2;
        return isnan(intersectionArea) ? 0.0 : intersectionArea; //isnan == no overlap
    }
}

这里的半径不能以米或英里为单位,因此,如果您有一个circularRegion,则必须将其转换为 MKCooperativeRegion:

let region1 = MKCoordinateRegionMakeWithDistance(circularRegion.center, circularRegion.radius, circularRegion.radius)

然后:

if circlesIntesectionArea(x1: region1.center.longitude, y1: region1.center.latitude, r1: region1.span.latitudeDelta,
                          x2: region2.center.longitude, y2: region2.center.latitude, r2: region2.span.latitudeDelta) == 0.0 {
    print("No overlapping")
} else {
    print("Overlapping")
}

我知道这是一个老问题,但可能有人会发现这很有用......

I wrote this function that takes center x, y and radius for two circles and return the intersection area.

public func circlesIntesectionArea(x1 x1: Double, y1: Double, r1: Double, x2: Double, y2: Double, r2: Double) -> Double {

    let d: Double = sqrt( pow(x1 - x2, 2) + pow(y1 - y2, 2) ) // distance between circles center

    let dd: Double = pow(d, 2)
    let rr1: Double = pow(r1, 2)
    let rr2: Double = pow(r2, 2)

    if d > r2 + r1 { return 0.0 } // no overlap
    if d <= abs(r1 - r2) {
        if r1 >= r2 { return M_PI * rr2 } //Circle2 inside circle1
        else { return M_PI * rr1 } //Circle1 inside circle2
    } else {
        let phi: Double = acos((dd + rr1 - rr2) / (2 * r1 * d)) * 2; // circle1 sector angle
        let area1: Double = (phi * rr1)/2 - (rr1 * sin(phi))/2; // sector1 area - triangle1 area

        let theta: Double = acos((dd + rr2 - rr1) / (2 * r2 * d)) * 2; // circle2 sector center angle
        let area2: Double = (theta * rr2)/2 - (rr2 * sin(theta))/2; // sector2 area - triangle2 area

        let intersectionArea: Double = area1 + area2;
        return isnan(intersectionArea) ? 0.0 : intersectionArea; //isnan == no overlap
    }
}

Radius can't be in meters or miles here, so, if you have a circularRegion you have to convert it to MKCoordinateRegion:

let region1 = MKCoordinateRegionMakeWithDistance(circularRegion.center, circularRegion.radius, circularRegion.radius)

Then:

if circlesIntesectionArea(x1: region1.center.longitude, y1: region1.center.latitude, r1: region1.span.latitudeDelta,
                          x2: region2.center.longitude, y2: region2.center.latitude, r2: region2.span.latitudeDelta) == 0.0 {
    print("No overlapping")
} else {
    print("Overlapping")
}

I know this is an old question but may be someone will find this useful anyway...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文