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