1 /***************************************************************************
2  *
3  * Project:  OpenCPN
4  *
5  ***************************************************************************
6  *   Copyright (C) 2010 by David S. Register                               *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
22  **************************************************************************/
23 
24 #include <wx/tokenzr.h>
25 #include <wx/regex.h>
26 
27 #include "PositionParser.h"
28 #include "navutil.h"
29 
PositionParser(const wxString & src)30 PositionParser::PositionParser(const wxString & src)
31 {
32     parsedOk = false;
33     if( FindSeparator( src ) ) {
34         latitude = fromDMM( latitudeString );
35         longitude = fromDMM( longitudeString );
36         if( (latitude != 0.0) && (longitude != 0.0) ) parsedOk = true;
37     }
38 }
39 
FindSeparator(const wxString & src)40 bool PositionParser::FindSeparator(const wxString & src)
41 {
42 
43     // Used when format is similar to "12 34.56 N 12 34.56 E"
44     wxString posPartOfSeparator = _T("");
45 
46     // First the XML case:
47     // Generalized XML tag format, accepts anything like <XXX yyy="<lat>" zzz="<lon>" >
48     // GPX format <wpt lat="<lat>" lon="<lon>" /> tag among others.
49 
50     wxRegEx regex;
51 
52     int re_compile_flags = wxRE_ICASE;
53 #ifdef wxHAS_REGEX_ADVANCED
54     re_compile_flags |= wxRE_ADVANCED;
55 #endif
56 
57     regex.Compile(
58             _T( "<[a-z,A-Z]*\\s*[a-z,A-Z]*=\"([0-9,.]*)\"\\s*[a-z,A-Z]*=\"([-,0-9,.]*)\"\\s*/*>" ),
59                   re_compile_flags );
60 
61     if( regex.IsValid() ) {
62         if( regex.Matches( src ) ) {
63 			int n = regex.GetMatchCount();
64             latitudeString = regex.GetMatch( src, 1 );
65             longitudeString = regex.GetMatch( src, 2 );
66             latitudeString.Trim( true );
67             latitudeString.Trim( false );
68             longitudeString.Trim( true );
69             longitudeString.Trim( false );
70             return true;
71         }
72     }
73 
74     // Now try various separators.
75 
76     separator = _T(", ");
77     wxStringTokenizer tk1(src, separator);
78     if (tk1.CountTokens() == 2) {
79         latitudeString = tk1.GetNextToken();
80         latitudeString.Trim(true);
81         latitudeString.Trim(false);
82         longitudeString = tk1.GetNextToken();
83         longitudeString.Trim(true);
84         longitudeString.Trim(false);
85 
86         return true;
87     }
88 
89     separator = _T(",");
90     wxStringTokenizer tk2 (src, separator);
91     if (tk2.CountTokens() == 2) {
92         latitudeString = tk2.GetNextToken();
93         latitudeString.Trim(true);
94         latitudeString.Trim(false);
95         longitudeString = tk2.GetNextToken();
96         longitudeString.Trim(true);
97         longitudeString.Trim(false);
98 
99         return true;
100     }
101 
102     separator = _T(" ");
103     wxStringTokenizer tk3(src, separator);
104     if (tk3.CountTokens() == 2) {
105         latitudeString = tk3.GetNextToken();
106         latitudeString.Trim(true);
107         latitudeString.Trim(false);
108         longitudeString = tk3.GetNextToken();
109         longitudeString.Trim(true);
110         longitudeString.Trim(false);
111 
112         return true;
113     }
114 
115     separator = _T("\t");
116     wxStringTokenizer tk4(src, separator);
117     if (tk4.CountTokens() == 2) {
118         latitudeString = tk4.GetNextToken();
119         latitudeString.Trim(true);
120         latitudeString.Trim(false);
121         longitudeString = tk4.GetNextToken();
122         longitudeString.Trim(true);
123         longitudeString.Trim(false);
124 
125         return true;
126     }
127 
128     separator = _T("\n");
129     wxStringTokenizer tk5(src, separator);
130     if (tk5.CountTokens() == 2) {
131         latitudeString = tk5.GetNextToken();
132         latitudeString.Trim(true);
133         latitudeString.Trim(false);
134         longitudeString = tk5.GetNextToken();
135         longitudeString.Trim(true);
136         longitudeString.Trim(false);
137 
138         return true;
139     }
140 
141     separator = _T("N");
142     posPartOfSeparator = _T("N");
143     wxStringTokenizer tk6(src, separator);
144     if (tk6.CountTokens() == 2) {
145         latitudeString = tk6.GetNextToken() << posPartOfSeparator;
146         latitudeString.Trim(true);
147         latitudeString.Trim(false);
148         longitudeString = tk6.GetNextToken();
149         longitudeString.Trim(true);
150         longitudeString.Trim(false);
151 
152         return true;
153     }
154 
155     separator = _T("S");
156     posPartOfSeparator = _T("S");
157     wxStringTokenizer tk7(src, separator);
158     if (tk7.CountTokens() == 2) {
159         latitudeString = tk7.GetNextToken() << posPartOfSeparator;
160         latitudeString.Trim(true);
161         latitudeString.Trim(false);
162         longitudeString = tk7.GetNextToken();
163         longitudeString.Trim(true);
164         longitudeString.Trim(false);
165 
166         return true;
167     }
168 
169     // Give up.
170     return false;
171 }
172 
173