В данном случае меня интересовали: геометрия (lat, lon), имя (name), высота (ele), дата/время (cmt), символ(sym). Содержание <desc> дублирует <cmt>, с точки зрения MapSource: <cmt> - время, <desc> - комментарий к точке, <extensions> влияет только на отображение точки в MapSource. Символ <sym> записывается как string, лучше вынести в отдельную таблицу.
Я это называю - "собирать бисер". В 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), ')'));
Для разработки модуля импорта данных, я выбрал 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). Так же разделено преобразование даты/время, но здесь это оправданно - как было сказано выше, в точках и трэках время записано по разному.
DimMyConnectAsADODB.ConnectionPublicFunctionConnectToMySQL()AsADODB.Connection'Подключаемся к БДSetConnectToMySQL=NewADODB.ConnectionConnectToMySQL.ConnectionString="Driver={MySQL ODBC 5.1 Driver};Server=localhost;Database=gpx_DB;User=guest;Password=guest;Option=3;"ConnectToMySQL.OpenEndFunctionPublicSubStart1()'Подключаемся к БДSetMyConnect=ConnectToMySQLEndSub'"SELECT id FROM `gpx_db`.`symtbl` where `desc`="PublicFunctionGetSymId(SymDescAsString)AsInteger' Обрабатываем <sym>, получаем ключ из symtblDimStrSQLAsStringDimMyRSAsADODB.Recordset'SetMyRS=NewADODB.RecordsetSetMyRS.ActiveConnection=MyConnectMyRS.Source="SELECT id FROM `gpx_db`.`symtbl` where `desc`="""&SymDesc&""";"MyRS.OpenIfMyRS.BOFAndMyRS.EOFThenInsSymDesc(SymDesc)GetSymId=GetSymId(SymDesc)ElseGetSymId=MyRS.fields(0).ValueEndIfEndFunction'insert into `gpx_db`.`symtbl` values (null,'Restaurant')PublicSubInsSymDesc(SymDescAsString)'Добавляем новое значение <sym>MyConnect.Execute"insert into `gpx_db`.`symtbl` values (null,"""&SymDesc&""");"EndSub'SELECT * FROM wpt w where p=geomfromtext('POINT(60.5513457 59.5433567)') and cmt=str_to_date('15-AUG-12 9:38:50', '%d-%M-%Y %H:%i:%s');PublicFunctionSearchWPT(nWPTAswpt_rec)AsInteger'Ищем waypoints в БДDimStrSQLAsStringDimMyRSAsADODB.Recordset'SetMyRS=NewADODB.RecordsetSetMyRS.ActiveConnection=MyConnectMyRS.Source="SELECT id FROM wpt w where p=geomfromtext(""POINT("&nWPT.lon&" "&nWPT.lat&")"") and cmt="&_
"str_to_date("""&nWPT.cmt&""", ""%d-%M-%Y %H:%i:%s"");"MyRS.OpenIfMyRS.BOFAndMyRS.EOFThenSearchWPT=0ElseSearchWPT=MyRS.fields(0).ValueEndIfEndFunction'select str_to_date('15-AUG-12 9:38:50', '%d-%M-%Y %H:%i:%s')PublicSubInsWPT(nWPTAswpt_rec)'Добавляем waypoints в БДIfSearchWPT(nWPT)=0Then'Проверяем наличие'geomfromtext('Point(0 0)')MyConnect.Execute"insert into `gpx_db`.`wpt` values (null,geomfromtext(""Point("&nWPT.lon&" "&nWPT.lat&")""), """&nWPT.name&_
""", "&nWPT.ele&", str_to_date("""&nWPT.cmt&""", '%d-%M-%Y %H:%i:%s'), "&nWPT.sym&");"EndIfEndSub'SELECT id FROM trk t where name='ACTIVE LOG' and dt='2012-08-15 09:51:32';PublicFunctionSearchTRK(nTRKAstrk_rec)AsInteger'Ищем tracklogs в БДDimStrSQLAsStringDimMyRSAsADODB.Recordset'SetMyRS=NewADODB.RecordsetSetMyRS.ActiveConnection=MyConnectMyRS.Source="SELECT id FROM trk where name="""&nTRK.name&""" and dt=CONVERT_TZ(str_to_date("""&nTRK.s(0).p(0).time&_
""", '%Y-%m-%d %H:%i:%s'),'+00:00','+6:00');"'MyRS.Source = "select SearchTrk(" & nTRK.s(0).p(0).lon & ", " & nTRK.s(0).p(0).lat & ", CONVERT_TZ(str_to_date(""" & nTRK.s(0).p(0).time & _' """, '%Y-%m-%d %H:%i:%s'),'+00:00','+6:00'))"MyRS.OpenIfMyRS.BOFAndMyRS.EOFThenSearchTRK=0ElseSearchTRK=MyRS.fields(0).ValueEndIfEndFunctionPublicFunctionInsTRK(nTRKAstrk_rec)AsInteger'Добавляем tracklogs в БДDimresAsInteger'IfnTRK.s(0).p(0).time<>""Thenres=SearchTRK(nTRK)Ifres=0ThenMyConnect.Execute"insert into `gpx_db`.`trk` values (null, """&nTRK.name&""", 0, null, CONVERT_TZ(str_to_date("""&_
nTRK.s(0).p(0).time&""", '%Y-%m-%d %H:%i:%s'),'+00:00','+6:00'));"res=SearchTRK(nTRK)InsTRKptsnTRK,resMyConnect.Execute"call CreateTrkLine("&res&");"EndIfInsTRK=resEndIfEndFunctionPublicSubInsTRKpts(nTRKAstrk_rec,TRK_idAsInteger)'Добавляем Track Point в БДDimi,JAsInteger'Fori=0ToUBound(nTRK.s)ForJ=0ToUBound(nTRK.s(i).p)MyConnect.Execute"insert into `gpx_db`.`trkpt` values (null, "&TRK_id&", "&i+1&_
", geomfromtext(""Point("&nTRK.s(i).p(J).lon&" "&nTRK.s(i).p(J).lat&")""), "&_
"CONVERT_TZ(str_to_date("""&nTRK.s(i).p(J).time&""", '%Y-%m-%d %H:%i:%s'),'+00:00','+6:00'), "&_
nTRK.s(i).p(J).ele&");"NextJNextiEndSub