Re: Как написать каpту?

From
Kirill Volkov (2:5024/15.50)
To
Andrey Ilyin
Date
2002-06-24T22:23:53Z
Area
RU.ALGORITHMS
Числа 24 Jun 02  10:40:05 писал Andrey Ilyin к All  по теме Re: Как написать каpту?.
Здравствуй, Andrey Ilyin !

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

AI> а почему бы не воспользоваться готовым? имеется достаточно много движков
AI> GIS в исходниках, к пpимеpу на SourceForge.net. а если все-таки pешил
AI> написать это сам, то сходу могу пpедложить два pешения: в качестве баз
AI> объекты у тебя будут такие: точечные, полилинии, полигоны. естественно в
AI> вектоpном исполнении.

Сразу всю информацию разбил на три части:
- векторная графика - те самые полигоны.
- текстовая информация на карте.
- прочая информация из БД.

Сразу отмечу, что я имею болезненную склонность к ассемблеру, поэтому предлагаемые решения продумывались именно под эту вещь. Все данные для каждого обекта располагал в памяти последовательно. Формат данных для каждого объека:
- номер, чтобы связать обект с информацией в БД (например, число жителей в доме) и с текстовыми надписями.
- номер слоя. Используется как для собственно дифференциации слоев на дороги, парки, реки и т.п., так и для определения, в каком масштабе будет виден объект. Т.е., например, с 1-10 - улицы, 11-20 - парки, 21-30 - вода, а разряд единиц указывает, начиная с какого масштаба объект виден.
- Цвет. Не обязательно, можно использовать общие настройки для слоя
- координаты прямоугольника, в который вписан объект. Позволяет быстро определить, нужно ли его отрисовывать на экране, или нет -  не надо искать пересечения для каждого ребра полигона с прямоугольником экрана.
- координаты точек, сначала, координата точки по X, потом координата по Y
- точка с координатами (0,0) как признак того, что объект закончился и начинается следующий объект.

Относительно текстовых надписей не все так гладко, но все же:
- Номер
- Номер слоя
- Координаты прямоугольника, в которй вписана надпись
- Размер шрифта
- Угол наклона надписи
- Цвет. Не обязательно
- Текст надписи
- 00h как признак того, что что объект закончился и начинается следубщий объект

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

База данных.
- Номер
- ВСЕ_ЧТО_ДУШЕ_УГОДНО

Теперь умазаключения и прстранные размышления :)
Все полигоны считаем залитыми. Однако никто не мешает ввести цвет "прозрачный". 
Я рисовал стандартными дельфовыми процедурами на канве объекта TImage - сам понимаешь, глубокий изврат, и для реальных целий можно было бы использовать хотя бы средства DirectX - меньше тормозов, перемаргиваний и глюков.
Т.к. использовал стандартные процедуры, то если прямоугольник, в который входил полигон, пересекался с прямоугольником экрана и масштаб удовлтворял условиям для данного объекта, то полигон рисовался целиком в надежде на то, что умная стандартная процедура рисования полигонов сама лишнее отрежет. Иногда это было не так.
Желательно отсортировать объекты по слоям, чтобы сначала рисовать реки и поверх них - мосты, а не наоборот.
Да, чуть не забыл - все рассуждения ведутся не для исходного массива данных, а для уже сформатированного. Т.е. Каждая координата для каждой точки бережно делилась на коэффициент пропорциональности (выбранный масштаб) и сохранялась в новое место, где ее и использовали для работы в программе. Но можно и пойти другим путем, динамически вычисляя координаты. Но это - лишние тормоза. Масштаб человек сменит один раз, и вот влево-вправо по карте продвинется с десяток раз, так что легче перемасштабировать все и сразу. Не забыв при этом в новый массив данных не включать неотображаемые объекты для данного масштаба.

Теперь о реализации. Если использовать для каждый координаты 2 байта, то квадрат 65535 х 65535 м можно закартографировать с точностью до метра. Я живу во Владимире, и мне этого вполне достаточно. Для области или крупных городов можно либо смириться с потерей точности, либо использовать 4 байта на координату.

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

Так что всем твоим требованиям в принципе удовлетворяет.
Еще о вводе информации. Сканируется карта. Задается начальные координаты отсканированного прямоугольника в координатах нашей программы. И далее мышкой каждый объект "обкликивыается" (получаем координаты), затем вводится его номер, слой и т.д.
После этого информация со всех отсканированных и "обкликанных" частей объединяется и сортируется. С текстом сложнее, но тоже рашаемо в этой же манере.

Всего наилучшего, Волков Кирилл, Россия, Владимир.
Mailto: VolkovK@chat.ru     форвардинг в ФИДО
        KAVolkov@Mail.ru    InterNet
--- FIPS/2000
 * Origin: Это вы научили меня выживать... (2:5024/15.50)