2008-10-26 4 views
87

Я дал местоположение, определенное широтой и долготой. Теперь я хочу рассчитать ограничивающий прямоугольник, например. 10 километров этого пункта.Как вычислить ограничительную рамку для заданного местоположения lat/lng?

Ограничительная коробка должна быть определена как latmin, lngmin и latmax, lngmax.

Мне нужен этот материал, чтобы использовать panoramio API.

Знает ли кто-нибудь формулу того, как получить очки?

Edit: Ребята я ищу формулы/функции, которая принимает широчайшие & LNG в качестве входных данных и возвращает прямоугольник, как latmin & lngmin и latmax & latmin. Mysql, php, C#, javascript в порядке, но также псевдокод должен быть в порядке.

Edit: Я не ищу решение, которое показывает мне расстояние 2 балла

+0

Если вы используете базу геоданных где-то, что они, несомненно, имеют расчет ограничительной рамки интегрированной Можно даже пойти проверить источник PostGIS/GEOS, например – 2008-10-26 17:13:50

ответ

54

Я предлагаю приблизительно локализовать поверхность Земли как сферу с радиусом, заданным эллипсоидом WGS84 на данной широте. Я подозреваю, что точное вычисление latMin и latMax потребует эллиптических функций и не даст заметного увеличения точности (WGS84 сам по себе является приближением).

Моя реализация следующим образом (это написано в Python, я не проверял):

# 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: Следующий код преобразует (градусы, простые числа, секунды) в градусах + доли градуса, и наоборот (не проверено):

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)) 
+4

Как было отмечено. в документации к предлагаемой библиотеке CPAN это имеет смысл только для halfSide <= 10 км. – 2008-10-27 03:53:24

+1

Это работает вблизи полюсов? Кажется, это не так, потому что похоже, что это заканчивается latMin <-pi (для юга полюс) или latMax> pi (для северного полюса)? Я думаю, что когда вы находитесь в пределах половины полюса, вам нужно вернуть ограничивающий прямоугольник, который включает в себя все долготы и широты, рассчитанные нормально для стороны от полюса и на полюсе на стороне около полюса. – 2010-04-23 21:48:00

+0

Это также не работает вокруг полюсов. http: // Jan Matuschek.de/LatitudeLongitudeBoundingCoordinates дает «правильный алгоритм» – 2012-06-21 15:00:09

6

Вы ищете эллипсоида формулу.

Лучшее место, которое я нашел для начала кодирования, основано на библиотеке Geo :: Ellipsoid от CPAN. Это дает вам базовый уровень для создания ваших тестов и сравнения ваших результатов с результатами. Я использовал его как основу для подобной библиотеки для PHP у своего предыдущего работодателя.

Geo::Ellipsoid

Посмотрите на метод location. Назовите это дважды, и у вас есть ваш bbox.

Вы не разместили какой язык вы использовали. Возможно, для вас уже существует библиотека геокодирования.

О, и если вы еще не поняли это, карты Google используют эллипсоид WGS84.

47

я написал статью о поиске ограничивающего координаты:

http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates

Статья объясняет формулы, а также предоставляет реализацию Java. (Он также показывает, почему формула Федерико для минимальной/максимальной долготы неточна.)

25

Здесь я преобразовал ответ Federico A. Ramponi на C# для всех, кто заинтересован:

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)); 
} 
0

Это очень просто просто пойти на сайт Panoramio и затем откройте карту мира с сайта панорамы. Затем перейдите в указанное место, где требуется широта и долгота.

Затем вы нашли широту и долготу в адресной строке, например, в этом адресе.

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

л = 32,739485 => широта п = 70,491211 => долгота

это Panoramio JavaScript API виджет создать ограничительную рамку вокруг Шир/пары, а затем возвращается все фотографии с в этих пределах ,

Другой вид виджета API-панорамы Panoramio, в котором вы также можете изменить цвет фона с помощью example and code is here.

Это не проявляется при составлении настроения. Это представление после публикации.

<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> 
1

я работал над проблемой ограничительной рамки в качестве побочного вопроса, чтобы найти все точки в радиусе SrcRad статического LAT, LONG точки. Там было довольно много расчетов, которые используют

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

для вычисления долготы границ, но я нашел, что это не дает ответы на все вопросы, которые были необходимы. Потому что вы действительно хотите сделать, это

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

Я знаю, я знаю, что ответ должен быть таким же, но я обнаружил, что это не было. Оказалось, что, не убедившись, что я делаю сначала (SRCrad/RadEarth), а затем делясь на Cos, я оставлял некоторые точки местоположения.

После того, как вы получите все свои точки ограничительной рамки, если у вас есть функция, которая вычисляет расстояние от точки до точки, заданную lat, долгое время легко получить только те точки, которые являются определенным радиусом расстояния от неподвижной точки. Вот что я сделал. Я знаю, что сделал несколько дополнительных шагов, но это помогло мне

-- 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 
; 
10

Я написал функцию JavaScript, которая возвращает четыре координаты квадратной ограничительной рамки, учитывая расстояние и пару координат:

'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() 
    ]; 
}; 
2

Иллюстрация @Jan Philip Matuschek Отличное объяснение. (Пожалуйста, проголосовав за его ответ, не это, я добавляю это, поскольку я потратил немного времени на понимание оригинального ответа)

Метод ограничительной коробки оптимизации поиска ближайшие соседи wo uld необходимо вывести минимальную и максимальную широту, пары долготы, для точки P на расстоянии d. Все точки, которые выходят за их пределы, определенно находятся на расстоянии больше d от точки. Одно замечание здесь - это вычисление широты пересечения, как указано в объяснении Ян Филиппа Матушека.Широта пересечения не находится на широте точки P, но немного смещена от нее. Это часто пропущенная, но важная роль в определении правильной минимальной и максимальной ограничивающей долготы для точки P для расстояния d. Это также полезно при проверке.

Расстояние между гавернерами (широта пересечения, долгота) до (широта, долгота) P равно расстоянию d.

Python Суть здесь https://gist.github.com/alexcpn/f95ae83a7ee0293a5225

enter image description here

0

Здесь я преобразовал ответ Federico A. Ramponi на PHP, если кто-то заинтересован:

<?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)); 
} 
?> 
3

Поскольку мне нужна была очень грубая оценка, так отфильтруйте некоторые ненужные документы в запросе elasticsearch, я использовал приведенную ниже формулу:

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 = км требуется форма данного места. Для вашего случая N = 10

Неточно, но удобно.

4

Вот простая реализация с использованием javascript, которая основана на преобразовании степени широты в км, где 1 degree latitude ~ 111.2 km.

Я вычисляю границы карты с заданной широты и долготы с шириной 10 км.

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; 
} 
0

Благодаря @Fedrico А. для реализации Фитон, я портировал его в Objective категории C класса. Вот так:

#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 

Я тестировал его и, кажется, работал хорошо. Struct BoundsLocation следует заменить классом, я использовал его, чтобы поделиться им здесь.

0

Все приведенные выше ответы являются только частично правильными. Специально в регионе, таком как Австралия, они всегда включают полюс и вычисляют очень большой прямоугольник даже для 10 км.

В частности, алгоритм Ян Филип Матучек в http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#UsingIndex включал очень большой прямоугольник от (-37, -90, -180, 180) практически для каждой точки Австралии. Это поражает крупных пользователей в базе данных, а расстояние должно быть рассчитано для всех пользователей почти в половине страны.

Я обнаружил, что алгоритм API Drupal API Earth API-интерфейса компании Rochester работает лучше на полюсе, а также в другом месте и намного проще реализовать.

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

Использование earth_latitude_range и earth_longitude_range из приведенного выше алгоритма расчета ограничивающего прямоугольника

И использовать формулу вычисления расстояния задокументировано Google Maps, чтобы рассчитать расстояние

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

К поиск километров вместо миль, замените 3959 ед. ч 6371. Для (Lat, LNG) = (37, -122) и таблицы маркеров с колоннами и лат LNG, формула:

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; 

Прочитайте мой развернутый ответ на https://stackoverflow.com/a/45950426/5076414

0

Вот ответ Федерико Рампони в Го. Примечание:. нет проверки ошибок :(

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), 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^