使用group\u concat()在mysql中生成多边形

f8rj6qna  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(322)

我有一个有列的表 zone (作为字符串的区域名称), longitude (十进制), latitude (十进制), logical order (整数)。 logical_order 指示可以组合坐标以创建多边形的顺序。例如,每个区域在该表中都有多个具有不同属性的行 longitude , latitude . 对于每个分区行 logical_order 将从1开始(作为起点),每行增加一个。例如,如果一个区域有3个点, logical_order 将从1运行到3。3处的坐标与1处的坐标不同。换句话说,坐标不闭合多边形。
我在努力创造 POLYGON 通过将每个分区的坐标分组并使用如下空间包:
我尝试了以下查询:

SELECT t0.zone, ST_GeometryFromText(CONCAT("'POLYGON((", GROUP_CONCAT(t0.coordinate ORDER BY t0.logical_order SEPARATOR ','), "))'")) FROM
(
    (SELECT zone, CONCAT(longitude, ' ', latitude) AS coordinate, logical_order FROM zones)
    UNION ALL
    (SELECT zone, CONCAT(longitude, ' ', latitude) AS coordinate, 1000 AS logical_order FROM zones WHERE logical_order = 1)
) t0 
GROUP BY t0.zone

但是,这给了我一个错误:

Error Code: 3037. Invalid GIS data provided to function st_geometryfromtext.

如何修复此错误?我走对路了吗?
编辑:
如果我尝试不带 ST_GeometryFromText() 在第二个查询中,我得到如下字符串:

POLYGON(77.5068350000 -11.4907909800,179.7363280000 -11.4907909800,179.7363280000 -60.0000000000,77.5068350000 -60.0000000000,77.5068350000 -11.4907909800)

加上两个括号后,仍然会出现相同的错误:

POLYGON((77.5068350000 -11.4907909800,179.7363280000 -11.4907909800,179.7363280000 -60.0000000000,77.5068350000 -60.0000000000,77.5068350000 -11.4907909800))

编辑2:
我还手动检查了一个接一个的多边形封闭,这是罚款每个区域。我增加了字符数的限制 group_concat() 我也是。但这个错误仍然存在。
编辑3:
sql摆弄示例数据:http://www.sqlfiddle.com/#!9/5094e5/5号

py49o6xq

py49o6xq1#

伊佩尔库贝回答了这个问题ᵀᴹ 在数据库交换中。你可以参考这里的实际答案和讨论。
有几个问题:
字符数的默认值 group_concat_max_len 太低了切断了一些坐标
用在最外层的双引号 CONCAT() 造成了问题。需要使用单引号
就像我用 GROUP BY 这是值得怀疑的。
为了未来用户的利益,我将把答案复制到这里:
错误的原因可能是“循环”未闭合,即多边形中的最后一个点与第一个点不匹配。
这可能来自两个问题:
这个 group_concat_max_len 设置太低(默认值为1024)。
解决方案:在服务器或会话级别增加它。
容易出错 GROUP BY 用于添加附加点。
这个 GROUP BY 您使用的很容易给出错误的结果,因为它可能并不总是选择您想要的行( WHERE logical_order = 1 )要读取坐标:

(
    SELECT zone, 
           CONCAT(longitude, ' ', latitude) AS coordinate, 
           logical_order 
    FROM zones
    UNION
    -- This is to close the polygon by adding the first coordinate also 
    -- as the final coordinate of the zone. 
    SELECT zone, 
           CONCAT(longitude, ' ', latitude) AS coordinate, 
           COUNT(zone) + 1 AS logical_order 
    FROM zones 
    GROUP BY zone
) t0

我会这样写:

(
    SELECT zone, 
           CONCAT(longitude, ' ', latitude) AS coordinate, 
           logical_order 
    FROM zones
    UNION ALL
    -- This is to close the polygon by adding the first coordinate also
    -- as the final coordinate of the zone. 
    SELECT zone, 
           CONCAT(longitude, ' ', latitude), 
           1000000     -- unlikely to have a million points polygon
    FROM zones
    WHERE logical_order = 1
) t0

最终工作查询:

SELECT t0.zone, ST_GeometryFromText(CONCAT('POLYGON((', GROUP_CONCAT(t0.coordinate ORDER BY t0.logical_order SEPARATOR ','), '))')) FROM
(
    (SELECT zone, CONCAT(longitude, ' ', latitude) AS coordinate, logical_order FROM zones)
    UNION
    (SELECT zone, CONCAT(longitude, ' ', latitude) AS coordinate, 10000 AS logical_order FROM zones WHERE logical_order = 1)
) t0 
GROUP BY t0.zone;

需要设置 group_concat_max_len 适当地。

相关问题