JSON 将地理库中的 GEO.Point 编码为人类可读的形式
JSON encode GEO.Point from geo library as human readable form
我有这个架构,它有一个 Geo Geo.Point
:
defmodule Api.Shop do
use Ecto.Schema
import Ecto.Changeset
import Api.Repo
import Ecto.Query
@derive {Poison.Encoder, only: [:name, :place_id, :geo_json, :distance]}
schema "shops" do
field :name, :string
field :place_id, :string
field :point, Geo.Point
field :geo_json, :string, virtual: true
field :distance, :float, virtual: true
timestamps()
end
def encode_model(shop) do
%Api.Shop{shop | geo_json: Geo.JSON.encode(shop.point) }
end
defimpl Poison.Encoder, for: Api.Shop do
def encode(shop, options) do
shop = Api.Shop.encode_model(shop)
Poison.Encoder.Map.encode(Map.take(shop, [:id, :name, :geo_json]), options)
end
end
def changeset(shop, params \ %{}) do
shop
|> cast(params, [:name, :place_id, :point])
|> validate_required([:name, :place_id, :point])
|> unique_constraint(:place_id)
end......
end
当我 return 查询中的 shop.point
字段时:
def create_query_no_keyword(categories, shop_ids) do
products_shops_categories = from p in Product,
distinct: p.id,
join: ps in ProductShop, on: p.id == ps.p_id,
join: s in Shop, on: s.id == ps.s_id,
join: pc in ProductCategory, on: p.id == pc.p_id,
join: c in Subcategory, on: c.id == pc.c_id,
where: c.id in ^categories,
where: s.id in ^shop_ids,
group_by: [p.id, p.name, p.brand],
select: %{product: p, categories: fragment("json_agg( DISTINCT (?, ?)) AS category", c.id, c.name), shops: fragment("json_agg( DISTINCT (?, ?, ?)) AS shop", s.id, s.name, s.point)}
end
得到 returned 的实际上是 0101000020E6100000A3BDB0EB0DD9654030AC2C1BE76D42C0
,这是错误的格式 - WKB。我希望编码为具有可读坐标的 WKT。
如何让 s.point
成为 WKT
格式并因此具有坐标,当它被查询 return 编辑时?
我发现 this Stack Exchange GIS answer 是解决方案:
use this for point object:
SELECT ST_AsText(the_geom)
FROM myTable; and viewing X,Y and geom object:
SELECT ST_X(the_geom), ST_Y(the_geom), ST_AsText(the_geom)
FROM myTable;
Geo library is using PostGIS 和解决方案是特定于 PostGIS 的。您需要使用 ST_AsText
或来自 PostGIS 的 ST_X
和 ST_Y
select 列。
我的 select 语句更改为:
select: %{product: p, categories: fragment("json_agg( DISTINCT (?, ?)) AS category", c.id, c.name), shops: fragment("json_agg( DISTINCT (?, ?, ST_X(?), ST_Y(?))) AS shop", s.id, s.name, s.point, s.point)}
我有这个架构,它有一个 Geo Geo.Point
:
defmodule Api.Shop do
use Ecto.Schema
import Ecto.Changeset
import Api.Repo
import Ecto.Query
@derive {Poison.Encoder, only: [:name, :place_id, :geo_json, :distance]}
schema "shops" do
field :name, :string
field :place_id, :string
field :point, Geo.Point
field :geo_json, :string, virtual: true
field :distance, :float, virtual: true
timestamps()
end
def encode_model(shop) do
%Api.Shop{shop | geo_json: Geo.JSON.encode(shop.point) }
end
defimpl Poison.Encoder, for: Api.Shop do
def encode(shop, options) do
shop = Api.Shop.encode_model(shop)
Poison.Encoder.Map.encode(Map.take(shop, [:id, :name, :geo_json]), options)
end
end
def changeset(shop, params \ %{}) do
shop
|> cast(params, [:name, :place_id, :point])
|> validate_required([:name, :place_id, :point])
|> unique_constraint(:place_id)
end......
end
当我 return 查询中的 shop.point
字段时:
def create_query_no_keyword(categories, shop_ids) do
products_shops_categories = from p in Product,
distinct: p.id,
join: ps in ProductShop, on: p.id == ps.p_id,
join: s in Shop, on: s.id == ps.s_id,
join: pc in ProductCategory, on: p.id == pc.p_id,
join: c in Subcategory, on: c.id == pc.c_id,
where: c.id in ^categories,
where: s.id in ^shop_ids,
group_by: [p.id, p.name, p.brand],
select: %{product: p, categories: fragment("json_agg( DISTINCT (?, ?)) AS category", c.id, c.name), shops: fragment("json_agg( DISTINCT (?, ?, ?)) AS shop", s.id, s.name, s.point)}
end
得到 returned 的实际上是 0101000020E6100000A3BDB0EB0DD9654030AC2C1BE76D42C0
,这是错误的格式 - WKB。我希望编码为具有可读坐标的 WKT。
如何让 s.point
成为 WKT
格式并因此具有坐标,当它被查询 return 编辑时?
我发现 this Stack Exchange GIS answer 是解决方案:
use this for point object:
SELECT ST_AsText(the_geom)
FROM myTable; and viewing X,Y and geom object:
SELECT ST_X(the_geom), ST_Y(the_geom), ST_AsText(the_geom)
FROM myTable;
Geo library is using PostGIS 和解决方案是特定于 PostGIS 的。您需要使用 ST_AsText
或来自 PostGIS 的 ST_X
和 ST_Y
select 列。
我的 select 语句更改为:
select: %{product: p, categories: fragment("json_agg( DISTINCT (?, ?)) AS category", c.id, c.name), shops: fragment("json_agg( DISTINCT (?, ?, ST_X(?), ST_Y(?))) AS shop", s.id, s.name, s.point, s.point)}