Search code examples
javascriptgoogle-maps-api-2

googlemaps get bounding box around marker


In googlemaps api v2 I have one marker on map and i need to calculate a bounding box around this one. How would I get a bonding box of 5 by 5 kilometers of which this marker is the center?


Solution

  • I'm not sure that such a functionality is provided by google map, but math will help you to survive ;) Calculate distance, bearing and more between Latitude/Longitude points is a great reference to different calculations with geographic data. Open that page, and go to "Destination point given distance and bearing from start point" part, there are formulas, as well as online calculator, so you can check them (as well as you can see points on the map). Formula has few parameters:

    (lat1,lng1) - your point (marker coordinates)
    d - distance (in your case it would be 2.5km)
    brng - angle.. 
    

    to find bound you need to find coordinates of south, north, east and west rectangle sides, so everything you will change in parameters is angle, and in your case it will be 0, 90, 180 and 270 grads. Formulas:

    var lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) + 
                          Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng) );
    var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1), 
                                 Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
    

    Well, specifying angle = 0 you find north, PI/2 - east, PI - south, 3*PI/2 - west (angles should be passed in radians).

    R = earth’s radius (mean radius = 6,371km)
    

    ADD-ON: just looked at the source code of that page, because when I enter in online form bearing = 0, distance = 2 then I see map with two points and according to the map scale the distance between them is really 2km. Well, you can use this library under a simple attribution license, without any warranty express or implied, just include it

    <script src="http://www.movable-type.co.uk/scripts/latlon.js"></script>
    

    Function you need is:

    /**
     * Returns the destination point from this point having travelled the given distance (in km) on the
     * given initial bearing (bearing may vary before destination is reached)
     *
     * see http://williams.best.vwh.net/avform.htm#LL
     *
     * @param {Number} brng: Initial bearing in degrees
     * @param {Number} dist: Distance in km
     * @returns {LatLon} Destination point
     */
    LatLon.prototype.destinationPoint = function(brng, dist) {
     dist = typeof(dist)=='number' ? dist : typeof(dist)=='string' && dist.trim()!='' ? +dist : NaN;
     dist = dist/this._radius; // convert dist to angular distance in radians
     brng = brng.toRad(); //
     var lat1 = this._lat.toRad(), lon1 = this._lon.toRad();
    
     var lat2 = Math.asin( Math.sin(lat1)*Math.cos(dist) +
     Math.cos(lat1)*Math.sin(dist)*Math.cos(brng) );
     var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(dist)*Math.cos(lat1),
     Math.cos(dist)-Math.sin(lat1)*Math.sin(lat2));
     lon2 = (lon2+3*Math.PI)%(2*Math.PI) - Math.PI; // normalise to -180...+180
    
     return new LatLon(lat2.toDeg(), lon2.toDeg());
    }
    

    and when I enter in online form bearing = 0, distance = 2, this method is executed with arguments latLonCalc.destinationPoint( 0, "2" );

    try it, otherwise give me input parameters so I could check what's wrong

    UPDATE2 that library works with grads,and converts them to radians for calculations and then back to grads. Just performed simple test:

    var latLonCalc = new  new LatLon( 25, 45 );
    var point = latLonCalc.destinationPoint( 0, "2" );
    console.info( point );
    // prints 25°01′05″N, 045°00′00″E { _lat=25.01798643211838, _lon=45.00000000000005, _radius=6371}
    

    so the distance between entry point and final destination is a bit more than 1 minute;

    earth = 2 * PI * 6371; // 40 009.98km
    => 40 009.98km / 360grad =~111.14
    => 111,14 / 60 = 1.85 (km/minute) ~2km
    

    it was round calculation, which tells me that final point is not far away then entry point, and distance should be 2km ;)