Свой редактор для ОСМ

Ура, товарищи!!! Мы на линуксе!!!)

Ubuntu 9.10 x64, полет нормальный!)
То что на скрине рисуется где-то 3-5 фпс. Но рисуется примитивно через glBegin(GL_POINTS); и glBegin(GL_LINE_STRIP);!!!
Абсолютно никакой оптимизации… с VBO, отсеивалками и т.д. практически уверен, что никаких тормозов не будет вообще.
Прикручу их попозже… тут я от радости решил схалтурить и сделать как попало лишь бы заработало под убунтой)
Мне почему-то казалось что OpenGL под линухом будет медленнее или вообще не будет))
Питон на линухе тоже завелся без проблем… работает!

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

Если сравнивать с ДЖОСМ’ом или просто с площадью, которою можно загрузить с сервера за один раз, то для редактирования таких данных ресурсов нужно значительно меньше… можно и без особо навороченных алгоритмов оптимизации сделать)

Есть и неприятный момент: у меня выгорела плашка памяти на 2 гига! Но это не связано с особенностями работы моей тулзы)))

Данные центра Москвы подгружались прямо с сервачка, правда кусками… т.к. большую область он не дает за раз скачать.
Прикрутил “выбиралку” места редактирования.

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

Прикрутил слои, правда пока только с данными.
Авторизация, загружалка данных на сервер есть, но пока очень примитивная… не сильно отличается от того что я выкладывал.

Вот такие вот дела.

Красивенько!

А с проекциями вы чего решили? Взяли proj4? Что-то другое? Или что-то свое?

Использую либу Boost.Geometry (aka GGL, Generic Geometry Library)… возможно она обертка над proj4, пока не разбирался.
Конвертацию долготы/широты в “свои” XY, которые рисует OpenGL на данный момент сделал вот так:



typedef double CoordType;
typedef boost::geometry::point_ll< CoordType, boost::geometry::cs::geographic< boost::geometry::degree> > LL;
typedef boost::geometry::point_xy< CoordType > XY;

boost::geometry::projection::parameters params = boost::geometry::projection::detail::pj_init_plus("+proj=merc +ellps=WGS84 +units=m");
projection_converter = boost::shared_ptr< boost::geometry::projection::merc_ellipsoid<LL, XY> >(new boost::geometry::projection::merc_ellipsoid<LL, XY>(params));


Конвертить можно так:

    LL ll;
    XY xy;

    double lon;
    double lat;

    double x;
    double y;

    // Туда
    ll.lon( ...значение... );
    ll.lat( ...значение... );

    projection_converter->forward(ll, xy);
    lat = ll.lat();
    lon = ll.lon();
    x = xy.x();
    y = xy.y();


        // Сюда
    xy.x( ...значение... );
    xy.y( ...значение... );

    projection_converter->inverse(xy, ll);
    lat = ll.lat();
    lon = ll.lon();
    x = xy.x();
    y = xy.y();
    

Подозреваю что строкой “+proj=merc +ellps=WGS84 +units=m” можно управлять алгоритмом пересчета координат, но толком в этом не разбираюсь. Также это что-то стандартное, потому как в инете полно примеров с подобными строками, эту собственно подобрал методом тыка)

Плохо вот что:
при приближении до домов точки начинают скакать при рендере относительно истинной позиции, но не более чем на метр.
Этот трабл я подправлю… возможно тут я неправильно выбрал единицы измерения, в следствии чего числа где-то округляются. Сейчас это double у которого, насколько я понимаю, 1.0 - это один метр… хотя тут я немного путаюсь метр на проекциях ведь может выглядеть по-разному в разных местах.

Интересно, какая проекция у яховских снимков?

У Яхи по идее должна быть такая, такая же как у JOSM по умолчанию, у Гугла и пр. +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs Так называемая EPSG:900913.

Aleksandr Dezhin, спасибо! В параметрах строки буду разбираться!

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

Ограничения можно подобрать исходя из точности данных OSM’а.
Подскажите, пожалуйста, какая предельная точность в осме?

Координаты он возвращает в виде 37.8850174 т.е. минимальный шаг 0.0000001, а это, если умножить на радиус Земли…

2pi6378137 = 40075017 метров… длина экватора
40075017 / 360 = 111319,49 метров в градусе
111319,49 * 0.0000001 = 0,0111 м

т.е. в осме минимальный шаг около 11 см? 11 см как-то не понтово)
Если это так, то, возможно, в базе данные с большей точностью хранятся.

Вот это все проблематично… метрологию не люблю

1.1см по широте (а по долготе еще меньше) - для GIS этого более чем достаточно. 7 знаков после запятой выбраны не случайно, диапазон -1800000000 до +1800000000 умещается в INT32. Т.е. базу в памяти можно держать как массив INT32, а не double. Так и XML парсить быстрее (достаточно выкинуть десятичную точку :)), и памяти жрет меньше, и проверки на видимость устраивать проще.

Со временем можно пойти дальше и при загрузке отдельного региона небольшого размера, при импорте на лету конвертировать его в прямоугольную систему координат типа TM, центральный меридиан выбрать середину района работы и работать с целочисленными координатами. Т.е. хранить в базе например оригинальный NODE в ASCII (на случай экспорта, если координата не менялась), плюс он же конвертированный в прямоугольные XY (в сантиметрах, точнее не надо) для расчетов и рендеринга. Для всяких умножений/делений правда прийдется использовать INT64. Но этим можно заняться, когда появится функционал, пока что на оптимизацию лучше время не тратить.

Я не некропостер, прошло много времени, но кое-что изменилось… надеюсь смогу почаще отмечаться.
Оставлю след, чтобы самому сие начинание не забросить)

За прошедшее время вышел PySide и под винду… тоже самое что и PyQt4 только под LGPL!
Мне удалось немного криво, но “скрестить” PySide и Boost.Python через PythonQt.
Таким образом проблема скриптов, обсуждаемая в этом топике по большей части решилась.
Стало возможным создавать Qt объекты в питоне и взаимодействовать с С++ объектами из этого же питона.
Другими словами получается довольно удобная “система плагинов”… например, можно написать виджеты на Python и добавить их на тулбар С++'ой формы, создавая новые инструменты.
Boost.Python обеспечивает механизм взаимодействия с С++ функциями, классами, объектами и т.д.
Вобщем почти все что мне хотелось получить от скриптов… еще бы попроще немного и покрасивее) А так связка Boost.Python+PythonQt и PySide или PyQt (уже пофиг, они взаимозаменяемы)
Теперь постараюсь подтянуть C++ минимальный функционал, чтобы было хоть что-то работоспособное…

Родил функции для преобразования координат в меркатор и обратно…
Формулы такое же как в исходниках JOSM’а.
Но функции работают с целыми числами… int32
Вид приблизительно такой:


#pragma once
#include <math.h>
#include <limits>

typedef int CoordType;

const double pi = 3.14159265358979323846264338;
const double pi_4 = pi / 4;
const double pi_4_90 = pi_4 / 900000000.0;
const double pi_4_90_i = 900000000.0 / pi_4;

const double intmax = std::numeric_limits<int>::max();
const double intmax_pi = intmax / 3.14159265358979323846264338;
const double dint_max_180 = intmax / 1800000000.0;

CoordType latToY(const CoordType &lat)
{
    return floor(log(tan(lat*pi_4_90 + pi_4)) * intmax_pi + 0.5);
}

CoordType yToLat(const CoordType &y)
{
    return floor(atan(exp(y / intmax_pi))*pi_4_90_i - 899999999.5);
}

CoordType lonToX(const CoordType &lon)
{
    return floor(lon*dint_max_180 + 0.5);
}

CoordType xToLon(const CoordType &x)
{
    return floor(x / dint_max_180 + 0.5);
}

на вход подаются градусы в формате осма, но без точки… т.е. например в осме 33.1122334 (градусы + семь знаков в дробной части) тогда int32 вида 331122334… бывает в осме последнии нули не прописываются, соответственно дополняем: 33.112 → 331120000

В опенгл для определения координат точки можно использовать GLint… он в хидерах задан как обычный int
Соответственно размерность всего пространства опенгл будет предел от -2147483648 до 2147483647. Это обеспечивает и даже немного превышает необходимую точность осма.
Как я посчитал длина окружности экватора около 40 тысяч километров и по горизонтали данного диапазона хватает чтобы задавать координаты точки с шагов в 1см или даже ~8мм… по вертикали все еще проще и точнее, насколько я понял…

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

Возможно кто подскажет как их накодить пошустрее… оптимизировать. Т.к. вызываться они будут довольно часто. Можно добавить inline наверное, но от преобразования типов и работы с double я уйти не смог.
floor(x + 0.5); - это просто округление числа до целого, аналогично функции round, но ее что-то нет… можно округление убрать и просто привести к инту, но тогда на отрицательных числах условие вида if(i == xToLon(lonToX(i))) не выполняется…
в данном варианте в цикле прогнал функции по всему диапазону и ошибок не получил.
Пока кодил гонял их, мерял скорость и пытался сделать побыстрее, но нет предела совершенству)))

Всем привет!!!
Возможно сделать какой нибудь “лайт”-редактор что б в КПК ставился.
Что б прям по ходу обьезжать, и пометки делать. Дома скинуть на сервер.
Пусть не ввсё, но хотя б основные действия.
Я б прям в машине ехал, писал трек. Вижу лежачего полицейского, остановился, пометил, здания, …
Дать класификацию треку, вот и дорога.
Дома я трек выложил, а всё остальное что, по памяти делать?
Писать бумажки я не люблю, это если “бортовой” журнал вести вдоль трека …
Если б облегчить “понимание”, я б мог знакомых подтянуть в это благородное дело.
Есть мотаются не мало, дарог бы понарисовали, только заморачиваться не будут, один из таких навигатор в окно выкину, когда он его в дыру завёз, это 2 года назад было, сейчас то карты по лучше в любом случае, да и разбираться начали, что навигатор это не телевизор, купил и смотри, здесь карты обновлять надо, да и саму программу.

http://wiki.openstreetmap.org/wiki/RU:OSMtracker
Умеет записывать трек, ставить разнообразные метки (я бы сказал - любые. В т.ч. произвольные, т.к. - )
Интерфейс можно “русифицировать” и настроить под свои нужды/интересы.

Для Андроид есть http://code.google.com/p/osmeditor4android/

Ой мама…

Выкинуть вообще всю плавучку, переписать тангенс с логарифом на работу с единицами “градусы * 10 000 000” и радоваться жизни.

Да, это будет велосипед с квадратными колёсами. Зато быстрый :))

по первой ссылке - это вещь. закладку поставил. будет время опробую.
Благодарю.
Всем удачи!