?

Log in

No account? Create an account
..., имеющее, однако, весьма существенное влияние на активацию карт в BaseCamp.

До сих пор активация самодельных карт в BaseCamp всегда приводила к сбросу прописанного в карте ProductID в ноль, даже в том случае, если к навигатору была привязана какая-либо другая из подписок BirdsEye, скажем, BirdsEye TOPO (ProductID = 8).

Однако, один из пользователей Global Mapper на днях выяснил, что пара байтов блока мета-информации в файлах JNX, ранее считавшиеся неиспользуемыми, на самом деле содержат идентификатор подписки, который используется BaseCamp при активации карты.
Речь идет о втором и третьем байтах, следующих за строкой с названием продукта. И имеющиеся в данный момент JNX-конвертеры записывают в это поле ноль, что и приводит к сбросу номера подписки.

Итак, вместо трех байтов с непонятным назначением имеем один байт непонятного назначения и два байта, в которых нужно дублировать значение ProductID из заголовка файла.

Что касается оставшегося байта, следующего непосредственно за названием продукта, эксперименты показывают, что это на самом деле не нулевой байт, а строка нулевой длины. Если записать сюда произвольную строку в UTF-8, BaseCamp без проблем показывает карту, однако, записанная в этом поле строка нигде не отображается.
Писать что-либо в это поле я бы не рекомендовал, так как в этом случае карта может не открываться в сторонних программах, поддерживающих формат JNX.

Информация про эти новые два поля данных уже внесена в описание формата. Также необходимые исправления были сделаны в коде библиотеки JNXLib, использующейся в SAS.Planet (исправление уже ушло в свежую ночную сборку) и в Global Mapper (ожидается, что новая версия библиотеки будет включена в версию 15.1.8).

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

Метки:

Файлы MTX в программе Mapsource Product Creator, фактически, выполняют точно те же функции, что и MP-файлы в GpsMapEdit, то есть содержат полное описание карты, передаваемое компилятору.
Единственное отличие в том, что MTX создается MPC непосредственно перед передачей компилятору карт bld_gmap32.exe и удаляется сразу же после компиляции (если не установлена опция сохранения временных файлов).

Никто не мешает сделать собственный файл в формате MTX и на его основе скомпилировать IMG-карту с практически произвольными параметрам и содержимым. Именно этот способ применяется в конвертере jnx2img (см. тут или тут).
Ну или остановить компиляцию карты в MPC, взять промежуточный MTX и исправить его нужным образом.

Описать структуру MTX-файла полностью я не смогу не только потому, что лень, но и по той простой причине, что меня интересовало только создание растровых IMG, так что всякие особенности векторных элементов я просто не изучал.

Так что я просто приведу тот список параметров-опций (с префиксом H4), которые изучал в процессе подбора нужных мне параметров. Список в том виде, который валяется у меня на диске, особо не редактировал. Для некоторых параметров удалось установить, в каком поле заголовка TRE они хранятся - такие поля указаны в скобках.
      3d  - Map intended for 3d mesh display (TRE + 0x42, mask 20)
      ti  - map template ID
      af  - FTR address finder
      cp  - Include clip region in map
      csN - text packing
        N=2 - 8-bit SBCS Text packing
        N=3 - 8-bit DBCS Text packing
        N=4 - 8-bit Huffman SBCS Text packing
        N=5 - 8-bit Huffman DBCS Text packing
      cr  - copyright string
      ds  - driving side, 0 - right, 1 - left (TRE + 0x3f, mask 20)
      df  - DEM options
      erN - Extended resolution bits, N=0..4
      ffNNNN - FTR group enumeration
      fhMN
        M - .MDR-file version (must be 1 in GMP)
        N - Multi-body records in FTR
      ft  - .FTR file creation
      id  - Map identifier
      la  - language
      ll  - Create Link Location Records in .NET file
      maN - Maximum area vertices number
      mb  - Combinable Map (TRE + 0x043)
      mcN - map class
      mdN - Map display priority
      mf  - Map format. 1 - old, 2 - NT
      mg  - make GMP
      mlN - Maximum line vertices number
      mo  - transparent map (TRE + 0x3f, mask 02)
      mt  - 0 - full map / 1 - partial map (TRE + 0x3f, mask 01)
      ms  - Map series id (TRE + 0x45)
      nb  - Node blocking factor
      ns  - node block size
      nt  - .NET file creation
      pf  - Point-finder records
      pp  - Postal code displayed 0 - AFTER / 1 - BEFORE city or state (TRE + 0x3f, mask 08)
      hp  - House number displayed 0 - BEFORE / 1 - AFTER street name (TRE + 0x3f, mask 04)
      pnMN
        M=1 - Export POI phone numbers to MDR
        N=0 - Create formatted phone numbers
      sp  - Single-pass line simplification
      tf  - Generate a .ITF Traffic file
      tl  - Maximum text length
      wm  - Map background is WATER (TRE + 0x3f, mask 10)


Что интересно, компилятор умеет делать 3 типа IMG - старый (не-NT), не-NTшный GMP, и честный NTшный GMP. Единственное отличие, если я правильно понимаю, заключается в столь долго не поддающейся реверсингу упаковке координат объектов в полноценном NT-формате.

Метки:

В различных частях контейнера IMG имеются блоки данных, длина которых задается одним или более байтами. Все источники информации о IMG, с которыми я до сих пор сталкивался, упоминают, что для определения количества байтов, задающих длину блока, используется младший бит первого байта - если он равен единице, то для кодирования длины используются остальные 7 битов первого байта, а данные блока начинаются со второго байта; если же младший бит равен нулю, то длина кодируется оставшимися 7 битами первого байта и вторым байтом целиком, данные же в этом случае начинаются с третьего байта.

Исследования BaseCamp показывают, что описанный выше подход - лишь частный случай. На самом деле для указания длины используется до 4 первых байтов, а то, какое количество байтов должно быть использовано, определяется по младшим 3 битам первого байта. Для упрощения объяснения постараюсь изобразить все возможные комбинации схематично:

1 случай - младший бит равен 1, для кодирования длины блока используются 7 старших битов первого байта:
    b7 b6 b5 b4 b3 0 0 | 1
    b7 b6 b5 b4 b3 0 1 | 1
    b7 b6 b5 b4 b3 1 0 | 1
    b7 b6 b5 b4 b3 1 1 | 1

2 случай - младший бит равен 0, следующий бит равен 1, для кодирования используются 6 старших битов первого байта и второй байт целиком:
    byte1  b7 b6 b5 b4 b3 0 | 1 0
    byte1  b7 b6 b5 b4 b3 1 | 1 0

3 случай - два младших бита равны 0, а следующий равен 1, длина блока задается 5 старшими битами первого байта, а также двумя следующими байтами:
    byte2 byte1  b7 b6 b5 b4 b3 | 1 0 0

4 случай - все три младших бита первого байта равны 0, в этом случае длина блока опять же задается 5 старшими битами первого байта, но к ним добавляется уже 3 следующих байта:
    byte3 byte2 byte1  b7 b6 b5 b4 b3 | 0 0 0

Для того, чтобы вычислить длину блока, можно проверить значения младших битов первого байта, а потом взять от 1 до 3 дополнительных байтов для вычисления самой длины - этот способ идеален при поточном чтении из файла.
Другой способ ("арифметический") можно использовать, если весь блок данных уже есть в памяти, и просто требуется понять, где заканчивается очередной блок:
    unsigned long GetBlockLength(const unsigned char* &BufPtr) {
      const unsigned long masks[8]   =
        { 0x1FFFFFFF, 0x7F, 0x3FFF, 0x7F, 0x1FFFFF, 0x7F, 0x3FFF, 0x7F };
      const unsigned char counts[8]  =
        {          4,    1,      2,    1,        3,    1,      2,    1 };
      const unsigned char rshifts[8] =
        {          3,    1,      2,    1,        3,    1,      2,    1 };
    
      unsigned long CurValue   = *BufPtr;
      unsigned char Lower3Bits = CurValue & 7;
    
      unsigned long BlockLength = CurValue >> rshifts[Lower3Bits];
      BlockLength &= masks[Lower3Bits];
    
      BufPtr += counts[Lower3Bits];
    
      return BlockLength;
    }

В принципе, можно обойтись и без and-масок, но по какой-то причине в BaseCamp код вычисления длины именно такой.

Метки:

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

С форматом JNX, можно считать, разобрались. Настало время поковырять формат IMG.

Изначально векторный, этот формат был некоторое время назад "прокачан" до поддержки DEM-слоев и спутниковых снимков местности в формате JPEG. В качестве примеров могу привести карты Garmin GB Discoverer (искать на файлопомойках) и свободно доступную карту острова Мэн.

Читать дальше...Свернуть )

Метки:

JNX scale values explained

Русская версия здесь.

JNX format description contains the following "standard" set of scale values, which is recommended to use in the hand-made JNX maps: 75, 149, 298, 597, 1194, 2388, 4777, 9554, 19109, 38218, 76437, 152877, 305758, 611526, 1223072, 2446184.

This set is an extension of the set used in BirdsEye subscription maps: 597, 1194, 4777 and 76437.
Still, there were no explanation of what these numbers mean.

Several days ago, I got a mail from Dmitry Sklyarov with quite logical reasoning.
Читать дальше...Свернуть )

Метки:

English version is here.

Описание формата JNX содержит следующий набор "стандартных" значений масштабов, которые рекомендуется использовать в файлах JNX: 75, 149, 298, 597, 1194, 2388, 4777, 9554, 19109, 38218, 76437, 152877, 305758, 611526, 1223072, 2446184.

Это набор представляет собой расширение набора значений, применяемых в картах подписки BirdsEye, а именно 597, 1194, 4777 и 76437.
Однако, пока не было сколько-либо внятного объяснения того, что на самом деле означают эти числа.
На днях Дмитрий Скляров прислал письмо, содержащее достаточно подробное обоснование выбора именно этих значений.
Читать дальше...Свернуть )

Метки: