Регулярное выражение для действительных строк строки WKT (в BigQuery)?

Пока у меня есть следующее:

 select WKT, column1, column2
  from table
 where REGEXP_CONTAINS(WKT, r"-?(?:\.\d+|\d+(?:\.\d*)?)") is true

Это заботится о большинстве случаев, но я все еще получаю следующую ошибку:

ST_GeogFromText failed: Linestring should have at least two unique points, but had 1

Как я могу использовать regex для фильтрации всех недействительных строк LINESTRING в Google BigQuery? Я не могу использовать ST_NUMPOINTS(), потому что он принимает объект GEOGRAPHY, и я не могу преобразовать строку в GEOGRAPHY, если она недействительна.

Редактировать: LINESTRING WKT имеют следующий формат: LINESTRING (x1 y1, x2 y2, x3 y3, ..., xn yn), где каждая пара (xn, yn) представляет n-ю пару Lat/Long.


person manesioz    schedule 30.10.2019    source источник
comment
Для неосведомленных из нас: какая структура у строки WKT? Можете ли вы предоставить несколько образцов?   -  person Jan    schedule 30.10.2019
comment
Конечно! Я отредактирую вопрос соответственно, извините за это.   -  person manesioz    schedule 30.10.2019
comment
Итак, в заключение: у меня есть несколько записей, которые выглядят так (LINESTRING (1.00 2.00)), но они должны иметь более одной пары чисел (например: LINESTRING (1.00 2.00, 3.00 4.00) )   -  person manesioz    schedule 30.10.2019


Ответы (2)


Не используйте REGEXP — это вряд ли решит все проблемы. Например. WKT может иметь широту больше 90 градусов, что вызывает сбой в ST_GeogFromText, но почти невозможно отловить в REGEXP. Или у вас могут быть две одинаковые точки LINESTRING (1 2, 1 2), и это также недопустимая LineString.

Вместо этого используйте префикс SAFE. Функция возвращает NULL. вместо ошибочного запроса, когда ввод недействителен. Это дает вам точную проверку!

select SAFE.ST_GeogFromText('foo')
NULL
person Michael Entin    schedule 30.10.2019

Попробуйте ниже расширение вашего исходного регулярного выражения

WHERE REGEXP_CONTAINS(WKT, r'LINESTRING \((?:(?:\.\d+|\d+(?:\.\d*)?) (?:\.\d+|\d+(?:\.\d*)?)(?:, |\))){2,}')
person Mikhail Berlyant    schedule 30.10.2019
comment
Спасибо за ответ. Оказывается, использование префикса SAFE более надежно для моего варианта использования. Кроме того, на случай, если у кого-то нет этой опции, я обнаружил, что использование LINESTRING\s\((?:\-?\d{1,3}(?:\.\d+)?\s\-?\d{1,3}(?:\.\d+)?)(?:\,\s?\-?\d{1,3}(?:\.\d+)?\s\-?\d{1,3}(?:\.\d+)?)+\) в любом случае более надежно, поскольку позволяет захватывать возможные значения, такие как: LINESTRING (-10.00002 111.222222,2 -4,1.646373 -20.555). - person manesioz; 31.10.2019
comment
конечно, нет проблем. мне было трудно представить, что вы не знали о префиксе SAFE. поэтому я предположил, что вы специально ищете вариант регулярного выражения. и да - похоже, я пропустил -? для обращения к отрицательным значениям :o) - person Mikhail Berlyant; 31.10.2019