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