如何通过遍历现有的OSM数据表在PostgreSQL中生成新表

1 投票
1 回答
2120 浏览
提问于 2025-04-17 15:24

我有一个PostgreSQL数据库,里面存的是伦敦的OSM地图数据。我是通过osm2psql这个工具导入这些数据的。现在我想做以下几件事:

  • 遍历planet_osm_line这个表里的每一条线
  • 把这些线分成一个个独立的线段
  • 给每个线段计算一个值(在这个例子里,值设为0.5)
  • 把这些线段作为新记录写入一个新表里。

下面的Python代码似乎可以实现这些功能,但有一个问题。它好像只访问了数据库的一小部分。

import psycopg2

conn = psycopg2.connect("dbname=db user=username")
maincur = conn.cursor()
readcur = conn.cursor()
writecur = conn.cursor()

maincur.execute("DROP TABLE lines_red")
maincur.execute("CREATE TABLE lines_red (osm_id bigint, name text, way geometry, value float);")

maincur.execute("SELECT osm_id, ST_NPOINTS(way) FROM planet_osm_line")
    for record in maincur:
    pointlist = []
    for i in range(0,record[1]):
        readcur.execute("SELECT ST_ASTEXT(ST_POINTN(way, %s+1)) FROM planet_osm_line WHERE osm_id=%s;",(i,record[0]))
        output = readcur.fetchone()
        pointlist.append(output[0])
    for i in range(0,record[1]-1):  
        if pointlist[i+1] != None:
            value = 0.5
            writecur.execute("INSERT INTO lines_red (name, way, value) VALUES ('testname', ST_Makeline(%s, %s), %s);", (pointlist[i],pointlist[i+1],value))

conn.commit()
maincur.close()
readcur.close()
writecur.close()
conn.close()

为了说明这个问题,下面的图片展示了完整的planet_osm_line表(灰色部分)和查询结果(红色部分)。红色的线应该覆盖整个地图,因为代码应该遍历完整的planet_osm_line表。我正在使用tilemill来显示结果。

尝试遍历整个planet_osm_line表的结果

1 个回答

0

这个问题出在我使用TileMill的时候。

当你创建一个新图层时,它的默认设置是根据输入的数据库表来预先计算范围。这意味着这个图层的大小只会和最开始创建它时用的数据集一样。

在我的情况下,我是先用一部分数据来测试我的代码,所以范围是根据这部分数据计算出来的。当我用整个数据集来运行代码时,代码确实遍历了整个数据库,但只显示了之前计算的范围内的结果。

解决办法是创建一个新图层,或者把图层的范围设置改成“动态”,而不是“预计算”。

撰写回答