2017-07-18 74 views
0

我使用rgeo和activerecord-postgis-adapter gem。我想查找包含多邊形中特殊點的所有記錄。我在谷歌地圖上標記了矩形,並期望sql返回行,如果點在裏面,並且當點在外面時不返回行。不幸的是​​也返回結果。我做錯了什麼?我應該使用投影而不是真正的經緯度?如何找到所有包含特殊緯度長點的多邊形

enter image description here

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 

遷移:

class AddPolygonToNurse < ActiveRecord::Migration[5.1] 
    def change 
    add_column :nurses, :area, :st_polygon, :geographic => true 
    add_column :nurses, :latlong, :st_point, :geographic => true 
    end 
end 
+2

'ST_Dwithin',你是內4326米多邊形的詢問點。如果你在多邊形內尋找點,它應該是0。您還正在使用地理座標(lat/long)和'simple_mercator_factory'這是一個投影座標系(其中一個錯誤,無論是座標還是工廠) – JGH

+1

是的,我相信他正在尋找[ST_Contains](https ://postgis.net/docs/ST_Contains.html)而不是'ST_Dwithin'。 4326是WGS86地理投影系統的編號。第2點可能在框內4.326公里內。 –

+0

@JGH這是一個正確的答案。非常感謝你。我將4326更改爲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 
+0

這是有益的,但它不是直接的答案。 @JGH解決我的問題。您的解決方案基於不同格式的點。即使這是正確的,我認爲它更復雜一點 –

相關問題