Каков наилучший способ чтения, представления и рендеринга картографических данных?

StackOverflow https://stackoverflow.com/questions/222716

Вопрос

Я заинтересован в написании упрощенного навигационного приложения в качестве домашнего проекта.После поиска бесплатных картографических данных я остановился на ТИГР Бюро переписи населения США 2007 Данные карты строк / шейп-файлов.Данные разделены на zip-файлы для отдельных округов, и я загрузил единую карту округов-данные для моего региона.

Каков был бы наилучший способ перевести эти картографические данные в удобный формат?

Как я должен:

  • Прочтите в этих файлах
  • Разбирать их - регулярное выражение или какая-то библиотека, которая уже может разбирать эти шейп-файлы?
  • Загрузите данные в мое приложение - должен ли я загружать точки непосредственно в какую-либо структуру данных в памяти?Использовать небольшую базу данных?У меня нет необходимости в постоянстве, как только вы закроете приложение с картографическими данными.Пользователь может снова загрузить шейп-файл.

Каков был бы наилучший способ визуализации карты после того, как я прочитал данные из шейп-файла?

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

Как я должен:

  • Преобразовать точки широты / lon в экранные координаты?- Насколько я знаю, шейп-файл использует долготу и широту для своих точек.Поэтому, очевидно, мне придется каким-то образом преобразовать их в экранные координаты, чтобы отобразить объекты карты.
  • Визуализировать данные карты (серию полилиний для дорог, границ и т.д.) Таким образом, чтобы я мог легко поворачивать и масштабировать всю карту?
  • Визуализировать всю мою карту в виде серии "плиток", чтобы отображались только объекты / линии в области просмотра?

Бывший.данных TIGER, отображаемых в виде отображаемой карты:
alt text

Любой, у кого есть некоторый опыт и понимание того, как мне лучше всего читать в этих файлах, как я должен представлять их (база данных, структура данных в памяти) в моей программе и как я должен отображать (с поворотом / масштабированием) картографические данные на экране, был бы признателен.

Редактировать:Чтобы уточнить, я не хочу использовать какие-либо Google или Yahoo maps API.Точно так же я не хочу использовать OpenStreetMap.Я ищу подход "с нуля", чем использование этих API / программ.Это будет Для рабочего стола применение.

Это было полезно?

Решение

Во-первых, я рекомендую вам использовать Файлы ТИГРА 2008 года.

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

Если вы хотите начать с более низкого уровня

Синтаксический анализ

Создать свой собственный анализатор TIGER (достаточно просто - всего лишь база данных линейных сегментов) и создать поверх этого простой рендеринг (линии, полигоны, буквы / имена) также будет довольно просто.Вам захочется взглянуть на различные типы картографических проекций для фазы рендеринга.Наиболее часто используемым (и, следовательно, наиболее знакомым пользователям) является Проекция Меркатора - это довольно просто и быстро.Возможно, вы захотите поиграть с поддержкой других проекций.

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

Рендеринг

Когда я разрабатывал свой рендерер, я решил использовать фиксированный размер окна (встроенное устройство) и фиксированное увеличение.Это означало, что я мог центрировать карту по широте / lon, и с помощью центрального пикселя = center lat / lon при заданном увеличении, и с учетом проекции меркатора я мог вычислить, какой пиксель представляет каждую широту / lon, и наоборот.

Вместо этого некоторые программы позволяют изменять размер окна, и вместо использования увеличения и фиксированной точки они используют две фиксированные точки (часто верхний левый и нижний правый углы прямоугольника, определяющего окно).В этом случае становится тривиальным определить перенос пикселя в широту / lon - это всего лишь несколько вычислений интерполяции.Поворот и масштабирование делают эту передаточную функцию немного более сложной, но не должны быть настолько значительными - это все еще прямоугольное окно с интерполяцией, но углы окна не обязательно должны находиться в какой-либо определенной ориентации относительно севера.Это добавляет несколько дополнительных моментов (например, вы можете вывернуть карту наизнанку и просматривать ее как бы изнутри земли), но они не являются обременительными и могут быть устранены по мере работы над ней.

Как только вы закончите перенос широты / долготы в пиксель, рендеринг линий и полигонов станет довольно простым, за исключением обычных графических проблем (таких как неправильное перекрытие краев линий или полигонов, сглаживание и т.д.).Но рендеринг базовой уродливой карты, такой, как это делают многие программы рендеринга с открытым исходным кодом, довольно прост.

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

Хранилища и сооружения

Однако то, как вы храните данные и обращаетесь к ним, во многом зависит от того, что вы планируете с ними делать.Множество сложных проблем возникает, если вы хотите использовать одну и ту же структуру базы данных для демографии и маршрутизации - данная структура базы данных и индексация будут быстрыми для одного и медленными для другого.

Использование почтовых индексов и загрузка только близлежащих почтовых индексов работает для небольших проектов рендеринга карт, но если вам нужен маршрут через всю страну, вам нужна другая структура.Некоторые реализации имеют базы данных "overlay", которые содержат только основные дороги и привязывают маршруты к оверлею (или через несколько оверлеев - local, metro, county, state, country).Это приводит к быстрой, но иногда неэффективной маршрутизации.

Облицовка плиткой

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

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

Вы поймете, о чем я говорю, когда будете работать над этой проблемой.

Найти данные, которые также входят в данный фрагмент, нетривиально - линия может иметь оба конца за пределами данного фрагмента, но проходить по нему.Вам нужно будет проконсультироваться по этому поводу с графическими книгами (Книга Майкла Абраша - это основополагающий справочник, свободно доступен сейчас по предыдущей ссылке).Хотя в нем говорится в основном об играх, здесь применимы оконные настройки, обрезка, края полигонов, столкновения и т.д.

Однако, возможно, вы захотите играть на более высоком уровне.

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

Обратное геокодирование достаточно просто. Введите широту / lon (или щелкните по карте) и получите ближайший адрес.Это научит вас, как интерпретировать адреса вдоль линейных сегментов в данных TIGER.

Базовое геокодирование - сложная проблема. Написание анализатора адресов - полезный и интересный проект, а затем преобразование его в широту / lon с использованием данных TIGER нетривиально, но очень весело.Начните с простого и небольшого, требуя точного соответствия имени и формату, а затем начните изучать соответствие "нравится" и фонетическое соответствие.В этой области проводится много исследований - посмотрите на проекты поисковых систем, чтобы получить некоторую помощь здесь.

Нахождение кратчайшего пути между двумя точками - нетривиальная задача. Существует много-много алгоритмов для этого, большинство из которых запатентованы.Я рекомендую, если вы попробуете это, использовать простой алгоритм вашей собственной разработки, а затем провести некоторое исследование и сравнить свой дизайн с самым современным.Это очень весело, если вы увлекаетесь теорией графов.

Следуя по пути и упреждающе давая инструкции это не так просто, как кажется на первый взгляд.Получив набор инструкций с соответствующим массивом пар широты / lon, "следуйте" маршруту, используя внешний ввод (GPS или имитацию GPS), и разработайте алгоритм, который выдает инструкции пользователю по мере приближения к каждому реальному перекрестку.Обратите внимание, что пар широта / долгота больше, чем инструкций из-за извилистых дорог и т.д., И вам нужно будет определить направление движения и так далее.Множество угловых случаев, которые вы не увидите, пока не попытаетесь это реализовать.

Поиск интересных мест. Этот вариант интересен - вам нужно найти текущее местоположение и все достопримечательности (не являющиеся частью TIGER, создайте свои собственные или найдите другой источник) в пределах определенного расстояния (по прямой или на более труднодоступной дороге) от источника.Этот вариант интересен тем, что вам нужно преобразовать базу данных POI в формат, удобный для поиска в данных обстоятельствах.Вы не можете тратить время на просмотр миллионов записей, вычисление расстояния (sqrt(x ^ 2 + y ^ 2)) и возврат результатов.Сначала у вас должен быть какой-то метод или алгоритм, чтобы сократить объем данных.

Коммивояжер. Маршрутизация с несколькими пунктами назначения.Просто более сложная версия обычной маршрутизации.

Вы можете найти ряд ссылок на многие проекты и источники информации по этому вопросу здесь.

Удачи, и, пожалуйста, публикуйте все, что вы делаете, независимо от того, насколько вы примитивны или уродливы, чтобы другие могли извлечь пользу!

-Адам

Другие советы

Четкая карта является механизмом сопоставления .NET 2.0 с открытым исходным кодом для WinForms и ASP.NET .Это может обеспечить всю необходимую вам функциональность.Он имеет дело с наиболее распространенными форматами векторных и растровых данных ГИС, включая шейп-файлы ESRI.

решение заключается в :

  • геопространственный сервер, такой как mapserver, geoserver, degree (с открытым исходным кодом).

Они могут читать шейп-файлы и обслуживать их (и многое другое).Например, geoserver (при установке) предоставляет данные из шейп-файлов TIGER Бюро переписи населения США в качестве демонстрационных

  • картографическая библиотека javascript, подобная openlayers (смотрите примеры на текст ссылки

В Интернете есть множество примеров использования этого решения

Забавный вопрос.Вот как я это делаю.

Я собираю любую геометрию, которая мне нужна, в любых форматах, в которых они представлены.Я извлекал данные из USGS, так что это составляет кучу:

Затем я написал программу, которая "компилирует" эти определения фигур в форму, эффективную для рендеринга.Это означает выполнение любых прогнозов и преобразований формата данных, которые необходимы для эффективного отображения данных.Некоторые детали:

  • Для 2D-приложения вы можете использовать любую проекцию, какую захотите: Картографические Проекции.
  • Для 3D вы хотите преобразовать эти широты / долготы в 3D-координаты.Вот некоторая математика о том, как это сделать: преобразование из сферических координат в обычные прямоугольные координаты.
  • Разбейте все примитивы на quadtree / octree (2D / 3D).Конечные узлы в этом дереве содержат ссылки на всю геометрию, которая пересекает ограничивающую рамку этого конечного узла (выровненную по оси).(Это означает, что на элемент геометрии можно ссылаться более одного раза.)
  • Затем геометрия разбивается на таблицу вершин и таблицу команд рисования.Это идеальный формат для OpenGL.Команды могут быть выданы через глДравАррайс использование вершинных буферов (Объекты вершинного Буфера).
  • Общий шаблон посещения используется для обхода квадратичного / восьмиугольника.Прохождение включает в себя проверку того, пересекает ли посетитель заданные узлы дерева, пока не встретится конечный узел.Посетители включают в себя:рисование, обнаружение столкновений и выбор.(Поскольку листья дерева могут содержать повторяющиеся ссылки на геометрию, ходок помечает узлы как посещаемые и впоследствии игнорирует их.Эти метки должны быть сброшены или иным образом обновлены перед выполнением следующего обхода.)
  • Использование системы пространственного разбиения (одного из деревьев) и представления, эффективного для рисования, имеет решающее значение для достижения высокой частоты кадров.Я обнаружил, что в приложениях такого типа требуется, чтобы частота кадров была как можно выше, как минимум 20 кадров в секунду.Не говоря уже о том факте, что высокая производительность даст вам массу возможностей для создания более привлекательной карты.(Мой далеко не красавец, но когда-нибудь доберется и до этого.)
  • Пространственное разделение повышает производительность рендеринга за счет уменьшения количества команд рисования, отправляемых в процессор.Однако может наступить момент, когда пользователь действительно захочет просмотреть весь набор данных (возможно, arial view).В этом случае вам необходим уровень детализации системы управления.Поскольку мое приложение имеет дело с улицами, я отдаю приоритет автомагистралям и более крупным дорогам.Мой код рисования знает о том, сколько примитивов я могу нарисовать, прежде чем моя частота кадров снизится.Примитивы также сортируются по этому приоритету.Я рисую только первый x предметы, в которых x это количество примитивов, которые я могу нарисовать при желаемой частоте кадров.

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

Вот несколько примеров моей существующей реализации:

Изображение http://seabusmap.com/assets/Picture%205.png Изображение http://seabusmap.com/assets/Picture%207.png

для локального хранения данных tiger я бы выбрал Postgresql с помощью postgis ( постгис ) Инструменты.

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

вам нужно будет взглянуть на инструменты, которые взаимодействуют с postgis, скорее всего, какой-то картографический сервер

От http://postgis.refractions.net/documentation/:

В настоящее время существует несколько инструментов с открытым исходным кодом, которые работают с PostGIS.Проект uDig работает над полноценной средой чтения / записи на рабочем столе, которая может напрямую работать с PostGIS.Для интернет-картографирования картографический сервер Университета Миннесоты может использовать PostGIS в качестве источника данных.GeoTools Java GIS toolkit поддерживает PostGIS, как и сервер веб-функций GeoServer.GRASS поддерживает PostGIS в качестве источника данных.JUMP Java desktop GIS viewer имеет простой плагин для чтения данных PostGIS, а QGIS desktop имеет хорошую поддержку PostGIS.Данные PostGIS могут быть экспортированы в несколько выходных форматов ГИС с помощью библиотеки OGR C ++ и инструментов командной строки (и, конечно, с помощью входящего в комплект Shape file dumper).И, конечно, любой язык, который может работать с PostgreSQL, может работать с PostGIS - список включает Perl, PHP, Python, TCL, C, C ++, Java, C # и другие.

Редактировать:поскольку mapserver имеет в своем названии слово SERVER, его можно будет использовать в среде рабочего стола.

Хотя вы уже решили использовать данные TIGER, вас могут заинтересовать OSM (Открыть карту улиц), поскольку OSM имеет полный импорт данных TIGER в нем, обогащенный пользовательскими данными.Если вы будете придерживаться формата TIGER, ваше приложение будет бесполезно для международных пользователей, с OSM вы получаете TIGER и все остальное сразу.

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

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

Там также есть Служба маршрутизации OSM доступный.Он имеет веб-интерфейс и также может запрашиваться через API веб-сервиса.Опять же, это еще не все закончено.Пользователи определенно могли бы использовать настольное или мобильное приложение маршрутизации, созданное поверх этого.

Даже если вы не решите взяться за этот проект, вы можете почерпнуть из него массу вдохновения.Просто взгляните на вики проекта и на исходные тексты различных программных проектов, которые задействованы (вы найдете ссылки на них внутри wiki).

Вы также можете работать с приложением visual earth mapping от Microsoft и API или использовать API Google.Я всегда программировал на коммерческой основе с помощью продуктов ESRI и не так уж много играл с открытым API.

Кроме того, возможно, вы захотите взглянуть на Maker!и Искатель!Это относительно новые программы, но я думаю, что они бесплатны.Может быть ограничено встраивание данных.Создатель можно найти здесь.

Проблема в том, что пространственная обработка является довольно новым явлением в некоммерческом масштабе.

Если вы не возражаете заплатить за решение Безопасное программное обеспечение производит продукт под названием FME.Этот инструмент поможет вам перевести данные из любого формата практически в любой другой.Включая KML в формат Google Планета Земля или визуализируя его в формате JPEG (или серии JPEG-файлов).После преобразования данных вы можете встроить Google Планета Земля в свое приложение, используя их API или просто отобразите изображения, выложенные плиткой.

Кроме того, FME - это очень мощная платформа, поэтому при выполнении ваших переводов вы можете добавлять или удалять части данных, которые вам не обязательно нужны.Объедините источники, если у вас их несколько.Преобразуйте координаты (я не помню, что именно использует Google Планета Земля).Храните резервные копии в базе данных.Но серьезно, если вы готовы выложить несколько долларов, вам следует присмотреться к этому.

Вы также можете создавать флаги (очень похожие на ваш образец карты), которые содержат местоположение (куда его поместить) и другие данные / комментарии о местоположении.Эти флаги бывают разных форм и размеров.

Одно из упрощений по сравнению с Меркатором или другой проекцией заключается в предположении постоянного коэффициента преобразования широты и долготы.Умножьте градусы широты на 69,172 мили;для определения долготы выберите среднюю широту области вашей карты и умножьте (180-долгота) на косинус (middle_legatity)*69.172.После преобразования в мили вы можете использовать другой набор преобразований, чтобы перейти к экранным координатам.

Это то, что сработало у меня еще в 1979 году.

Мой источник для определения количества миль на градус.

Когда я давал этот ответ, вопрос был помечен как

"Каков был бы наилучший способ визуализации шейп-файла (картографических данных) с полилиниями в .Net?"

Теперь это другой вопрос, но я оставляю свой ответ на первоначальный вопрос.

Я написал версию .net, которая могла бы рисовать векторные данные (например, геометрию из shp-файла), используя обычный GDI + на c #.Это было довольно весело.

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

Главное при этом - создать окно просмотра и перевести / преобразовать координаты WGIS84 к уменьшенному масштабу и GDI + x, y координаты и подождите с проекцией если вам вообще нужно перепроектировать.

Одним из решений является использование MapXtreme.У них есть API для Java и C #.API способен загружать эти файлы и отображать их.

Для Java:

http://www.mapinfo.com/products/developer-tools/desktop%2c-mobile-%26-internet-offering/mapxtreme-java

Для .NET:

http://www.mapinfo.com/products/developer-tools/desktop%2c-mobile-%26-internet-offering/mapxtreme-2008

Я использовал это решение в настольном приложении, и оно хорошо сработало.Он предлагает намного больше, чем просто визуализация информации.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top