Osmium
0.1
|
00001 #ifndef OSMIUM_GEOMETRY_POLYGON_HPP 00002 #define OSMIUM_GEOMETRY_POLYGON_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 <algorithm> 00026 00027 #include <osmium/geometry/from_way.hpp> 00028 #include <osmium/exceptions.hpp> 00029 00030 namespace Osmium { 00031 00032 namespace Geometry { 00033 00037 class Polygon : public FromWay { 00038 00039 public: 00040 00044 Polygon(const Osmium::OSM::WayNodeList& way_node_list, 00045 osm_object_id_t id=0) 00046 : FromWay(way_node_list, false, id) { 00047 if (!way_node_list.is_closed()) { 00048 throw Osmium::Exception::IllegalGeometry(); 00049 } 00050 } 00051 00055 Polygon(const Osmium::OSM::Way& way) 00056 : FromWay(way.nodes(), false, way.id()) { 00057 if (!way.nodes().is_closed()) { 00058 throw Osmium::Exception::IllegalGeometry(); 00059 } 00060 } 00061 00062 std::ostream& write_to_stream(std::ostream& out, AsWKT, bool with_srid=false) const { 00063 if (with_srid) { 00064 out << "SRID=4326;"; 00065 } 00066 LonLatListWriter<Osmium::OSM::WayNode> writer(out); 00067 out << "POLYGON((" << std::setprecision(10); 00068 for_each(m_way_node_list->begin(), m_way_node_list->end(), writer); 00069 return out << "))"; 00070 } 00071 00072 std::ostream& write_to_stream(std::ostream& out, AsWKB, bool with_srid=false) const { 00073 write_binary_wkb_header(out, with_srid, wkbPolygon); 00074 write_binary<uint32_t>(out, 1); // ring count 00075 write_binary<uint32_t>(out, m_way_node_list->size()); // ring #1 point count 00076 for (Osmium::OSM::WayNodeList::const_iterator it = m_way_node_list->begin(); it != m_way_node_list->end(); ++it) { 00077 write_binary<double>(out, it->lon()); 00078 write_binary<double>(out, it->lat()); 00079 } 00080 return out; 00081 } 00082 00083 std::ostream& write_to_stream(std::ostream& out, AsHexWKB, bool with_srid=false) const { 00084 write_hex_wkb_header(out, with_srid, wkbPolygon); 00085 write_hex<uint32_t>(out, 1); // ring count 00086 write_hex<uint32_t>(out, m_way_node_list->size()); // ring #1 point count 00087 for (Osmium::OSM::WayNodeList::const_iterator it = m_way_node_list->begin(); it != m_way_node_list->end(); ++it) { 00088 write_hex<double>(out, it->lon()); 00089 write_hex<double>(out, it->lat()); 00090 } 00091 return out; 00092 } 00093 00094 #ifdef OSMIUM_WITH_GEOS 00095 00100 geos::geom::Geometry* create_geos_geometry() const { 00101 try { 00102 std::vector<geos::geom::Coordinate>* c = new std::vector<geos::geom::Coordinate>; 00103 for (Osmium::OSM::WayNodeList::const_iterator it = m_way_node_list->begin(); it != m_way_node_list->end(); ++it) { 00104 c->push_back(it->position()); 00105 } 00106 geos::geom::CoordinateSequence* cs = Osmium::Geometry::geos_geometry_factory()->getCoordinateSequenceFactory()->create(c); 00107 geos::geom::LinearRing* lr = Osmium::Geometry::geos_geometry_factory()->createLinearRing(cs); 00108 return static_cast<geos::geom::Geometry*>(Osmium::Geometry::geos_geometry_factory()->createPolygon(lr, NULL)); 00109 } catch (const geos::util::GEOSException& exc) { 00110 std::cerr << "error building polygon geometry, leave it as NULL\n"; 00111 return NULL; 00112 } 00113 } 00114 #endif // OSMIUM_WITH_GEOS 00115 00116 #ifdef OSMIUM_WITH_SHPLIB 00117 00123 SHPObject* create_shp_object() const { 00124 return create_line_or_polygon(SHPT_POLYGON); 00125 } 00126 #endif // OSMIUM_WITH_SHPLIB 00127 00128 #ifdef OSMIUM_WITH_OGR 00129 00134 OGRPolygon* create_ogr_geometry() const { 00135 OGRPolygon* p = new OGRPolygon(); 00136 OGRLinearRing* r = new OGRLinearRing(); 00137 for (Osmium::OSM::WayNodeList::const_reverse_iterator it = m_way_node_list->rbegin(); it != m_way_node_list->rend(); ++it) { 00138 r->addPoint(it->lon(), it->lat()); 00139 } 00140 p->addRingDirectly(r); 00141 return p; 00142 } 00143 #endif // OSMIUM_WITH_OGR 00144 00145 #ifdef OSMIUM_WITH_JAVASCRIPT 00146 v8::Local<v8::Object> js_instance() const { 00147 return JavascriptTemplate::get<JavascriptTemplate>().create_instance((void *)this); 00148 } 00149 00150 v8::Handle<v8::Value> js_to_array(const v8::Arguments& /*args*/) { 00151 v8::HandleScope scope; 00152 v8::Local<v8::Array> polygon = v8::Array::New(1); 00153 v8::Local<v8::Array> linear_ring = v8::Array::New(m_way_node_list->size()); 00154 polygon->Set(0, linear_ring); 00155 unsigned int max = m_way_node_list->size() - 1; 00156 if (m_reverse) { 00157 for (unsigned int i=0; i <= max; ++i) { 00158 linear_ring->Set(max - i, (*m_way_node_list)[i].position().js_to_array()); 00159 } 00160 } else { 00161 for (unsigned int i=0; i <= max; ++i) { 00162 linear_ring->Set(i, (*m_way_node_list)[i].position().js_to_array()); 00163 } 00164 } 00165 return scope.Close(polygon); 00166 } 00167 00168 struct JavascriptTemplate : public Osmium::Geometry::Geometry::JavascriptTemplate { 00169 00170 JavascriptTemplate() : Osmium::Geometry::Geometry::JavascriptTemplate() { 00171 js_template->Set("toArray", v8::FunctionTemplate::New(function_template<Polygon, &Polygon::js_to_array>)); 00172 } 00173 00174 }; 00175 #endif // OSMIUM_WITH_JAVASCRIPT 00176 00177 }; // class Polygon 00178 00179 } // namespace Geometry 00180 00181 } // namespace Osmium 00182 00183 #ifdef OSMIUM_WITH_JAVASCRIPT 00184 v8::Handle<v8::Value> Osmium::OSM::Way::js_polygon_geom() const { 00185 if (m_node_list.has_position() && m_node_list.is_closed()) { 00186 Osmium::Geometry::Polygon* geom = new Osmium::Geometry::Polygon(*this); 00187 return Osmium::Javascript::Template::get<Osmium::Geometry::Polygon::JavascriptTemplate>().create_persistent_instance<Osmium::Geometry::Polygon>(geom); 00188 } else { 00189 Osmium::Geometry::Null* geom = new Osmium::Geometry::Null(); 00190 return Osmium::Javascript::Template::get<Osmium::Geometry::Null::JavascriptTemplate>().create_persistent_instance<Osmium::Geometry::Null>(geom); 00191 } 00192 } 00193 #endif // OSMIUM_WITH_JAVASCRIPT 00194 00195 #endif // OSMIUM_GEOMETRY_POLYGON_HPP