在我的Grails 1.3.7应用程序中,我有一个具有双纬度和双经度的Building实体。我正在实现一个简单的搜索引擎,以便找到与用户所在点的给定距离(以十进制度表示的纬度和经度)的所有Building实例。我发现这个http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL很好,因为我使用的是MySQL数据库。边界框近似对我来说非常好,因为我需要执行额外的过滤和计算,我只需要一个查找器来缩小我正在过滤的实例数量。我的问题是:有人已经在Grails环境中实现了这种搜索吗?如何实现的?
发布于 2011-05-08 21:14:17
我以前实现过类似需求的东西,并且我使用了HQL查询。那是很久以前的事了,我记得我花了相当长的时间来阅读和理解,所以希望能为你节省一些时间。
这将根据当前位置(一个简单long容器对象)和一个"name“(以开头)执行select。它选择域对象(场所)以及距离当前位置几英里的位置。它是按照几英里外的升序排列的。注意,我添加了一个“道路因子”模糊来近似道路距离。
def getVenuesInArea(venueName, location, miles, optionsMap)
{
def max = optionsMap?.max ?: 10
def offset = optionsMap?.offset ?: 0
if (venueName == null) venueName = ""
venueName += '%'
double roadFactor = 1.20 // add 20% for the roads, instead of as crow flies...
def query
def results
def countQuery = """ select count( distinct v)
from Venue as v
WHERE
v.name like :venueName AND
( acos
(
sin(radians(:lat))
* sin(radians(v.location.latitude))
+ cos(radians(:lat))
* cos(radians(v.location.latitude))
* cos(radians(v.location.longitude) - radians(:lon))
) * 3956.1676 * :roadFactor < :distance
)
"""
def count = Venue.executeQuery(countQuery, [venueName:venueName, lat:location.latitude, lon:location.longitude, distance:miles, roadFactor:roadFactor])[0]
query = """ select distinct v,
(
acos
(
sin(radians(:lat))
* sin(radians(v.location.latitude))
+ cos(radians(:lat))
* cos(radians(v.location.latitude))
* cos(radians(v.location.longitude) - radians(:lon))
)
* 3956.1676 * :roadFactor
) as milesAway
from Venue as v
WHERE
v.name like :venueName AND
( acos
(
sin(radians(:lat))
* sin(radians(v.location.latitude))
+ cos(radians(:lat))
* cos(radians(v.location.latitude))
* cos(radians(v.location.longitude) - radians(:lon))
) * 3956.1676 * :roadFactor < :distance
)
order by
(
acos
(
sin(radians(:lat))
* sin(radians(v.location.latitude))
+ cos(radians(:lat))
* cos(radians(v.location.latitude))
* cos(radians(v.location.longitude) - radians(:lon))
)
* 3956.1676 * :roadFactor
)
asc,
v.name
"""
results = Venue.executeQuery( query, [venueName:venueName, lat:location.latitude, lon:location.longitude, distance:miles, roadFactor:roadFactor, max:max, offset:offset])
def venues = []
MathContext mc = new MathContext(2)
results.each
{ result ->
VenueWithDetails venueDetails = new VenueWithDetails( venue:result[0], milesFrom:new BigDecimal(result[1]).round(mc) )
venues.add(venueDetails)
}
return [venues:venues, count:count]
}这是在grails版本1.3.4上完成的,但我非常确定它在1.3.7上应该可以很好地工作。
希望这对你有帮助克里斯。
https://stackoverflow.com/questions/5918009
复制相似问题