Таблицы¶
Для того, чтобы мы могли работать как с географической, так и с атрибутивной информацией, данные в Аксиоме.ГИС организованы в виде групп файлов, имеющих общее имя, но разные расширения.
Пользователь оперирует только с одним файлом из этой группы – так называемым «табличным» файлом, которые имеет расширение TAB. Все файлы из группы автоматически создаются, обновляются и поддерживаются самой программой Аксиома.ГИС.
Открытие таблиц¶
Работа с источником данных начинается с открытия объекта данных
с помощью функции openfile()
. Для таблиц возвращаемый
объект данных будет типа axipy.da.Table
.
from axipy import io
table = io.openfile('../path/to/datadir/worldcap.tab')
Некоторые форматы могут содержать несколько таблиц в одном файле,
например GeoPackage. В таком случае нужно указать в параметре
dataobject=
, какую таблицу из файла вы хотите открыть.
table = io.openfile('../path/to/datadir/example.gpkg', dataobject='world')
Источники данных и дополнительные параметры¶
Источником данных может быть не только файл. Например, это может быть База Данных. Также для открытия или создания некоторых объектов данных может понадобиться указать дополнительные параметры, применимые только для этого типа источника.
Для открытия таких Объектов данных используется функция
open()
,
которая принимает словарь со всеми необходимыми параметрами.
Пример открытия таблицы из базы данных PostgreSQL:
from axipy import io
definition = {
"src": "<Адрес сервера БД>",
"port": 5432,
"db": "<Имя базы данных>",
"user": "<Имя прользователя>",
"password": "<Пароль>",
"dataobject": '"DataAxi"."World"',
"provider": "PgDataProvider"
}
table = io.open(definition)
Функцию open()
можно использовать и для рассмотренного
нами ранее простого открытия из файла. Можно сказать, что она более
универсальна.
Функция openfile()
реализована через функцию
open()
:
definition = { 'src': '../path/to/datadir/example.gpkg', 'dataobject': 'world' }
table = io.open(definition)
table.name
>>> 'world'
Открытие источников с множеством таблиц¶
При открытии Таблицы функцией open()
есть параметр
dataobject
. Он содержит имя таблицы, которую необходимо открыть. Для
источников данных с единственной Таблицей этот параметр можно опустить.
Для источников с множеством таблиц, например, базы данных или файла
GeoPackage, этот параметр обязателен.
Для получения всех доступных таблиц используется функция
read_contents()
:
from axipy import io
io.read_contents('../path/to/datadir/example.gpkg')
>>> ['world', 'worldcap']
Для источников с единственной таблицей список будет содержать одно имя:
io.read_contents({'src': '../path/to/datadir/worldcap.tab'})
>>> ['worldcap']
Провайдеры¶
Дополнительным параметром при открытии таблиц является Провайдер. Обычно Аксиома может сама определить, каким провайдером открывать файл.
Для получения списка загруженных провайдеров есть функция loaded_providers()
.
Например:
io.loaded_providers()
{'CsvDataProvider': 'Файловый провайдер: Текст с разделителями',
'DwgDgnFileProvider': 'Провайдер DWG и DGN (Версия 5.0.19.123)',
'GdalDataProvider': 'Растровый провайдер GDAL',
'MifMidDataProvider': 'Провайдер данных MIF-MID',
'OgrDataProvider': 'Векторный провайдер OGR',
'PgDataProvider': 'PostgreSQL',
'RestDataProvider': 'ArcGIS REST',
'SqliteDataProvider': 'Векторный провайдер sqlite',
'TabDataProvider': 'MapInfo',
'TerplanDataProvider': 'Провайдер территориального планирования',
'TileDataProvider': 'Растровый провайдер тайлов',
'TmsDataProvider': 'Тайловые сервисы',
'WfsDataProvider': 'Web Feature Service',
'WmsDataProvider': 'Web Map Service',
'WmtsDataProvider': 'Web Map Tile Service',
'XlsDataProvider': 'Провайдер чтения файлов Excel'}
Но иногда провайдер необходимо задать явно. Например, если один тип файлов может быть открыт несколькими провайдерами (например, GeoPackage, который может содержать как таблицу с атрибутикой, так и растр), или при подключении к СУБД.
table = io.openfile('../path/to/datadir/example.gpkg', dataobject='worldcap', provider='SqliteDataProvider')
table.name
>>> 'worldcap'
У таблицы можно узнать провайдер, которым она была открыта - свойство
axipy.da.DataObject.provider
:
table.provider
>>> 'SqliteDataProvider'
Схема таблицы¶
Записи таблицы имеют фиксированную структуру, повторяющую столбцы
таблицы. Схема представлена типом axipy.da.Schema
.
Свойство axipy.da.Schema.coordsystem
указывает на то, что
таблица является пространственной. Атрибуты axipy.da.Attribute
перечислены в том же порядке, что и столбцы таблицы.
Совет
Схему можно рассматривать как список list
атрибутов
axipy.da.Attribute
. Манипулировать атрибутами схемы можно также,
как элементами списка.
Схему таблицы можно получить методом axipy.da.Table.schema()
.
Например:
schema = table.schema()
Схема имеет простую стандартную структуру и с ней просто работать. Например, можно легко вывести все имена атрибутов:
schema.attribute_names()
# эквивалентно
[attr.name for attr in schema]
Атрибуты схемы¶
Атрибут представлен типом axipy.da.Attribute
. Его главные параметры -
это имя name
и тип typedef
.
Тип атрибута представляется строкой. В нем может быть указана
максимальная длина - для строк и десятичного типа через двоеточие,
например, string:254
. И точность - для десятичного типа через точку,
например, decimal:7.3
.
Доступные типы:
Тип |
Описание |
---|---|
string |
строка |
int |
целое число |
double |
вещественное число с плавающей запятой |
decimal |
вещественное число с фиксированной запятой |
bool |
логическое значение |
date |
дата |
time |
время |
datetime |
дата и время |
Специальный атрибут Система Координат coordsystem
содержит значение СК в “универсальном представлении” и указывает на то, что
таблица пространственная - может содержать геометрию и стиль.
См.также
Подробнее в главе Системы Координат.
Создание схемы таблицы. Вспомогательные функции¶
Класс axipy.da.Attribute
содержит вспомогательные функции
axipy.da.Attribute.string()
и другие для создания атрибутов; а также
функцию для создания схемы таблицы - axipy.da.Attribute.schema()
.
Например, так можно создать схему таблицы:
schema = attr.schema(
attr.string('Столица', 25),
attr.string('Capital', 25),
attr.string('Страна', 30),
attr.string('Country', 30),
attr.decimal('Cap_Pop', 8, 5),
coordsystem='prj:Earth Projection 12, 62, "m", 0'
)
Свойства axipy.da.Attribute.length
и axipy.da.Attribute.precision
позволяют получить длину и точность типа. Список всех свойств описан в справочнике
на тип axipy.da.Attribute
.
Чтение записей¶
Объект таблица axipy.da.Table
дает возможность работать с записями
axipy.da.Feature
. Метод axipy.da.Table.items()
возвращает
итератор (iterator
) по записям.
См.также
Подробнее о записях в главе Записи.
features = table.items()
for feature in features:
# обработка записи
...
Возвращается именно Итератор. При чтении он движется вперед и в конце становится пустым. Чтобы начать чтение сначала, нужно создать новый итератор.
Создание таблиц¶
Создавать таблицы несколько сложнее, чем открывать готовые. Для них нужно определить схему, СК, Провайдер и пр. Все эти параметры были рассмотрены выше.
Провайдер может быть задан явно:
newtable = io.tab.create_open('../path/to/datadir/newtable.tab', schema)
или найден автоматически из расширения файла:
newtable = io.createfile('../path/to/datadir/newtable.tab', schema)
Добавим в таблицу несколько записей из вселенной Властелин Колец:
features_to_insert = [
Feature({'country': 'Мордор', 'capital': 'Барад-Дур'}),
Feature(country='Гондор', capital='Минас Тирит'), # создание с использованием **kwargs
Feature({'country': 'Рохан'}), # не обязательно подавать все значения, они будут пустыми
]
newtable.insert(features_to_insert)
Редактирование таблиц¶
Один из возможных способов редактирования таблиц - открыть исходную таблицу, создать целевую таблицу с той же или другой структурой. И при чтении записей из исходной таблицы редактировать их и записывать в целевую. В результате получится отредактированная копия.
Например, для таблицы world
необходимо оставить только колонки
“Страна” и “Население”; и оставить только те страны, население которых
больше 100 миллионов
.
Вот один из вариантов, как это можно реализовать.
def is_over_100million(feature) -> bool:
return feature['Население'] > 100_000_000
orig_table = io.openfile('../path/to/datadir/world.tab')
definition = {
'src': '../path/to/datadir/edit/edited_world.tab',
'schema': attr.schema(
attr.string('Страна'),
attr.integer('Население'),
)
}
copy_table = io.create(definition)
orig_features = orig_table.items()
filtered_features = filter(is_over_100million, orig_features)
copy_table.insert(filtered_features)
Запросы¶
SQL-запросы являются мощным инструментом обработки данных. При выполнении
запроса к таблицам образуется отдельный объект данных. При открытии данных они
попадают в единый каталог axipy.da.DataCatalog
.
Запрос выполняется относительно всех таблиц, находящихся в этом каталоге, с
помощью метода axipy.da.DataCatalog.query()
.
query_text = 'SELECT * FROM world WHERE Население > 100000000'
query_table = catalog.query(query_text)