Ошибка при построении перекрестка для дорог

Я пытался разделить необработанные данные о дороге на сегменты. Сначала я создал таблицу road_segments. Затем я преобразовал содержимое таблицы дорог в серию связанных сегментов дорог, используя shapely.

Для каждой дороги я начинаю с загрузки ее названия и геометрии в память.

Код до сих пор работает правильно.

У меня есть геометрия LineString дороги, я хочу разделить ее в каждой точке, где она касается или пересекает другую дорогу. Для этого я пытаюсь построить список перекрестков для этой дороги.

 crossroads = []
 cursor.execute("SELECT ST_AsText(centerline) FROM ROADS" +
                   "WHERE ST_Touches(roads.centerline, " +
                   "ST_GeomFromText(%s)) OR ST_Crosses(" +
                   "roads.centerline, ST_GeomFromText(%s))",
                   (wkt, wkt))
  for row in cursor:
        crossroad = shapely.wkt.loads(row[0])
        crossroads.append(crossroad)

Но выходит следующая ошибка:

---------------------------------------------------------------------------
ProgrammingError                          Traceback (most recent call last)
<ipython-input-9-0d71c4db883b> in <module>()
      4                    "ST_GeomFromText(%s)) OR ST_Crosses(" +
      5                    "roads.centerline, ST_GeomFromText(%s))",
----> 6                    (wkt, wkt))

ProgrammingError: syntax error at or near "."
LINE 1: ...sText(centerline) FROM ROADSWHERE ST_Touches(roads.centerlin...

Когда я отредактировал код, как показано ниже:

crossroads = []
cursor.execute("SELECT ST_AsText(centerline) FROM ROADS WHERE ST_Touches(roads.centerline, " +
                   "ST_GeomFromText(%s)) OR ST_Crosses(" +
                   "roads.centerline, ST_GeomFromText(%s))",
                   (wkt, wkt))
for row in cursor:
    crossroad = shapely.wkt.loads(row[0])
    crossroads.append(crossroad)

Следующая ошибка:

---------------------------------------------------------------------------
InternalError                             Traceback (most recent call last)
<ipython-input-5-b50bc9a8488c> in <module>()
      3                    "ST_GeomFromText(%s)) OR ST_Crosses(" +
      4                    "roads.centerline, ST_GeomFromText(%s))",
----> 5                    (wkt, wkt))
      6 for row in cursor:
      7     crossroad = shapely.wkt.loads(row[0])

InternalError: current transaction is aborted, commands ignored until end of transaction block

person Himal Acharya    schedule 25.05.2016    source источник
comment
Должен ли быть пробел между FROM ROADS и WHERE ST_Touches?   -  person Jeremy Weirich    schedule 25.05.2016
comment
Да ..Космос предполагается.   -  person Himal Acharya    schedule 25.05.2016
comment
Ваш стол очень большой? У меня была аналогичная проблема с огромной таблицей и неправильно настроенной установкой postgres.   -  person fradal83    schedule 25.05.2016
comment
Да, таблица большая. Я отредактировал код, как показано ниже, и все заработало: crossroads = [] cursor.execute('SELECT ST_AsText(centerline) FROM ROADS WHERE ST_Touches(roads.centerline,ST_GeomFromText(%s)) OR ST_Crosses(roads. осевая линия,ST_GeomFromText(%s))', (wkt, wkt))   -  person Himal Acharya    schedule 26.05.2016


Ответы (1)


Первая ошибка связана с тем, что между «ROADSWHERE» нет пробела, а вторая InternalError связана с тем, что транзакцию необходимо откатить, то есть conn.rollback().

Во-первых, WKB — это более быстрый способ передачи геометрии без потерь между PostGIS и Shapely. Вы можете получить это из стройной геометрии со свойством .wkb_hex и из PostGIS, не делая ничего особенного. А во-вторых, я считаю, что лучше всего писать выражения SQL с использованием тройных кавычек, например:

from shapely import wkb
cursor.execute("""\
SELECT centerline FROM ROADS
WHERE ST_Touches(roads.centerline, %(geom)s)
   OR ST_Crosses(roads.centerline, %(geom)s;
""", {'geom': geom.wkb_hex})
for row in cursor:
    crossroad = wkb.loads(row[0], hex=True)
    crossroads.append(crossroad)

Наконец, я не уверен, поможет ли это, но чтобы лучше понять, как работают предикатные операторы, такие как «Касание» и «Крестики», вы можете посмотреть DE-9IM. Вы можете создавать пользовательские предикаты с помощью ST_Relate вместо вызова двух разных предикатов.

person Mike T    schedule 26.05.2016