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