【问题标题】:How to fix InvalidParameterValue in PostGIS ST_DWithin() (in rails)如何修复 PostGIS ST_DWithin() 中的 InvalidParameterValue(在 rails 中)
【发布时间】:2017-03-07 12:46:50
【问题描述】:

我的桌子是

create_table :infomaps do |t|
  t.string :name_station
  t.string :name_location
  t.integer :waterlevel
  t.integer :rain
  t.integer :water_sealevel
  t.integer :tropical_level
  t.integer :bank_level
  t.string :river_name
  t.string :place
  t.st_point :lonlat, geographic: true
  t.integer :time
  t.timestamps null: false
end

我想使用以下示例代码:

SELECT name FROM nyc_streets WHERE ST_DWithin(
    geom,
    ST_GeomFromText('POINT(583571 4506714)',26918),
    10
  );

预期结果:

 name:Wall St, Broad St and   Nassau St

但是当尝试在 ruby​​ on rails 中这样做时,像这样:

    @result = Infomap.find_by_sql("SELECT name_station FROM infomaps    WHERE ST_DWithin(lonlat,
    ST_GeomFromText('POINT(20 100)',26918),
    100); ")

我收到此错误:

PG::InvalidParameterValue: ERROR: Only lon/lat coordinate systems are supported in geography. : SELECT name_station FROM infomaps WHERE ST_DWithin(lonlat, ST_GeomFromText('POINT(20 100)',26918), 100); 

如何解决 ST_DWithin 的 InvalidParameterValue 错误?

【问题讨论】:

  • 您的示例查询和ruby 代码中的查询完全不同。使用相同的查询,它会工作
  • EPSG:26918 是投影坐标系,而不是经纬度,geography 类型应使用该坐标系。

标签: ruby-on-rails ruby postgresql postgis


【解决方案1】:

您正在混合使用 geometrygeography 类型。请参阅此 PostGIS FAQ 了解更多上下文以及指向其他更详细讨论的链接。

当使用ST_DWithin 时,两个参数必须是同一类型。 geography(想想 lon/lat)或 geometry 在同一投影坐标系中。

请注意,您可以使用快捷方式::geography 语法将geometry 类型转换为geography。例如

SELECT name_station FROM infomaps
    WHERE ST_DWithin(
        lonlat::geography,
        ST_GeomFromText('POINT(20 100)',26918)::geography,
        100);

如果这不起作用,请尝试将几何点显式转换为 EPSG 代码 4326,例如

SELECT name_station FROM infomaps
    WHERE ST_DWithin(
        lonlat::geography,
        ST_Transform(ST_GeomFromText('POINT(20 100)', 26918), 4326)::geography,
        100);

或者,将您的 lonlat 点转换为与您的 geometry 点相同的投影坐标参考系,这应该更快计算(尽管根据您的用例可能可以忽略不计):

SELECT name_station FROM infomaps
    WHERE ST_DWithin(
        ST_Transform(lonlat, 26918),
        ST_GeomFromText('POINT(20 100)', 26918),
        100);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    相关资源
    最近更新 更多