ka_*_*lin 4 oracle search geo oracle-spatial
我有下表城市:
ID(int),City(char),latitude(float),longitude(float).
Run Code Online (Sandbox Code Playgroud)
现在根据用户的经度(例如:44.8)和纬度(例如:46.3),我想在100英里/公里范围内搜索他附近的所有城市.
我找到了一些例子,但不知道如何使它们适应我的情况
select *
from GEO.Cities a
where SDO_WITHIN_DISTANCE([I don`t know],
MDSYS.SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(44.8,46.3, NULL) ,NULL, NULL),
'distance = 1000') = 'TRUE';
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激.
PS:如果可以有距离并进行分类
PPS:我想这样做,这样由于性能问题,我已经以这种方式做到了这一点http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL但它的时间太长...
O. *_*nes 16
对于mySQL距离搜索,你有很好的参考.
忘记Oracle Spatial的东西.代码太多,复杂性太大,没有足够的增值.
这是一个可以解决问题的查询.这使用法定里程的距离. 编辑这修复了mdarwin提到的错误,如果你试图将它用于北极或南极的位置,则以划分检查为代价.
SELECT id, city, LATITUDE, LONGITUDE, distance
FROM
(
SELECT id,
city,
LATITUDE, LONGITUDE,
(3959 * ACOS(COS(RADIANS(LATITUDE))
* COS(RADIANS(mylat))
* COS(RADIANS(LONGITUDE) - RADIANS(mylng))
+ SIN(RADIANS(LATITUDE))
* SIN(RADIANS(mylat))
))
AS distance,
b.mydst
FROM Cities
JOIN (
SELECT :LAT AS mylat,
:LONG AS mylng,
:RADIUS_LIMIT AS mydst
FROM DUAL
)b ON (1 = 1)
WHERE LATITUDE >= mylat -(mydst/69)
AND LATITUDE <= mylat +(mydst/69)
AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
)a
WHERE distance <= mydst
ORDER BY distance
Run Code Online (Sandbox Code Playgroud)
如果您以公里为单位工作,请将mydst/69更改为mydst/111.045,并将3959更改为6371.4.(1/69将英里转换为度数; 3959是行星半径的值.)
现在,您可能会想要将这个大型查询用作"魔术黑盒子".不要这样做!这不是很难理解,如果你理解它,你将能够做得更好.这是正在发生的事情.
该子句是使查询快速运行的核心.它会在您的Cities表中搜索您指定的点附近的城市.
WHERE LATITUDE >= mylat -(mydst/69)
AND LATITUDE <= mylat +(mydst/69)
AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
Run Code Online (Sandbox Code Playgroud)
要使它工作,你肯定需要一个LATITUDE列的索引.LONGITUDE列上的索引也会有所帮助.它进行近似搜索,寻找在您的点附近的地球表面上的准矩形块内的行.它选择了太多的城市,但不是太多.
此子句允许您从结果集中删除额外的城市:
WHERE distance <= mydst
Run Code Online (Sandbox Code Playgroud)
该子句是用于计算每个城市与您的观点之间的大圆距离的半正公式.
(3959 * ACOS(COS(RADIANS(LATITUDE))
* COS(RADIANS(mylat))
* COS(RADIANS(LONGITUDE) - RADIANS(mylng))
+ SIN(RADIANS(LATITUDE))
* SIN(RADIANS(mylat))
Run Code Online (Sandbox Code Playgroud)
此子句允许您输入您的点和半径限制,只需输入一次作为查询的绑定变量.它很有用,因为各种公式多次使用这些变量.
SELECT :LAT AS mylat,
:LONG AS mylng,
:RADIUS_LIMIT AS mydst
FROM DUAL
Run Code Online (Sandbox Code Playgroud)
查询的其余部分只是组织事物,以便您按距离选择和排序.
这是一个更完整的解释:http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/