25.09.2017

Чем Открыть Xpart

Поиск маршрутов за 1 человеко- месяц / Хабрахабр. Краситель Универсальный Джинса Инструкция. Однажды для нашего проекта потребовался функционал прокладки маршрутов. Программистов у нас не то чтобы очень много, а скорее наоборот, поэтому мы хотели найти какое- то готовое решение, поискали и ничего хорошего не нашли. Данные дорожного графа у нас были, но в таком виде, что ни в одну библиотеку или какой- то middle- ware их так просто не подать.

Чем Открыть Xpart Файл

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

  1. Файл с расширением jpg – как и чем открыть, описание формата. Ссылки на программы для открытия jpg-файла.
  2. Tim Lashkhidze есть на Facebook. Присоединяйтесь к Facebook, чтобы связаться с Tim Lashkhidze и найти других друзей. Facebook предоставляет .

О процессе разработки сервиса и расскажу. О графе. Несколько слов о данных. Данные мы получаем от стороннего поставщика, на формат и состав данных влиять не можем. Данные о дорогах имеют вид файла в формате Arc. View (Shapefile). Все улицы разбиты на сегменты от перекрестка до перекрестка, каждому сегменту сопоставлены атрибуты: — уникальный идентификатор сегмента— геометрическая ломаная, изображающая сегмент дороги— данные о разрешенной максимальной скорости по ПДД— данные о возможности разворота в начале и конце сегмента— признак одностороннего движения на сегменте— Z уровень начала и конца сегмента (например въезд на эстакаду имеет в начале уровень 0, а в конце уровень 1)Кроме того есть отдельный файл с ограничениями движения, накладываемыми логикой и/или ПДД. Каждое ограничение — это вектор идентификаторов, ссылающихся на сегменты улицы (из первого файла), последовательное движение по которым запрещено.

OSRM именно под Open Street Maps заточен, но вам стоит всё же .

Пример того, как все это выглядит, висит в заголовке поста (красным — запреты, к сожалению, наш софт в данном случае не позволяет нарисовать запреты с направлением). Для работы алгоритмов на графе, требуется, чтобы граф был представлен в каком- то общепринятом виде, например в виде списка связанности вершин, или матрицы связанности. То есть фактически требуются данные о вершинах и связях между ними. Поскольку в наших данных сведения о вершинах очень неполные, есть только данные об их геометрическом местоположении, пришлось провести обработку, чтобы все вершины получили уникальные идентификаторы. За основу мы взяли геометрическое местоположение вершин, но было одно обстоятельство: координаты конечных вершин сегментов не всегда совпадали на 1. ГИС системы, точно не знаю).

Поэтому мы приняли решение считать одной вершиной графа все конечные точки сегментов, имеющие одинаковый Z- уровень и отстоящие друг от друга не дальше чем на 1 метр. Всего сегментов уличной дорожной сети в наших данных примерно 1. Соответственно нужен был какой- то нелобовой алгоритм нахождения всех соседей на расстоянии до 1 метра каждой точки. Лобовой перебор всех пар имеет квадратичную сложность и работает чрезмерно долго. Поскольку мы решили, что наша программка будет работать напрямую с исходным представлением данных, то есть с Shape- файлами (причины: легко обновлять, не нужно поддерживать, документировать, версионировать собственный формат хранения), то нужен был эффективный алгоритм идентификации вершин. Придумали вот что (здесь и далее код на С++): 1.

Сделали контейнер для ребер графа: typedef size. Вероятно это было не самое правильное решение, потому что на мой взгляд усложнило логику некоторых процедур, но в начале казалось, что так будет нормально. Рис 1. 2. Координатную плоскость разбили на квадратики метр на метр (рис 1). Каждой вершине сопоставили ключ: static. Сделали хэш- контейнерtypedef size. Если с таким ключом в контейнере уже есть точки, то новую точку не добавляем, а возвращаем идентификатор уже имеющейся (при условии что имеющаяся точка в контейнере на том же Z уровне что и добавляемая). Если по ключу в контейнере ничего нет, то вносим точку в контейнер и возвращаем идентификатор добавленной точки.

Чем Открыть Xpart Файлы

Правда точки, расстояние между которыми меньше 1 метра, могут иметь разные ключи, поэтому мы проверяем контейнер не только по вычисленному ключу, но и по 8- ми соседним: std: :vector< size. И если оно меньше заданного, то считаем, что точки одинаковы и объединяем в одну вершину (на рисунке покрашены в один цвет), возвращая идентификатор подходящей вершины уже имеющейся в ячейке с ключом get. Key(x. Part, y. Part). В результате получаем, что соседние точки ближе заданного порога получают один идентификатор.

Теперь у нас есть список смежных вершин. Временная сложность получения такого списка линейно зависит от количества вершин, потому что каждую мы обрабатываем ровно 1 раз, а операции поиска и вставки в хэш- контейнер имеет асимптотически константную сложность. Как вы уже, должно быть, заметили, мы не обрабатываем промежуточные вершины ломаной уличного сегмента, так как на топологию графа они не влияют (в середине сегмента нельзя осуществить никакого маневра, во всяком случае у нас нет об этом данных). Если бы мы разбили ломаную на составляющие ее отрезки и каждый отрезок считали бы ребром, то в графе вместо примерно 1. Значительно возросло бы время поиска пути, в конце я покажу эту разницу в абсолютных значениях. Остался последний штрих. Ограничения, или запрещенные маневры.

Ограничение запрещает какой- либо маневр, например поворот налево на перекрестке. Исходно в данных представляет собой список сегментов, последовательное движение по которым запрещено. Приведу пример: Рис. Красные стрелки показывают запрещенный маневр, числа обозначают идентификаторы сегментов. Фактически в данных этот запрет выглядит как .

И через эти дублированные вершины провесили ребра так, чтобы создать разрешенные маневры, а для запрещенного маневра такой маршрут просто не создавать. При клонировании вершины ее геометрическое местоположение остается прежним (показанные на рисунке вершины v. Проиллюстрирую сказанное на примере перекрестка с запрещенным левым поворотом выше: Рис 3. Видно, что на графе с измененной топологией осуществить левый поворот по запрещенному пути на перекрестке больше нельзя, при этом все разрешенные маневры остались возможными. Ограничения из более чем 2- х ребер обрабатываются по тому же принципу, но порождают больше новых вершин и ребер, на размер графа эти трансформации влияют, но не значительно (рост числа ребер примерно на 5%). В наших данных порядка 5.

Вот иллюстрация того, как трансформируется граф под действием ограничения из 3- х ребер: Было: Рис 4. Стало: Рис 5. Надо сказать, что реализация алгоритма трансформации графа стала самым сложным этапом всей работы (на нее ушло около 3. Отчасти это связано с не самой хорошей проработкой структуры хранения данных.

Так что если что- то осталось непонятным — не страшно, это действительно было непросто, задавайте вопросы, постараюсь ответить. Об инструментах. И так теперь у нас был граф представленный в удобном виде с учетом всех ограничений, по которому можно было прокладывать маршруты. В качестве алгоритма решили попробовать классический алгоритм Дейкстры, хорошая реализация которого есть в библиотеке boost. Тут добавить особо нечего, по boost: :graph есть хорошая документация и даже книги, мы взяли код одного из примеров и с небольшими изменениями использовали его у нас.

Следующим этапом стала обработка запросов. Мы решили, что удобно, если сервис сможет прокладывать маршрут, имея только начальную и конечную точку, заданные координатами.

А значит надо быстро найти начальную и конечную вершину в графе, которые максимально близко расположены к соответствующим точкам запроса. Для этого нужно было быстро уметь находить ближайшую к заданной пользователем точку на уличной сети (пользователь может захотеть маршрут от точки находящейся вне дорожно- уличной сети). Тут уместно вспомнить о том, что сегменты дорожно- уличной сети в наших данных это ломаные, поэтому нам надо было найти ближайшую к заданной точку на ломаной (это может быть точка лежащая на ломаной, либо ее начальная или конечная вершина). Ломаных довольно много (1. Искать перебором всех сегментов слишком медленно. Тут на помощь пришла свежая версия библиотеки boost: :geometry, где появились пространственные индексы (boost: :geometry: :index) уже с поддержкой такого объекта как ломаная линия (linestring). С использованием этого индекса мы быстро находим несколько ближайших кандидатов, из них затем точным алгоритмом определяется сегмент, наиболее близко проходящий возле заданной точки.

Для чтения SHP файлов мы использовали библиотеку GDAL, для преобразования между географическими системами координат (мы работаем в локальной системе города, так исторически сложилось), а пользователю удобнее использовать GPS (WGS8. О деталях.— маршрут к середине ребра. Напомню что наш граф — топологическое представление дорожной сети, геометрические детали для работы алгоритма Дейкстры неважны. Но геометрический аспект важен для пользователя. Вспомним, что алгоритм Дейкстры строит кратчайшие маршруты от заданной вершины графа до всех остальных (включая искомую конечную вершину).

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

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

Файл с расширением . Чем открыть? Множество программ менеджеров закачки при загрузке из интернета какого- либо файла добавляют к имени файла расширение . Предположим, скачивается файл movie. Когда файл скачается полностью, из его имени пропадет расширение . Скорее всего, большой пользы из файла с расширением .

Придется дождаться полной загрузки файла или начать загрузку заново. Но если ситуация не позволяет этого сделать, можно удалить из имени файла расширение . Если вы не нашли ответ или нужную информацию.