Мои мысли и проекты

Общее описание

Навигация
Счетчики
Cпoнcоры

Общее описание

Существует такой проект как «OpenStreetMap» (OSM) — это совместное создание и свободное распространение детальных карт всего мира. Вы можете участвовать в проекте (загружать свои треки на сервер, дорисовывать общедоступную карту по спутниковым снимкам Yahoo!, Bing, Космоснимки и др.) и использовать эти карты совершенно свободно, в отличие от многих других карт, даже бесплатных, свободное использование которых на самом деле ограничено.
В данной статье (и возможно она будет не одна) я хочу описать несколько мыслей на тему использования OSM при отрисовке 3D карт.
При отображении карт OSM делит всю земную поверхность на тайлы (впрочем точно также поступают и другие картографические сервисы). На самом верхнем уровне вся поверхность Земли представлена одним тайлом. На следующем уровне 4, дальше 16 и т.д. Т.е. каждый следующий уровень детализации состоит из 4-х тайлов. Этот метод называется QuadTree (смотрите рисунок).

На верхнем уровне тайл размером 256x256 пикселей, на следующем уровне размер изображения уже будет 512x512 пикселей (т.е. 2x2 тайла и каждый размером 256x256 и того получаем 512x512). Т.е. каждый следующий уровень в 2 раза больше предыдущего.
В OSM размеры по lng: от -180° до 180°, по lat: от -85.0511° до 85.0511° ( Значение 85.0511° связано с ограничением проекции Меркатора ).
Мы определились, как мы делить карту на части,чтобы её было удобно выводить. Однако пока у нас нет информации: что именно мы будем выводить на карте. Обычно вся информация делится по слоям, поэтому и мы тоже так сделаем. Каждая программа будет сама выбирать, какие слои отображать. Пока не будем конкретизировать какие слои нам нужны, а просто подведем итоги: выводить карту мы будем по тайлам. Каждый тайл должен содержать следующую информацию:
  • Ограничивающий прямоугольник тайла [нижний-левый угол,верхний-правый угол] заданный в градусах.
  • Ссылку на родительский тайл (если он есть).
  • Ссылку на дочерние тайлы (если они есть).
  • Список слоев

Каждая программа может сама решать, какие слои она будет выводить, а какие игнорировать. Данные каждого слоя будем хранить в отдельном файле[/]. Если программа не поддерживает вывод какого-то слоя, то она может даже и не скачивать этот файл.
Попробуем определиться со списком слоев:
  • Ландшафт
  • 3D объекты (здания, светофоры, мосты и т.д. и т.п.)
  • POI (точки интересов). Указатели интересных мест
  • Граф дорог для построения пути в пределах тайла (графы могут быть разные: для автомобилей, пешеходов, велосипедистов и т.д.)

Ландшафт может быть как простым (полигон+текстура на нем), так и сложным (заданная 3D моделью).
3D объекты задаются 3D моделью, состоящую из вершин (lng°, lat°, высота в метрах) и полигонов (материал, вершины полигона (номер вершины + текстурные координаты)). Модель указывается в локальных координатах. А в слое 3D объектов указываем модель + 2D координату положения + угол поворота в градусах вокруг оси Z. Считаем, что в локальных координатах объекта ось Z направлена вверх, ось X вправо, ось Y от зрителя за экран. Положительный угол поворота вокруг оси Z считаем от оси X к оси Y.
POI задаём 2D точкой на карте + тип + имя + имя файла с подробным описанием. Подробное описание выносим в отдельный файл, чтобы не грузить лишнюю информацию.
Граф для построения пути передвижения - на текущий момент я про это сказать ничего не могу так как никогда этим не занимался. Однако при хранении слоев в отдельных файлах нам не обязательно в одном слое знать принцип организации другого слоя. Поэтому пока я это описывать не буду.

Все данные будут хранится в формате XML, так как этот формат универсальный, что очень хорошо подходит для наших задач. Хотя он будет читаться медленне бинарного формата, но не думаю, что для современных устройств это является таким уж слабым местом. При использовании SAX-парсера даже затраты на память будут минимальны.
Ниже я привожу ориентировочный формат данных.
Тайл.
 
<tile bbox="-180,-85.511,180,85.511"> 
 <parent>Ссылка на родительский тайл (если есть. Если ссылки нет, то данный тэг отсутствует)</parent>
 <child bbox="-180,-85.511,  0,     0">Ссылка на дочерний тайл 1(если есть. Если ссылки нет, то данный тэг отсутствует)</child>
 <child bbox="-180,      0,  0,85.511">Ссылка на дочерний тайл 2(если есть. Если ссылки нет, то данный тэг отсутствует)</child>
 <child bbox="   0,      0,180,85.511">Ссылка на дочерний тайл 3(если есть. Если ссылки нет, то данный тэг отсутствует)</child>
 <child bbox="   0,-85.511,180,     0">Ссылка на дочерний тайл 4(если есть. Если ссылки нет, то данный тэг отсутствует)</child>
 <layer type="landscape">Сcылка на МОДЕЛЬ ландшафта</layer>
 <layer type="landscape-lite">Сcылка на ТЕКСТУРУ</layer>
 <layer type="objects3D">Сcылка на файл</layer>
 <layer type="POIs">Сcылка на файл</layer>
</tile>

Слой landscape-lite - это упрошенный вариант ландшафта, который состоит из одного полигона с натянутой на него текстурой. В случае с OSM текстура - это картинка тайла.
Каждый раз запрос будет начинаться с тайла самого верхнего уровня и затем уже "спускаться" до нужного. При этом достаточно загружать только сам тайл, так как в нем содержится вся необходимая информация для следующих запросов. При этом можно КЕШ-ировать все запрошенные данные как в памяти, так и на диске. И данное КЕШ-ирование можно применить ко всем файлам.
Слой: 3D объекты
 
<objects3D>
 <!-- Список объектов -->
 <object pos="lat,lng[,высота в метрах. Если не задана, то = 0]" rotX="угол поворота вокруг оси X" rotZ="угол поворота вокруг оси Z">Ссылка на модель объекта</object>
 <object pos="lat,lng[,высота в метрах. Если не задана, то = 0]" rot="угол поворота">Ссылка на модель объекта</object>
 ...
</objects3D>
 

Слой: Точки интересов
 
<POIs>
 <!-- Список POI -->
 <poi pos="lat,lng" type="тип" name="имя">Ссылка на файл с подробным описанием</poi>
 <poi pos="lat,lng" type="тип" name="имя">Ссылка на файл с подробным описанием</poi>
 ...
</POIs>
 

3D модель
 
<model>
 <!-- Список вершин -->
 <vertex>lat,lng,высота в метрах</vertex>
 <vertex>lat,lng,высота в метрах</vertex>
 ...
 <!-- Список полигонов. Вершины задаются против часовой стрелки. -->
 <polygon material="ссылка на файл материала">
  <node>индекс вершины[,текстурная координата U,текстурная координата V]</node>
  <node>индекс вершины[,текстурная координата U,текстурная координата V]</node>
  ...
 </polygon>
 <polygon material="ссылка на файл материала">
  <node>индекс вершины[,текстурная координата U,текстурная координата V]</node>
  <node>индекс вершины[,текстурная координата U,текстурная координата V]</node>
  ...
 </polygon>
 ...
</model>
 

Файл материала
 
<material>
 <texture0>Ссылка на файл текстуры</texture0>
</material>
 

Пока в материале есть только один параметр - текстура. Остальное в случае необходимости будет введено позже.

Во всех XML файлах описывается ссылка на файл. Ссылка задаётся в формате URI. Используемые схемы: http и file.

Категории: OSM 3D