Проектирование ГИС

Вопросы по нескольким пакетам сразу, или вопросы, которые непонятно к какой ГИС отнести
e1ywka
Новоприбывший
Сообщения: 8
Зарегистрирован: 07 июн 2011, 23:35
Репутация: 0
Контактная информация:

Проектирование ГИС

Сообщение e1ywka »

Я разрабатываю ГИС :). Концепция системы предполагает многопользовательскую работу с картой (просмотр и редактирование). Проект реализован на dotNet-е. Система имеет трехзвенную архитектуру. База данных со spatial-расширением (MySQL, PostGIS), доступ к данным с использованием NHibernate, в частности NHSP для работы с пространсвенными объектами с помощью библиотеки NetTopologySuite. Клиент и сервер общаются по WCF, клиент отрисовывает карту с использованием GDI+.
В данный момент в системе реализованы основные модули. Основная проблема, что не удалось добиться приемлемой скорости работы на больших наборах данных: карта города имеет порядка 250000 геометрий (где-то 25 слоев).
Как путь развития, я вижу изменение формата данных. Необходимо произвести симплификацию геометрий и на разных зумах отображать различный набор данных, дополнительно отключая чрезмерно детализированные слои (как, в принципе, делается на всех онлайн картах). Подскажите, сложно ли идти по этому пути с учетом выбранных средств реализации, и есть ли какие рекомендации. Если нужно, могу дать пояснения по конкретным аспектам реализации системы.
yellow-sky
Гуру
Сообщения: 588
Зарегистрирован: 30 мар 2009, 21:53
Репутация: 55
Откуда: Королев

Re: Проектирование ГИС

Сообщение yellow-sky »

Проблемы с производительностью вашей системы вполне объяснимы. Основная причина - выбранные средства реализации и архитектура системы.
.NET сам по себе не очень быстрый, а когда вы пытаетесь использовать его на больших объемах динамических данных вся его рантайм оптимизация стремится к нулю.
GDI+ - тот еще тормоз. Мало того, что он не использует ни какой хардварной акселерации, так и заменить то его практически нечем - WPF тоже не блещет производительностью. И хотя мелкомягкие обещали прикрутить к нему железное ускорение, все тесты которые я проводил в этом плане, не показали существенной прибавки в скорости (хотя я тестировал еще на бета версиях WPF, и сейчас все изменилось). Если у вас самописный движок рендеринга, то возможно имеет смысл сменить GDI+ либо на Direct2D (перенос будет посложнее) либо поискать в инете старенькую библиотеку QuickDraw Надолинского Никиты (это ускоренный вариант GDI+ и потому перенос кода по-моему будет проще).
Ну и еще одно узкое место вашей системы - WCF. Да, он удобен и легок при разработке. Но если вы передаете через него большие объемы, то он будет явно просаживать скорость доступа к данным (Я надеюсь вы хотя бы используете TCPшные биндинги и передаете геометрии в WKB). К сожалению, доступ к геометриям через сервисы еще долго будут отставать от доступа через прямое соединение с базой.
А генерализация и симплификация данных - это обязательный шаг, при подготовке конечных карт-сервисов и продуктов. Но выполняются они обычно стандартными средствами подготовки данных и правильной настройкой карт проектов. И это не должно влиять на саму разработку и оптимизацию системы. Это так сказать ваши мешки с песком, последний козырь оптимизации конечного продукта. И не стоит использовать эти методы на ранних стадиях разработки собственного ГИС движка. Использовав их, вы не ускорите свой движок. Вы ускорите один из конечных продуктов. А по поводу на сколько сложно использовать генерализацию и симплификацию - я думаю скорее просто чем сложно. И то и другое можно провести не написав ни строчки кода, работая только с данными.
yellow-sky
Гуру
Сообщения: 588
Зарегистрирован: 30 мар 2009, 21:53
Репутация: 55
Откуда: Королев

Re: Проектирование ГИС

Сообщение yellow-sky »

И да, забыл указать по оптимизации WCF и самого рендеринга - при отрисовке данных (при редактировании это не так актуально) я бы посоветовал использовать многопоточный доступ к данным. Один поток WCF редко когда загружает канал целиком. У вас 25 слоев. И если загрузку данных распараллелить на несколько потоков (я бы выбрал параметр - колво ядер - 1, все таки gdi+ софтовый рендерер), то отрисовка будет происходить без задержек из-за сетевых запросов.
Ну и как в любой современной ГИС желательно использовать кэширование данных на клиенте.
e1ywka
Новоприбывший
Сообщения: 8
Зарегистрирован: 07 июн 2011, 23:35
Репутация: 0
Контактная информация:

Re: Проектирование ГИС

Сообщение e1ywka »

yellow_sky, большое спасибо за Ваш ответ.
Да, согласен, .Net не оптимальный инструмент, но я пришел в ГИС из иной предметной области, и начинал изучение используя свои знания. Основные плюсы -- это низкие требования к уровню разработчика и высокая скорость разработки.

В данный момент система достигла своего развития. Domain объекты и DTO хранят геометрии в формате WKB, используются spatial-индексы в СУБД. Сжатие данных zip-ом для передачи по каналу wcf (биндинг wsHttp). Клиент использует локальный кэш (EntLib Caching Block).
Карта загружается в несколько потоков. При конвертации карты из статичных файлов в БД создается сетка, по элементам которой и происходит выборка данных (MBRIntersects).
При профилировании приложения выявил, что львиная доля памяти и времени уходит на создание геометрий (байтовых массивов wkb). Причина, думаю, -- криво нарисованные карты, где "полигончики" могут иметь до сотни и больше точек.
К GDI у меня особых притензий нет, при загрузке сетки перерисовывается только загруженный кусочек, так что здесь всё оптимально.

yellow_sky, Вы точно выразились, пора сбрасывать мешки )
yellow-sky
Гуру
Сообщения: 588
Зарегистрирован: 30 мар 2009, 21:53
Репутация: 55
Откуда: Королев

Re: Проектирование ГИС

Сообщение yellow-sky »

e1ywka писал(а): В данный момент система достигла своего развития.
Да, часто бывает, что у ГИС разработчиков нет возможности выбора инструментов реализации. Особенно если это глубоко интегрированное решение или добавление ГИС функциональности в уже существующую систему. Сам так мучаюсь уже во втором проекте :)
e1ywka писал(а): Сжатие данных zip-ом для передачи по каналу wcf (биндинг wsHttp).
По моему сменить биндинг очень просто, подправив всего одну строку в конфиге сервера и клиента. Ради интереса я бы провел сравнительное тестирование на TCP и HTTP биндингах.
e1ywka писал(а): Клиент использует локальный кэш (EntLib Caching Block).
К сожалению в проекте не используются enterprise library, потому ни чего не могу сказать про данный тип кэша. Я часто делаю простой тип кэширования на уровне дата сорсов - все привязывается к последнему экстенту запрошенных данных. Но этот вариант плохо управляется по размеру памяти - можно регулировать только на уровне количества записей в дто.
e1ywka писал(а): Карта загружается в несколько потоков.
О! Вот это я понимаю. Впервые вижу реализацию с изначально верной политикой загрузки ) Сами мы используем SharpMap и сейчас думаем о переписывании процесса загрузки данных. Но пока все это только в планах (
e1ywka писал(а): При конвертации карты из статичных файлов в БД создается сетка, по элементам которой и происходит выборка данных (MBRIntersects).
Не очень понял этот абзац. Вы сами реализовывали пространственный индекс?
e1ywka писал(а): При профилировании приложения выявил, что львиная доля памяти и времени уходит на создание геометрий (байтовых массивов wkb). Причина, думаю, -- криво нарисованные карты, где "полигончики" могут иметь до сотни и больше точек.
Тоже не понял. Вы генерируете wkb на сервере для передачи? Для повышения общей "скорострельности" системы я бы посоветовал и хранить и передавать все геометрии без промежуточных конвертаций. Единственное преобразование должно быть на этапе отрисовки. А по поводу полигонов с сотнями вертексов - это не является показателем кривизны карты. У нас есть данные по лесным массивам с тысячами вертексами на полигон, а бывает что все это в составе мультиполигона. Таковы данные.
e1ywka писал(а): К GDI у меня особых притензий нет, при загрузке сетки перерисовывается только загруженный кусочек, так что здесь всё оптимально.
Эээ.. Вы отрисовываете только часть канвы при загрузке новых данных? Как вы решили проблему со сложными заливками, например зашитрихованные полигоны или полигоны залитые битмапами? Артефакты на границах не вылазят?
Я конечно понимаю, что такой способ отрисовки наиболее оптимальный, но по-моему реализация излишне сложная. На память не приходит ни одной ГИС, у которой такой вариант рендеринга. Может вы откроете код рендерера под LGPL )
dwarwood
Завсегдатай
Сообщения: 316
Зарегистрирован: 09 июн 2005, 10:38
Репутация: 2
Откуда: Yaroslavl, Russia
Контактная информация:

Re: Проектирование ГИС

Сообщение dwarwood »

Р. Томлинсон "Думая о ГИС", хотя бы бегло, книгу видели?
наверняка на какие-ниб из граблей, там хорошо описанных, "придя из другой области", вы наступили :-)

//.net и прочее в данном случае не самое худшее, бывает такая архитектура и работает. правда то что я видел с самого начала "точилось" под медленные каналы, и особенности типа генерализации слоев (==" симплификацию геометрий и на разных зумах отображать различный набор данных") закладывались.
e1ywka
Новоприбывший
Сообщения: 8
Зарегистрирован: 07 июн 2011, 23:35
Репутация: 0
Контактная информация:

Re: Проектирование ГИС

Сообщение e1ywka »

yellow_sky писал(а):Не очень понял этот абзац. Вы сами реализовывали пространственный индекс?
Нет, имеется в виду, что карта разрезается на логические "квадраты", достаточно малые для использования spatial-индекса СУБД по таблице с реальными геометриями, но не слишком малые, чтобы не плодить много потоков при загрузке. Т.е. это такие же геометрии-квадраты, по которым строится свой индекс. Плюс они имеют версию, при изменении которой перезагружается кэш на клиенте.
yellow_sky писал(а):Тоже не понял. Вы генерируете wkb на сервере для передачи?
Здесь проявляется минус NHibernate, что он самостоятельно создает объекты. Загружает как объект, формирует wkb, передает так на клиент по wcf. Это, кстати, тоже корявое место, надо будет пересмотреть реализацию.

Для отрисовки используются всякие HatchBrush, TextureBrush. Для хранения стилей используется довольно громоздкий объект, но мы работаем с этим через иерархию хибера, так что более менее удобно. (Простите за мой сленг). При рендеринге задаются Clip регионы, а отрендеренная картинка отрисовывается на панель с DoubleBuffered = true в перегруженном методе OnPaint.
У меня была идея выложить ядро проекта под свободной лицензией, чтоб продукт сам себя рекламировал ) тем более система заточена под плагины. Но пока местами стыдно за код :oops:

dwarwood, я уже столько информации переварил за последний год ) спасибо за совет, почитаю.
yellow-sky
Гуру
Сообщения: 588
Зарегистрирован: 30 мар 2009, 21:53
Репутация: 55
Откуда: Королев

Re: Проектирование ГИС

Сообщение yellow-sky »

e1ywka писал(а): Нет, имеется в виду, что карта разрезается на логические "квадраты", достаточно малые для использования spatial-индекса СУБД по таблице с реальными геометриями, но не слишком малые, чтобы не плодить много потоков при загрузке.
Я совершенно запутался ) Что есть разрезание на логические квадраты? Вы разрезаете сами данные по сетке, или просто строете саму сетку? Я не очень понимаю смысл всей этой конструкции. GiST индекс отлично справляется даже с сильно отличными в плане размеров геометриями. И его скорость тоже не вызывает нареканий.
Я не понимаю зачем строить дополнительную сетку. Если сетка регулярная, то её можно эмулировать экстентами, имеющими фиксированный размер\положение. Если весь вопрос в обновлении кэша, то и это можно было реализовать без сетки. При изменении геометрии можно оповещать клиента о необходимости обновления экстента территории, равной экстенту этой геометрии. Я делал подобную систему обновления тайлов и вполне обходился без регулярных сеток.
e1ywka
Новоприбывший
Сообщения: 8
Зарегистрирован: 07 июн 2011, 23:35
Репутация: 0
Контактная информация:

Re: Проектирование ГИС

Сообщение e1ywka »

Сетка - это физически существующая таблица с записями. У меня сложилось понимание, что пространственный индекс, базирующийся на R-tree, хорошо работает при поиске по малой области на карте, но производительность значительно падает при загрузке более менее крупной. Это показывали и наши суррогатные тесты.
В существующей релизации только клиент может инициировать запрос на сервер. При каждом перемещении карты он определяет нужно ли ему запрашивать данные с сервера. Клиент отправляет координаты области, видимой на экране, на сервер, сервер определяет ячейки, которые содержатся в этой области, клиент проверяет по координатам и версии наличие этих ячеек в кэше и загружает / обновляет требуемое.
Если другой пользователь меняет геометрию, меняется версия ячейки сетки, и клиент вынужден перезагрузить область. Это же служит для определения конфликтных ситуаций (optimistic locking).
yellow-sky
Гуру
Сообщения: 588
Зарегистрирован: 30 мар 2009, 21:53
Репутация: 55
Откуда: Королев

Re: Проектирование ГИС

Сообщение yellow-sky »

К сожалению я не делал сурогатных тестов для пространственного индекса в постгисе, но замерял скорость отдачи реальных данных и сравнивал c mssql2008. Никакой просадки по сравнению с сиквелом я не заметил (может плохо тестировал)
Кстати в постгисе используется RTree поверх GiST, он null безопасный. Алгоритм поиска в современных реализациях RTree очень хорош, и многие меня уверяют что он один из лучших, даже в наихудших случаях (я с ними всегда спорю, но доказать мне нечем :( ). В сиквеле если я не ошибаюсь тоже используются сбалансированные деревья. Но реализация мелкомягкого индекса очень уж мне напоминает многоуровневый индекс есраевцев. Так что у меня есть много оснований предполагать, что индексы в постгисы очень даже эффективные, и очень даже хорошо масштабируются.
Не могу утверждать, но мне кажется, что вы могли не собирать статистику и не выполнять VACUUM для таблиц после добавления больших объемов данных. К сожалению, Gist индексы, а вернее планировщик запросов, ведет себя очень странно с таким типом индекса. И если статистика не собрана, то очень часто он вообще игнорирует его. Поэтому при тестировании всегда важно проверять что планировщик точно использовал индекс.
Не подумайте что я придираюсь к вашей реализации, но мне и правда интересно, зачем вы реализовывали свою версию индекса, так сказать в чем его прелесть? Кстати забыл спросить. А что же хранится в самих ячейках вашего грида?
e1ywka
Новоприбывший
Сообщения: 8
Зарегистрирован: 07 июн 2011, 23:35
Репутация: 0
Контактная информация:

Re: Проектирование ГИС

Сообщение e1ywka »

У нас просто небольшое недопонимание. Ячейка - это фактически геометрия, полигон с 4 вершинами. Этот полигон используется для фильтрации данных по таблице геометрий. Т.е. никакой это не индекс, просто логическая условность. Как я упоминал, помимо выборки данных, она используется для синхронизации многопользовательского доступа, для кэша и как единица загрузки одного потока.

Наш продакшн -- MySQL, так что я на самом деле мало что могу сказать по поводу Gist, в боевых условиях не использовал. Но Ваши слова ободряют, так как планируем перейти на PostGIS как на более развитый.
yellow-sky
Гуру
Сообщения: 588
Зарегистрирован: 30 мар 2009, 21:53
Репутация: 55
Откуда: Королев

Re: Проектирование ГИС

Сообщение yellow-sky »

А.. теперь понятнее )
И еще один вопрос - а после того, как на сервере были вычислены необходимые ячейки, как происходит выборка реальных геометрий? Обычным ST_Intersect'ом?
e1ywka
Новоприбывший
Сообщения: 8
Зарегистрирован: 07 июн 2011, 23:35
Репутация: 0
Контактная информация:

Re: Проектирование ГИС

Сообщение e1ywka »

Фактически да. В мускуле еще есть аналог -- MBRIntersects
yellow-sky
Гуру
Сообщения: 588
Зарегистрирован: 30 мар 2009, 21:53
Репутация: 55
Откуда: Королев

Re: Проектирование ГИС

Сообщение yellow-sky »

Ну в данном случае пространственный индекс все равно используется, если он конечно создан для таблицы с геометриями. От его наличия\использования общая скорость выборки данных будет сильно зависеть.
Примерно понял. Спасибо за разъяснения.
e1ywka
Новоприбывший
Сообщения: 8
Зарегистрирован: 07 июн 2011, 23:35
Репутация: 0
Контактная информация:

Re: Проектирование ГИС

Сообщение e1ywka »

Вот здесь написано про генерализацию, хорошая отправная точка, может кому пригодится
Generalisati
Ответить

Вернуться в «Общий - ПО»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя