Osmium
0.1
|
00001 #ifndef OSMIUM_GEOMETRY_HPP 00002 #define OSMIUM_GEOMETRY_HPP 00003 00004 /* 00005 00006 Copyright 2011 Jochen Topf <jochen@topf.org> and others (see README). 00007 00008 This file is part of Osmium (https://github.com/joto/osmium). 00009 00010 Osmium is free software: you can redistribute it and/or modify it under the 00011 terms of the GNU Lesser General Public License or (at your option) the GNU 00012 General Public License as published by the Free Software Foundation, either 00013 version 3 of the Licenses, or (at your option) any later version. 00014 00015 Osmium is distributed in the hope that it will be useful, but WITHOUT ANY 00016 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 00017 PARTICULAR PURPOSE. See the GNU Lesser General Public License and the GNU 00018 General Public License for more details. 00019 00020 You should have received a copy of the Licenses along with Osmium. If not, see 00021 <http://www.gnu.org/licenses/>. 00022 00023 */ 00024 00025 #include <sstream> 00026 00027 #ifdef OSMIUM_WITH_GEOS 00028 # include <geos/geom/GeometryFactory.h> 00029 # include <geos/geom/PrecisionModel.h> 00030 #endif // OSMIUM_WITH_GEOS 00031 00032 #ifdef OSMIUM_WITH_SHPLIB 00033 # include <shapefil.h> 00034 #endif // OSMIUM_WITH_SHPLIB 00035 00036 #ifdef OSMIUM_WITH_OGR 00037 # include <ogr_geometry.h> 00038 #endif // OSMIUM_WITH_OGR 00039 00040 #include <osmium/exceptions.hpp> 00041 #include <osmium/osm/types.hpp> 00042 00043 namespace Osmium { 00044 00048 namespace Geometry { 00049 00051 const int srid = 4326; 00052 00060 enum wkbGeometryType { 00061 wkbPoint = 1, 00062 wkbLineString = 2, 00063 wkbPolygon = 3, 00064 wkbMultiPoint = 4, 00065 wkbMultiLineString = 5, 00066 wkbMultiPolygon = 6, 00067 wkbGeometryCollection = 7, 00068 00069 // SRID-presence flag (EWKB) 00070 wkbSRID = 0x20000000 00071 }; 00072 00076 enum wkbByteOrder { 00077 wkbXDR = 0, // Big Endian 00078 wkbNDR = 1 // Little Endian 00079 }; 00080 00081 #ifdef OSMIUM_WITH_GEOS 00082 00087 geos::geom::GeometryFactory* geos_geometry_factory() { 00088 static geos::geom::PrecisionModel pm; 00089 static geos::geom::GeometryFactory factory(&pm, -1); 00090 return &factory; 00091 } 00092 #endif // OSMIUM_WITH_GEOS 00093 00094 class Geometry; 00095 00117 template <typename T> 00118 struct StreamFormat { 00119 StreamFormat(const Geometry& geometry, bool with_srid) : m_geometry(geometry), m_with_srid(with_srid) {} 00120 const Geometry& m_geometry; 00121 const bool m_with_srid; 00122 }; 00123 00127 template <typename T> 00128 std::ostream& operator<<(std::ostream& out, StreamFormat<T> format) { 00129 return format.m_geometry.write_to_stream(out, format, format.m_with_srid); 00130 } 00131 00137 template<typename T> 00138 inline void write_binary(std::ostream& out, const T value) { 00139 out.write(reinterpret_cast<const char*>(&value), sizeof(T)); 00140 } 00141 00147 template<typename T> 00148 inline void write_hex(std::ostream& out, const T value) { 00149 static const char* lookup_hex = "0123456789ABCDEF"; 00150 for (const char* in = reinterpret_cast<const char*>(&value); in < reinterpret_cast<const char*>(&value) + sizeof(T); ++in) { 00151 out << lookup_hex[(*in >> 4) & 0xf] 00152 << lookup_hex[*in & 0xf]; 00153 } 00154 } 00155 00163 inline void write_binary_wkb_header(std::ostream& out, bool with_srid, uint32_t type) { 00164 write_binary<uint8_t>(out, wkbNDR); 00165 if (with_srid) { 00166 write_binary<uint32_t>(out, type | wkbSRID); 00167 write_binary<uint32_t>(out, srid); 00168 } else { 00169 write_binary<uint32_t>(out, type); 00170 } 00171 } 00172 00180 inline void write_hex_wkb_header(std::ostream& out, bool with_srid, uint32_t type) { 00181 write_hex<uint8_t>(out, wkbNDR); 00182 if (with_srid) { 00183 write_hex<uint32_t>(out, type | wkbSRID); 00184 write_hex<uint32_t>(out, srid); 00185 } else { 00186 write_hex<uint32_t>(out, type); 00187 } 00188 } 00189 00195 class Geometry { 00196 00197 public: 00198 00199 Geometry(osm_object_id_t id=0) : m_id(id) { 00200 } 00201 00202 virtual ~Geometry() { 00203 } 00204 00205 osm_object_id_t id() const { 00206 return m_id; 00207 } 00208 00209 // These types are never instantiated, they are used in the write_to_stream() 00210 // methods below as parameters to make the overloading mechanism choose the 00211 // right version. 00212 typedef StreamFormat<struct WKT_> AsWKT; 00213 typedef StreamFormat<struct WKB_> AsWKB; 00214 typedef StreamFormat<struct HWKB_> AsHexWKB; 00215 00216 AsWKT as_WKT(bool with_srid=false) const { 00217 return AsWKT(*this, with_srid); 00218 } 00219 00220 AsWKB as_WKB(bool with_srid=false) const { 00221 return AsWKB(*this, with_srid); 00222 } 00223 00224 AsHexWKB as_HexWKB(bool with_srid=false) const { 00225 return AsHexWKB(*this, with_srid); 00226 } 00227 00229 virtual std::ostream& write_to_stream(std::ostream& out, AsWKT, bool with_srid=false) const = 0; 00230 00232 virtual std::ostream& write_to_stream(std::ostream& out, AsWKB, bool with_srid=false) const = 0; 00233 00235 virtual std::ostream& write_to_stream(std::ostream& out, AsHexWKB, bool with_srid=false) const = 0; 00236 00237 #ifdef OSMIUM_WITH_SHPLIB 00238 virtual SHPObject* create_shp_object() const { 00239 return NULL; 00240 } 00241 #endif // OSMIUM_WITH_SHPLIB 00242 00243 #ifdef OSMIUM_WITH_JAVASCRIPT 00244 v8::Handle<v8::Value> js_to_wkt(const v8::Arguments& args) { 00245 std::ostringstream oss; 00246 bool with_srid = false; 00247 if (args.Length() >= 1) { 00248 with_srid = args[0]->ToBoolean()->Value(); 00249 } 00250 oss << this->as_WKT(with_srid); 00251 return v8::String::New(oss.str().c_str()); 00252 } 00253 00254 v8::Handle<v8::Value> js_to_wkb(const v8::Arguments& args) { 00255 std::ostringstream oss; 00256 bool with_srid = false; 00257 if (args.Length() >= 1) { 00258 with_srid = args[0]->ToBoolean()->Value(); 00259 } 00260 oss << this->as_WKB(with_srid); 00261 return v8::String::New(oss.str().c_str()); 00262 } 00263 00264 v8::Handle<v8::Value> js_to_hexwkb(const v8::Arguments& args) { 00265 std::ostringstream oss; 00266 bool with_srid = false; 00267 if (args.Length() >= 1) { 00268 with_srid = args[0]->ToBoolean()->Value(); 00269 } 00270 oss << this->as_HexWKB(with_srid); 00271 return v8::String::New(oss.str().c_str()); 00272 } 00273 00274 struct JavascriptTemplate : public Osmium::Javascript::Template { 00275 00276 JavascriptTemplate() : Osmium::Javascript::Template() { 00277 js_template->Set("toWKT", v8::FunctionTemplate::New(function_template<Geometry, &Geometry::js_to_wkt>)); 00278 js_template->Set("toWKB", v8::FunctionTemplate::New(function_template<Geometry, &Geometry::js_to_wkb>)); 00279 js_template->Set("toHexWKB", v8::FunctionTemplate::New(function_template<Geometry, &Geometry::js_to_hexwkb>)); 00280 } 00281 00282 }; 00283 #endif // OSMIUM_WITH_JAVASCRIPT 00284 00285 private: 00286 00287 osm_object_id_t m_id; 00288 00289 }; // class Geometry 00290 00299 template <typename TLonLat> 00300 class LonLatListWriter { 00301 00302 public: 00303 00304 LonLatListWriter(std::ostream& out, 00305 char delim_lonlat=' ', 00306 char delim_items=',') 00307 : m_out(out), 00308 m_delim_lonlat(delim_lonlat), 00309 m_delim_items(delim_items), 00310 m_first(true) { 00311 } 00312 00313 void operator()(const TLonLat& lonlat) { 00314 if (m_first) { 00315 m_first = false; 00316 } else { 00317 m_out << m_delim_items; 00318 } 00319 m_out << lonlat.lon() << m_delim_lonlat << lonlat.lat(); 00320 } 00321 00322 private: 00323 00324 std::ostream& m_out; 00325 char m_delim_lonlat; 00326 char m_delim_items; 00327 bool m_first; 00328 00329 }; // class LonLatListWriter 00330 00331 } // namespace Geometry 00332 00333 } // namespace Osmium 00334 00335 #endif // OSMIUM_GEOMETRY_HPP