OK - Tôi đã vật lộn với điều này trong khoảng 3 tháng và tắt và kể từ khi tôi đã cạn kiệt mọi công thức địa lý gần đó mà tôi đã gặp và tôi không phải là gần gũi hơn để có được kết quả đúng, tôi đã tìm ra thời gian để yêu cầu sự giúp đỡ.Thiếu kết quả do công thức lân cận địa lý (định vị cửa hàng)
THE AIM
Tôi đang thiết lập một thực hiện khá cơ bản của một cửa hàng định vị. Người dùng nhập mã bưu điện của họ và chọn từ danh sách tìm kiếm được xác định trước. API gmaps tạo ra các tọa độ vĩ độ/dài cho địa chỉ này và chuyển chúng đến một tập lệnh php. Trong kịch bản này, coords người dùng được truy vấn đối với một bảng cơ sở dữ liệu mysql (cấu trúc bên dưới)
post_id int(11)
post_type varchar(20)
lat float(10,6)
lng float(10,6)
Kết quả của truy vấn này (bài id) được nhập vào một truy vấn wordpress mà tạo ra XML chứa dữ liệu bản đồ đánh dấu. (Truy vấn wordpress sử dụng post__in và posts_per_page -1 để hiển thị thông tin cho tất cả các ID được tạo ra bởi các truy vấn
CÁC VẤN ĐỀ
Tóm lại, tất cả các thực hiện của công thức Haversine tôi đã đi qua dường như là kết quả trong các điểm đánh dấu bị thiếu - đặc biệt là bất kỳ điểm đánh dấu nào rất gần với tọa độ đã nhập của người dùng (không biết chính xác nhưng tôi nghĩ nó nằm trong khoảng 500m) .Đây là một vấn đề lớn nếu người dùng nhập mã bưu điện của họ và có một cửa hàng rất gần vị trí của họ sẽ không hiển thị.
Tôi đã thử khoảng 8 hoán vị khác nhau của forumla mà tôi đã đào lên fr om hướng dẫn khác nhau với cùng một kết quả. Dưới đây là công thức mà tôi hiện đang sử dụng trên các trang web mà cung cấp tất cả các dấu hiệu ngoại trừ những người rất gần gũi với người sử dụng vào các mục:
$center_lat = $_GET["lat"];
$center_lng = $_GET["lng"];
$radius = $_GET["radius"];
// Calculate square radius search
$lat1 = (float) $center_lat - ((int) $radius/69);
$lat2 = (float) $center_lat + ((int) $radius/69);
$lng1 = (float) $center_lng - (int) $radius/abs(cos(deg2rad((float) $center_lat)) * 69);
$lng2 = (float) $center_lng + (int) $radius/abs(cos(deg2rad((float) $center_lat)) * 69);
$sqlsquareradius = "
SELECT
post_id, lat, lng
FROM
wp_geodatastore
WHERE
lat BETWEEN ".$lat1." AND ".$lat2."
AND
lng BETWEEN ".$lng1." AND ".$lng2."
"; // End $sqlsquareradius
// Create sql for circle radius check
$sqlcircleradius = "
SELECT
t.post_id,
3956 * 2 * ASIN(
SQRT(
POWER(
SIN(
(".(float) $center_lat." - abs(t.lat)) * pi()/180/2
), 2
) + COS(
".(float) $center_lat." * pi()/180
) * COS(
abs(t.lat) * pi()/180
) * POWER(
SIN(
(".(float) $center_lng." - t.lng) * pi()/180/2
), 2
)
)
) AS distance
FROM
(".$sqlsquareradius.") AS t
HAVING
distance <= ".(int) $radius."
ORDER BY distance
"; // End $sqlcircleradius
$result = mysql_query($sqlcircleradius);
$row = mysql_fetch_array($result);
while($row = mysql_fetch_array($result)) {
// the contents of each row
$post_ids[] = $row['post_id'];
}
Có 1 công thức mà tôi đã cố gắng đã được đề xuất bởi Mike Pelley đây : Geolocation SQL query not finding exact location
Công thức này dường như hiển thị các điểm đánh dấu rất gần với vị trí đã nhập của người dùng nhưng bỏ qua các điểm đánh dấu khác đã được hiển thị trong bán kính nhất định. Để làm sáng tỏ bất kỳ sự nhầm lẫn này là mã tôi đã sử dụng:
$center_lat = $_GET["lat"];
$center_lng = $_GET["lng"];
$radius = $_GET["radius"];
$sql = "
SELECT post_id, lat, lng,
truncate((degrees(acos(sin(radians(lat))
* sin(radians(".$center_lat."))
+ cos(radians(lat))
* cos(radians(".$center_lat."))
* cos(radians(".$center_lng." - lng))))
* 69.09*1.6),1) as distance
FROM wp_geodatastore HAVING distance <= ".$radius." ORDER BY distance desc
"; // End $sqlcircleradius
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
while($row = mysql_fetch_array($result)) {
// Print out the contents of each row
$post_ids[] = $row['post_id'];
}
CÁC YÊU CẦU
Về cơ bản tôi muốn biết tại sao không phải của các khối mã được hiển thị đánh dấu chính xác. Nếu bất cứ ai có thể đề nghị bất kỳ cải tiến mã hoặc có thể chỉ cho tôi hướng tới một số tài nguyên mà tôi có thể đã bỏ lỡ điều đó sẽ là tuyệt vời
EDIT
tưởng câu trả lời psudeo tôi đang làm việc nhưng khi nó quay ra rằng vẫn gặp sự cố. Tôi đã kết thúc lên cho một tack rất khác nhau bây giờ và tôi đang sử dụng một định vị cửa hàng jquery rất tốt mà có thể được tìm thấy ở đây: http://www.bjornblog.com/web/jquery-store-locator-plugin
Sẽ không làm việc cho mọi dự án ra có nhưng cho nhu cầu của tôi nó là hoàn hảo (và hoạt động!)
Có lý do nào bạn không sử dụng khả năng không gian địa lý được xây dựng của MySQL không? http://dev.mysql.com/doc/refman/5.0/en/creating-a-spatially-enabled-mysql-database.html – Kenneth
Tôi đang đấu tranh để hiểu một số nội dung trong mã của bạn. Tại sao 'HAVING' thay vì' WHERE'? Điều gì đang xảy ra với công cụ 'int' trong' (float) $ center_lat - ((int) $ radius/69); 'và' truncate' trong truy vấn khác của bạn? Hãy ghi nhớ điều này khi bạn áp dụng các công thức: một phút kinh độ tại đường xích đạo được định nghĩa là một hải lý. Một mức độ nguyên là 60 hải lý. Cuối cùng, hãy thử loại bỏ 'BETWEEN' và sử dụng 'WHERE a> = lat1 AND thay vì <= lat2'. Nó sẽ cung cấp cho cùng một phức tạp của truy vấn và nó giải thích sự bao gồm/độc quyền của phạm vi bạn đang tìm kiếm. –
@Kenneth - Tôi không sử dụng các truy vấn địa không gian vì một vài lý do. Đầu tiên, tôi đang sử dụng [plugin lưu trữ dữ liệu địa lý] (http://wordpress.org/extend/plugins/geo-data-store) để tạo và duy trì bảng dữ liệu điểm đánh dấu của mình. Plugin này tạo ra cấu trúc bảng mà tôi đã trình bày ở trên. Thứ hai, phần lớn các hướng dẫn tôi đã đi qua để tạo bản đồ kiểu định vị cửa hàng dường như đề xuất cấu trúc bảng tương tự như cấu trúc được liệt kê. Có lẽ đây không phải là lý do tốt nhất nhưng tôi đã đi xa với thiết lập hiện tại và tôi khá chắc chắn rằng những gì tôi đang cố gắng làm nên có thể. – FourStacks