How is Geofence calculated?

542
3
04-17-2023 12:22 AM
GeraldLim
New Contributor

I took over a project recently and already implemented a set of codes to calculate the geofence area and draw. I have difficulty in understand this set of codes. Could anyone explain to me, how is the geofence being calculated; what is the diameter, what coordinates are needed to draw etc? 

Also, is there any guide to which I could refer?

static final double EARTH_RADIUS_X = 6378137.0;
static final double EARTH_RADIUS_Y = 6356752.3142;
final List< Polygon > mGeoFences = new ArrayList<>();
final List< Point > mLatLngs = new ArrayList<>();

void drawGeoFence() {

final GraphicsOverlay overlay = map_view.getGraphicsOverlays().get( 0 );

for( final Point point : mLatLngs ) {
mMap.addPointToDetermine1stTimeZoom( point );
final double lat = point.getY();
final double lng = point.getX();
mGeoFences.add( drawCircle( overlay.getGraphics(), mThreshold, lat, lng, false ) );
drawCircle( overlay.getGraphics(), 3, lat, lng, true ); // center point
}

}

Polygon drawCircle( final List< Graphic > graphics, final float radius, final double lat, final double lng, boolean isCenter ) {

final Point point = new Point( lng, lat, SpatialReferences.getWgs84() );
final PointCollection c = new PointCollection( SpatialReferences.getWgs84() );
final double centerX = point.getX();
final double centerY = point.getY();
final int pointsCount = 360;
final double slice = Math.PI / 180.0;
final double dX = radius / EARTH_RADIUS_X / slice;
final double dY = radius / ( EARTH_RADIUS_Y * Math.cos( lat * slice ) ) / slice;

for( int i = 0; i <= pointsCount; i++ ) {
final double r = slice * i;
final double x = centerX + dX * Math.cos( r );
final double y = centerY + dY * Math.sin( r );
c.add( x, y );
}

final Polygon polygon;

try {
polygon = new Polygon( c );
} catch( final Throwable e ) {
AdvancedLog.e( e );
PopUp.showErrorMsgDialog( this, PopUp.getListenerFinishActivity( this ), R.string.msg_invalid_asset_location_data );
return null;
}

final SimpleFillSymbol fillSymbols = new SimpleFillSymbol( SimpleFillSymbol.Style.SOLID,
isCenter ? Color.RED : red_transparent, null );
graphics.add( new Graphic( polygon, fillSymbols ) );
final Polyline polyline = new Polyline( c );
final SimpleLineSymbol lineSymbol = new SimpleLineSymbol( SimpleLineSymbol.Style.SOLID, Color.RED, 1 );
graphics.add( new Graphic( polyline, lineSymbol ) );
graphics.add( new Graphic( point ) );
return polygon;

}

 

 

Tags (1)
0 Kudos
3 Replies
MarkBaird
Esri Regular Contributor

@GeraldLim 

Looking at the code I can see:

 - You are using a Graphics Overlay on a MapView.  A Graphics Overlay is a container for Graphics which are for drawing points, line or polygons which persist in memory for the lifetime of your application

- The method drawCircle creates a polygon which has a number of vertices dependant on the radius.  

 - When you draw the polygon as a graphic you are using a SimpleFillSymbol to define the fill of your polygon and a SimpleLineSymbol to define the outline of the polygon.

 

There is some documentation about graphics overlays here.  There is a tutorial too which you can follow which will take you through the basics.

We also have a samples repository you can look at where there are a few samples which show graphics overlays.  This sample is worth looking at.

One observation I have about the drawCircle method is this could be simplified.  A circle is basically a buffer around a point and we have a method which does that for you.  Take a look at this sample which makes use of buffers and mentions geodesic buffers which are what I suspect you will need to use.

Does this help?

0 Kudos
GeraldLim
New Contributor

Hi @MarkBaird, thanks for the reply.  I kinda get the buffer around a point. However, I am puzzled at why does the code do a loop over mLatLngs and draws multiple circles. Do you have any idea on that?


 

 

0 Kudos
MarkBaird
Esri Regular Contributor

@GeraldLim 

I can't see enough of the app to see what it is doing.  You are correct, there is a loop which iterates over the mLatLngs which is a collection of points, but the code only shows an empty collection defined.

I don't know what your app is used for to attempt to guess why it is drawing multiple circles.  Can you describe the use-case?

I'm happy to help, but I need more context about that your app does and the problem you are trying to solve.

0 Kudos