2013-08-28 6 views
8

So erstellen Sie Polygon Geofence aus mehreren Geo-Standorten (lange, lat-Werte). Auch wie man Benutzer verfolgt, tritt in diese Geofence-Region ein oder verlässt diese Region auf Android.Android Geofencing (Polygon)

Antwort

12

Ein Geofence ist einfach eine Anordnung von Breiten-/Längenpunkten, die ein Polygon bilden. Sobald Sie eine Liste von Breiten-/Längenpunkten haben, können Sie mit einer Punkt-Innen-Polygon-Prüfung feststellen, ob sich ein Ort innerhalb des Polygons befindet.

Dies ist Code, den ich in meinen eigenen Projekten verwendet haben, für sehr große konkave Polygone (20K + Eckpunkte) Point-in-Polygon-Überprüfungen durchzuführen:

public class PolygonTest 
{ 
    class LatLng 
    { 
     double Latitude; 
     double Longitude; 

     LatLng(double lat, double lon) 
     { 
      Latitude = lat; 
      Longitude = lon; 
     } 
    } 

    bool PointIsInRegion(double x, double y, LatLng[] thePath) 
    { 
     int crossings = 0; 

     LatLng point = new LatLng (x, y); 
     int count = thePath.length; 
     // for each edge 
     for (var i=0; i < count; i++) 
     { 
      var a = thePath [i]; 
      var j = i + 1; 
      if (j >= count) 
      { 
       j = 0; 
      } 
      var b = thePath [j]; 
      if (RayCrossesSegment(point, a, b)) 
      { 
       crossings++; 
      } 
     } 
     // odd number of crossings? 
     return (crossings % 2 == 1); 
    } 

    bool RayCrossesSegment(LatLng point, LatLng a, LatLng b) 
    { 
     var px = point.Longitude; 
     var py = point.Latitude; 
     var ax = a.Longitude; 
     var ay = a.Latitude; 
     var bx = b.Longitude; 
     var by = b.Latitude; 
     if (ay > by) 
     { 
      ax = b.Longitude; 
      ay = b.Latitude; 
      bx = a.Longitude; 
      by = a.Latitude; 
     } 
      // alter longitude to cater for 180 degree crossings 
     if (px < 0) { px += 360; }; 
     if (ax < 0) { ax += 360; }; 
     if (bx < 0) { bx += 360; }; 

     if (py == ay || py == by) py += 0.00000001; 
     if ((py > by || py < ay) || (px > Math.max(ax, bx))) return false; 
     if (px < Math.min(ax, bx)) return true; 

     var red = (ax != bx) ? ((by - ay)/(bx - ax)) : float.MAX_VALUE; 
     var blue = (ax != px) ? ((py - ay)/(px - ax)) : float.MAX_VALUE; 
     return (blue >= red); 
    } 
} 

In Bezug auf die Programmablauf, möchten Sie einen Hintergrund Service, um Standortaktualisierungen durchzuführen, und führen Sie dann diese Überprüfung für Ihre Breiten-/Langpolygondaten durch, um festzustellen, ob sich der Standort darin befindet.

+0

Geofence kann auch konkav sein. Ich habe eine Geofence-PHP-Klasse geschrieben. – Bytemain

+0

Ah, ich habe das falsche geschrieben, oder? Danke, dass du das hervorgehoben hast. – matthewrdev

+0

Das ist reines Gold IMHO. Hat es praktische Einschränkungen, Unzulänglichkeiten oder Ungenauigkeiten? Hat dieser Algorithmus auch einen Namen? – LucasM