[odb-users] Mapping PostGIS POLYGON type

Weiss, Yoav yoav.weiss at intel.com
Wed Mar 30 08:16:14 EDT 2016


Thanks Alex for your help.

However, I still have an error when running odb with –s (generate schema). The Error I get is:
error: unknown PostgreSQL type 'GEOMETRY'

The definition I used is (which is the PostGIS syntax for a polygon):
  #pragma db type("GEOMETRY(POLYGON)")
  geos::geom::LinearRing m_geom;

Eventually, since I do want odb to generate the schema, I need the correct type and not a conversion from string.

Is that possible or should I create the schema myself?



From: Alexandre Pretyman [mailto:alexandre.pretyman at gmail.com]
Sent: Tuesday, March 29, 2016 18:37
To: Weiss, Yoav <yoav.weiss at intel.com>
Cc: odb-users at codesynthesis.com
Subject: Re: [odb-users] Mapping PostGIS POLYGON type

Hi Yoav,

If you are using GEOS, they will have Well Known Binary (WKB) conversion functions, so you will avoid the string conversion.

My little experience in this subject is using boost geometry, which only had Well Known Text (WKT) at the time.

But the work flow I've used with SpatiaLite is like this:

Create your member variable with the DB type of the geometry, in SpatiaLite is just called GEOMETRY, in PostGIS, if I recall correctly, it's the same.


using linear_ring = boost::geometry::model::ring<coordinate, true, true>;


class X {

// ...

#pragma db type("GEOMETRY")

linear_ring my_ring


};


Then you will create traits for that type, for you "geos::geom::Polygon" but here is "linear_ring", for the DB Type, my example is SQLite, but obviously you will need to do it in PostgreSQL, which the namespace for it is "pgsql" instead of the "sqlite" in the example below.

I used the WKT functions from Boost Geometry, you would use the WKB from GEOS (WKBReader & WKBWriter):


#pragma once



#include <limits>  // std::numeric_limits

#include <sstream>

#include <cstring> // std::memcpy



#include <boost/geometry/io/wkt/write.hpp>

#include <boost/geometry/io/wkt/read.hpp>



#include <odb/sqlite/traits.hxx>

namespace odb

{

  namespace sqlite

  {

    using linear_ring = boost::geometry::model::ring<coordinate, true, true>;


    template <>

    class value_traits<linear_ring, id_text>

    {

    public:

      typedef linear_ring value_type;

      typedef linear_ring query_type;

      typedef details::buffer image_type;



      static void

      set_value (linear_ring& v,

                 const details::buffer& b,

                 std::size_t n,

                 bool is_null)

      {

        if (is_null)

          v = linear_ring ();

        else

        {

          std::string wkt(b.data (), n);

          bg::read_wkt(wkt, v);

        }

      }



      static void

      set_image (details::buffer& b,

                 std::size_t& n,

                 bool& is_null,

                 const linear_ring& v)

      {

        is_null = false;

        std::ostringstream os;

        const std::string& s (os.str ());

        n = s.size ();



        if (n > b.capacity ())

          b.capacity (n);



        std::memcpy (b.data (), s.c_str (), n);

      }

    };

  }

}



Then you'll have to include those traits when persisting/loading the object.



It's best to have Boris validate those steps.



Good luck!



On 29 March 2016 at 09:22, Weiss, Yoav <yoav.weiss at intel.com<mailto:yoav.weiss at intel.com>> wrote:
I would like to use the PostGIS type polygon in my code, so my header will look like:

  #pragma db type("GEOMETRY(POLYGON)")
  geos::geom::Polygon* m_p_geom;

Is there a best known method to achieve this? What will be the most efficient implementation (trying to avoid conversions from/to strings)?

Yoav



---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.



--
Alexandre Pretyman
---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


More information about the odb-users mailing list