Как лучше всего читать, представлять и отображать данные карты? - PullRequest
12 голосов
/ 21 октября 2008

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

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

Как я должен:

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

Как лучше всего отобразить карту после прочтения данных в Shapefile?

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

Как мне:

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

Ex. данных TIGER, отображаемых как карта отображения:
alt text

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

РЕДАКТИРОВАТЬ: Чтобы уточнить, я не хочу использовать API карт Google или Yahoo. Точно так же я не хочу использовать OpenStreetMap. Я ищу более подход с нуля, чем использование этих API / программ. Это будет приложение desktop .

Ответы [ 11 ]

24 голосов
/ 28 января 2009

Во-первых, я рекомендую использовать файлы 2008 TIGER .

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

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

1010 * Синтаксический *

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

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

Rendering

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

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

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

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

Хранение и конструкции

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

Использование почтовых индексов и загрузка только ближайших почтовых индексов работает для небольших проектов рендеринга карт, но если вам нужен маршрут по всей стране, вам нужна другая структура. У некоторых реализаций есть базы данных «наложения», которые содержат только основные дороги и привязывают маршруты к наложению (или через несколько наложений - местный, метро, ​​округ, штат, страна). Это приводит к быстрой, но иногда неэффективной маршрутизации.

Черепица

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-Adam

14 голосов
/ 21 октября 2008

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

7 голосов
/ 27 января 2009

решение:

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

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

  • картографическая библиотека javascript, такая как openlayers (см. Примеры в текст ссылки

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

5 голосов
/ 30 января 2009

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

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

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

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

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

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

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

2 голосов
/ 29 января 2009

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

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

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

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

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

2 голосов
/ 28 января 2009

для локального хранения данных тигра, я бы выбрал Postgresql с инструментами postgis .

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

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

из http://postgis.refractions.net/documentation/:

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

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

1 голос
/ 29 января 2009

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

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

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

1 голос
/ 28 января 2009

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

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

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

1 голос
/ 25 октября 2008

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

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

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

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

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

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

1 голос
/ 21 октября 2008

Вы также можете работать с приложением Microsoft для визуального отображения Земли и API или использовать API Google. Я всегда программировал коммерчески с продуктами ESRI и не слишком много играл с открытыми API.

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

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

...