Osmium  0.1
include/osmium/geometry.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines