Cập nhật: Tôi đã viết lên một bài đăng trên blog chi tiết hơn về chủ đề cụ thể này trên http://www.mullie.eu/geographic-searches/
-
Vòng qua tất cả các thị trấn có sẵn bằng cách sử dụng API của Google Maps để tìm kinh độ của họ theo độ dài &. Lưu những nơi này (cơ sở dữ liệu). - Hãy coi chừng, Google sẽ không chấp nhận một số lượng lớn các cuộc gọi, vì vậy hãy tăng tốc các cuộc gọi của bạn.
Sau đó, khi lấy một thị trấn, bạn có thể sử dụng mã tương tự như mã dưới đây để lấy những thành phố withing một phạm vi nhất định:
public static function getNearby($lat, $lng, $type = 'cities', $limit = 50, $distance = 50, $unit = 'km')
{
// radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius'
if ($unit == 'km') $radius = 6371.009; // in kilometers
elseif ($unit == 'mi') $radius = 3958.761; // in miles
// latitude boundaries
$maxLat = (float) $lat + rad2deg($distance/$radius);
$minLat = (float) $lat - rad2deg($distance/$radius);
// longitude boundaries (longitude gets smaller when latitude increases)
$maxLng = (float) $lng + rad2deg($distance/$radius/cos(deg2rad((float) $lat)));
$minLng = (float) $lng - rad2deg($distance/$radius/cos(deg2rad((float) $lat)));
// get results ordered by distance (approx)
$nearby = (array) FrontendDB::getDB()->retrieve('SELECT *
FROM table
WHERE lat > ? AND lat < ? AND lng > ? AND lng < ?
ORDER BY ABS(lat - ?) + ABS(lng - ?) ASC
LIMIT ?;',
array($minLat, $maxLat, $minLng, $maxLng, (float) $lat, (float) $lng, (int) $limit));
return $nearby;
}
Thuyết minh về đoạn code trên:
- cơ sở dữ liệu riêng trình bao bọc được sử dụng, vì vậy hãy chuyển sang mysql_query, PDO, ...
- Điều này sẽ không chính xác. Chúng tôi không thể thực hiện các phép tính hình cầu chính xác trong DB, vì vậy, chúng tôi đã thực hiện các giới hạn kinh độ trên & trên vĩ độ & kinh độ thấp hơn. Điều này về cơ bản có nghĩa là một vị trí hơi xa hơn khoảng cách của bạn (ví dụ ở phía đông bắc, ngay bên ngoài bán kính thực tế (thực sự là một vòng tròn), nhưng vẫn nằm trong vĩ độ tối đa & kinh độ (vì chúng ta so sánh nó vuông giới hạn trong cơ sở dữ liệu) này sẽ chỉ cung cấp cho một thô nhưng hạt 100% lựa chọn chính xác của thành phố withing bán kính của bạn
tôi sẽ cố gắng để minh họa điều này:..
_________________
| /\ |
| Y/ \ |
|/ \ |
|( X )|
| \ /|
| \ / |
|______\_/______|
trên đây vòng tròn (phần nào) là bán kính thực tế nơi bạn muốn tìm vị trí bên trong, dựa trên vị trí X. Đây là quá khó để hoàn thành ngay lập tức DB của bạn, vì vậy những gì chúng tôi thực sự lấy từ DB là quảng trường xung quanh. Như bạn có thể thấy, có thể các vị trí (như Y) nằm trong các ranh giới tối thiểu & tối thiểu này, mặc dù chúng không thực sự có bán kính được yêu cầu. Sau này, chúng có thể được lọc qua PHP.
Để giải quyết vấn đề cuối cùng này, bạn có thể lặp lại tất cả kết quả và tính toán khoảng cách chính xác giữa vị trí gốc và kết quả phù hợp để tính toán nếu chúng thực sự nằm trong bán kính của bạn. Đối với điều đó, bạn có thể sử dụng mã này:
public static function getDistance($lat1, $lng1, $lat2, $lng2, $unit = 'km')
{
// radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius'
if ($unit == 'km') $radius = 6371.009; // in kilometers
elseif ($unit == 'mi') $radius = 3958.761; // in miles
// convert degrees to radians
$lat1 = deg2rad((float) $lat1);
$lng1 = deg2rad((float) $lng1);
$lat2 = deg2rad((float) $lat2);
$lng2 = deg2rad((float) $lng2);
// great circle distance formula
return $radius * acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($lng1 - $lng2));
}
Điều này sẽ tính chính xác khoảng cách chính xác giữa vị trí X và vị trí Y, sau đó bạn có thể lọc chính xác những thành phố đủ gần -fetch, nhưng không chỉ đủ gần để thực sự nằm trong giới hạn của bạn.
có một số câu hỏi và đáp ứng đầy hứa hẹn tại: http://stackoverflow.com/search?q=radius+search+google+maps+php - bạn đã kiểm tra điều gì và tại sao chúng không giúp bạn giải quyết vấn đề của mình? – Gordon
Tôi sẽ có một cái nhìn thông qua những người, tôi đã xem xét các bài viết được đề xuất trong khi gõ câu hỏi của tôi nhưng không thấy nhiều thứ hữu ích. Bạn có biết nơi tôi có thể có được một cơ sở dữ liệu mã bưu chính Anh mà không trả tiền cho Royal Mail ngớ ngẩn không? Tôi thấy một bài báo cho biết wikileaks phát hành nó nhưng đây là trong năm 2009 vì vậy tôi đoán nó không được cập nhật đầy đủ –
không có ý tưởng, xin lỗi. một google nhanh chóng đưa lên https://www.ordnancesurvey.co.uk/opendatadownload/products.html nhưng tôi không chắc chắn liệu chúng có miễn phí để sử dụng hay hữu ích hay không. – Gordon