Frage

Ich habe einen definierten Position nach breiten-und Längengrad.Jetzt möchte ich berechnen einen Begrenzungsrahmen innerhalb von z.B.10 Kilometer von diesem Punkt.

Die bounding box definiert werden sollte, wie latmin, lngmin und latmax, lngmax.

Ich brauche dieses Zeug, um die panoramio-API.

Hat jemand wissen die Formel, wie man diese Punkte?

Edit: Jungs, ich Suche eine Formel/Funktion, die lat & lng als Eingabe und gibt eine bounding-box als latmin & lngmin und latmax & latmin.Mysql, php, c#, javascript in Ordnung ist, aber auch pseudocode sollte okay sein.

Edit: Ich bin nicht auf der Suche nach einer Lösung, die mir zeigt, der Abstand von 2 Punkten

War es hilfreich?

Lösung

Ich schlage vor, lokal die Erdoberfläche als eine Kugel mit dem Radius von dem WGS84 Ellipsoid bei der gegebenen Breite gegeben anzunähern. Ich vermute, dass die genaue Berechnung von LatMin und latMax würde elliptischen Funktionen erfordern und würde keine nennenswerte Steigerung der Genauigkeit ergeben (WGS84 ist selbst eine Annäherung).

Meine Implementierung folgt (Es ist in Python geschrieben, ich habe es nicht getestet):

# degrees to radians
def deg2rad(degrees):
    return math.pi*degrees/180.0
# radians to degrees
def rad2deg(radians):
    return 180.0*radians/math.pi

# Semi-axes of WGS-84 geoidal reference
WGS84_a = 6378137.0  # Major semiaxis [m]
WGS84_b = 6356752.3  # Minor semiaxis [m]

# Earth radius at a given latitude, according to the WGS-84 ellipsoid [m]
def WGS84EarthRadius(lat):
    # http://en.wikipedia.org/wiki/Earth_radius
    An = WGS84_a*WGS84_a * math.cos(lat)
    Bn = WGS84_b*WGS84_b * math.sin(lat)
    Ad = WGS84_a * math.cos(lat)
    Bd = WGS84_b * math.sin(lat)
    return math.sqrt( (An*An + Bn*Bn)/(Ad*Ad + Bd*Bd) )

# Bounding box surrounding the point at given coordinates,
# assuming local approximation of Earth surface as a sphere
# of radius given by WGS84
def boundingBox(latitudeInDegrees, longitudeInDegrees, halfSideInKm):
    lat = deg2rad(latitudeInDegrees)
    lon = deg2rad(longitudeInDegrees)
    halfSide = 1000*halfSideInKm

    # Radius of Earth at given latitude
    radius = WGS84EarthRadius(lat)
    # Radius of the parallel at given latitude
    pradius = radius*math.cos(lat)

    latMin = lat - halfSide/radius
    latMax = lat + halfSide/radius
    lonMin = lon - halfSide/pradius
    lonMax = lon + halfSide/pradius

    return (rad2deg(latMin), rad2deg(lonMin), rad2deg(latMax), rad2deg(lonMax))

EDIT: Der folgende Code konvertiert (Grad, primes, Sekunden) in Grad + Bruchteile eines Grades, und umgekehrt (nicht getestet):

def dps2deg(degrees, primes, seconds):
    return degrees + primes/60.0 + seconds/3600.0

def deg2dps(degrees):
    intdeg = math.floor(degrees)
    primes = (degrees - intdeg)*60.0
    intpri = math.floor(primes)
    seconds = (primes - intpri)*60.0
    intsec = round(seconds)
    return (int(intdeg), int(intpri), int(intsec))

Andere Tipps

Ich schrieb einen Artikel über die Begrenzungs finden Koordinaten:

http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates

Der Artikel beschreibt die Formeln und stellt auch eine Java-Implementierung. (Es zeigt auch, warum Federicos Formel für die min / max Länge ungenau ist.)

Hier habe ich Federico A. Ramponi Antwort auf C # für jeden umgewandelt interessiert:

public class MapPoint
{
    public double Longitude { get; set; } // In Degrees
    public double Latitude { get; set; } // In Degrees
}

public class BoundingBox
{
    public MapPoint MinPoint { get; set; }
    public MapPoint MaxPoint { get; set; }
}        

// Semi-axes of WGS-84 geoidal reference
private const double WGS84_a = 6378137.0; // Major semiaxis [m]
private const double WGS84_b = 6356752.3; // Minor semiaxis [m]

// 'halfSideInKm' is the half length of the bounding box you want in kilometers.
public static BoundingBox GetBoundingBox(MapPoint point, double halfSideInKm)
{            
    // Bounding box surrounding the point at given coordinates,
    // assuming local approximation of Earth surface as a sphere
    // of radius given by WGS84
    var lat = Deg2rad(point.Latitude);
    var lon = Deg2rad(point.Longitude);
    var halfSide = 1000 * halfSideInKm;

    // Radius of Earth at given latitude
    var radius = WGS84EarthRadius(lat);
    // Radius of the parallel at given latitude
    var pradius = radius * Math.Cos(lat);

    var latMin = lat - halfSide / radius;
    var latMax = lat + halfSide / radius;
    var lonMin = lon - halfSide / pradius;
    var lonMax = lon + halfSide / pradius;

    return new BoundingBox { 
        MinPoint = new MapPoint { Latitude = Rad2deg(latMin), Longitude = Rad2deg(lonMin) },
        MaxPoint = new MapPoint { Latitude = Rad2deg(latMax), Longitude = Rad2deg(lonMax) }
    };            
}

// degrees to radians
private static double Deg2rad(double degrees)
{
    return Math.PI * degrees / 180.0;
}

// radians to degrees
private static double Rad2deg(double radians)
{
    return 180.0 * radians / Math.PI;
}

// Earth radius at a given latitude, according to the WGS-84 ellipsoid [m]
private static double WGS84EarthRadius(double lat)
{
    // http://en.wikipedia.org/wiki/Earth_radius
    var An = WGS84_a * WGS84_a * Math.Cos(lat);
    var Bn = WGS84_b * WGS84_b * Math.Sin(lat);
    var Ad = WGS84_a * Math.Cos(lat);
    var Bd = WGS84_b * Math.Sin(lat);
    return Math.Sqrt((An*An + Bn*Bn) / (Ad*Ad + Bd*Bd));
}

Ich schrieb eine JavaScript-Funktion, die die vier Koordinaten eines quadratischen Begrenzungsrahmen zurückgibt, eine Entfernung und ein Paar von Koordinaten angegeben:

'use strict';

/**
 * @param {number} distance - distance (km) from the point represented by centerPoint
 * @param {array} centerPoint - two-dimensional array containing center coords [latitude, longitude]
 * @description
 *   Computes the bounding coordinates of all points on the surface of a sphere
 *   that has a great circle distance to the point represented by the centerPoint
 *   argument that is less or equal to the distance argument.
 *   Technique from: Jan Matuschek <http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates>
 * @author Alex Salisbury
*/

getBoundingBox = function (centerPoint, distance) {
  var MIN_LAT, MAX_LAT, MIN_LON, MAX_LON, R, radDist, degLat, degLon, radLat, radLon, minLat, maxLat, minLon, maxLon, deltaLon;
  if (distance < 0) {
    return 'Illegal arguments';
  }
  // helper functions (degrees<–>radians)
  Number.prototype.degToRad = function () {
    return this * (Math.PI / 180);
  };
  Number.prototype.radToDeg = function () {
    return (180 * this) / Math.PI;
  };
  // coordinate limits
  MIN_LAT = (-90).degToRad();
  MAX_LAT = (90).degToRad();
  MIN_LON = (-180).degToRad();
  MAX_LON = (180).degToRad();
  // Earth's radius (km)
  R = 6378.1;
  // angular distance in radians on a great circle
  radDist = distance / R;
  // center point coordinates (deg)
  degLat = centerPoint[0];
  degLon = centerPoint[1];
  // center point coordinates (rad)
  radLat = degLat.degToRad();
  radLon = degLon.degToRad();
  // minimum and maximum latitudes for given distance
  minLat = radLat - radDist;
  maxLat = radLat + radDist;
  // minimum and maximum longitudes for given distance
  minLon = void 0;
  maxLon = void 0;
  // define deltaLon to help determine min and max longitudes
  deltaLon = Math.asin(Math.sin(radDist) / Math.cos(radLat));
  if (minLat > MIN_LAT && maxLat < MAX_LAT) {
    minLon = radLon - deltaLon;
    maxLon = radLon + deltaLon;
    if (minLon < MIN_LON) {
      minLon = minLon + 2 * Math.PI;
    }
    if (maxLon > MAX_LON) {
      maxLon = maxLon - 2 * Math.PI;
    }
  }
  // a pole is within the given distance
  else {
    minLat = Math.max(minLat, MIN_LAT);
    maxLat = Math.min(maxLat, MAX_LAT);
    minLon = MIN_LON;
    maxLon = MAX_LON;
  }
  return [
    minLon.radToDeg(),
    minLat.radToDeg(),
    maxLon.radToDeg(),
    maxLat.radToDeg()
  ];
};

Sie suchen nach einer Ellipsoid Formel.

Der beste Ort, den ich gefunden habe, starten Codierung auf der Geo-basierte :: Ellipsoid-Bibliothek von CPAN. Es gibt Ihnen eine Basis zu schaffen, die Tests ab von und Ihre Ergebnisse mit ihren Ergebnissen zu vergleichen. Ich benutzte es als Grundlage für eine ähnliche Bibliothek für PHP bei meinem früheren Arbeitgeber.

Geo :: Ellipsoid

Werfen Sie einen Blick auf die location Methode. Nennen Sie es zweimal, und Sie haben Ihre bbox.

Sie haben keine Beiträge, welche Sprache Sie verwendet haben. Bereits eine Geokodierung Bibliothek für Sie sein kann.

Oh, und wenn Sie es nicht jetzt herausgefunden, Google Maps verwendet das WGS84 Ellipsoid.

Da ich eine sehr grobe Schätzung erforderlich, so einige unnötige Dokumente in einer Elasticsearch Abfrage, um herauszufiltern, ich verwendet, um die folgenden Formel:

Min.lat = Given.Lat - (0.009 x N)
Max.lat = Given.Lat + (0.009 x N)
Min.lon = Given.lon - (0.009 x N)
Max.lon = Given.lon + (0.009 x N)

N = km erforderlich bilden den gegebenen Ort. Für Ihren Fall N = 10

Nicht genau, aber praktisch.

Angepasst ich ein PHP-Skript, das ich gefunden, genau dies zu tun.Sie können es verwenden, um finden die Ecken einer box um einen Punkt (sagen wir, 20 km).Mein konkretes Beispiel ist für die Google Maps API:

http://www.richardpeacock.com/blog/2011/11/draw-box-around-coordinate-google-maps-based-miles-or-kilometers

Hier ist eine einfache Implementierung mit Hilfe von JavaScript, die auf der Umwandlung von Breitengrad basiert auf kms wo 1 degree latitude ~ 111.2 km.

Ich bin Grenzen der Karte von einer gegebenen Breite und Länge mit 10 km Breite berechnet wird.

function getBoundsFromLatLng(lat, lng){
     var lat_change = 10/111.2;
     var lon_change = Math.abs(Math.cos(lat*(Math.PI/180)));
     var bounds = { 
         lat_min : lat - lat_change,
         lon_min : lng - lon_change,
         lat_max : lat + lat_change,
         lon_max : lng + lon_change
     };
     return bounds;
}

Abbildung von @Jan Philip Matuschek ausgezeichneter Erklärung (Bitte up-Abstimmung seine Antwort, das nicht; Ich füge dies als ich eine wenig Zeit in Anspruch nahm die ursprüngliche Antwort zu verstehen).

Die Zeichen-Box-Technik zur Optimierung der nächsten Nachbarn zu finden, müssten die minimale und maximale Breite abzuleiten, Länge Paare, für einen Punkt P im Abstand d. Alle Punkte, die außerhalb dieser fallen, sind auf jeden Fall in einem Abstand von mehr als von dem Punkt d. Eine Sache zu beachten ist hier die Berechnung der Breite der Kreuzung wie in Jan Philip Matuschek Erklärung wird hervorgehoben. Die Breite des Schnittpunktes ist auf der Höhe des Punkt P nicht, aber leicht von dieser versetzt. Dies ist ein oft übersehen, aber wichtiger Teil des richtige Minimums bei der Bestimmung und maximale Begrenzungs ist Länge für Punkt P für die Entfernung d.This auch nützlich bei der Überprüfung.

Der Haversine Abstand zwischen (Breite Schnitt, Längengrad hoch) bis (Breitengrad, Längengrad) von P gleich Abstand d.

Python Kern hier https://gist.github.com/alexcpn/f95ae83a7ee0293a5225

Ich arbeite an dem Begrenzungsrahmen Problem als nebensächlich alle Punkte innerhalb SrcRad Radius eines statischen LAT, LONG Punktes zu finden. Es gab ziemlich viele Berechnungen, dass die Verwendung

maxLon = $lon + rad2deg($rad/$R/cos(deg2rad($lat)));
minLon = $lon - rad2deg($rad/$R/cos(deg2rad($lat)));

die Länge Grenzen zu berechnen, aber ich fand dies nicht alle Antworten zu geben, die benötigt wurden. Denn das, was Sie wirklich wollen, zu tun ist,

(SrcRad/RadEarth)/cos(deg2rad(lat))

Ich weiß, ich weiß die Antwort gleich sein soll, aber ich fand, dass es nicht. Es zeigte sich, dass durch nicht dafür, dass ich die (SRCrad / RadEarth) Erstes tun und dann durch den Cos Teil Dividieren ich einige Ortspunkte auslassen.

Nachdem Sie alle Zeichen-Box erhalten Punkte, wenn Sie eine Funktion haben, dass der Punkt berechnet Entfernung lat gegeben Punkt, lange ist es einfach, nur die Punkte, die in einem gewissen Abstand Radius von dem festen Punkt sind. Hier ist, was ich tat. Ich weiß, es dauert ein paar zusätzlichen Schritte, aber es hat mir geholfen,

-- GLOBAL Constants
gc_pi CONSTANT REAL := 3.14159265359;  -- Pi

-- Conversion Factor Constants
gc_rad_to_degs          CONSTANT NUMBER := 180/gc_pi; -- Conversion for Radians to Degrees 180/pi
gc_deg_to_rads          CONSTANT NUMBER := gc_pi/180; --Conversion of Degrees to Radians

lv_stat_lat    -- The static latitude point that I am searching from 
lv_stat_long   -- The static longitude point that I am searching from 

-- Angular radius ratio in radians
lv_ang_radius := lv_search_radius / lv_earth_radius;
lv_bb_maxlat := lv_stat_lat + (gc_rad_to_deg * lv_ang_radius);
lv_bb_minlat := lv_stat_lat - (gc_rad_to_deg * lv_ang_radius);

--Here's the tricky part, accounting for the Longitude getting smaller as we move up the latitiude scale
-- I seperated the parts of the equation to make it easier to debug and understand
-- I may not be a smart man but I know what the right answer is... :-)

lv_int_calc := gc_deg_to_rads * lv_stat_lat;
lv_int_calc := COS(lv_int_calc);
lv_int_calc := lv_ang_radius/lv_int_calc;
lv_int_calc := gc_rad_to_degs*lv_int_calc;

lv_bb_maxlong := lv_stat_long + lv_int_calc;
lv_bb_minlong := lv_stat_long - lv_int_calc;

-- Now select the values from your location datatable 
SELECT *  FROM (
SELECT cityaliasname, city, state, zipcode, latitude, longitude, 
-- The actual distance in miles
spherecos_pnttopntdist(lv_stat_lat, lv_stat_long, latitude, longitude, 'M') as miles_dist    
FROM Location_Table 
WHERE latitude between lv_bb_minlat AND lv_bb_maxlat
AND   longitude between lv_bb_minlong and lv_bb_maxlong)
WHERE miles_dist <= lv_limit_distance_miles
order by miles_dist
;

Es ist sehr einfach gehen Sie einfach auf panoramio Website und öffnen Weltkarte von panoramio website.Then zu bestimmten Ort gehen Rechenblatt geografische Breite und Länge erforderlich.

Dann sind Sie Breite und Länge in der Adressleiste beispielsweise in dieser Adresse.

http: // www. panoramio.com/map#lt=32.739485&ln=70.491211&z=9&k=1&a=1&tab=1&pl=all

lt = 32.739485 => Breite ln = 70.491211 => Länge

Dieses Panoramio JavaScript API-Widget einen Begrenzungsrahmen um ein lat / long Paar erstellen und dann alle Fotos mit in diesen Grenzen zurück.

Eine andere Art von Panoramio JavaScript API-Widget, in dem Sie auch Hintergrundfarbe mit Beispiel und Code ist hier .

Es zeigt nicht mood.It Show beim Komponieren nach der Veröffentlichung.

<div dir="ltr" style="text-align: center;" trbidi="on">
<script src="https://ssl.panoramio.com/wapi/wapi.js?v=1&amp;hl=en"></script>
<div id="wapiblock" style="float: right; margin: 10px 15px"></div>
<script type="text/javascript">
var myRequest = {
  'tag': 'kahna',
  'rect': {'sw': {'lat': -30, 'lng': 10.5}, 'ne': {'lat': 50.5, 'lng': 30}}
};
  var myOptions = {
  'width': 300,
  'height': 200
};
var wapiblock = document.getElementById('wapiblock');
var photo_widget = new panoramio.PhotoWidget('wapiblock', myRequest, myOptions);
photo_widget.setPosition(0);
</script>
</div>

Hier habe ich Federico A. Ramponi Antwort auf PHP umgewandelt, wenn jemand interessiert:

<?php
# deg2rad and rad2deg are already within PHP

# Semi-axes of WGS-84 geoidal reference
$WGS84_a = 6378137.0;  # Major semiaxis [m]
$WGS84_b = 6356752.3;  # Minor semiaxis [m]

# Earth radius at a given latitude, according to the WGS-84 ellipsoid [m]
function WGS84EarthRadius($lat)
{
    global $WGS84_a, $WGS84_b;

    $an = $WGS84_a * $WGS84_a * cos($lat);
    $bn = $WGS84_b * $WGS84_b * sin($lat);
    $ad = $WGS84_a * cos($lat);
    $bd = $WGS84_b * sin($lat);

    return sqrt(($an*$an + $bn*$bn)/($ad*$ad + $bd*$bd));
}

# Bounding box surrounding the point at given coordinates,
# assuming local approximation of Earth surface as a sphere
# of radius given by WGS84
function boundingBox($latitudeInDegrees, $longitudeInDegrees, $halfSideInKm)
{
    $lat = deg2rad($latitudeInDegrees);
    $lon = deg2rad($longitudeInDegrees);
    $halfSide = 1000 * $halfSideInKm;

    # Radius of Earth at given latitude
    $radius = WGS84EarthRadius($lat);
    # Radius of the parallel at given latitude
    $pradius = $radius*cos($lat);

    $latMin = $lat - $halfSide / $radius;
    $latMax = $lat + $halfSide / $radius;
    $lonMin = $lon - $halfSide / $pradius;
    $lonMax = $lon + $halfSide / $pradius;

    return array(rad2deg($latMin), rad2deg($lonMin), rad2deg($latMax), rad2deg($lonMax));
}
?>

Danke @Fedrico A. für die Phyton Umsetzung habe ich es in eine Objective-C-Klasse portiert. Hier lautet:

#import "LocationService+Bounds.h"

//Semi-axes of WGS-84 geoidal reference
const double WGS84_a = 6378137.0; //Major semiaxis [m]
const double WGS84_b = 6356752.3; //Minor semiaxis [m]

@implementation LocationService (Bounds)

struct BoundsLocation {
    double maxLatitude;
    double minLatitude;
    double maxLongitude;
    double minLongitude;
};

+ (struct BoundsLocation)locationBoundsWithLatitude:(double)aLatitude longitude:(double)aLongitude maxDistanceKm:(NSInteger)aMaxKmDistance {
    return [self boundingBoxWithLatitude:aLatitude longitude:aLongitude halfDistanceKm:aMaxKmDistance/2];
}

#pragma mark - Algorithm 

+ (struct BoundsLocation)boundingBoxWithLatitude:(double)aLatitude longitude:(double)aLongitude halfDistanceKm:(double)aDistanceKm {
    double radianLatitude = [self degreesToRadians:aLatitude];
    double radianLongitude = [self degreesToRadians:aLongitude];
    double halfDistanceMeters = aDistanceKm*1000;


    double earthRadius = [self earthRadiusAtLatitude:radianLatitude];
    double parallelRadius = earthRadius*cosl(radianLatitude);

    double radianMinLatitude = radianLatitude - halfDistanceMeters/earthRadius;
    double radianMaxLatitude = radianLatitude + halfDistanceMeters/earthRadius;
    double radianMinLongitude = radianLongitude - halfDistanceMeters/parallelRadius;
    double radianMaxLongitude = radianLongitude + halfDistanceMeters/parallelRadius;

    struct BoundsLocation bounds;
    bounds.minLatitude = [self radiansToDegrees:radianMinLatitude];
    bounds.maxLatitude = [self radiansToDegrees:radianMaxLatitude];
    bounds.minLongitude = [self radiansToDegrees:radianMinLongitude];
    bounds.maxLongitude = [self radiansToDegrees:radianMaxLongitude];

    return bounds;
}

+ (double)earthRadiusAtLatitude:(double)aRadianLatitude {
    double An = WGS84_a * WGS84_a * cosl(aRadianLatitude);
    double Bn = WGS84_b * WGS84_b * sinl(aRadianLatitude);
    double Ad = WGS84_a * cosl(aRadianLatitude);
    double Bd = WGS84_b * sinl(aRadianLatitude);
    return sqrtl( ((An * An) + (Bn * Bn))/((Ad * Ad) + (Bd * Bd)) );
}

+ (double)degreesToRadians:(double)aDegrees {
    return M_PI*aDegrees/180.0;
}

+ (double)radiansToDegrees:(double)aRadians {
    return 180.0*aRadians/M_PI;
}



@end

Ich habe es getestet und scheint arbeiten schön. Struct BoundsLocation sollte durch eine Klasse ersetzt werden, habe ich verwende es hier nur zu teilen.

Alle obigen Antworten sind nur teilweise richtig.Speziell in der region wie Australien, Sie schließen immer die pole und die Berechnung einer sehr großen Rechteck sogar für 10 km.

Speziell der Algorithmus von Jan Philip Matuschek an http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#UsingIndex enthalten ein sehr großes Rechteck aus (-37, -90, -180, 180), die für fast jeden Punkt in Australien.Das trifft eine große Benutzer in der Datenbank und Entfernung berechnet werden, die für alle Benutzer in der fast die Hälfte des Landes.

Ich fand, dass die Drupal-API-Erde-Algorithmus von Rochester Institute of Technology besser funktioniert rund um die pole, wie auch anderswo, und ist wesentlich leichter zu implementieren.

https://www.rit.edu/drupal/api/drupal/sites%21all%21modules%21location%21earth.inc/7.54

Verwenden earth_latitude_range und earth_longitude_range aus der obigen Algorithmus für die Berechnung der bounding rectangle

Und verwenden Sie das Entfernung Berechnung Formel dokumentiert von google maps um Abstand zu berechnen

https://developers.google.com/maps/solutions/store-locator/clothing-store-locator#outputting-data-as-xml-using-php

Auf der Suche nach Kilometern anstelle von Meilen, ersetzen Sie 3959 mit 6371.Für (Lat, Lng) = (37, -122) und ein Marker-Tabelle mit Spalten lat und lng, die Formel ist:

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

Lesen Sie meine ausführliche Antwort an https://stackoverflow.com/a/45950426/5076414

Hier ist Federico Ramponi Antwort in Go. Hinweis: keine Fehlerprüfung: (

import (
    "math"
)

// Semi-axes of WGS-84 geoidal reference
const (
    // Major semiaxis (meters)
    WGS84A = 6378137.0
    // Minor semiaxis (meters)
    WGS84B = 6356752.3
)

// BoundingBox represents the geo-polygon that encompasses the given point and radius
type BoundingBox struct {
    LatMin float64
    LatMax float64
    LonMin float64
    LonMax float64
}

// Convert a degree value to radians
func deg2Rad(deg float64) float64 {
    return math.Pi * deg / 180.0
}

// Convert a radian value to degrees
func rad2Deg(rad float64) float64 {
    return 180.0 * rad / math.Pi
}

// Get the Earth's radius in meters at a given latitude based on the WGS84 ellipsoid
func getWgs84EarthRadius(lat float64) float64 {
    an := WGS84A * WGS84A * math.Cos(lat)
    bn := WGS84B * WGS84B * math.Sin(lat)

    ad := WGS84A * math.Cos(lat)
    bd := WGS84B * math.Sin(lat)

    return math.Sqrt((an*an + bn*bn) / (ad*ad + bd*bd))
}

// GetBoundingBox returns a BoundingBox encompassing the given lat/long point and radius
func GetBoundingBox(latDeg float64, longDeg float64, radiusKm float64) BoundingBox {
    lat := deg2Rad(latDeg)
    lon := deg2Rad(longDeg)
    halfSide := 1000 * radiusKm

    // Radius of Earth at given latitude
    radius := getWgs84EarthRadius(lat)

    pradius := radius * math.Cos(lat)

    latMin := lat - halfSide/radius
    latMax := lat + halfSide/radius
    lonMin := lon - halfSide/pradius
    lonMax := lon + halfSide/pradius

    return BoundingBox{
        LatMin: rad2Deg(latMin),
        LatMax: rad2Deg(latMax),
        LonMin: rad2Deg(lonMin),
        LonMax: rad2Deg(lonMax),
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top