我正在尝试查找给定点(CLLocationCoordinate2D
)是否在Polygon NSManagedObject中。
我的Polygon对象定义为:
public class Polygon: NSManagedObject {
@NSManaged var points: NSOrderedSet?
@NSManaged var centroid: Point?
@NSManaged var computed : NSNumber!
}
Point对象:
public class Point: NSManagedObject {
@NSManaged var longitude: NSNumber!
@NSManaged var latitude: NSNumber!
}
我当前的方法使用它来为Polygon
对象创建谓词:
public static func nearbyPredicate(offset offset: Double, nearLocation location: CLLocationCoordinate2D) -> NSPredicate {
let maxLat = location.latitude + offset
let minLat = location.latitude - offset
let maxLong = location.longitude - offset
let minLong = location.longitude + offset
return NSPredicate(format: "(centroid.latitude <= %@) && (centroid.latitude >= %@) && (centroid.longitude >= %@) && (centroid.longitude <= %@) && (computed == false)", argumentArray: [maxLat, minLat, maxLong, minLong])
}
offset
是任意搜索'半径'。 {I}属性是我设置为computed
的布尔值,一旦我试图检测true
是否包含给定点,以便后续的提取调用排除对象(如谓词中所示) )。对于检测,我首先使用上面的谓词获取Polygon
s,然后使用:
Polygon
这可能在计算上很重。我正在测试的多边形可能非常大且形状奇特。
是否有使用Core Data提高此流程的效率?有没有办法抵消计算let location : CLLocationCoordinate2D // ... point to test
for poly in polysFetched {
poly.computed = NSNumber(bool: true)
let path = UIBezierPath()
path.moveToPoint(CGPoint(x: (poly.points!.array as! [Point]).first!.longitude.doubleValue, y: (poly.points!.array as! [Point]).first!.latitude.doubleValue)) //set initial point
for pt in poly.points!.array as! [Point] {
path.addLineToPoint(CGPoint(x: pt.longitude.doubleValue, y: pt.latitude.doubleValue))
}
if (CGPathContainsPoint(path.CGPath, nil, CGPoint(x: location.longitude, y: location.latitude), false)) {
print("Poly \(poly) matches location \(location)")
return
}
}
或其他方面的一个点的包含计算?
答案 0 :(得分:2)
我最终以一些方式解决了这个问题并大大加快了这个过程。由于Point
NSManagedObject仅存在于通过Polygon
关系获取它们并计算UIBezierPath
的路径(Polygon
),因此我只计算了创建Polygon
对象并将其存储为属性。我还将Centriod
关系更改为两个属性c_lat
,c_long
并完全删除了Point
类!索引c_lat
和c_long
属性也可以加快获取请求的速度。
新的Polygon
课程是:
public class Polygon: NSManagedObject {
@NSManaged internal var pathData : NSData!
@NSManaged internal var c_lat : NSNumber!
@NSManaged internal var c_long : NSNumber!
@NSManaged var computed : NSNumber!
var path : UIBezierPath {
get {
return NSKeyedUnarchiver.unarchiveObjectWithData(pathData) as! UIBezierPath
}
set {
pathData = NSKeyedArchiver.archivedDataWithRootObject(newValue)
}
}
var centroid : CLLocationCoordinate2D {
get {
return CLLocationCoordinate2D(latitude: c_lat.doubleValue, longitude: c_long.doubleValue)
}
set {
c_lat = newValue.latitude
c_long = newValue.longitude
}
}
func containsLocation(location : CLLocationCoordinate2D) -> Bool {
return self.path.containsPoint(CGPoint(x: location.latitude, y: location.longitude))
}
}
Code不同的评论我原来的帖子建议维基百科页面检测多边形中的点,但方便的是用UIBezierPath
从我身上抽象出来,并且存在一个函数CGPathContainsPoint
一个布尔值作为其最后一个参数,用于在维基百科文章中提到的用于检测多边形中的点的两种算法之间进行选择。
对于遇到与我相同或类似问题的人,我建议内联关系并使用计算属性来访问您希望存储在Core Data中的非原始数据类型。