在Rails 4.2.4和activerecord-postgis-adapter 3.1.2中有一个带RGeo列的表
class CreateAddresses < ActiveRecord::Migration
def change
create_table :addresses do |t|
t.st_point :coordinates, geographic: true, srid: 4326
end
add_index :addresses, :coordinates, using: :gist
end
end
Run Code Online (Sandbox Code Playgroud)
以及按对象位置对对象进行分组的方法
def self.group_by_coords
includes(:address).
joins(:address).
group('addresses.coordinates::geometry').
pluck(
'array_agg(realties.id) as ids, addresses.coordinates::geometry'
)
end
Run Code Online (Sandbox Code Playgroud)
与相应的测试:
describe 'group_by_coords' do
it 'correctly group realties' do
# create samples
expect(Realty.group_by_coords).to eq(
[[[r1.id, r2.id], r1.address.coordinates], [[r3.id], r3.address.coordinates]]
)
end
end
Run Code Online (Sandbox Code Playgroud)
问题是pluck返回 RGeo::Geos::CAPIPointImpl而不是 RGeo::Geographic::SphericalPointImpl
expected: [[[1670, 1671], #<RGeo::Geographic::SphericalPointImpl:0x3fd37e9b8a20 "POINT (106.0 10.0)">], [[1672], #<RGeo::Geographic::SphericalPointImpl:0x3fd37ab2dddc "POINT (106.5 10.5)">]] …Run Code Online (Sandbox Code Playgroud) 我正在使用RoR和PostGIS来存储位置数据.我正在尝试使用圆形存储估计的位置(例如,带有半径的中心点).
我尝试过类似的东西,但它不起作用:
@location = Location.new(:place_id => place.id,
:circle => %{ST_Buffer(ST_MakePoint(#{latitude}, #{longitude})::geography, #{accuracy})})
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用RGeo和它的工厂,但不确定如何使用它.
任何帮助将不胜感激.谢谢.
编辑1:我取得了一些进展.
factory = RGeo::Cartesian.factory
center_point = factory.point(latitude, longitude)
circle = center_point.buffer(accuracy)
@location = Location.new(:place_id => place.id,
:circle => circle)
Run Code Online (Sandbox Code Playgroud)
但是 - 现在它抛出以下异常:
can't cast RGeo::Cartesian::Polygon Impl to string
Run Code Online (Sandbox Code Playgroud)
再次,任何帮助将不胜感激.
我有一个使用rgeo 0.3.19的rails应用程序,proj4支持使用rgeo-activerecord 0.4.5 gem连接到PostGIS 1.5数据库.
我的应用程序有一个名为Region的模型,它包含一个地理点,一个半径和一个多边形.当一个新区域即将保存时,它使用区域的geofactory缓冲区函数来使用半径和地理点创建多边形.
这是用于区域模型的geofactory
GEOFACTORY = RGeo::Geographic.projected_factory(:buffer_resolution => 8, :projection_proj4 => '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs', :projection_srid => 3857)
Run Code Online (Sandbox Code Playgroud)
我正在使用的projection_srid是Apple和Google映射的mercator投影3857.问题是正在创建的缓冲区与我在苹果地图或谷歌地图中绘制的缓冲区大小不同.例如,如果我使用内置的MapKit函数MKCircle
[MKCircle circleWithCenterCoordinate:self.coordinate radius:50];
Run Code Online (Sandbox Code Playgroud)
圆圈将像这样绘制和叠加.

但是如果我从数据库中构成多边形形状的缓冲函数创建的坐标并在谷歌地图上绘制它我得到了这个.

如您所见,使用相同投影系统创建的多边形小于应有的多边形.该问题基于所定义的半径的大小呈指数地失控.我也尝试使用RGeo中定义的simple_mercator工厂,它产生了相同的结果.
希望有人能够深入了解为什么当经度,纬度投影点被缓冲时,它会创建一个不正确大小的多边形.
我正在使用一个MySQL数据库,其中多边形以WKT格式存储.数据库中的许多多边形具有重复点(例如,在下面的示例中,点-122.323502 47.600959重复三次).
当试图在这些多边形上调用RGeo :: Cartesian :: Factory.parse_wkt()时,结果为nil.
如何在不修改多边形数据的情况下从这些多边形创建RGeo对象.
poly = "MULTIPOLYGON(((-122.362163 47.618641,-122.344621 47.592555,-122.332017 47.592458,-122.32748 47.59241,-122.326109 47.592652,-122.324738 47.592895,-122.323147 47.593478,-122.321412 47.59411,-122.320826 47.594984,-122.320669 47.596296,-122.321149 47.598627,-122.323502 47.600959,-122.323502 47.600959,-122.323502 47.600959,-122.324071 47.601688,-122.320757 47.601688,-122.32073 47.604262,-122.320767 47.607663,-122.320746 47.609703,-122.320723 47.611938,-122.320714 47.612812,-122.320772 47.614075,-122.320799 47.618495,-122.362163 47.618641)))"
parsed_poly = RGeo::Cartesian::Factory.new().parse_wkt(poly)
=>nil
Run Code Online (Sandbox Code Playgroud) 在尝试运行迁移以添加空间索引时,请获取
Unknown key: spatial/Users/ME/.rvm/gems/ruby-2.0.0-p353/gems/activesupport-4.0.2/lib/active_support/core_ext/hash/keys.rb:70:in `block in assert_valid_keys'
Run Code Online (Sandbox Code Playgroud)
运用
迁移索引文件看起来像
class CreateAddresses < ActiveRecord::Migration
def change
create_table :addresses, :options => 'ENGINE=MyISAM' do |t|
t.string :street_1
t.string :street2
t.string :city
t.string :state
t.string :zip
t.string :country
t.string :full_address
t.column :latlon, :point, :null => false
t.timestamps
end
add_index :addresses, :latlon, :spatial => true
end
end
Run Code Online (Sandbox Code Playgroud)
UPDATE
当我将database.yml文件中的适配器从mysql2更改为mysql2spatial时,更正了此错误和其他错误
我试图将"原始"PostGIS SQL查询转换为Rails ActiveRecord查询.我的目标是将两个连续的ActiveRecord查询(每个需要大约1毫秒)转换为单个ActiveRecord查询(~1ms).使用下面的SQL ActiveRecord::Base.connection.execute我能够验证时间的减少.
因此,我的直接请求是帮助我将此查询转换为ActiveRecord查询(以及执行它的最佳方法).
SELECT COUNT(*)
FROM "users"
INNER JOIN (
SELECT "centroid"
FROM "zip_caches"
WHERE "zip_caches"."postalcode" = '<postalcode>'
) AS "sub" ON ST_Intersects("users"."vendor_coverage", "sub"."centroid")
WHERE "users"."active" = 1;
Run Code Online (Sandbox Code Playgroud)
请注意,该值<postalcode>是此查询中唯一的可变数据.显然,这里有两个型号User和ZipCache.User与...没有直接关系ZipCache.
当前的两步ActiveRecord查询如下所示.
zip = ZipCache.select(:centroid).where(postalcode: '<postalcode>').limit(1).first
User.where{st_intersects(vendor_coverage, zip.centroid)}.count
Run Code Online (Sandbox Code Playgroud) 我想从两个几何的并集创建一个新的MultiPolygon,但它返回nil.
multipolygon_1 = RGeo::Geos.factory(srid: 4326).parse_wkt("MULTIPOLYGON ...")
multipolygon_2 = RGeo::Geos.factory(srid: 4326).parse_wkt("MULTIPOLYGON ...")
multipolygon_1 + multipolygon_2 # => nil
Run Code Online (Sandbox Code Playgroud)
可以在以下要点中找到重现此错误的MultiPolygons值:
https://gist.github.com/babasbot/926ae326ff3eb4a79601d56288e82a5f


我有一堆具有自相交的多边形,这在进一步后处理它们时会导致一些错误(特别是 - 我无法计算这些多边形与其他多边形的相交面积)。这是一个破碎多边形的例子:
{
"type": "MultiPolygon",
"coordinates": [
[
[
[
6.881057785381658,
46.82373306675715
],
[
6.857171686909481,
46.81861230543794
],
[
6.857354659059071,
46.81856788926046
],
[
6.856993473052509,
46.82693029065604
],
[
6.8612894138116785,
46.83422796373707
],
[
6.86720955648855,
46.835636765630476
],
[
6.871281147359957,
46.83078486366309
],
[
6.871573291317274,
46.8306215963777
],
[
6.877608228639841,
46.82771553607934
],
[
6.877758462659651,
46.82772313420989
],
[
6.877852632482749,
46.827735617670285
],
[
6.880928107931434,
46.82630213148064
],
[
6.8810399979122305,
46.82622029042867
],
[
6.881117606743071,
46.826115612819855
],
[
6.881057785381658,
46.82373306675715
]
]
]
]
}
Run Code Online (Sandbox Code Playgroud)
这就是地图上的样子 - 如您所见,两条多边形边相交。RGeo引发错误,指向交点坐标(I猜): => "Geos::GEOSException: TopologyException: …
我尝试按照自述文件安装activerecord-postgis-adapter但无法创建模型实例,因为我不断收到下面提到的错误:
NoMethodError:nil的未定义方法"point":NilClass
以下是我的不同文件的样子:
Location.rb(模型,更新代码)
# == Schema Information
#
# Table name: locations
#
# id :integer not null, primary key
# locatable_id :integer
# locatable_type :string
# created_at :datetime not null
# updated_at :datetime not null
# coordinates :geography({:srid point, 4326
#
class Location < ActiveRecord::Base
#self.rgeo_factory_generator = RGeo::Geos.factory_generator
#set_rgeo_factory_for_column(:coordinates,
# RGeo::Geographic.spherical_factory(:srid => 4326) )
locFactory = RGeo::ActiveRecord::SpatialFactoryStore.instance.factory(:geo_type => 'point')
belongs_to :locatable,
polymorphic: true
validates :locatable, presence: true
attr_accessor :longitude, :latitude
end
Run Code Online (Sandbox Code Playgroud)
的Gemfile
gem 'rgeo'
gem 'rgeo-activerecord'
gem 'activerecord-postgis-adapter' …Run Code Online (Sandbox Code Playgroud) rgeo ×10
ruby ×6
postgis ×5
activerecord ×2
gis ×2
arel ×1
geojson ×1
mysql ×1
polygon ×1
postgresql ×1