如何找到包含特殊lat长点的所有多边形

时间:2017-07-18 11:46:39

标签: ruby-on-rails postgis rgeo

我使用rgeo和activerecord-postgis-adapter gem。我想找到多边形中包含特殊点的所有记录。我在谷歌地图上标记了矩形,如果点在里面,则期望sql返回行,当点在外面时,不会返回行。不幸的是,/routes/{placeholder}/idLocationA/idLocationB也会返回结果。我做错了什么?我应该使用预测而不是真正的lat-long吗?

enter image description here

point_outside_2

迁移:

describe 'polygon' do
  let(:factory) { RGeo::Geographic.simple_mercator_factory }

  let(:left_up_corner) { factory.point(50.095073, 19.852121) }
  let(:right_up_corner) { factory.point(50.092230, 20.057740) }
  let(:left_bottom_corner) { factory.point(50.021297, 19.857577) }
  let(:right_bottom_corner) { factory.point(50.015820, 20.051943) }

  let(:point_inside_1) { factory.point(50.059631, 19.939323) }
  let(:point_inside_2) { factory.point(50.029995, 19.941997) }
  let(:point_outside_1) { factory.point(50.153008, 19.990906) }
  let(:point_outside_2) { factory.point(50.118037, 19.970446) }


  let(:line) { factory.line_string([left_up_corner, right_up_corner, right_bottom_corner, left_bottom_corner]) }
  let(:area) { factory.polygon(line) }

  it 'finds nurses with polygon include point' do
    Nurse.create(area: area)
    expect(count_nurses(point_inside_1)).to be 1
    expect(count_nurses(point_inside_2)).to be 1
    expect(count_nurses(point_outside_1)).to be 0
    expect(count_nurses(point_outside_2)).to be 0 # it return 1
  end

  def count_nurses(point)
    Nurse.where("ST_DWithin(area, ST_Point(#{point.coordinates.join(',')}), 4326)").count
  end
end

1 个答案:

答案 0 :(得分:1)

试试这个,我在使用RGeo的应用程序中做类似的事情来查找多边形内的点。希望这对你有用

describe 'polygon' do
  let(:factory) { RGeo::Geographic.simple_mercator_factory }
  let(:ewkb_generator) do
    RGeo::WKRep::WKBGenerator.new(
      type_format:    :ewkb,
      emit_ewkb_srid: true,
      hex_format:     true
    )
  end

  let(:left_up_corner) { factory.point(50.095073, 19.852121) }
  let(:right_up_corner) { factory.point(50.092230, 20.057740) }
  let(:left_bottom_corner) { factory.point(50.021297, 19.857577) }
  let(:right_bottom_corner) { factory.point(50.015820, 20.051943) }

  let(:point_inside_1) { factory.point(50.059631, 19.939323) }
  let(:point_inside_2) { factory.point(50.029995, 19.941997) }
  let(:point_outside_1) { factory.point(50.153008, 19.990906) }
  let(:point_outside_2) { factory.point(50.118037, 19.970446) }


  let(:line) { factory.line_string([left_up_corner, right_up_corner, right_bottom_corner, left_bottom_corner]) }
  let(:area) { factory.polygon(line) }

  it 'finds nurses with polygon include point' do
    Nurse.create(area: area)
    expect(count_nurses(point_inside_1)).to be 1
    expect(count_nurses(point_inside_2)).to be 1
    expect(count_nurses(point_outside_1)).to be 0
    expect(count_nurses(point_outside_2)).to be 0 # it return 1
  end

  def count_nurses(point)
    ewkb = ewkb_generator.generate(point.projection)
    Nurse.where('ST_Intersects(area, ST_GeomFromEWKB(E?))', "\\\\x#{ewkb}").count
  end
end