383 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			383 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | #if defined MYDDAS_MYSQL
 | ||
|  | 
 | ||
|  | #include <stdio.h>
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include "Yap.h"
 | ||
|  | #include <netinet/in.h>
 | ||
|  | #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 USES_REGS); | ||
|  | 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 USES_REGS){ | ||
|  |   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 PASS_REGS); | ||
|  |   } | ||
|  | 
 | ||
|  |   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" PASS_REGS); | ||
|  |   case WKBLINESTRING: | ||
|  |     return get_linestring("linestring"); | ||
|  |   case WKBPOLYGON: | ||
|  |     return get_polygon("polygon"); | ||
|  |   case WKBMULTIPOINT: | ||
|  |     { | ||
|  |       uint32 n; | ||
|  |       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 */ | ||
|  | 	get_inbyteorder(); | ||
|  | 	get_wkbType(); | ||
|  | 
 | ||
|  | 	c_list[i] = get_point(NULL PASS_REGS); | ||
|  |       } | ||
|  | 
 | ||
|  |       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: | ||
|  |     { | ||
|  |       uint32 n; | ||
|  |       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 */ | ||
|  | 	get_inbyteorder(); | ||
|  | 	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: | ||
|  |     { | ||
|  |       uint32 n; | ||
|  |       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 */ | ||
|  | 	get_inbyteorder(); | ||
|  | 	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: | ||
|  |     { | ||
|  |       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++ ) { | ||
|  | 	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*/
 |