geo 查询从 ruby 复制到 Ecto Elixir
geo Query replicating from ruby to Ecto Elixir
在 Ruby 中我有这个函数 query.by_distance
其中 by_distance
类似于
def_dataset_method(:by_distance) do |from, meters|
point = Geocoding.as_point(from)
query = "ST_DWithin(location, ST_SetSRID(ST_Point(?, ?), 4326)::geography, ?)"
where(query, point.lng, point.lat, meters)
end
在 ruby 端点用户传递 2 个值,它们是 is_near_to
,主要是城市或国家的名称。Geecoding
通过它获得积分和 2值为 within_distance
,其中 meters
用于在此 distance
.
内获取摄像头
以上发生在Ruby。
在 Elixir 中复制它的方法是
def by_distance(query, is_near_to, within_distance) do
[%{"lat" => lat, "lng" => lng}] = fetch(is_near_to)
latitude = lat
longitude = lng
query
|> where([cam], st_dwithin(cam.location, st_set_srid(st_point_from_text(^"#{latitude},#{longitude}"), 4326), ^within_distance))
end
为了获得纬度和经度,我正在做一些
defmodule EvercamMedia.Geocode do
def fetch(address) do
response = HTTPotion.get "http://maps.googleapis.com/maps/api/geocode/json?address=#{URI.encode(address)}&sensor=false"
{:ok, results} = Poison.decode response.body
get_in(results, ["results", Access.all(), "geometry", "location"])
end
end
现在我有相同的场景。我有两个值 is_near_to
和 within_distance
。但是我完全不知道这一点,我如何在查询中复制与我们在项目中使用 geo
相同的东西,根据文档,这显然是可能的,但我不知道如何去做。
这是我正在开发的应用程序的一部分,我相信它可以满足您的需求,它使用片段将 ST_distance_sphere 调用直接传递给 postgis。
使用库 https://github.com/bryanjos/geo 和 postgis
在模型中
def near_by(query, point, distance) do
from place in query,
where: fragment("ST_distance_sphere(?,?)", place.location, ^point) >= ^distance,
order_by: fragment("ST_distance_sphere(?,?)", place.location, ^point),
select: {place, fragment("ST_distance_sphere(?,?)", place.location, ^point)}
end
在控制器
def near_by(conn, %{"latitude" => latitude, "longitude" => longitude, "distance" => distance}) do
point = %Geo.Point{coordinates: {String.to_float(latitude), String.to_float(longitude)}, srid: 4326}
places = Place
|> Place.near_by(point, String.to_float(distance))
|> Repo.all
render(conn, "near_by.json", places: places)
end
在视图中
def render("near_by_place.json", %{place: place}) do
{ place, distance } = place
{lat, lon} = place.location.coordinates
%{id: place.id,
name: place.name,
latitude: lat,
longitude: lon,
distance: distance}
end
在 Ruby 中我有这个函数 query.by_distance
其中 by_distance
类似于
def_dataset_method(:by_distance) do |from, meters|
point = Geocoding.as_point(from)
query = "ST_DWithin(location, ST_SetSRID(ST_Point(?, ?), 4326)::geography, ?)"
where(query, point.lng, point.lat, meters)
end
在 ruby 端点用户传递 2 个值,它们是 is_near_to
,主要是城市或国家的名称。Geecoding
通过它获得积分和 2值为 within_distance
,其中 meters
用于在此 distance
.
以上发生在Ruby。
在 Elixir 中复制它的方法是
def by_distance(query, is_near_to, within_distance) do
[%{"lat" => lat, "lng" => lng}] = fetch(is_near_to)
latitude = lat
longitude = lng
query
|> where([cam], st_dwithin(cam.location, st_set_srid(st_point_from_text(^"#{latitude},#{longitude}"), 4326), ^within_distance))
end
为了获得纬度和经度,我正在做一些
defmodule EvercamMedia.Geocode do
def fetch(address) do
response = HTTPotion.get "http://maps.googleapis.com/maps/api/geocode/json?address=#{URI.encode(address)}&sensor=false"
{:ok, results} = Poison.decode response.body
get_in(results, ["results", Access.all(), "geometry", "location"])
end
end
现在我有相同的场景。我有两个值 is_near_to
和 within_distance
。但是我完全不知道这一点,我如何在查询中复制与我们在项目中使用 geo
相同的东西,根据文档,这显然是可能的,但我不知道如何去做。
这是我正在开发的应用程序的一部分,我相信它可以满足您的需求,它使用片段将 ST_distance_sphere 调用直接传递给 postgis。
使用库 https://github.com/bryanjos/geo 和 postgis
在模型中
def near_by(query, point, distance) do
from place in query,
where: fragment("ST_distance_sphere(?,?)", place.location, ^point) >= ^distance,
order_by: fragment("ST_distance_sphere(?,?)", place.location, ^point),
select: {place, fragment("ST_distance_sphere(?,?)", place.location, ^point)}
end
在控制器
def near_by(conn, %{"latitude" => latitude, "longitude" => longitude, "distance" => distance}) do
point = %Geo.Point{coordinates: {String.to_float(latitude), String.to_float(longitude)}, srid: 4326}
places = Place
|> Place.near_by(point, String.to_float(distance))
|> Repo.all
render(conn, "near_by.json", places: places)
end
在视图中
def render("near_by_place.json", %{place: place}) do
{ place, distance } = place
{lat, lon} = place.location.coordinates
%{id: place.id,
name: place.name,
latitude: lat,
longitude: lon,
distance: distance}
end