Don't force the user to specify the metric
[xapian.git] / xapian-core / geospatial / latlongcoord.cc
blob56bd6e74d34392fe898c412b0b1505429c4900fd
1 /** @file latlongcoord.cc
2 * @brief Latitude and longitude representations.
3 */
4 /* Copyright 2008 Lemur Consulting Ltd
5 * Copyright 2011 Richard Boulton
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 * USA
23 #include <config.h>
25 #include "xapian/geospatial.h"
26 #include "xapian/error.h"
28 #include "geoencode.h"
29 #include "str.h"
31 #include <cmath>
33 using namespace Xapian;
34 using namespace std;
36 LatLongCoord::LatLongCoord(double latitude_, double longitude_)
37 : latitude(latitude_),
38 longitude(longitude_)
40 if (latitude < -90.0 || latitude > 90.0)
41 throw InvalidArgumentError("Latitude out-of-range");
42 longitude = fmod(longitude_, 360);
43 if (longitude < 0) longitude += 360;
46 void
47 LatLongCoord::unserialise(const string & serialised)
49 const char * ptr = serialised.data();
50 const char * end = ptr + serialised.size();
51 unserialise(&ptr, end);
52 if (ptr != end)
53 throw SerialisationError(
54 "Junk found at end of serialised LatLongCoord");
57 void
58 LatLongCoord::unserialise(const char ** ptr, const char * end)
60 size_t len = end - *ptr;
61 if (len < 2) {
62 latitude = 0;
63 longitude = 0;
64 return;
66 GeoEncode::decode(*ptr, end - *ptr, latitude, longitude);
67 if (len < 6) {
68 *ptr = end;
69 } else {
70 *ptr += 6;
74 string
75 LatLongCoord::serialise() const
77 string result;
78 GeoEncode::encode(latitude, longitude, result);
79 return result;
82 string
83 LatLongCoord::get_description() const
85 string res("Xapian::LatLongCoord(");
86 res += str(latitude);
87 res += ", ";
88 res += str(longitude);
89 res += ")";
90 return res;
93 void
94 LatLongCoords::unserialise(const string & serialised)
96 const char * ptr = serialised.data();
97 const char * end_ptr = ptr + serialised.size();
98 coords.clear();
99 while (ptr != end_ptr) {
100 coords.push_back(LatLongCoord());
101 coords.back().unserialise(&ptr, end_ptr);
103 if (ptr != end_ptr) {
104 throw SerialisationError("Junk found at end of serialised "
105 "LatLongCoords");
109 string
110 LatLongCoords::serialise() const
112 string result;
113 vector<LatLongCoord>::const_iterator coord;
114 for (coord = coords.begin(); coord != coords.end(); ++coord)
116 GeoEncode::encode(coord->latitude, coord->longitude, result);
118 return result;
121 string
122 LatLongCoords::get_description() const
124 string res("Xapian::LatLongCoords(");
125 vector<LatLongCoord>::const_iterator coord;
126 for (coord = coords.begin(); coord != coords.end(); ++coord) {
127 if (coord != coords.begin()) {
128 res += ", ";
130 res += "(";
131 res += str(coord->latitude);
132 res += ", ";
133 res += str(coord->longitude);
134 res += ")";
136 res += ")";
137 return res;