shape файлы что это

Работа с ShapeFile (*.shp) в среде Delphi

В ходе работы столкнулся с задачей чтения файлов с расширением «.shp». Та информация, которую я нашел в интернете, была разрозненной и расплывчатой, и, поэтому, я решил объединить то, до чего мне пришлось доходить самостоятельно, и рассказать вам.

Постановка задачи

У нас имеется файл с расширением «.shp». В этом файле находится карта в виде изолиний: каждая изолиния сделана отдельным шейпом; наименованием шейпа является высотная характеристика изолинии. Нашей задачей станет считать данные из этого в массив. Массив представляет собой набор точек определенный тремя координатами (x, y, z). Далее этот массив нужно занести в базу данных, но данный момент мы упустим из рассмотрения.

Немного теории

Рассмотрим важные для нас особенности формата «*.shp». На самом деле ShapeFile содержит много информации, но у нас узкий интерес. Во первых нам нужно знать, что ShapeFile разделен на так называемые «Шейпы» (англ. Shape — Фигура). Шейп представляет собой фигуру или набор фигур (возможно не связанных между собой) сложных форм. Хранится шейп в виде отдельных точек и информации о линиях соединяющих их. В нашем случае каждый шейп это непрерывная кривая обозначающая положение точек земного ландшафта имеющих одинаковую высоту (наименование шейпа соответствует численному значение высоты). В виду специфичности задачи нас не будет интересовать информация о линиях соединяющих точки, а только информация о положении точек и их высота.

Стоит так же отметить, что вместе с файлом формата «*.shp» формируется файл формата «*.dbf» содержащий заголовочную информацию о наших шейпах. Файл «*.dbf» должен иметь такое же название, что и файл «.shp».

MapWindowGIS

После небольших поисков в сети, мною была обнаружены библиотека MapWindowGIS. Возможности этой библиотеки весьма широки и она поможет нам в достижении наших целей. Скачать ее можно по следующей ссылке.

После того, как Вы скачаете данную библиотеку необходимо ее установить. После установки, запускаем среду разработки Delphi. Выполняем команду Component-Import AciveX Control… после чего появится окно:
shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

В списке библиотек ActiveX находим — MapWinGIS Component и нажимаем на кнопку «Install…«, после чего необходимо установить данную библиотеку как обычный компонент. После успешной установки данной библиотеки, компонент TMap появиться на вкладке ActiveX.

Добавляем отображение карты

Для начала добавим на форму компонент Map1 типа TMap. Как уже говорилось, он находится на последней позиции вкладки ActiveX.

Для того что бы наш компонент отображал карту, содержащуюся в нашем файле, достаточно простого кода:

shp:Shapefile; //переменная ассоциируемая с шейп-файлом
HandleLayer:integr; //необходимо для индексации слоев в шейп файле

shp:=CoShapefile.Create; //создание шейп-файла
shp.Open(‘map.shp’,nil); //считывание из файла ‘map.shp’
Map1.Focused; //в некоторых случаях, если не добавить данную строчку возникает ошибка
HandleLayer:=Map1.AddLayer(shp,true); //добавление слоя карты на компонент
Map1.ZoomToMaxExtents; //уменьшение (или увеличение) масштаба так, что бы все влезло

Считывание заголовочной информации о шейпах

Что бы считать заголовочную информацию из файла формата «*.dbf» мы будем использовать компоненты TTable и TDataSource. Для этого добавим на форму компоненты Table1 типа TTable и DataSource1 типа TDataSource из вкладок «BDE» и «Data Access» соответственно. Компонент Table1 оставляем без изменения, а в компоненте DataSource1 в параметре «DataSet» выбираем «Table1».

Для удобства добавляем на форму компонент OpenDialog1 типа TOpenDialog из вкладки «Dialogs». В параметре «Filter» компонента OpenDialog1, добавляем фильтр с наименованием «Shape files (.shp)» и фильтрацией «*.shp» (без кавычек). Кроме того добавим кнопки «Открыть» и «Сохранить».

Полный код процедуры на кнопку «Открыть» будет выглядеть следующим образом:

nameDB:WideString; //в этой переменной будет содержаться наименование файла
HandleLayer:integr;

nameDB:=OpenDialog1.FileName; //присваиваем наименование в соответствии с выбором пользователя
shp:=CoShapefile.Create;
shp.Open(nameDB,nil);
Map1.Focused;
HandleLayer:=Map1.AddLayer(shp,true);
Map1.ZoomToMaxExtents;

Delete(nameDB,length(nameDB)-2,3); //обрубаем разрешение
nameDB:=nameDB+’dbf’; //меняем разрешение на «.dbf»
Table1.TableName:=nameDB; //ассоциируем таблицу с фалом «*.dbf»
Table1.Active:=True; //»запускаем» таблицу

Не забываем, что переменную shp нужно добавить в раздел глобальных переменных.

Считываем точки из файла

Для начала приведу код процедуры назначенной на кнопку «Сохранить»:

i,j:integer; //индексирующие переменные
z:integer; //высота точек, считываемая из наименования

if shp<>nil then //проверка на наличие информации в переменной shp
begin

Table1.First; //берем первый шейп из заголовочной таблицы
k:=0;
for i:=0 to shp.NumShapes-1 do //перебор всех шейпов
begin
z:=StrToInt(Table1.Fields[2].Value); //считывание высоты из заголовочной таблицы шейпов
for j:=0 to shp.Shape[i].numPoints-1 do //перебор всех точек шейпа
begin
Mas[k].x:=shp.Shape[i].Point[j].x;
Mas[k].y:=shp.Shape[i].Point[j].y;
Mas[k].z:=z;
inc(k);
end;
Table1.Next; //переходим к следующему шейпу
end;
..
//тут можно например сохранить массив в базу данных
..

end
else ShowMessage(‘Файл не открыт’);
end;

Давайте рассмотрим некоторые особенности. Итак, Mas — одномерный массив точек имеющий три параметра типа Double (x, y, z). Параметр shp.NumShapes равен количеству шейпов внутри файла. Параметр Table1.Fields[2].Value — это наименование текущего шейпа (файл «*.dbf» устроен таким образом, что наименование записано в 3-тьем столбце). shp.Shape[i].numPoints, как вы наверно уже догадались — количество точек в i-том шейпе. shp.Shape[i].Point[j].x и shp.Shape[i].Point[j].y — те самые заветные координаты j-той точки i-того шейпа. Остальное, думаю, понятно из комментариев.

Заключение

Вот мы и закончили рассматривать особенности работы с ShapeFile в среде Delphi. С поставленной задачей мы справились полностью. Конечно, данный обзор является только вершиной айсберга, но я надеюсь эта вводная статья поможет вам в дальнейшем освоении этого направления.

Источник

Справка

Несколько лет назад в Esri были разработаны три основных формата данных для хранения географической информации – покрытия, шейп-файлы и базы геоданных. Шейп-файлы были разработаны как простой формат для хранения географической и атрибутивной информации. В силу их простоты, шейп-файлы стали популярным форматом для обмена данными. Хотя шейп-файлы просты и удобны в работе, они имеют некоторые ограничения, которые отсутствуют в базах геоданных. При использовании шейп-файлов, эти ограничения следует учитывать. В целом,

Эти и другие проблемы делают шейп-файлы слабо пригодными для активной работы с базами данных – они не соответствуют современным способам создания, редактирования, поддержки версий и архивирования.

Когда следует использовать шейп-файл?

Когда не следует использовать шейп-файл?

С некоторыми исключениями, описанными ниже, шейп-файлы подходят для хранения простой геометрии пространственных объектов. Однако шейп-файлы имеют серьезные проблемы, связанные с хранением атрибутов. Например, они не могут хранить значения NULL, округлять числа, имеют ограниченную поддержку символов Unicode, не могут хранить поля, имена которых длиннее 10 знаков, и не могут хранить дату и время в одном поле. Это только основные ограничения. Кроме того, они не поддерживают возможности, присутствующие в базах геоданных, например, работу с доменами и подтипами. Поэтому, не следует использовать шейп-файлы, если вы хотите хранить сложные атрибуты и пользоваться возможностями, предоставляемыми базами геоданных.

Компоненты шейп-файлов и расширения файлов

Шейп-файлы хранятся в трех или более файлах, которые имеют одинаковый префикс и находятся в одной папке (рабочей области шейп-файлов). Отдельные файлы можно увидеть с помощью Проводника Windows, в ArcCatalog они не отображаются.

Основной файл, в котором хранится геометрия объектов. В этом файле не хранятся атрибуты – только геометрия.

Таблица dBASE, в которой находятся атрибуты пространственных объектов.

Файлы, в которых хранится пространственный индекс объектов.

Атрибутивный индекс, создающийся в ArcCatalog для каждой таблицы dBASE.

Индекс геокодирования для чтения-записи шейп-файлов.

Файл, в котором хранится информация о системе координат.

Метаданные для ArcGIS; хранит информацию о шейп-файле.

Источник

Как в Delphi / Lazarus / С++ Builder работать с картами в формате SHP

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

ShapeFile, они же «Шейпы» (англ. Shape — Фигура) представляют собой фигуру или набор фигур (возможно не связанных между собой) сложных форм. Фигуры бывают в виде точек, полилиний или полигонов.

Если один из файлов набора будет утерян, данные могут быть повреждены или же вовсе проект будет утерян.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

ArcGIS является географической информационной системой (ГИС) для работы с картами и географической информацией. Он используется для создания и использования карт, составления географических данных, анализа отображенной информации, обмена и обнаружения географической информации, с использования карт и географической информации в ряде приложений и управлений географической информации в базе данных. Подробнее о технологии ArcGIS.

В контексте ГИС векторные форматы данных (или по сути – векторные модели хранения данных) являются одним из способов отображения объектов реального мира.

Вы можете открыть файлы SHP с помощью следующих программ: CADE Pro, Parallels, Tools Center, AutoCAD, ESRI’s ArcExplorer, Free File Viewer Pro.

Преимущества шейп-файлов

Недостатки шейп-файлов

Шейп-файлы подходят для хранения простой геометрии пространственных объектов. Однако имеются серьезные проблемы, связанные с хранением атрибутов. Например, они не могут округлять числа, имеют ограниченную поддержку символов Unicode, не могут хранить поля, имена которых длиннее 10 знаков, и не могут хранить дату и время в одном поле. Это только основные ограничения. Кроме того, они не поддерживают возможности, присутствующие в базах геоданных, например, работу с доменами и подтипами. Поэтому, не следует использовать шейп-файлы, если вы хотите хранить сложные атрибуты и пользоваться возможностями, предоставляемыми базами геоданных.

Ограничения по геометрии Shape-файлов

Каждый файл-компонент шейп-файла не может быть более 2 GB, что составляет примерно 70 миллионов точечных объектов, потому что для ссылок внутри файла используются 4-байтные числа. Количество линейных или полигональных объектов, которые могут содержаться в шейп-файле, зависит от числа вершин этих объектов (вершина является эквивалентом точки).

В классах объектов базы геоданных значения допуска (x;y) хранится напрямую, в шейп-файлах совершенно по-другому. Допуск по (x;y) – это минимальное расстояние между координатами, ближе которого они будут считаться идентичными. Между пространственными объектами одного класса объектов, или между объектами нескольких различных классов при оценке взаимосвязей используется тот самый допуск. Также он активно используется при редактировании объектов. Если вы используете такие операции и инструменты как: Наложение (Overlay), Вырезать (Clip), Выбрать в слое по расположению (Select Layer By Location), или любой инструмент, который использует в качестве входных данных два или более класса пространственных объектов, то вместо шейп-файлов лучше использовать класс объектов базы геоданных(где доступ осуществляется по x, y).

Шейп-файл может занимать от трех до пяти раз больше места, по сравнению с файловой базой геоданных или SDE, поскольку использует иные методы сжатия.

Шейп-файлы поддерживают объекты-мультипатчи, но не поддерживают следующие возможности мультипатчей:

Пространственный индекс шейп-файла малоэффективен по сравнению с индексом класса объектов базы геоданных. Пространственные запросы такие как выбор объектов в пределах полигона займут у вас больше времени в отличие от того же класса объектов базы геоданных. Данный недостаток наблюдается только с большим количеством пространственных объектов.

Параметрически заданные кривые (также известные как кривые дуговых сегментов) не поддерживаются в шейп-файлах. Параметрические кривые можно создать, отредактировав класс объектов базы геоданных. Для построения кривых используются математические формулы. При экспорте класса объектов базы геоданных, который содержит параметрические кривые, в шейп-файл, кривые будут трансформированы в простые линейные объекты, вершины которых будут расположены очень близко друг к другу, чтобы сохранить соответствующую форму.

В отличие от других форматов, шейп-файл хранит числовые атрибуты в символьном, а не бинарном формате. Для реальных числовых значений (например, с десятичными знаками), это может привести к ошибкам из-за округления. Это ограничение касается только атрибутов, и не относится к хранению координат.

Как создать файл в формате SHP с помощью кода

Про сам формат поговорили и как готовые файлы открыть узнали, а как работать в Delphi? Тут есть три пути:

Создаём файл с картой в формате SHP

Заходим в FR Designer. Находим Object “Map” и добавляем его в документ.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Для добавления нового слоя нажмите кнопку «Добавить. «. Будет показано следующее окно:

На этом шаге нужно выбрать тип слоя:

Если вы выбрали слой на основе файла карты, укажите дополнительно, как хранить картографические данные:

— данные внедряются в файл отчета. При этом отчет может сильно увеличиться в размерах.

— файл отчета ссылается на файл карты, внедрения не происходит. Этот режим полезен, если у вас есть несколько отчетов, использующих одни и те же карты.

Карты большого объема (более 30Мб) или с большим количеством полигонов (более 20000) серьезно замедлят работу отчета.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что этоПри нажатии на Fill мы попадаем в редактор заливки. Во вкладке Кисть есть 3 свойства:

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Стиль кисти имеет несколько готовых видов форматирования:

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что этоshape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Цвет фона, как и цвет переднего плана можно выбрать из готовой палитры цветов или настроить необходимый цвет нажав на Other.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Во второй вкладке у нас настройки градиента для фона.

Стиль градиента может быть горизонтальным, вертикальным, овальным, прямоугольным, вертикальным с переходом в другой цвет по центру, горизонтальным с переходом в другой цвет по центру.

Начальный и конечный цвет можно выбрать из готовой палитры цветов или настроить необходимый цвет нажав на Other.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что этоshape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

В третьей вкладке настройки заливки в виде стекла.

Имеется выбор ориентации: вертикальный, горизонтальный, вертикальное и горизонтальное зеркало.

Цвет можно выбрать из готовой палитры или настроить необходимый цвет нажав на Other.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что этоshape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Вернёмся в редактор карты и найдём уже редактор рамок.

Блок линий: можно выбрать стиль из предложенных вариантов, задать ширину линии и выбрать цвет.

Блок рамки: в центре у нас образец кадра, выбираем к каким сторонам применить стиль линий через образец или с помощью кнопочек (поля на всех сторонах, без полей или стороны по отдельности).

Добавляя тень мы также можем указать ширину и цвет.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что этоshape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Цвет рамки можно выбрать из готовой палитры цветов, установив ширину рамок. Выставляем позицию шкалы. На примере у нас расположение в правом нижнем углу.

Название шкалы вписываем в поле Text, через Font… настроим шрифт и его размер.

Вкладка Размер шкалы по виду не отличается от Цвета шкалы, поэтому повторяться не буду.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Сохранив полученный результат переходим во вкладку превью и видим готовый результат. Наша карта не будет статичной, ещё можно масштабировать в любом месте, а при наведении на определённую область (в нашем случае на любую страну) будет подсвечиваться весь этот фрагмент.

shape файлы что это. Смотреть фото shape файлы что это. Смотреть картинку shape файлы что это. Картинка про shape файлы что это. Фото shape файлы что это

Создаём карту в формате SHP с помощью кода

Shape далеко не единственный формат для работы с картами, существуют ещё OpenStreetMap (OSM) и GPS eXchange Format, но о них я расскажу в других статьях.

Источник

СОДЕРЖАНИЕ

Обзор

Заголовок основного файла имеет фиксированную длину 100 байт и содержит 17 полей; девять 4-байтовых (32-битных целых числа со знаком или int32) целочисленных полей, за которыми следуют восемь 8-байтовых ( двойных ) подписанных полей с плавающей запятой:

БайтыТипПорядок байтовиспользование
0–3int32большойКод файла (всегда шестнадцатеричное значение 0x0000270a )
4–23int32большойНе используется; пять uint32
24–27int32большойДлина файла (16-битными словами, включая заголовок)
28–31int32маленькийВерсия
32–35int32маленькийТип формы (см. Ссылку ниже)
36–67двойноймаленькийМинимальный ограничивающий прямоугольник (MBR) всех фигур, содержащихся в наборе данных; четыре двойных в следующем порядке: мин. X, мин. Y, макс. X, макс. Y
68–83двойноймаленькийДиапазон Z; два дубля в следующем порядке: min Z, max Z
84–99двойноймаленькийДиапазон M; два дубля в следующем порядке: мин М, макс М

Затем файл содержит любое количество записей переменной длины. Каждой записи предшествует заголовок записи размером 8 байтов:

БайтыТипПорядок байтовиспользование
0–3int32большойНомер записи (от 1)
4–7int32большойДлина записи (в 16-битных словах)

За заголовком записи следует фактическая запись:

БайтыТипПорядок байтовиспользование
0–3int32маленькийТип формы (см. Ссылку ниже)
4–Контент формы

Содержимое записи переменной длины зависит от типа фигуры, который должен быть либо типом фигуры, указанным в заголовке файла, либо пустым. Ниже перечислены возможные типы фигур:

ЦенитьТип формыПоля
0Нулевая формаНикто
1ТочкаX, Y
3Ломаная линияMBR, Количество деталей, Количество точек, Детали, Пункты
5МногоугольникMBR, Количество деталей, Количество точек, Детали, Пункты
8MultiPointMBR, Количество точек, Баллы
11PointZX, Y, Z

13PolylineZОбязательно : MBR, количество частей, количество точек, частей, точек, диапазон Z, массив Z

Дополнительно : диапазон M, массив M

15PolygonZОбязательно : MBR, количество частей, количество точек, частей, точек, диапазон Z, массив Z

Дополнительно : диапазон M, массив M

18MultiPointZОбязательно : MBR, количество точек, точки, диапазон Z, массив Z

Дополнительно : диапазон M, массив M

21 годPointMX, Y, M
23PolylineMОбязательно : MBR, Количество деталей, Количество точек, Детали, Пункты

Дополнительно : диапазон M, массив M

25PolygonMОбязательно : MBR, Количество деталей, Количество точек, Детали, Пункты

Дополнительно : диапазон M, массив M

28 годMultiPointMОбязательно : MBR, Количество баллов, Баллы

Необязательные поля : диапазон M, массив M

31 годМультипатчОбязательно : MBR, количество деталей, количество точек, детали, типы деталей, точки, диапазон Z, массив Z

Дополнительно : диапазон M, массив M

БайтыТипПорядок байтовиспользование
0–3int32большойСмещение записи (16-битными словами)
4–7int32большойДлина записи (в 16-битных словах)

Имена и значения атрибутов не стандартизированы и будут отличаться в зависимости от источника шейп-файла.

Ограничения

Топология и формат шейп-файла

Формат шейп-файла не позволяет хранить топологическую информацию. В ESRI ArcInfo покрытия и личный / файл / предприятия геоданных имеют возможность хранить особенность топологии.

Пространственное представление

Хранилище данных

Смешивание типов форм

Поскольку тип формы предшествует каждой записи геометрии, шейп-файл технически способен хранить смесь различных типов форм. Однако в спецификации указано: «Все фигуры, отличные от Null, в шейп-файле должны быть одного и того же типа». Следовательно, эта возможность смешивания типов фигур должна быть ограничена перемежением пустых фигур с одним типом фигуры, объявленным в заголовке файла. Шейп-файл не должен содержать данные как полилинии, так и полигона, например, описания колодца (точки), реки (полилинии) и озера (многоугольника) будут храниться в трех отдельных наборах данных.

Источник

ArcMap

Несколько лет назад в Esri были разработаны три основных формата данных для хранения географической информации – покрытия, шейп-файлы и базы геоданных. Шейп-файлы были разработаны как простой формат для хранения географической и атрибутивной информации. В силу их простоты, шейп-файлы стали популярным форматом для обмена данными. Хотя шейп-файлы просты и удобны в работе, они имеют некоторые ограничения, которые отсутствуют в базах геоданных. При использовании шейп-файлов, эти ограничения следует учитывать. В целом,

Эти и другие проблемы делают шейп-файлы мало пригодными для активной работы с базами данных. Шейп-файлы не соответствуют современным способам создания, редактирования, поддержки версий и архивирования.

Когда следует использовать шейп-файл?

Когда не следует использовать шейп-файл?

С некоторыми исключениями, описанными ниже, шейп-файлы подходят для хранения простой геометрии пространственных объектов. Однако шейп-файлы имеют серьезные проблемы, связанные с хранением атрибутов. Например, они не могут хранить значения NULL, они округляют числа, они не полностью поддерживают строки символов Unicode, не могут работать с полями, имена которых длиннее 10 знаков, и не могут хранить время в поле дат. Это только основные ограничения. Кроме того, они не поддерживают возможности, присутствующие в базах геоданных, например, работу с доменами и подтипами. Поэтому, не следует использовать шейп-файлы, если вы хотите хранить сложные атрибуты и пользоваться возможностями, предоставляемыми базами геоданных.

Компоненты шейп-файлов и расширения файлов

Шейп-файлы хранятся в трех или более файлах, которые имеют одинаковый префикс и находятся в одной папке (рабочей области шейп-файлов). Отдельные файлы можно увидеть с помощью Проводника Windows, в ArcCatalog они не отображаются.

Основной файл, в котором хранится геометрия объектов. В этом файле не хранятся атрибуты – только геометрия.

Таблица dBASE, в которой находятся атрибуты пространственных объектов.

Файлы, в которых хранится пространственный индекс объектов.

Атрибутивный индекс, создающийся для каждой таблицы dBASE.

Индекс геокодирования для чтения-записи шейп-файлов.

Файл, в котором хранится информация о системе координат.

Метаданные для ArcGIS; хранит информацию о шейп-файле.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *