尝试计算某个距离和最近点的最近点。
db / migrate / xxx_create_points.rb中的“:
class CreatePoints < ActiveRecord::Migration
def change
create_table :points do |t|
t.point :location, :geographic => true
t.string :name, :null => false
t.timestamps
end
change_table :points do |t|
t.index :location, :spatial => true
end
end
end
在config / routes.rb中:
get 'points/:lat/:lon/:distance', to: 'points#index', :constraints => { :lat => /[^\/]+/, :lon => /[^\/]+/}
在controllers / points_controller.rb中:
class PointsController < ApplicationController
def index
@points= Point.all
if params[:distance].present? && params[:lat].present? && params[:lon].present?
@distance = params[:distance].to_i
@latitude = params[:lat].to_f
@longitude = params[:lon].to_f
@points= Point.near(@latitude, @longitude, @distance)
@near = Point.nearest(@latitude, @longitude, 100).first
end
end
在models / point.rb中:
class Point < ActiveRecord::Base
set_rgeo_factory_for_column(:location,
RGeo::Geographic.spherical_factory(:srid => 4326))
attr_accessible :location, :name
scope :near, lambda { |latitude, longitude, distance|
where("ST_Distance(location,
"+"'POINT(#{latitude} #{longitude})') < #{distance}")}
scope :nearest, lambda { |latitude, longitude, distance|
where("ST_Distance(location,
"+"'POINT(#{latitude} #{longitude})') < {distance}")
.order("ST_Distance(location, ST_GeographyFromText('POINT(#{latitude} #{longitude})'))").limit(1)}
end
在views / points / index.html.erb中:
<script>
$.each(response.data, function(i, point) {
$('#map_canvas').gmap('addMarker', {
'position': new google.maps.LatLng(point.latitude, point.longitude), 'bounds': true });
}
$('#map_canvas').gmap('addShape', 'Circle', {
...
'center': new google.maps.LatLng(<%= "#{@latitude},#{@longitude}" %>),
'radius': 1 });
$('#map_canvas').gmap('addShape', 'Circle', {
...
'center': new google.maps.LatLng(<%= "#{@latitude},#{@longitude}" %>),
'radius': <%= @distance %> });
$('#map_canvas').gmap('addShape', 'Circle', {
...
'center': new google.maps.LatLng(<%= "#{@near.location.x},#{@near.location.y}" %>),
'radius': 2 });
</script>
浏览器中的结果:http://xxx/points?distance=200&lat=55.7632500&lon=52.442000
我做错了什么?
答案 0 :(得分:1)
PostGIS始终使用坐标轴顺序(X Y)或(经度纬度)。我在代码中看到了相反的片段:
ST_GeographyFromText('POINT(#{latitude} #{longitude})')
这需要切换:
ST_MakePoint(#{longitude}, #{latitude})::geography
答案 1 :(得分:0)
Google地图使用墨卡托投影,您看到的差异可能是由您在模型中使用的球形投影与墨卡托投影之间的距离计算差异引起的。
尝试在Point类中使用RGeo的simple_mercator_factory,而不是使用spherical_factory。
RGeo's documentation为您提供了有关详细信息。
# Many popular visualization technologies, such as Google and Bing # maps, actually use two coordinate systems. The first is the # standard WSG84 lat-long system used by the GPS and represented # by EPSG 4326. Most API calls and input-output in these mapping # technologies utilize this coordinate system. The second is a # Mercator projection based on a "sphericalization" of the WGS84 # lat-long system. This projection is the basis of the map's screen # and tiling coordinates, and has been assigned EPSG 3857.