Утилита выгрузки данных ArcGIS Server
- SergeyRyzhkov
- Гуру
- Сообщения: 909
- Зарегистрирован: 02 июл 2014, 19:13
- Репутация: 203
- Ваше звание: GP-экотеррористы
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Утилита выгрузки данных ArcGIS Server
Донецков, спасибо Вам за конструктив.
Вы могли бы выслать geoJSON, который не открывается? Я проверяю валидность на ресурсе http://geojsonlint.com/
JSON и pJSON - это формат ESRI. pJSON - форматированнный JSON
geoJSON - согласно стандарту http://geojson.org/ Причем в поля, которые определены домены, подставляются значения, а не коды (что удобно).
JSON,pJSON, KMZ - выгружаю напрямую через ArcGIS Server
geoJSON и WKT - выгружаю сначала через ArcGIS Server в родном формате, а потом преобразую.
Вы могли бы выслать geoJSON, который не открывается? Я проверяю валидность на ресурсе http://geojsonlint.com/
JSON и pJSON - это формат ESRI. pJSON - форматированнный JSON
geoJSON - согласно стандарту http://geojson.org/ Причем в поля, которые определены домены, подставляются значения, а не коды (что удобно).
JSON,pJSON, KMZ - выгружаю напрямую через ArcGIS Server
geoJSON и WKT - выгружаю сначала через ArcGIS Server в родном формате, а потом преобразую.
-
- Гуру
- Сообщения: 3058
- Зарегистрирован: 19 май 2010, 19:44
- Репутация: 189
Re: Утилита выгрузки данных ArcGIS Server
Проблемы скорее всего были именно в конкретном наборе данных, т.к. по другому кварталу и в json и geojson нормально открывается, только в последнем уже вместо кодов нормальные надписи...
Буду пробовать еще...
Буду пробовать еще...
- Вложения
-
pack.zip
- (183.92 КБ) 405 скачиваний
-
- Активный участник
- Сообщения: 163
- Зарегистрирован: 28 июн 2012, 01:02
- Репутация: 84
- Откуда: Vladivostok
Re: Утилита выгрузки данных ArcGIS Server
Хотел бы обратить ваше внимание на такой параметр в настроках сервера Росреестра: MaxRecordCount: 1000, который говорит о том, что сервер не может вернуть больше 1000 объектов. Но кадастровых кварталов, в которых более 1000 участков довольно много. Поэтому получение участков через запросы вида CAD_NUM LIKE '54:35:092425%' может... "не соответствовать действительности". Не могу с уверенностью сказать произвольная или постоянная эта 1000 участков.
Проверить превышен ли лимит объектов в ответе можно по параметру "exceededTransferLimit": true. И в таком случае выдавать пользователю предупреждение и предложение застрелиться использовать оператор IN с указанием всех кадастровых номеров участков вручную, но не более 1000 за раз. Либо придумать иной запрос.
Проверить превышен ли лимит объектов в ответе можно по параметру "exceededTransferLimit": true. И в таком случае выдавать пользователю предупреждение и предложение застрелиться использовать оператор IN с указанием всех кадастровых номеров участков вручную, но не более 1000 за раз. Либо придумать иной запрос.
-
- Гуру
- Сообщения: 619
- Зарегистрирован: 09 авг 2009, 13:09
- Репутация: 67
- Ваше звание: топограф, технолог
- Откуда: Мааськва
Re: Утилита выгрузки данных ArcGIS Server
Во-первых, можно запрос делать по-другому:
А потом еще раз, но уже с 1001 до 2000 и т.д.
Во-вторых, можно, наверное, в саму программу цикл какой-нибудь встроить, который будет загружать, пока участки в квартале не исчерпаются.
(Это я честно подглядел на http://terraingis.ru/article/read/poluc ... v_PKK.html)CAD_NUM BETWEEN '**:**:*******:0000' AND '**:**:*******:1000', где звездочки - нужный кадастровый квартал.
А потом еще раз, но уже с 1001 до 2000 и т.д.
Во-вторых, можно, наверное, в саму программу цикл какой-нибудь встроить, который будет загружать, пока участки в квартале не исчерпаются.
-
- Активный участник
- Сообщения: 163
- Зарегистрирован: 28 июн 2012, 01:02
- Репутация: 84
- Откуда: Vladivostok
Re: Утилита выгрузки данных с ППК Росреестра
Вот я и хотел указать на необходимость программной реализации, т.к. руками довольно муторно. И без такой реализации утилита работает не на 100%.
[ Сообщение с мобильного устройства ]
[ Сообщение с мобильного устройства ]
- SergeyRyzhkov
- Гуру
- Сообщения: 909
- Зарегистрирован: 02 июл 2014, 19:13
- Репутация: 203
- Ваше звание: GP-экотеррористы
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Утилита выгрузки данных ArcGIS Server
doujin Спасибо! Замечание очень верное, самое главное очень Важное, так как не зная о данном факте можно ввести себя в заблуждение.
- SergeyRyzhkov
- Гуру
- Сообщения: 909
- Зарегистрирован: 02 июл 2014, 19:13
- Репутация: 203
- Ваше звание: GP-экотеррористы
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Утилита выгрузки данных ArcGIS Server
В связи с тем что в утилите был явно прописан URL сервисов , я эту ошибку исправил. Вводить в отдельное поле путь до сервиса, например, границы Алабамы
http://gis.apfo.usda.gov/arcgis/rest/se ... apServer/3
Спасибо уважаемому коллеге, который обратил внимание (в ЛС) на мой огрех ...
http://gis.apfo.usda.gov/arcgis/rest/se ... apServer/3
Спасибо уважаемому коллеге, который обратил внимание (в ЛС) на мой огрех ...
-
- Гуру
- Сообщения: 619
- Зарегистрирован: 09 авг 2009, 13:09
- Репутация: 67
- Ваше звание: топограф, технолог
- Откуда: Мааськва
Re: Утилита выгрузки данных ArcGIS Server
Гм... Может быть оставить все-таки какие-нибудь подсказки, наводки или даже просто список этих сервисов? Если список конечен. Или подсказка самых используемых хотя бы, но с возможностью вписывать любой нужный. Иначе - черт его знает, где и как в нужную минуту его искать.SergeyRyzhkov писал(а):...был явно прописан URL сервисов...
- SergeyRyzhkov
- Гуру
- Сообщения: 909
- Зарегистрирован: 02 июл 2014, 19:13
- Репутация: 203
- Ваше звание: GP-экотеррористы
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Утилита выгрузки данных ArcGIS Server
Сделал чтобы можно было локально вносить в файл servers.txt (где exe лежит) или вносить в поле вручную. Сохранения не будет, чтобы коллеги не ворчали.АлексЮстасу писал(а):Гм... Может быть оставить все-таки какие-нибудь подсказки, наводки или даже просто список этих сервисов? Если список конечен. Или подсказка самых используемых хотя бы, но с возможностью вписывать любой нужный. Иначе - черт его знает, где и как в нужную минуту его искать.SergeyRyzhkov писал(а):...был явно прописан URL сервисов ...
Также добавил выбор кодировки
Также добавил возможность подставлять алиасы полей вместо наименований (актуально, например для ПКК)
В первом сообщении обновил
-
- Гуру
- Сообщения: 4231
- Зарегистрирован: 10 апр 2006, 22:34
- Репутация: -344969098
- Откуда: Париж
Re: Утилита выгрузки данных ArcGIS Server
проблема N за раз и не больше: не действует на запрос вида:
Для OBJECTID 100%-но работает BETWEEN.-
- Активный участник
- Сообщения: 163
- Зарегистрирован: 28 июн 2012, 01:02
- Репутация: 84
- Откуда: Vladivostok
Re: Утилита выгрузки данных ArcGIS Server
Это вернет только список значений OBJECTID.Boris писал(а):проблема N за раз и не больше: не действует на запрос вида
OBJECTID идут не по порядку, BETWEEN будет возвращать много "лишних" участков и снова упрется в 1000 объектов (с атрибутами и геометрией) за раз. Можно немного подробнее что делать со списком дальше?Boris писал(а):Для OBJECTID 100%-но работает BETWEEN.
Меня немного смущает то, что получение участков для "тяжелых" кварталов превращается в десятки запросов к ПКК, а с ее склонностью тупить и возвращать ошибки это ведет к большому объему ручной работы и сверки результатов. Хорошо бы эту работу скрыть для технически неподготовленных пользователей.
-
- Гуру
- Сообщения: 619
- Зарегистрирован: 09 авг 2009, 13:09
- Репутация: 67
- Ваше звание: топограф, технолог
- Откуда: Мааськва
Re: Утилита выгрузки данных ArcGIS Server
Запустил, тупо забыв написать запрос к ПКК, но результаты получилSergeyRyzhkov писал(а):Сохранения не будет, чтобы коллеги не ворчали.
Также добавил выбор кодировки

В результатах:
и т.д."CAD_NUM":"02:47:140702:231"
С кодировкой US-ASCII Global Mapper, например, русские символы читает криво.
С остальными кодировками у меня - "Необрабатываемое исключение в приложении...".
Больше жалко, что не сохраняются запросы - подсматривать удобнее, с синтаксисом меньше ошибок.
Для этого многие делают конструкторы запросов. Как вариант.
-
- Гуру
- Сообщения: 4231
- Зарегистрирован: 10 апр 2006, 22:34
- Репутация: -344969098
- Откуда: Париж
Re: Утилита выгрузки данных ArcGIS Server
1. Возращение 1-го поля не ограничивает вас в любых изощренных условиях на остальные столбцы. Поверьте, это ограничивает число лишних строк на порядки. Замечено, что ряд запросов с одним условием "предок=" - не работают. Добавите к ним еще одно доп.условие - работают.doujin писал(а):Можно немного подробнее что делать со списком дальше?
2. Вы получаете список объектов, которые гарантировано отвечают вашим условиям,

3. Кроме фильтра в where гарантированно работает оператор order.
4. Да, вы на следующем шаге имеете это ограничение в 1000, не жадничайте, пусть будет 300, для особо крупных 30 и не больше, если не хотите строить систему проверки адекватности результатов. Хотя все равно придется.

5. Следующим ходом по этим кодам вы получаете набор cad_num или ppk_id в приятной вам последовательности заранее зная сколько запросить и сколько вы получите. Можете доверить серверу отсортировать его для вас, я - не доверяю. На фоне остальных время-силы затрат добавочная сортировка никаких ограничений не даст.
6. Теперь вы управляемо имеете упорядоченный список устойчивых кодов, реагирующий на оператор between. От него и можете плясать дальше.
7. Да, добавляется лишний запрос или два. Но запрос быстрый (в разумных пределах) однозначный и упорядоченный. Гарантированно возвращающий количество и индексы всех объектов, подходящих под ваш фильтр. 50000 выдаст за нормальное время и без падения сервера.
8. Если вы сохраняете указанный выше фильтр, добавляя к нему оператор ограничивающий выборку через between, или < и >, то число основных записей будет равно числу записей, которое дал obid.
9. Результирующий алгоритм с лишним запросом - проще, надежней и экономичней, к тому же быстрее по реакции сервера. Не надо изобретать всякие запросы с бесконечным like, там где вернется пустота. На каждой стадии вы гарантировано знаете сколько записей должны получить. Кроме того вы можете накапливать номера, что бы запрашивать по 100, 200, 300 - сколько сервер выдержит за раз, а не брать единицу запроса с WHERE, который может вернуть 5000 записей, а может и 1 или 0.
- SergeyRyzhkov
- Гуру
- Сообщения: 909
- Зарегистрирован: 02 июл 2014, 19:13
- Репутация: 203
- Ваше звание: GP-экотеррористы
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Утилита выгрузки данных ArcGIS Server
АлексЮстасу - спасибо. Ошибку исправлю. Запрос будем сохранять. Наареное еще удобно будет не только урл сервиса хранить в файле, но и человеческое наименование
Boris - спасибо!! Сколько работал с арксерваком, первый раз такую фичу узнал.
Насчет выгрузки данных более чем заданно в параметре сервича MaxRecordCount (по ум.1000), если надо сделать, в обед сделаю. Давайте определимся с алгоритмом.
Борис все толково и грамотно расписал. С учетом свободного моего времени, предлагаю следующий алгоритм алгоритм:
1. Получаем ВСЕ идентификаторы записей (на время выполнения запроса) для заданного условия, то есть в запросе будет returnIdsOnly=true
2. Полученный json сохраняем на диск в виде файла + файл-журнал
3. Из п.2 получаем наименование поля-идентификатора
4. Из настроек считываем количество значений строк в порции (итерации выкачки)
5. Далее выполняем запрос как и ранее, но добавляем AND "поле" (п.3) IN (перечисление порции идентификаторов)
6. Выгрузив порцию - склеиваем с предыдущей и так пока не пройдем все полученные идентификаторы.
7. После удачной выгрузки очередной порции в файле журнале удаляем идентификаторы, по которым было удачно выгружено.
Файл журнал нужен чтобы возможно было "докачать" остатки, если сервер лежит или инет дома слетел и т.д.
Какие еще предложения?
Boris - спасибо!! Сколько работал с арксерваком, первый раз такую фичу узнал.
Насчет выгрузки данных более чем заданно в параметре сервича MaxRecordCount (по ум.1000), если надо сделать, в обед сделаю. Давайте определимся с алгоритмом.
Борис все толково и грамотно расписал. С учетом свободного моего времени, предлагаю следующий алгоритм алгоритм:
1. Получаем ВСЕ идентификаторы записей (на время выполнения запроса) для заданного условия, то есть в запросе будет returnIdsOnly=true
2. Полученный json сохраняем на диск в виде файла + файл-журнал
3. Из п.2 получаем наименование поля-идентификатора
4. Из настроек считываем количество значений строк в порции (итерации выкачки)
5. Далее выполняем запрос как и ранее, но добавляем AND "поле" (п.3) IN (перечисление порции идентификаторов)
6. Выгрузив порцию - склеиваем с предыдущей и так пока не пройдем все полученные идентификаторы.
7. После удачной выгрузки очередной порции в файле журнале удаляем идентификаторы, по которым было удачно выгружено.
Файл журнал нужен чтобы возможно было "докачать" остатки, если сервер лежит или инет дома слетел и т.д.
Какие еще предложения?
-
- Активный участник
- Сообщения: 163
- Зарегистрирован: 28 июн 2012, 01:02
- Репутация: 84
- Откуда: Vladivostok
Re: Утилита выгрузки данных ArcGIS Server
Предложу свое виденье частностей.
Для примера взял наугад квартал только с парой участков (54:37:020318) и в запросах оставил только параметры, которые надо изменить. Задача та же: получить все участки квартала по его номеру.
[1] Изначальный запрос как и раньше, но только с OBJECTID:
[2] В ответ получим:
Сохранять ответ не вижу смысла, т.к. если Boris прав, то со временем эти идентификаторы будут указывать уже на совсем другие участки. Городить еще запросы, что бы получить постоянный и надежный PKK_ID тоже не вижу смысла, т.к. эти запросы опять будут упираться в ограничение. Поэтому будем получать геометрию и атрибуты сразу.
[3] Берем этот список идентификаторов и вставляем его в следующий запрос. Там для OBJECTID прям есть специальное поле:Если список содержит больше 500 значений, то разбиваем его по 500 и шлем необходимое число раз, заменяя идентификаторы.
[4] В ответ прийдет стандартное:
[6] Собираем все участки из ответов воедино. Обрабатываем.
[7] Каждый запрос пытаться повторить раза два. Если ПКК упорно шлет ошибку на какой-то кусок, считать всю попытку получения квартала неудачной и выдавать сообщение с предложением попробовать ночью позже.
[8] Проверкой "А не сменились ли OBJECTID, и не получили ли мы участок не с того квартала?" предлагаю принебречь. Т.к. по моим прикидкам такой опрос сервера затянется минут на 10 максимум. Или это уже долго?
По сути тоже самое, только некоторые углы, на мой взгляд, срезал.
Для примера взял наугад квартал только с парой участков (54:37:020318) и в запросах оставил только параметры, которые надо изменить. Задача та же: получить все участки квартала по его номеру.
[1] Изначальный запрос как и раньше, но только с OBJECTID:
Спойлер
Код: Выделить всё
http://maps.rosreestr.ru/arcgis/rest/services/Cadastre/CadastreSelected/MapServer/1/query?where=CAD_NUM+LIKE+%2754%3A37%3A020318%25%27&returnIdsOnly=true&f=pjson
Спойлер
Код: Выделить всё
{
"objectIdFieldName": "OBJECTID",
"objectIds": [
21521880,
21521881
]
}
[3] Берем этот список идентификаторов и вставляем его в следующий запрос. Там для OBJECTID прям есть специальное поле:
Спойлер
Код: Выделить всё
http://maps.rosreestr.ru/arcgis/rest/services/Cadastre/CadastreSelected/MapServer/1/query?objectIds=21521880%2C21521881&outFields=*&f=pjson
[4] В ответ прийдет стандартное:
Спойлер
Код: Выделить всё
{
"displayFieldName": "PKK_ID",
"fieldAliases": {
"OBJECTID": "OBJECTID",
"REGION_KEY": "Ключ СФ",
"PARCEL_ID": "Строковый идентификатор ИПГУ",
"TEMP_ID": "Числовой идентификатор ИПГУ",
"PKK_ID": "Идентификатор ПКК",
"PARENT_ID": "Идентификатор родителя",
"CAD_NUM": "Кадастровый номер земельного участка",
"STATE_CODE": "Статус земельного участка (код)",
"ANNO_TEXT": "Аннотация",
"CP_VALUE": "Значение кадастровой стоимости",
"CATEGORY_CODE": "Категория земель (код)",
"ACTUAL_DATE": "Дата актуальности",
"ERROR_CODE": "Код ошибки",
"XC": "X центра",
"YC": "Y центра",
"XMIN": "Экстент - X мин.",
"XMAX": "Экстент - X макс.",
"YMIN": "Экстент - Y мин.",
"YMAX": "Экстент - Y макс.",
"DEL_FEATURE": "Объект обработан - можно удалять",
"G_AREA": "G_AREA",
"SHAPE_Length": "Shape_Length",
"SHAPE_Area": "Shape_Area"
},
"geometryType": "esriGeometryPolygon",
"spatialReference": {
"wkid": 102100,
"latestWkid": 3857
},
"fields": [
{
"name": "OBJECTID",
"type": "esriFieldTypeOID",
"alias": "OBJECTID"
},
{
"name": "REGION_KEY",
"type": "esriFieldTypeString",
"alias": "Ключ СФ",
"length": 3
},
{
"name": "PARCEL_ID",
"type": "esriFieldTypeString",
"alias": "Строковый идентификатор ИПГУ",
"length": 64
},
{
"name": "TEMP_ID",
"type": "esriFieldTypeInteger",
"alias": "Числовой идентификатор ИПГУ"
},
{
"name": "PKK_ID",
"type": "esriFieldTypeString",
"alias": "Идентификатор ПКК",
"length": 24
},
{
"name": "PARENT_ID",
"type": "esriFieldTypeString",
"alias": "Идентификатор родителя",
"length": 14
},
{
"name": "CAD_NUM",
"type": "esriFieldTypeString",
"alias": "Кадастровый номер земельного участка",
"length": 25
},
{
"name": "STATE_CODE",
"type": "esriFieldTypeString",
"alias": "Статус земельного участка (код)",
"length": 2
},
{
"name": "ANNO_TEXT",
"type": "esriFieldTypeString",
"alias": "Аннотация",
"length": 8
},
{
"name": "CP_VALUE",
"type": "esriFieldTypeDouble",
"alias": "Значение кадастровой стоимости"
},
{
"name": "CATEGORY_CODE",
"type": "esriFieldTypeString",
"alias": "Категория земель (код)",
"length": 12
},
{
"name": "ACTUAL_DATE",
"type": "esriFieldTypeDate",
"alias": "Дата актуальности",
"length": 8
},
{
"name": "ERROR_CODE",
"type": "esriFieldTypeInteger",
"alias": "Код ошибки"
},
{
"name": "XC",
"type": "esriFieldTypeDouble",
"alias": "X центра"
},
{
"name": "YC",
"type": "esriFieldTypeDouble",
"alias": "Y центра"
},
{
"name": "XMIN",
"type": "esriFieldTypeDouble",
"alias": "Экстент - X мин."
},
{
"name": "XMAX",
"type": "esriFieldTypeDouble",
"alias": "Экстент - X макс."
},
{
"name": "YMIN",
"type": "esriFieldTypeDouble",
"alias": "Экстент - Y мин."
},
{
"name": "YMAX",
"type": "esriFieldTypeDouble",
"alias": "Экстент - Y макс."
},
{
"name": "DEL_FEATURE",
"type": "esriFieldTypeSmallInteger",
"alias": "Объект обработан - можно удалять"
},
{
"name": "G_AREA",
"type": "esriFieldTypeDouble",
"alias": "G_AREA"
},
{
"name": "SHAPE_Length",
"type": "esriFieldTypeDouble",
"alias": "Shape_Length"
},
{
"name": "SHAPE_Area",
"type": "esriFieldTypeDouble",
"alias": "Shape_Area"
}
],
"features": [
{
"attributes": {
"OBJECTID": 21521880,
"REGION_KEY": "154",
"PARCEL_ID": "54:37:20318:2",
"TEMP_ID": 480535251,
"PKK_ID": "543700203180000201",
"PARENT_ID": "54370020318",
"CAD_NUM": "54:37:020318:2",
"STATE_CODE": "01",
"ANNO_TEXT": "2",
"CP_VALUE": 452002.83049999998,
"CATEGORY_CODE": "003002000000",
"ACTUAL_DATE": 1300320000000,
"ERROR_CODE": 0,
"XC": 8461875.8895999994,
"YC": 7404744.6834000004,
"XMIN": 8461698.6348000001,
"XMAX": 8461983.6949000005,
"YMIN": 7404648.5613000002,
"YMAX": 7404808.7823999999,
"DEL_FEATURE": null,
"G_AREA": 28044.315822119999,
"SHAPE_Length": 760.65774372565124,
"SHAPE_Area": 28044.319502916187
},
"geometry": {
"rings": [
[
[
8461705.9761962891,
7404765.0151977539
],
[
8461698.6602172852,
7404767.1708374023
],
[
8461698.6350097656,
7404769.099609375
],
[
8461701.7944335938,
7404776.0140380859
],
[
8461733.9010009766,
7404796.2770385742
],
[
8461983.6950073242,
7404808.7825927734
],
[
8461983.341003418,
7404668.5079956055
],
[
8461931.6478271484,
7404648.5614013672
],
[
8461811.1394042969,
7404719.4768066406
],
[
8461809.6384277344,
7404718.4813842773
],
[
8461784.8128051758,
7404732.9479980469
],
[
8461748.1705932617,
7404741.8510131836
],
[
8461707.8135986328,
7404756.4515991211
],
[
8461705.9761962891,
7404765.0151977539
]
]
]
}
},
{
"attributes": {
"OBJECTID": 21521881,
"REGION_KEY": "154",
"PARCEL_ID": "54:37:20318:9",
"TEMP_ID": 480535253,
"PKK_ID": "543700203180000901",
"PARENT_ID": "54370020318",
"CAD_NUM": "54:37:020318:9",
"STATE_CODE": "01",
"ANNO_TEXT": "9",
"CP_VALUE": 232502.37,
"CATEGORY_CODE": "003002000000",
"ACTUAL_DATE": 1300320000000,
"ERROR_CODE": 0,
"XC": 8462287.8391999993,
"YC": 7404605.9847999997,
"XMIN": 8462232.0723000001,
"XMAX": 8462343.5934999995,
"YMIN": 7404567.1859999998,
"YMAX": 7404644.7895999998,
"DEL_FEATURE": null,
"G_AREA": 5915.8207941399996,
"SHAPE_Length": 319.99096690715305,
"SHAPE_Area": 5915.822080951184
},
"geometry": {
"rings": [
[
[
8462243.7506103516,
7404567.1862182617
],
[
8462232.0723876953,
7404623.9940185547
],
[
8462331.9340209961,
7404644.7897949219
],
[
8462343.5936279297,
7404587.9645996094
],
[
8462243.7506103516,
7404567.1862182617
]
]
]
}
}
]
}
[7] Каждый запрос пытаться повторить раза два. Если ПКК упорно шлет ошибку на какой-то кусок, считать всю попытку получения квартала неудачной и выдавать сообщение с предложением попробовать ночью позже.
[8] Проверкой "А не сменились ли OBJECTID, и не получили ли мы участок не с того квартала?" предлагаю принебречь. Т.к. по моим прикидкам такой опрос сервера затянется минут на 10 максимум. Или это уже долго?
По сути тоже самое, только некоторые углы, на мой взгляд, срезал.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей