0

Say I have a GPS coord say A (in longitude-latitude decimal form then I want to create a zone of 30 meters radius (a circle) so that I can trap any device(with GPS coord) which enters that zone, how to do it ? Thanks

Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104

1 Answers1

3

Take a look at this javascript example, but it's easy to implement on any other language.

Main code:

    var earthRadiusKm = 3437.74677 * 1.1508 * 1.6093470878864446;

    function GeoArea(centerLat, centerLng, distanceKm, northPoint, southPoint, eastPoint, westPoint) {
        this.northPoint = northPoint;
        this.southPoint = southPoint;
        this.eastPoint = eastPoint;
        this.westPoint = westPoint;
        this.inArea = function (lat, lng) {
            var inBox = southPoint.lat <= lat && lat <= northPoint.lat && westPoint.lng <= lng && lng <= eastPoint.lng;
            if (inBox) {
                var distanceFromCenterKm = calcDistance(centerLat, centerLng, lat, lng);
                return distanceFromCenterKm <= distanceKm;
            } else {
                return false;
            }
        }
    }

    function GeoPoint(lat, lng) {
        this.lat = lat;
        this.lng = lng;
    }

    function toDegrees(radians) {
        return radians / (Math.PI / 180);
    }

    function toRadians(degrees) {
        return Math.PI / 180 * degrees;
    }

    function calcDistance(latA, lngA, latB, lngB) {
        var rLatA = toRadians(latA);
        var rLatB = toRadians(latB);
        var rHalfDeltaLat = toRadians((latB - latA) / 2);
        var rHalfDeltaLng = toRadians((lngB - lngA) / 2);

        return 2 * earthRadiusKm * Math.asin(Math.sqrt(Math.pow(Math.sin(rHalfDeltaLat), 2) + Math.cos(rLatA) * Math.cos(rLatB) * Math.pow(Math.sin(rHalfDeltaLng), 2)));
    }

    function findPoint(lat, lng, bearing, distance) {
        var rLat = toRadians(lat);
        var rLng = toRadians(lng);
        var rBearing = toRadians(bearing);
        var rAngDist = distance / earthRadiusKm;

        var rLatB = Math.asin(Math.sin(rLat) * Math.cos(rAngDist) + Math.cos(rLat) * Math.sin(rAngDist) * Math.cos(rBearing));
        var rLngB = rLng + Math.atan2(Math.sin(rBearing) * Math.sin(rAngDist) * Math.cos(rLat), Math.cos(rAngDist) - Math.sin(rLat) * Math.sin(rLatB));

        var pLat = toDegrees(rLatB);
        var pLng = toDegrees(rLngB);
        return new GeoPoint(pLat, pLng);
    }

    function calcArea(lat, lng, distanceKm) {
        var northPoint = findPoint(lat, lng, 0, distanceKm);
        var eastPoint = findPoint(lat, lng, 90, distanceKm);
        var southPoint = findPoint(lat, lng, 180, distanceKm);
        var westPoint = findPoint(lat, lng, 270, distanceKm);
        return new GeoArea(lat, lng, distanceKm, northPoint, southPoint, eastPoint, westPoint);
    }

Usage example:

    // calculate area with center in lat:55.742793 lng:37.615401
    // and distance in 23 km
    var area = calcArea(55.742793, 37.615401, 23);

    //returns true
    area.inArea(55.714735, 37.629547);
    //returns false
    area.inArea(55.693842, 38.015442);
Nikita Koksharov
  • 10,283
  • 1
  • 62
  • 71
  • looks good - I shall try it - thank you very much, I hope it works with 30 metres – user1379094 May 07 '12 at 10:11
  • yes, it works. distanceKm parameter in this case should be equals to 0.030 – Nikita Koksharov May 07 '12 at 12:20
  • sorry Nikita, I tried but I got so many errors, what should I declare before I start this code ? which Java version do you use ? Thank you for your help – user1379094 May 07 '12 at 20:48
  • I tried it as Javascript but it did not work - no errors but no output – user1379094 May 08 '12 at 03:54
  • 1
    It's a javascript NOT Java. Take a look here http://jsfiddle.net/CY9rm/ - just press 'run'. In this version I added two alerts, to show you 'true' and 'false' results. All works as should! – Nikita Koksharov May 08 '12 at 06:58
  • Yes I know, it works now with alert in a document write but in the browser it displays also, that the area is undefined – user1379094 May 09 '12 at 02:49
  • Sorry I was incorrectly testing it. Again thank you very much. Now I can get a display in browser like 55.714735, 37.629547 is within 23km of GPS 55.742793, 37.615401 AND 55.693842, 38.015442 is more than 23km of GPS 55.742793, 37.615401 but how to increase the accuracy ? because - currently it is off by around 2 meters compared to http://www.csgnetwork.com/gpsdistcalc.html I suppose it uses more significant figures ? – user1379094 May 09 '12 at 04:45
  • I redefinded 'earthRadiusKm' in more precise form, so try it. Accuracy should increase. – Nikita Koksharov May 09 '12 at 06:33
  • sorry to ask again (I am really a newbee to GPS), I have compared your algorithm of calcDistance to krysstal.com/sphertrig - for London to Bagdad, the distance differs by around 14km ie. 4075.94km and 4089.88km, which one is more accurate and why is it so ? – user1379094 May 15 '12 at 02:30
  • another more compelling question : if in both cases we use spherical formula, why is it that the difference is so large (14 km) ?? – user1379094 May 15 '12 at 02:51
  • but if we are in the equator.. it is better to use spheroid formula right and not spherical. If it is so, then the radius will be of two values. What do you think ? – user1379094 May 16 '12 at 05:08
  • hmm... maybe it's a good idea. Good to know how change accuracy in this case – Nikita Koksharov May 17 '12 at 13:39
  • hello Nikita, you are a really a nifty programmer - With your programme, how can I display or do a document.write on the distanceFromCenterKm variable ? I am really a newbee in javascript - thanks – user1379094 Aug 25 '12 at 17:53
  • Hi! You can use "calcDistance" function for it. `var distance = calcDistance(123, 32, 32, 32); document.write(distance);` – Nikita Koksharov Aug 26 '12 at 07:10