Revision: 7780
          http://playerstage.svn.sourceforge.net/playerstage/?rev=7780&view=rev
Author:   thjc
Date:     2009-06-04 06:24:20 +0000 (Thu, 04 Jun 2009)

Log Message:
-----------
added initial playerwkb version, currently disabled in top level lists file as 
it doesnt build

Modified Paths:
--------------
    code/player/trunk/CMakeLists.txt

Added Paths:
-----------
    code/player/trunk/libplayerwkb/
    code/player/trunk/libplayerwkb/CMakeLists.txt
    code/player/trunk/libplayerwkb/playerwkb.c
    code/player/trunk/libplayerwkb/playerwkb.h

Modified: code/player/trunk/CMakeLists.txt
===================================================================
--- code/player/trunk/CMakeLists.txt    2009-06-04 00:42:45 UTC (rev 7779)
+++ code/player/trunk/CMakeLists.txt    2009-06-04 06:24:20 UTC (rev 7780)
@@ -60,6 +60,7 @@
 ADD_SUBDIRECTORY (libplayercore)
 ADD_SUBDIRECTORY (libplayerxdr)
 ADD_SUBDIRECTORY (config)           # Example config files
+#ADD_SUBDIRECTORY (libplayerwkb)
 ADD_SUBDIRECTORY (libplayerjpeg)
 ADD_SUBDIRECTORY (libplayertcp)
 ADD_SUBDIRECTORY (libplayersd)

Added: code/player/trunk/libplayerwkb/CMakeLists.txt
===================================================================
--- code/player/trunk/libplayerwkb/CMakeLists.txt                               
(rev 0)
+++ code/player/trunk/libplayerwkb/CMakeLists.txt       2009-06-04 06:24:20 UTC 
(rev 7780)
@@ -0,0 +1,8 @@
+SET (playerwkbSrcs playerwkb.c)
+PLAYER_ADD_LIBRARY (playerwkb ${playerwkbSrcs})
+PLAYER_INSTALL_HEADERS (playerwkb playerwkb.h)
+
+IF (HAVE_GEOS)
+    TARGET_LINK_LIBRARIES (playerwkb geos_c)
+    PLAYERCORE_ADD_INT_LINK_LIB (geos_c)
+ENDIF (HAVE_GEOS)

Added: code/player/trunk/libplayerwkb/playerwkb.c
===================================================================
--- code/player/trunk/libplayerwkb/playerwkb.c                          (rev 0)
+++ code/player/trunk/libplayerwkb/playerwkb.c  2009-06-04 06:24:20 UTC (rev 
7780)
@@ -0,0 +1,319 @@
+#include "playerwkb.h"
+#include <playerconfig.h> /* this also includes <stdint.h> if needed for types 
like uint8_t */
+#include <libplayercore/error.h>
+#include <stddef.h>
+
+#ifdef HAVE_GEOS
+
+#ifndef GEOS_VERSION_MAJOR
+#include <geos_c.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int geosinit_done = 0;
+
+/** Dummy function passed as a function pointer GEOS when it is initialised. 
GEOS uses this for logging. */
+void player_wkb_geosprint(const char * format, ...)
+{
+  va_list ap;
+  va_start(ap, format);
+  fprintf(stderr, "GEOSError: ");
+  vfprintf(stderr,format, ap);
+  fflush(stderr);
+  va_end(ap);
+};
+
+#else
+
+#include <string.h>
+
+#define WKB_POINT 1
+#define WKB_LINESTRING 2
+#define WKB_POLYGON 3
+#define WKB_MULTIPOINT 4
+#define WKB_MULTILINESTRING 5
+#define WKB_MULTIPOLYGON 6
+#define WKB_GEOMETRYCOLLECTION 7
+
+int player_wkb_endians_detect(struct PlayerWKBEndians * endians)
+{
+  int ui32_one = 1;
+  double dbl_one = 1.0;
+  uint8_t uint32_one_be[] = { 0, 0, 0, 1 };
+  uint8_t uint32_one_le[] = { 1, 0, 0, 0 };
+  uint8_t dbl_one_be[] = { 0x3f, 0xf0, 0, 0, 0, 0, 0, 0 };
+  uint8_t dbl_one_le[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x3f };
+  const uint8_t * bytes;
+
+  memset(endians, 0, sizeof(struct PlayerWKBEndians));
+  if (sizeof(double) != 8)
+  {
+    PLAYER_ERROR("incompatible size of double");
+    return -1;
+  }
+  if (sizeof(uint32_t) != 4)
+  {
+    PLAYER_ERROR("incompatible size of uint32_t");
+    return -1;
+  }
+  bytes = (uint8_t *)(&ui32_one);
+  if (!memcmp(uint32_one_be, bytes, sizeof(uint32_t)))
+  {
+    endians->uint32_endians = player_wkb_big;
+  } else if (!memcmp(uint32_one_le, bytes, sizeof(uint32_t)))
+  {
+    endians->uint32_endians = player_wkb_little;
+  } else
+  {
+    PLAYER_ERROR("unknown integer endians");
+    return -1;
+  }
+  bytes = (uint8_t *)(&dbl_one);
+  if (!memcmp(dbl_one_be, bytes, sizeof(double)))
+  {
+    endians->dbl_endians = player_wkb_big;
+  } else if (!memcmp(dbl_one_le, bytes, sizeof(double)))
+  {
+    endians->dbl_endians = player_wkb_little;
+  } else
+  {
+    PLAYER_ERROR("unknown double precision endians");
+    return -1;
+  }
+  return 0;
+}
+
+#endif
+
+playerwkbprocessor_t player_wkb_create_processor()
+{
+#ifdef HAVE_GEOS
+  return initGEOS_r(player_wkb_geosprint, player_wkb_geosprint);
+#else
+  return NULL;
+#endif
+}
+
+void player_wkb_destroy_processor(playerwkbprocessor_t wkbprocessor)
+{
+#ifdef HAVE_GEOS
+  finishGEOS_r(wkbprocessor);
+#endif
+}
+
+#ifdef HAVE_GEOS
+
+void player_wkb_process_geom(playerwkbprocessor_t wkbprocessor, const 
GEOSGeometry * geom, void (* callback)(void *, double, double, double, double), 
void * ptr)
+{
+  double x0, y0, x1, y1;
+  const GEOSCoordSequence * seq;
+  size_t numcoords;
+  int i;
+
+  switch (GEOSGeomTypeId_r((GEOSContextHandle_t)wkbprocessor, geom))
+  {
+  case GEOS_POINT:
+    seq = GEOSGeom_getCoordSeq_r((GEOSContextHandle_t)wkbprocessor, geom);
+    if (!seq)
+    {
+      PLAYER_ERROR("Invalid coordinate sequence");
+      return;
+    }
+    GEOSCoordSeq_getX(seq, 0, &x0);
+    GEOSCoordSeq_getY(seq, 0, &y0);
+    callback(ptr, x0 - 0.1, y0, x0 + 0.1, y0);
+    break;
+  case GEOS_LINESTRING:
+  case GEOS_LINEARRING:
+    seq = GEOSGeom_getCoordSeq_r((GEOSContextHandle_t)wkbprocessor, geom);
+    if (GEOSCoordSeq_getSize_r((GEOSContextHandle_t)wkbprocessor, seq, 
(unsigned int *)(&numcoords)))
+    {
+      if (numcoords > 0)
+      {
+        GEOSCoordSeq_getX_r((GEOSContextHandle_t)wkbprocessor, seq, 0, &x1);
+       GEOSCoordSeq_getY_r((GEOSContextHandle_t)wkbprocessor, seq, 0, &y1);
+        if (numcoords < 2)
+        {
+          callback(ptr, x1 - 0.1, y1, x1 + 0.1, y1);
+          callback(ptr, x1, y1 - 0.1, x1, y1 + 0.1);
+
+        } else for (i = 0; i < (signed)numcoords; i++)
+        {
+          x0 = x1;
+          y0 = y1;
+          GEOSCoordSeq_getX_r((GEOSContextHandle_t)wkbprocessor, seq, i, &x1);
+          GEOSCoordSeq_getY_r((GEOSContextHandle_t)wkbprocessor, seq, i, &y1);
+         callback(ptr, x0, y0, x1, y1);
+        }
+      }
+    }
+    break;
+  case GEOS_POLYGON:
+    player_wkb_process_geom(wkbprocessor, 
GEOSGetExteriorRing_r((GEOSContextHandle_t)wkbprocessor, geom), callback, ptr);
+    numcoords = GEOSGetNumInteriorRings_r((GEOSContextHandle_t)wkbprocessor, 
geom);
+    for (i = 0; i < (signed)numcoords; i++) 
player_wkb_process_geom(wkbprocessor, 
GEOSGetInteriorRingN_r((GEOSContextHandle_t)wkbprocessor, geom, i), callback, 
ptr);
+    break;
+  case GEOS_MULTIPOINT:
+  case GEOS_MULTILINESTRING:
+  case GEOS_MULTIPOLYGON:
+  case GEOS_GEOMETRYCOLLECTION:
+    numcoords = GEOSGetNumGeometries_r((GEOSContextHandle_t)wkbprocessor, 
geom);
+    for (i = 0; i < (signed)numcoords; i++) 
player_wkb_process_geom(wkbprocessor, 
GEOSGetGeometryN_r((GEOSContextHandle_t)wkbprocessor, geom, i), callback, ptr);
+    break;
+  default:
+    PLAYER_WARN("unknown feature type!");
+  }
+}
+
+#endif
+
+const uint8_t * player_wkb_process_wkb(playerwkbprocessor_t wkbprocessor, 
const uint8_t * wkb, size_t wkb_count, void (* callback)(void *, double, 
double, double, double), void * ptr)
+{
+#ifdef HAVE_GEOS
+
+  GEOSGeometry * geom;
+
+  if (!wkb)
+  {
+    PLAYER_ERROR("NULL wkb");
+    return NULL;
+  }
+  geom = GEOSGeomFromWKB_buf_r((GEOSContextHandle_t)wkbprocessor, wkb, 
wkb_count);
+  if (!geom)
+  {
+    PLAYER_ERROR("cannot read wkb");
+    return NULL;
+  }
+  player_wkb_process_geom(wkbprocessor, geom, callback, ptr);
+  GEOSGeom_destroy_r((GEOSContextHandle_t)wkbprocessor, geom);
+  return wkb + wkb_count;
+
+#else
+
+  double x0, y0, x1, y1;
+  struct PlayerWKBEndians endians;
+  uint32_t numcoords, numrings;
+  int i, j;
+  uint32_t type;
+  enum player_wkb_endians wkb_endians;
+
+#define UINT_FROM_WKB(dst) do \
+{ \
+  if (wkb_endians == (endians.uint32_endians)) memcpy((dst), wkb, 4); \
+  else \
+  { \
+    ((uint8_t *)(dst))[0] = wkb[(4 - 1) - 0]; \
+    ((uint8_t *)(dst))[1] = wkb[(4 - 1) - 1]; \
+    ((uint8_t *)(dst))[2] = wkb[(4 - 1) - 2]; \
+    ((uint8_t *)(dst))[3] = wkb[(4 - 1) - 3]; \
+  } \
+  wkb += 4; \
+} while (0)
+
+#define DBL_FROM_WKB(dst) do \
+{ \
+  if (wkb_endians == (endians.dbl_endians)) memcpy((dst), wkb, 8); \
+  else \
+  { \
+    ((uint8_t *)(dst))[0] = wkb[(8 - 1) - 0]; \
+    ((uint8_t *)(dst))[1] = wkb[(8 - 1) - 1]; \
+    ((uint8_t *)(dst))[2] = wkb[(8 - 1) - 2]; \
+    ((uint8_t *)(dst))[3] = wkb[(8 - 1) - 3]; \
+    ((uint8_t *)(dst))[4] = wkb[(8 - 1) - 4]; \
+    ((uint8_t *)(dst))[5] = wkb[(8 - 1) - 5]; \
+    ((uint8_t *)(dst))[6] = wkb[(8 - 1) - 6]; \
+    ((uint8_t *)(dst))[7] = wkb[(8 - 1) - 7]; \
+  } \
+  wkb += 8; \
+} while (0)
+
+  wkbprocessor = wkbprocessor;
+  wkb_count = wkb_count;
+  if (!wkb)
+  {
+    PLAYER_ERROR("NULL wkb");
+    return NULL;
+  }
+  if (player_wkb_endians_detect(&endians)) return NULL;
+  wkb_endians = (enum player_wkb_endians)(wkb[0]); wkb++;
+  if ((wkb_endians != player_wkb_big) && (wkb_endians != player_wkb_little))
+  {
+    PLAYER_ERROR1("invalid wkb: unknown endians, %d", wkb_endians);
+    return NULL;
+  }
+  UINT_FROM_WKB(&type);
+  switch (type)
+  {
+  case WKB_POINT:
+    DBL_FROM_WKB(&x0);
+    DBL_FROM_WKB(&y0);
+    callback(ptr, x0 - 0.1, y0, x0 + 0.1, y0);
+    callback(ptr, x0, y0 - 0.1, x0, y0 + 0.1);
+    break;
+  case WKB_LINESTRING:
+    UINT_FROM_WKB(&numcoords);
+    if (numcoords > 0)
+    {
+      DBL_FROM_WKB(&x1);
+      DBL_FROM_WKB(&y1);
+      if (numcoords < 2)
+      {
+        callback(ptr, x1 - 0.1, y1, x1 + 0.1, y1);
+        callback(ptr, x1, y1 - 0.1, x1, y1 + 0.1);
+      } else for (i = 1; i < ((signed)(numcoords)); i++)
+      {
+       x0 = x1;
+       y0 = y1;
+       DBL_FROM_WKB(&x1);
+       DBL_FROM_WKB(&y1);
+       callback(ptr, x0, y0, x1, y1);
+      }
+    }
+    break;
+  case WKB_POLYGON:
+    UINT_FROM_WKB(&numrings);
+    for (i = 0; i < (signed)(numrings); i++)
+    {
+      UINT_FROM_WKB(&numcoords);
+      if (numcoords > 0)
+      {
+       DBL_FROM_WKB(&x1);
+       DBL_FROM_WKB(&y1);
+       if (numcoords < 2)
+       {
+          callback(ptr, x1 - 0.1, y1, x1 + 0.1, y1);
+         callback(ptr, x1, y1 - 0.1, x1, y1 + 0.1);
+       } else for (j = 1; j < (signed)(numcoords); j++)
+       {
+         x0 = x1;
+         y0 = y1;
+         DBL_FROM_WKB(&x1);
+         DBL_FROM_WKB(&y1);
+         callback(ptr, x0, y0, x1, y1);
+       }
+      }
+    }
+    break;
+  case WKB_MULTIPOINT:
+  case WKB_MULTILINESTRING:
+  case WKB_MULTIPOLYGON:
+  case WKB_GEOMETRYCOLLECTION:
+    UINT_FROM_WKB(&numrings);
+    for (i = 0; i < (signed)(numrings); i++)
+    {
+      wkb = player_wkb_process_wkb(wkb, callback, ptr);
+      if (!wkb) return NULL;
+    }
+    break;
+  default:
+    PLAYER_WARN("unknown wkb feature type!");
+    return NULL;
+  }
+  return wkb;
+#undef UINT_FROM_WKB
+#undef DBL_FROM_WKB
+
+#endif
+}

Added: code/player/trunk/libplayerwkb/playerwkb.h
===================================================================
--- code/player/trunk/libplayerwkb/playerwkb.h                          (rev 0)
+++ code/player/trunk/libplayerwkb/playerwkb.h  2009-06-04 06:24:20 UTC (rev 
7780)
@@ -0,0 +1,43 @@
+#ifndef __PLAYER_WKB_H
+#define __PLAYER_WKB_H
+
+#include <playerconfig.h> /* this also includes <stdint.h> if needed for types 
like uint8_t */
+
+#ifdef HAVE_GEOS
+
+#ifndef GEOS_VERSION_MAJOR
+#include <geos_c.h>
+#endif
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_GEOS
+
+typedef GEOSContextHandle_t playerwkbprocessor_t;
+
+#else
+
+typedef void * playerwkbprocessor_t;
+
+enum player_wkb_endians { player_wkb_big = 0, player_wkb_little = 1 };
+
+struct PlayerWKBEndians
+{
+  enum player_wkb_endians uint32_endians, dbl_endians;
+};
+
+#endif
+
+playerwkbprocessor_t player_wkb_create_processor();
+void player_wkb_destroy_processor(playerwkbprocessor_t wkbprocessor);
+const uint8_t * player_wkb_process_wkb(playerwkbprocessor_t wkbprocessor, 
const uint8_t * wkb, size_t wkb_count, void (* callback)(void *, double, 
double, double, double), void * ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises 
looking to deploy the next generation of Solaris that includes the latest 
innovations from Sun and the OpenSource community. Download a copy and 
enjoy capabilities such as Networking, Storage and Virtualization. 
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to