【发布时间】:2020-09-28 16:21:45
【问题描述】:
我正在使用 Google Maps iOS 在建筑群周围设置地理围栏。我在复合体周围创建了一条折线,如果用户在折线之外点击,它会将标记移动到折线上的最近点,否则它只会放置标记。使用this method 似乎效果相对较好。
但是我注意到,这种方法似乎只在所讨论的点垂直于线上的点时才有效,否则会产生奇怪的结果。我在下面发布了我的代码和一些屏幕截图。
-(CLLocationCoordinate2D) findClosestPointWithinFence:(CLLocationCoordinate2D) pointToTest {
CLLocationDistance smallestDistance = 0;
CLLocationCoordinate2D closestPoint = pointToTest;
for(int i = 0; i < [geoFencePoints count] - 1; i++) {
CGPoint point = [[geoFencePoints objectAtIndex:i] CGPointValue];
CGPoint point2 = [[geoFencePoints objectAtIndex:i + 1] CGPointValue];
CLLocationCoordinate2D locationA = CLLocationCoordinate2DMake(point.x, point.y);
CLLocationCoordinate2D locationB = CLLocationCoordinate2DMake(point2.x, point2.y);
CLLocationCoordinate2D myLoc = [self findClosestPointOnLine:locationA secondPoint:locationB fromPoint:pointToTest];
if(GMSGeometryIsLocationOnPath(myLoc, dealershipParameters.path, YES)) {
if(smallestDistance == 0) {
smallestDistance = GMSGeometryDistance(myLoc, pointToTest);
closestPoint = myLoc;
} else {
if(smallestDistance > GMSGeometryDistance(myLoc, pointToTest)) {
smallestDistance = GMSGeometryDistance(myLoc, pointToTest);
closestPoint = myLoc;
}
}
}
}
return closestPoint;
}
-(CLLocationCoordinate2D) findClosestPointOnLine:(CLLocationCoordinate2D)locationA secondPoint:(CLLocationCoordinate2D)locationB fromPoint:(CLLocationCoordinate2D) pointToTest {
CGPoint aToP = CGPointMake(pointToTest.latitude - locationA.latitude, pointToTest.longitude - locationA.longitude);
CGPoint aToB = CGPointMake(locationB.latitude - locationA.latitude, locationB.longitude - locationA.longitude);
float atb2 = (aToB.x * aToB.x) + (aToB.y * aToB.y);
float atp_dot_atb = (aToP.x * aToB.x) + (aToP.y * aToB.y);
float t = atp_dot_atb / atb2;
CLLocationCoordinate2D myLoc = CLLocationCoordinate2DMake(locationA.latitude + aToB.x * t, locationA.longitude + aToB.y * t);
return myLoc;
}
-(BOOL)testIfInsideGeoFence:(CLLocationCoordinate2D) pointToTest {
return GMSGeometryContainsLocation(pointToTest, dealershipParameters.path, YES) || GMSGeometryIsLocationOnPath(pointToTest, dealershipParameters.path, YES);
}
在第一个屏幕截图下方显示了标记成功找到最近的点,蓝线外的标记是我最初点击的位置,蓝线上的标记是它找到的点。第二个显示标记未能找到最近的点。屏幕上的标记是我最初点击的位置,因为它无法找到合适的解决方案,所以没有放置第二个标记。
【问题讨论】:
标签: ios google-maps