[postgis-devel] PostGIS RC1/2 and QGIS
strk at refractions.net
strk at refractions.net
Wed Feb 9 03:31:46 PST 2005
Some contextual infos and a tester program.
PostGIS-0.x used WKB as output from asbinary().
PostGIS-1.x uses plain bytea output.
The internal representation of 0.x WKB type (now obsoleted)
was OGC WKB + 3d extension.
When compiled against PostgreSQL > 73 the PostGIS-0.x WKB type has
a send function converting WKB to bytea.
Before PGSQL 73 the send function was implicitly a dump of the
internal representation.
Basically both layouts should work in the same way, as the WKB->bytea
converter does nothing but change the tag.
Attached is a small C code to test equality of binary result
of the query "asbinary(force_2d(force_collection(geom)))" from
two databases. You set appropriate environmental variables
and call it as:
$ wkbtest mytable the_geom db1 db2
The program will fetch all records from the two db and compare them.
You can optionally specify an ordering column, if required:
$ wkbtest mytable the_geom db1 db2 id
Please report any mismatch.
--strk;
On Wed, Feb 09, 2005 at 10:33:45AM +0100, strk at refractions.net wrote:
> On Tue, Feb 08, 2005 at 06:53:44PM -0900, Gary Sherman wrote:
> > The latest release candidates of PostGIS do not work with QGIS.
> > Currently we use a binary cursor, using the asbinary function to fetch
> > the features. I took a quick look around and didn't find any
> > documentation on the changes in lwgeom and the appropriate way to read
> > features.
> >
> > Can anyone point me to a document or give me a hint?
>
> Can you give *us* an hint ?
> We're hunting exactly this bug. Reports are multipolygons
> work while polygons don't. Can you confirm this ?
> Can you provide sample data exploiting the bug ?
>
> TIA
>
> --strk;
>
> >
> > Thanks,
> > -gary
>
>
>
> > _______________________________________________
> > postgis-devel mailing list
> > postgis-devel at postgis.refractions.net
> > http://postgis.refractions.net/mailman/listinfo/postgis-devel
>
> _______________________________________________
> postgis-devel mailing list
> postgis-devel at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-devel
-------------- next part --------------
#include <stdlib.h>
#include <stdio.h>
#include "libpq-fe.h"
Oid
find_geometry_oid(PGconn *conn)
{
Oid oid;
PGresult *res;
res = PQexec(conn,
"select oid from pg_type where typname = 'geometry'");
if ( PQresultStatus(res) != PGRES_TUPLES_OK )
{
fprintf(stderr, "%s", PQerrorMessage(conn));
exit(1);
}
oid = atoi(PQgetvalue(res, 0, 0));
PQclear(res);
}
char *
hexify(unsigned char *wkb, size_t len)
{
static char *buf=NULL;
static size_t bufsize=0;
const char hexchar[] = {"0123456789ABCDEF"};
char *ptr;
int i;
if ( len*2+2 > bufsize ) {
bufsize=len*2+2;
buf = realloc(buf, bufsize);
}
ptr=buf;
for (i=0; i<len; i++)
{
*ptr++=hexchar[wkb[i]>>4];
*ptr++=hexchar[wkb[i]&0x0F];
}
*ptr='\0';
return buf;
}
void
checkfetch(PGresult *res, PGconn *conn, int num)
{
if ( PQresultStatus(res) != PGRES_TUPLES_OK )
{
printf("%s: %s\n", PQdb(conn), PQerrorMessage(conn));
exit(0);
}
if ( ! PQbinaryTuples(res) )
{
printf("%s: No binary tuples\n", PQdb(conn));
exit(0);
}
if ( PQntuples(res) < 1)
{
// terminating condition
exit(0);
}
}
void
checkdeclare(PGresult *res, PGconn *conn)
{
if ( PQresultStatus(res) != PGRES_COMMAND_OK )
{
printf("%s: %s\n", PQdb(conn), PQerrorMessage(conn));
exit(0);
}
}
int
main(int argc, char **argv)
{
PGconn *conn1;
PGconn *conn2;
PGresult *res1, *res2;
int i;
char *wkb1, *wkb2;
size_t len1, len2;
char connstr1[256], connstr2[256];
char query[512];
if ( argc < 5 ) {
fprintf(stderr, "Usage: %s <table> <geom_col> <hwgeomdb> <lwgeomdb> [<order_col>]\n",
argv[0]);
exit(1);
}
if ( argc == 5 )
{
snprintf(query, 511, "DECLARE a BINARY CURSOR FOR SELECT asbinary(force_2d(force_collection(%s))) FROM %s", argv[2], argv[1]);
}
else
{
snprintf(query, 511, "DECLARE a BINARY CURSOR FOR SELECT asbinary(force_2d(force_collection(%s))) FROM %s ORDER BY %s", argv[2], argv[1], argv[5]);
}
snprintf(connstr1, 255, "dbname=%s", argv[3]);
snprintf(connstr2, 255, "dbname=%s", argv[4]);
conn1 = PQconnectdb(connstr1);
if ( PQstatus(conn1) != CONNECTION_OK ) {
fprintf(stderr, "Connection ERROR: %s", PQerrorMessage(conn1));
exit(1);
}
conn2 = PQconnectdb(connstr2);
if ( PQstatus(conn2) != CONNECTION_OK ) {
fprintf(stderr, "Connection ERROR: %s", PQerrorMessage(conn2));
exit(1);
}
PQexec(conn1, "BEGIN;");
res1=PQexec(conn1, query);
checkdeclare(res1, conn1);
PQclear(res1);
PQexec(conn2, "BEGIN;");
res2=PQexec(conn2, query);
checkdeclare(res2, conn2);
PQclear(res1);
for (i=0;;i++)
{
res1 = PQexec(conn1, "FETCH 1 FROM a");
res2 = PQexec(conn2, "FETCH 1 FROM a");
checkfetch(res1, conn1, 0);
checkfetch(res2, conn2, 0);
printf("[%d]\n", i);
if ( PQgetisnull(res1, 0, 0) != PQgetisnull(res2, 0, 0) )
{
printf("Both null\n");
continue;
}
len1 = PQgetlength(res1, 0, 0);
wkb1 = PQgetvalue(res1, 0, 0);
len2 = PQgetlength(res2, 0, 0);
wkb2 = PQgetvalue(res2, 0, 0);
if ( len1 != len2 || memcmp(wkb1, wkb2, len1) )
{
printf("Mismatch!\n");
printf("%s: %s\n", PQdb(conn1),
hexify(wkb1, len1));
printf("%s: %s\n", PQdb(conn2),
hexify(wkb2, len2));
exit(1);
}
printf("No diffs\n");
PQclear(res1);
PQclear(res2);
}
}
More information about the postgis-devel
mailing list