Hi, I’m trying to make an app which tells me when I reach a certain destination but I want it to have a small tolerance - you don’t need to reach the point exactly, you just need to be near to it.
But it is not working. It always shows “5”
I do not believe what you tried will work unfortunately.
How to tell you if your device is near a destination is either to create a ringed fence and determine whether you are in the polygon of the geocoordinate limits or to calculate your distance from point of interest and when that distance is within certain limits; do something.
A simple way to determine how far you are from a destination is described here:
Geofence - using the MIT Map and Circle components to define a circular geofence by SteveJG
This example uses the Map, Circle and LocationSensor components to define whether the Android is inside a circle geofence of 8 meters radius or outside of the area.
The example app samples the device’s location every 30 seconds. Some GPS hardware might obtain updated satellite fixes more rapidly or others, with fewer receive channels, might require more time (most cell phones). Thirty seconds is hard coded. You can code a faster TimeInterval but the GPS will not update until it receives a different satellite fix.
For purposes of this tutorial, the position of the target geofence circle on your map is determined by adding 0.00008 degrees to the actual device location as a demonstration. 0.00001 is about 1.11 meters . The example uses (a offset of the device location latitude and longitude for the circle’s location to demonstrate the principle. Use a fixed location in your app to place the circle geofence, Write your own code to be able to place it where you actually want it
Button1 (Check Status) forces a GPS update immediately (if possible).
The demonstration provides a notation about current GPS Accuracy property in meters. The distance to the target geofence circle (if the device is not within the geofence already) is calculated. It will report whether the device is within the geofence or not (inside/outside). An OpenStreetMap tile is shown at a zoom of 18 (so the app can show / resolve sufficient detail of the circle geofence (8 meter red circle) and the current GPS Accuracy circle (pale blue circle).
The best location resolution is obtainable with higher quality GPS receiver models. The more receive GPS channels available in the GPS hardware the better. The display image is from a Samsung A10 tablet. Most older and cell phone Android devices will not provide as good resolution. Resolution and best Accuracy (low numbers) depends on many factors (is it raining, is device is indoors in a steel frame building, is located in a city canyon where building obscure the view etc.
What is reasonable to expect from your GPS and app.
Can your Android find your geofenced area? Maybe. Whether it can determine whether you device is within or outside the bounds of the circle geofence depends on the size of the geofence circle, the setting of TimeInterval and how fast the Android is moving (in a moving car, carried while walking etc.)
Your Android may be traveling too fast to resolve the geofence. Traveling at 60 mph ( 88 feet/sec (26.8 meters/sec) you travel 264 feet ( about 80.5 meters) in 3 seconds at 60 mph. Be aware, 0.00001 degree of latitude is approximately 1.11 meters at the equator (3.6 feet) ( https://www.usna.edu/Users/oceano/pguth/md_help/html/approx_equivalents.htm )
. If your device travels at 60 mph, you blow through the 8 meter radius circle (16 m in diameter) geofence in less than a second. If you sample at each thirty seconds (a reasonable rate) then it is easy for your device to be outside of the circle at a sampling point and then the device may not sample again until you are on the other side of the geofence. You could try more rapid sampling rates but your GPS certainly will not refresh within a second.
It is difficult for your app and device to determine whether your device is within or outside of small areas (geofences) with any reliability. The example uses a Circle with a radius of 8 meters. Try a radius of 100 meters. You can, however monitor how close you are to the geofence (i.e. distance to the geofence from your present location) but only to the extent Accuracy is rather low values and sampling is sufficient to obtain valid location of the moving Android in relation to the frequency of sampling.
Your GPS really does not ‘know’ exactly where it is at any moment. The green circle is where the Android actually is, the other marker pins show where the LocationSensor (resting on a desk , reporting its location once a minute, thought the device was … occasionally over 50 meters away from the actual location.
A cell phone GPS cannot resolve better than within two meters; professional papers indicate most cell phones are capable of resolving about 5 m most of the time but often are only capable of resolving 30 m. The Accuracy is variable (it changes for each satellite fix) so when the LocationSensor posts a location, that location is only about 68 percent reliable. If you move too fast near or through a small circular geofence , the device might not notice the geofence circle. Consequently, small geofences cannot be reliable when used using a cell phone GPS with any guarantee of registering where one is inside or outside the geofence.
To test if your geofence works, remove the Blocks that show latitude / longitude plus 0.00008 degrees and replace them with the coordinates you really want. Then walk through it. Outside of the circle area will report outside and inside, well, you get the idea. Experiment. You can also set the Circle radius to 100 meters.and leave the other blocks alone… the app should tell you you are inside . Does it? Also experiment with the distance to the edge of the circle …using the distance. When you are within the Circle, the distance is 0, outside, it could be almost anything.
You can code this so that when distance is zero, you use the Sound component to produce a beep or use the TextToSpeech component to say you arrived , lucky your ring fence was large enough to register or something.
CircleGeofence.aia (5.2 KB)
A determination can also be made using the ring fence advice discussed in Programming Your App to Make Decisions pages 290 to 294.
Good luck,
Steve
Regards,
SteveJG
Thank you so much! I will try that out!
You never use ELSEIF?
Hi Steve, Can the Geofencing/Circle feature be used to determine at which point/bearing one enters the geofence/circle assuming that location to be a point on a public road?
Perhaps. How do you determine a point is on a public road? If you know the point is on a public road you should be able to use - BearingToPoint( latitude , longitude ) which returns the bearing from the Marker
to the given latitude
and longitude
, in degrees from due north.
If your the 'road' is a LineString you created, you might be able to use
- BearingToFeature( mapFeature , centroids ) which returns the bearing from the
Marker
to the given map feature, in degrees from due north. If thecentroids
parameter istrue
, the bearing will be to the center of the map feature. Otherwise, the bearing will be computed to the point in the feature nearest theMarker
.
As far as I am aware, there is no way to determine if a point is on an OpenStreetMap 'drawn' road using any of the Map components
You can easily determine the point at which one enters the circle geofence, you just can't determine if that point is actually on a road.
Thanks Steve, that was quick! You do not need to determine if that point was on a road. Here's what I am currently doing:
- Someone marks the location on a road - eg, of a collision.
- That location should serve as a warning to someone else only if travelling in the
same direction/bearing and same lane as the original person who marked it, not if that person was travelling in the opposite direction. (The alarm sounds when the next vehicle crosses a 200m geofence line) - Because i am using a geo-fence for each incident, the alarm
unfortunately also sounds when travelling towards the incident from the opposite direction/
lane or, when travelling in any road near the incident, within the geofencing circumference.
I could calculate the bearing of the original reporter of the incident and make the warning conditional, but there are problems with that approach - eg the original person might have sent the co-ords seconds after passing the location when his vehicle might have changed direction slightly on a bend etc. OR, I am driving in a service road near the incident but inside the geofence, it would give me a false alarm., but if I had a way to determine the spot on a circle or rectangular geofence that the original vehicle entered the geofence, then I could make the alarm conditional to sound only if the next vehicle enters the geofence at the same point. Lets say, instead of a circular geofence, one could place a rectangular one in such a way that it lies lengthwise along the road, we could then stipulate that only when someone enters one of the sides, the alarm should sound? I'll try attaching a sketch.
You have a really neat idea. It might be possible if you can eliminate some issues.
You probably already read about a property reported by the LocationSensor called Accuracy. Using the Location Sensor If Accuracy is a small number what you hope to do might be possible; if it is on the order of 10 m or more it could be a huge problem. The problem could be ameliorated by filtering out all geocoordinate values larger than a fixed value at the expense of possibly mislocating the accident. Accuracy of the location fix varies with each LocationChanged event.
These comments from an earlier post are still valid (whether using a circular or rectangular ringed fence):
Rectangular ring fence is a great idea, except if the road is curving as you noted.
Regarding your item #1, by the time someone clocks the accident, their location will likely be somewhere down the road from the accident they report (unless they stop). A vehicle traveling at 100km/hr will travel about 28 meters in a second.
Placing an accident location in your database might be sufficient to indicate the accident hazard is near you. It isn't necessary to know which lane the accident is in. A ringed fence is not really needed. Poll your database accident location Tag and continually calculate the distance the user is from the reported accident. Sound an alarm when they get close and stop the alarm when they are farther away again. You mention three other valid ways to address proximity to the accident. Actually, traffic in both directions would benefit by knowing their distance from the event alerting them to a hazardous condition. I would keep this simple and merely calculate a distance between user and the accident. This tutorial shows one way to possibly code the distance calculation Social Distancing ... a CloudDB / Location Marker Tutorial . The complex solutions are exciting but using them might introduce uncertainty sometimes rather than increase confidence in the information.
You will have other issues. To be effective the accident location needs to monitor continuously. What will happen when your app goes to sleep? How do you determine when to remove the accident location from your database?
Let us know how your experiments work out. Your Project is very interesting. The community will be interested in what is possible and what is not.
You could also integrate Maps with this, by marking a pointer on the map and (somehow) upload it to every other app. This way, everybody can know approximately where the crash occurred; they don't have to be right on top of it.
If your app makes use of a CloudDB or FirebaseDB or a GoogleSheet used as a database you can do that by placing a Marker at the accident site that all users of your real time database can see using the Map component. Users can see the accident Marker in real time. (see the tutorial linked in post #9 ; it can be adapted to provide the accident Marker.
You could also post the location on Google My Maps and share that; however in that case only you can locate the accident; the users won't be able to report it.
This has the potential to become a fully-fledged app. There can be various trust levels of people (just like in this community). People with more validated reports will have higher trust levels, and they can be trusted more.
People can be validated by posting a picture of the accident or something like that.
The project works 100%. User logs into App, downloads an updated database of "incident" locations. App runs through them comparing DB locations to current location. If you are within 200m or so of the "incident" recorded in the database, App alerts you. However, I wanted to introduce some more discriminatory aspect. If the "incident" only affects one lane, ie, one direction, then it is nuisance value to alert cars in the opposite, unaffected lane coming towards the incident. As I said, it would be easy to use "bearing" to do the job but that still allows other nuisance alerts like traffic in adjacent roads within the alert geofence area. I want to nail it down to cars travelling in the exact road and lane and direction that is affected by the incident.
Maps are already integrated. All incidents within a certain zoom level surrounding your location are marked on the map.