2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2010 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published
7 ** by the Free Software Foundation; either version 3 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ** File: geolocation.cpp
23 #include "libnetxms.h"
24 #include <geolocation.h>
27 static const double ROUND_OFF
= 0.00000001;
31 // Default constructor - create location of type UNSET
34 GeoLocation
::GeoLocation()
40 posToString(false, 0);
46 // Constructor - create location from double lat/lon values
49 GeoLocation
::GeoLocation(int type
, double lat
, double lon
)
54 posToString(true, lat
);
55 posToString(false, lon
);
61 // Constructor - create location from string lat/lon values
64 GeoLocation
::GeoLocation(int type
, const TCHAR
*lat
, const TCHAR
*lon
)
67 m_isValid
= parseLatitude(lat
) && parseLongitude(lon
);
68 posToString(true, m_lat
);
69 posToString(false, m_lon
);
77 GeoLocation
::GeoLocation(const GeoLocation
&src
)
82 nx_strncpy(m_latStr
, src
.m_latStr
, 20);
83 nx_strncpy(m_lonStr
, src
.m_lonStr
, 20);
84 m_isValid
= src
.m_isValid
;
89 // Create geolocation object from data in NXCP message
92 GeoLocation
::GeoLocation(CSCPMessage
&msg
)
94 m_type
= (int)msg
.GetVariableShort(VID_GEOLOCATION_TYPE
);
95 m_lat
= msg
.GetVariableDouble(VID_LATITUDE
);
96 m_lon
= msg
.GetVariableDouble(VID_LONGITUDE
);
97 posToString(true, m_lat
);
98 posToString(false, m_lon
);
107 GeoLocation
::~GeoLocation()
113 // Assignment operator
116 GeoLocation
& GeoLocation
::operator =(const GeoLocation
&src
)
121 nx_strncpy(m_latStr
, src
.m_latStr
, 20);
122 nx_strncpy(m_lonStr
, src
.m_lonStr
, 20);
123 m_isValid
= src
.m_isValid
;
132 void GeoLocation
::fillMessage(CSCPMessage
&msg
)
134 msg
.SetVariable(VID_GEOLOCATION_TYPE
, (WORD
)m_type
);
135 msg
.SetVariable(VID_LATITUDE
, m_lat
);
136 msg
.SetVariable(VID_LONGITUDE
, m_lon
);
141 // Getters for degree, minutes, and seconds from double value
144 int GeoLocation
::getIntegerDegree(double pos
)
146 return (int)(fabs(pos
) + ROUND_OFF
);
149 int GeoLocation
::getIntegerMinutes(double pos
)
151 double d
= fabs(pos
) + ROUND_OFF
;
152 return (int)((d
- (double)((int)d
)) * 60.0);
155 double GeoLocation
::getDecimalSeconds(double pos
)
157 double d
= fabs(pos
) * 60.0 + ROUND_OFF
;
158 return (d
- (double)((int)d
)) * 60.0;
163 // Convert position to string
166 void GeoLocation
::posToString(bool isLat
, double pos
)
168 TCHAR
*buffer
= isLat ? m_latStr
: m_lonStr
;
171 if ((pos
< -180.0) || (pos
> 180.0))
173 _tcscpy(buffer
, _T("<invalid>"));
180 *buffer
= (pos
< 0) ?
_T('S') : _T('N');
184 *buffer
= (pos
< 0) ?
_T('W') : _T('E');
189 _sntprintf(buffer
, 18, _T("%02d° %02d' %02.3f\""), getIntegerDegree(pos
), getIntegerMinutes(pos
), getDecimalSeconds(pos
));
194 // Parse latitude/longitude string
197 double GeoLocation
::parse(const TCHAR
*str
, bool isLat
, bool *isValid
)
201 // Prepare input string
202 TCHAR
*in
= _tcsdup(str
);
205 // Check if string given is just double value
207 double value
= _tcstod(in
, &eptr
);
212 else // If not a valid double, check if it's in DMS form
214 // Check for invalid characters
215 if (_tcsspn(in
, isLat ?
_T("0123456789.°'\" NS") : _T("0123456789.°'\" EW")) == _tcslen(in
))
220 if ((*curr
== _T('N')) || (*curr
== _T('E')))
225 else if ((*curr
== _T('S')) || (*curr
== _T('W')))
231 while(*curr
== _T(' '))
234 double deg
= 0.0, min
= 0.0, sec
= 0.0;
236 deg
= _tcstod(curr
, &eptr
);
237 if (*eptr
== 0) // End of string
239 if ((*eptr
!= _T('°')) && (*eptr
!= _T(' ')))
240 goto cleanup
; // Unexpected character
242 while(*curr
== _T(' '))
245 min
= _tcstod(curr
, &eptr
);
246 if (*eptr
== 0) // End of string
248 if (*eptr
!= _T('\''))
249 goto cleanup
; // Unexpected character
251 while(*curr
== _T(' '))
254 sec
= _tcstod(curr
, &eptr
);
255 if (*eptr
== 0) // End of string
257 if (*eptr
!= _T('"'))
258 goto cleanup
; // Unexpected character
260 while(*curr
== _T(' '))
263 if ((*curr
== _T('N')) || (*curr
== _T('E')))
268 else if ((*curr
== _T('S')) || (*curr
== _T('W')))
275 goto cleanup
; // Hemisphere was not specified
278 value
= sign
* (deg
+ min
/ 60.0 + sec
/ 3600.0);
293 bool GeoLocation
::parseLatitude(const TCHAR
*lat
)
297 m_lat
= parse(lat
, true, &isValid
);
308 bool GeoLocation
::parseLongitude(const TCHAR
*lon
)
312 m_lon
= parse(lon
, false, &isValid
);