#if defined MYDDAS_MYSQL #include #include #include "Yap.h" #include #include "myddas_wkb.h" #include "myddas_wkb2prolog.h" static void readswap4(uint32 *buf); static void readswap8(double *buf); static byte get_hostbyteorder(void); static byte get_inbyteorder(void); static uint32 get_wkbType(void); static Term get_point(char *functor); static Term get_linestring(char *functor); static Term get_polygon(char *functor); static Term get_geometry(uint32 type); static int swaporder; static byte inbyteorder, hostbyteorder; static byte *cursor; Term wkb2prolog(char *wkb) { uint32 type; cursor = wkb; /*ignore the SRID 4 bytes*/ cursor += 4; /*byteorder*/ hostbyteorder = get_hostbyteorder(); inbyteorder = get_inbyteorder(); swaporder = 0; if ( hostbyteorder != inbyteorder ) swaporder = 1; type = get_wkbType(); return get_geometry(type); } static byte get_hostbyteorder(void){ uint16_t host = 5; uint16_t net; net = htons(host); if ( net == host ) return(WKBXDR); else return(WKBNDR); } static byte get_inbyteorder(void){ byte b = cursor[0]; if (b != WKBNDR && b != WKBXDR) { fprintf(stderr, "Unknown byteorder: %d\n",b); exit(0); } cursor++; return(b); } static uint32 get_wkbType(void){ uint32 u; /* read the type */ readswap4(&u); if (u > WKBMAXTYPE || u < WKBMINTYPE) { fprintf(stderr, "Unknown type: %d\n",u); exit(0); } return(u); } static void readswap4(uint32 *buf){ ((byte *) buf)[0] = cursor[0]; ((byte *) buf)[1] = cursor[1]; ((byte *) buf)[2] = cursor[2]; ((byte *) buf)[3] = cursor[3]; if ( swaporder ) { if ( inbyteorder == WKBXDR ) { *buf = (uint32)ntohl((u_long)*buf); } else { byte u[4]; u[0] = ((byte *) buf)[3]; u[1] = ((byte *) buf)[2]; u[2] = ((byte *) buf)[1]; u[3] = ((byte *) buf)[0]; ((byte *) buf)[0] = u[0]; ((byte *) buf)[1] = u[1]; ((byte *) buf)[2] = u[2]; ((byte *) buf)[3] = u[3]; } } cursor += 4; } static void readswap8(double *buf) { ((byte *) buf)[0] = cursor[0]; ((byte *) buf)[1] = cursor[1]; ((byte *) buf)[2] = cursor[2]; ((byte *) buf)[3] = cursor[3]; ((byte *) buf)[4] = cursor[4]; ((byte *) buf)[5] = cursor[5]; ((byte *) buf)[6] = cursor[6]; ((byte *) buf)[7] = cursor[7]; if ( swaporder ) { if ( inbyteorder == WKBXDR ) { u_long u[2]; u[0] = ((u_long *) buf)[0]; u[1] = ((u_long *) buf)[1]; ((u_long *) buf)[1] = ntohl(u[0]); ((u_long *) buf)[0] = ntohl(u[1]); } else { byte u[8]; u[0] = ((byte *) buf)[7]; u[1] = ((byte *) buf)[6]; u[2] = ((byte *) buf)[5]; u[3] = ((byte *) buf)[4]; u[4] = ((byte *) buf)[3]; u[5] = ((byte *) buf)[2]; u[6] = ((byte *) buf)[1]; u[7] = ((byte *) buf)[0]; ((byte *) buf)[0] = u[0]; ((byte *) buf)[1] = u[1]; ((byte *) buf)[2] = u[2]; ((byte *) buf)[3] = u[3]; ((byte *) buf)[4] = u[4]; ((byte *) buf)[5] = u[5]; ((byte *) buf)[6] = u[6]; ((byte *) buf)[7] = u[7]; } } cursor += 8; } static Term get_point(char *func){ Term args[2]; Functor functor; double d; if(func == NULL) /*functor "," => (_,_)*/ functor = Yap_MkFunctor(Yap_LookupAtom(","), 2); else functor = Yap_MkFunctor(Yap_LookupAtom(func), 2); /* read the X */ readswap8(&d); args[0] = MkFloatTerm(d); /* read the Y */ readswap8(&d); args[1] = MkFloatTerm(d); return Yap_MkApplTerm(functor, 2, args); } static Term get_linestring(char *func){ CACHE_REGS Term *c_list; Term list; Functor functor; uint32 n; int i; /* read the number of vertices */ readswap4(&n); /* space for arguments */ c_list = (Term *) calloc(sizeof(Term),n); for ( i = 0; i < n; i++) { c_list[i] = get_point(NULL); } list = MkAtomTerm(Yap_LookupAtom("[]")); for (i = n - 1; i >= 0; i--) { list = MkPairTerm(c_list[i],list); } if(func == NULL) return list; else{ functor = Yap_MkFunctor(Yap_LookupAtom(func), 1); return Yap_MkApplTerm(functor, 1, &list); } } static Term get_polygon(char *func){ CACHE_REGS uint32 r; int i; Functor functor; Term *c_list; Term list; /* read the number of rings */ readswap4(&r); /* space for rings */ c_list = (Term *) calloc(sizeof(Term),r); for ( i = 0; i < r; i++ ) { c_list[i] = get_linestring(NULL); } list = MkAtomTerm(Yap_LookupAtom("[]")); for (i = r - 1; i >= 0; i--) { list = MkPairTerm(c_list[i],list); } if(func == NULL) return list; else{ functor = Yap_MkFunctor(Yap_LookupAtom("polygon"), 1); return Yap_MkApplTerm(functor, 1, &list); } } static Term get_geometry(uint32 type){ CACHE_REGS switch(type) { case WKBPOINT: return get_point("point"); case WKBLINESTRING: return get_linestring("linestring"); case WKBPOLYGON: return get_polygon("polygon"); case WKBMULTIPOINT: { byte b; uint32 n, u; int i; Functor functor; Term *c_list; Term list; /* read the number of points */ readswap4(&n); /* space for points */ c_list = (Term *) calloc(sizeof(Term),n); for ( i = 0; i < n; i++ ) { /* read (and ignore) the byteorder and type */ b = get_inbyteorder(); u = get_wkbType(); c_list[i] = get_point(NULL); } list = MkAtomTerm(Yap_LookupAtom("[]")); for (i = n - 1; i >= 0; i--) { list = MkPairTerm(c_list[i],list); } functor = Yap_MkFunctor(Yap_LookupAtom("multipoint"), 1); return Yap_MkApplTerm(functor, 1, &list); } case WKBMULTILINESTRING: { byte b; uint32 n, u; int i; Functor functor; Term *c_list; Term list; /* read the number of polygons */ readswap4(&n); /* space for polygons*/ c_list = (Term *) calloc(sizeof(Term),n); for ( i = 0; i < n; i++ ) { /* read (and ignore) the byteorder and type */ b = get_inbyteorder(); u = get_wkbType(); c_list[i] = get_linestring(NULL); } list = MkAtomTerm(Yap_LookupAtom("[]")); for (i = n - 1; i >= 0; i--) { list = MkPairTerm(c_list[i],list); } functor = Yap_MkFunctor(Yap_LookupAtom("multilinestring"), 1); return Yap_MkApplTerm(functor, 1, &list); } case WKBMULTIPOLYGON: { byte b; uint32 n, u; int i; Functor functor; Term *c_list; Term list; /* read the number of polygons */ readswap4(&n); /* space for polygons*/ c_list = (Term *) calloc(sizeof(Term),n); for ( i = 0; i < n; i++ ) { /* read (and ignore) the byteorder and type */ b = get_inbyteorder(); u = get_wkbType(); c_list[i] = get_polygon(NULL); } list = MkAtomTerm(Yap_LookupAtom("[]")); for (i = n - 1; i >= 0; i--) { list = MkPairTerm(c_list[i],list); } functor = Yap_MkFunctor(Yap_LookupAtom("multipolygon"), 1); return Yap_MkApplTerm(functor, 1, &list); } case WKBGEOMETRYCOLLECTION: { byte b; uint32 n; int i; Functor functor; Term *c_list; Term list; /* read the number of geometries */ readswap4(&n); /* space for geometries*/ c_list = (Term *) calloc(sizeof(Term),n); for ( i = 0; i < n; i++ ) { b = get_inbyteorder(); c_list[i] = get_geometry(get_wkbType()); } list = MkAtomTerm(Yap_LookupAtom("[]")); for (i = n - 1; i >= 0; i--) { list = MkPairTerm(c_list[i],list); } functor = Yap_MkFunctor(Yap_LookupAtom("geometrycollection"), 1); return Yap_MkApplTerm(functor, 1, &list); } } return MkAtomTerm(Yap_LookupAtom("[]")); } #endif /*MYDDAS_MYSQL*/