计算Linestring米制长度时遇无效几何错误,求问题排查
解决PostGIS ST_Length调用的解析错误问题
嘿,这个错误的原因其实一眼就能看出来——你在SQL查询里犯了个小失误:把path列名用单引号括起来了!
当你写ST_Length('path')的时候,PostgreSQL会把'path'当成一个普通的字符串字面量,而不是tracks表中的path几何列。PostGIS尝试把这个字符串解析成几何对象时,自然会失败,因为"pa"根本不是有效的WKT(Well-Known Text)几何格式的开头,这就是错误提示里"pa" <-- parse error的由来。
修正方案1:修正原生SQL查询
把SQL里的单引号去掉,让数据库识别path是列名,同时还要处理find_by_sql的返回值(它返回的是数组,我们需要提取具体的长度数值):
def show @track = Track.friendly.find(params[:id]) # 去掉path的单引号,添加别名方便取值,然后取出第一个结果的length属性 length_result = Track.find_by_sql ["SELECT ST_Length(path) AS length FROM tracks WHERE id = ?", @track.id].first @track_length = length_result&.length end
对应的视图可以正常显示:
<p>Track id : <%= @track.id%></p> <p>Longueur : <%= @track_length %> 米</p> <p>Linestring : <%= @track.path %></p>
修正方案2:用更Rails化的方式(推荐)
如果你已经使用了activerecord-postgis-adapter这类PostGIS适配gem,完全不需要写原生SQL,直接通过模型对象调用几何字段的方法即可:
def show @track = Track.friendly.find(params[:id]) # 直接调用path字段的length方法,适配gem会自动转换为PostGIS的ST_Length查询 @track_length = @track.path.length end
额外注意事项
还要确认你的path字段的坐标系:
- 如果是米制投影坐标系(比如EPSG:3857、EPSG:2154),
ST_Length返回的就是米为单位的长度,没问题。 - 如果是地理坐标系(比如EPSG:4326,WGS84经纬度),
ST_Length返回的是度为单位的数值,不是真实的米制长度。这时候需要用ST_Length_Spheroid来计算球面长度,比如:
# 原生SQL写法 length_result = Track.find_by_sql ["SELECT ST_Length_Spheroid(path, 'SPHEROID[\"WGS 84\",6378137,298.257223563]') AS length FROM tracks WHERE id = ?", @track.id].first
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

