387 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			387 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);
 | 
						|
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*/
 |