首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Rails / PostGIS / RGeo存储数据

用Rails / PostGIS / RGeo存储数据
EN

Stack Overflow用户
提问于 2016-12-24 19:06:27
回答 1查看 1.2K关注 0票数 2

在使用丹尼尔·祖马(氏)溶液 / Rails处理Google数据时难以实现RGeo。

设置

位置表:

代码语言:javascript
运行
复制
create_table "locations", force: :cascade do |t|
  t.string   "name",        
  t.geometry "polygon", limit: {:srid=>3857, :type=>"polygon"}
end

位置类:

代码语言:javascript
运行
复制
class Location < ActiveRecord::Base

  # Create a simple mercator factory. This factory itself is
  # geographic (latitude-longitude) but it also contains a
  # companion projection factory that uses EPSG 3857.
  FACTORY = RGeo::Geographic.simple_mercator_factory

  # To interact in projected coordinates,
  # just use the "polygon" attributes directly.
  def polygon_projected
    self.polygon
  end
  def polygon_projected=(value)
    self.polygon = value
  end

  # To use geographic (lat/lon) coordinates,
  # convert them using the wrapper factory.
  def polygon_geographic
    FACTORY.unproject(self.polygon)
  end
  def polygon_geographic=(value)
    self.polygon = FACTORY.project(value)
  end

  def self.from_geojson(geojson)

    location = Location.new
    decoded_polygon = RGeo::GeoJSON.decode(geojson, json_parser: :json, geo_factory: RGeo::Geographic.simple_mercator_factory)
    location.polygon_geographic = decoded_polygon
    return location

  end

end

initializers/rgeo.rb:

代码语言:javascript
运行
复制
RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
  # By default, use the GEOS implementation for spatial columns.
  config.default = RGeo::Geos.factory_generator
end

(从这里这里派生的解决方案)

问题

因此,我们开始-我创建一个新的位置对象从一个geojson形状包含坐标从谷歌地图:

代码语言:javascript
运行
复制
manhattan_polygon_data = '{"type":"Polygon","coordinates":[[[-73.9784998975546,40.7367992185915],[-73.9808911983494,40.7334453322506],[-73.9899687850649,40.7350399153528],[-73.9894998975546,40.7395992185915]]]}'
location = Location.from_geojson(manhattan_polygon_data)

此时,我们所有的地理属性都在正常工作:

代码语言:javascript
运行
复制
# Test geo properties:
location.polygon_projected
=> #<RGeo::Geos::CAPIPolygonImpl:0x3fc428c0c7dc "POLYGON ((-8235248.938246019 4973596.780357394, -8235515.136632829 4973104.057720993, -8236525.648963631 4973338.316345756, -8236473.452644745 4974008.150049943, -8235248.938246019 4973596.780357394))">
location.polygon_geographic
=> #<RGeo::Geographic::ProjectedPolygonImpl:0x3fc425d137a0 "POLYGON ((-73.9784998975546 40.73679921859151, -73.9808911983494 40.73344533225058, -73.9899687850649 40.73503991535281, -73.9894998975546 40.73959921859151, -73.9784998975546 40.73679921859151))">

但是当我们从数据库中保存和重新读取数据时,有些地方出错了:

代码语言:javascript
运行
复制
# Save and retrieve from DB:
location.save!
location_from_db = Location.find(location.id)

# Test geo properties again:
location_from_db.polygon_projected
=> #<RGeo::Geos::CAPIPolygonImpl:0x3fc425cfb664 "POLYGON ((-8235248.938246019 4973596.780357394, -8235515.136632829 4973104.057720993, -8236525.648963631 4973338.316345756, -8236473.452644745 4974008.150049943, -8235248.938246019 4973596.780357394))">
location_from_db.polygon_geographic
RGeo::Error::InvalidGeometry: You can unproject only features that are in the projected coordinate space.
    from /usr/local/lib/ruby/gems/2.3.0/gems/rgeo-0.5.3/lib/rgeo/geographic/factory.rb:270:in `unproject'

考虑到两个对象的投影几何是等价的,我不知道为什么后一个unproject操作失败。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-25 17:29:30

在这里找到我的答案:简单的Mercator工厂项目/Unproject- Google组

问题是,与ActiveRecord适配器使用的属性相比,我对属性使用的是不同的工厂实例。解决方案是在初始化器中创建简单mercator工厂的单个实例。

位置类:

代码语言:javascript
运行
复制
class Location < ActiveRecord::Base

  # To interact in projected coordinates,
  # just use the "polygon" attributes directly.
  def polygon_projected
    self.polygon
  end
  def polygon_projected=(value)
    self.polygon = value
  end

  # To use geographic (lat/lon) coordinates,
  # convert them using the wrapper factory.
  def polygon_geographic
    FACTORY.unproject(self.polygon)
  end
  def polygon_geographic=(value)
    self.polygon = FACTORY.project(value)
  end

  def self.from_geojson(geojson)

    location = Location.new
    decoded_polygon = RGeo::GeoJSON.decode(geojson, json_parser: :json, geo_factory: RGeo::Geographic.simple_mercator_factory)
    location.polygon_geographic = decoded_polygon
    return location

  end

end

initializers/rgeo.rb:

代码语言:javascript
运行
复制
# Create a single instance of simple mercator factory. 
# This factory itself is geographic (latitude-longitude) 
# but it also contains a companion projection factory that uses EPSG 3857.
FACTORY = RGeo::Geographic.simple_mercator_factory

RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
  config.default = FACTORY.projection_factory
end
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41316122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档