Пример создания базы данных GPS-измерений: различия между версиями

Материал из GIS-Lab
Перейти к навигации Перейти к поиску
Нет описания правки
 
(не показаны 3 промежуточные версии этого же участника)
Строка 13: Строка 13:
:*собственное  расширение (<extensions>)
:*собственное  расширение (<extensions>)
:*дата  и  время  для  waypoints  пишется  как  текст  в  элементы  <cmt>  и  <desc>
:*дата  и  время  для  waypoints  пишется  как  текст  в  элементы  <cmt>  и  <desc>
<br />
Дамп БД:[[Файл:Gpx db 20130407 2315.zip|Дамп БД]]
Дамп БД:[[Файл:Gpx db 20130407 2315.zip|Дамп БД]]
{{Скрытый
{{Скрытый
Строка 36: Строка 35:
   </wpt>
   </wpt>
</syntaxhighlight>}}
</syntaxhighlight>}}
:В  данном  случае  меня  интересовали: геометрия (lat, lon), имя  (name), высота (ele), дата/время (cmt), символ(sym). Содержание  <desc>  дублирует  <cmt>, с  точки  зрения  MapSource: <cmt> - время, <desc> - комментарий  к  точке, <extensions>  влияет  только  на  отображение  точки  в  MapSource. Символ  <sym>  записывается  как  string, лучше  вынести  в  отдельную  таблицу.
В  данном  случае  меня  интересовали: геометрия (lat, lon), имя  (name), высота (ele), дата/время (cmt), символ(sym). Содержание  <desc>  дублирует  <cmt>, с  точки  зрения  MapSource: <cmt> - время, <desc> - комментарий  к  точке, <extensions>  влияет  только  на  отображение  точки  в  MapSource. Символ  <sym>  записывается  как  string, лучше  вынести  в  отдельную  таблицу.
 
{{Скрытый
{{Скрытый
|Рамка = 1px dashed #aa0000
|Рамка = 1px dashed #aa0000
Строка 55: Строка 53:
   PRIMARY KEY  (`id`))
   PRIMARY KEY  (`id`))
</syntaxhighlight>
</syntaxhighlight>
<br />
<syntaxhighlight lang="SQL">
<syntaxhighlight lang="SQL">
CREATE TABLE `symtbl` (
CREATE TABLE `symtbl` (
Строка 61: Строка 58:
   `desc` varchar(45) NOT NULL,
   `desc` varchar(45) NOT NULL,
   PRIMARY KEY  (`id`))
   PRIMARY KEY  (`id`))
</syntaxhighlight>
</syntaxhighlight>}}
<br />}}
{{Скрытый
{{Скрытый
|Рамка = 1px dashed #aa0000
|Рамка = 1px dashed #aa0000
Строка 86: Строка 82:
   </trk>
   </trk>
</syntaxhighlight>}}
</syntaxhighlight>}}
<br />
Трек  имеет  только  имя  и  множество  точек, тип  которых – wptType, но  с  более  аскетичным  содержанием. Здесь  надо  заметить, что  элемент  <time>  содержит  время  в  Univeral Coordinated Time (UTC), в  отличии  от  локального  в  <cmt>, следует  выбрать  единое  время  для  БД  и  привести  к  нему  все  значения. Для  удобства  следует  получить  linestring, для  отображения  трэка, но  желательно  сохранить  время  для  каждой  точки  трэка. Также  удобно  знать  время  трэка, по  первой  точке. Для  трэков  с  одной  точкой  поле  trk_line=null. Также  надо  учитывать, что  трэк  может  содержать  несколько  сегментов (Track Segment), хотя  MapSource  кажется, так  не  делает, вместо  этого  создавая  новый  трэк. Создадим  таблицы, для  треков  и  точек  треков, у  последних  получится  два  внешних  ключа  trk_id  и  nseg, хотя  nseg  получается  «висячим» - так  как  никуда  не  указывает…
:Трек  имеет  только  имя  и  множество  точек, тип  которых – wptType, но  с  более  аскетичным  содержанием. Здесь  надо  заметить, что  элемент  <time>  содержит  время  в  Univeral Coordinated Time (UTC), в  отличии  от  локального  в  <cmt>, следует  выбрать  единое  время  для  БД  и  привести  к  нему  все  значения. Для  удобства  следует  получить  linestring, для  отображения  трэка, но  желательно  сохранить  время  для  каждой  точки  трэка. Также  удобно  знать  время  трэка, по  первой  точке. Для  трэков  с  одной  точкой  поле  trk_line=null. Также  надо  учитывать, что  трэк  может  содержать  несколько  сегментов (Track Segment), хотя  MapSource  кажется, так  не  делает, вместо  этого  создавая  новый  трэк. Создадим  таблицы, для  треков  и  точек  треков, у  последних  получится  два  внешних  ключа  trk_id  и  nseg, хотя  nseg  получается  «висячим» - так  как  никуда  не  указывает…
{{Скрытый
 
|Рамка = 1px dashed #aa0000
:Структура  таблиц  trk(tracklogs) и  trkpt (Track Point)
|Ссылка = left
|Выравнивание_заголовка = left
|Заголовок = Структура  таблиц  trk(tracklogs) и  trkpt (Track Point)
|Фон_заголовка = #ccccff
|Содержание =
<syntaxhighlight lang="SQL">
<syntaxhighlight lang="SQL">
CREATE TABLE `trk` (
CREATE TABLE `trk` (
Строка 108: Строка 108:
   `ele` double default NULL,
   `ele` double default NULL,
   PRIMARY KEY  (`id`))
   PRIMARY KEY  (`id`))
</syntaxhighlight>
</syntaxhighlight>}}
<br />
:Функция для заполнения `trk_line`
:Функция для заполнения `trk_line`
Я это называю - "собирать бисер". В SFA нет функций для редактирования геометрии (в PostGIS и Oracle Spatila - есть). По хорошему надо использовать WKB - но как сделать это на SQL - я не знаю. Поэтому использую WKT и колдую с текстом (longText, по началу использовал text - как то не хватило...). У MySQL есть пара неприятных моментов связанных с геометрией: при попытке создать в хранимке определённую геометрию (например LINESTRING) - MySQL меняет функцию на создание просто геометрии (и внезапно получаем MULTIPOINT, хотя может это косяк моей версии), поэтому я использовал geomfromtext и в строке явно указывал тип геометрии. При объявлении "Declare p1, p2 point;" p1, p2 - это указатели, а значит при set p1=p2 мы получаем два указателя на '''один''' объект. Что бы скопировать точку приходится городить такое : Set p1 = geomfromtext(concat('Point(', X(CrP), ' ', Y(CrP), ')'));
Я это называю - "собирать бисер". В SFA нет функций для редактирования геометрии (в PostGIS и Oracle Spatila - есть). По хорошему надо использовать WKB - но как сделать это на SQL - я не знаю. Поэтому использую WKT и колдую с текстом (longText, по началу использовал text - как то не хватило...). У MySQL есть пара неприятных моментов связанных с геометрией: при попытке создать в хранимке определённую геометрию (например LINESTRING) - MySQL меняет функцию на создание просто геометрии (и внезапно получаем MULTIPOINT, хотя может это косяк моей версии), поэтому я использовал geomfromtext и в строке явно указывал тип геометрии. При объявлении "Declare p1, p2 point;" p1, p2 - это указатели, а значит при set p1=p2 мы получаем два указателя на '''один''' объект. Что бы скопировать точку приходится городить такое : Set p1 = geomfromtext(concat('Point(', X(CrP), ' ', Y(CrP), ')'));
{{Скрытый
|Рамка = 1px dashed #aa0000
|Ссылка = left
|Выравнивание_заголовка = left
|Заголовок = CreateTrkLine
|Фон_заголовка = #ccccff
|Содержание =
<syntaxhighlight lang="SQL">
<syntaxhighlight lang="SQL">
PROCEDURE `CreateTrkLine`(nid int)
PROCEDURE `CreateTrkLine`(nid int)
Строка 142: Строка 148:
   update trk set `trk_line`=CrLn where id=nid;
   update trk set `trk_line`=CrLn where id=nid;
END $$
END $$
</syntaxhighlight>
</syntaxhighlight>}}
<br />
{{Скрытый
:Функция для добавления Point к LineString
|Рамка = 1px dashed #aa0000
|Ссылка = left
|Выравнивание_заголовка = left
|Заголовок = Функция для добавления Point к LineString
|Фон_заголовка = #ccccff
|Содержание =
<syntaxhighlight lang="SQL">
<syntaxhighlight lang="SQL">
FUNCTION `LS_AddPoint`(Ls LineString, np point) RETURNS linestring
FUNCTION `LS_AddPoint`(Ls LineString, np point) RETURNS linestring
Строка 161: Строка 172:
   Return LineFromText(nStr);
   Return LineFromText(nStr);
END $$
END $$
</syntaxhighlight>
</syntaxhighlight>}}
<br />
<br />
# '''Импорт  данных'''
# '''Импорт  данных'''
:Для  разработки  модуля  импорта  данных, я  выбрал  VBA, по  двум  причинам: наиболее  удобный  IDE  из  доступных  у  меня  на  рабочей  машине; наличие  опыта  и  наработок. Перед  началом  работы, необходимо  подключить  Microsoft  XML  v6.0 (работа  с  XML)  и  Microsoft ActiveX Data Objects 2.8 Library (подключение  БД). Также  я  использовал  WinAPI, а  именно  GetOpenFileNameA  из  comdlg32.dll.
Для  разработки  модуля  импорта  данных, я  выбрал  VBA, по  двум  причинам: наиболее  удобный  IDE  из  доступных  у  меня  на  рабочей  машине; наличие  опыта  и  наработок. Перед  началом  работы, необходимо  подключить  Microsoft  XML  v6.0 (работа  с  XML)  и  Microsoft ActiveX Data Objects 2.8 Library (подключение  БД). Также  я  использовал  WinAPI, а  именно  GetOpenFileNameA  из  comdlg32.dll.
:Изначально, было решено, разделить чтение и запись, что бы передать данные используются структуры: wpt_rec и trk_rec. В начале разработки, в отладочных целях, данные записывались на Лист в Excel'е - данный код приведён в листингах, но закомментирован. Некрасиво получилось то, что фильтрация исходных данных происходить в разных местах: для точек - при чтении XML'я (If cWPT.cmt <> "" Then 'У "ненужных" точек cWPT.cmt=""), для треков в начале записи в БД (If nTRK.s(0).p(0).time <> "" Then). Так же разделено преобразование даты/время, но здесь это оправданно - как было сказано выше, в точках и трэках время записано по разному.
Изначально, было решено, разделить чтение и запись, что бы передать данные используются структуры: wpt_rec и trk_rec. В начале разработки, в отладочных целях, данные записывались на Лист в Excel'е - данный код приведён в листингах, но закомментирован. Некрасиво получилось то, что фильтрация исходных данных происходить в разных местах: для точек - при чтении XML'я (If cWPT.cmt <> "" Then 'У "ненужных" точек cWPT.cmt=""), для треков в начале записи в БД (If nTRK.s(0).p(0).time <> "" Then). Так же разделено преобразование даты/время, но здесь это оправданно - как было сказано выше, в точках и трэках время записано по разному.
:Запуск импорта - test1.
:Запуск импорта - test1.
<br />
<br />
Файл с макросами (xlsm):[[Файл:Imp_gpx.zip|файл с макросами (xlsm)]]
Файл с макросами (xlsm):[[Файл:Imp_gpx.zip|файл с макросами (xlsm)]]
<br />
<br />
:Обработка XML'я
{{Скрытый
|Рамка = 1px dashed #aa0000
|Ссылка = left
|Выравнивание_заголовка = left
|Заголовок = Обработка XML'я
|Фон_заголовка = #ccccff
|Содержание =
<syntaxhighlight lang="VB">
<syntaxhighlight lang="VB">
'Переменные для записи данных на Лист
'Переменные для записи данных на Лист
Строка 353: Строка 370:
  'InsTRK cTRK
  'InsTRK cTRK
End Sub
End Sub
</syntaxhighlight>
</syntaxhighlight>}}
<br />
{{Скрытый
:Загрузка в БД
|Рамка = 1px dashed #aa0000
|Ссылка = left
|Выравнивание_заголовка = left
|Заголовок = Загрузка в БД
|Фон_заголовка = #ccccff
|Содержание =
<syntaxhighlight lang="VB">
<syntaxhighlight lang="VB">
Dim MyConnect As ADODB.Connection
Dim MyConnect As ADODB.Connection
Строка 473: Строка 495:
  Next i
  Next i
End Sub
End Sub
</syntaxhighlight>
</syntaxhighlight>}}
<br />
{{Скрытый
:OpenFile
|Рамка = 1px dashed #aa0000
|Ссылка = left
|Выравнивание_заголовка = left
|Заголовок = OpenFile
|Фон_заголовка = #ccccff
|Содержание =
<syntaxhighlight lang="VB">
<syntaxhighlight lang="VB">
Private Const OFN_ALLOWMULTISELECT As Long = &H200
Private Const OFN_ALLOWMULTISELECT As Long = &H200
Строка 576: Строка 603:
   End With
   End With
End Function
End Function
</syntaxhighlight>
</syntaxhighlight>}}


==Использование==
==Использование==

Текущая версия от 18:35, 12 июля 2013

Эта страница является черновиком статьи.


Задача

Дано: Имеется много gpx-файлов, полученные из MapSource (BaseCamp)

Получить: Собрать все данные (точки (waypoints) и трэки (tracklogs)) в одном месте. Отсеяв дубли, «ненужные» точки.

Ресурсы: MySQL Server 5.0.67-community-nt via TCP/IP; MySQL GUI 5.1.11; MySQL Connector/ODBC 5.1.12; Microsoft Office 2007

Решение

  1. Структура БД
Gpx полученные из MapSource, обладают рядом особенностей:
  • заполняются не все «поля»
  • собственное расширение (<extensions>)
  • дата и время для waypoints пишется как текст в элементы <cmt> и <desc>

Дамп БД:Файл:Gpx db 20130407 2315.zip


В данном случае меня интересовали: геометрия (lat, lon), имя (name), высота (ele), дата/время (cmt), символ(sym). Содержание <desc> дублирует <cmt>, с точки зрения MapSource: <cmt> - время, <desc> - комментарий к точке, <extensions> влияет только на отображение точки в MapSource. Символ <sym> записывается как string, лучше вынести в отдельную таблицу.



Трек имеет только имя и множество точек, тип которых – wptType, но с более аскетичным содержанием. Здесь надо заметить, что элемент


Функция для заполнения `trk_line`

Я это называю - "собирать бисер". В SFA нет функций для редактирования геометрии (в PostGIS и Oracle Spatila - есть). По хорошему надо использовать WKB - но как сделать это на SQL - я не знаю. Поэтому использую WKT и колдую с текстом (longText, по началу использовал text - как то не хватило...). У MySQL есть пара неприятных моментов связанных с геометрией: при попытке создать в хранимке определённую геометрию (например LINESTRING) - MySQL меняет функцию на создание просто геометрии (и внезапно получаем MULTIPOINT, хотя может это косяк моей версии), поэтому я использовал geomfromtext и в строке явно указывал тип геометрии. При объявлении "Declare p1, p2 point;" p1, p2 - это указатели, а значит при set p1=p2 мы получаем два указателя на один объект. Что бы скопировать точку приходится городить такое : Set p1 = geomfromtext(concat('Point(', X(CrP), ' ', Y(CrP), ')'));




  1. Импорт данных

Для разработки модуля импорта данных, я выбрал VBA, по двум причинам: наиболее удобный IDE из доступных у меня на рабочей машине; наличие опыта и наработок. Перед началом работы, необходимо подключить Microsoft XML v6.0 (работа с XML) и Microsoft ActiveX Data Objects 2.8 Library (подключение БД). Также я использовал WinAPI, а именно GetOpenFileNameA из comdlg32.dll. Изначально, было решено, разделить чтение и запись, что бы передать данные используются структуры: wpt_rec и trk_rec. В начале разработки, в отладочных целях, данные записывались на Лист в Excel'е - данный код приведён в листингах, но закомментирован. Некрасиво получилось то, что фильтрация исходных данных происходить в разных местах: для точек - при чтении XML'я (If cWPT.cmt <> "" Then 'У "ненужных" точек cWPT.cmt=""), для треков в начале записи в БД (If nTRK.s(0).p(0).time <> "" Then). Так же разделено преобразование даты/время, но здесь это оправданно - как было сказано выше, в точках и трэках время записано по разному.

Запуск импорта - test1.


Файл с макросами (xlsm):Файл:Imp gpx.zip




Использование

QGIS
AutoCAD Map 3D

Ссылки

gpx.xsd
MapSource
GpxExtensions