Well you guessed right on all counts below. I will create the pull
request shortly. Hope it can make it into 3.2.2 

I hadn't seen your
support for boost geometry as binary, so I have basically done the same,
only outside of the boost scope and also less elegant than your
solution. Also I haven't found anywhere to put it on the web yet. So I
will just leave a couple of bits here if anybody is interested. Using
the code below in the proper soci namespace allow something as simple as
the following for your example: 

point0_t p0;

sql << "SELECT geom FROM
soci_geoms WHERE id=:id", into(p0), use(id);

sql << "INSERT INTO
soci_geoms(geom) VALUES(:geom)", use(p0);

The to_ewkb will also work
directly with PostgreSQL COPY or pg_bulkload 

Please notice the code
will not compile since other bits are missing. 

typedef
boost::geometry::model::ll::point<> position; 

template<> struct
type_conversion<geo::position>
{
 typedef std::string base_type;


static void from_base( base_type const & in, indicator ind,
geo::position & out )
 {
 if (ind == i_null)
 {
 out = geo::position();

}
 else
 {
 assert(from_ewkb(in,out));
 }
 }

 static void to_base(
geo::position const & in, base_type & out, indicator & ind )
 {
 if (
geo::is_valid(in) )
 {
 out = to_ewkb(in);
 ind = i_ok;
 }
 else
 {
 ind
= i_null;
 }
 }
}; 

bool from_ewkb(const std::string &_ewkb,
geo::position &_pos) // Hex formatted
{
 const size_t wkb_point_size =
sizeof(char)+sizeof(std::uint32_t)+2*sizeof(double);
 std::string binary
= from_hex(_ewkb);
 if (binary.length() < wkb_point_size) return false;
// some magic that we need to solve in a better way.
 const char *p1 =
binary.data();
 if(get_char(p1) != 1) return false;
 std::uint32_t type
= get_uint32(p1);
 if((type & 0x0000000f) != 1) return false;
 if((type
& 0x20000000) != 0)
 {
 if (binary.length() <
wkb_point_size+sizeof(std::uint32_t) || get_uint32(p1) != 4326 )
 return
false;
 }
 double lon = get_double(p1);
 double lat = get_double(p1);

if (lon < -180 || lon > 180 || lat < -90 || lat > 90) return false;

_pos = geo::position(geo::longitude<>(lon),geo::latitude<>(lat));

return true;
}

std::string to_ewkb(const geo::position &_input)
{

std::string result;
 char endian = 1;
 uint32_t type = 1; // 1 = POINT

result += endian;
 result.append((const char*)&type,sizeof(type));


result.append((const char*)&_input.lon(),sizeof(double));

result.append((const char*)&_input.lat(),sizeof(double));
 result =
to_hex(result);
 return result;
}

Den 2013-06-11 00:06, Mateusz Loskot
skrev: 

> On 10 June 2013 20:07, pba <p...@mailme.dk> wrote:
> 
>> I use
the Postgis quite a lot for a couple of projects.
> 
> Welcome to the
club :)
> 
>> In the backend/psotgresql/statement.cpp describe_column
function the typeoid is used for determining actual soci type. This
works fine for the built-in PostgreSQL types since the OID's are hard
coded. However for user defined types this will not work. As far as I
understand we are not guaranteed that they will remain static.
> 
> In
general, they are not guaranteed, but in practice, they usually work.
>
However, I agree it's that kind of assumption which is week.




Links:
------
[1]
https://github.com/mloskot/soci/tree/soci-type-binary
[2]
https://github.com/mloskot/soci/blob/soci-type-binary/src/core/boost-geometry.h
[3]
https://github.com/mloskot/soci/blob/soci-type-binary/src/examples/example1.cpp
[4]
https://github.com/mloskot/soci/blob/soci-type-binary/src/backends/postgresql/statement.cpp#L38
[5]
http://mateusz.loskot.net
[6] http://p.sf.net/sfu/windows-dev2dev
[7]
mailto:soci-devel@lists.sourceforge.net
[8]
https://lists.sourceforge.net/lists/listinfo/soci-devel
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
soci-devel mailing list
soci-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/soci-devel

Reply via email to