При анализе картографических данных часто бывает нужно найти объекты из одного слоя, относящиеся к определенным объектам в другом слое. Например, у нас есть слой c административными районами и слой с дорожной сетью, и мы хотим выделить все дороги, относящиеся к одному из районов.
Для этого в MapInfo Pro можно написать небольшой универсальный скрипт на MapBasic, который можно будет сохранить и использовать в дальнейшем во всех таких случаях. Скрипт будет сравнивать выбранные в данный момент объекты (текущую выборку) с объектами из указанной таблицы, и будет отбирать только те записи, которые пересекаются.
Создание скрипта
Откроем окно "SQL", добавленное в MapInfo v2019, из меню на вкладке "Объекты" и создадим в нем следующий скрипт.
Вот его текст для вашего удобства:
Select *
From sTabToQuery
Where OBJ Intersects
(Select AggregateCombine(obj) From Selection)
Into Selection
Давайте рассмотрим запрос немного подробнее.
Таблица, которую мы указали для выбора - sTabToQuery, является не конкретной таблицей, а переменной. Создадим эту переменную с помощью "Редактирования переменных" из раскрывающего списка "Переменные" в окне SQL.
Тип переменной - Таблица. Это означает, что при запуске скрипта MapInfo Pro предложит выбрать таблицу из списка всех открытых таблиц. В поле "Значения" укажем следующее выражение: TableInfo(ScriptContext(SCRIPT_CONTEXT_TABLEALIAS), TAB_INFO_MAPPABLE), чтобы ограничить список таблиц только таблицами с возможностью отображения. В выражение также можно добавить и другие дополнительные условия на ваше усмотрение, например, чтобы в списке были только TABы или нельзя было выбрать растры.
Сохраним новую переменную и вернемся назад в окно SQL.
Обратите внимание на две вещи в "Where" части запроса. Первый заключается в том, что мы указали Intersect в качестве пространственного оператора. Если вы знаете, что будете сравнивать точки с полигонами, вы также можете использовать оператор Within/Contains. Почему не стоит использовать Within/Contains для полигонов и полилиний? Потому, что эти операторы сравнивают центроиды объектов, а центроиды полигона и полилинии зачастую не дают хорошего представления об объекте, т.к. находятся вне его пределов.
Второе, на что следует обратить внимание, это то, что мы используем подвыборку, в которой объединяем объекты из текущей выборки в один объект с помощью пространственного агрегата AggregateCombine. Объединение выбранных объектов обычно выполняется очень быстро. Особенно, если вы используете небольшие полигоны, такие как зоны транспортной доступности или административные границы. Однако, если вы используете полигоны большего размера - например, огромные полигоны покрытия телекоммуникационных компаний, можно заметить, что запрос выполняется медленее обычного.
Не забудьте указать имя для скрипта, а также сохранить его.
Использование скрипта
Выберем интересующий нас площадной объект, например, парковую зону, как в данном примере, состоящую из нескольких полигонов.
Далее из раскрывающегося списка "SQL" на вкладке "Объекты" выберем и запустим созданный нами скрипт.
Появится окошко, где нужно будет только указать талицу, в которой будет производиться поиск пересечений. В данном случае выбран слой с дорогами.
В результате выполнения скрипта создастся новый запрос с объектами из указанного слоя, пересекающими изначальный выбранный объект.
Заключение
Несмотря на то что запрос составлен правильно, он может не дать вам именно то, что вы ищете. Данный запрос возвращает любую запись, которая каким-либо образом пересекает выборку. Это означает, что возвращаемые записи могут лишь частично пересекаться с выборкой. Может быть и такое, что они вообще имеют только один общий узел, формально это тоже считается пересечением.
Поэтому обратите внимание: если вы используете результат этого запроса, то будете использовать объект целиком, а не только ту его часть, которая пересекает выборку. То же самое относится и к значениям атрибутов. Возможно, вы захотите воспользоваться функцией ProportionalOverlap для вычисления пропорциональных значений. Если вы знаете, какие столбцы есть в вашей таблице, вы можете также включить эти пропорциональные вычисления непосредственно в запрос. То есть вместо использования простого оператора Intersect можно добавить более сложные методы для принятия решения о включении или невключении записи в набор результатов.
Другие полезные статьи:
Новые возможности SQL в MapInfo Pro 2019 |
Расположение файлов таблиц и рабочих наборов в MapInfo Pro |
Использование функции ProportionOverlap в MapInfo Pro |