Tùy chọn 1:Thực hiện tính toán trên cơ sở dữ liệu bằng cách chuyển sang cơ sở dữ liệu hỗ trợ GeoIP.
Tùy chọn 2:Thực hiện phép tính trên cơ sở dữ liệu bằng cách sử dụng quy trình được lưu trữ như sau:
CREATE FUNCTION calcDistance (latA double, lonA double, latB double, LonB double)
RETURNS double DETERMINISTIC
BEGIN
SET @RlatA = radians(latA);
SET @RlonA = radians(lonA);
SET @RlatB = radians(latB);
SET @RlonB = radians(LonB);
SET @deltaLat = @RlatA - @RlatB;
SET @deltaLon = @RlonA - @RlonB;
SET @d = SIN(@deltaLat/2) * SIN(@deltaLat/2) +
COS(@RlatA) * COS(@RlatB) * SIN(@deltaLon/2)*SIN(@deltaLon/2);
RETURN 2 * ASIN(SQRT(@d)) * 6371.01;
END//
Nếu bạn có chỉ mục về vĩ độ và kinh độ trong cơ sở dữ liệu của mình, bạn có thể giảm số lượng phép tính cần tính bằng cách tạo ra một hộp giới hạn ban đầu trong PHP ($ minLat, $ maxLat, $ minLong và $ maxLong) và giới hạn các hàng cho một tập hợp con các mục nhập của bạn dựa trên đó (NƠI vĩ độ GIỮA $ minLat VÀ $ maxLat VÀ kinh độ GIỮA $ minLong VÀ $ maxLong). Sau đó, MySQL chỉ cần thực hiện tính toán khoảng cách cho tập hợp con các hàng đó.
Nếu bạn chỉ đơn giản sử dụng một thủ tục được lưu trữ để tính toán khoảng cách) thì SQL vẫn phải xem xét mọi bản ghi trong cơ sở dữ liệu của bạn và tính toán khoảng cách cho mọi bản ghi trong cơ sở dữ liệu của bạn trước khi nó có thể quyết định trả lại hàng đó hay loại bỏ nó. .
Bởi vì phép tính thực thi tương đối chậm, sẽ tốt hơn nếu bạn có thể giảm tập hợp các hàng cần tính toán, loại bỏ các hàng rõ ràng sẽ nằm ngoài khoảng cách yêu cầu, để chúng tôi chỉ thực hiện phép tính tốn kém cho số lượng hàng ít hơn.
Nếu bạn cho rằng những gì bạn đang làm về cơ bản là vẽ một vòng tròn trên bản đồ, tập trung vào điểm ban đầu của bạn và với bán kính khoảng cách; thì công thức chỉ đơn giản xác định hàng nào nằm trong vòng tròn đó ... nhưng nó vẫn phải kiểm tra từng hàng.
Sử dụng hộp giới hạn giống như vẽ một hình vuông trên bản đồ trước tiên với các cạnh trái, phải, trên và dưới ở khoảng cách thích hợp từ tâm điểm của chúng ta. Sau đó, vòng tròn của chúng ta sẽ được vẽ bên trong hộp đó, với các điểm Cực Bắc, Cực Đông, Cực Nam và Cực Tây trên vòng tròn chạm vào đường viền của hộp. Một số hàng sẽ nằm ngoài ô đó, vì vậy SQL thậm chí không bận tâm đến việc tính toán khoảng cách cho các hàng đó. Nó chỉ tính toán khoảng cách cho những hàng nằm trong hộp giới hạn để xem chúng có nằm trong vòng tròn hay không.
Trong PHP của bạn (đoán bạn đang chạy PHP từ tên biến $), chúng tôi có thể sử dụng một phép tính rất đơn giản để tính ra vĩ độ và kinh độ tối thiểu và tối đa dựa trên khoảng cách của chúng tôi, sau đó đặt các giá trị đó trong mệnh đề WHERE của SQL của bạn tuyên bố. Đây thực sự là hộp của chúng tôi và bất kỳ thứ gì nằm ngoài hộp đó sẽ tự động bị loại bỏ mà không cần thực sự tính toán khoảng cách của nó.
Có một lời giải thích tốt về điều này (với mã PHP) trên Loại có thể di chuyển trang web đó sẽ là bài đọc cần thiết cho bất kỳ ai có kế hoạch thực hiện bất kỳ công việc Định vị địa lý nào trong PHP.
CHỈNH SỬA Giá trị 6371.01 trong quy trình lưu trữ calcDistance là hệ số để cung cấp cho bạn kết quả trả về tính bằng km. Sử dụng các hệ số thay thế thích hợp nếu bạn muốn tính theo dặm, hải lý, mét, bất cứ thứ gì