Рисую току на карте (план-схема, метры). Координаты выставляю с 6-ю знаками после запятой (и даже больше, до 9). Не сохраняя карты создаю ее mid/mif копию. Смотрю mif в блокноте: координаты такие, как я создал. Сохраняю таблицу. Координаты сразу округляются до 4-х знаков. Делаю mid/mif после этого, смотрю новый mif в блокноте: координаты 4 знака.
Я бы не заморачивался этим, если бы в реальном модуле при аналогичных процедурах, но более запутанных, когда в таблицу вставляются объекты, таблица сохраняется, а затем из нее вытаскиваются записи в другую, а там оказываются только два знака после запятой. А вот этого уже недостаточно.
Как это объяснить и можно ли побороть? Значение точности отображения в настройках карты никакого влияния не оказывает.
P.S. Аксиома версии 5.2, Widows 10.
Уменьшение точности координат при сохранении
Re: Уменьшение точности координат при сохранении
Заранее извиняюсь, если мой ответ не верный.
Насколько я помню, MapInfo хранит координаты объектов в файле MAP в виде целых чисел.
Для приведения их в вещественные координаты, в драйвере OGR используется функция Int2Coord https://github.com/OSGeo/gdal/blob/mast ... .cpp#L1042
TABMAPFile::Int2Coordsys() https://github.com/OSGeo/gdal/blob/mast ... e.cpp#L886
Если я не ошибаюсь (сейчас не могу найти), для приведения из целых чисел, в которых хранятся координаты, в вещественные числа, используемые для отображения на карте, используется экстент таблицы(слоя).
В файле MIF вы можете это видеть в строке описания системы координат в виде " Bounds (-20000000, -20000000) (20000000, 20000000)".
Для увеличения точности вещественных координат попробуйте уменьшить размер экстента используемой таблицы. Например в файле MIF замените на Bounds "(-50000, -50000) (50000, 50000)" и импортируйте заново таблицу для использования.
Насколько я помню, MapInfo хранит координаты объектов в файле MAP в виде целых чисел.
Для приведения их в вещественные координаты, в драйвере OGR используется функция Int2Coord https://github.com/OSGeo/gdal/blob/mast ... .cpp#L1042
TABMAPFile::Int2Coordsys() https://github.com/OSGeo/gdal/blob/mast ... e.cpp#L886
Если я не ошибаюсь (сейчас не могу найти), для приведения из целых чисел, в которых хранятся координаты, в вещественные числа, используемые для отображения на карте, используется экстент таблицы(слоя).
В файле MIF вы можете это видеть в строке описания системы координат в виде " Bounds (-20000000, -20000000) (20000000, 20000000)".
Для увеличения точности вещественных координат попробуйте уменьшить размер экстента используемой таблицы. Например в файле MIF замените на Bounds "(-50000, -50000) (50000, 50000)" и импортируйте заново таблицу для использования.
Re: Уменьшение точности координат при сохранении
Увы, у меня и так Bounds (-100000, -100000) (100000, 100000). В MapInfo точность сохраняется, по крайней мере, необходимые мне 3 знака после запятой.
Re: Уменьшение точности координат при сохранении
В OGR нашел функцию, которая пересчитывает координаты при чтении: https://github.com/OSGeo/gdal/blob/mast ... k.cpp#L360.
При перерасчете координаты Х используются переменные m_XDispl, m_XScale, m_nCoordOriginQuadrant
if (m_nCoordOriginQuadrant == 2 || m_nCoordOriginQuadrant == 3 ||
m_nCoordOriginQuadrant == 0)
dX = -1.0 * (nX + m_XDispl) / m_XScale;
else
dX = (nX - m_XDispl) / m_XScale;
а затем данные округляются с использованием переменной m_XPrecision
// Round coordinates to the desired precision
if (m_XPrecision > 0 && m_YPrecision > 0)
{
dX = round(dX * m_XPrecision) / m_XPrecision;
dY = round(dY * m_YPrecision) / m_YPrecision;
}
Переменная m_XPrecision рассчитывается на основании переменной m_XScale в функции UpdatePrecision()
https://github.com/OSGeo/gdal/blob/mast ... k.cpp#L915
При использовании версии файла мапинфо ниже 10 m_XScale расчитывается на основании переменной m_nCoordPrecision (для версии файла ниже 100) , которая хранится в файле в виде байта по смещению 0х161 https://github.com/OSGeo/gdal/blob/mast ... k.cpp#L249
Если вы импортируете MIF в Axioma или MapInfo
Version 300
Charset "WindowsCyrillic"
Delimiter ","
CoordSys NonEarth Units "m" Bounds (81000, 130000) (82000, 131000)
Columns 1
ID Integer
Data
Point 81650.005050505 130850.123456789
Symbol (36,0,12,"Map Symbols",0,0)
и пересохраните его в другой MIF, то получите округление координат
Version 300
Charset "WindowsCyrillic"
Delimiter ","
CoordSys NonEarth Units "m" Bounds (81000, 130000) (82000, 131000)
Columns 1
ID Integer
Data
Point 81650.0050505 130850.123457
Symbol (36,0,12,"Map Symbols",0,0)
Если в исходном файле поменяете на Bounds (0, 0) (200000, 200000) и проделаете операцию импорта - экспорта, получите такой MIF
Version 300
Charset "WindowsCyrillic"
Delimiter ","
CoordSys NonEarth Units "m" Bounds (0, 0) (200000, 200000)
Columns 1
ID Integer
Data
Point 81650.0051 130850.1235
Symbol (36,0,12,"Map Symbols",0,0)
Проверьте пожалуйста экстент второй вашей таблицы и уменьшите его по возможности.
При перерасчете координаты Х используются переменные m_XDispl, m_XScale, m_nCoordOriginQuadrant
if (m_nCoordOriginQuadrant == 2 || m_nCoordOriginQuadrant == 3 ||
m_nCoordOriginQuadrant == 0)
dX = -1.0 * (nX + m_XDispl) / m_XScale;
else
dX = (nX - m_XDispl) / m_XScale;
а затем данные округляются с использованием переменной m_XPrecision
// Round coordinates to the desired precision
if (m_XPrecision > 0 && m_YPrecision > 0)
{
dX = round(dX * m_XPrecision) / m_XPrecision;
dY = round(dY * m_YPrecision) / m_YPrecision;
}
Переменная m_XPrecision рассчитывается на основании переменной m_XScale в функции UpdatePrecision()
https://github.com/OSGeo/gdal/blob/mast ... k.cpp#L915
При использовании версии файла мапинфо ниже 10 m_XScale расчитывается на основании переменной m_nCoordPrecision (для версии файла ниже 100) , которая хранится в файле в виде байта по смещению 0х161 https://github.com/OSGeo/gdal/blob/mast ... k.cpp#L249
Если вы импортируете MIF в Axioma или MapInfo
Version 300
Charset "WindowsCyrillic"
Delimiter ","
CoordSys NonEarth Units "m" Bounds (81000, 130000) (82000, 131000)
Columns 1
ID Integer
Data
Point 81650.005050505 130850.123456789
Symbol (36,0,12,"Map Symbols",0,0)
и пересохраните его в другой MIF, то получите округление координат
Version 300
Charset "WindowsCyrillic"
Delimiter ","
CoordSys NonEarth Units "m" Bounds (81000, 130000) (82000, 131000)
Columns 1
ID Integer
Data
Point 81650.0050505 130850.123457
Symbol (36,0,12,"Map Symbols",0,0)
Если в исходном файле поменяете на Bounds (0, 0) (200000, 200000) и проделаете операцию импорта - экспорта, получите такой MIF
Version 300
Charset "WindowsCyrillic"
Delimiter ","
CoordSys NonEarth Units "m" Bounds (0, 0) (200000, 200000)
Columns 1
ID Integer
Data
Point 81650.0051 130850.1235
Symbol (36,0,12,"Map Symbols",0,0)
Проверьте пожалуйста экстент второй вашей таблицы и уменьшите его по возможности.
Re: Уменьшение точности координат при сохранении
Похоже, Вы правы. Я вставляю объект в таблицу, которую создаю с указанием системы координат, но не указав Rect охвата. А по умолчанию он, очевидно, берется максимально возможный. Отсюда и обрезание точности.
Это рассуждения, проверить до понедельника не смогу. Проверю - отпишусь.
В любом случае спасибо за участие и помощь!
Это рассуждения, проверить до понедельника не смогу. Проверю - отпишусь.
В любом случае спасибо за участие и помощь!
Re: Уменьшение точности координат при сохранении
Да, как правильно отметил Mitrich, в формате TAB (в файле *.map) координаты хранятся в виде целых чисел.
Каждой системе координат присваивается охват для сохранения в TAB-формате, и точность по X может отличаться от точности по Y.
Для вычисления точности записи координат необходимо взять длину охвата системы координат и разделить её на 2 миллиарда (2 000 000 000).
Дополнительную информацию можно найти здесь: https://mapinfo.ru/article/mapinfo_precision
Разберем ваш случай:
Относительно выбора охвата можно дать несколько рекомендаций:
1) Длина охвата по X должна быть равна длине охвата по Y.
2) Минимум и максимум охвата по X и Y не обязательно должны быть одинаковыми.
3) Избегайте установки длины охвата так, чтобы коэффициент перед степенью 10 был дробным числом.
4) Лучше всего, если коэффициент перед степенью 10 у длины охвата будет равен 2 (двум): 200 000 000; 2 000 000; 20 000 и т.д. Тогда коэффициент перед степенью 10 у точности будет 1, например: 0,1; 0,001; 0,00001.
5) Длина охвата должна быть 2×(10 в степени a) для точности 1×(10 в степени a-9). Если длина диапазона равна 1×(10 в степени a), то точность будет 5×(10 в степени a-10).
Пример охвата:
(500000; 200000) (700000; 400000)
Точность охвата:
X: (700000 - 500000) / 2000000000 = 0,0001
Y: (400000 - 200000) / 2000000000 = 0,0001
Каждой системе координат присваивается охват для сохранения в TAB-формате, и точность по X может отличаться от точности по Y.
Для вычисления точности записи координат необходимо взять длину охвата системы координат и разделить её на 2 миллиарда (2 000 000 000).
Дополнительную информацию можно найти здесь: https://mapinfo.ru/article/mapinfo_precision
Разберем ваш случай:
Формат mif/mid не имеет ограничений на точность координат, поэтому координаты не округляются.
При вашем охвате [-100 000; 100 000] точность составляет (100000 - (-100000)) / 2000000000 = 0,0001. При сохранении координаты округляются до этого значения.Сохраняю таблицу. Координаты сразу округляются до 4-х знаков.
Координаты уже округлены при сохранении, поэтому в mif/mid записываются округленные координаты.Делаю mid/mif после этого, смотрю новый mif в блокноте: координаты 4 знака.
Для точного ответа на проблему нужно изучить процесс более подробно. Однако вероятно, проблема связана с точностью хранения координат в TAB-формате.Я бы не заморачивался этим, если бы в реальном модуле при аналогичных процедурах, но более запутанных, когда в таблицу вставляются объекты, таблица сохраняется, а затем из нее вытаскиваются записи в другую, а там оказываются только два знака после запятой. А вот этого уже недостаточно.
Как это объяснить и можно ли побороть?
Да, это значение отображает только точность отображения.Значение точности отображения в настройках карты никакого влияния не оказывает.
Относительно выбора охвата можно дать несколько рекомендаций:
1) Длина охвата по X должна быть равна длине охвата по Y.
2) Минимум и максимум охвата по X и Y не обязательно должны быть одинаковыми.
3) Избегайте установки длины охвата так, чтобы коэффициент перед степенью 10 был дробным числом.
4) Лучше всего, если коэффициент перед степенью 10 у длины охвата будет равен 2 (двум): 200 000 000; 2 000 000; 20 000 и т.д. Тогда коэффициент перед степенью 10 у точности будет 1, например: 0,1; 0,001; 0,00001.
5) Длина охвата должна быть 2×(10 в степени a) для точности 1×(10 в степени a-9). Если длина диапазона равна 1×(10 в степени a), то точность будет 5×(10 в степени a-10).
Пример охвата:
(500000; 200000) (700000; 400000)
Точность охвата:
X: (700000 - 500000) / 2000000000 = 0,0001
Y: (400000 - 200000) / 2000000000 = 0,0001
Re: Уменьшение точности координат при сохранении
Все верно, учел охват и нужный результат удовлетворяет. Ошибка моя в том, что при создании временной таблицы я не задал Bounds в системе координат. В результате охват в ней был максимальный и записываемые в нее координаты потеряли в точности.
Спасибо Mitrich и Александру за помощь!
Спасибо Mitrich и Александру за помощь!