【问题标题】:How to check if anyone is enter/left in/from particular boundary area even if application is in background mode or kill mode?即使应用程序处于后台模式或终止模式,如何检查是否有人进入/离开特定边界区域?
【发布时间】:2017-01-31 06:15:19
【问题描述】:

我想检查是否有人进入分配的边界,然后我必须像“您已进入”一样提醒该用户,当用户离开时,“您已离开”。我正在使用 .KML 文件绘制超过纬度和经度的边界。在这里,我附上了相同的屏幕截图。所以,我担心的是我如何检测到有人进入了这个边界并离开了那个边界。提前谢谢 边界看起来像这样。红色线是边界。

【问题讨论】:

  • @AndreasOetjen 感谢您的评论。但是您提到的问题的答案似乎不再可用。我已经看到了这个问题,但似乎我正在使用 .kml 文件并使用 Apple 提供的 kml 解析器代码进行解析,而不是使用 .gpx 文件。
  • @Birju 检查我的答案。
  • @Andreas Oetjen 我的问题不重复。请从我的问题中删除重复标签。

标签: ios objective-c mkmapview cllocation gmsmapview


【解决方案1】:

使用地图矩形。这是一个使用地图当前可见矩形的示例。关于您的问题,您可以使用 convertRegion:toRectToView: 先将您的区域转换为 MKMapRect。

MKMapPoint userPoint = MKMapPointForCoordinate(mapView.userLocation.location.coordinate);
MKMapRect mapRect = mapView.visibleMapRect; // find visible map rect
//MKMapRect mapRect = [self getMapRectUsingAnnotations:arrCordinate];//find custom map rect
BOOL inside = MKMapRectContainsPoint(mapRect, userPoint);

MKMapRect mapRect = mapView.visibleMapRect; 使用来自多个纬度和经度的边界区域创建自定义 mapRect

- (MKMapRect) getMapRectUsingAnnotations:(NSArray*)arrCordinate {

    MKMapPoint points[[arrCordinate count]];

    for (int i = 0; i < [arrCordinate count]; i++) {
        points[i] = MKMapPointForCoordinate([arrCordinate[i] MKCoordinateValue]);
    }

    MKPolygon *poly = [MKPolygon polygonWithPoints:points count:[arrCordinate count]];

    return [poly boundingMapRect];
}

【讨论】:

  • 感谢您对我的问题的回复。在您的回答中,我认为我每次都必须检查用户在 maprect 中的位置。如果没有更多条件,还有其他方法可以检查吗?例如 CLLocationManager 有它自己的方法 didEnterRegion 和 didExitRegion。
  • 我没有任何自己的方法,但可以使用 didUpdateToLocation 方法。 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
  • 如果我每次都必须在 didUpdateToLocation 中检查,那么如果我的应用程序处于终止模式,它是否有效?
  • @Birju 杀戮模式男士终止模式?可以通过个人聊天进行连接,因为您的问题很有趣。
  • Yes kill mode 表示终止模式。
【解决方案2】:

地理围栏不适用于复杂的多边形区域。也许你可以用其他方法解决问题。例如,将区域划分为更小的 CLCircularRegion,然后为必须为所有那些 locationManager:didEnterRegion: 和 locationManager:didExitRegion: 回调显示通知的情况开发聚合逻辑。但请记住,每个应用最多只能同时监控 20 个区域。

请参阅https://forums.developer.apple.com/thread/21323phillippk1 建议以了解其他可能的方法。

【讨论】:

  • Dios,谢谢你的回答。我会检查这个并更新你。
【解决方案3】:

试试这个代码。这是基于绕组数算法。这适用于复杂的形状,例如红线。

typedef struct {
  double lon;
  double lat;
} LATLON;

// returns true if w/in region
bool chkInRegion(LATLON poi, int npoi, LATLON *latlon)
{
  int wn = 0;
  for (int i = 0 ; i < npoi-1 ; i++) {
    if (latlon[i].lat <= poi.lat && latlon[i+1].lat > poi.lat) {
      double vt = (poi.lat - latlon[i].lat)/(latlon[i+1].lat - latlon[i].lat);
      if (poi.lon < (latlon[i].lon + (vt * (latlon[i+1].lon - latlon[i].lon)))) {
        wn++;
      }
    } else if (latlon[i].lat > poi.lat && latlon[i+1].lat <= poi.lat) {
      double vt = (poi.lat - latlon[i].lat)/(latlon[i+1].lat - latlon[i].lat);
      if (poi.lon < (latlon[i].lon + (vt * (latlon[i+1].lon - latlon[i].lon)))) {
        wn--;
      }
    }
  }
  return wn < 0;
}

// test data
LATLON llval[] = {
  {100,100},
  {200,500},
  {600,500},
  {700,100},
  {400,300},
  {100,100}
};
#define NLATLON (sizeof(llval)/sizeof(LATLON))

int main(int argc, char **argv) {
  while (1) {
    char buf[1024];
    fprintf(stderr, "lon = ");
    fgets(buf, sizeof(buf), stdin);
    double lon = atof(buf);
    fprintf(stderr, "lat = ");
    fgets(buf, sizeof(buf), stdin);
    double lat = atof(buf);
    LATLON ltest;
    ltest.lat = lat;
    ltest.lon = lon;
    if (chkInRegion(ltest, NLATLON, llval)) {
      fprintf(stderr, "\n*** in region ***\n\n");
    } else {
      fprintf(stderr, "\n=== outside ===\n\n");
    }
  }
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多