をDBストレージのlat/lngの代わりに、結果のクエリ式が、lat/lng距離の可能なクエリよりもdbサーバのロード/タイムに対してより単純であるためです。
PHP実装の例は、下に見出すことができる:
http://headers-already-sent.com/geodistance/
方法「getCartesian」デカルト座標に緯度/経度に変換し、メソッド「getDistanceByCartesian」は実際の距離を計算する方法を示しています。あなたがする必要があるのは、この距離計算をPHPからSQLクエリに転送することです(複雑であってはなりません)。
編集、私はあなたが私は私の会社の場所と、すべてのマクドナルドのレストランのための2デモ・テーブルを設定上記のリンクの下に見つけることができますクラスに基づいて、より実用的な例
を与えるために時間を見つけて私たちの近くにあるとデカルトX、Y、ZにGoogleマップから緯度/経度に変換:で、一定の距離(2000内のすべての場所(レストラン)を見つけるためのSQL-クエリこの2つのテーブルに基づいて
CREATE TABLE `locations` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '',
`lat` double NOT NULL,
`lng` double NOT NULL,
`x` double NOT NULL,
`y` double NOT NULL,
`z` double NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `locations` (`id`, `title`, `lat`, `lng`, `x`, `y`, `z`)
VALUES
(1,'Ida-Ehre-Platz 10, 20095 Hamburg',53.55053,9.99949,3727600.05477,657242.251356,5124712.81705),
(2,'Kieler Straße 191-193, 22525 Hamburg',53.57731,9.93686,3725956.4981,652753.812254,5126481.40905),
(3,'Reeperbahn 42, 20359 Hamburg',53.549951,9.964937,3728046.74189,655003.113578,5124674.56664),
(4,'Theodor-Heuss-Platz 3, 20354 Hamburg',53.56083,9.99038,3726797.15378,656489.722425,5125393.17725),
(5,'Mundsburger Damm 67, 22087 Hamburg',53.57028,10.02642,3725550.98379,658686.623655,5126017.24553),
(6,'Paul-Nevermann-Platz 1, 22765 Hamburg',53.552602,9.936678,3728135.78521,653123.397726,5124849.69505),
(7,'Friedrich-Ebert-Damm 101, 22047 Hamburg',53.58753,10.08958,3723303.02881,662522.688778,5127156.05819),
(8,'Amsinckstraße 73, 20097 Hamburg',53.54271,10.02654,3727978.07563,659123.791421,5124196.16112),
(9,'Eiffestraße 440, 20537 Hamburg',53.55214,10.04638,3726919.13256,660267.521487,5124819.17553);
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`lat` double NOT NULL,
`lng` double NOT NULL,
`x` double NOT NULL,
`y` double NOT NULL,
`z` double NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`, `name`, `lat`, `lng`, `x`, `y`, `z`)
VALUES
(1,'Ministry.BBS, Cremon 36, 20457 Hamburg',53.545943,9.988761,3728127.10678,656615.385203,5124409.77226),
(2,'BBS, Dorotheenstraße 60, 22301 Hamburg',53.583231,10.008315,3724617.80169,657307.963226,5126872.28974);
メートル)は、すべてのユーザー(私たちの会社のオフィス)になります:
SELECT locations.*,
2 * 6371000.785 *
asin(
sqrt(
pow(locations.x - user.x, 2)
+ pow(locations.y - user.y, 2)
+ pow(locations.z - user.z, 2)
)/(2 * 6371000.785)
) AS distance
FROM locations, user
HAVING distance < 2000
ORDER BY distance ASC
「メートル」以外のものが必要な場合は、地球の半径を約3分の1に変更する必要があります。 6371000.785(メートル単位)を必要なものに変更し、2000年の希望の距離を好みのものに変更するか、ユーザーごとにユーザーテーブルに保存します。
2つ目の欠点は、新しいイベント/顧客が追加されるたびにそのリストを更新または更新する必要があることです。 – xQbert
@xQbertあなたが正しいです、私は十分に明確にしていませんでした。私はもう少し追加します。 – ean5533