[postgis-commits] svn - r2815 - in trunk: . liblwgeom lwgeom
postgis-commits at postgis.refractions.net
postgis-commits at postgis.refractions.net
Sun Jun 29 12:11:50 PDT 2008
Author: mcayland
Date: 2008-06-29 12:11:48 -0700 (Sun, 29 Jun 2008)
New Revision: 2815
Added:
trunk/liblwgeom/
trunk/liblwgeom/Makefile.in
trunk/liblwgeom/box2d.c
trunk/liblwgeom/lex.yy.c
trunk/liblwgeom/liblwgeom.h
trunk/liblwgeom/lwcollection.c
trunk/liblwgeom/lwcompound.c
trunk/liblwgeom/lwcurve.c
trunk/liblwgeom/lwcurvepoly.c
trunk/liblwgeom/lwgeom.c
trunk/liblwgeom/lwgeom_api.c
trunk/liblwgeom/lwgparse.c
trunk/liblwgeom/lwgunparse.c
trunk/liblwgeom/lwline.c
trunk/liblwgeom/lwmcurve.c
trunk/liblwgeom/lwmline.c
trunk/liblwgeom/lwmpoint.c
trunk/liblwgeom/lwmpoly.c
trunk/liblwgeom/lwmsurface.c
trunk/liblwgeom/lwpoint.c
trunk/liblwgeom/lwpoly.c
trunk/liblwgeom/lwutil.c
trunk/liblwgeom/measures.c
trunk/liblwgeom/ptarray.c
trunk/liblwgeom/vsprintf.c
trunk/liblwgeom/wktparse.h
trunk/liblwgeom/wktparse.lex
trunk/liblwgeom/wktparse.tab.c
trunk/liblwgeom/wktparse.tab.h
trunk/liblwgeom/wktparse.y
Removed:
trunk/lwgeom/box2d.c
trunk/lwgeom/lex.yy.c
trunk/lwgeom/liblwgeom.c
trunk/lwgeom/liblwgeom.h
trunk/lwgeom/lwcollection.c
trunk/lwgeom/lwcompound.c
trunk/lwgeom/lwcurve.c
trunk/lwgeom/lwcurvepoly.c
trunk/lwgeom/lwgeom.c
trunk/lwgeom/lwgeom_api.c
trunk/lwgeom/lwgparse.c
trunk/lwgeom/lwline.c
trunk/lwgeom/lwmcurve.c
trunk/lwgeom/lwmline.c
trunk/lwgeom/lwmpoint.c
trunk/lwgeom/lwmpoly.c
trunk/lwgeom/lwmsurface.c
trunk/lwgeom/lwpoint.c
trunk/lwgeom/lwpoly.c
trunk/lwgeom/measures.c
trunk/lwgeom/ptarray.c
trunk/lwgeom/vsprintf.c
trunk/lwgeom/wktparse.h
trunk/lwgeom/wktparse.lex
trunk/lwgeom/wktparse.tab.c
trunk/lwgeom/wktparse.tab.h
trunk/lwgeom/wktparse.y
trunk/lwgeom/wktunparse.c
Modified:
trunk/GNUmakefile
trunk/configure.ac
trunk/lwgeom/Makefile.in
trunk/lwgeom/lwgeom_dump.c
trunk/lwgeom/lwgeom_functions_basic.c
trunk/lwgeom/lwgeom_geos_c.c
trunk/lwgeom/lwgeom_gist.c
trunk/lwgeom/lwgeom_inout.c
trunk/lwgeom/lwgeom_ogc.c
trunk/lwgeom/lwgeom_pg.c
trunk/lwgeom/lwgeom_pg.h
trunk/lwgeom/lwgeom_sqlmm.c
Log:
Split the basic geometry accessors into a separate static library liblwgeom.a; this potentially allows re-use of the liblwgeom functions from within PostGIS, or could be extended at a later date to include databases other than MySQL. This patch includes a change to the liblwgeom handler functions; instead of sprinkling init_pg_func()s around the source, I have changed the default liblwgeom handlers to make use of a callback to allow linked libraries to set their own handlers the first time any of them are called. I have also tidied up the parser API a little in liblwgeom.h, which means wktparse.h can be removed from all of the headers in the lwgeom/ directory, plus renamed wktunparse.c to lwgunparse.c to keep things similar to lwgparse.c. Finally, I renamed liblwgeom.c to lwutil.c to avoid confusion within the new interface. TODO: the liblwgeom Makefile has some gcc-specific options, but these can be fixed later - it seemed more important to make the warnings visible to developers.
Modified: trunk/GNUmakefile
===================================================================
--- trunk/GNUmakefile 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/GNUmakefile 2008-06-29 19:11:48 UTC (rev 2815)
@@ -4,13 +4,13 @@
#
#-----------------------------------------------------
-all: liblwgeom loaderdumper utils
+all: postgis loaderdumper utils
-install: all liblwgeom-install loaderdumper-install
+install: all postgis-install loaderdumper-install
-uninstall: liblwgeom-uninstall loaderdumper-uninstall docs-uninstall
+uninstall: postgis-uninstall loaderdumper-uninstall docs-uninstall
-clean: liblwgeom-clean loaderdumper-clean docs-clean test-clean
+clean: liblwgeom-clean postgis-clean loaderdumper-clean docs-clean test-clean
rm -f lwpostgis.sql lwpostgis_upgrade.sql
distclean: clean
@@ -35,16 +35,24 @@
test-clean:
$(MAKE) -C regress clean
-liblwgeom:
+liblwgeom/liblwgeom.a:
+ $(MAKE) -C liblwgeom
+
+liblwgeom: liblwgeom/liblwgeom.a
+
+liblwgeom-clean:
+ $(MAKE) -C liblwgeom clean
+
+postgis: liblwgeom/liblwgeom.a
$(MAKE) -C lwgeom
-liblwgeom-clean:
+postgis-clean:
$(MAKE) -C lwgeom clean
-liblwgeom-install:
+postgis-install:
$(MAKE) -C lwgeom install
-liblwgeom-uninstall:
+postgis-uninstall:
$(MAKE) -C lwgeom uninstall
loaderdumper:
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/configure.ac 2008-06-29 19:11:48 UTC (rev 2815)
@@ -357,5 +357,5 @@
dnl AC_MSG_RESULT([SHLIB_LINK: $SHLIB_LINK])
dnl Output the relevant files
-AC_OUTPUT([lwgeom/Makefile lwgeom/sqldefines.h loader/Makefile.pgsql2shp loader/Makefile.shp2pgsql regress/Makefile doc/Makefile])
+AC_OUTPUT([liblwgeom/Makefile lwgeom/Makefile lwgeom/sqldefines.h loader/Makefile.pgsql2shp loader/Makefile.shp2pgsql regress/Makefile doc/Makefile])
Added: trunk/liblwgeom/Makefile.in
===================================================================
--- trunk/liblwgeom/Makefile.in 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/Makefile.in 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,51 @@
+# **********************************************************************
+# * $Id: Makefile.in
+# *
+# * PostGIS - Spatial Types for PostgreSQL
+# * http://postgis.refractions.net
+# * Copyright 2008 Mark Cave-Ayland
+# *
+# * This is free software; you can redistribute and/or modify it under
+# * the terms of the GNU General Public Licence. See the COPYING file.
+# *
+# **********************************************************************
+
+CC=@CC@
+CFLAGS=@CFLAGS@ -Wall -Wmissing-prototypes -fPIC
+
+# Standalone LWGEOM objects
+SA_OBJS=measures.o \
+ box2d.o \
+ ptarray.o \
+ lwgeom_api.o \
+ lwgeom.o \
+ lwpoint.o \
+ lwline.o \
+ lwpoly.o \
+ lwmpoint.o \
+ lwmline.o \
+ lwmpoly.o \
+ lwcollection.o \
+ lwcurve.o \
+ lwcompound.o \
+ lwcurvepoly.o \
+ lwmcurve.o \
+ lwmsurface.o \
+ lwutil.o \
+ lwgunparse.o \
+ lwgparse.o \
+ wktparse.tab.o \
+ lex.yy.o \
+ vsprintf.o
+
+all: $(SA_OBJS)
+ ar rs liblwgeom.a $(SA_OBJS)
+
+clean:
+ rm -f $(SA_OBJS)
+ rm -f liblwgeom.a
+
+# Command to build each of the .o files
+$(SA_OBJS): %.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
Added: trunk/liblwgeom/box2d.c
===================================================================
--- trunk/liblwgeom/box2d.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/box2d.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "liblwgeom.h"
+
+#ifndef EPSILON
+#define EPSILON 1.0E-06
+#endif
+#ifndef FPeq
+#define FPeq(A,B) (fabs((A) - (B)) <= EPSILON)
+#endif
+
+
+/* Expand given box of 'd' units in all directions */
+void
+expand_box2d(BOX2DFLOAT4 *box, double d)
+{
+ box->xmin -= d;
+ box->ymin -= d;
+
+ box->xmax += d;
+ box->ymax += d;
+}
+
+
+/*
+ * This has been changed in PostGIS 1.1.2 to
+ * check exact equality of values (rather then using
+ * the FPeq macro taking into account coordinate drifts).
+ */
+char
+box2d_same(BOX2DFLOAT4 *box1, BOX2DFLOAT4 *box2)
+{
+ return( (box1->xmax==box2->xmax) &&
+ (box1->xmin==box2->xmin) &&
+ (box1->ymax==box2->ymax) &&
+ (box1->ymin==box2->ymin));
+#if 0
+ return(FPeq(box1->xmax, box2->xmax) &&
+ FPeq(box1->xmin, box2->xmin) &&
+ FPeq(box1->ymax, box2->ymax) &&
+ FPeq(box1->ymin, box2->ymin));
+#endif
+}
+
+BOX2DFLOAT4 *
+box2d_clone(const BOX2DFLOAT4 *in)
+{
+ BOX2DFLOAT4 *ret = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(ret, in, sizeof(BOX2DFLOAT4));
+ return ret;
+}
Added: trunk/liblwgeom/lex.yy.c
===================================================================
--- trunk/liblwgeom/lex.yy.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lex.yy.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,4562 @@
+#define yy_create_buffer lwg_parse_yy_create_buffer
+#define yy_delete_buffer lwg_parse_yy_delete_buffer
+#define yy_scan_buffer lwg_parse_yy_scan_buffer
+#define yy_scan_string lwg_parse_yy_scan_string
+#define yy_scan_bytes lwg_parse_yy_scan_bytes
+#define yy_flex_debug lwg_parse_yy_flex_debug
+#define yy_init_buffer lwg_parse_yy_init_buffer
+#define yy_flush_buffer lwg_parse_yy_flush_buffer
+#define yy_load_buffer_state lwg_parse_yy_load_buffer_state
+#define yy_switch_to_buffer lwg_parse_yy_switch_to_buffer
+#define yyin lwg_parse_yyin
+#define yyleng lwg_parse_yyleng
+#define yylex lwg_parse_yylex
+#define yyout lwg_parse_yyout
+#define yyrestart lwg_parse_yyrestart
+#define yytext lwg_parse_yytext
+#define yywrap lwg_parse_yywrap
+
+#line 20 "lex.yy.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+static yyconst short yy_nxt[][128] =
+ {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+ },
+
+ {
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+ 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
+ 9, 10, 6, 6, 11, 6, 6, 6, 12, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 13,
+ 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
+
+ 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
+ 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
+ 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
+ 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6
+ },
+
+ {
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+ 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
+
+ 9, 10, 6, 6, 11, 6, 6, 6, 12, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 13,
+ 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
+ 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
+ 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
+ 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
+ 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6
+ },
+
+ {
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+
+ 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
+ 9, 10, 6, 22, 11, 22, 23, 6, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 6, 13,
+ 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
+ 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
+ 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
+ 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
+
+ 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
+ 6, 6, 6, 6, 22, 6, 6, 6
+ },
+
+ {
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+ 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
+ 9, 10, 6, 22, 11, 22, 23, 6, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 6, 13,
+ 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
+ 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
+
+ 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
+ 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
+ 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
+ 6, 6, 6, 6, 22, 6, 6, 6
+ },
+
+ {
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
+ -5, -5, -5, -5, -5, -5, -5, -5
+ },
+
+ {
+ 5, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+
+ -6, -6, -6, -6, -6, -6, -6, -6
+ },
+
+ {
+ 5, -7, -7, -7, -7, -7, -7, -7, -7, 25,
+ 25, -7, -7, 25, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, 25, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7
+ },
+
+ {
+ 5, -8, -8, -8, -8, -8, -8, -8, -8, 25,
+ 25, -8, -8, 25, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, 25, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
+ -8, -8, -8, -8, -8, -8, -8, -8
+ },
+
+ {
+ 5, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9
+
+ },
+
+ {
+ 5, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -10, -10, -10, -10, -10
+ },
+
+ {
+ 5, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11
+ },
+
+ {
+ 5, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+
+ -12, -12, -12, -12, -12, -12, -12, -12, 26, 27,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12
+ },
+
+ {
+ 5, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13
+ },
+
+ {
+ 5, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14
+ },
+
+ {
+ 5, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+
+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+ -15, -15, -15, 28, -15, -15, -15, -15, -15, 29,
+ -15, -15, -15, -15, -15, 30, -15, -15, -15, -15,
+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
+ -15, -15, -15, -15, -15, 28, -15, -15, -15, -15,
+ -15, 29, -15, -15, -15, -15, -15, 30, -15, -15,
+ -15, -15, -15, -15, -15, -15, -15, -15
+ },
+
+ {
+ 5, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, 31, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, 31,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+
+ -16, -16, -16, -16, -16, -16, -16, -16
+ },
+
+ {
+ 5, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, 32,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, 32, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17
+ },
+
+ {
+ 5, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, 33, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, 33, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18
+ },
+
+ {
+ 5, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, 34, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, 34, -19, -19,
+ -19, -19, -19, -19, -19, -19, -19, -19
+
+ },
+
+ {
+ 5, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, 35,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+
+ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, 35, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20
+ },
+
+ {
+ 5, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, 36, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, 36, -21, -21, -21, -21, -21,
+ -21, -21, -21, -21, -21, -21, -21, -21
+ },
+
+ {
+ 5, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+
+ -22, -22, -22, -22, -22, -22, 37, -22, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, -22, -22, -22, -22, -22
+ },
+
+ {
+ 5, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23
+ },
+
+ {
+ 5, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, 40, -24, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, 41,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, 41, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24
+ },
+
+ {
+ 5, -25, -25, -25, -25, -25, -25, -25, -25, 25,
+ 25, -25, -25, 25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, 25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, -25, -25, -25, -25, -25
+ },
+
+ {
+ 5, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, -26, -26,
+ -26, -26, -26, -26, -26, 42, 42, 42, 42, 42,
+ 42, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, 42, 42, 42,
+ 42, 42, 42, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+
+ -26, -26, -26, -26, -26, -26, -26, -26
+ },
+
+ {
+ 5, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27, -27, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, -27, -27,
+ -27, -27, -27, -27, -27, 43, 43, 43, 43, 43,
+ 43, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+
+ -27, -27, -27, -27, -27, -27, -27, 43, 43, 43,
+ 43, 43, 43, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27, -27
+ },
+
+ {
+ 5, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, 44, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, 44, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, -28, -28, -28, -28
+ },
+
+ {
+ 5, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, 45, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, 45,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29
+
+ },
+
+ {
+ 5, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, 46, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, 46, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30
+ },
+
+ {
+ 5, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ 47, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, 47, -31, -31, -31, -31, -31, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31, -31
+ },
+
+ {
+ 5, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, 48,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, 48, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32
+ },
+
+ {
+ 5, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, 49, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+
+ 49, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33, -33
+ },
+
+ {
+ 5, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, 50, -34, -34, -34,
+
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, 50, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34
+ },
+
+ {
+ 5, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, 51, -35, -35, 52, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, 51, -35, -35, 52, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35
+ },
+
+ {
+ 5, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, 53, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, 53, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+
+ -36, -36, -36, -36, -36, -36, -36, -36
+ },
+
+ {
+ 5, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37, -37
+ },
+
+ {
+ 5, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, 40, -38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, -38, -38,
+
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, 41,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, 41, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38
+ },
+
+ {
+ 5, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, 54,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, 54, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39
+
+ },
+
+ {
+ 5, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40
+ },
+
+ {
+ 5, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, 56, -41, 56, -41, -41, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41
+ },
+
+ {
+ 5, -42, -42, -42, -42, -42, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
+
+ -42, -42, -42, -42, -42, -42, -42, -42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, -42, -42,
+ -42, -42, -42, -42, -42, 42, 42, 42, 42, 42,
+ 42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, -42, 42, 42, 42,
+ 42, 42, 42, -42, -42, -42, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, -42, -42
+ },
+
+ {
+ 5, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, -43, -43,
+ -43, -43, -43, -43, -43, 43, 43, 43, 43, 43,
+ 43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, 43, 43, 43,
+ 43, 43, 43, -43, -43, -43, -43, -43, -43, -43,
+
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43
+ },
+
+ {
+ 5, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, 58, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, 58,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44
+ },
+
+ {
+ 5, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ 59, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, 59, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45
+ },
+
+ {
+ 5, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, 60, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, -46, 60, -46,
+
+ -46, -46, -46, -46, -46, -46, -46, -46
+ },
+
+ {
+ 5, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, 61, -47, -47, -47, -47, -47,
+
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, 61, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47
+ },
+
+ {
+ 5, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, 62, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, 62,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48
+ },
+
+ {
+ 5, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, 63,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, 63, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49
+
+ },
+
+ {
+ 5, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, 64, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+
+ -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, 64, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50, -50
+ },
+
+ {
+ 5, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+
+ -51, -51, -51, -51, -51, -51, -51, -51, 65, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ 65, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51, -51
+ },
+
+ {
+ 5, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, 66,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, 66, -52, -52, -52, -52, -52, -52
+ },
+
+ {
+ 5, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, 67, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ 67, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53
+ },
+
+ {
+ 5, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, 68, -54, 68, -54, -54, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54
+ },
+
+ {
+ 5, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, 55, 55,
+
+ 55, 55, 55, 55, 55, 55, 55, 55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, 41,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, 41, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55, -55
+ },
+
+ {
+ 5, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+
+ -56, -56, -56, -56, -56, -56, -56, -56
+ },
+
+ {
+ 5, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57
+ },
+
+ {
+ 5, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, 70, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, 70, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58, -58
+ },
+
+ {
+ 5, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, 71,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, 71, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59, -59
+
+ },
+
+ {
+ 5, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, 72,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+
+ -60, 72, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, -60, -60, -60, -60, -60
+ },
+
+ {
+ 5, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, 73,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, 73, -61, -61, -61, -61, -61, -61
+ },
+
+ {
+ 5, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, 74,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, 74, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, -62, -62, -62, -62, -62
+ },
+
+ {
+ 5, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, 75, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+
+ -63, -63, -63, -63, -63, 75, -63, -63, -63, -63,
+ -63, -63, -63, -63, -63, -63, -63, -63
+ },
+
+ {
+ 5, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, 76, -64, -64, -64, -64, -64, -64,
+
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, 76, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, -64, -64, -64, -64, -64
+ },
+
+ {
+ 5, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, 77, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, 77, -65, -65, -65,
+ -65, -65, -65, -65, -65, -65, -65, -65
+ },
+
+ {
+ 5, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, 78, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, 78, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+
+ -66, -66, -66, -66, -66, -66, -66, -66
+ },
+
+ {
+ 5, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, -67, -67, -67, -67, -67
+ },
+
+ {
+ 5, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, -68, -68,
+
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, -68, -68, -68, -68, -68
+ },
+
+ {
+ 5, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, -69, -69, -69, -69, -69
+
+ },
+
+ {
+ 5, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, 79, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+
+ -70, -70, -70, -70, -70, -70, -70, -70, 79, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, -70, -70, -70, -70, -70
+ },
+
+ {
+ 5, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, 80, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, 80, -71, -71,
+ -71, -71, -71, -71, -71, -71, -71, -71
+ },
+
+ {
+ 5, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ 81, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, 81, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, -72, -72, -72, -72, -72
+ },
+
+ {
+ 5, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+
+ -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, -73, -73, -73, -73, -73
+ },
+
+ {
+ 5, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+
+ -74, -74, -74, -74, 82, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, 82, -74, -74, -74,
+ -74, -74, -74, -74, -74, -74, -74, -74
+ },
+
+ {
+ 5, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, 83, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, 83, -75, -75, -75,
+ -75, -75, -75, -75, -75, -75, -75, -75
+ },
+
+ {
+ 5, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+
+ -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, -76, -76, -76, -76, 84, -76, -76,
+ -76, -76, -76, -76, -76, -76, 85, -76, -76, -76,
+ 86, -76, -76, 87, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, -76, -76, -76, -76, -76, -76, 84,
+ -76, -76, -76, -76, -76, -76, -76, -76, 85, -76,
+ -76, -76, 86, -76, -76, 87, -76, -76, -76, -76,
+
+ -76, -76, -76, -76, -76, -76, -76, -76
+ },
+
+ {
+ 5, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, 88, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, 88,
+ -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
+ -77, -77, -77, -77, -77, -77, -77, -77
+ },
+
+ {
+ 5, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, 89,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, 89, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78
+ },
+
+ {
+ 5, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, 90, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, 90, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
+ -79, -79, -79, -79, -79, -79, -79, -79
+
+ },
+
+ {
+ 5, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, 91, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ 91, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80
+ },
+
+ {
+ 5, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, 92,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, 92, -81, -81, -81, -81, -81, -81, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, -81
+ },
+
+ {
+ 5, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, 93, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, 93, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82
+ },
+
+ {
+ 5, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, 94, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+
+ -83, -83, -83, -83, 94, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83
+ },
+
+ {
+ 5, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+
+ -84, -84, -84, -84, -84, 95, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, 95, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84
+ },
+
+ {
+ 5, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, 96, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, 96, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85
+ },
+
+ {
+ 5, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, 97,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
+ -86, 97, -86, -86, -86, -86, -86, -86, -86, -86,
+
+ -86, -86, -86, -86, -86, -86, -86, -86
+ },
+
+ {
+ 5, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, 98, -87, -87, -87, -87,
+
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, 98, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87
+ },
+
+ {
+ 5, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88
+ },
+
+ {
+ 5, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, 99, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ 99, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, -89, -89, -89, -89, -89, -89, -89
+
+ },
+
+ {
+ 5, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, 100, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, 100, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90
+ },
+
+ {
+ 5, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, 101, -91,
+
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ 101, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91, -91, -91
+ },
+
+ {
+ 5, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, 102, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, 102, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, -92, -92, -92, -92, -92, -92, -92
+ },
+
+ {
+ 5, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, 103,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, 103, -93, -93, -93, -93, -93, -93
+ },
+
+ {
+ 5, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, 104, -94, -94, -94, -94, -94, -94,
+
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, 104, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, -94, -94, -94, -94, -94
+ },
+
+ {
+ 5, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, 105, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, 105, -95, -95, -95, -95, -95,
+ -95, -95, -95, -95, -95, -95, -95, -95
+ },
+
+ {
+ 5, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, 106, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ 106, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+
+ -96, -96, -96, -96, -96, -96, -96, -96
+ },
+
+ {
+ 5, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, 107, -97, -97, 108, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, 107, -97, -97, 108, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, -97, -97, -97, -97, -97
+ },
+
+ {
+ 5, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, 109, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, 109, -98, -98, -98, -98, -98,
+ -98, -98, -98, -98, -98, -98, -98, -98
+ },
+
+ {
+ 5, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, 110, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, 110,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99
+
+ },
+
+ {
+ 5, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, 111, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+
+ -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, 111, -100, -100, -100, -100,
+ -100, -100, -100, -100, -100, -100, -100, -100
+ },
+
+ {
+ 5, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, 112, -101, -101,
+
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, 112,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, -101, -101, -101, -101
+ },
+
+ {
+ 5, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, 113,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, 113, -102, -102, -102, -102, -102, -102
+ },
+
+ {
+ 5, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, 114, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, 114,
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+
+ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, -103, -103, -103, -103, -103
+ },
+
+ {
+ 5, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, 115, -104,
+
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ 115, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, -104, -104, -104, -104, -104
+ },
+
+ {
+ 5, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, 116, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, 116, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105
+ },
+
+ {
+ 5, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, 117,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, 117, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+
+ -106, -106, -106, -106, -106, -106, -106, -106
+ },
+
+ {
+ 5, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, 118, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ 118, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107
+ },
+
+ {
+ 5, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, 119,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, 119, -108, -108, -108, -108, -108, -108
+ },
+
+ {
+ 5, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ 120, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, 120, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, -109, -109, -109, -109, -109
+
+ },
+
+ {
+ 5, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, -110, -110, -110, -110, -110
+ },
+
+ {
+ 5, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, 121, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, 121, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111
+ },
+
+ {
+ 5, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, 122, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, 122, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112
+ },
+
+ {
+ 5, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, 123, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, 123, -113, -113, -113, -113, -113, -113,
+
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113
+ },
+
+ {
+ 5, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, 124,
+
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, 124, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, -114, -114, -114, -114, -114
+ },
+
+ {
+ 5, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, 125, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, 125, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, -115, -115, -115, -115, -115, -115, -115
+ },
+
+ {
+ 5, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, 126,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, 126, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+
+ -116, -116, -116, -116, -116, -116, -116, -116
+ },
+
+ {
+ 5, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, 127, -117, -117, -117, -117, -117, -117,
+
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, 127, -117, -117, -117, -117,
+ -117, -117, -117, -117, -117, -117, -117, -117
+ },
+
+ {
+ 5, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, 128, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, 128, -118, -118, -118,
+ -118, -118, -118, -118, -118, -118, -118, -118
+ },
+
+ {
+ 5, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, 129, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, 129, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, -119, -119, -119, -119, -119
+
+ },
+
+ {
+ 5, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, 130, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, 130, -120, -120,
+
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, -120, -120, -120, -120, -120
+ },
+
+ {
+ 5, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, 131, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, 131, -121, -121, -121, -121, -121,
+ -121, -121, -121, -121, -121, -121, -121, -121
+ },
+
+ {
+ 5, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, 132, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, 132, -122, -122, -122, -122, -122,
+ -122, -122, -122, -122, -122, -122, -122, -122
+ },
+
+ {
+ 5, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, 133,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+
+ -123, 133, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, -123, -123, -123, -123, -123
+ },
+
+ {
+ 5, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, 134, -124, -124, -124,
+
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, 134, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, -124, -124, -124, -124, -124
+ },
+
+ {
+ 5, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, 135, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, 135,
+ -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, -125, -125, -125, -125, -125
+ },
+
+ {
+ 5, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, 136, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, 136,
+ -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+
+ -126, -126, -126, -126, -126, -126, -126, -126
+ },
+
+ {
+ 5, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, 137, -127, -127, -127, -127, -127,
+
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, 137, -127, -127, -127,
+ -127, -127, -127, -127, -127, -127, -127, -127
+ },
+
+ {
+ 5, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, 138, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, 138,
+ -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, -128, -128, -128, -128, -128
+ },
+
+ {
+ 5, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, 139,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, 139, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, -129, -129, -129, -129, -129
+
+ },
+
+ {
+ 5, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, 140, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, 140,
+
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, -130, -130, -130, -130, -130
+ },
+
+ {
+ 5, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+
+ -131, -131, -131, 141, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, 141, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, -131, -131, -131, -131, -131
+ },
+
+ {
+ 5, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, 142, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132, 142, -132,
+ -132, -132, -132, -132, -132, -132, -132, -132
+ },
+
+ {
+ 5, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, 143, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+
+ 143, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, -133, -133, -133, -133, -133
+ },
+
+ {
+ 5, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, 144, -134, -134, -134,
+
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, 144, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, -134, -134, -134, -134, -134
+ },
+
+ {
+ 5, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135
+ },
+
+ {
+ 5, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+
+ -136, -136, -136, -136, -136, -136, -136, -136
+ },
+
+ {
+ 5, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, 145, -137, -137, -137, -137, -137, -137, -137,
+
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, 145, -137, -137, -137, -137, -137,
+ -137, -137, -137, -137, -137, -137, -137, -137
+ },
+
+ {
+ 5, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, -138, -138, -138, -138, -138
+ },
+
+ {
+ 5, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, 146, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ 146, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, -139, -139, -139, -139, -139
+
+ },
+
+ {
+ 5, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, 147,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+
+ -140, 147, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, -140, -140, -140, -140, -140
+ },
+
+ {
+ 5, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+
+ -141, -141, -141, -141, -141, -141, -141, -141, 148, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ 148, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, -141, -141, -141, -141, -141
+ },
+
+ {
+ 5, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, 149,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, 149, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, -142, -142, -142, -142, -142
+ },
+
+ {
+ 5, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, 150, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, 150,
+
+ -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, -143, -143, -143, -143, -143
+ },
+
+ {
+ 5, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, 151,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, 151, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, -144, -144, -144, -144, -144
+ },
+
+ {
+ 5, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, 152, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, 152, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, -145, -145, -145, -145, -145
+ },
+
+ {
+ 5, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, 153, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, 153,
+ -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+
+ -146, -146, -146, -146, -146, -146, -146, -146
+ },
+
+ {
+ 5, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, 154, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, 154,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147
+ },
+
+ {
+ 5, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, 155, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, 155, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, -148, -148, -148, -148, -148
+ },
+
+ {
+ 5, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, 156, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, 156,
+ -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, -149, -149, -149, -149, -149
+
+ },
+
+ {
+ 5, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, -150, -150, -150, -150, -150
+ },
+
+ {
+ 5, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, 157, -151, -151,
+
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, 157,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, -151, -151, -151, -151, -151
+ },
+
+ {
+ 5, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, 158, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ 158, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, -152, -152, -152, -152, -152
+ },
+
+ {
+ 5, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+
+ -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, -153, -153, -153, -153, -153
+ },
+
+ {
+ 5, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, -154, -154, -154, -154, -154
+ },
+
+ {
+ 5, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, 159, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, 159,
+ -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, -155
+ },
+
+ {
+ 5, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+
+ -156, -156, -156, -156, -156, -156, -156, -156
+ },
+
+ {
+ 5, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, 160, -157, -157, -157, -157, -157,
+
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, 160, -157, -157, -157,
+ -157, -157, -157, -157, -157, -157, -157, -157
+ },
+
+ {
+ 5, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, 161, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, 161, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, -158, -158, -158, -158, -158
+ },
+
+ {
+ 5, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, -159, -159, -159, -159, -159
+
+ },
+
+ {
+ 5, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, 162, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+
+ -160, -160, -160, -160, -160, 162, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, -160, -160, -160, -160, -160
+ },
+
+ {
+ 5, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+
+ -161, -161, -161, -161, -161, -161, -161, 163, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, 163,
+ -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, -161, -161, -161, -161, -161
+ },
+
+ {
+ 5, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, 164,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, 164, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, -162, -162, -162, -162, -162
+ },
+
+ {
+ 5, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+
+ -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, -163, -163, -163, -163, -163
+ },
+
+ {
+ 5, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, 165, -164,
+
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ 165, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, -164, -164, -164, -164, -164
+ },
+
+ {
+ 5, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, 166, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, 166,
+ -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, -165, -165, -165, -165, -165
+ },
+
+ {
+ 5, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+
+ -166, -166, -166, -166, -166, -166, -166, -166
+ },
+
+ } ;
+
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 38
+#define YY_END_OF_BUFFER 39
+static yyconst short int yy_accept[167] =
+ { 0,
+ 0, 0, 0, 0, 39, 37, 36, 36, 31, 32,
+ 33, 37, 35, 34, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 1, 36, 3, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 2, 0,
+ 0, 3, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29, 0, 2, 0,
+ 0, 0, 30, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 11, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 21, 0, 17, 0, 0,
+ 0, 0, 0, 0, 8, 22, 0, 18, 0, 0,
+ 0, 0, 15, 0, 0, 23, 25, 0, 13, 16,
+ 0, 0, 24, 26, 9, 14, 0, 0, 10, 0,
+ 19, 0, 20, 0, 27, 28
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+static yyconst yy_state_type yy_NUL_trans[167] =
+ { 0,
+ 6, 6, 6, 6, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "wktparse.lex"
+#define INITIAL 0
+/*
+ * Written by Ralph Mason ralph.mason<at>telogis.com
+ *
+ * Copyright Telogis 2004
+ * www.telogis.com
+ *
+ */
+#define vals_ok 1
+
+#line 11 "wktparse.lex"
+#include "wktparse.tab.h"
+#include <unistd.h>
+#include <stdlib.h> // need stdlib for atof() definition
+
+void init_parser(const char *src);
+void close_parser(void);
+int lwg_parse_yywrap(void);
+int lwg_parse_yylex(void);
+
+static YY_BUFFER_STATE buf_state;
+ void init_parser(const char *src) { BEGIN(0);buf_state = lwg_parse_yy_scan_string(src); }
+ void close_parser() { lwg_parse_yy_delete_buffer(buf_state); }
+ int lwg_parse_yywrap(void){ return 1; }
+
+#line 3281 "lex.yy.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp = NULL, *yy_bp = NULL;
+ register int yy_act;
+
+#line 27 "wktparse.lex"
+
+
+#line 3422 "lex.yy.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ while ( (yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]) > 0 )
+ {
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+
+ ++yy_cp;
+ }
+
+ yy_current_state = -yy_current_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos + 1;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 29 "wktparse.lex"
+{ lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 30 "wktparse.lex"
+{ lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 32 "wktparse.lex"
+{ lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 33 "wktparse.lex"
+{ lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 35 "wktparse.lex"
+{ return POINT; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 36 "wktparse.lex"
+{ return POINTM; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 37 "wktparse.lex"
+{ return LINESTRING; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 38 "wktparse.lex"
+{ return LINESTRINGM; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 39 "wktparse.lex"
+{ return CIRCULARSTRING; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 40 "wktparse.lex"
+{ return CIRCULARSTRINGM; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 41 "wktparse.lex"
+{ return POLYGON; }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 42 "wktparse.lex"
+{ return POLYGONM; }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 43 "wktparse.lex"
+{ return COMPOUNDCURVE; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 44 "wktparse.lex"
+{ return COMPOUNDCURVEM; }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 45 "wktparse.lex"
+{ return CURVEPOLYGON; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 46 "wktparse.lex"
+{ return CURVEPOLYGONM; }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 47 "wktparse.lex"
+{ return MULTIPOINT; }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 48 "wktparse.lex"
+{ return MULTIPOINTM; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 49 "wktparse.lex"
+{ return MULTILINESTRING; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 50 "wktparse.lex"
+{ return MULTILINESTRINGM; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 51 "wktparse.lex"
+{ return MULTICURVE; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 52 "wktparse.lex"
+{ return MULTICURVEM; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 53 "wktparse.lex"
+{ return MULTIPOLYGON; }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 54 "wktparse.lex"
+{ return MULTIPOLYGONM; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 55 "wktparse.lex"
+{ return MULTISURFACE; }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 56 "wktparse.lex"
+{ return MULTISURFACEM; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 57 "wktparse.lex"
+{ return GEOMETRYCOLLECTION; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 58 "wktparse.lex"
+{ return GEOMETRYCOLLECTIONM; }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 59 "wktparse.lex"
+{ BEGIN(vals_ok); return SRID; }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 60 "wktparse.lex"
+{ return EMPTY; }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 62 "wktparse.lex"
+{ BEGIN(vals_ok); return LPAREN; }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 63 "wktparse.lex"
+{ return RPAREN; }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 64 "wktparse.lex"
+{ return COMMA ; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 65 "wktparse.lex"
+{ return EQUALS ; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 66 "wktparse.lex"
+{ BEGIN(0); return SEMICOLON; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 67 "wktparse.lex"
+/*eat whitespace*/
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 68 "wktparse.lex"
+{ return lwg_parse_yytext[0]; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 70 "wktparse.lex"
+ECHO;
+ YY_BREAK
+#line 3683 "lex.yy.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(vals_ok):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ if ( *yy_cp )
+ {
+ yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)];
+ }
+ else
+ yy_current_state = yy_NUL_trans[yy_current_state];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ yy_current_state = yy_NUL_trans[yy_current_state];
+ yy_is_jam = (yy_current_state == 0);
+
+ if ( ! yy_is_jam )
+ {
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ }
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+#endif /* YY_NO_INPUT */
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 70 "wktparse.lex"
+
+
Added: trunk/liblwgeom/liblwgeom.h
===================================================================
--- trunk/liblwgeom/liblwgeom.h 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/liblwgeom.h 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,1269 @@
+#ifndef _LIBLWGEOM_H
+#define _LIBLWGEOM_H 1
+
+#include "../postgis_config.h"
+#include <stdio.h>
+/* #include "compat.h" */
+
+#define INTEGRITY_CHECKS 1
+
+/*
+ * Floating point comparitors.
+ */
+#define PGIS_EPSILON 1e-12
+#define FP_MAX(A, B) ((A > B) ? A : B)
+#define FP_MIN(A, B) ((A < B) ? A : B)
+#define FP_LT(A, B) ((A + PGIS_EPSILON) < B)
+#define FP_LTEQ(A, B) ((A - PGIS_EPSILON) <= B)
+#define FP_CONTAINS_TOP(A, X, B) (FP_LT(A, X) && FP_LTEQ(X, B))
+#define FP_CONTAINS_BOTTOM(A, X, B) (FP_LTEQ(A, X) && FP_LT(X, B))
+#define FP_CONTAINS_INCL(A, X, B) (FP_LTEQ(A, X) && FP_LTEQ(X, B))
+#define FP_CONTAINS_EXCL(A, X, B) (FP_LT(A, X) && FP_LT(X, B))
+#define FP_CONTAINS(A, X, B) FP_CONTAINS_EXCL(A, X, B)
+
+/*
+ * Memory management function types
+ */
+extern void lwgeom_init_allocators(void);
+
+typedef void* (*lwallocator)(size_t size);
+typedef void* (*lwreallocator)(void *mem, size_t size);
+typedef void (*lwfreeor)(void* mem);
+typedef void (*lwreporter)(const char* fmt, ...);
+
+#ifndef C_H
+
+typedef unsigned int uint32;
+typedef int int32;
+
+#endif
+
+/*
+ * this will change to NaN when I figure out how to
+ * get NaN in a platform-independent way
+ */
+#define NO_VALUE 0.0
+#define NO_Z_VALUE NO_VALUE
+#define NO_M_VALUE NO_VALUE
+
+
+/* prototypes */
+void *default_allocator(size_t size);
+void *default_reallocator(void *mem, size_t size);
+void default_freeor(void *ptr);
+void default_errorreporter(const char *fmt, ...);
+void default_noticereporter(const char *fmt, ...);
+
+/* globals */
+extern lwreallocator lwrealloc_var;
+extern lwallocator lwalloc_var;
+extern lwfreeor lwfree_var;
+extern lwreporter lwerror;
+extern lwreporter lwnotice;
+
+/* Debug macros */
+#if POSTGIS_DEBUG_LEVEL > 0
+
+/* Display a notice at the given debug level */
+#define LWDEBUG(level, msg) \
+ do { \
+ if (POSTGIS_DEBUG_LEVEL >= level) \
+ lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__); \
+ } while (0);
+
+/* Display a formatted notice at the given debug level (like printf, with variadic arguments) */
+#define LWDEBUGF(level, msg, ...) \
+ do { \
+ if (POSTGIS_DEBUG_LEVEL >= level) \
+ lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__, __VA_ARGS__); \
+ } while (0);
+
+#else
+
+/* Empty prototype that can be optimised away by the compiler for non-debug builds */
+#define LWDEBUG(level, msg) \
+ ((void) 0)
+
+/* Empty prototype that can be optimised away by the compiler for non-debug builds */
+#define LWDEBUGF(level, msg, ...) \
+ ((void) 0)
+
+#endif
+
+/******************************************************************/
+
+typedef unsigned char uchar;
+
+typedef struct
+{
+ float xmin;
+ float ymin;
+ float xmax;
+ float ymax;
+} BOX2DFLOAT4;
+
+typedef struct
+{
+ double xmin, ymin, zmin;
+ double xmax, ymax, zmax;
+} BOX3D;
+
+typedef struct chiptag
+{
+ int size; /* unused (for use by postgresql) */
+
+ int endian_hint; /* the number 1 in the endian of this datastruct */
+
+ BOX3D bvol;
+ int SRID;
+ char future[4];
+ float factor; /* Usually 1.0.
+ * Integer values are multiplied by this number
+ * to get the actual height value
+ * (for sub-meter accuracy height data).
+ */
+
+ int datatype; /* 1 = float32,
+ * 5 = 24bit integer,
+ * 6 = 16bit integer (short)
+ * 7 = 16bit ???
+ * 8 = 8bit ???
+ * 101 = float32 (NDR),
+ * 105 = 24bit integer (NDR),
+ * 106 = 16bit int (NDR)
+ * 107 = 16bit ??? (NDR)
+ * 108 = 8bit ??? (NDR) (this doesn't make sense)
+ */
+ int height;
+ int width;
+ int compression; /* 0 = no compression, 1 = differencer
+ * 0x80 = new value
+ * 0x7F = nodata
+ */
+
+ /*
+ * this is provided for convenience, it should be set to
+ * sizeof(chip) bytes into the struct because the serialized form is:
+ * <header><data>
+ * NULL when serialized
+ */
+ void *data; /* data[0] = bottm left,
+ * data[width] = 1st pixel, 2nd row (uncompressed)
+ */
+
+} CHIP;
+
+/*
+ * standard definition of an ellipsoid (what wkt calls a spheroid)
+ * f = (a-b)/a
+ * e_sq = (a*a - b*b)/(a*a)
+ * b = a - fa
+ */
+typedef struct
+{
+ double a; /* semimajor axis */
+ double b; /* semiminor axis */
+ double f; /* flattening */
+ double e; /* eccentricity (first) */
+ double e_sq; /* eccentricity (first), squared */
+ char name[20]; /* name of ellipse */
+} SPHEROID;
+
+
+/*
+ * ALL LWGEOM structures will use POINT3D as an abstract point.
+ * This means a 2d geometry will be stored as (x,y) in its serialized
+ * form, but all functions will work on (x,y,0). This keeps all the
+ * analysis functions simple.
+ * NOTE: for GEOS integration, we'll probably set z=NaN
+ * so look out - z might be NaN for 2d geometries!
+ */
+typedef struct { double x,y,z; } POINT3DZ;
+typedef struct { double x,y,z; } POINT3D; /* alias for POINT3DZ */
+typedef struct { double x,y,m; } POINT3DM;
+
+
+/*
+ * type for 2d points. When you convert this to 3d, the
+ * z component will be either 0 or NaN.
+ */
+typedef struct
+{
+ double x;
+ double y;
+} POINT2D;
+
+typedef struct
+{
+ double x;
+ double y;
+ double z;
+ double m;
+} POINT4D;
+
+/******************************************************************/
+
+/*
+ * Point array abstracts a lot of the complexity of points and point lists.
+ * It handles miss-alignment in the serialized form, 2d/3d translation
+ * (2d points converted to 3d will have z=0 or NaN)
+ * DONT MIX 2D and 3D POINTS! *EVERYTHING* is either one or the other
+ */
+typedef struct
+{
+ /* array of POINT 2D, 3D or 4D. probably missaligned. */
+ uchar *serialized_pointlist;
+
+ /* use TYPE_* macros to handle */
+ uchar dims;
+
+ uint32 npoints;
+} POINTARRAY;
+
+
+/*
+ * Use the following to build pointarrays
+ * when number of points in output is not
+ * known in advance
+ */
+typedef struct {
+ POINTARRAY *pa;
+ size_t ptsize;
+ size_t capacity; /* given in points */
+} DYNPTARRAY;
+
+/* Create a new dynamic pointarray */
+extern DYNPTARRAY *dynptarray_create(size_t initial_capacity, int dims);
+
+/*
+ * Add a POINT4D to the dynamic pointarray.
+ *
+ * The dynamic pointarray may be of any dimension, only
+ * accepted dimensions will be copied.
+ *
+ * If allow_duplicates is set to 0 (false) a check
+ * is performed to see if last point in array is equal to the
+ * provided one. NOTE that the check is 4d based, with missing
+ * ordinates in the pointarray set to NO_Z_VALUE and NO_M_VALUE
+ * respectively.
+ */
+extern int dynptarray_addPoint4d(DYNPTARRAY *dpa, POINT4D *p4d,
+ int allow_duplicates);
+
+/******************************************************************
+ *
+ * LWGEOM (any type)
+ *
+ ******************************************************************/
+
+typedef struct
+{
+ uchar type;
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID; /* -1 == unneeded */
+ void *data;
+} LWGEOM;
+
+/* POINTYPE */
+typedef struct
+{
+ uchar type; /* POINTTYPE */
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ POINTARRAY *point; /* hide 2d/3d (this will be an array of 1 point) */
+} LWPOINT; /* "light-weight point" */
+
+/* LINETYPE */
+typedef struct
+{
+ uchar type; /* LINETYPE */
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ POINTARRAY *points; /* array of POINT3D */
+} LWLINE; /* "light-weight line" */
+
+/* POLYGONTYPE */
+typedef struct
+{
+ uchar type; /* POLYGONTYPE */
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int nrings;
+ POINTARRAY **rings; /* list of rings (list of points) */
+} LWPOLY; /* "light-weight polygon" */
+
+/* MULTIPOINTTYPE */
+typedef struct
+{
+ uchar type;
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int ngeoms;
+ LWPOINT **geoms;
+} LWMPOINT;
+
+/* MULTILINETYPE */
+typedef struct
+{
+ uchar type;
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int ngeoms;
+ LWLINE **geoms;
+} LWMLINE;
+
+/* MULTIPOLYGONTYPE */
+typedef struct
+{
+ uchar type;
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int ngeoms;
+ LWPOLY **geoms;
+} LWMPOLY;
+
+/* COLLECTIONTYPE */
+typedef struct
+{
+ uchar type;
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int ngeoms;
+ LWGEOM **geoms;
+} LWCOLLECTION;
+
+/* Casts LWGEOM->LW* (return NULL if cast is illegal) */
+extern LWMPOLY *lwgeom_as_lwmpoly(LWGEOM *lwgeom);
+extern LWMLINE *lwgeom_as_lwmline(LWGEOM *lwgeom);
+extern LWMPOINT *lwgeom_as_lwmpoint(LWGEOM *lwgeom);
+extern LWCOLLECTION *lwgeom_as_lwcollection(LWGEOM *lwgeom);
+extern LWPOLY *lwgeom_as_lwpoly(LWGEOM *lwgeom);
+extern LWLINE *lwgeom_as_lwline(LWGEOM *lwgeom);
+extern LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom);
+
+/* Casts LW*->LWGEOM (always cast) */
+extern LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj);
+extern LWGEOM *lwmline_as_lwgeom(LWMLINE *obj);
+extern LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj);
+extern LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj);
+extern LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj);
+extern LWGEOM *lwline_as_lwgeom(LWLINE *obj);
+extern LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj);
+
+/*
+ * Call this function everytime LWGEOM coordinates
+ * change so to invalidate bounding box
+ */
+extern void lwgeom_changed(LWGEOM *lwgeom);
+
+/*
+ * Call this function to drop BBOX and SRID
+ * from LWGEOM. If LWGEOM type is *not* flagged
+ * with the HASBBOX flag and has a bbox, it
+ * will be released.
+ */
+extern void lwgeom_dropBBOX(LWGEOM *lwgeom);
+
+/* Compute a bbox if not already computed */
+extern void lwgeom_addBBOX(LWGEOM *lwgeom);
+
+extern void lwgeom_dropSRID(LWGEOM *lwgeom);
+
+/******************************************************************/
+
+/*
+ * copies a point from the point array into the parameter point
+ * will set point's z=0 (or NaN) if pa is 2d
+ * will set point's m=0 (or NaN) if pa is 3d or 2d
+ * NOTE: point is a real POINT3D *not* a pointer
+ */
+extern POINT4D getPoint4d(const POINTARRAY *pa, int n);
+
+/*
+ * copies a point from the point array into the parameter point
+ * will set point's z=0 (or NaN) if pa is 2d
+ * will set point's m=0 (or NaN) if pa is 3d or 2d
+ * NOTE: this will modify the point4d pointed to by 'point'.
+ */
+extern int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point);
+
+/*
+ * copies a point from the point array into the parameter point
+ * will set point's z=0 (or NaN) if pa is 2d
+ * NOTE: point is a real POINT3D *not* a pointer
+ */
+extern POINT3DZ getPoint3dz(const POINTARRAY *pa, int n);
+extern POINT3DM getPoint3dm(const POINTARRAY *pa, int n);
+
+/*
+ * copies a point from the point array into the parameter point
+ * will set point's z=0 (or NaN) if pa is 2d
+ * NOTE: this will modify the point3d pointed to by 'point'.
+ */
+extern int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point);
+extern int getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *point);
+
+
+/*
+ * copies a point from the point array into the parameter point
+ * z value (if present is not returned)
+ * NOTE: point is a real POINT3D *not* a pointer
+ */
+extern POINT2D getPoint2d(const POINTARRAY *pa, int n);
+
+/*
+ * copies a point from the point array into the parameter point
+ * z value (if present is not returned)
+ * NOTE: this will modify the point2d pointed to by 'point'.
+ */
+extern int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point);
+
+/*
+ * set point N to the given value
+ * NOTE that the pointarray can be of any
+ * dimension, the appropriate ordinate values
+ * will be extracted from it
+ *
+ */
+extern void setPoint4d(POINTARRAY *pa, int n, POINT4D *p4d);
+
+/*
+ * get a pointer to nth point of a POINTARRAY
+ * You'll need to cast it to appropriate dimensioned point.
+ * Note that if you cast to a higher dimensional point you'll
+ * possibly corrupt the POINTARRAY.
+ *
+ * WARNING: Don't cast this to a POINT !
+ * it would not be reliable due to memory alignment constraints
+ */
+extern uchar *getPoint_internal(const POINTARRAY *pa, int n);
+
+/* --- here is a macro equivalent, for speed... */
+/* #define getPoint(x,n) &( (x)->serialized_pointlist[((x)->ndims*8)*(n)] ) */
+
+
+/*
+ * constructs a POINTARRAY.
+ * NOTE: points is *not* copied, so be careful about modification
+ * (can be aligned/missaligned)
+ * NOTE: hasz and hasm are descriptive - it describes what type of data
+ * 'points' points to. No data conversion is done.
+ */
+extern POINTARRAY *pointArray_construct(uchar *points, char hasz, char hasm,
+ uint32 npoints);
+
+/*
+ * Calculate the (BOX3D) bounding box of a set of points.
+ * Returns an alloced BOX3D or NULL (for empty geom) in the first form.
+ * Write result in user-provided BOX3D in second form (return 0 if untouched).
+ * If pa is 2d, then box3d's zmin/zmax will be set to NO_Z_VALUE
+ */
+extern BOX3D *ptarray_compute_box3d(const POINTARRAY *pa);
+extern int ptarray_compute_box3d_p(const POINTARRAY *pa, BOX3D *out);
+
+/*
+ * size of point represeneted in the POINTARRAY
+ * 16 for 2d, 24 for 3d, 32 for 4d
+ */
+extern int pointArray_ptsize(const POINTARRAY *pa);
+
+
+#define POINTTYPE 1
+#define LINETYPE 2
+#define POLYGONTYPE 3
+#define MULTIPOINTTYPE 4
+#define MULTILINETYPE 5
+#define MULTIPOLYGONTYPE 6
+#define COLLECTIONTYPE 7
+
+#define WKBZOFFSET 0x80000000
+#define WKBMOFFSET 0x40000000
+#define WKBSRIDFLAG 0x20000000
+#define WKBBBOXFLAG 0x10000000
+
+/* These macros work on PG_LWGEOM.type, LWGEOM.type and all its subclasses */
+
+#define TYPE_SETTYPE(c,t) ((c)=(((c)&0xF0)|(t)))
+#define TYPE_SETZM(t,z,m) ((t)=(((t)&0xCF)|((z)<<5)|((m)<<4)))
+#define TYPE_SETHASBBOX(t,b) ((t)=(((t)&0x7F)|((b)<<7)))
+#define TYPE_SETHASSRID(t,s) ((t)=(((t)&0xBF)|((s)<<6)))
+
+#define TYPE_HASZ(t) ( ((t)&0x20)>>5 )
+#define TYPE_HASM(t) ( ((t)&0x10)>>4 )
+#define TYPE_HASBBOX(t) ( ((t)&0x80)>>7 )
+#define TYPE_HASSRID(t) ( (((t)&0x40))>>6 )
+#define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2)
+#define TYPE_GETTYPE(t) ((t)&0x0F)
+
+/* 0x02==Z 0x01==M */
+#define TYPE_GETZM(t) (((t)&0x30)>>4)
+
+extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set */
+extern int lwgeom_ndims(uchar type); /* returns 2,3 or 4 */
+extern int lwgeom_hasZ(uchar type); /* has Z ? */
+extern int lwgeom_hasM(uchar type); /* has M ? */
+extern int lwgeom_getType(uchar type); /* returns the tttt value */
+
+extern uchar lwgeom_makeType(char hasZ, char hasM, char hasSRID, int type);
+extern uchar lwgeom_makeType_full(char hasZ, char hasM, char hasSRID, int type, char hasBBOX);
+extern char lwgeom_hasSRID(uchar type); /* true iff S bit is set */
+extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set */
+
+
+
+/*
+ * This is the binary representation of lwgeom compatible
+ * with postgresql varlena struct
+ */
+typedef struct {
+ uint32 size; /* varlena header (do not touch directly!) */
+ uchar type; /* encodes ndims, type, bbox presence,
+ srid presence */
+ uchar data[1];
+} PG_LWGEOM;
+
+/*
+ * Construct a full PG_LWGEOM type (including size header)
+ * from a serialized form.
+ * The constructed PG_LWGEOM object will be allocated using palloc
+ * and the serialized form will be copied.
+ * If you specify a SRID other then -1 it will be set.
+ * If you request bbox (wantbbox=1) it will be extracted or computed
+ * from the serialized form.
+ */
+extern PG_LWGEOM *PG_LWGEOM_construct(uchar *serialized, int SRID,
+ int wantbbox);
+
+/*
+ * Compute bbox of serialized geom
+ */
+extern int compute_serialized_box2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
+extern BOX3D *compute_serialized_box3d(uchar *serialized_form);
+extern int compute_serialized_box3d_p(uchar *serialized_form, BOX3D *box);
+
+
+/*
+ * Evaluate with an heuristic if the provided PG_LWGEOM is worth
+ * caching a bbox
+ */
+char is_worth_caching_pglwgeom_bbox(const PG_LWGEOM *);
+char is_worth_caching_serialized_bbox(const uchar *);
+char is_worth_caching_lwgeom_bbox(const LWGEOM *);
+
+/*
+ * Use this macro to extract the char * required
+ * by most functions from an PG_LWGEOM struct.
+ * (which is an PG_LWGEOM w/out int32 size casted to char *)
+ */
+#define SERIALIZED_FORM(x) ((uchar *)VARDATA((x)))
+
+/*
+ This structure is a "glue" structure for returning a serialized
+ LWGEOM from the parser, along with its size. By using a separate
+ type, we remove the constraint that the output from the
+ parser must be PG_LWGEOM format (and hence protect ourselves
+ from future varlena changes)
+*/
+typedef struct serialized_lwgeom {
+ uchar *lwgeom;
+ int size;
+} SERIALIZED_LWGEOM;
+
+/*
+ * This function computes the size in bytes
+ * of the serialized geometries.
+ */
+extern size_t lwgeom_size(const uchar *serialized_form);
+extern size_t lwgeom_size_subgeom(const uchar *serialized_form, int geom_number);
+extern size_t lwgeom_size_line(const uchar *serialized_line);
+extern size_t lwgeom_size_curve(const uchar *serialized_curve);
+extern size_t lwgeom_size_point(const uchar *serialized_point);
+extern size_t lwgeom_size_poly(const uchar *serialized_line);
+
+
+/*--------------------------------------------------------
+ * all the base types (point/line/polygon) will have a
+ * basic constructor, basic de-serializer, basic serializer,
+ * bounding box finder and (TODO) serialized form size finder.
+ *--------------------------------------------------------*/
+
+/*
+ * given the LWPOINT serialized form (or a pointer into a muli* one)
+ * construct a proper LWPOINT.
+ * serialized_form should point to the 8bit type format (with type = 1)
+ * Returns NULL if serialized form is not a point.
+ * See serialized form doc
+ */
+extern LWPOINT *lwpoint_deserialize(uchar *serialized_form);
+
+/*
+ * Find size this point would get when serialized (no BBOX)
+ */
+extern size_t lwpoint_serialize_size(LWPOINT *point);
+
+/*
+ * convert this point into its serialize form
+ * result's first char will be the 8bit type.
+ * See serialized form doc
+ */
+extern uchar *lwpoint_serialize(LWPOINT *point);
+
+/* same as above, writes to buf */
+extern void lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *size);
+
+/*
+ * find bounding box (standard one)
+ * zmin=zmax=0 if 2d (might change to NaN)
+ */
+extern BOX3D *lwpoint_compute_box3d(LWPOINT *point);
+
+/*
+ * convenience functions to hide the POINTARRAY
+ */
+extern int lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out);
+extern int lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out);
+extern int lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out);
+extern int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out);
+
+/******************************************************************
+ * LWLINE functions
+ ******************************************************************/
+
+/*
+ * given the LWGEOM serialized form (or a pointer into a muli* one)
+ * construct a proper LWLINE.
+ * serialized_form should point to the 8bit type format (with type = 2)
+ * See SERIALIZED_FORM doc
+ */
+extern LWLINE *lwline_deserialize(uchar *serialized_form);
+
+/* find the size this line would get when serialized */
+extern size_t lwline_serialize_size(LWLINE *line);
+
+/*
+ * convert this line into its serialize form
+ * result's first char will be the 8bit type. See serialized form doc
+ * copies data.
+ */
+extern uchar *lwline_serialize(LWLINE *line);
+
+/* same as above, writes to buf */
+extern void lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *size);
+
+/*
+ * find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
+ */
+extern BOX3D *lwline_compute_box3d(LWLINE *line);
+
+/******************************************************************
+ * LWPOLY functions
+ ******************************************************************/
+
+/*
+ * given the LWPOLY serialized form (or a pointer into a muli* one)
+ * construct a proper LWPOLY.
+ * serialized_form should point to the 8bit type format (with type = 3)
+ * See SERIALIZED_FORM doc
+ */
+extern LWPOLY *lwpoly_deserialize(uchar *serialized_form);
+
+/* find the size this polygon would get when serialized */
+extern size_t lwpoly_serialize_size(LWPOLY *poly);
+
+/*
+ * create the serialized form of the polygon
+ * result's first char will be the 8bit type. See serialized form doc
+ * points copied
+ */
+extern uchar *lwpoly_serialize(LWPOLY *poly);
+
+/* same as above, writes to buf */
+extern void lwpoly_serialize_buf(LWPOLY *poly, uchar *buf, size_t *size);
+
+/*
+ * find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
+ */
+extern BOX3D *lwpoly_compute_box3d(LWPOLY *poly);
+
+/******************************************************************
+ * LWGEOM functions
+ ******************************************************************/
+
+extern size_t lwgeom_serialize_size(LWGEOM *geom);
+extern size_t lwcollection_serialize_size(LWCOLLECTION *coll);
+extern void lwgeom_serialize_buf(LWGEOM *geom, uchar *buf, size_t *size);
+extern uchar *lwgeom_serialize(LWGEOM *geom);
+extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, uchar *buf, size_t *size);
+
+/*
+ * Deserialize an lwgeom serialized form.
+ * The deserialized (recursive) structure will store
+ * pointers to the serialized form (POINTARRAYs).
+ */
+LWGEOM *lwgeom_deserialize(uchar *serializedform);
+
+/*
+ * Release memory associated with LWGEOM.
+ * POINTARRAYs are not released as they are usually
+ * pointers to user-managed memory.
+ * BBOX is released.
+ */
+void lwgeom_release(LWGEOM *lwgeom);
+
+/******************************************************************
+ * LWMULTIx and LWCOLLECTION functions
+ ******************************************************************/
+
+LWMPOINT *lwmpoint_deserialize(uchar *serializedform);
+LWMLINE *lwmline_deserialize(uchar *serializedform);
+LWMPOLY *lwmpoly_deserialize(uchar *serializedform);
+LWCOLLECTION *lwcollection_deserialize(uchar *serializedform);
+LWGEOM *lwcollection_getsubgeom(LWCOLLECTION *, int);
+
+/******************************************************************
+ * SERIALIZED FORM functions
+ ******************************************************************/
+
+
+/******************************************************************
+ * Multi-geometries
+ *
+ * These are all handled equivelently so its easy to write iterator code.
+ * NOTE NOTE: you can hand in a non-multigeometry to most of these functions
+ * and get usual behavior (ie. get geometry 0 on a POINT
+ * will return the point).
+ * This makes coding even easier since you dont have to necessarily
+ * differenciate between the multi* and non-multi geometries.
+ *
+ * NOTE: these usually work directly off the serialized form, so
+ * they're a little more difficult to handle (and slower)
+ * NOTE NOTE: the get functions maybe slow, so we may want to have an
+ * "analysed" lwgeom that would just have pointer to the start
+ * of each sub-geometry.
+ *
+ ******************************************************************/
+
+/* use this version for speed. READ-ONLY! */
+typedef struct
+{
+ int SRID;
+ const uchar *serialized_form; /* orginal structure */
+ uchar type; /* 8-bit type for the LWGEOM */
+ int ngeometries; /* number of sub-geometries */
+ uchar **sub_geoms; /* list of pointers (into serialized_form)
+ of the sub-geoms */
+} LWGEOM_INSPECTED;
+
+extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected,
+ int geom_number);
+
+/*
+ * note - for a simple type (ie. point), this will have
+ * sub_geom[0] = serialized_form.
+ * for multi-geomtries sub_geom[0] will be a few bytes into the
+ * serialized form.
+ * This function just computes the length of each sub-object and
+ * pre-caches this info.
+ * For a geometry collection of multi* geometries, you can inspect
+ * the sub-components as well.
+ */
+extern LWGEOM_INSPECTED *lwgeom_inspect(const uchar *serialized_form);
+
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a point (with geom_num=0), multipoint
+ * or geometrycollection
+ */
+extern LWPOINT *lwgeom_getpoint(uchar *serialized_form, int geom_number);
+extern LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual geometry isnt a LINE, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a line, multiline or geometrycollection
+ */
+extern LWLINE *lwgeom_getline(uchar *serialized_form, int geom_number);
+extern LWLINE *lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a polygon, multipolygon or geometrycollection
+ */
+extern LWPOLY *lwgeom_getpoly(uchar *serialized_form, int geom_number);
+extern LWPOLY *lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
+
+extern LWGEOM *lwgeom_getgeom_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
+
+/*
+ * this gets the serialized form of a sub-geometry
+ * 1st geometry has geom_number = 0
+ * if this isnt a multi* geometry, and geom_number ==0 then it returns
+ * itself
+ * returns null on problems.
+ * in the future this is how you would access a muli* portion of a
+ * geometry collection.
+ * GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1))
+ * ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1)
+ * --> POINT(1 1)
+ * you can inspect the sub-geometry as well if you wish.
+ */
+extern uchar *lwgeom_getsubgeometry(const uchar *serialized_form, int geom_number);
+extern uchar *lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
+
+
+/*
+ * 1st geometry has geom_number = 0
+ * use geom_number = -1 to find the actual type of the serialized form.
+ * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
+ * --> multipoint
+ * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
+ * --> point
+ * gets the 8bit type of the geometry at location geom_number
+ */
+extern uchar lwgeom_getsubtype(uchar *serialized_form, int geom_number);
+extern uchar lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
+
+
+/*
+ * how many sub-geometries are there?
+ * for point,line,polygon will return 1.
+ */
+extern int lwgeom_getnumgeometries(uchar *serialized_form);
+extern int lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected);
+
+
+
+/*
+ * set finalType to COLLECTIONTYPE or 0 (0 means choose a best type)
+ * (ie. give it 2 points and ask it to be a multipoint)
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
+ * all subgeometries must have the same SRID
+ * if you want to construct an inspected, call this then inspect the result...
+ */
+extern uchar *lwgeom_serialized_construct(int SRID, int finalType, char hasz, char hasm, int nsubgeometries, uchar **serialized_subs);
+
+
+/* construct the empty geometry (GEOMETRYCOLLECTION(EMPTY)) */
+extern uchar *lwgeom_constructempty(int SRID, char hasz, char hasm);
+extern void lwgeom_constructempty_buf(int SRID, char hasz, char hasm, uchar *buf, size_t *size);
+size_t lwgeom_empty_length(int SRID);
+
+/*
+ * get the SRID from the LWGEOM
+ * none present => -1
+ */
+extern int lwgeom_getsrid(uchar *serialized);
+
+
+/*------------------------------------------------------
+ * other stuff
+ *
+ * handle the double-to-float conversion. The results of this
+ * will usually be a slightly bigger box because of the difference
+ * between float8 and float4 representations.
+ */
+
+extern BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box);
+extern int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *res);
+
+extern BOX3D box2df_to_box3d(BOX2DFLOAT4 *box);
+extern void box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *box3d);
+
+extern BOX3D *box3d_union(BOX3D *b1, BOX3D *b2);
+extern int box3d_union_p(BOX3D *b1, BOX3D *b2, BOX3D *ubox);
+
+/*
+ * Returns a pointer to the BBOX internal to the serialized form.
+ * READ-ONLY!
+ * Or NULL if serialized form does not have a BBOX
+ * OBSOLETED to avoid memory alignment problems.
+ */
+/*extern BOX2DFLOAT4 *getbox2d_internal(uchar *serialized_form);*/
+
+/*
+ * this function writes to 'box' and returns 0 if serialized_form
+ * does not have a bounding box (empty geom)
+ */
+extern int getbox2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
+
+/* Expand given box of 'd' units in all directions */
+void expand_box2d(BOX2DFLOAT4 *box, double d);
+void expand_box3d(BOX3D *box, double d);
+
+/* Check if to boxes are equal (considering FLOAT approximations) */
+char box2d_same(BOX2DFLOAT4 *box1, BOX2DFLOAT4 *box2);
+
+/****************************************************************
+ * memory management -- these only delete the memory associated
+ * directly with the structure - NOT the stuff pointing into
+ * the original de-serialized info
+ ****************************************************************/
+
+
+extern void pfree_inspected(LWGEOM_INSPECTED *inspected);
+extern void pfree_point (LWPOINT *pt);
+extern void pfree_line (LWLINE *line);
+extern void pfree_polygon (LWPOLY *poly);
+extern void pfree_POINTARRAY(POINTARRAY *pa);
+
+
+/****************************************************************
+ * utility
+ ****************************************************************/
+
+extern uint32 lw_get_uint32(const uchar *loc);
+extern int32 lw_get_int32(const uchar *loc);
+extern void printBOX3D(BOX3D *b);
+extern void printPA(POINTARRAY *pa);
+extern void printLWPOINT(LWPOINT *point);
+extern void printLWLINE(LWLINE *line);
+extern void printLWPOLY(LWPOLY *poly);
+extern void printBYTES(uchar *a, int n);
+extern void printMULTI(uchar *serialized);
+extern void printType(uchar str);
+
+
+extern float LWGEOM_Minf(float a, float b);
+extern float LWGEOM_Maxf(float a, float b);
+extern double LWGEOM_Mind(double a, double b);
+extern double LWGEOM_Maxd(double a, double b);
+
+extern float nextDown_f(double d);
+extern float nextUp_f(double d);
+extern double nextDown_d(float d);
+extern double nextUp_d(float d);
+
+extern float nextafterf_custom(float x, float y);
+
+
+#define LW_MAX(a,b) ((a) > (b) ? (a) : (b))
+#define LW_MIN(a,b) ((a) <= (b) ? (a) : (b))
+#define LW_ABS(a) ((a) < (0) ? (-a) : (a))
+
+
+/* general utilities */
+extern double lwgeom_polygon_area(LWPOLY *poly);
+extern double lwgeom_polygon_perimeter(LWPOLY *poly);
+extern double lwgeom_polygon_perimeter2d(LWPOLY *poly);
+extern double lwgeom_pointarray_length2d(POINTARRAY *pts);
+extern double lwgeom_pointarray_length(POINTARRAY *pts);
+extern void lwgeom_force2d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
+extern void lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize);
+extern void lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize);
+extern void lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
+extern double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
+extern double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
+extern double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D);
+extern double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa);
+extern double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2);
+extern int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring);
+extern int pt_in_poly_2d(POINT2D *p, LWPOLY *poly);
+extern double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly);
+extern double distance2d_point_point(LWPOINT *point1, LWPOINT *point2);
+extern double distance2d_point_line(LWPOINT *point, LWLINE *line);
+extern double distance2d_line_line(LWLINE *line1, LWLINE *line2);
+extern double distance2d_point_poly(LWPOINT *point, LWPOLY *poly);
+extern double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2);
+extern double distance2d_line_poly(LWLINE *line, LWPOLY *poly);
+extern int azimuth_pt_pt(POINT2D *p1, POINT2D *p2, double *ret);
+extern double lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2);
+extern double lwgeom_mindistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance);
+extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
+extern int32 lwgeom_npoints(uchar *serialized);
+extern char ptarray_isccw(const POINTARRAY *pa);
+extern void lwgeom_reverse(LWGEOM *lwgeom);
+extern void lwline_reverse(LWLINE *line);
+extern void lwpoly_reverse(LWPOLY *poly);
+extern void lwpoly_forceRHR(LWPOLY *poly);
+extern void lwgeom_forceRHR(LWGEOM *lwgeom);
+extern char *lwgeom_summary(LWGEOM *lwgeom, int offset);
+extern const char *lwgeom_typename(int type);
+extern int ptarray_compute_box2d_p(const POINTARRAY *pa, BOX2DFLOAT4 *result);
+extern BOX2DFLOAT4 *ptarray_compute_box2d(const POINTARRAY *pa);
+extern int lwpoint_compute_box2d_p(LWPOINT *point, BOX2DFLOAT4 *box);
+extern int lwline_compute_box2d_p(LWLINE *line, BOX2DFLOAT4 *box);
+extern int lwpoly_compute_box2d_p(LWPOLY *poly, BOX2DFLOAT4 *box);
+extern int lwcollection_compute_box2d_p(LWCOLLECTION *col, BOX2DFLOAT4 *box);
+extern BOX2DFLOAT4 *lwgeom_compute_box2d(LWGEOM *lwgeom);
+
+extern void interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F);
+
+/* return alloced memory */
+extern BOX2DFLOAT4 *box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2);
+
+/* args may overlap ! */
+extern int box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox);
+extern int lwgeom_compute_box2d_p(LWGEOM *lwgeom, BOX2DFLOAT4 *box);
+void lwgeom_longitude_shift(LWGEOM *lwgeom);
+
+/* Is lwgeom1 geometrically equal to lwgeom2 ? */
+char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2);
+char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2);
+char lwpoint_same(const LWPOINT *p1, const LWPOINT *p2);
+char lwline_same(const LWLINE *p1, const LWLINE *p2);
+char lwpoly_same(const LWPOLY *p1, const LWPOLY *p2);
+char lwcollection_same(const LWCOLLECTION *p1, const LWCOLLECTION *p2);
+
+/*
+ * Add 'what' to 'to' at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Mix of dimensions is not allowed (TODO: allow it?).
+ * Returns a newly allocated LWGEOM (with NO BBOX)
+ */
+extern LWGEOM *lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what);
+
+LWGEOM *lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what);
+LWGEOM *lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what);
+LWGEOM *lwpoly_add(const LWPOLY *to, uint32 where, const LWGEOM *what);
+LWGEOM *lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what);
+LWGEOM *lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what);
+LWGEOM *lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what);
+LWGEOM *lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what);
+
+/*
+ * Clone an LWGEOM
+ * pointarray are not copied.
+ * BBOXes are copied
+ */
+extern LWGEOM *lwgeom_clone(const LWGEOM *lwgeom);
+extern LWPOINT *lwpoint_clone(const LWPOINT *lwgeom);
+extern LWLINE *lwline_clone(const LWLINE *lwgeom);
+extern LWPOLY *lwpoly_clone(const LWPOLY *lwgeom);
+extern LWCOLLECTION *lwcollection_clone(const LWCOLLECTION *lwgeom);
+extern BOX2DFLOAT4 *box2d_clone(const BOX2DFLOAT4 *lwgeom);
+extern POINTARRAY *ptarray_clone(const POINTARRAY *ptarray);
+
+/*
+ * Geometry constructors
+ * Take ownership of arguments
+ */
+extern LWPOINT *lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox,
+ POINTARRAY *point);
+extern LWLINE *lwline_construct(int SRID, BOX2DFLOAT4 *bbox,
+ POINTARRAY *points);
+
+/*
+ * Construct a new LWPOLY. arrays (points/points per ring) will NOT be copied
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
+ */
+extern LWPOLY *lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox,
+ unsigned int nrings, POINTARRAY **points);
+
+extern LWCOLLECTION *lwcollection_construct(unsigned int type, int SRID,
+ BOX2DFLOAT4 *bbox, unsigned int ngeoms, LWGEOM **geoms);
+extern LWCOLLECTION *lwcollection_construct_empty(int SRID,
+ char hasZ, char hasM);
+
+/* Other constructors */
+extern LWPOINT *make_lwpoint2d(int SRID, double x, double y);
+extern LWPOINT *make_lwpoint3dz(int SRID, double x, double y, double z);
+extern LWPOINT *make_lwpoint3dm(int SRID, double x, double y, double m);
+extern LWPOINT *make_lwpoint4d(int SRID, double x, double y, double z, double m);
+extern LWLINE *lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points);
+extern LWLINE *lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint);
+extern LWLINE *lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where);
+extern LWLINE *lwline_removepoint(LWLINE *line, unsigned int which);
+extern void lwline_setPoint4d(LWLINE *line, unsigned int which, POINT4D *newpoint);
+extern LWPOLY *lwpoly_from_lwlines(const LWLINE *shell, unsigned int nholes, const LWLINE **holes);
+
+/* Return a char string with ASCII versionf of type flags */
+extern const char *lwgeom_typeflags(uchar type);
+
+/* Construct an empty pointarray */
+extern POINTARRAY *ptarray_construct(char hasz, char hasm,
+ unsigned int npoints);
+
+/*
+ * extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts);
+ * extern POINTARRAY *ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts);
+ * extern POINTARRAY *ptarray_construct3dm(uint32 npoints, const POINT3DM *pts);
+ * extern POINTARRAY *ptarray_construct4d(uint32 npoints, const POINT4D *pts);
+ */
+
+extern POINTARRAY *ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims,
+ unsigned int where);
+extern POINTARRAY *ptarray_removePoint(POINTARRAY *pa, unsigned int where);
+
+extern int ptarray_isclosed2d(const POINTARRAY *pa);
+
+extern void ptarray_longitude_shift(POINTARRAY *pa);
+
+extern int32 lwgeom_nrings_recursive(uchar *serialized);
+extern void ptarray_reverse(POINTARRAY *pa);
+extern POINTARRAY *ptarray_substring(POINTARRAY *, double, double);
+extern double ptarray_locate_point(POINTARRAY *, POINT2D *);
+extern void closest_point_on_segment(POINT2D *p, POINT2D *A, POINT2D *B, POINT2D *ret);
+
+/*
+ * Ensure every segment is at most 'dist' long.
+ * Returned LWGEOM might is unchanged if a POINT.
+ */
+extern LWGEOM *lwgeom_segmentize2d(LWGEOM *line, double dist);
+extern POINTARRAY *ptarray_segmentize2d(POINTARRAY *ipa, double dist);
+extern LWLINE *lwline_segmentize2d(LWLINE *line, double dist);
+extern LWPOLY *lwpoly_segmentize2d(LWPOLY *line, double dist);
+extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
+
+extern uchar parse_hex(char *str);
+extern void deparse_hex(uchar str, char *result);
+
+/* Parser access routines */
+extern char *unparse_WKT(uchar* serialized, lwallocator alloc, lwfreeor free);
+extern char *unparse_WKB(uchar* serialized, lwallocator alloc, lwfreeor free, char endian, size_t *outsize, uchar hex);
+
+extern SERIALIZED_LWGEOM *parse_lwgeom_wkt(char *wkt_input);
+extern char *lwgeom_to_ewkt(LWGEOM *lwgeom);
+extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder);
+extern LWGEOM *lwgeom_from_ewkb(uchar *ewkb, size_t ewkblen);
+extern uchar *lwgeom_to_ewkb(LWGEOM *lwgeom, char byteorder, size_t *ewkblen);
+
+extern void *lwalloc(size_t size);
+extern void *lwrealloc(void *mem, size_t size);
+extern void lwfree(void *mem);
+
+/* Utilities */
+extern void trim_trailing_zeros(char *num);
+
+/* Machine endianness */
+#define XDR 0
+#define NDR 1
+extern char getMachineEndian(void);
+
+void errorIfSRIDMismatch(int srid1, int srid2);
+
+/* CURVETYPE */
+typedef struct
+{
+ uchar type; /* CURVETYPE */
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ POINTARRAY *points; /* array of POINT(3D/3DM) */
+} LWCURVE; /* "light-weight arcline" */
+
+/* COMPOUNDTYPE */
+typedef struct
+{
+ uchar type; /* COMPOUNDTYPE */
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int ngeoms;
+ LWGEOM **geoms;
+} LWCOMPOUND; /* "light-weight compound line" */
+
+/* CURVEPOLYTYPE */
+typedef struct
+{
+ uchar type; /* CURVEPOLYTYPE */
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int nrings;
+ LWGEOM **rings; /* list of rings (list of points) */
+} LWCURVEPOLY; /* "light-weight polygon" */
+
+/* MULTICURVE */
+typedef struct
+{
+ uchar type;
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int ngeoms;
+ LWGEOM **geoms;
+} LWMCURVE;
+
+/* MULTISURFACETYPE */
+typedef struct
+{
+ uchar type;
+ BOX2DFLOAT4 *bbox;
+ uint32 SRID;
+ int ngeoms;
+ LWGEOM **geoms;
+} LWMSURFACE;
+
+#define CURVETYPE 8
+#define COMPOUNDTYPE 9
+#define CURVEPOLYTYPE 13
+#define MULTICURVETYPE 14
+#define MULTISURFACETYPE 15
+
+/******************************************************************
+ * LWCURVE functions
+ ******************************************************************/
+
+/* Casts LWGEOM->LW* (return NULL if cast is illegal) */
+extern LWCURVE *lwgeom_as_lwcurve(LWGEOM *lwgeom);
+
+
+LWCURVE *lwcurve_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points);
+
+/*
+ * given the LWGEOM serialized form (or a pointer into a muli* one)
+ * construct a proper LWCURVE.
+ * serialized_form should point to the 8bit type format (with type = 2)
+ * See SERIALIZED_FORM doc
+ */
+extern LWCURVE *lwcurve_deserialize(uchar *serialized_form);
+
+/* find the size this curve would get when serialized */
+extern size_t lwcurve_serialize_size(LWCURVE *curve);
+
+/*
+ * convert this curve into its serialize form
+ * result's first char will be the 8bit type. See serialized form doc
+ * copies data.
+ */
+extern uchar *lwcurve_serialize(LWCURVE *curve);
+
+/* same as above, writes to buf */
+extern void lwcurve_serialize_buf(LWCURVE *curve, uchar *buf, size_t *size);
+
+/*
+ * find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
+ */
+extern BOX3D *lwcurve_compute_box3d(LWCURVE *curve);
+
+LWGEOM *lwcurve_add(const LWCURVE *to, uint32 where, const LWGEOM *what);
+extern int lwcurve_compute_box2d_p(LWCURVE *curve, BOX2DFLOAT4 *box);
+extern BOX3D *lwcurve_compute_box3d(LWCURVE *curve);
+extern void pfree_curve(LWCURVE *curve);
+LWCURVE *lwcurve_clone(const LWCURVE *curve);
+
+/******************************************************************
+ * LWMULTIx and LWCOLLECTION functions
+ ******************************************************************/
+
+LWCOMPOUND *lwcompound_deserialize(uchar *serialized_form);
+
+LWGEOM *lwcompound_add(const LWCOMPOUND *to, uint32 where, const LWGEOM *what);
+
+LWCURVEPOLY *lwcurvepoly_deserialize(uchar *serialized_form);
+
+LWGEOM *lwcurvepoly_add(const LWCURVEPOLY *to, uint32 where, const LWGEOM *what);
+
+LWMCURVE *lwmcurve_deserialize(uchar *serialized_form);
+
+LWGEOM *lwmcurve_add(const LWMCURVE *to, uint32 where, const LWGEOM *what);
+
+LWMSURFACE *lwmsurface_deserialize(uchar *serialized_form);
+
+LWGEOM *lwmsurface_add(const LWMSURFACE *to, uint32 where, const LWGEOM *what);
+
+/*******************************************************************************
+ * SQLMM internal functions
+ ******************************************************************************/
+
+uint32 has_arc(LWGEOM *geom);
+double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
+LWGEOM *lwgeom_segmentize(LWGEOM *geom, uint32 perQuad);
+extern double lwgeom_curvepolygon_area(LWCURVEPOLY *curvepoly);
+double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
+
+#endif /* !defined _LIBLWGEOM_H */
+
Added: trunk/liblwgeom/lwcollection.c
===================================================================
--- trunk/liblwgeom/lwcollection.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwcollection.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,356 @@
+/**********************************************************************
+ * $Id: lwcollection.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+
+#define CHECK_LWGEOM_ZM 1
+
+LWCOLLECTION *
+lwcollection_construct(unsigned int type, int SRID, BOX2DFLOAT4 *bbox,
+ unsigned int ngeoms, LWGEOM **geoms)
+{
+ LWCOLLECTION *ret;
+ int hasz, hasm;
+#ifdef CHECK_LWGEOM_ZM
+ char zm;
+ unsigned int i;
+#endif
+
+ LWDEBUGF(2, "lwcollection_construct called with %d, %d, %p, %d, %p.", type, SRID, bbox, ngeoms, geoms);
+
+ hasz = 0;
+ hasm = 0;
+ if ( ngeoms > 0 )
+ {
+ hasz = TYPE_HASZ(geoms[0]->type);
+ hasm = TYPE_HASM(geoms[0]->type);
+#ifdef CHECK_LWGEOM_ZM
+ zm = TYPE_GETZM(geoms[0]->type);
+
+ LWDEBUGF(3, "lwcollection_construct type[0]=%d", geoms[0]->type);
+
+ for (i=1; i<ngeoms; i++)
+ {
+ LWDEBUGF(3, "lwcollection_construct type=[%d]=%d", i, geoms[i]->type);
+
+ if ( zm != TYPE_GETZM(geoms[i]->type) )
+ lwerror("lwcollection_construct: mixed dimension geometries: %d/%d", zm, TYPE_GETZM(geoms[i]->type));
+ }
+#endif
+ }
+
+
+ ret = lwalloc(sizeof(LWCOLLECTION));
+ ret->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1),
+ type, 0);
+ ret->SRID = SRID;
+ ret->ngeoms = ngeoms;
+ ret->geoms = geoms;
+ ret->bbox = bbox;
+
+ return ret;
+}
+
+LWCOLLECTION *
+lwcollection_construct_empty(int SRID, char hasz, char hasm)
+{
+ LWCOLLECTION *ret;
+
+ ret = lwalloc(sizeof(LWCOLLECTION));
+ ret->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1),
+ COLLECTIONTYPE, 0);
+ ret->SRID = SRID;
+ ret->ngeoms = 0;
+ ret->geoms = NULL;
+ ret->bbox = NULL;
+
+ return ret;
+}
+
+
+LWCOLLECTION *
+lwcollection_deserialize(uchar *srl)
+{
+ LWCOLLECTION *result;
+ LWGEOM_INSPECTED *insp;
+ char typefl = srl[0];
+ int type = lwgeom_getType(typefl);
+ int i;
+
+ if ( type != COLLECTIONTYPE )
+ {
+ lwerror("lwcollection_deserialize called on NON geometrycollection: %d", type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(srl);
+
+ result = lwalloc(sizeof(LWCOLLECTION));
+ result->type = typefl;
+ result->SRID = insp->SRID;
+ result->ngeoms = insp->ngeometries;
+
+ if (lwgeom_hasBBOX(srl[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+
+ if ( insp->ngeometries )
+ {
+ result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
+ for (i=0; i<insp->ngeometries; i++)
+ {
+ result->geoms[i] =
+ lwgeom_deserialize(insp->sub_geoms[i]);
+ }
+ }
+
+ return result;
+}
+
+LWGEOM *
+lwcollection_getsubgeom(LWCOLLECTION *col, int gnum)
+{
+ return (LWGEOM *)col->geoms[gnum];
+}
+
+/* find serialized size of this collection */
+size_t
+lwcollection_serialize_size(LWCOLLECTION *col)
+{
+ size_t size = 5; /* type + nsubgeoms */
+ int i;
+
+ if ( col->SRID != -1 ) size += 4; /* SRID */
+ if ( col->bbox ) size += sizeof(BOX2DFLOAT4);
+
+ LWDEBUGF(2, "lwcollection_serialize_size[%p]: start size: %d", col, size);
+
+
+ for (i=0; i<col->ngeoms; i++)
+ {
+ size += lwgeom_serialize_size(col->geoms[i]);
+
+ LWDEBUGF(3, "lwcollection_serialize_size[%p]: with geom%d: %d", col, i, size);
+ }
+
+ LWDEBUGF(3, "lwcollection_serialize_size[%p]: returning %d", col, size);
+
+ return size;
+}
+
+/*
+ * convert this collectoin into its serialize form writing it into
+ * the given buffer, and returning number of bytes written into
+ * the given int pointer.
+ */
+void
+lwcollection_serialize_buf(LWCOLLECTION *coll, uchar *buf, size_t *retsize)
+{
+ size_t size=1; /* type */
+ size_t subsize=0;
+ char hasSRID;
+ uchar *loc;
+ int i;
+
+ LWDEBUGF(2, "lwcollection_serialize_buf called (%s with %d elems)",
+ lwgeom_typename(TYPE_GETTYPE(coll->type)), coll->ngeoms);
+
+ hasSRID = (coll->SRID != -1);
+
+ buf[0] = lwgeom_makeType_full(
+ TYPE_HASZ(coll->type), TYPE_HASM(coll->type),
+ hasSRID, TYPE_GETTYPE(coll->type), coll->bbox ? 1 : 0);
+ loc = buf+1;
+
+ /* Add BBOX if requested */
+ if ( coll->bbox )
+ {
+ memcpy(loc, coll->bbox, sizeof(BOX2DFLOAT4));
+ size += sizeof(BOX2DFLOAT4);
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ /* Add SRID if requested */
+ if (hasSRID)
+ {
+ memcpy(loc, &coll->SRID, 4);
+ size += 4;
+ loc += 4;
+ }
+
+ /* Write number of subgeoms */
+ memcpy(loc, &coll->ngeoms, 4);
+ size += 4;
+ loc += 4;
+
+ /* Serialize subgeoms */
+ for (i=0; i<coll->ngeoms; i++)
+ {
+ lwgeom_serialize_buf(coll->geoms[i], loc, &subsize);
+ size += subsize;
+ loc += subsize;
+ }
+
+ if (retsize) *retsize = size;
+
+ LWDEBUG(3, "lwcollection_serialize_buf returning");
+}
+
+int
+lwcollection_compute_box2d_p(LWCOLLECTION *col, BOX2DFLOAT4 *box)
+{
+ BOX2DFLOAT4 boxbuf;
+ uint32 i;
+
+ if ( ! col->ngeoms ) return 0;
+ if ( ! lwgeom_compute_box2d_p(col->geoms[0], box) ) return 0;
+ for (i=1; i<col->ngeoms; i++)
+ {
+ if ( ! lwgeom_compute_box2d_p(col->geoms[i], &boxbuf) )
+ return 0;
+ if ( ! box2d_union_p(box, &boxbuf, box) ) return 0;
+ }
+ return 1;
+}
+
+/*
+ * Clone LWCOLLECTION object. POINTARRAY are not copied.
+ * Bbox is cloned if present in input.
+ */
+LWCOLLECTION *
+lwcollection_clone(const LWCOLLECTION *g)
+{
+ uint32 i;
+ LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
+ memcpy(ret, g, sizeof(LWCOLLECTION));
+ if ( g->ngeoms > 0 )
+ {
+ ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
+ for (i=0; i<g->ngeoms; i++)
+ {
+ ret->geoms[i] = lwgeom_clone(g->geoms[i]);
+ }
+ if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
+ }
+ else
+ {
+ ret->bbox = NULL; /* empty collection */
+ ret->geoms = NULL;
+ }
+ return ret;
+}
+
+/*
+ * Add 'what' to this collection at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a GEOMETRYCOLLECTION
+ */
+LWGEOM *
+lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ uint32 i;
+
+ if ( where == -1 ) where = to->ngeoms;
+ else if ( where < -1 || where > to->ngeoms )
+ {
+ lwerror("lwcollection_add: add position out of range %d..%d",
+ -1, to->ngeoms);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
+ for (i=0; i<where; i++)
+ {
+ geoms[i] = lwgeom_clone(to->geoms[i]);
+ lwgeom_dropSRID(geoms[i]);
+ lwgeom_dropBBOX(geoms[i]);
+ }
+ geoms[where] = lwgeom_clone(what);
+ lwgeom_dropSRID(geoms[where]);
+ lwgeom_dropBBOX(geoms[where]);
+ for (i=where; i<to->ngeoms; i++)
+ {
+ geoms[i+1] = lwgeom_clone(to->geoms[i]);
+ lwgeom_dropSRID(geoms[i+1]);
+ lwgeom_dropBBOX(geoms[i+1]);
+ }
+
+ col = lwcollection_construct(COLLECTIONTYPE,
+ to->SRID, NULL,
+ to->ngeoms+1, geoms);
+
+ return (LWGEOM *)col;
+
+}
+
+LWCOLLECTION *
+lwcollection_segmentize2d(LWCOLLECTION *col, double dist)
+{
+ unsigned int i;
+ LWGEOM **newgeoms;
+
+ if ( ! col->ngeoms ) return col;
+
+ newgeoms = lwalloc(sizeof(LWGEOM *)*col->ngeoms);
+ for (i=0; i<col->ngeoms; i++)
+ newgeoms[i] = lwgeom_segmentize2d(col->geoms[i], dist);
+
+ return lwcollection_construct(col->type, col->SRID, NULL,
+ col->ngeoms, newgeoms);
+}
+
+/* check for same geometry composition */
+char
+lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2)
+{
+ unsigned int i, j;
+ unsigned int *hit;
+
+ LWDEBUG(2, "lwcollection_same called");
+
+ if ( TYPE_GETTYPE(c1->type) != TYPE_GETTYPE(c2->type) ) return 0;
+ if ( c1->ngeoms != c2->ngeoms ) return 0;
+
+ hit = lwalloc(sizeof(unsigned int)*c1->ngeoms);
+ memset(hit, 0, sizeof(unsigned int)*c1->ngeoms);
+
+ for (i=0; i<c1->ngeoms; i++)
+ {
+ char found=0;
+ for (j=0; j<c2->ngeoms; j++)
+ {
+ if ( hit[j] ) continue;
+ if ( lwgeom_same(c1->geoms[i], c2->geoms[j]) )
+ {
+ hit[j] = 1;
+ found=1;
+ break;
+ }
+ }
+ if ( ! found ) return 0;
+ }
+ return 1;
+}
Added: trunk/liblwgeom/lwcompound.c
===================================================================
--- trunk/liblwgeom/lwcompound.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwcompound.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,118 @@
+/**********************************************************************
+ * $Id$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+LWCOMPOUND *
+lwcompound_deserialize(uchar *serialized)
+{
+ LWCOMPOUND *result;
+ LWGEOM_INSPECTED *insp;
+ int type = lwgeom_getType(serialized[0]);
+ int i;
+
+ if(type != COMPOUNDTYPE)
+ {
+ lwerror("lwcompound_deserialize called on non compound: %d", type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(serialized);
+
+ result = lwalloc(sizeof(LWCOMPOUND));
+ result->type = insp->type;
+ result->SRID = insp->SRID;
+ result->ngeoms = insp->ngeometries;
+ result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
+
+ if(lwgeom_hasBBOX(serialized[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, serialized + 1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+ for(i = 0; i < insp->ngeometries; i++)
+ {
+ if(lwgeom_getType(insp->sub_geoms[i][0]) == LINETYPE)
+ result->geoms[i] = (LWGEOM *)lwline_deserialize(insp->sub_geoms[i]);
+ else
+ result->geoms[i] = (LWGEOM *)lwcurve_deserialize(insp->sub_geoms[i]);
+ if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
+ {
+ lwerror("Mixed dimensions (compound:%d, line/curve%d:%d)",
+ TYPE_NDIMS(result->type), i,
+ TYPE_NDIMS(result->geoms[i]->type)
+ );
+ lwfree(result);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+/*
+ * Add 'what' to this string at position 'where'
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a COMPOUND or a GEOMETRYCOLLECTION
+ */
+LWGEOM *
+lwcompound_add(const LWCOMPOUND *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+
+ LWDEBUG(2, "lwcompound_add called.");
+
+ if(where != -1 && where != 0)
+ {
+ lwerror("lwcompound_add only supports 0 or -1 as a second argument, not %d", where);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*2);
+ if(where == -1) /* append */
+ {
+ geoms[0] = lwgeom_clone((LWGEOM *)to);
+ geoms[1] = lwgeom_clone(what);
+ }
+ else /* prepend */
+ {
+ geoms[0] = lwgeom_clone(what);
+ geoms[1] = lwgeom_clone((LWGEOM *)to);
+ }
+
+ /* reset SRID and wantbbox flag from component types */
+ geoms[0]->SRID = geoms[1]->SRID = -1;
+ TYPE_SETHASSRID(geoms[0]->type, 0);
+ TYPE_SETHASSRID(geoms[1]->type, 0);
+ TYPE_SETHASBBOX(geoms[0]->type, 0);
+ TYPE_SETHASBBOX(geoms[1]->type, 0);
+
+ /* Find appropriate geom type */
+ if(TYPE_GETTYPE(what->type) == LINETYPE || TYPE_GETTYPE(what->type) == CURVETYPE) newtype = COMPOUNDTYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL, 2, geoms);
+
+ return (LWGEOM *)col;
+}
+
Added: trunk/liblwgeom/lwcurve.c
===================================================================
--- trunk/liblwgeom/lwcurve.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwcurve.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,707 @@
+/**********************************************************************
+ * $Id$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+/* basic LWCURVE functions */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "liblwgeom.h"
+
+BOX3D *lwcircle_compute_box3d(POINT4D *p1, POINT4D *p2, POINT4D *p3);
+void printLWCURVE(LWCURVE *curve);
+void lwcurve_reverse(LWCURVE *curve);
+LWCURVE *lwcurve_segmentize2d(LWCURVE *curve, double dist);
+char lwcurve_same(const LWCURVE *me, const LWCURVE *you);
+LWCURVE *lwcurve_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points);
+LWCURVE *lwcurve_from_lwmpoint(int SRID, LWMPOINT *mpoint);
+LWCURVE *lwcurve_addpoint(LWCURVE *curve, LWPOINT *point, unsigned int where);
+LWCURVE *lwcurve_removepoint(LWCURVE *curve, unsigned int index);
+void lwcurve_setPoint4d(LWCURVE *curve, unsigned int index, POINT4D *newpoint);
+
+
+
+#ifndef MAXFLOAT
+ #define MAXFLOAT 3.402823466e+38F
+#endif
+
+/*
+ * Construct a new LWCURVE. points will *NOT* be copied
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
+ */
+LWCURVE *
+lwcurve_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points)
+{
+ LWCURVE *result;
+
+ /*
+ * The first arc requires three points. Each additional
+ * arc requires two more points. Thus the minimum point count
+ * is three, and the count must be odd.
+ */
+ if(points->npoints % 2 != 1 || points->npoints < 3)
+ {
+ lwerror("lwcurve_construct: invalid point count %d", points->npoints);
+ return NULL;
+ }
+
+ result = (LWCURVE*) lwalloc(sizeof(LWCURVE));
+
+ result->type = lwgeom_makeType_full(
+ TYPE_HASZ(points->dims),
+ TYPE_HASM(points->dims),
+ (SRID!=-1), CURVETYPE, 0);
+ result->SRID = SRID;
+ result->points = points;
+ result->bbox = bbox;
+
+ return result;
+}
+
+/*
+ * given the LWGEOM serialized form (or a point into a multi* one)
+ * construct a propert LWCURVE.
+ * serialized_form should point to the 8bit type format (with type = 8)
+ * See serialized form doc
+ */
+LWCURVE *
+lwcurve_deserialize(uchar *serialized_form)
+{
+ uchar type;
+ LWCURVE *result;
+ uchar *loc=NULL;
+ uint32 npoints;
+ POINTARRAY *pa;
+
+ type = (uchar)serialized_form[0];
+ if(lwgeom_getType(type) != CURVETYPE)
+ {
+ lwerror("lwcurve_deserialize: attempt to deserialize a curve which is really a %s", lwgeom_typename(type));
+ return NULL;
+ }
+
+ result = (LWCURVE*) lwalloc(sizeof(LWCURVE));
+ result->type = type;
+
+ loc = serialized_form + 1;
+
+ if(lwgeom_hasBBOX(type))
+ {
+ LWDEBUG(3, "lwcurve_deserialize: input has bbox");
+
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
+ loc += sizeof(BOX2DFLOAT4);
+ }
+ else
+ {
+ LWDEBUG(3, "lwcurve_deserialize: input lacks bbox");
+
+ result->bbox = NULL;
+ }
+
+ if(lwgeom_hasSRID(type))
+ {
+ LWDEBUG(3, "lwcurve_deserialize: input has srid");
+
+ result->SRID = lw_get_int32(loc);
+ loc += 4; /* type + SRID */
+ }
+ else
+ {
+ LWDEBUG(3, "lwcurve_deserialize: input lacks srid");
+
+ result->SRID = -1;
+ }
+
+ /* we've read the type (1 byte) and SRID (4 bytes, if present) */
+
+ npoints = lw_get_uint32(loc);
+
+ LWDEBUGF(3, "curve npoints = %d", npoints);
+
+ loc += 4;
+ pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints);
+ result->points = pa;
+ return result;
+}
+
+/*
+ * convert this curve into its serialized form
+ * result's first char will be the 8bit type. See serialized form doc
+ */
+uchar *
+lwcurve_serialize(LWCURVE *curve)
+{
+ size_t size, retsize;
+ uchar * result;
+
+ if(curve == NULL) {
+ lwerror("lwcurve_serialize:: given null curve");
+ return NULL;
+ }
+
+ size = lwcurve_serialize_size(curve);
+ result = lwalloc(size);
+ lwcurve_serialize_buf(curve, result, &retsize);
+ if(retsize != size)
+ lwerror("lwcurve_serialize_size returned %d, ..selialize_buf returned %d", size, retsize);
+ return result;
+}
+
+/*
+ * convert this curve into its serialized form writing it into
+ * the given buffer, and returning number of bytes written into
+ * the given int pointer.
+ * result's first char will be the 8bit type. See serialized form doc
+ */
+void lwcurve_serialize_buf(LWCURVE *curve, uchar *buf, size_t *retsize)
+{
+ char hasSRID;
+ uchar *loc;
+ int ptsize;
+ size_t size;
+
+ LWDEBUGF(2, "lwcurve_serialize_buf(%p, %p, %p) called",
+ curve, buf, retsize);
+
+ if(curve == NULL)
+ {
+ lwerror("lwcurve_serialize:: given null curve");
+ return;
+ }
+
+ if(TYPE_GETZM(curve->type) != TYPE_GETZM(curve->points->dims))
+ {
+ lwerror("Dimensions mismatch in lwcurve");
+ return;
+ }
+
+ ptsize = pointArray_ptsize(curve->points);
+
+ hasSRID = (curve->SRID != -1);
+
+ buf[0] = (uchar)lwgeom_makeType_full(
+ TYPE_HASZ(curve->type), TYPE_HASM(curve->type),
+ hasSRID, CURVETYPE, curve->bbox ? 1 : 0);
+ loc = buf+1;
+
+ LWDEBUGF(3, "lwcurve_serialize_buf added type (%d)", curve->type);
+
+ if(curve->bbox)
+ {
+ memcpy(loc, curve->bbox, sizeof(BOX2DFLOAT4));
+ loc += sizeof(BOX2DFLOAT4);
+
+ LWDEBUG(3, "lwcurve_serialize_buf added BBOX");
+ }
+
+ if(hasSRID)
+ {
+ memcpy(loc, &curve->SRID, sizeof(int32));
+ loc += sizeof(int32);
+
+ LWDEBUG(3, "lwcurve_serialize_buf added SRID");
+ }
+
+ memcpy(loc, &curve->points->npoints, sizeof(uint32));
+ loc += sizeof(uint32);
+
+ LWDEBUGF(3, "lwcurve_serialize_buf added npoints (%d)",
+ curve->points->npoints);
+
+ /* copy in points */
+ size = curve->points->npoints * ptsize;
+ memcpy(loc, getPoint_internal(curve->points, 0), size);
+ loc += size;
+
+ LWDEBUGF(3, "lwcurve_serialize_buf copied serialized_pointlist (%d bytes)",
+ ptsize * curve->points->npoints);
+
+ if(retsize) *retsize = loc-buf;
+
+ LWDEBUGF(3, "lwcurve_serialize_buf returning (loc: %p, size: %d)",
+ loc, loc-buf);
+}
+
+/* find length of this deserialized curve */
+size_t
+lwcurve_serialize_size(LWCURVE *curve)
+{
+ size_t size = 1; /* type */
+
+ LWDEBUG(2, "lwcurve_serialize_size called");
+
+ if(curve->SRID != -1) size += 4; /* SRID */
+ if(curve->bbox) size += sizeof(BOX2DFLOAT4);
+
+ size += 4; /* npoints */
+ size += pointArray_ptsize(curve->points) * curve->points->npoints;
+
+ LWDEBUGF(3, "lwcurve_serialize_size returning %d", size);
+
+ return size;
+}
+
+BOX3D *
+lwcircle_compute_box3d(POINT4D *p1, POINT4D *p2, POINT4D *p3)
+{
+ double x1, x2, y1, y2, z1, z2;
+ double angle, radius, sweep;
+ /*
+ double top, left;
+ */
+ double a1, a2, a3;
+ double xe = 0.0, ye = 0.0;
+ POINT4D *center;
+ int i;
+ BOX3D *box;
+
+ LWDEBUG(2, "lwcircle_compute_box3d called.");
+
+ center = lwalloc(sizeof(POINT4D));
+ radius = lwcircle_center(p1, p2, p3, ¢er);
+ if(radius < 0.0) return NULL;
+
+ /*
+ top = center->y + radius;
+ left = center->x - radius;
+
+ LWDEBUGF(3, "lwcircle_compute_box3d: top=%.16f, left=%.16f", top, left);
+ */
+
+ x1 = MAXFLOAT;
+ x2 = -1 * MAXFLOAT;
+ y1 = MAXFLOAT;
+ y2 = -1 * MAXFLOAT;
+
+ a1 = atan2(p1->y - center->y, p1->x - center->x);
+ a2 = atan2(p2->y - center->y, p2->x - center->x);
+ a3 = atan2(p3->y - center->y, p3->x - center->x);
+
+ /* Determine sweep angle */
+ if(a1 > a2 && a2 > a3)
+ {
+ sweep = a3 - a1;
+ }
+ /* Counter-clockwise */
+ else if(a1 < a2 && a2 < a3)
+ {
+ sweep = a3 - a1;
+ }
+ /* Clockwise, wrap */
+ else if((a1 < a2 && a1 > a3) || (a2 < a3 && a1 > a3))
+ {
+ sweep = a3 - a1 + 2*M_PI;
+ }
+ /* Counter-clockwise, wrap */
+ else if((a1 > a2 && a1 < a3) || (a2 > a3 && a1 < a3))
+ {
+ sweep = a3 - a1 - 2*M_PI;
+ }
+ else
+ {
+ sweep = 0.0;
+ }
+
+ LWDEBUGF(3, "a1 %.16f, a2 %.16f, a3 %.16f, sweep %.16f", a1, a2, a3, sweep);
+
+ angle = 0.0;
+ for(i=0; i < 6; i++)
+ {
+ switch(i) {
+ case 0:
+ angle = 0.0;
+ xe = center->x + radius;
+ ye = center->y;
+ break;
+ case 1:
+ angle = M_PI_2;
+ xe = center->x;
+ ye = center->y + radius;
+ break;
+ case 2:
+ angle = M_PI;
+ xe = center->x - radius;
+ ye = center->y;
+ break;
+ case 3:
+ angle = -1 * M_PI_2;
+ xe = center->x;
+ ye = center->y - radius;
+ break;
+ case 4:
+ angle = a1;
+ xe = p1->x;
+ ye = p1->y;
+ break;
+ case 5:
+ angle = a3;
+ xe = p3->x;
+ ye = p3->y;
+ break;
+ }
+ if(i < 4)
+ {
+ if(sweep > 0.0 && (angle > a3 || angle < a1)) continue;
+ if(sweep < 0.0 && (angle < a3 || angle > a1)) continue;
+ }
+
+ LWDEBUGF(3, "lwcircle_compute_box3d: potential extreame %d (%.16f, %.16f)", i, xe, ye);
+
+ x1 = (x1 < xe) ? x1 : xe;
+ y1 = (y1 < ye) ? y1 : ye;
+ x2 = (x2 > xe) ? x2 : xe;
+ y2 = (y2 > ye) ? y2 : ye;
+ }
+
+ LWDEBUGF(3, "lwcircle_compute_box3d: extreames found (%.16f %.16f, %.16f %.16f)", x1, y1, x2, y2);
+
+ /*
+ x1 = center->x + x1 * radius;
+ x2 = center->x + x2 * radius;
+ y1 = center->y + y1 * radius;
+ y2 = center->y + y2 * radius;
+ */
+ z1 = (p1->z < p2->z) ? p1->z : p2->z;
+ z1 = (z1 < p3->z) ? z1 : p3->z;
+ z2 = (p1->z > p2->z) ? p1->z : p2->z;
+ z2 = (z2 > p3->z) ? z2 : p3->z;
+
+ box = lwalloc(sizeof(BOX3D));
+ box->xmin = x1; box->xmax = x2;
+ box->ymin = y1; box->ymax = y2;
+ box->zmin = z1; box->zmax = z2;
+
+ lwfree(center);
+
+ return box;
+}
+
+/*
+ * Find bounding box (standard one)
+ * zmin=zmax=NO_Z_VALUE if 2d
+ * TODO: This ignores curvature, which should be taken into account.
+ */
+BOX3D *
+lwcurve_compute_box3d(LWCURVE *curve)
+{
+ BOX3D *box, *tmp;
+ int i;
+ POINT4D *p1 = lwalloc(sizeof(POINT4D));
+ POINT4D *p2 = lwalloc(sizeof(POINT4D));
+ POINT4D *p3 = lwalloc(sizeof(POINT4D));
+
+ LWDEBUG(2, "lwcurve_compute_box3d called.");
+
+ /* initialize box values */
+ box = lwalloc(sizeof(BOX3D));
+ box->xmin = MAXFLOAT; box->xmax = -1 * MAXFLOAT;
+ box->ymin = MAXFLOAT; box->ymax = -1 * MAXFLOAT;
+ box->zmin = MAXFLOAT; box->zmax = -1 * MAXFLOAT;
+
+ for(i = 2; i < curve->points->npoints; i+=2)
+ {
+ getPoint4d_p(curve->points, i-2, p1);
+ getPoint4d_p(curve->points, i-1, p2);
+ getPoint4d_p(curve->points, i, p3);
+ tmp = lwcircle_compute_box3d(p1, p2, p3);
+ if(tmp == NULL) continue;
+ box->xmin = (box->xmin < tmp->xmin) ? box->xmin : tmp->xmin;
+ box->xmax = (box->xmax > tmp->xmax) ? box->xmax : tmp->xmax;
+ box->ymin = (box->ymin < tmp->ymin) ? box->ymin : tmp->ymin;
+ box->ymax = (box->ymax > tmp->ymax) ? box->ymax : tmp->ymax;
+ box->zmin = (box->zmin < tmp->zmin) ? box->zmin : tmp->zmin;
+ box->zmax = (box->zmax > tmp->zmax) ? box->zmax : tmp->zmax;
+
+ LWDEBUGF(4, "curve %d x=(%.16f,%.16f) y=(%.16f,%.16f) z=(%.16f,%.16f)", i/2, box->xmin, box->xmax, box->ymin, box->ymax, box->zmin, box->zmax);
+ }
+
+
+ return box;
+}
+
+int
+lwcurve_compute_box2d_p(LWCURVE *curve, BOX2DFLOAT4 *result)
+{
+ BOX3D *box = lwcurve_compute_box3d(curve);
+ LWDEBUG(2, "lwcurve_compute_box2d_p called.");
+
+ if(box == NULL) return 0;
+ box3d_to_box2df_p(box, result);
+ return 1;
+}
+
+void pfree_curve(LWCURVE *curve)
+{
+ lwfree(curve->points);
+ lwfree(curve);
+}
+
+/* find length of this serialized curve */
+size_t
+lwgeom_size_curve(const uchar *serialized_curve)
+{
+ int type = (uchar)serialized_curve[0];
+ uint32 result = 1; /* type */
+ const uchar *loc;
+ uint32 npoints;
+
+ LWDEBUG(2, "lwgeom_size_curve called");
+
+ if(lwgeom_getType(type) != CURVETYPE)
+ lwerror("lwgeom_size_curve::attempt to find the length of a non-curve");
+
+ loc = serialized_curve + 1;
+ if(lwgeom_hasBBOX(type))
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ result += sizeof(BOX2DFLOAT4);
+ }
+
+ if(lwgeom_hasSRID(type))
+ {
+ loc += 4; /* type + SRID */
+ result += 4;
+ }
+
+ /* we've read the type (1 byte) and SRID (4 bytes, if present) */
+ npoints = lw_get_uint32(loc);
+ result += sizeof(uint32); /* npoints */
+
+ result += TYPE_NDIMS(type) * sizeof(double) * npoints;
+
+ LWDEBUGF(3, "lwgeom_size_curve returning %d", result);
+
+ return result;
+}
+
+void printLWCURVE(LWCURVE *curve)
+{
+ lwnotice("LWCURVE {");
+ lwnotice(" ndims = %i", (int)TYPE_NDIMS(curve->type));
+ lwnotice(" SRID = %i", (int)curve->SRID);
+ printPA(curve->points);
+ lwnotice("}");
+}
+
+/* Clone LWCURVE object. POINTARRAY is not copied. */
+LWCURVE *
+lwcurve_clone(const LWCURVE *g)
+{
+ LWCURVE *ret = lwalloc(sizeof(LWCURVE));
+ memcpy(ret, g, sizeof(LWCURVE));
+ if(g->bbox) ret->bbox = box2d_clone(g->bbox);
+ return ret;
+}
+
+/*
+ * Add 'what' to this curve at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTICURVE or a GEOMETRYCOLLECTION
+ */
+LWGEOM *
+lwcurve_add(const LWCURVE *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+
+ if(where != -1 && where != 0)
+ {
+ lwerror("lwcurve_add only supports 0 or -1 as second argument %d", where);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*2);
+ if(where == -1) /* append */
+ {
+ geoms[0] = lwgeom_clone((LWGEOM *)to);
+ geoms[1] = lwgeom_clone(what);
+ }
+ else /* prepend */
+ {
+ geoms[0] = lwgeom_clone(what);
+ geoms[1] = lwgeom_clone((LWGEOM *)to);
+ }
+
+ /* reset SRID and wantbbox flag from component types */
+ geoms[0]->SRID = geoms[1]->SRID = -1;
+ TYPE_SETHASSRID(geoms[0]->type, 0);
+ TYPE_SETHASSRID(geoms[1]->type, 0);
+ TYPE_SETHASBBOX(geoms[0]->type, 0);
+ TYPE_SETHASBBOX(geoms[1]->type, 0);
+
+ /* Find appropriate geom type */
+ if(TYPE_GETTYPE(what->type) == CURVETYPE || TYPE_GETTYPE(what->type) == LINETYPE) newtype = MULTICURVETYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ 2, geoms);
+
+ return (LWGEOM *)col;
+}
+
+void lwcurve_reverse(LWCURVE *curve)
+{
+ ptarray_reverse(curve->points);
+}
+
+/*
+ * TODO: Invalid segmentization. This should accomodate the curvature.
+ */
+LWCURVE *
+lwcurve_segmentize2d(LWCURVE *curve, double dist)
+{
+ return lwcurve_construct(curve->SRID, NULL,
+ ptarray_segmentize2d(curve->points, dist));
+}
+
+/* check coordinate equality */
+char
+lwcurve_same(const LWCURVE *me, const LWCURVE *you)
+{
+ return ptarray_same(me->points, you->points);
+}
+
+/*
+ * Construct a LWCURVE from an array of LWPOINTs
+ * LWCURVE dimensions are large enough to host all input dimensions.
+ */
+LWCURVE *
+lwcurve_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points)
+{
+ int zmflag=0;
+ unsigned int i;
+ POINTARRAY *pa;
+ uchar *newpoints, *ptr;
+ size_t ptsize, size;
+
+ /*
+ * Find output dimensions, check integrity
+ */
+ for(i = 0; i < npoints; i++)
+ {
+ if(TYPE_GETTYPE(points[i]->type) != POINTTYPE)
+ {
+ lwerror("lwcurve_from_lwpointarray: invalid input type: %s",
+ lwgeom_typename(TYPE_GETTYPE(points[i]->type)));
+ return NULL;
+ }
+ if(TYPE_HASZ(points[i]->type)) zmflag |= 2;
+ if(TYPE_HASM(points[i]->type)) zmflag |=1;
+ if(zmflag == 3) break;
+ }
+
+ if(zmflag == 0) ptsize = 2 * sizeof(double);
+ else if(zmflag == 3) ptsize = 4 * sizeof(double);
+ else ptsize = 3 * sizeof(double);
+
+ /*
+ * Allocate output points array
+ */
+ size = ptsize * npoints;
+ newpoints = lwalloc(size);
+ memset(newpoints, 0, size);
+
+ ptr = newpoints;
+ for(i = 0; i < npoints; i++)
+ {
+ size = pointArray_ptsize(points[i]->point);
+ memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
+ ptr += ptsize;
+ }
+ pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints);
+
+ return lwcurve_construct(SRID, NULL, pa);
+}
+
+/*
+ * Construct a LWCURVE from a LWMPOINT
+ */
+LWCURVE *
+lwcurve_from_lwmpoint(int SRID, LWMPOINT *mpoint)
+{
+ unsigned int i;
+ POINTARRAY *pa;
+ char zmflag = TYPE_GETZM(mpoint->type);
+ size_t ptsize, size;
+ uchar *newpoints, *ptr;
+
+ if(zmflag == 0) ptsize = 2 * sizeof(double);
+ else if(zmflag == 3) ptsize = 4 * sizeof(double);
+ else ptsize = 3 * sizeof(double);
+
+ /* Allocate space for output points */
+ size = ptsize * mpoint->ngeoms;
+ newpoints = lwalloc(size);
+ memset(newpoints, 0, size);
+
+ ptr = newpoints;
+ for(i = 0; i < mpoint->ngeoms; i++)
+ {
+ memcpy(ptr,
+ getPoint_internal(mpoint->geoms[i]->point, 0),
+ ptsize);
+ ptr += ptsize;
+ }
+
+ pa = pointArray_construct(newpoints, zmflag&2, zmflag&1,
+ mpoint->ngeoms);
+
+ LWDEBUGF(3, "lwcurve_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);
+
+ return lwcurve_construct(SRID, NULL, pa);
+}
+
+LWCURVE *
+lwcurve_addpoint(LWCURVE *curve, LWPOINT *point, unsigned int where)
+{
+ POINTARRAY *newpa;
+ LWCURVE *ret;
+
+ newpa = ptarray_addPoint(curve->points,
+ getPoint_internal(point->point, 0),
+ TYPE_NDIMS(point->type), where);
+ ret = lwcurve_construct(curve->SRID, NULL, newpa);
+
+ return ret;
+}
+
+LWCURVE *
+lwcurve_removepoint(LWCURVE *curve, unsigned int index)
+{
+ POINTARRAY *newpa;
+ LWCURVE *ret;
+
+ newpa = ptarray_removePoint(curve->points, index);
+ ret = lwcurve_construct(curve->SRID, NULL, newpa);
+
+ return ret;
+}
+
+/*
+ * Note: input will be changed, make sure you have permissions for this.
+ * */
+void
+lwcurve_setPoint4d(LWCURVE *curve, unsigned int index, POINT4D *newpoint)
+{
+ setPoint4d(curve->points, index, newpoint);
+}
+
+
Added: trunk/liblwgeom/lwcurvepoly.c
===================================================================
--- trunk/liblwgeom/lwcurvepoly.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwcurvepoly.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,86 @@
+/**********************************************************************
+ * $Id$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+/* basic LWCURVEPOLY manipulation */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+
+LWCURVEPOLY *
+lwcurvepoly_deserialize(uchar *srl)
+{
+ LWCURVEPOLY *result;
+ LWGEOM_INSPECTED *insp;
+ int type = lwgeom_getType(srl[0]);
+ int i;
+
+ LWDEBUG(3, "lwcurvepoly_deserialize called.");
+
+ if(type != CURVEPOLYTYPE)
+ {
+ lwerror("lwcurvepoly_deserialize called on NON curvepoly: %d",
+ type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(srl);
+
+ result = lwalloc(sizeof(LWCURVEPOLY));
+ result->type = insp->type;
+ result->SRID = insp->SRID;
+ result->nrings = insp->ngeometries;
+ result->rings = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
+
+ if(lwgeom_hasBBOX(srl[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+ for(i = 0; i < insp->ngeometries; i++)
+ {
+ result->rings[i] = lwgeom_deserialize(insp->sub_geoms[i]);
+ if(lwgeom_getType(result->rings[i]->type) != CURVETYPE
+ && lwgeom_getType(result->rings[i]->type) != LINETYPE)
+ {
+ lwerror("Only Circular curves and Linestrings are currently supported as rings, not %s (%d)", lwgeom_typename(result->rings[i]->type), result->rings[i]->type);
+ lwfree(result);
+ lwfree(insp);
+ return NULL;
+ }
+ if(TYPE_NDIMS(result->rings[i]->type) != TYPE_NDIMS(result->type))
+ {
+ lwerror("Mixed dimensions (curvepoly %d, ring %d)",
+ TYPE_NDIMS(result->type), i,
+ TYPE_NDIMS(result->rings[i]->type));
+ lwfree(result);
+ lwfree(insp);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+LWGEOM *
+lwcurvepoly_add(const LWCURVEPOLY *to, uint32 where, const LWGEOM *what)
+{
+ /* TODO */
+ lwerror("lwcurvepoly_add not yet implemented.");
+ return NULL;
+}
+
+
+
Added: trunk/liblwgeom/lwgeom.c
===================================================================
--- trunk/liblwgeom/lwgeom.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwgeom.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,696 @@
+/**********************************************************************
+ * $Id: lwgeom.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+/*#include "lwgeom_pg.h"*/
+#include "liblwgeom.h"
+#include "wktparse.h"
+
+
+LWGEOM *
+lwgeom_deserialize(uchar *srl)
+{
+ int type = lwgeom_getType(srl[0]);
+
+ LWDEBUGF(2, "lwgeom_deserialize got %d - %s", type, lwgeom_typename(type));
+
+ switch (type)
+ {
+ case POINTTYPE:
+ return (LWGEOM *)lwpoint_deserialize(srl);
+ case LINETYPE:
+ return (LWGEOM *)lwline_deserialize(srl);
+ case CURVETYPE:
+ return (LWGEOM *)lwcurve_deserialize(srl);
+ case POLYGONTYPE:
+ return (LWGEOM *)lwpoly_deserialize(srl);
+ case MULTIPOINTTYPE:
+ return (LWGEOM *)lwmpoint_deserialize(srl);
+ case MULTILINETYPE:
+ return (LWGEOM *)lwmline_deserialize(srl);
+ case MULTIPOLYGONTYPE:
+ return (LWGEOM *)lwmpoly_deserialize(srl);
+ case COLLECTIONTYPE:
+ return (LWGEOM *)lwcollection_deserialize(srl);
+ case COMPOUNDTYPE:
+ return (LWGEOM *)lwcompound_deserialize(srl);
+ case CURVEPOLYTYPE:
+ return (LWGEOM *)lwcurvepoly_deserialize(srl);
+ case MULTICURVETYPE:
+ return (LWGEOM *)lwmcurve_deserialize(srl);
+ case MULTISURFACETYPE:
+ return (LWGEOM *)lwmsurface_deserialize(srl);
+ default:
+ lwerror("Unknown geometry type: %d", type);
+
+ return NULL;
+ }
+
+}
+
+size_t
+lwgeom_serialize_size(LWGEOM *lwgeom)
+{
+ int type = TYPE_GETTYPE(lwgeom->type);
+
+ LWDEBUGF(2, "lwgeom_serialize_size(%s) called", lwgeom_typename(type));
+
+ switch (type)
+ {
+ case POINTTYPE:
+ return lwpoint_serialize_size((LWPOINT *)lwgeom);
+ case LINETYPE:
+ return lwline_serialize_size((LWLINE *)lwgeom);
+ case POLYGONTYPE:
+ return lwpoly_serialize_size((LWPOLY *)lwgeom);
+ case CURVETYPE:
+ return lwcurve_serialize_size((LWCURVE *)lwgeom);
+ case CURVEPOLYTYPE:
+ case COMPOUNDTYPE:
+ case MULTIPOINTTYPE:
+ case MULTILINETYPE:
+ case MULTICURVETYPE:
+ case MULTIPOLYGONTYPE:
+ case MULTISURFACETYPE:
+ case COLLECTIONTYPE:
+ return lwcollection_serialize_size((LWCOLLECTION *)lwgeom);
+ default:
+ lwerror("Unknown geometry type: %d", type);
+
+ return 0;
+ }
+}
+
+void
+lwgeom_serialize_buf(LWGEOM *lwgeom, uchar *buf, size_t *retsize)
+{
+ int type = TYPE_GETTYPE(lwgeom->type);
+
+ LWDEBUGF(2, "lwgeom_serialize_buf called with a %s",
+ lwgeom_typename(type));
+
+ switch (type)
+ {
+ case POINTTYPE:
+ lwpoint_serialize_buf((LWPOINT *)lwgeom, buf, retsize);
+ break;
+ case LINETYPE:
+ lwline_serialize_buf((LWLINE *)lwgeom, buf, retsize);
+ break;
+ case POLYGONTYPE:
+ lwpoly_serialize_buf((LWPOLY *)lwgeom, buf, retsize);
+ break;
+ case CURVETYPE:
+ lwcurve_serialize_buf((LWCURVE *)lwgeom, buf, retsize);
+ break;
+ case CURVEPOLYTYPE:
+ case COMPOUNDTYPE:
+ case MULTIPOINTTYPE:
+ case MULTILINETYPE:
+ case MULTICURVETYPE:
+ case MULTIPOLYGONTYPE:
+ case MULTISURFACETYPE:
+ case COLLECTIONTYPE:
+ lwcollection_serialize_buf((LWCOLLECTION *)lwgeom, buf,
+ retsize);
+ break;
+ default:
+ lwerror("Unknown geometry type: %d", type);
+ return;
+ }
+ return;
+}
+
+uchar *
+lwgeom_serialize(LWGEOM *lwgeom)
+{
+ size_t size = lwgeom_serialize_size(lwgeom);
+ size_t retsize;
+ uchar *serialized = lwalloc(size);
+
+ lwgeom_serialize_buf(lwgeom, serialized, &retsize);
+
+#if POSTGIS_DEBUG_LEVEL > 0
+ if ( retsize != size )
+ {
+ lwerror("lwgeom_serialize: computed size %d, returned size %d",
+ size, retsize);
+ }
+#endif
+
+ return serialized;
+}
+
+/* Force Right-hand-rule on LWGEOM polygons */
+void
+lwgeom_forceRHR(LWGEOM *lwgeom)
+{
+ LWCOLLECTION *coll;
+ int i;
+
+ switch (TYPE_GETTYPE(lwgeom->type))
+ {
+ case POLYGONTYPE:
+ lwpoly_forceRHR((LWPOLY *)lwgeom);
+ return;
+
+ case MULTIPOLYGONTYPE:
+ case COLLECTIONTYPE:
+ coll = (LWCOLLECTION *)lwgeom;
+ for (i=0; i<coll->ngeoms; i++)
+ lwgeom_forceRHR(coll->geoms[i]);
+ return;
+ }
+}
+
+/* Reverse vertex order of LWGEOM */
+void
+lwgeom_reverse(LWGEOM *lwgeom)
+{
+ int i;
+ LWCOLLECTION *col;
+
+ switch (TYPE_GETTYPE(lwgeom->type))
+ {
+ case LINETYPE:
+ lwline_reverse((LWLINE *)lwgeom);
+ return;
+ case POLYGONTYPE:
+ lwpoly_reverse((LWPOLY *)lwgeom);
+ return;
+ case MULTILINETYPE:
+ case MULTIPOLYGONTYPE:
+ case COLLECTIONTYPE:
+ col = (LWCOLLECTION *)lwgeom;
+ for (i=0; i<col->ngeoms; i++)
+ lwgeom_reverse(col->geoms[i]);
+ return;
+ }
+}
+
+int
+lwgeom_compute_box2d_p(LWGEOM *lwgeom, BOX2DFLOAT4 *buf)
+{
+ LWDEBUGF(2, "lwgeom_compute_box2d_p called of %p of type %d.", lwgeom, TYPE_GETTYPE(lwgeom->type));
+
+ switch(TYPE_GETTYPE(lwgeom->type))
+ {
+ case POINTTYPE:
+ return lwpoint_compute_box2d_p((LWPOINT *)lwgeom, buf);
+ case LINETYPE:
+ return lwline_compute_box2d_p((LWLINE *)lwgeom, buf);
+ case CURVETYPE:
+ return lwcurve_compute_box2d_p((LWCURVE *)lwgeom, buf);
+ case POLYGONTYPE:
+ return lwpoly_compute_box2d_p((LWPOLY *)lwgeom, buf);
+ case COMPOUNDTYPE:
+ case CURVEPOLYTYPE:
+ case MULTIPOINTTYPE:
+ case MULTILINETYPE:
+ case MULTICURVETYPE:
+ case MULTIPOLYGONTYPE:
+ case MULTISURFACETYPE:
+ case COLLECTIONTYPE:
+ return lwcollection_compute_box2d_p((LWCOLLECTION *)lwgeom, buf);
+ }
+ return 0;
+}
+
+/*
+ * dont forget to lwfree() result
+ */
+BOX2DFLOAT4 *
+lwgeom_compute_box2d(LWGEOM *lwgeom)
+{
+ BOX2DFLOAT4 *result = lwalloc(sizeof(BOX2DFLOAT4));
+ if ( lwgeom_compute_box2d_p(lwgeom, result) ) return result;
+ else {
+ lwfree(result);
+ return NULL;
+ }
+}
+
+LWPOINT *
+lwgeom_as_lwpoint(LWGEOM *lwgeom)
+{
+ if ( TYPE_GETTYPE(lwgeom->type) == POINTTYPE )
+ return (LWPOINT *)lwgeom;
+ else return NULL;
+}
+
+LWLINE *
+lwgeom_as_lwline(LWGEOM *lwgeom)
+{
+ if ( TYPE_GETTYPE(lwgeom->type) == LINETYPE )
+ return (LWLINE *)lwgeom;
+ else return NULL;
+}
+
+LWCURVE *
+lwgeom_as_lwcurve(LWGEOM *lwgeom)
+{
+ if( TYPE_GETTYPE(lwgeom->type) == CURVETYPE )
+ return (LWCURVE *)lwgeom;
+ else return NULL;
+}
+
+LWPOLY *
+lwgeom_as_lwpoly(LWGEOM *lwgeom)
+{
+ if ( TYPE_GETTYPE(lwgeom->type) == POLYGONTYPE )
+ return (LWPOLY *)lwgeom;
+ else return NULL;
+}
+
+LWCOLLECTION *
+lwgeom_as_lwcollection(LWGEOM *lwgeom)
+{
+ if ( TYPE_GETTYPE(lwgeom->type) >= MULTIPOINTTYPE
+ && TYPE_GETTYPE(lwgeom->type) <= COLLECTIONTYPE)
+ return (LWCOLLECTION *)lwgeom;
+ else return NULL;
+}
+
+LWMPOINT *
+lwgeom_as_lwmpoint(LWGEOM *lwgeom)
+{
+ if ( TYPE_GETTYPE(lwgeom->type) == MULTIPOINTTYPE )
+ return (LWMPOINT *)lwgeom;
+ else return NULL;
+}
+
+LWMLINE *
+lwgeom_as_lwmline(LWGEOM *lwgeom)
+{
+ if ( TYPE_GETTYPE(lwgeom->type) == MULTILINETYPE )
+ return (LWMLINE *)lwgeom;
+ else return NULL;
+}
+
+LWMPOLY *
+lwgeom_as_lwmpoly(LWGEOM *lwgeom)
+{
+ if ( TYPE_GETTYPE(lwgeom->type) == MULTIPOLYGONTYPE )
+ return (LWMPOLY *)lwgeom;
+ else return NULL;
+}
+
+LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj) { return (LWGEOM *)obj; }
+LWGEOM *lwmline_as_lwgeom(LWMLINE *obj) { return (LWGEOM *)obj; }
+LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj) { return (LWGEOM *)obj; }
+LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj) { return (LWGEOM *)obj; }
+LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj) { return (LWGEOM *)obj; }
+LWGEOM *lwline_as_lwgeom(LWLINE *obj) { return (LWGEOM *)obj; }
+LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj) { return (LWGEOM *)obj; }
+
+void
+lwgeom_release(LWGEOM *lwgeom)
+{
+ uint32 i;
+ LWCOLLECTION *col;
+
+#ifdef INTEGRITY_CHECKS
+ if ( ! lwgeom )
+ lwerror("lwgeom_release: someone called on 0x0");
+#endif
+
+ /* Drop bounding box (always a copy) */
+ if ( lwgeom->bbox ) {
+ LWDEBUG(3, "lwgeom_release: releasing bbox.");
+
+ lwfree(lwgeom->bbox);
+ }
+
+ /* Collection */
+ if ( (col=lwgeom_as_lwcollection(lwgeom)) )
+ {
+ LWDEBUG(3, "lwgeom_release: Releasing collection.");
+
+ for (i=0; i<col->ngeoms; i++)
+ {
+ lwgeom_release(col->geoms[i]);
+ }
+ lwfree(lwgeom);
+ }
+
+ /* Single element */
+ else lwfree(lwgeom);
+
+}
+
+/* Clone an LWGEOM object. POINTARRAY are not copied. */
+LWGEOM *
+lwgeom_clone(const LWGEOM *lwgeom)
+{
+ LWDEBUGF(2, "lwgeom_clone called with %p, %d", lwgeom, TYPE_GETTYPE(lwgeom->type));
+
+ switch(TYPE_GETTYPE(lwgeom->type))
+ {
+ case POINTTYPE:
+ return (LWGEOM *)lwpoint_clone((LWPOINT *)lwgeom);
+ case LINETYPE:
+ return (LWGEOM *)lwline_clone((LWLINE *)lwgeom);
+ case CURVETYPE:
+ return (LWGEOM *)lwcurve_clone((LWCURVE *)lwgeom);
+ case POLYGONTYPE:
+ return (LWGEOM *)lwpoly_clone((LWPOLY *)lwgeom);
+ case COMPOUNDTYPE:
+ case CURVEPOLYTYPE:
+ case MULTIPOINTTYPE:
+ case MULTILINETYPE:
+ case MULTICURVETYPE:
+ case MULTIPOLYGONTYPE:
+ case MULTISURFACETYPE:
+ case COLLECTIONTYPE:
+ return (LWGEOM *)lwcollection_clone((LWCOLLECTION *)lwgeom);
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Add 'what' to 'to' at position 'where'
+ *
+ * where=0 == prepend
+ * where=-1 == append
+ * Appended-to LWGEOM gets a new type based on new condition.
+ * Mix of dimensions is not allowed (TODO: allow it?).
+ */
+LWGEOM *
+lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what)
+{
+ if ( TYPE_NDIMS(what->type) != TYPE_NDIMS(to->type) )
+ {
+ lwerror("lwgeom_add: mixed dimensions not supported");
+ return NULL;
+ }
+
+ LWDEBUGF(2, "lwgeom_add(%s, %d, %s) called",
+ lwgeom_typename(TYPE_GETTYPE(to->type)),
+ where,
+ lwgeom_typename(TYPE_GETTYPE(what->type)));
+
+ switch(TYPE_GETTYPE(to->type))
+ {
+ case POINTTYPE:
+ return (LWGEOM *)lwpoint_add((const LWPOINT *)to, where, what);
+ case LINETYPE:
+ return (LWGEOM *)lwline_add((const LWLINE *)to, where, what);
+
+ case CURVETYPE:
+ return (LWGEOM *)lwcurve_add((const LWCURVE *)to, where, what);
+
+ case POLYGONTYPE:
+ return (LWGEOM *)lwpoly_add((const LWPOLY *)to, where, what);
+
+ case COMPOUNDTYPE:
+ return (LWGEOM *)lwcompound_add((const LWCOMPOUND *)to, where, what);
+
+ case CURVEPOLYTYPE:
+ return (LWGEOM *)lwcurvepoly_add((const LWCURVEPOLY *)to, where, what);
+
+ case MULTIPOINTTYPE:
+ return (LWGEOM *)lwmpoint_add((const LWMPOINT *)to,
+ where, what);
+
+ case MULTILINETYPE:
+ return (LWGEOM *)lwmline_add((const LWMLINE *)to,
+ where, what);
+
+ case MULTICURVETYPE:
+ return (LWGEOM *)lwmcurve_add((const LWMCURVE *)to,
+ where, what);
+
+ case MULTIPOLYGONTYPE:
+ return (LWGEOM *)lwmpoly_add((const LWMPOLY *)to,
+ where, what);
+
+ case MULTISURFACETYPE:
+ return (LWGEOM *)lwmsurface_add((const LWMSURFACE *)to,
+ where, what);
+
+ case COLLECTIONTYPE:
+ return (LWGEOM *)lwcollection_add(
+ (const LWCOLLECTION *)to, where, what);
+
+ default:
+ lwerror("lwgeom_add: unknown geometry type: %d",
+ TYPE_GETTYPE(to->type));
+ return NULL;
+ }
+}
+
+/*
+ * Return an alloced string
+ */
+char *
+lwgeom_to_ewkt(LWGEOM *lwgeom)
+{
+ uchar *serialized = lwgeom_serialize(lwgeom);
+ char *ret;
+ if ( ! serialized ) {
+ lwerror("Error serializing geom %p", lwgeom);
+ }
+ ret = unparse_WKT(serialized, lwalloc, lwfree);
+ lwfree(serialized);
+ return ret;
+}
+
+/*
+ * Return an alloced string
+ */
+char *
+lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder)
+{
+ uchar *serialized = lwgeom_serialize(lwgeom);
+ char *hexwkb = unparse_WKB(serialized, lwalloc, lwfree, byteorder,NULL,1);
+ lwfree(serialized);
+ return hexwkb;
+}
+
+/*
+ * Return an alloced string
+ */
+uchar *
+lwgeom_to_ewkb(LWGEOM *lwgeom, char byteorder, size_t *outsize)
+{
+ uchar *serialized = lwgeom_serialize(lwgeom);
+
+ /*
+ * We cast return to "unsigned" char as we are
+ * requesting a "binary" output, not HEX
+ * (last argument set to 0)
+ */
+ uchar *hexwkb = (uchar *)unparse_WKB(serialized, lwalloc, lwfree,
+ byteorder, outsize, 0);
+ lwfree(serialized);
+ return hexwkb;
+}
+
+/*
+ * Make an LWGEOM object from a EWKB binary representation.
+ * Currently highly unoptimized as it:
+ * - convert EWKB to HEXEWKB
+ * - construct PG_LWGEOM
+ * - deserialize it
+ */
+LWGEOM *
+lwgeom_from_ewkb(uchar *ewkb, size_t size)
+{
+ size_t hexewkblen = size*2;
+ char *hexewkb;
+ long int i;
+ LWGEOM *ret;
+ SERIALIZED_LWGEOM *serialized_lwgeom;
+
+ /* "HEXify" the EWKB */
+ hexewkb = lwalloc(hexewkblen+1);
+ for (i=0; i<size; ++i) deparse_hex(ewkb[i], &hexewkb[i*2]);
+ hexewkb[hexewkblen] = '\0';
+
+ /* Rely on grammar parser to construct a LWGEOM */
+ serialized_lwgeom = parse_lwgeom_wkt(hexewkb);
+
+ /* Free intermediate HEXified representation */
+ lwfree(hexewkb);
+
+ /* Deserialize */
+ ret = lwgeom_deserialize(serialized_lwgeom->lwgeom);
+
+ return ret;
+}
+
+/*
+ * geom1 same as geom2
+ * iff
+ * + have same type
+ * + have same # objects
+ * + have same bvol
+ * + each object in geom1 has a corresponding object in geom2 (see above)
+ */
+char
+lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
+{
+ LWDEBUGF(2, "lwgeom_same(%s, %s) called",
+ lwgeom_typename(TYPE_GETTYPE(lwgeom1->type)),
+ lwgeom_typename(TYPE_GETTYPE(lwgeom2->type)));
+
+ if ( TYPE_GETTYPE(lwgeom1->type) != TYPE_GETTYPE(lwgeom2->type) )
+ {
+ LWDEBUG(3, " type differ");
+
+ return 0;
+ }
+
+ if ( TYPE_GETZM(lwgeom1->type) != TYPE_GETZM(lwgeom2->type) )
+ {
+ LWDEBUG(3, " ZM flags differ");
+
+ return 0;
+ }
+
+ /* Check boxes if both already computed */
+ if ( lwgeom1->bbox && lwgeom2->bbox )
+ {
+ /*lwnotice("bbox1:%p, bbox2:%p", lwgeom1->bbox, lwgeom2->bbox);*/
+ if ( ! box2d_same(lwgeom1->bbox, lwgeom2->bbox) )
+ {
+ LWDEBUG(3, " bounding boxes differ");
+
+ return 0;
+ }
+ }
+
+ /* geoms have same type, invoke type-specific function */
+ switch(TYPE_GETTYPE(lwgeom1->type))
+ {
+ case POINTTYPE:
+ return lwpoint_same((LWPOINT *)lwgeom1,
+ (LWPOINT *)lwgeom2);
+ case LINETYPE:
+ return lwline_same((LWLINE *)lwgeom1,
+ (LWLINE *)lwgeom2);
+ case POLYGONTYPE:
+ return lwpoly_same((LWPOLY *)lwgeom1,
+ (LWPOLY *)lwgeom2);
+ case MULTIPOINTTYPE:
+ case MULTILINETYPE:
+ case MULTIPOLYGONTYPE:
+ case COLLECTIONTYPE:
+ return lwcollection_same((LWCOLLECTION *)lwgeom1,
+ (LWCOLLECTION *)lwgeom2);
+ default:
+ lwerror("lwgeom_same: unknown geometry type: %d",
+ TYPE_GETTYPE(lwgeom1->type));
+ return 0;
+ }
+
+}
+
+void
+lwgeom_changed(LWGEOM *lwgeom)
+{
+ if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
+ lwgeom->bbox = NULL;
+ TYPE_SETHASBBOX(lwgeom->type, 0);
+}
+
+void
+lwgeom_dropBBOX(LWGEOM *lwgeom)
+{
+ if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
+ lwgeom->bbox = NULL;
+ TYPE_SETHASBBOX(lwgeom->type, 0);
+}
+
+/*
+ * Ensure there's a box in the LWGEOM.
+ * If the box is already there just return,
+ * else compute it.
+ */
+void
+lwgeom_addBBOX(LWGEOM *lwgeom)
+{
+ if ( lwgeom->bbox ) return;
+ lwgeom->bbox = lwgeom_compute_box2d(lwgeom);
+ TYPE_SETHASBBOX(lwgeom->type, 1);
+}
+
+void
+lwgeom_dropSRID(LWGEOM *lwgeom)
+{
+ TYPE_SETHASSRID(lwgeom->type, 0);
+ lwgeom->SRID = -1;
+}
+
+LWGEOM *
+lwgeom_segmentize2d(LWGEOM *lwgeom, double dist)
+{
+ switch(TYPE_GETTYPE(lwgeom->type))
+ {
+ case LINETYPE:
+ return (LWGEOM *)lwline_segmentize2d((LWLINE *)lwgeom,
+ dist);
+ case POLYGONTYPE:
+ return (LWGEOM *)lwpoly_segmentize2d((LWPOLY *)lwgeom,
+ dist);
+ case MULTILINETYPE:
+ case MULTIPOLYGONTYPE:
+ case COLLECTIONTYPE:
+ return (LWGEOM *)lwcollection_segmentize2d(
+ (LWCOLLECTION *)lwgeom, dist);
+
+ default:
+ return lwgeom_clone(lwgeom);
+ }
+}
+
+void
+lwgeom_longitude_shift(LWGEOM *lwgeom)
+{
+ int i;
+ switch(TYPE_GETTYPE(lwgeom->type))
+ {
+ LWPOINT *point;
+ LWLINE *line;
+ LWPOLY *poly;
+ LWCOLLECTION *coll;
+
+ case POINTTYPE:
+ point = (LWPOINT *)lwgeom;
+ ptarray_longitude_shift(point->point);
+ return;
+ case LINETYPE:
+ line = (LWLINE *)lwgeom;
+ ptarray_longitude_shift(line->points);
+ return;
+ case POLYGONTYPE:
+ poly = (LWPOLY *)lwgeom;
+ for (i=0; i<poly->nrings; i++)
+ ptarray_longitude_shift(poly->rings[i]);
+ return;
+ case MULTILINETYPE:
+ case MULTIPOLYGONTYPE:
+ case COLLECTIONTYPE:
+ coll = (LWCOLLECTION *)lwgeom;
+ for (i=0; i<coll->ngeoms; i++)
+ lwgeom_longitude_shift(coll->geoms[i]);
+ return;
+ default:
+ lwerror("%s:%d: unknown geom type: %d",
+ __FILE__, __LINE__,
+ TYPE_GETTYPE(lwgeom->type));
+ }
+}
Added: trunk/liblwgeom/lwgeom_api.c
===================================================================
--- trunk/liblwgeom/lwgeom_api.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwgeom_api.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,2185 @@
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "liblwgeom.h"
+#include "wktparse.h"
+
+/*
+ * Lower this to reduce integrity checks
+ */
+#define PARANOIA_LEVEL 1
+
+
+
+/**********************************************************************
+ * BOX routines
+ *
+ * returns the float thats very close to the input, but <=
+ * handles the funny differences in float4 and float8 reps.
+ **********************************************************************/
+
+
+/*
+ * These are taken from glibc
+ * some machines do *not* have these functions defined, so we give
+ * an implementation of them here.
+ */
+typedef int int32_tt;
+typedef unsigned int u_int32_tt;
+
+typedef union
+{
+ float value;
+ u_int32_tt word;
+} ieee_float_shape_type;
+
+#define GET_FLOAT_WORD(i,d) \
+ do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+ } while (0)
+
+
+#define SET_FLOAT_WORD(d,i) \
+ do { \
+ ieee_float_shape_type sf_u; \
+ sf_u.word = (i); \
+ (d) = sf_u.value; \
+ } while (0)
+
+
+/*
+ * Returns the next smaller or next larger float
+ * from x (in direction of y).
+ */
+float
+nextafterf_custom(float x, float y)
+{
+ int32_tt hx,hy,ix,iy;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hy,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffff; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ (iy>0x7f800000)) /* y is nan */
+ return x+y;
+ if(x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hx>hy) { /* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(hy>=0||hx>hy){ /* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy<0x00800000) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(y,hx);
+ return y;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+
+
+float nextDown_f(double d)
+{
+ float result = d;
+
+ if ( ((double) result) <=d)
+ return result;
+
+ return nextafterf_custom(result, result - 1000000);
+
+}
+
+/*
+ * Returns the float thats very close to the input, but >=.
+ * handles the funny differences in float4 and float8 reps.
+ */
+float
+nextUp_f(double d)
+{
+ float result = d;
+
+ if ( ((double) result) >=d)
+ return result;
+
+ return nextafterf_custom(result, result + 1000000);
+}
+
+
+/*
+ * Returns the double thats very close to the input, but <.
+ * handles the funny differences in float4 and float8 reps.
+ */
+double
+nextDown_d(float d)
+{
+ double result = d;
+
+ if ( result < d)
+ return result;
+
+ return nextafterf_custom(result, result - 1000000);
+}
+
+/*
+ * Returns the double thats very close to the input, but >
+ * handles the funny differences in float4 and float8 reps.
+ */
+double
+nextUp_d(float d)
+{
+ double result = d;
+
+ if ( result > d)
+ return result;
+
+ return nextafterf_custom(result, result + 1000000);
+}
+
+
+
+/*
+ * Convert BOX3D to BOX2D
+ * returned box2d is allocated with 'lwalloc'
+ */
+BOX2DFLOAT4 *
+box3d_to_box2df(BOX3D *box)
+{
+ BOX2DFLOAT4 *result = (BOX2DFLOAT4*) lwalloc(sizeof(BOX2DFLOAT4));
+
+#if PARANOIA_LEVEL > 0
+ if (box == NULL)
+ {
+ lwerror("box3d_to_box2df got NUL box");
+ return NULL;
+ }
+#endif
+
+ result->xmin = nextDown_f(box->xmin);
+ result->ymin = nextDown_f(box->ymin);
+
+ result->xmax = nextUp_f(box->xmax);
+ result->ymax = nextUp_f(box->ymax);
+
+ return result;
+}
+
+/*
+ * Convert BOX3D to BOX2D using pre-allocated BOX2D
+ * returned box2d is allocated with 'lwalloc'
+ * return 0 on error (NULL input box)
+ */
+int
+box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *result)
+{
+#if PARANOIA_LEVEL > 0
+ if (box == NULL)
+ {
+ lwerror("box3d_to_box2df got NUL box");
+ return 0;
+ }
+#endif
+
+ result->xmin = nextDown_f(box->xmin);
+ result->ymin = nextDown_f(box->ymin);
+
+ result->xmax = nextUp_f(box->xmax);
+ result->ymax = nextUp_f(box->ymax);
+
+ return 1;
+}
+
+
+
+/*
+ * Convert BOX2D to BOX3D
+ * zmin and zmax are set to NO_Z_VALUE
+ */
+BOX3D
+box2df_to_box3d(BOX2DFLOAT4 *box)
+{
+ BOX3D result;
+
+#if PARANOIA_LEVEL > 0
+ if (box == NULL)
+ lwerror("box2df_to_box3d got NULL box");
+#endif
+
+ result.xmin = box->xmin;
+ result.ymin = box->ymin;
+
+ result.xmax = box->xmax;
+ result.ymax = box->ymax;
+
+ result.zmin = result.zmax = NO_Z_VALUE;
+
+ return result;
+}
+
+/*
+ * Convert BOX2D to BOX3D, using pre-allocated BOX3D as output
+ * Z values are set to NO_Z_VALUE.
+ */
+void
+box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *out)
+{
+ if (box == NULL) return;
+
+ out->xmin = box->xmin;
+ out->ymin = box->ymin;
+
+ out->xmax = box->xmax;
+ out->ymax = box->ymax;
+
+ out->zmin = out->zmax = NO_Z_VALUE;
+}
+
+
+
+/*
+ * Returns a BOX3D that encloses b1 and b2
+ * box3d_union(NULL,A) --> A
+ * box3d_union(A,NULL) --> A
+ * box3d_union(A,B) --> A union B
+ */
+BOX3D *
+box3d_union(BOX3D *b1, BOX3D *b2)
+{
+ BOX3D *result;
+
+ result = lwalloc(sizeof(BOX3D));
+
+ if ( (b1 == NULL) && (b2 == NULL) )
+ {
+ return NULL;
+ }
+
+ if (b1 == NULL)
+ {
+ /*return b2 */
+ memcpy(result, b2, sizeof(BOX3D));
+ return result;
+ }
+ if (b2 == NULL)
+ {
+ /*return b1 */
+ memcpy(result, b1, sizeof(BOX3D));
+ return result;
+ }
+
+ if (b1->xmin < b2->xmin)
+ result->xmin = b1->xmin;
+ else
+ result->xmin = b2->xmin;
+
+ if (b1->ymin < b2->ymin)
+ result->ymin = b1->ymin;
+ else
+ result->ymin = b2->ymin;
+
+
+ if (b1->xmax > b2->xmax)
+ result->xmax = b1->xmax;
+ else
+ result->xmax = b2->xmax;
+
+ if (b1->ymax > b2->ymax)
+ result->ymax = b1->ymax;
+ else
+ result->ymax = b2->ymax;
+
+ if (b1->zmax > b2->zmax)
+ result->zmax = b1->zmax;
+ else
+ result->zmax = b2->zmax;
+
+ if (b1->zmin > b2->zmin)
+ result->zmin = b1->zmin;
+ else
+ result->zmin = b2->zmin;
+
+ return result;
+}
+
+/* Make given ubox a union of b1 and b2 */
+int
+box3d_union_p(BOX3D *b1, BOX3D *b2, BOX3D *ubox)
+{
+
+ LWDEBUG(2, "box3d_union_p called: (xmin, xmax), (ymin, ymax), (zmin, zmax)");
+ LWDEBUGF(4, "b1: (%.16f, %.16f),(%.16f, %.16f),(%.16f, %.16f)", b1->xmin, b1->xmax, b1->ymin, b1->ymax, b1->zmin, b1->zmax);
+ LWDEBUGF(4, "b2: (%.16f, %.16f),(%.16f, %.16f),(%.16f, %.16f)", b2->xmin, b2->xmax, b2->ymin, b2->ymax, b2->zmin, b2->zmax);
+
+ if ( (b1 == NULL) && (b2 == NULL) )
+ {
+ return 0;
+ }
+
+ if (b1 == NULL)
+ {
+ memcpy(ubox, b2, sizeof(BOX3D));
+ return 1;
+ }
+ if (b2 == NULL)
+ {
+ memcpy(ubox, b1, sizeof(BOX3D));
+ return 1;
+ }
+
+ if (b1->xmin < b2->xmin)
+ ubox->xmin = b1->xmin;
+ else
+ ubox->xmin = b2->xmin;
+
+ if (b1->ymin < b2->ymin)
+ ubox->ymin = b1->ymin;
+ else
+ ubox->ymin = b2->ymin;
+
+
+ if (b1->xmax > b2->xmax)
+ ubox->xmax = b1->xmax;
+ else
+ ubox->xmax = b2->xmax;
+
+ if (b1->ymax > b2->ymax)
+ ubox->ymax = b1->ymax;
+ else
+ ubox->ymax = b2->ymax;
+
+ if (b1->zmax > b2->zmax)
+ ubox->zmax = b1->zmax;
+ else
+ ubox->zmax = b2->zmax;
+
+ if (b1->zmin < b2->zmin)
+ ubox->zmin = b1->zmin;
+ else
+ ubox->zmin = b2->zmin;
+
+ return 1;
+}
+
+#if 0 /* UNUSED */
+/*
+ * Returns a pointer to internal storage, or NULL
+ * if the serialized form does not have a BBOX.
+ */
+BOX2DFLOAT4 *
+getbox2d_internal(uchar *srl)
+{
+ if (TYPE_HASBBOX(srl[0])) return (BOX2DFLOAT4 *)(srl+1);
+ else return NULL;
+}
+#endif /* UNUSED */
+
+/*
+ * Same as getbox2d, but modifies box instead of returning result on the stack
+ */
+int
+getbox2d_p(uchar *srl, BOX2DFLOAT4 *box)
+{
+ uchar type = srl[0];
+ uchar *loc;
+ BOX3D box3d;
+
+ LWDEBUG(2, "getbox2d_p call");
+
+ loc = srl+1;
+
+ if (lwgeom_hasBBOX(type))
+ {
+ /*woot - this is easy */
+ LWDEBUG(4, "getbox2d_p: has box");
+ memcpy(box, loc, sizeof(BOX2DFLOAT4));
+ return 1;
+ }
+
+ LWDEBUG(4, "getbox2d_p: has no box - computing");
+
+ /* We have to actually compute it! */
+ if ( ! compute_serialized_box3d_p(srl, &box3d) ) return 0;
+
+ LWDEBUGF(4, "getbox2d_p: compute_serialized_box3d returned %p", box3d);
+
+ if ( ! box3d_to_box2df_p(&box3d, box) ) return 0;
+
+ LWDEBUG(4, "getbox2d_p: box3d converted to box2d");
+
+ return 1;
+}
+
+/************************************************************************
+ * POINTARRAY support functions
+ *
+ * TODO: should be moved to ptarray.c probably
+ *
+ ************************************************************************/
+
+/*
+ * Copies a point from the point array into the parameter point
+ * will set point's z=NO_Z_VALUE if pa is 2d
+ * will set point's m=NO_M_VALUE if pa is 3d or 2d
+ *
+ * NOTE: point is a real POINT3D *not* a pointer
+ */
+POINT4D
+getPoint4d(const POINTARRAY *pa, int n)
+{
+ POINT4D result;
+ getPoint4d_p(pa, n, &result);
+ return result;
+}
+
+/*
+ * Copies a point from the point array into the parameter point
+ * will set point's z=NO_Z_VALUE if pa is 2d
+ * will set point's m=NO_M_VALUE if pa is 3d or 2d
+ *
+ * NOTE: this will modify the point4d pointed to by 'point'.
+ */
+int
+getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *op)
+{
+ uchar *ptr;
+ int zmflag;
+
+#if PARANOIA_LEVEL > 0
+ if ( ! pa ) lwerror("getPoint4d_p: NULL pointarray");
+
+ if ( (n<0) || (n>=pa->npoints))
+ {
+ lwerror("getPoint4d_p: point offset out of range");
+ }
+#endif
+
+ LWDEBUG(4, "getPoint4d_p called.");
+
+ /* Get a pointer to nth point offset and zmflag */
+ ptr=getPoint_internal(pa, n);
+ zmflag=TYPE_GETZM(pa->dims);
+
+ LWDEBUGF(4, "ptr %p, zmflag %d", ptr, zmflag);
+
+ switch (zmflag)
+ {
+ case 0: /* 2d */
+ memcpy(op, ptr, sizeof(POINT2D));
+ op->m=NO_M_VALUE;
+ op->z=NO_Z_VALUE;
+ break;
+
+ case 3: /* ZM */
+ memcpy(op, ptr, sizeof(POINT4D));
+ break;
+
+ case 2: /* Z */
+ memcpy(op, ptr, sizeof(POINT3DZ));
+ op->m=NO_M_VALUE;
+ break;
+
+ case 1: /* M */
+ memcpy(op, ptr, sizeof(POINT3DM));
+ op->m=op->z; /* we use Z as temporary storage */
+ op->z=NO_Z_VALUE;
+ break;
+
+ default:
+ lwerror("Unknown ZM flag ??");
+ }
+ return 1;
+
+}
+
+
+
+/*
+ * Copy a point from the point array into the parameter point
+ * will set point's z=NO_Z_VALUE if pa is 2d
+ * NOTE: point is a real POINT3DZ *not* a pointer
+ */
+POINT3DZ
+getPoint3dz(const POINTARRAY *pa, int n)
+{
+ POINT3DZ result;
+ getPoint3dz_p(pa, n, &result);
+ return result;
+}
+
+/*
+ * Copy a point from the point array into the parameter point
+ * will set point's z=NO_Z_VALUE if pa is 2d
+ *
+ * NOTE: point is a real POINT3DZ *not* a pointer
+ */
+POINT3DM
+getPoint3dm(const POINTARRAY *pa, int n)
+{
+ POINT3DM result;
+ getPoint3dm_p(pa, n, &result);
+ return result;
+}
+
+/*
+ * Copy a point from the point array into the parameter point
+ * will set point's z=NO_Z_VALUE if pa is 2d
+ *
+ * NOTE: this will modify the point3dz pointed to by 'point'.
+ */
+int
+getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *op)
+{
+ uchar *ptr;
+
+#if PARANOIA_LEVEL > 0
+ if ( ! pa ) return 0;
+
+ if ( (n<0) || (n>=pa->npoints))
+ {
+ LWDEBUGF(4, "%d out of numpoint range (%d)", n, pa->npoints);
+ return 0; /*error */
+ }
+#endif
+
+ LWDEBUGF(2, "getPoint3dz_p called on array of %d-dimensions / %u pts",
+ TYPE_NDIMS(pa->dims), pa->npoints);
+
+ /* Get a pointer to nth point offset */
+ ptr=getPoint_internal(pa, n);
+
+ /*
+ * if input POINTARRAY has the Z, it is always
+ * at third position so make a single copy
+ */
+ if ( TYPE_HASZ(pa->dims) )
+ {
+ memcpy(op, ptr, sizeof(POINT3DZ));
+ }
+
+ /*
+ * Otherwise copy the 2d part and initialize
+ * Z to NO_Z_VALUE
+ */
+ else
+ {
+ memcpy(op, ptr, sizeof(POINT2D));
+ op->z=NO_Z_VALUE;
+ }
+
+ return 1;
+
+}
+
+/*
+ * Copy a point from the point array into the parameter point
+ * will set point's m=NO_Z_VALUE if pa has no M
+ *
+ * NOTE: this will modify the point3dm pointed to by 'point'.
+ */
+int
+getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *op)
+{
+ uchar *ptr;
+ int zmflag;
+
+#if PARANOIA_LEVEL > 0
+ if ( ! pa ) return 0;
+
+ if ( (n<0) || (n>=pa->npoints))
+ {
+ lwerror("%d out of numpoint range (%d)", n, pa->npoints);
+ return 0; /*error */
+ }
+#endif
+
+ LWDEBUGF(2, "getPoint3dm_p(%d) called on array of %d-dimensions / %u pts",
+ n, TYPE_NDIMS(pa->dims), pa->npoints);
+
+
+ /* Get a pointer to nth point offset and zmflag */
+ ptr=getPoint_internal(pa, n);
+ zmflag=TYPE_GETZM(pa->dims);
+
+ /*
+ * if input POINTARRAY has the M and NO Z,
+ * we can issue a single memcpy
+ */
+ if ( zmflag == 1 )
+ {
+ memcpy(op, ptr, sizeof(POINT3DM));
+ return 1;
+ }
+
+ /*
+ * Otherwise copy the 2d part and
+ * initialize M to NO_M_VALUE
+ */
+ memcpy(op, ptr, sizeof(POINT2D));
+
+ /*
+ * Then, if input has Z skip it and
+ * copy next double, otherwise initialize
+ * M to NO_M_VALUE
+ */
+ if ( zmflag == 3 )
+ {
+ ptr+=sizeof(POINT3DZ);
+ memcpy(&(op->m), ptr, sizeof(double));
+ }
+ else
+ {
+ op->m=NO_M_VALUE;
+ }
+
+ return 1;
+}
+
+
+/*
+ * Copy a point from the point array into the parameter point
+ * z value (if present) is not returned.
+ *
+ * NOTE: point is a real POINT2D *not* a pointer
+ */
+POINT2D
+getPoint2d(const POINTARRAY *pa, int n)
+{
+ POINT2D result;
+ getPoint2d_p(pa, n, &result);
+ return result;
+}
+
+/*
+ * Copy a point from the point array into the parameter point
+ * z value (if present) is not returned.
+ *
+ * NOTE: this will modify the point2d pointed to by 'point'.
+ */
+int
+getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
+{
+#if PARANOIA_LEVEL > 0
+ if ( ! pa ) return 0;
+
+ if ( (n<0) || (n>=pa->npoints))
+ {
+ lwerror("getPoint2d_p: point offset out of range");
+ return 0; /*error */
+ }
+#endif
+
+ /* this does x,y */
+ memcpy(point, getPoint_internal(pa, n), sizeof(POINT2D));
+ return 1;
+}
+
+/*
+ * set point N to the given value
+ * NOTE that the pointarray can be of any
+ * dimension, the appropriate ordinate values
+ * will be extracted from it
+ *
+ */
+void
+setPoint4d(POINTARRAY *pa, int n, POINT4D *p4d)
+{
+ uchar *ptr=getPoint_internal(pa, n);
+ switch ( TYPE_GETZM(pa->dims) )
+ {
+ case 3:
+ memcpy(ptr, p4d, sizeof(POINT4D));
+ break;
+ case 2:
+ memcpy(ptr, p4d, sizeof(POINT3DZ));
+ break;
+ case 1:
+ memcpy(ptr, p4d, sizeof(POINT2D));
+ ptr+=sizeof(POINT2D);
+ memcpy(ptr, &(p4d->m), sizeof(double));
+ break;
+ case 0:
+ memcpy(ptr, p4d, sizeof(POINT2D));
+ break;
+ }
+}
+
+
+/*
+ * Get a pointer to nth point of a POINTARRAY.
+ * You cannot safely cast this to a real POINT, due to memory alignment
+ * constraints. Use getPoint*_p for that.
+ */
+uchar *
+getPoint_internal(const POINTARRAY *pa, int n)
+{
+ int size;
+
+#if PARANOIA_LEVEL > 0
+ if ( pa == NULL ) {
+ lwerror("getPoint got NULL pointarray");
+ return NULL;
+ }
+
+ if ( (n<0) || (n>=pa->npoints))
+ {
+ return NULL; /*error */
+ }
+#endif
+
+ size = pointArray_ptsize(pa);
+
+ return &(pa->serialized_pointlist[size*n]);
+}
+
+
+
+/*
+ * Constructs a POINTARRAY.
+ *
+ * NOTE: points is *not* copied, so be careful about modification
+ * (can be aligned/missaligned).
+ *
+ * NOTE: ndims is descriptive - it describes what type of data 'points'
+ * points to. No data conversion is done.
+ */
+POINTARRAY *
+pointArray_construct(uchar *points, char hasz, char hasm,
+ uint32 npoints)
+{
+ POINTARRAY *pa;
+
+ LWDEBUG(2, "pointArray_construct called.");
+
+ pa = (POINTARRAY*)lwalloc(sizeof(POINTARRAY));
+
+ pa->dims = 0;
+ TYPE_SETZM(pa->dims, hasz?1:0, hasm?1:0);
+ pa->npoints = npoints;
+
+ pa->serialized_pointlist = points;
+
+ LWDEBUGF(4, "pointArray_construct returning %p", pa);
+
+ return pa;
+}
+
+
+/*
+ * Size of point represeneted in the POINTARRAY
+ * 16 for 2d, 24 for 3d, 32 for 4d
+ */
+int
+pointArray_ptsize(const POINTARRAY *pa)
+{
+ LWDEBUGF(2, "pointArray_ptsize: TYPE_NDIMS(pa->dims)=%x\n",
+ TYPE_NDIMS(pa->dims));
+
+ return sizeof(double)*TYPE_NDIMS(pa->dims);
+}
+
+
+/***************************************************************************
+ * Basic type handling
+ ***************************************************************************/
+
+
+/* Returns true if this type says it has an SRID (S bit set) */
+char
+lwgeom_hasSRID(uchar type)
+{
+ return TYPE_HASSRID(type);
+}
+
+/* Returns either 2,3, or 4 -- 2=2D, 3=3D, 4=4D */
+int
+lwgeom_ndims(uchar type)
+{
+ return TYPE_NDIMS(type);
+}
+
+/* has M ? */
+int lwgeom_hasM(uchar type)
+{
+ return ( (type & 0x10) >>4);
+}
+
+/* has Z ? */
+int lwgeom_hasZ(uchar type)
+{
+ return ( (type & 0x20) >>5);
+}
+
+
+/* get base type (ie. POLYGONTYPE) */
+int
+lwgeom_getType(uchar type)
+{
+ LWDEBUGF(2, "lwgeom_getType %d", type);
+
+ return (type & 0x0F);
+}
+
+
+/* Construct a type (hasBOX=false) */
+uchar
+lwgeom_makeType(char hasz, char hasm, char hasSRID, int type)
+{
+ return lwgeom_makeType_full(hasz, hasm, hasSRID, type, 0);
+}
+
+/*
+ * Construct a type
+ * TODO: needs to be expanded to accept explicit MZ type
+ */
+uchar
+lwgeom_makeType_full(char hasz, char hasm, char hasSRID, int type, char hasBBOX)
+{
+ uchar result = (char)type;
+
+ TYPE_SETZM(result, hasz, hasm);
+ TYPE_SETHASSRID(result, hasSRID);
+ TYPE_SETHASBBOX(result, hasBBOX);
+
+ return result;
+}
+
+/* Returns true if there's a bbox in this LWGEOM (B bit set) */
+char
+lwgeom_hasBBOX(uchar type)
+{
+ return TYPE_HASBBOX(type);
+}
+
+/*****************************************************************************
+ * Basic sub-geometry types
+ *****************************************************************************/
+
+/* handle missaligned unsigned int32 data */
+uint32
+lw_get_uint32(const uchar *loc)
+{
+ uint32 result;
+
+ memcpy(&result, loc, sizeof(uint32));
+ return result;
+}
+
+/* handle missaligned signed int32 data */
+int32
+lw_get_int32(const uchar *loc)
+{
+ int32 result;
+
+ memcpy(&result,loc, sizeof(int32));
+ return result;
+}
+
+
+/*************************************************************************
+ *
+ * Multi-geometry support
+ *
+ * Note - for a simple type (ie. point), this will have
+ * sub_geom[0] = serialized_form.
+ *
+ * For multi-geomtries sub_geom[0] will be a few bytes
+ * into the serialized form.
+ *
+ * This function just computes the length of each sub-object and
+ * pre-caches this info.
+ *
+ * For a geometry collection of multi* geometries, you can inspect
+ * the sub-components
+ * as well.
+ */
+LWGEOM_INSPECTED *
+lwgeom_inspect(const uchar *serialized_form)
+{
+ LWGEOM_INSPECTED *result = lwalloc(sizeof(LWGEOM_INSPECTED));
+ uchar typefl = (uchar)serialized_form[0];
+ uchar type;
+ uchar **sub_geoms;
+ const uchar *loc;
+ int t;
+
+ LWDEBUGF(2, "lwgeom_inspect: serialized@%p", serialized_form);
+
+ if (serialized_form == NULL)
+ return NULL;
+
+ result->serialized_form = serialized_form;
+ result->type = (uchar) serialized_form[0];
+ result->SRID = -1; /* assume */
+
+ type = lwgeom_getType(typefl);
+
+ loc = serialized_form+1;
+
+ if ( lwgeom_hasBBOX(typefl) )
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ if ( lwgeom_hasSRID(typefl) )
+ {
+ result->SRID = lw_get_int32(loc);
+ loc += 4;
+ }
+
+ if ( (type==POINTTYPE) || (type==LINETYPE) || (type==POLYGONTYPE) || (type == CURVETYPE))
+ {
+ /* simple geometry (point/line/polygon)-- not multi! */
+ result->ngeometries = 1;
+ sub_geoms = (uchar**) lwalloc(sizeof(char*));
+ sub_geoms[0] = (uchar *)serialized_form;
+ result->sub_geoms = (uchar **)sub_geoms;
+ return result;
+ }
+
+ /* its a GeometryCollection or multi* geometry */
+
+ result->ngeometries = lw_get_uint32(loc);
+ loc +=4;
+
+ LWDEBUGF(3, "lwgeom_inspect: geometry is a collection of %d elements",
+ result->ngeometries);
+
+ if ( ! result->ngeometries ) return result;
+
+ sub_geoms = lwalloc(sizeof(uchar*) * result->ngeometries );
+ result->sub_geoms = sub_geoms;
+ sub_geoms[0] = (uchar *)loc;
+
+ LWDEBUGF(3, "subgeom[0] @ %p (+%d)", sub_geoms[0], sub_geoms[0]-serialized_form);
+
+ for (t=1;t<result->ngeometries; t++)
+ {
+ /* -1 = entire object */
+ int sub_length = lwgeom_size_subgeom(sub_geoms[t-1], -1);
+ sub_geoms[t] = sub_geoms[t-1] + sub_length;
+
+ LWDEBUGF(3, "subgeom[%d] @ %p (+%d)",
+ t, sub_geoms[t], sub_geoms[0]-serialized_form);
+ }
+
+ return result;
+
+}
+
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a point (with geom_num=0),
+ * multipoint or geometrycollection
+ */
+LWPOINT *
+lwgeom_getpoint(uchar *serialized_form, int geom_number)
+{
+ int type = lwgeom_getType((uchar)serialized_form[0]);
+ uchar *sub_geom;
+
+ if ((type == POINTTYPE) && (geom_number == 0))
+ {
+ /* Be nice and do as they want instead of what they say */
+ return lwpoint_deserialize(serialized_form);
+ }
+
+ if ((type != MULTIPOINTTYPE) && (type != COLLECTIONTYPE) )
+ return NULL;
+
+ sub_geom = lwgeom_getsubgeometry(serialized_form, geom_number);
+ if (sub_geom == NULL)
+ return NULL;
+
+ type = lwgeom_getType(sub_geom[0]);
+ if (type != POINTTYPE)
+ return NULL;
+
+ return lwpoint_deserialize(sub_geom);
+}
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a point (with geom_num=0), multipoint
+ * or geometrycollection
+ */
+LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
+{
+ uchar *sub_geom;
+ uchar type;
+
+ sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
+
+ if (sub_geom == NULL) return NULL;
+
+ type = lwgeom_getType(sub_geom[0]);
+ if (type != POINTTYPE) return NULL;
+
+ return lwpoint_deserialize(sub_geom);
+}
+
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual geometry isnt a LINE, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a line, multiline or geometrycollection
+ */
+LWLINE *
+lwgeom_getline(uchar *serialized_form, int geom_number)
+{
+ uchar type = lwgeom_getType( (uchar) serialized_form[0]);
+ uchar *sub_geom;
+
+ if ((type == LINETYPE) && (geom_number == 0))
+ {
+ /* be nice and do as they want instead of what they say */
+ return lwline_deserialize(serialized_form);
+ }
+
+ if ((type != MULTILINETYPE) && (type != COLLECTIONTYPE) )
+ return NULL;
+
+ sub_geom = lwgeom_getsubgeometry(serialized_form, geom_number);
+ if (sub_geom == NULL) return NULL;
+
+ type = lwgeom_getType((uchar) sub_geom[0]);
+ if (type != LINETYPE) return NULL;
+
+ return lwline_deserialize(sub_geom);
+}
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual geometry isnt a LINE, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a line, multiline or geometrycollection
+ */
+LWLINE *
+lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
+{
+ uchar *sub_geom;
+ uchar type;
+
+ sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
+
+ if (sub_geom == NULL) return NULL;
+
+ type = lwgeom_getType((uchar) sub_geom[0]);
+ if (type != LINETYPE) return NULL;
+
+ return lwline_deserialize(sub_geom);
+}
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a polygon, multipolygon or geometrycollection
+ */
+LWPOLY *
+lwgeom_getpoly(uchar *serialized_form, int geom_number)
+{
+ uchar type = lwgeom_getType((uchar)serialized_form[0]);
+ uchar *sub_geom;
+
+ if ((type == POLYGONTYPE) && (geom_number == 0))
+ {
+ /* Be nice and do as they want instead of what they say */
+ return lwpoly_deserialize(serialized_form);
+ }
+
+ if ((type != MULTIPOLYGONTYPE) && (type != COLLECTIONTYPE) )
+ return NULL;
+
+ sub_geom = lwgeom_getsubgeometry(serialized_form, geom_number);
+ if (sub_geom == NULL) return NULL;
+
+ type = lwgeom_getType(sub_geom[0]);
+ if (type != POLYGONTYPE) return NULL;
+
+ return lwpoly_deserialize(sub_geom);
+}
+
+/*
+ * 1st geometry has geom_number = 0
+ * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
+ * if there arent enough geometries, return null.
+ * this is fine to call on a polygon, multipolygon or geometrycollection
+ */
+LWPOLY *
+lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
+{
+ uchar *sub_geom;
+ uchar type;
+
+ sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
+
+ if (sub_geom == NULL) return NULL;
+
+ type = lwgeom_getType(sub_geom[0]);
+ if (type != POLYGONTYPE) return NULL;
+
+ return lwpoly_deserialize(sub_geom);
+}
+
+/*
+ * 1st geometry has geom_number = 0
+ * if there arent enough geometries, return null.
+ */
+LWGEOM *lwgeom_getgeom_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
+{
+ uchar *sub_geom;
+ uchar type;
+
+ sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
+
+ if (sub_geom == NULL) return NULL;
+
+ type = lwgeom_getType(sub_geom[0]);
+
+ return lwgeom_deserialize(sub_geom);
+}
+
+
+/*
+ * This gets the serialized form of a sub-geometry
+ *
+ * 1st geometry has geom_number = 0
+ * if this isnt a multi* geometry, and geom_number ==0 then it returns
+ * itself.
+ *
+ * Returns null on problems.
+ *
+ * In the future this is how you would access a muli* portion of a
+ * geometry collection.
+ * GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1))
+ * ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1)
+ * --> POINT(1 1)
+ *
+ * You can inspect the sub-geometry as well if you wish.
+ *
+ */
+uchar *
+lwgeom_getsubgeometry(const uchar *serialized_form, int geom_number)
+{
+ uchar *result;
+ /*major cheat!! */
+ LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized_form);
+
+ result = lwgeom_getsubgeometry_inspected(inspected, geom_number);
+ pfree_inspected(inspected);
+ return result;
+}
+
+uchar *
+lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
+{
+ if ((geom_number <0) || (geom_number >= inspected->ngeometries) )
+ {
+ lwerror("lwgeom_getsubgeometry_inspected: geom_number out of range");
+ return NULL;
+ }
+
+ return inspected->sub_geoms[geom_number];
+}
+
+
+/*
+ * 1st geometry has geom_number = 0
+ * use geom_number = -1 to find the actual type of the serialized form.
+ * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
+ * --> multipoint
+ * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
+ * --> point
+ * gets the 8bit type of the geometry at location geom_number
+ */
+uchar
+lwgeom_getsubtype(uchar *serialized_form, int geom_number)
+{
+ char result;
+ /*major cheat!! */
+ LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized_form);
+
+ result = lwgeom_getsubtype_inspected(inspected, geom_number);
+ pfree_inspected(inspected);
+ return result;
+}
+
+uchar
+lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
+{
+ if ((geom_number <0) || (geom_number >= inspected->ngeometries) )
+ return 99;
+
+ return inspected->sub_geoms[geom_number][0]; /* 1st byte is type */
+}
+
+
+/*
+ * How many sub-geometries are there?
+ * for point,line,polygon will return 1.
+ */
+int
+lwgeom_getnumgeometries(uchar *serialized_form)
+{
+ uchar type = lwgeom_getType((uchar)serialized_form[0]);
+ uchar *loc;
+
+ if ( (type==POINTTYPE) || (type==LINETYPE) || (type==POLYGONTYPE) ||
+ (type==CURVETYPE) || (type==COMPOUNDTYPE) || (type==CURVEPOLYTYPE) )
+ {
+ return 1;
+ }
+
+ loc = serialized_form+1;
+
+ if (lwgeom_hasBBOX((uchar) serialized_form[0]))
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ if (lwgeom_hasSRID((uchar) serialized_form[0]) )
+ {
+ loc += 4;
+ }
+ /* its a GeometryCollection or multi* geometry */
+ return lw_get_uint32(loc);
+}
+
+/*
+ * How many sub-geometries are there?
+ * for point,line,polygon will return 1.
+ */
+int
+lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected)
+{
+ return inspected->ngeometries;
+}
+
+
+/*
+ * Set finalType to COLLECTIONTYPE or 0 (0 means choose a best type)
+ * (ie. give it 2 points and ask it to be a multipoint)
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
+ * all subgeometries must have the same SRID
+ * if you want to construct an inspected, call this then inspect the result...
+ */
+uchar *
+lwgeom_serialized_construct(int SRID, int finalType, char hasz, char hasm,
+ int nsubgeometries, uchar **serialized_subs)
+{
+ uint32 *lengths;
+ int t;
+ int total_length = 0;
+ char type = (char)-1;
+ char this_type = -1;
+ uchar *result;
+ uchar *loc;
+
+ if (nsubgeometries == 0)
+ return lwgeom_constructempty(SRID, hasz, hasm);
+
+ lengths = lwalloc(sizeof(int32) * nsubgeometries);
+
+ for (t=0;t<nsubgeometries;t++)
+ {
+ lengths[t] = lwgeom_size_subgeom(serialized_subs[t],-1);
+ total_length += lengths[t];
+ this_type = lwgeom_getType((uchar) (serialized_subs[t][0]));
+ if (type == (char)-1)
+ {
+ type = this_type;
+ }
+ else if (type == COLLECTIONTYPE)
+ {
+ /* still a collection type... */
+ }
+ else
+ {
+ if ( (this_type == MULTIPOINTTYPE) || (this_type == MULTILINETYPE) || (this_type == MULTIPOLYGONTYPE) || (this_type == COLLECTIONTYPE) )
+ {
+ type = COLLECTIONTYPE;
+ }
+ else
+ {
+ if ( (this_type == POINTTYPE) && (type==POINTTYPE) )
+ type=MULTIPOINTTYPE;
+ else if ( (this_type == LINETYPE) && (type==LINETYPE) )
+ type=MULTILINETYPE;
+ else if ( (this_type == POLYGONTYPE) && (type==POLYGONTYPE) )
+ type=MULTIPOLYGONTYPE;
+ else if ( (this_type == POLYGONTYPE) && (type==MULTIPOLYGONTYPE) )
+ ; /* nop */
+ else if ( (this_type == LINETYPE) && (type==MULTILINETYPE) )
+ ; /* nop */
+ else if ( (this_type == POINTTYPE) && (type==MULTIPOINTTYPE) )
+ ; /* nop */
+ else
+ type = COLLECTIONTYPE;
+ }
+ }
+ }
+
+ if (type == POINTTYPE)
+ type = MULTIPOINTTYPE;
+ if (type == LINETYPE)
+ type = MULTILINETYPE;
+ if (type == POINTTYPE)
+ type = MULTIPOINTTYPE;
+
+ if (finalType == COLLECTIONTYPE)
+ type = COLLECTIONTYPE;
+
+ /* now we have a multi* or GEOMETRYCOLLECTION, let's serialize it */
+
+ if (SRID != -1)
+ total_length +=4; /* space for SRID */
+
+ total_length +=1 ; /* main type; */
+ total_length +=4 ; /* nsubgeometries */
+
+ result = lwalloc(total_length);
+ result[0] = (uchar) lwgeom_makeType(hasz, hasm, SRID != -1, type);
+ if (SRID != -1)
+ {
+ memcpy(&result[1],&SRID,4);
+ loc = result+5;
+ }
+ else
+ loc = result+1;
+
+ memcpy(loc,&nsubgeometries,4);
+ loc +=4;
+
+ for (t=0;t<nsubgeometries;t++)
+ {
+ memcpy(loc, serialized_subs[t], lengths[t] );
+ loc += lengths[t] ;
+ }
+
+ lwfree(lengths);
+ return result;
+}
+
+
+/*
+ * Construct the empty geometry (GEOMETRYCOLLECTION(EMPTY)).
+ *
+ * Returns serialized form
+ */
+uchar *
+lwgeom_constructempty(int SRID, char hasz, char hasm)
+{
+ int size = 0;
+ uchar *result;
+ int ngeoms = 0;
+ uchar *loc;
+
+ if (SRID != -1)
+ size +=4;
+
+ size += 5;
+
+ result = lwalloc(size);
+
+ result[0] = lwgeom_makeType(hasz, hasm, SRID != -1, COLLECTIONTYPE);
+ if (SRID != -1)
+ {
+ memcpy(&result[1],&SRID,4);
+ loc = result+5;
+ }
+ else
+ loc = result+1;
+
+ memcpy(loc,&ngeoms,4);
+ return result;
+}
+
+size_t
+lwgeom_empty_length(int SRID)
+{
+ int size = 5;
+ if ( SRID != 1 ) size += 4;
+ return size;
+}
+
+/*
+ * Construct the empty geometry (GEOMETRYCOLLECTION(EMPTY))
+ * writing it into the provided buffer.
+ */
+void
+lwgeom_constructempty_buf(int SRID, char hasz, char hasm,
+ uchar *buf, size_t *retsize)
+{
+ int ngeoms = 0;
+
+ buf[0] =(uchar) lwgeom_makeType( hasz, hasm, SRID != -1, COLLECTIONTYPE);
+ if (SRID != -1)
+ {
+ memcpy(&buf[1],&SRID,4);
+ buf += 5;
+ }
+ else
+ buf += 1;
+
+ memcpy(buf, &ngeoms, 4);
+
+ if (retsize) *retsize = lwgeom_empty_length(SRID);
+}
+
+/*
+ * helper function (not for general use)
+ * find the size a geometry (or a sub-geometry)
+ * 1st geometry has geom_number = 0
+ * use geom_number = -1 to find the actual type of the serialized form.
+ * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
+ * --> size of the multipoint
+ * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
+ * --> size of the point
+ * take a geometry, and find its length
+ */
+size_t
+lwgeom_size(const uchar *serialized_form)
+{
+ uchar type = lwgeom_getType((uchar) serialized_form[0]);
+ int t;
+ const uchar *loc;
+ uint32 ngeoms;
+ int sub_size;
+ int result = 1; /* type */
+
+ LWDEBUG(2, "lwgeom_size called");
+
+ if (type == POINTTYPE)
+ {
+ LWDEBUG(3, "lwgeom_size: is a point");
+
+ return lwgeom_size_point(serialized_form);
+ }
+ else if (type == LINETYPE)
+ {
+ LWDEBUG(3, "lwgeom_size: is a line");
+
+ return lwgeom_size_line(serialized_form);
+ }
+ else if(type == CURVETYPE)
+ {
+ LWDEBUG(3, "lwgeom_size: is a curve");
+
+ return lwgeom_size_curve(serialized_form);
+ }
+ else if (type == POLYGONTYPE)
+ {
+ LWDEBUG(3, "lwgeom_size: is a polygon");
+
+ return lwgeom_size_poly(serialized_form);
+ }
+ else if (type == COMPOUNDTYPE)
+ {
+ LWDEBUG(3, "lwgeom_size: is a compound curve");
+ }
+
+ if ( type == 0 )
+ {
+ lwerror("lwgeom_size called with unknown-typed serialized geometry");
+ return 0;
+ }
+
+ /*
+ * Handle all the multi* and geometrycollections the same
+ *
+ * NOTE: for a geometry collection of GC of GC of GC we will
+ * be recursing...
+ */
+
+ LWDEBUGF(3, "lwgeom_size called on a geoemtry with type %d", type);
+
+ loc = serialized_form+1;
+
+ if (lwgeom_hasBBOX((uchar) serialized_form[0]))
+ {
+ LWDEBUG(3, "lwgeom_size: has bbox");
+
+ loc += sizeof(BOX2DFLOAT4);
+ result +=sizeof(BOX2DFLOAT4);
+ }
+
+ if (lwgeom_hasSRID( (uchar) serialized_form[0]) )
+ {
+ LWDEBUG(3, "lwgeom_size: has srid");
+
+ result +=4;
+ loc +=4;
+ }
+
+
+ ngeoms = lw_get_uint32(loc);
+ loc +=4;
+ result += 4; /* numgeoms */
+
+ LWDEBUGF(3, "lwgeom_size called on a geoemtry with %d elems (result so far: %d)", ngeoms, result);
+
+ for (t=0;t<ngeoms;t++)
+ {
+ sub_size = lwgeom_size(loc);
+
+ LWDEBUGF(3, " subsize %d", sub_size);
+
+ loc += sub_size;
+ result += sub_size;
+ }
+
+ LWDEBUGF(3, "lwgeom_size returning %d", result);
+
+ return result;
+}
+
+size_t
+lwgeom_size_subgeom(const uchar *serialized_form, int geom_number)
+{
+ if (geom_number == -1)
+ {
+ return lwgeom_size(serialized_form);
+ }
+ return lwgeom_size( lwgeom_getsubgeometry(serialized_form,geom_number));
+}
+
+
+
+int
+lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number)
+{
+ return lwgeom_size(inspected->sub_geoms[geom_number]);
+}
+
+int
+compute_serialized_box3d_p(uchar *srl, BOX3D *out)
+{
+ BOX3D *box = compute_serialized_box3d(srl);
+ if ( ! box ) return 0;
+ out->xmin = box->xmin;
+ out->ymin = box->ymin;
+ out->zmin = box->zmin;
+ out->xmax = box->xmax;
+ out->ymax = box->ymax;
+ out->zmax = box->zmax;
+ lwfree(box);
+
+ return 1;
+}
+
+/*
+ * Compute bounding box of a serialized LWGEOM, even if it is
+ * already cached. The computed BOX2DFLOAT4 is stored at
+ * the given location, the function returns 0 is the geometry
+ * does not have a bounding box (EMPTY GEOM)
+ */
+int
+compute_serialized_box2d_p(uchar *srl, BOX2DFLOAT4 *out)
+{
+ BOX3D *result = compute_serialized_box3d(srl);
+ if ( ! result ) return 0;
+ out->xmin = result->xmin;
+ out->xmax = result->xmax;
+ out->ymin = result->ymin;
+ out->ymax = result->ymax;
+ lwfree(result);
+
+ return 1;
+}
+
+/*
+ * Don't forget to lwfree() result !
+ */
+BOX3D *
+compute_serialized_box3d(uchar *srl)
+{
+ int type = lwgeom_getType(srl[0]);
+ int t;
+ uchar *loc;
+ uint32 ngeoms;
+ BOX3D *result;
+ BOX3D b1;
+ int sub_size;
+ char nboxes=0;
+
+ LWDEBUGF(2, "compute_serialized_box3d called on type %d", type);
+
+ if (type == POINTTYPE)
+ {
+ LWPOINT *pt = lwpoint_deserialize(srl);
+
+ LWDEBUG(3, "compute_serialized_box3d: lwpoint deserialized");
+
+ result = lwpoint_compute_box3d(pt);
+
+ LWDEBUG(3, "compute_serialized_box3d: bbox found");
+
+ pfree_point(pt);
+ return result;
+ }
+
+ else if (type == LINETYPE)
+ {
+ LWLINE *line = lwline_deserialize(srl);
+ result = lwline_compute_box3d(line);
+ pfree_line(line);
+ return result;
+
+ }
+ else if (type == CURVETYPE)
+ {
+ LWCURVE *curve = lwcurve_deserialize(srl);
+ result = lwcurve_compute_box3d(curve);
+ pfree_curve(curve);
+ return result;
+ }
+ else if (type == POLYGONTYPE)
+ {
+ LWPOLY *poly = lwpoly_deserialize(srl);
+ result = lwpoly_compute_box3d(poly);
+ pfree_polygon(poly);
+ return result;
+ }
+
+ if ( ! ( type == MULTIPOINTTYPE || type == MULTILINETYPE ||
+ type == MULTIPOLYGONTYPE || type == COLLECTIONTYPE ||
+ type == COMPOUNDTYPE || type == CURVEPOLYTYPE ||
+ type == MULTICURVETYPE || type == MULTISURFACETYPE) )
+ {
+ lwnotice("compute_serialized_box3d called on unknown type %d", type);
+ return NULL;
+ }
+
+ loc = srl+1;
+
+ if (lwgeom_hasBBOX(srl[0]))
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ if (lwgeom_hasSRID(srl[0]) )
+ {
+ loc +=4;
+ }
+
+ ngeoms = lw_get_uint32(loc);
+ loc += 4;
+
+ /* each sub-type */
+ result = NULL;
+ for (t=0; t<ngeoms; t++)
+ {
+ if ( compute_serialized_box3d_p(loc, &b1) )
+ {
+ LWDEBUG(3, "Geom %d have box:");
+#if POSTGIS_DEBUG_LEVEL >= 3
+ printBOX3D(&b1);
+#endif
+
+ if (result)
+ {
+ nboxes += box3d_union_p(result, &b1, result);
+ }
+ else
+ {
+ result = lwalloc(sizeof(BOX3D));
+ memcpy(result, &b1, sizeof(BOX3D));
+ }
+ }
+
+ sub_size = lwgeom_size(loc);
+ loc += sub_size;
+ }
+
+ return result;
+
+}
+
+/****************************************************************
+ * memory management
+ *
+ * these only delete the memory associated
+ * directly with the structure - NOT the stuff pointing into
+ * the original de-serialized info
+ *
+ ****************************************************************/
+
+void
+pfree_inspected(LWGEOM_INSPECTED *inspected)
+{
+ if ( inspected->ngeometries )
+ lwfree(inspected->sub_geoms);
+ lwfree(inspected);
+}
+
+
+void pfree_POINTARRAY(POINTARRAY *pa)
+{
+ lwfree(pa);
+}
+
+
+
+
+/************************************************
+ * debugging routines
+ ************************************************/
+
+
+void printBOX3D(BOX3D *box)
+{
+ lwnotice("BOX3D: %g %g, %g %g", box->xmin, box->ymin,
+ box->xmax, box->ymax);
+}
+
+void printPA(POINTARRAY *pa)
+{
+ int t;
+ POINT4D pt;
+ char *mflag;
+
+
+ if ( TYPE_HASM(pa->dims) ) mflag = "M";
+ else mflag = "";
+
+ lwnotice(" POINTARRAY%s{", mflag);
+ lwnotice(" ndims=%i, ptsize=%i",
+ TYPE_NDIMS(pa->dims), pointArray_ptsize(pa));
+ lwnotice(" npoints = %i", pa->npoints);
+
+ for (t =0; t<pa->npoints;t++)
+ {
+ getPoint4d_p(pa, t, &pt);
+ if (TYPE_NDIMS(pa->dims) == 2)
+ {
+ lwnotice(" %i : %lf,%lf",t,pt.x,pt.y);
+ }
+ if (TYPE_NDIMS(pa->dims) == 3)
+ {
+ lwnotice(" %i : %lf,%lf,%lf",t,pt.x,pt.y,pt.z);
+ }
+ if (TYPE_NDIMS(pa->dims) == 4)
+ {
+ lwnotice(" %i : %lf,%lf,%lf,%lf",t,pt.x,pt.y,pt.z,pt.m);
+ }
+ }
+
+ lwnotice(" }");
+}
+
+void printBYTES(uchar *a, int n)
+{
+ int t;
+ char buff[3];
+
+ buff[2] = 0; /* null terminate */
+
+ lwnotice(" BYTE ARRAY (n=%i) IN HEX: {", n);
+ for (t=0;t<n;t++)
+ {
+ deparse_hex(a[t], buff);
+ lwnotice(" %i : %s", t,buff );
+ }
+ lwnotice(" }");
+}
+
+
+void
+printMULTI(uchar *serialized)
+{
+ LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized);
+ LWLINE *line;
+ LWPOINT *point;
+ LWPOLY *poly;
+ int t;
+
+ lwnotice("MULTI* geometry (type = %i), with %i sub-geoms",lwgeom_getType((uchar)serialized[0]), inspected->ngeometries);
+
+ for (t=0;t<inspected->ngeometries;t++)
+ {
+ lwnotice(" sub-geometry %i:", t);
+ line = NULL; point = NULL; poly = NULL;
+
+ line = lwgeom_getline_inspected(inspected,t);
+ if (line !=NULL)
+ {
+ printLWLINE(line);
+ }
+ poly = lwgeom_getpoly_inspected(inspected,t);
+ if (poly !=NULL)
+ {
+ printLWPOLY(poly);
+ }
+ point = lwgeom_getpoint_inspected(inspected,t);
+ if (point !=NULL)
+ {
+ printPA(point->point);
+ }
+ }
+
+ lwnotice("end multi*");
+
+ pfree_inspected(inspected);
+}
+
+void
+printType(uchar type)
+{
+ lwnotice("type 0x%x ==> hasBBOX=%i, hasSRID=%i, ndims=%i, type=%i",(unsigned int) type, lwgeom_hasBBOX(type), lwgeom_hasSRID(type),lwgeom_ndims(type), lwgeom_getType(type));
+}
+
+/*
+ * Get the SRID from the LWGEOM.
+ * None present => -1
+ */
+int
+lwgeom_getsrid(uchar *serialized)
+{
+ uchar type = serialized[0];
+ uchar *loc = serialized+1;
+
+ if ( ! lwgeom_hasSRID(type)) return -1;
+
+ if (lwgeom_hasBBOX(type))
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ return lw_get_int32(loc);
+}
+
+char
+ptarray_isccw(const POINTARRAY *pa)
+{
+ int i;
+ double area = 0;
+ POINT2D p1, p2;
+
+ for (i=0; i<pa->npoints-1; i++)
+ {
+ getPoint2d_p(pa, i, &p1);
+ getPoint2d_p(pa, i+1, &p2);
+ area += (p1.y * p2.x) - (p1.x * p2.y);
+ }
+ if ( area > 0 ) return 0;
+ else return 1;
+}
+
+/*
+ * Returns a BOX2DFLOAT4 that encloses b1 and b2
+ *
+ * box2d_union(NULL,A) --> A
+ * box2d_union(A,NULL) --> A
+ * box2d_union(A,B) --> A union B
+ */
+BOX2DFLOAT4 *
+box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2)
+{
+ BOX2DFLOAT4 *result;
+
+ if ( (b1 == NULL) && (b2 == NULL) )
+ {
+ return NULL;
+ }
+
+ result = lwalloc(sizeof(BOX2DFLOAT4));
+
+ if (b1 == NULL)
+ {
+ memcpy(result, b2, sizeof(BOX2DFLOAT4));
+ return result;
+ }
+ if (b2 == NULL)
+ {
+ memcpy(result, b1, sizeof(BOX2DFLOAT4));
+ return result;
+ }
+
+ if (b1->xmin < b2->xmin) result->xmin = b1->xmin;
+ else result->xmin = b2->xmin;
+
+ if (b1->ymin < b2->ymin) result->ymin = b1->ymin;
+ else result->ymin = b2->ymin;
+
+ if (b1->xmax > b2->xmax) result->xmax = b1->xmax;
+ else result->xmax = b2->xmax;
+
+ if (b1->ymax > b2->ymax) result->ymax = b1->ymax;
+ else result->ymax = b2->ymax;
+
+ return result;
+}
+
+/*
+ * ubox may be one of the two args...
+ * return 1 if done something to ubox, 0 otherwise.
+ */
+int
+box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox)
+{
+ if ( (b1 == NULL) && (b2 == NULL) )
+ {
+ return 0;
+ }
+
+ if (b1 == NULL)
+ {
+ memcpy(ubox, b2, sizeof(BOX2DFLOAT4));
+ return 1;
+ }
+ if (b2 == NULL)
+ {
+ memcpy(ubox, b1, sizeof(BOX2DFLOAT4));
+ return 1;
+ }
+
+ if (b1->xmin < b2->xmin) ubox->xmin = b1->xmin;
+ else ubox->xmin = b2->xmin;
+
+ if (b1->ymin < b2->ymin) ubox->ymin = b1->ymin;
+ else ubox->ymin = b2->ymin;
+
+ if (b1->xmax > b2->xmax) ubox->xmax = b1->xmax;
+ else ubox->xmax = b2->xmax;
+
+ if (b1->ymax > b2->ymax) ubox->ymax = b1->ymax;
+ else ubox->ymax = b2->ymax;
+
+ return 1;
+}
+
+const char *
+lwgeom_typeflags(uchar type)
+{
+ static char flags[5];
+ int flagno=0;
+ if ( TYPE_HASZ(type) ) flags[flagno++] = 'Z';
+ if ( TYPE_HASM(type) ) flags[flagno++] = 'M';
+ if ( TYPE_HASBBOX(type) ) flags[flagno++] = 'B';
+ if ( TYPE_HASSRID(type) ) flags[flagno++] = 'S';
+ flags[flagno] = '\0';
+
+ LWDEBUGF(4, "Flags: %s - returning %p", flags, flags);
+
+ return flags;
+}
+
+/*
+ * Given a string with at least 2 chars in it, convert them to
+ * a byte value. No error checking done!
+ */
+uchar
+parse_hex(char *str)
+{
+ /* do this a little brute force to make it faster */
+
+ uchar result_high = 0;
+ uchar result_low = 0;
+
+ switch (str[0])
+ {
+ case '0' :
+ result_high = 0;
+ break;
+ case '1' :
+ result_high = 1;
+ break;
+ case '2' :
+ result_high = 2;
+ break;
+ case '3' :
+ result_high = 3;
+ break;
+ case '4' :
+ result_high = 4;
+ break;
+ case '5' :
+ result_high = 5;
+ break;
+ case '6' :
+ result_high = 6;
+ break;
+ case '7' :
+ result_high = 7;
+ break;
+ case '8' :
+ result_high = 8;
+ break;
+ case '9' :
+ result_high = 9;
+ break;
+ case 'A' :
+ result_high = 10;
+ break;
+ case 'B' :
+ result_high = 11;
+ break;
+ case 'C' :
+ result_high = 12;
+ break;
+ case 'D' :
+ result_high = 13;
+ break;
+ case 'E' :
+ result_high = 14;
+ break;
+ case 'F' :
+ result_high = 15;
+ break;
+ }
+ switch (str[1])
+ {
+ case '0' :
+ result_low = 0;
+ break;
+ case '1' :
+ result_low = 1;
+ break;
+ case '2' :
+ result_low = 2;
+ break;
+ case '3' :
+ result_low = 3;
+ break;
+ case '4' :
+ result_low = 4;
+ break;
+ case '5' :
+ result_low = 5;
+ break;
+ case '6' :
+ result_low = 6;
+ break;
+ case '7' :
+ result_low = 7;
+ break;
+ case '8' :
+ result_low = 8;
+ break;
+ case '9' :
+ result_low = 9;
+ break;
+ case 'A' :
+ result_low = 10;
+ break;
+ case 'B' :
+ result_low = 11;
+ break;
+ case 'C' :
+ result_low = 12;
+ break;
+ case 'D' :
+ result_low = 13;
+ break;
+ case 'E' :
+ result_low = 14;
+ break;
+ case 'F' :
+ result_low = 15;
+ break;
+ }
+ return (uchar) ((result_high<<4) + result_low);
+}
+
+
+/*
+ * Given one byte, populate result with two byte representing
+ * the hex number.
+ *
+ * Ie. deparse_hex( 255, mystr)
+ * -> mystr[0] = 'F' and mystr[1] = 'F'
+ *
+ * No error checking done
+ */
+void
+deparse_hex(uchar str, char *result)
+{
+ int input_high;
+ int input_low;
+ static char outchr[]={"0123456789ABCDEF" };
+
+ input_high = (str>>4);
+ input_low = (str & 0x0F);
+
+ result[0] = outchr[input_high];
+ result[1] = outchr[input_low];
+
+}
+
+SERIALIZED_LWGEOM *
+parse_lwgeom_wkt(char *wkt_input)
+{
+ SERIALIZED_LWGEOM *serialized_form = parse_lwg(wkt_input,
+ lwalloc, lwerror);
+
+
+ LWDEBUGF(2, "parse_lwgeom_wkt with %s",wkt_input);
+
+ if (serialized_form == NULL)
+ {
+ lwerror("parse_WKT:: couldnt parse!");
+ return NULL;
+ }
+
+ return serialized_form;
+
+}
+
+/*
+ * Find interpolation point I
+ * between point A and point B
+ * so that the len(AI) == len(AB)*F
+ * and I falls on AB segment.
+ *
+ * Example:
+ *
+ * F=0.5 : A----I----B
+ * F=1 : A---------B==I
+ * F=0 : A==I---------B
+ * F=.2 : A-I-------B
+ */
+void
+interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F)
+{
+#if PARANOIA_LEVEL > 0
+ double absF=fabs(F);
+ if ( absF < 0 || absF > 1 )
+ {
+ lwerror("interpolate_point4d: invalid F (%g)", F);
+ }
+#endif
+ I->x=A->x+((B->x-A->x)*F);
+ I->y=A->y+((B->y-A->y)*F);
+ I->z=A->z+((B->z-A->z)*F);
+ I->m=A->m+((B->m-A->m)*F);
+}
Added: trunk/liblwgeom/lwgparse.c
===================================================================
--- trunk/liblwgeom/lwgparse.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwgparse.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,1153 @@
+/*
+ * Written by Ralph Mason ralph.mason<at>telogis.com
+ *
+ * Copyright Telogis 2004
+ * www.telogis.com
+ *
+ */
+#include <string.h>
+#include <stdio.h>
+/* Solaris9 does not provide stdint.h */
+/* #include <stdint.h> */
+#include <inttypes.h>
+
+#include "liblwgeom.h"
+#include "wktparse.h"
+
+/*
+ * To get byte order
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+*/
+
+void set_zm(char z, char m);
+void close_parser(void);
+
+typedef uint32_t int4;
+
+typedef struct tag_tuple tuple;
+
+struct tag_outputstate{
+ uchar* pos;
+};
+
+typedef struct tag_outputstate output_state;
+typedef void (*output_func)(tuple* this, output_state* out);
+typedef void (*read_col_func)(const char **f);
+
+
+
+/* Globals */
+
+int srid=-1;
+
+static int ferror_occured;
+static allocator local_malloc;
+static report_error error_func;
+
+struct tag_tuple{
+ output_func of;
+ union union_tag {
+ double points[4];
+ int4 pointsi[4];
+
+ struct struct_tag {
+ tuple* stack_next;
+ int type;
+ int num;
+ int size_here;
+ } nn;
+ } uu;
+ struct tag_tuple *next;
+};
+
+struct {
+ int type;
+ int flags;
+ int srid;
+ int ndims;
+ int hasZ;
+ int hasM;
+ /* create integer version */
+ int lwgi;
+ /* input is integer (wkb only)*/
+ int from_lwgi;
+
+ int4 alloc_size;
+
+ /*
+ linked list of all tuples
+ */
+ tuple* first;
+ tuple* last;
+
+ /*
+ stack of open geometries
+ */
+ tuple* stack;
+
+} the_geom;
+
+tuple* free_list=0;
+int minpoints;
+int checkclosed;
+
+/*
+ * This inicates if the number of points in the geometry is required to
+ * be odd (one) or even (zero, currently not enforced) or whatever (-one)
+ */
+int isodd;
+double *first_point=NULL;
+double *last_point=NULL;
+
+/* External functions */
+extern void init_parser(const char *);
+
+/* Prototypes */
+tuple* alloc_tuple(output_func of,size_t size);
+static void error(const char* err);
+void free_tuple(tuple* to_free);
+void inc_num(void);
+void alloc_stack_tuple(int type,output_func of,size_t size);
+void check_dims(int num);
+void WRITE_DOUBLES(output_state* out,double* points, int cnt);
+#ifdef SHRINK_INTS
+void WRITE_INT4(output_state * out,int4 val);
+#endif
+void empty_stack(tuple* this,output_state* out);
+void alloc_lwgeom(int srid);
+void write_point_2(tuple* this,output_state* out);
+void write_point_3(tuple* this,output_state* out);
+void write_point_4(tuple* this,output_state* out);
+void write_point_2i(tuple* this,output_state* out);
+void write_point_3i(tuple* this,output_state* out);
+void write_point_4i(tuple* this,output_state* out);
+void alloc_point_2d(double x,double y);
+void alloc_point_3d(double x,double y,double z);
+void alloc_point_4d(double x,double y,double z,double m);
+void write_type(tuple* this,output_state* out);
+void write_count(tuple* this,output_state* out);
+void write_type_count(tuple* this,output_state* out);
+void alloc_point(void);
+void alloc_linestring(void);
+void alloc_linestring_closed(void);
+void alloc_circularstring(void);
+void alloc_circularstring_closed(void);
+void alloc_polygon(void);
+void alloc_multipoint(void);
+void alloc_multilinestring(void);
+void alloc_multicurve(void);
+void alloc_multipolygon(void);
+void alloc_multisurface(void);
+void alloc_geomertycollection(void);
+void alloc_counter(void);
+void alloc_empty(void);
+SERIALIZED_LWGEOM* make_serialized_lwgeom(void);
+uchar strhex_readbyte(const char *in);
+uchar read_wkb_byte(const char **in);
+void read_wkb_bytes(const char **in, uchar* out, int cnt);
+int4 read_wkb_int(const char **in);
+double read_wkb_double(const char **in, int convert_from_int);
+void read_wkb_point(const char **b);
+void read_wkb_polygon(const char **b);
+void read_wkb_linestring(const char **b);
+void read_wkb_curve(const char **b);
+void read_wkb_ordinate_array(const char **b);
+void read_collection(const char **b, read_col_func f);
+void parse_wkb(const char **b);
+void alloc_wkb(const char *parser);
+SERIALIZED_LWGEOM* parse_it(const char* geometry, allocator allocfunc, report_error errfunc);
+SERIALIZED_LWGEOM* parse_lwg(const char* geometry, allocator allocfunc, report_error errfunc);
+SERIALIZED_LWGEOM* parse_lwgi(const char* geometry, allocator allocfunc, report_error errfunc);
+
+void
+set_srid(double d_srid)
+{
+ if ( d_srid >= 0 )
+ d_srid+=0.1;
+ else
+ d_srid-=0.1;
+
+
+ srid=(int)(d_srid+0.1);
+}
+
+tuple *
+alloc_tuple(output_func of,size_t size)
+{
+ tuple* ret = free_list;
+
+ if ( ! ret ){
+ int toalloc = (ALLOC_CHUNKS /sizeof(tuple));
+ ret = malloc( toalloc *sizeof(tuple) );
+
+ free_list = ret;
+
+ while(--toalloc){
+ ret->next = ret+1;
+ ret++;
+ }
+
+ ret->next = NULL;
+
+ return alloc_tuple(of,size);
+ }
+
+ free_list = ret->next;
+ ret->of = of;
+ ret->next = NULL;
+
+ if ( the_geom.last ) {
+ the_geom.last->next = ret;
+ the_geom.last = ret;
+ }
+ else {
+ the_geom.first = the_geom.last = ret;
+ }
+
+ the_geom.alloc_size += size;
+ return ret;
+}
+
+static void
+error(const char* err)
+{
+ error_func(err);
+ ferror_occured=1;
+}
+
+void
+free_tuple(tuple* to_free)
+{
+
+ tuple* list_end = to_free;
+
+ if( !to_free)
+ return;
+
+ while(list_end->next){
+ list_end=list_end->next;
+ }
+
+ list_end->next = free_list;
+ free_list = to_free;
+}
+
+void
+inc_num(void)
+{
+ the_geom.stack->uu.nn.num++;
+}
+
+/*
+ Allocate a 'counting' tuple
+*/
+void
+alloc_stack_tuple(int type,output_func of,size_t size)
+{
+ tuple* p;
+ inc_num();
+
+ LWDEBUGF(2, "alloc_stack_tuple %d, %d", type, size);
+
+ p = alloc_tuple(of,size);
+ p->uu.nn.stack_next = the_geom.stack;
+ p->uu.nn.type = type;
+ p->uu.nn.size_here = the_geom.alloc_size;
+ p->uu.nn.num = 0;
+ the_geom.stack = p;
+}
+
+void
+pop(void)
+{
+ the_geom.stack = the_geom.stack->uu.nn.stack_next;
+}
+
+void
+popc(void)
+{
+
+ if ( the_geom.stack->uu.nn.num < minpoints){
+ error("geometry requires more points");
+ }
+ if(isodd != -1 && the_geom.stack->uu.nn.num % 2 != isodd) {
+ error("geometry must have an odd number of points");
+ }
+ if ( checkclosed && first_point && last_point) {
+ if ( memcmp(first_point, last_point,
+ sizeof(double)*the_geom.ndims) )
+ {
+ error("geometry contains non-closed rings");
+ }
+ }
+
+ the_geom.stack = the_geom.stack->uu.nn.stack_next;
+}
+
+
+void
+check_dims(int num)
+{
+ LWDEBUGF(2, "check_dims the_geom.ndims = %d, num = %d", the_geom.ndims, num);
+
+ if( the_geom.ndims != num){
+ if (the_geom.ndims) {
+ error("Can not mix dimensionality in a geometry");
+ } else {
+
+ LWDEBUGF(3, "check_dims: setting dim %d", num);
+
+ the_geom.ndims = num;
+ if ( num > 2 ) the_geom.hasZ = 1;
+ if ( num > 3 ) the_geom.hasM = 1;
+ }
+ }
+}
+
+#define WRITE_INT4_REAL(x,y) { memcpy(x->pos,&y,4); x->pos+=4;}
+#define WRITE_INT4_REAL_MULTIPLE(x,y,z) { memcpy(x->pos,&y,z*4); x->pos+=(z*4);}
+
+/*
+ we can shrink ints to one byte if they are less than 127
+ by setting the extra bit. Because if the different byte
+ ordering possibilities we need to set the lsb on little
+ endian to show a packed one and the msb on a big endian
+ machine
+*/
+#ifdef SHRINK_INTS
+void
+WRITE_INT4(output_state * out,int4 val)
+{
+ if ( val <= 0x7f ){
+ if ( getMachineEndian() == NDR ){
+ val = (val<<1) | 1;
+ }
+ else{
+ val |=0x80;
+ }
+
+ *out->pos++ = (uchar)val;
+ the_geom.alloc_size-=3;
+ }
+ else{
+ if ( getMachineEndian() == NDR ){
+ val <<=1;
+ }
+ WRITE_INT4_REAL(out,val);
+ }
+}
+#else
+#define WRITE_INT4 WRITE_INT4_REAL
+#endif
+
+
+void
+WRITE_DOUBLES(output_state* out,double* points, int cnt)
+{
+ if ( the_geom.lwgi){
+ int4 vals[4];
+ int i;
+
+ for(i=0; i<cnt;i++){
+ vals[i] = (int4)(((points[i]+180.0)*0xB60B60)+.5);
+ }
+ memcpy(out->pos,vals,sizeof(int4)*cnt);
+ out->pos+=sizeof(int4)*cnt;
+ }
+ else{
+ memcpy(out->pos,points,sizeof(double)*cnt);
+ out->pos+=sizeof(double)*cnt;
+ }
+
+}
+
+void
+empty_stack(tuple *this,output_state* out)
+{
+ /* Do nothing but provide an empty base for the geometry stack */
+}
+
+void
+alloc_lwgeom(int srid)
+{
+ LWDEBUGF(2, "alloc_lwgeom %d", srid);
+
+ the_geom.srid=srid;
+ the_geom.alloc_size=0;
+ the_geom.stack=NULL;
+ the_geom.ndims=0;
+ the_geom.hasZ=0;
+ the_geom.hasM=0;
+
+ /* Free if used already */
+ if ( the_geom.first ){
+ free_tuple(the_geom.first);
+ the_geom.first=the_geom.last=NULL;
+ }
+
+ if ( srid != -1 ){
+ the_geom.alloc_size+=4;
+ }
+
+ /* Setup up an empty tuple as the stack base */
+ the_geom.stack = alloc_tuple(empty_stack, 0);
+}
+
+void
+write_point_2(tuple* this,output_state* out)
+{
+ WRITE_DOUBLES(out,this->uu.points,2);
+}
+
+void
+write_point_3(tuple* this,output_state* out)
+{
+ WRITE_DOUBLES(out,this->uu.points,3);
+}
+
+void
+write_point_4(tuple* this,output_state* out)
+{
+ WRITE_DOUBLES(out,this->uu.points,4);
+}
+
+void
+write_point_2i(tuple* this,output_state* out)
+{
+ WRITE_INT4_REAL_MULTIPLE(out,this->uu.points,2);
+}
+
+void
+write_point_3i(tuple* this,output_state* out)
+{
+ WRITE_INT4_REAL_MULTIPLE(out,this->uu.points,3);
+}
+
+void
+write_point_4i(tuple* this,output_state* out)
+{
+ WRITE_INT4_REAL_MULTIPLE(out,this->uu.points,4);
+}
+
+void
+alloc_point_2d(double x,double y)
+{
+ tuple* p = alloc_tuple(write_point_2,the_geom.lwgi?8:16);
+ p->uu.points[0] = x;
+ p->uu.points[1] = y;
+
+ LWDEBUGF(2, "alloc_point_2d %f,%f", x, y);
+
+ /* keep track of point */
+ if ( checkclosed ) {
+ if ( ! the_geom.stack->uu.nn.num )
+ first_point = p->uu.points;
+ last_point = p->uu.points;
+ }
+
+ inc_num();
+ check_dims(2);
+}
+
+void
+alloc_point_3d(double x,double y,double z)
+{
+ tuple* p = alloc_tuple(write_point_3,the_geom.lwgi?12:24);
+ p->uu.points[0] = x;
+ p->uu.points[1] = y;
+ p->uu.points[2] = z;
+
+ LWDEBUGF(2, "alloc_point_3d %f, %f, %f", x, y, z);
+
+ /* keep track of point */
+ if ( checkclosed ) {
+ if ( ! the_geom.stack->uu.nn.num )
+ first_point = p->uu.points;
+ last_point = p->uu.points;
+ }
+
+ inc_num();
+ check_dims(3);
+}
+
+void
+alloc_point_4d(double x,double y,double z,double m)
+{
+ tuple* p = alloc_tuple(write_point_4,the_geom.lwgi?16:32);
+ p->uu.points[0] = x;
+ p->uu.points[1] = y;
+ p->uu.points[2] = z;
+ p->uu.points[3] = m;
+
+ LWDEBUGF(2, "alloc_point_4d %f, %f, %f, %f", x, y, z, m);
+
+ /* keep track of point */
+ if ( checkclosed ) {
+ if ( ! the_geom.stack->uu.nn.num )
+ first_point = p->uu.points;
+ last_point = p->uu.points;
+ }
+
+ inc_num();
+ check_dims(4);
+}
+
+void
+write_type(tuple* this,output_state* out)
+{
+ uchar type=0;
+
+ /* Empty handler - switch back */
+ if ( this->uu.nn.type == 0xff )
+ this->uu.nn.type = COLLECTIONTYPE;
+
+ type |= this->uu.nn.type;
+
+ if (the_geom.ndims) /* Support empty */
+ {
+ TYPE_SETZM(type, the_geom.hasZ, the_geom.hasM);
+ }
+
+ if ( the_geom.srid != -1 ){
+ type |= 0x40;
+ }
+
+ *(out->pos)=type;
+ out->pos++;
+
+ if ( the_geom.srid != -1 ){
+ /* Only the first geometry will have a srid attached */
+ WRITE_INT4(out,the_geom.srid);
+ the_geom.srid = -1;
+ }
+}
+
+void
+write_count(tuple* this,output_state* out)
+{
+ int num = this->uu.nn.num;
+ WRITE_INT4(out,num);
+}
+
+void
+write_type_count(tuple* this,output_state* out)
+{
+ write_type(this,out);
+ write_count(this,out);
+}
+
+void
+alloc_point(void)
+{
+ LWDEBUG(2, "alloc_point");
+
+ if( the_geom.lwgi)
+ alloc_stack_tuple(POINTTYPEI,write_type,1);
+ else
+ alloc_stack_tuple(POINTTYPE,write_type,1);
+
+ minpoints=1;
+ checkclosed=0;
+ isodd=-1;
+}
+
+void
+alloc_linestring(void)
+{
+ LWDEBUG(2, "alloc_linestring");
+
+ if( the_geom.lwgi)
+ alloc_stack_tuple(LINETYPEI,write_type,1);
+ else
+ alloc_stack_tuple(LINETYPE,write_type,1);
+
+ minpoints=2;
+ checkclosed=0;
+ isodd=-1;
+}
+
+void alloc_linestring_closed(void)
+{
+ LWDEBUG(2, "alloc_linestring_closed called.");
+
+ alloc_linestring();
+ checkclosed=1;
+}
+
+void
+alloc_circularstring(void)
+{
+ LWDEBUG(2, "alloc_circularstring");
+
+ alloc_stack_tuple(CURVETYPE,write_type,1);
+ minpoints=3;
+ checkclosed=0;
+ isodd=1;
+}
+
+void alloc_circularstring_closed(void)
+{
+ LWDEBUG(2, "alloc_circularstring_closed");
+
+ alloc_circularstring();
+ checkclosed=1;
+}
+
+void
+alloc_polygon(void)
+{
+ LWDEBUG(2, "alloc_polygon");
+
+ if( the_geom.lwgi)
+ alloc_stack_tuple(POLYGONTYPEI, write_type,1);
+ else
+ alloc_stack_tuple(POLYGONTYPE, write_type,1);
+
+ minpoints=3;
+ checkclosed=1;
+ isodd=-1;
+
+}
+
+void
+alloc_curvepolygon(void)
+{
+ LWDEBUG(2, "alloc_curvepolygon called.");
+
+ alloc_stack_tuple(CURVEPOLYTYPE, write_type, 1);
+ minpoints=3;
+ checkclosed=1;
+ isodd=-1;
+}
+
+void
+alloc_compoundcurve(void)
+{
+ LWDEBUG(2, "alloc_compoundcurve called.");
+
+ alloc_stack_tuple(COMPOUNDTYPE, write_type, 1);
+}
+
+void
+alloc_multipoint(void)
+{
+ LWDEBUG(2, "alloc_multipoint");
+
+ alloc_stack_tuple(MULTIPOINTTYPE,write_type,1);
+}
+
+void
+alloc_multilinestring(void)
+{
+ LWDEBUG(2, "alloc_multilinestring");
+
+ alloc_stack_tuple(MULTILINETYPE,write_type,1);
+}
+
+void
+alloc_multicurve(void)
+{
+ LWDEBUG(2, "alloc_multicurve");
+
+ alloc_stack_tuple(MULTICURVETYPE,write_type,1);
+}
+
+void
+alloc_multipolygon(void)
+{
+ LWDEBUG(2, "alloc_multipolygon");
+
+ alloc_stack_tuple(MULTIPOLYGONTYPE,write_type,1);
+}
+
+void
+alloc_multisurface(void)
+{
+ LWDEBUG(2, "alloc_multisurface called");
+
+ alloc_stack_tuple(MULTISURFACETYPE,write_type,1);
+}
+
+void
+alloc_geomertycollection(void)
+{
+ LWDEBUG(2, "alloc_geometrycollection");
+
+ alloc_stack_tuple(COLLECTIONTYPE,write_type,1);
+}
+
+void
+alloc_counter(void)
+{
+ LWDEBUG(2, "alloc_counter");
+
+ alloc_stack_tuple(0,write_count,4);
+}
+
+void
+alloc_empty(void)
+{
+ tuple* st = the_geom.stack;
+
+ LWDEBUG(2, "alloc_empty");
+
+ /* Find the last geometry */
+ while(st->uu.nn.type == 0){
+ st =st->uu.nn.stack_next;
+ }
+
+ /* Reclaim memory */
+ free_tuple(st->next);
+
+ /* Put an empty geometry collection on the top of the stack */
+ st->next=NULL;
+ the_geom.stack=st;
+ the_geom.alloc_size=st->uu.nn.size_here;
+
+ /* Mark as a empty stop */
+ if (st->uu.nn.type != 0xFF){
+ st->uu.nn.type=0xFF;
+ st->of = write_type_count;
+ the_geom.alloc_size+=4;
+ st->uu.nn.size_here=the_geom.alloc_size;
+ }
+
+ st->uu.nn.num=0;
+}
+
+SERIALIZED_LWGEOM *
+make_serialized_lwgeom(void)
+{
+ SERIALIZED_LWGEOM *out_serialized_lwgeom;
+ uchar* out_c;
+ output_state out;
+ tuple* cur;
+
+ LWDEBUG(2, "make_serialized_lwgeom");
+
+ /* Allocate the SERIALIZED_LWGEOM structure */
+ out_serialized_lwgeom = (SERIALIZED_LWGEOM *)local_malloc(sizeof(SERIALIZED_LWGEOM));
+
+ /* Allocate the LWGEOM itself */
+ out_c = (uchar*)local_malloc(the_geom.alloc_size);
+ out.pos = out_c;
+ cur = the_geom.first ;
+
+ while(cur){
+ cur->of(cur,&out);
+ cur=cur->next;
+ }
+
+ /* Setup the SERIALIZED_LWGEOM structure */
+ out_serialized_lwgeom->lwgeom = out_c;
+ out_serialized_lwgeom->size = the_geom.alloc_size;
+
+ return out_serialized_lwgeom;
+}
+
+void
+lwg_parse_yynotice(char* s)
+{
+ lwnotice(s);
+}
+
+int
+lwg_parse_yyerror(char* s)
+{
+ error("parse error - invalid geometry");
+ /* error_func("parse error - invalid geometry"); */
+ return 1;
+}
+
+/*
+ Table below generated using this ruby.
+
+ a=(0..0xff).to_a.collect{|x|0xff};('0'..'9').each{|x|a[x[0]]=x[0]-'0'[0]}
+ ('a'..'f').each{|x|v=x[0]-'a'[0]+10;a[x[0]]=a[x.upcase[0]]=v}
+ puts '{'+a.join(",")+'}'
+
+ */
+static const uchar to_hex[] = {
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 0,1,2,3,4,5,6,7,8,9,255,255,255,255,255,255,255,10,11,12,13,14,
+ 15,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,10,11,12,13,14,15,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255};
+
+uchar
+strhex_readbyte(const char* in)
+{
+ if ( *in == 0 ){
+ if ( ! ferror_occured){
+ error("invalid wkb");
+ }
+ return 0;
+ }
+ return to_hex[(int)*in]<<4 | to_hex[(int)*(in+1)];
+}
+
+uchar
+read_wkb_byte(const char** in)
+{
+ uchar ret = strhex_readbyte(*in);
+ (*in)+=2;
+ return ret;
+}
+
+int swap_order;
+
+void
+read_wkb_bytes(const char** in, uchar* out, int cnt)
+{
+ if ( ! swap_order ){
+ while(cnt--) *out++ = read_wkb_byte(in);
+ }
+ else{
+ out += (cnt-1);
+ while(cnt--) *out-- = read_wkb_byte(in);
+ }
+}
+
+int4
+read_wkb_int(const char** in)
+{
+ int4 ret=0;
+ read_wkb_bytes(in,(uchar*)&ret,4);
+ return ret;
+}
+
+double
+read_wkb_double(const char** in, int convert_from_int)
+{
+ double ret=0;
+
+ if ( ! convert_from_int){
+ read_wkb_bytes(in,(uchar*)&ret,8);
+ return ret;
+ }else{
+ ret = read_wkb_int(in);
+ ret /= 0xb60b60;
+ return ret-180.0;
+ }
+}
+
+void
+read_wkb_point(const char **b)
+{
+ int i;
+ tuple* p = NULL;
+
+
+ if(the_geom.lwgi && the_geom.from_lwgi ){
+ /*
+ * Special case - reading from lwgi to lwgi
+ * we don't want to go via doubles in the middle.
+ */
+ switch(the_geom.ndims){
+ case 2: p=alloc_tuple(write_point_2i,8); break;
+ case 3: p=alloc_tuple(write_point_3i,12); break;
+ case 4: p=alloc_tuple(write_point_4i,16); break;
+ }
+
+ for(i=0;i<the_geom.ndims;i++){
+ p->uu.pointsi[i]=read_wkb_int(b);
+ }
+ }
+ else{
+ int mul = the_geom.lwgi ? 1 : 2;
+
+ switch(the_geom.ndims){
+ case 2: p=alloc_tuple(write_point_2,8*mul); break;
+ case 3: p=alloc_tuple(write_point_3,12*mul); break;
+ case 4: p=alloc_tuple(write_point_4,16*mul); break;
+ }
+
+ for(i=0;i<the_geom.ndims;i++){
+ p->uu.points[i]=read_wkb_double(b,the_geom.from_lwgi);
+ }
+ }
+
+
+ /* keep track of point */
+ if ( checkclosed ) {
+ if ( ! the_geom.stack->uu.nn.num )
+ first_point = p->uu.points;
+ last_point = p->uu.points;
+ }
+
+ inc_num();
+ check_dims(the_geom.ndims);
+}
+
+void
+read_wkb_polygon(const char **b)
+{
+ /* Stack the number of ORDINATE_ARRAYs (rings) */
+ int4 cnt=read_wkb_int(b);
+ alloc_counter();
+
+ /* Read through each ORDINATE_ARRAY in turn */
+ while(cnt--){
+ if ( ferror_occured ) return;
+
+ /* Things to check for POLYGON ORDINATE_ARRAYs */
+ minpoints=3;
+ checkclosed=1;
+ isodd=-1;
+
+ read_wkb_ordinate_array(b);
+ }
+
+ pop();
+}
+
+void
+read_wkb_linestring(const char **b)
+{
+
+ /* Things to check for LINESTRING ORDINATE_ARRAYs */
+ minpoints=2;
+ checkclosed=0;
+ isodd=-1;
+
+ read_wkb_ordinate_array(b);
+}
+
+
+void
+read_wkb_curve(const char **b)
+{
+
+ /* Things to check for CURVE ORDINATE_ARRAYs */
+ minpoints=3;
+ checkclosed=0;
+ isodd=-1;
+
+ read_wkb_ordinate_array(b);
+}
+
+void
+read_wkb_ordinate_array(const char **b)
+{
+ /* Read through a WKB ordinate array */
+ int4 cnt=read_wkb_int(b);
+ alloc_counter();
+
+ while(cnt--){
+ if ( ferror_occured ) return;
+ read_wkb_point(b);
+ }
+
+ /* Perform a check of the ordinate array */
+ popc();
+}
+
+void
+read_collection(const char **b, read_col_func f)
+{
+ /* Read through a COLLECTION or an EWKB */
+ int4 cnt=read_wkb_int(b);
+ alloc_counter();
+
+ while(cnt--){
+ if ( ferror_occured ) return;
+ f(b);
+ }
+
+ pop();
+}
+
+void
+parse_wkb(const char **b)
+{
+ int4 type;
+ uchar xdr = read_wkb_byte(b);
+ int4 localsrid;
+
+ LWDEBUG(2, "parse_wkb");
+
+ swap_order=0;
+
+ if ( xdr != getMachineEndian() )
+ {
+ swap_order=1;
+ }
+
+ type = read_wkb_int(b);
+
+ /* quick exit on error */
+ if ( ferror_occured ) return;
+
+ the_geom.ndims=2;
+ if (type & WKBZOFFSET)
+ {
+ the_geom.hasZ = 1;
+ the_geom.ndims++;
+ }
+ else the_geom.hasZ = 0;
+ if (type & WKBMOFFSET)
+ {
+ the_geom.hasM = 1;
+ the_geom.ndims++;
+ }
+ else the_geom.hasM = 0;
+
+ if (type & WKBSRIDFLAG )
+ {
+ /* local (in-EWKB) srid spec overrides SRID=#; */
+ localsrid = read_wkb_int(b);
+ if ( localsrid != -1 )
+ {
+ if ( the_geom.srid == -1 ) the_geom.alloc_size += 4;
+ the_geom.srid = localsrid;
+ }
+ }
+
+ type &=0x0f;
+
+ if ( the_geom.lwgi ){
+
+ if ( type<= POLYGONTYPE )
+ alloc_stack_tuple(type +9,write_type,1);
+ else
+ alloc_stack_tuple(type,write_type,1);
+ }
+ else{
+ /* If we are writing lwg and are reading wbki */
+ int4 towrite=type;
+ if (towrite >= POINTTYPEI && towrite <= POLYGONTYPEI){
+ towrite-=9;
+ }
+ alloc_stack_tuple(towrite,write_type,1);
+ }
+
+ switch(type ){
+ case POINTTYPE:
+ read_wkb_point(b);
+ break;
+
+ case LINETYPE:
+ read_wkb_linestring(b);
+ break;
+
+ case CURVETYPE:
+ read_wkb_curve(b);
+ break;
+
+ case POLYGONTYPE:
+ read_wkb_polygon(b);
+ break;
+
+ case COMPOUNDTYPE:
+ read_collection(b,parse_wkb);
+ break;
+
+ case CURVEPOLYTYPE:
+ read_collection(b,parse_wkb);
+ break;
+
+ case MULTIPOINTTYPE:
+ case MULTILINETYPE:
+ case MULTICURVETYPE:
+ case MULTIPOLYGONTYPE:
+ case MULTISURFACETYPE:
+ case COLLECTIONTYPE:
+ read_collection(b,parse_wkb);
+ break;
+
+ case POINTTYPEI:
+ the_geom.from_lwgi=1;
+ read_wkb_point(b);
+ break;
+
+ case LINETYPEI:
+ the_geom.from_lwgi=1;
+ read_wkb_linestring(b);
+ break;
+
+ case POLYGONTYPEI:
+ the_geom.from_lwgi=1;
+ read_wkb_polygon(b);
+ break;
+
+ default:
+ error("Invalid type in wbk");
+ }
+
+ the_geom.from_lwgi=0;
+
+ pop();
+}
+
+
+void
+alloc_wkb(const char *parser)
+{
+ LWDEBUG(2, "alloc_wkb");
+
+ parse_wkb(&parser);
+}
+
+/*
+ Parse a string and return a LW_GEOM
+*/
+SERIALIZED_LWGEOM *
+parse_it(const char *geometry, allocator allocfunc, report_error errfunc)
+{
+ LWDEBUGF(2, "parse_it: %s", geometry);
+
+ local_malloc = allocfunc;
+ error_func=errfunc;
+
+ ferror_occured = 0;
+
+ init_parser(geometry);
+
+ lwg_parse_yyparse();
+
+ close_parser();
+
+ if (ferror_occured)
+ return NULL;
+
+ return make_serialized_lwgeom();
+}
+
+SERIALIZED_LWGEOM *
+parse_lwg(const char* geometry,allocator allocfunc,report_error errfunc)
+{
+ the_geom.lwgi=0;
+ return parse_it(geometry,allocfunc,errfunc);
+}
+
+SERIALIZED_LWGEOM *
+parse_lwgi(const char* geometry,allocator allocfunc,report_error errfunc)
+{
+ the_geom.lwgi=1;
+ return parse_it(geometry,allocfunc,errfunc);
+}
+
+void
+set_zm(char z, char m)
+{
+ LWDEBUGF(2, "set_zm %d, %d", z, m);
+
+ the_geom.hasZ = z;
+ the_geom.hasM = m;
+ the_geom.ndims = 2+z+m;
+}
+
Added: trunk/liblwgeom/lwgunparse.c
===================================================================
--- trunk/liblwgeom/lwgunparse.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwgunparse.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,765 @@
+/*
+ * Written by Ralph Mason ralph.mason<at>telogis.com
+ *
+ * Copyright Telogis 2004
+ * www.telogis.com
+ *
+ * $Id: wktunparse.c 2781 2008-05-22 20:43:00Z mcayland $
+ */
+
+
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+/* TO get byte order */
+#include <sys/types.h>
+#include <sys/param.h>
+/* Solaris9 does not provide stdint.h */
+/* #include <stdint.h> */
+#include <inttypes.h>
+
+#include "liblwgeom.h"
+#include "wktparse.h"
+
+
+/*-- Typedefs ---------------------------------------------- */
+
+typedef uint32_t int4;
+typedef uchar* (*outfunc)(uchar*,int);
+typedef uchar* (*outwkbfunc)(uchar*);
+
+/*-- Prototypes -------------------------------------------- */
+
+void ensure(int chars);
+void to_end(void);
+void write_str(const char* str);
+void write_double(double val);
+void write_int(int i);
+int4 read_int(uchar** geom);
+double read_double(uchar** geom);
+uchar* output_point(uchar* geom,int supress);
+uchar* output_single(uchar* geom,int supress);
+uchar* output_collection(uchar* geom,outfunc func,int supress);
+uchar* output_collection_2(uchar* geom,int suppress);
+uchar* output_multipoint(uchar* geom,int suppress);
+uchar* output_compound(uchar* geom, int suppress);
+uchar* output_multisurface(uchar* geom, int suppress);
+
+void write_wkb_hex_bytes(uchar* ptr, unsigned int cnt, size_t size);
+void write_wkb_bin_bytes(uchar* ptr, unsigned int cnt, size_t size);
+void write_wkb_bin_flip_bytes(uchar* ptr, unsigned int cnt, size_t size);
+void write_wkb_hex_flip_bytes(uchar* ptr, unsigned int cnt, size_t size);
+
+void write_wkb_int(int i);
+uchar* output_wkb_collection(uchar* geom,outwkbfunc func);
+uchar* output_wkb_collection_2(uchar* geom);
+uchar* output_wkb_point(uchar* geom);
+uchar* output_wkb(uchar* geom);
+
+/*-- Globals ----------------------------------------------- */
+
+static int dims;
+static allocator local_malloc;
+static freeor local_free;
+static char* out_start;
+static char* out_pos;
+static int len;
+static int lwgi;
+static uchar endianbyte;
+void (*write_wkb_bytes)(uchar* ptr,unsigned int cnt,size_t size);
+
+/*---------------------------------------------------------- */
+
+
+
+/*
+ * Ensure there is enough space for chars bytes.
+ * Reallocate memory is this is not the case.
+ */
+void
+ensure(int chars){
+
+ int pos = out_pos - out_start;
+
+ if ( (pos + chars) >= len ){
+ char* newp =(char*)local_malloc(len*2);
+ memcpy(newp,out_start,len);
+ local_free(out_start);
+ out_start = newp;
+ out_pos = newp + pos;
+ len *=2;
+ }
+}
+
+void
+to_end(void)
+{
+ while(*out_pos){
+ out_pos++;
+ }
+}
+
+void
+write_str(const char* str)
+{
+ ensure(32);
+ strcpy(out_pos,str);
+ to_end();
+}
+
+void
+write_double(double val){
+ ensure(32);
+ if (lwgi)
+ sprintf(out_pos,"%.8g",val);
+ else
+ sprintf(out_pos,"%.15g",val);
+ to_end();
+}
+
+void
+write_int(int i){
+ ensure(32);
+ sprintf(out_pos,"%i",i);
+ to_end();
+}
+
+int4
+read_int(uchar** geom)
+{
+ int4 ret;
+#ifdef SHRINK_INTS
+ if ( getMachineEndian() == NDR ){
+ if( (**geom)& 0x01){
+ ret = **geom >>1;
+ (*geom)++;
+ return ret;
+ }
+ }
+ else{
+ if( (**geom)& 0x80){
+ ret = **geom & ~0x80;
+ (*geom)++;
+ return ret;
+ }
+ }
+#endif
+ memcpy(&ret,*geom,4);
+
+#ifdef SHRINK_INTS
+ if ( getMachineEndian() == NDR ){
+ ret >>= 1;
+ }
+#endif
+
+ (*geom)+=4;
+ return ret;
+}
+
+double round(double);
+
+double read_double(uchar** geom){
+ if (lwgi){
+ double ret = *((int4*)*geom);
+ ret /= 0xb60b60;
+ (*geom)+=4;
+ return ret-180.0;
+ }
+ else{
+ double ret;
+ memcpy(&ret, *geom, 8);
+ (*geom)+=8;
+ return ret;
+ }
+}
+
+uchar *
+output_point(uchar* geom,int supress)
+{
+ int i;
+
+ for( i = 0 ; i < dims ; i++ ){
+ write_double(read_double(&geom));
+ if (i +1 < dims )
+ write_str(" ");
+ }
+ return geom;
+}
+
+uchar *
+output_single(uchar* geom,int supress)
+{
+ write_str("(");
+ geom=output_point(geom,supress);
+ write_str(")");
+ return geom;
+}
+
+uchar *
+output_collection(uchar* geom,outfunc func,int supress)
+{
+ int cnt = read_int(&geom);
+ if ( cnt == 0 ){
+ write_str(" EMPTY");
+ }
+ else{
+ write_str("(");
+ while(cnt--){
+ geom=func(geom,supress);
+ if ( cnt ){
+ write_str(",");
+ }
+ }
+ write_str(")");
+ }
+ return geom;
+}
+
+uchar *
+output_collection_2(uchar* geom,int suppress)
+{
+ return output_collection(geom,output_point,suppress);
+}
+
+uchar *output_wkt(uchar* geom, int supress);
+
+/* special case for multipoint to supress extra brackets */
+uchar *output_multipoint(uchar* geom,int suppress){
+ unsigned type = *geom & 0x0f;
+
+ if ( type == POINTTYPE )
+ return output_point(++geom,suppress);
+ else if ( type == POINTTYPEI ){
+ lwgi++;
+ geom=output_point(++geom,0);
+ lwgi--;
+ return geom;
+ }
+
+ return output_wkt(geom,suppress);
+}
+
+/* special case for compound to suppress linestring but not circularstring */
+uchar *output_compound(uchar* geom, int suppress) {
+ unsigned type;
+
+#ifdef PGIS_DEBUG_CALLS
+ lwnotice("output_compound called.");
+#endif
+
+ type=*geom++;
+ switch(TYPE_GETTYPE(type))
+ {
+ case LINETYPE:
+ geom = output_collection(geom,output_point,0);
+ break;
+ case CURVETYPE:
+ write_str("CIRCULARSTRING");
+ geom = output_collection(geom,output_point,1);
+ break;
+ }
+ return geom;
+}
+
+uchar *output_multisurface(uchar* geom, int suppress) {
+ unsigned type;
+
+#ifdef PGIS_DEBUG_CALLS
+ lwnotice("output_multisurface called.");
+#endif
+
+ type=*geom++;
+ switch(TYPE_GETTYPE(type))
+ {
+ case POLYGONTYPE:
+ geom = output_collection(geom, output_collection_2,0);
+ break;
+ case CURVEPOLYTYPE:
+ write_str("CURVEPOLYGON");
+ geom = output_collection(geom, output_compound,1);
+ break;
+ }
+ return geom;
+}
+
+/*
+ * Suppress=0 -- write TYPE, M, coords
+ * Suppress=1 -- write TYPE, coords
+ * Suppress=2 -- write only coords
+ */
+uchar *
+output_wkt(uchar* geom, int supress)
+{
+
+ unsigned type=*geom++;
+ char writeM=0;
+ dims = TYPE_NDIMS(type); /* ((type & 0x30) >> 4)+2; */
+
+#ifdef PGIS_DEBUG_CALLS
+ lwnotice("output_wkt called.");
+#endif
+
+ if ( ! supress && !TYPE_HASZ(type) && TYPE_HASM(type) ) writeM=1;
+
+
+ /* Skip the bounding box if there is one */
+ if ( TYPE_HASBBOX(type) )
+ {
+ geom+=16;
+ }
+
+ if ( TYPE_HASSRID(type) ) {
+ write_str("SRID=");write_int(read_int(&geom));write_str(";");
+ }
+
+ switch(TYPE_GETTYPE(type)) {
+ case POINTTYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("POINTM");
+ else write_str("POINT");
+ }
+ geom=output_single(geom,0);
+ break;
+ case LINETYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("LINESTRINGM");
+ else write_str("LINESTRING");
+ }
+ geom = output_collection(geom,output_point,0);
+ break;
+ case CURVETYPE:
+ if ( supress < 2 )
+ {
+ if(writeM) write_str("CIRCULARSTRINGM");
+ else write_str("CIRCULARSTRING");
+ }
+ geom = output_collection(geom,output_point,0);
+ break;
+ case POLYGONTYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("POLYGONM");
+ else write_str("POLYGON");
+ }
+ geom = output_collection(geom,output_collection_2,0);
+ break;
+ case COMPOUNDTYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("COMPOUNDCURVEM");
+ else write_str("COMPOUNDCURVE");
+ }
+ geom = output_collection(geom, output_compound,1);
+ break;
+ case CURVEPOLYTYPE:
+ if (supress < 2)
+ {
+ if(writeM) write_str("CURVEPOLYGONM");
+ else write_str("CURVEPOLYGON");
+ }
+ geom = output_collection(geom, output_compound,0);
+ break;
+ case MULTIPOINTTYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("MULTIPOINTM");
+ else write_str("MULTIPOINT");
+ }
+ geom = output_collection(geom,output_multipoint,2);
+ break;
+ case MULTILINETYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("MULTILINESTRINGM");
+ else write_str("MULTILINESTRING");
+ }
+ geom = output_collection(geom,output_wkt,2);
+ break;
+ case MULTICURVETYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("MULTICURVEM");
+ else write_str("MULTICURVE");
+ }
+ geom = output_collection(geom,output_compound,2);
+ break;
+ case MULTIPOLYGONTYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("MULTIPOLYGONM");
+ else write_str("MULTIPOLYGON");
+ }
+ geom = output_collection(geom,output_wkt,2);
+ break;
+ case MULTISURFACETYPE:
+ if ( supress < 2)
+ {
+ if (writeM) write_str("MULTISURFACEM");
+ else write_str("MULTISURFACE");
+ }
+ geom = output_collection(geom,output_multisurface,2);
+ break;
+ case COLLECTIONTYPE:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("GEOMETRYCOLLECTIONM");
+ else write_str("GEOMETRYCOLLECTION");
+ }
+ geom = output_collection(geom,output_wkt,1);
+ break;
+
+ case POINTTYPEI:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("POINTM");
+ else write_str("POINT");
+ }
+ lwgi++;
+ geom=output_single(geom,0);
+ lwgi--;
+ break;
+ case LINETYPEI:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("LINESTRINGM");
+ else write_str("LINESTRING");
+ }
+ lwgi++;
+ geom = output_collection(geom,output_point,0);
+ lwgi--;
+ break;
+ case POLYGONTYPEI:
+ if ( supress < 2 )
+ {
+ if (writeM) write_str("POLYGONM");
+ else write_str("POLYGON");
+ }
+ lwgi++;
+ geom =output_collection(geom,output_collection_2,0);
+ lwgi--;
+ break;
+ }
+ return geom;
+}
+
+char *
+unparse_WKT(uchar* serialized, allocator alloc, freeor free)
+{
+
+#ifdef PGIS_DEBUG_CALLS
+ lwnotice("unparse_WKT called.");
+#endif
+
+ if (serialized==NULL)
+ return NULL;
+
+ local_malloc=alloc;
+ local_free=free;
+ len = 128;
+ out_start = out_pos = alloc(len);
+ lwgi=0;
+
+ output_wkt(serialized, 0);
+
+ return out_start;
+}
+
+static char outchr[]={"0123456789ABCDEF" };
+
+/* Write HEX bytes flipping */
+void
+write_wkb_hex_flip_bytes(uchar* ptr, unsigned int cnt, size_t size)
+{
+ unsigned int bc; /* byte count */
+
+ ensure(cnt*2*size);
+
+ while(cnt--){
+ for(bc=size; bc; bc--)
+ {
+ *out_pos++ = outchr[ptr[bc-1]>>4];
+ *out_pos++ = outchr[ptr[bc-1]&0x0F];
+ }
+ ptr+=size;
+ }
+}
+
+/* Write HEX bytes w/out flipping */
+void
+write_wkb_hex_bytes(uchar* ptr, unsigned int cnt, size_t size)
+{
+ unsigned int bc; /* byte count */
+
+ ensure(cnt*2*size);
+
+ while(cnt--){
+ for(bc=0; bc<size; bc++)
+ {
+ *out_pos++ = outchr[ptr[bc]>>4];
+ *out_pos++ = outchr[ptr[bc]&0x0F];
+ }
+ ptr+=size;
+ }
+}
+
+/* Write BIN bytes flipping */
+void
+write_wkb_bin_flip_bytes(uchar* ptr, unsigned int cnt, size_t size)
+{
+ unsigned int bc; /* byte count */
+
+ ensure(cnt*size);
+
+ while(cnt--)
+ {
+ for(bc=size; bc; bc--)
+ *out_pos++ = ptr[bc-1];
+ ptr+=size;
+ }
+}
+
+
+/* Write BIN bytes w/out flipping */
+void
+write_wkb_bin_bytes(uchar* ptr, unsigned int cnt, size_t size)
+{
+ unsigned int bc; /* byte count */
+
+ ensure(cnt*size);
+
+ /* Could just use a memcpy here ... */
+ while(cnt--)
+ {
+ for(bc=0; bc<size; bc++)
+ *out_pos++ = ptr[bc];
+ ptr+=size;
+ }
+}
+
+uchar *
+output_wkb_point(uchar* geom)
+{
+ if ( lwgi ){
+ write_wkb_bytes(geom,dims,4);
+ return geom + (4*dims);
+ }
+ else{
+ write_wkb_bytes(geom,dims,8);
+ return geom + (8*dims);
+ }
+}
+
+void
+write_wkb_int(int i){
+ write_wkb_bytes((uchar*)&i,1,4);
+}
+
+uchar *
+output_wkb_collection(uchar* geom,outwkbfunc func)
+{
+ int cnt = read_int(&geom);
+#ifdef PGIS_DEBUG
+ lwnotice("output_wkb_collection: %d iterations loop", cnt);
+#endif
+ write_wkb_int(cnt);
+ while(cnt--) geom=func(geom);
+ return geom;
+}
+
+uchar *
+output_wkb_collection_2(uchar* geom){
+ return output_wkb_collection(geom,output_wkb_point);
+}
+
+uchar *
+output_wkb(uchar* geom)
+{
+ unsigned char type=*geom++;
+ int4 wkbtype;
+
+ dims = TYPE_NDIMS(type);
+#ifdef PGIS_DEBUG
+ lwnotice("output_wkb: dims set to %d", dims);
+#endif
+
+ /* Skip the bounding box */
+ if ( TYPE_HASBBOX(type) ) {
+ geom+=16;
+ }
+
+ wkbtype = TYPE_GETTYPE(type);
+
+ if ( TYPE_HASZ(type) )
+ wkbtype |= WKBZOFFSET;
+ if ( TYPE_HASM(type) )
+ wkbtype |= WKBMOFFSET;
+ if ( TYPE_HASSRID(type) ) {
+ wkbtype |= WKBSRIDFLAG;
+ }
+
+
+ /* Write byteorder (as from WKB specs...) */
+ write_wkb_bytes(&endianbyte,1,1);
+
+ write_wkb_int(wkbtype);
+
+ if ( TYPE_HASSRID(type) ) {
+ write_wkb_int(read_int(&geom));
+ }
+
+ switch(TYPE_GETTYPE(type)){
+ case POINTTYPE:
+ geom=output_wkb_point(geom);
+ break;
+ case LINETYPE:
+ geom=output_wkb_collection(geom,output_wkb_point);
+ break;
+ case CURVETYPE:
+ geom=output_wkb_collection(geom,output_wkb_point);
+ break;
+ case POLYGONTYPE:
+ geom=output_wkb_collection(geom,output_wkb_collection_2);
+ break;
+ case COMPOUNDTYPE:
+ geom=output_wkb_collection(geom,output_wkb);
+ break;
+ case CURVEPOLYTYPE:
+ geom=output_wkb_collection(geom,output_wkb);
+ break;
+ case MULTICURVETYPE:
+ case MULTISURFACETYPE:
+ case MULTIPOINTTYPE:
+ case MULTILINETYPE:
+ case MULTIPOLYGONTYPE:
+ case COLLECTIONTYPE:
+ geom = output_wkb_collection(geom,output_wkb);
+ break;
+
+ /*
+ These don't output standard wkb at the moment
+ the output and integer version.
+
+ however you could run it through the wkt parser
+ for a lwg and then output that. There should
+ also be a force_to_real_(lwgi)
+ */
+ case POINTTYPEI:
+ lwgi++;
+ geom=output_wkb_point(geom);
+ lwgi--;
+ break;
+ case LINETYPEI:
+ lwgi++;
+ geom = output_wkb_collection(geom,output_wkb_point);
+ lwgi--;
+ break;
+ case POLYGONTYPEI:
+ lwgi++;
+ geom = output_wkb_collection(geom,output_wkb_collection_2);
+ lwgi--;
+ break;
+ }
+ return geom;
+}
+
+char *
+unparse_WKB(uchar* serialized, allocator alloc, freeor free, char endian, size_t *outsize, uchar hex)
+{
+#ifdef PGIS_DEBUG
+ lwnotice("unparse_WKB(%p,...) called", serialized);
+#endif
+
+ if (serialized==NULL)
+ return NULL;
+
+ local_malloc=alloc;
+ local_free=free;
+ len = 128;
+ out_start = out_pos = alloc(len);
+ lwgi=0;
+
+ if ( endian == (char)-1 )
+ {
+ endianbyte = getMachineEndian();
+ if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
+ else write_wkb_bytes = write_wkb_bin_bytes;
+ }
+ else
+ {
+ endianbyte = endian;
+ if ( endianbyte != getMachineEndian() )
+ {
+ if ( hex ) write_wkb_bytes = write_wkb_hex_flip_bytes;
+ else write_wkb_bytes = write_wkb_bin_flip_bytes;
+ }
+ else
+ {
+ if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
+ else write_wkb_bytes = write_wkb_bin_bytes;
+ }
+ }
+
+ output_wkb(serialized);
+
+ if ( hex ) {
+ ensure(1);
+ *out_pos=0;
+ }
+
+ if ( outsize ) *outsize = (out_pos-out_start);
+
+ return out_start;
+}
+
+
+/******************************************************************
+ * $Log$
+ * Revision 1.23 2006/02/06 11:12:22 strk
+ * uint32_t typedef moved back from wktparse.h to lwgparse.c and wktunparse.c
+ *
+ * Revision 1.22 2006/02/03 20:53:37 strk
+ * Swapped stdint.h (unavailable on Solaris9) with inttypes.h
+ *
+ * Revision 1.21 2006/02/03 09:52:14 strk
+ * Changed int4 typedefs to use POSIX uint32_t
+ *
+ * Revision 1.20 2006/01/09 15:12:02 strk
+ * ISO C90 comments
+ *
+ * Revision 1.19 2005/03/10 18:19:16 strk
+ * Made void args explicit to make newer compilers happy
+ *
+ * Revision 1.18 2005/02/21 16:16:14 strk
+ * Changed byte to uchar to avoid clashes with win32 headers.
+ *
+ * Revision 1.17 2005/02/07 13:21:10 strk
+ * Replaced DEBUG* macros with PGIS_DEBUG*, to avoid clashes with postgresql DEBUG
+ *
+ * Revision 1.16 2005/01/18 09:32:03 strk
+ * Changed unparse_WKB interface to take an output size pointer and an HEXFORM
+ * specifier. Reworked code in wktunparse to use function pointers.
+ *
+ * Revision 1.15 2004/12/21 15:19:01 strk
+ * Canonical binary reverted back to EWKB, now supporting SRID inclusion.
+ *
+ * Revision 1.14 2004/12/17 11:08:53 strk
+ * Moved getMachineEndian from parser to liblwgeom.{h,c}.
+ * Added XDR and NDR defines.
+ * Fixed all usage of them.
+ *
+ * Revision 1.13 2004/10/25 12:27:33 strk
+ * Removed useless network type includes,
+ * Added param.h include for BYTE_ORDER defines under win32.
+ *
+ * Revision 1.12 2004/10/21 19:48:34 strk
+ * Stricter syntax fixes. Reported by Sébastien NICAISE <snicaise at iciatechnologies.com>
+ *
+ * Revision 1.11 2004/10/15 07:35:41 strk
+ * Fixed a bug introduced by me (byteorder skipped for inner geoms in WKB)
+ *
+ * Revision 1.10 2004/10/11 14:03:33 strk
+ * Added endiannes specification to unparse_WKB, AsBinary, lwgeom_to_wkb.
+ *
+ ******************************************************************/
Added: trunk/liblwgeom/lwline.c
===================================================================
--- trunk/liblwgeom/lwline.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwline.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,516 @@
+/**********************************************************************
+ * $Id: lwline.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+/* basic LWLINE functions */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+
+
+/*
+ * Construct a new LWLINE. points will *NOT* be copied
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
+ */
+LWLINE *
+lwline_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points)
+{
+ LWLINE *result;
+ result = (LWLINE*) lwalloc(sizeof(LWLINE));
+
+ LWDEBUG(2, "lwline_construct called.");
+
+ result->type = lwgeom_makeType_full(
+ TYPE_HASZ(points->dims),
+ TYPE_HASM(points->dims),
+ (SRID!=-1), LINETYPE,
+ 0);
+
+ LWDEBUGF(3, "lwline_construct type=%d", result->type);
+
+ result->SRID = SRID;
+ result->points = points;
+ result->bbox = bbox;
+
+ return result;
+}
+
+/*
+ * given the LWGEOM serialized form (or a pointer into a muli* one)
+ * construct a proper LWLINE.
+ * serialized_form should point to the 8bit type format (with type = 2)
+ * See serialized form doc
+ */
+LWLINE *
+lwline_deserialize(uchar *serialized_form)
+{
+ uchar type;
+ LWLINE *result;
+ uchar *loc =NULL;
+ uint32 npoints;
+ POINTARRAY *pa;
+
+ type = (uchar) serialized_form[0];
+
+ if ( lwgeom_getType(type) != LINETYPE)
+ {
+ lwerror("lwline_deserialize: attempt to deserialize a line which is really a %s", lwgeom_typename(type));
+ return NULL;
+ }
+
+ result = (LWLINE*) lwalloc(sizeof(LWLINE)) ;
+ result->type = type;
+
+ loc = serialized_form+1;
+
+ if (lwgeom_hasBBOX(type))
+ {
+ LWDEBUG(3, "lwline_deserialize: input has bbox");
+
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
+ loc += sizeof(BOX2DFLOAT4);
+ }
+ else
+ {
+ result->bbox = NULL;
+ /*lwnotice("line has NO bbox"); */
+ }
+
+ if ( lwgeom_hasSRID(type))
+ {
+ /*lwnotice("line has srid"); */
+ result->SRID = lw_get_int32(loc);
+ loc +=4; /* type + SRID */
+ }
+ else
+ {
+ /*lwnotice("line has NO srid"); */
+ result->SRID = -1;
+ }
+
+ /* we've read the type (1 byte) and SRID (4 bytes, if present) */
+
+ npoints = lw_get_uint32(loc);
+ /*lwnotice("line npoints = %d", npoints); */
+ loc +=4;
+ pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints);
+ result->points = pa;
+
+ return result;
+}
+
+/*
+ * convert this line into its serialize form
+ * result's first char will be the 8bit type. See serialized form doc
+ */
+uchar *
+lwline_serialize(LWLINE *line)
+{
+ size_t size, retsize;
+ uchar * result;
+
+ if (line == NULL) lwerror("lwline_serialize:: given null line");
+
+ size = lwline_serialize_size(line);
+ result = lwalloc(size);
+ lwline_serialize_buf(line, result, &retsize);
+
+ if ( retsize != size )
+ {
+ lwerror("lwline_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
+ }
+
+ return result;
+}
+
+/*
+ * convert this line into its serialize form writing it into
+ * the given buffer, and returning number of bytes written into
+ * the given int pointer.
+ * result's first char will be the 8bit type. See serialized form doc
+ */
+void
+lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *retsize)
+{
+ char hasSRID;
+ uchar *loc;
+ int ptsize;
+ size_t size;
+
+ LWDEBUGF(2, "lwline_serialize_buf(%p, %p, %p) called",
+ line, buf, retsize);
+
+ if (line == NULL)
+ lwerror("lwline_serialize:: given null line");
+
+ if ( TYPE_GETZM(line->type) != TYPE_GETZM(line->points->dims) )
+ lwerror("Dimensions mismatch in lwline");
+
+ ptsize = pointArray_ptsize(line->points);
+
+ hasSRID = (line->SRID != -1);
+
+ buf[0] = (uchar) lwgeom_makeType_full(
+ TYPE_HASZ(line->type), TYPE_HASM(line->type),
+ hasSRID, LINETYPE, line->bbox ? 1 : 0);
+ loc = buf+1;
+
+ LWDEBUGF(3, "lwline_serialize_buf added type (%d)", line->type);
+
+ if (line->bbox)
+ {
+ memcpy(loc, line->bbox, sizeof(BOX2DFLOAT4));
+ loc += sizeof(BOX2DFLOAT4);
+
+ LWDEBUG(3, "lwline_serialize_buf added BBOX");
+ }
+
+ if (hasSRID)
+ {
+ memcpy(loc, &line->SRID, sizeof(int32));
+ loc += sizeof(int32);
+
+ LWDEBUG(3, "lwline_serialize_buf added SRID");
+ }
+
+ memcpy(loc, &line->points->npoints, sizeof(uint32));
+ loc += sizeof(uint32);
+
+ LWDEBUGF(3, "lwline_serialize_buf added npoints (%d)",
+ line->points->npoints);
+
+ /*copy in points */
+ size = line->points->npoints*ptsize;
+ memcpy(loc, getPoint_internal(line->points, 0), size);
+ loc += size;
+
+ LWDEBUGF(3, "lwline_serialize_buf copied serialized_pointlist (%d bytes)",
+ ptsize * line->points->npoints);
+
+ if (retsize) *retsize = loc-buf;
+
+ /*printBYTES((uchar *)result, loc-buf); */
+
+ LWDEBUGF(3, "lwline_serialize_buf returning (loc: %p, size: %d)",
+ loc, loc-buf);
+}
+
+/*
+ * Find bounding box (standard one)
+ * zmin=zmax=NO_Z_VALUE if 2d
+ */
+BOX3D *
+lwline_compute_box3d(LWLINE *line)
+{
+ BOX3D *ret;
+
+ if (line == NULL) return NULL;
+
+ ret = ptarray_compute_box3d(line->points);
+ return ret;
+}
+
+/* find length of this deserialized line */
+size_t
+lwline_serialize_size(LWLINE *line)
+{
+ size_t size = 1; /* type */
+
+ LWDEBUG(2, "lwline_serialize_size called");
+
+ if ( line->SRID != -1 ) size += 4; /* SRID */
+ if ( line->bbox ) size += sizeof(BOX2DFLOAT4);
+
+ size += 4; /* npoints */
+ size += pointArray_ptsize(line->points)*line->points->npoints;
+
+ LWDEBUGF(3, "lwline_serialize_size returning %d", size);
+
+ return size;
+}
+
+void pfree_line (LWLINE *line)
+{
+ lwfree(line->points);
+ lwfree(line);
+}
+
+/* find length of this serialized line */
+size_t
+lwgeom_size_line(const uchar *serialized_line)
+{
+ int type = (uchar) serialized_line[0];
+ uint32 result = 1; /*type */
+ const uchar *loc;
+ uint32 npoints;
+
+ LWDEBUG(2, "lwgeom_size_line called");
+
+ if ( lwgeom_getType(type) != LINETYPE)
+ lwerror("lwgeom_size_line::attempt to find the length of a non-line");
+
+
+ loc = serialized_line+1;
+
+ if (lwgeom_hasBBOX(type))
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ result +=sizeof(BOX2DFLOAT4);
+ }
+
+ if ( lwgeom_hasSRID(type))
+ {
+ loc += 4; /* type + SRID */
+ result +=4;
+ }
+
+ /* we've read the type (1 byte) and SRID (4 bytes, if present) */
+ npoints = lw_get_uint32(loc);
+ result += sizeof(uint32); /* npoints */
+
+ result += TYPE_NDIMS(type) * sizeof(double) * npoints;
+
+ LWDEBUGF(3, "lwgeom_size_line returning %d", result);
+
+ return result;
+}
+
+void printLWLINE(LWLINE *line)
+{
+ lwnotice("LWLINE {");
+ lwnotice(" ndims = %i", (int)TYPE_NDIMS(line->type));
+ lwnotice(" SRID = %i", (int)line->SRID);
+ printPA(line->points);
+ lwnotice("}");
+}
+
+int
+lwline_compute_box2d_p(LWLINE *line, BOX2DFLOAT4 *box)
+{
+ return ptarray_compute_box2d_p(line->points, box);
+}
+
+/* Clone LWLINE object. POINTARRAY is not copied. */
+LWLINE *
+lwline_clone(const LWLINE *g)
+{
+ LWLINE *ret = lwalloc(sizeof(LWLINE));
+
+ LWDEBUGF(2, "lwline_clone called with %p", g);
+
+ memcpy(ret, g, sizeof(LWLINE));
+ if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
+ return ret;
+}
+
+/*
+ * Add 'what' to this line at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTILINE or a GEOMETRYCOLLECTION
+ */
+LWGEOM *
+lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+
+ if ( where != -1 && where != 0 )
+ {
+ lwerror("lwline_add only supports 0 or -1 as second argument, got %d", where);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*2);
+ if ( where == -1 ) /* append */
+ {
+ geoms[0] = lwgeom_clone((LWGEOM *)to);
+ geoms[1] = lwgeom_clone(what);
+ }
+ else /* prepend */
+ {
+ geoms[0] = lwgeom_clone(what);
+ geoms[1] = lwgeom_clone((LWGEOM *)to);
+ }
+
+ /* reset SRID and wantbbox flag from component types */
+ geoms[0]->SRID = geoms[1]->SRID = -1;
+ TYPE_SETHASSRID(geoms[0]->type, 0);
+ TYPE_SETHASSRID(geoms[1]->type, 0);
+ TYPE_SETHASBBOX(geoms[0]->type, 0);
+ TYPE_SETHASBBOX(geoms[1]->type, 0);
+
+ /* Find appropriate geom type */
+ if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ 2, geoms);
+
+ return (LWGEOM *)col;
+}
+
+void
+lwline_reverse(LWLINE *line)
+{
+ ptarray_reverse(line->points);
+}
+
+LWLINE *
+lwline_segmentize2d(LWLINE *line, double dist)
+{
+ return lwline_construct(line->SRID, NULL,
+ ptarray_segmentize2d(line->points, dist));
+}
+
+/* check coordinate equality */
+char
+lwline_same(const LWLINE *l1, const LWLINE *l2)
+{
+ return ptarray_same(l1->points, l2->points);
+}
+
+/*
+ * Construct a LWLINE from an array of LWPOINTs
+ * LWLINE dimensions are large enough to host all input dimensions.
+ */
+LWLINE *
+lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points)
+{
+ int zmflag=0;
+ unsigned int i;
+ POINTARRAY *pa;
+ uchar *newpoints, *ptr;
+ size_t ptsize, size;
+
+ /*
+ * Find output dimensions, check integrity
+ */
+ for (i=0; i<npoints; i++)
+ {
+ if ( TYPE_GETTYPE(points[i]->type) != POINTTYPE )
+ {
+ lwerror("lwline_from_lwpointarray: invalid input type: %s",
+ lwgeom_typename(TYPE_GETTYPE(points[i]->type)));
+ return NULL;
+ }
+ if ( TYPE_HASZ(points[i]->type) ) zmflag |= 2;
+ if ( TYPE_HASM(points[i]->type) ) zmflag |= 1;
+ if ( zmflag == 3 ) break;
+ }
+
+ if ( zmflag == 0 ) ptsize=2*sizeof(double);
+ else if ( zmflag == 3 ) ptsize=4*sizeof(double);
+ else ptsize=3*sizeof(double);
+
+ /*
+ * Allocate output points array
+ */
+ size = ptsize*npoints;
+ newpoints = lwalloc(size);
+ memset(newpoints, 0, size);
+
+ ptr=newpoints;
+ for (i=0; i<npoints; i++)
+ {
+ size=pointArray_ptsize(points[i]->point);
+ memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
+ ptr+=ptsize;
+ }
+
+ pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints);
+
+ return lwline_construct(SRID, NULL, pa);
+}
+
+/*
+ * Construct a LWLINE from a LWMPOINT
+ */
+LWLINE *
+lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint)
+{
+ unsigned int i;
+ POINTARRAY *pa;
+ char zmflag = TYPE_GETZM(mpoint->type);
+ size_t ptsize, size;
+ uchar *newpoints, *ptr;
+
+ if ( zmflag == 0 ) ptsize=2*sizeof(double);
+ else if ( zmflag == 3 ) ptsize=4*sizeof(double);
+ else ptsize=3*sizeof(double);
+
+ /* Allocate space for output points */
+ size = ptsize*mpoint->ngeoms;
+ newpoints = lwalloc(size);
+ memset(newpoints, 0, size);
+
+ ptr=newpoints;
+ for (i=0; i<mpoint->ngeoms; i++)
+ {
+ memcpy(ptr,
+ getPoint_internal(mpoint->geoms[i]->point, 0),
+ ptsize);
+ ptr+=ptsize;
+ }
+
+ pa = pointArray_construct(newpoints, zmflag&2, zmflag&1,
+ mpoint->ngeoms);
+
+ LWDEBUGF(3, "lwline_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);
+
+ return lwline_construct(SRID, NULL, pa);
+}
+
+LWLINE *
+lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where)
+{
+ POINTARRAY *newpa;
+ LWLINE *ret;
+
+ newpa = ptarray_addPoint(line->points,
+ getPoint_internal(point->point, 0),
+ TYPE_NDIMS(point->type), where);
+
+ ret = lwline_construct(line->SRID, NULL, newpa);
+
+ return ret;
+}
+
+LWLINE *
+lwline_removepoint(LWLINE *line, unsigned int index)
+{
+ POINTARRAY *newpa;
+ LWLINE *ret;
+
+ newpa = ptarray_removePoint(line->points, index);
+
+ ret = lwline_construct(line->SRID, NULL, newpa);
+
+ return ret;
+}
+
+/*
+ * Note: input will be changed, make sure you have permissions for this.
+ */
+void
+lwline_setPoint4d(LWLINE *line, unsigned int index, POINT4D *newpoint)
+{
+ setPoint4d(line->points, index, newpoint);
+}
Added: trunk/liblwgeom/lwmcurve.c
===================================================================
--- trunk/liblwgeom/lwmcurve.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwmcurve.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,125 @@
+/**********************************************************************
+ * $Id$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+LWMCURVE *
+lwmcurve_deserialize(uchar *srl)
+{
+ LWMCURVE *result;
+ LWGEOM_INSPECTED *insp;
+ int stype;
+ int type = lwgeom_getType(srl[0]);
+ int i;
+
+ if(type != MULTICURVETYPE)
+ {
+ lwerror("lwmcurve_deserialize called on NON multicurve: %d", type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(srl);
+
+ result = lwalloc(sizeof(LWMCURVE));
+ result->type = insp->type;
+ result->SRID = insp->SRID;
+ result->ngeoms = insp->ngeometries;
+ result->geoms = lwalloc(sizeof(LWCURVE *)*insp->ngeometries);
+
+ if(lwgeom_hasBBOX(srl[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+ for(i = 0; i < insp->ngeometries; i++)
+ {
+ stype = lwgeom_getType(insp->sub_geoms[i][0]);
+ if(stype == CURVETYPE)
+ {
+ result->geoms[i] = (LWGEOM *)lwcurve_deserialize(insp->sub_geoms[i]);
+ }
+ else if(stype == LINETYPE)
+ {
+ result->geoms[i] = (LWGEOM *)lwline_deserialize(insp->sub_geoms[i]);
+ }
+ else
+ {
+ lwerror("Only Circular and Line strings are currenly permitted in a MultiCurve.");
+ free(result);
+ free(insp);
+ return NULL;
+ }
+
+ if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
+ {
+ lwerror("Mixed diminsions (multicurve: %d, curve %d:%d)",
+ TYPE_NDIMS(result->type), i,
+ TYPE_NDIMS(result->geoms[i]->type));
+ free(result);
+ free(insp);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+/*
+ * Add 'what' to this multicurve at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTICURVE or a COLLECTION
+ */
+LWGEOM *
+lwmcurve_add(const LWMCURVE *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+ uint32 i;
+
+ if(where == -1) where = to->ngeoms;
+ else if(where < -1 || where > to->ngeoms)
+ {
+ lwerror("lwmcurve_add: add position out of range %d..%d",
+ -1, to->ngeoms);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
+ for(i = 0; i < where; i++)
+ {
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+ geoms[where] = lwgeom_clone(what);
+ for(i = where; i < to->ngeoms; i++)
+ {
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+
+ if(TYPE_GETTYPE(what->type) == CURVETYPE) newtype = MULTICURVETYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ to->ngeoms + 1, geoms);
+
+ return (LWGEOM *)col;
+}
+
Added: trunk/liblwgeom/lwmline.c
===================================================================
--- trunk/liblwgeom/lwmline.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwmline.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,110 @@
+/**********************************************************************
+ * $Id: lwmline.c 2369 2006-05-30 08:38:58Z strk $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+LWMLINE *
+lwmline_deserialize(uchar *srl)
+{
+ LWMLINE *result;
+ LWGEOM_INSPECTED *insp;
+ int type = lwgeom_getType(srl[0]);
+ int i;
+
+ if ( type != MULTILINETYPE )
+ {
+ lwerror("lwmline_deserialize called on NON multiline: %d",
+ type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(srl);
+
+ result = lwalloc(sizeof(LWMLINE));
+ result->type = insp->type;
+ result->SRID = insp->SRID;
+ result->ngeoms = insp->ngeometries;
+ result->geoms = lwalloc(sizeof(LWLINE *)*insp->ngeometries);
+
+ if (lwgeom_hasBBOX(srl[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+
+ for (i=0; i<insp->ngeometries; i++)
+ {
+ result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]);
+ if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
+ {
+ lwerror("Mixed dimensions (multiline:%d, line%d:%d)",
+ TYPE_NDIMS(result->type), i,
+ TYPE_NDIMS(result->geoms[i]->type)
+ );
+ return NULL;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Add 'what' to this multiline at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTILINE or a COLLECTION
+ */
+LWGEOM *
+lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+ uint32 i;
+
+ if ( where == -1 ) where = to->ngeoms;
+ else if ( where < -1 || where > to->ngeoms )
+ {
+ lwerror("lwmline_add: add position out of range %d..%d",
+ -1, to->ngeoms);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
+ for (i=0; i<where; i++)
+ {
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+ geoms[where] = lwgeom_clone(what);
+ for (i=where; i<to->ngeoms; i++)
+ {
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+
+ if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ to->ngeoms+1, geoms);
+
+ return (LWGEOM *)col;
+
+}
Added: trunk/liblwgeom/lwmpoint.c
===================================================================
--- trunk/liblwgeom/lwmpoint.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwmpoint.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,109 @@
+/**********************************************************************
+ * $Id: lwmpoint.c 2369 2006-05-30 08:38:58Z strk $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+LWMPOINT *
+lwmpoint_deserialize(uchar *srl)
+{
+ LWMPOINT *result;
+ LWGEOM_INSPECTED *insp;
+ int type = lwgeom_getType(srl[0]);
+ int i;
+
+ if ( type != MULTIPOINTTYPE )
+ {
+ lwerror("lwmpoint_deserialize called on NON multipoint: %d",
+ type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(srl);
+
+ result = lwalloc(sizeof(LWMPOINT));
+ result->type = insp->type;
+ result->SRID = insp->SRID;
+ result->ngeoms = insp->ngeometries;
+ result->geoms = lwalloc(sizeof(LWPOINT *)*result->ngeoms);
+
+ if (lwgeom_hasBBOX(srl[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+ for (i=0; i<insp->ngeometries; i++)
+ {
+ result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]);
+ if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
+ {
+ lwerror("Mixed dimensions (multipoint:%d, point%d:%d)",
+ TYPE_NDIMS(result->type), i,
+ TYPE_NDIMS(result->geoms[i]->type)
+ );
+ return NULL;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Add 'what' to this multipoint at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTIPOINT or a COLLECTION
+ */
+LWGEOM *
+lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+ uint32 i;
+
+ if ( where == -1 ) where = to->ngeoms;
+ else if ( where < -1 || where > to->ngeoms )
+ {
+ lwerror("lwmpoint_add: add position out of range %d..%d",
+ -1, to->ngeoms);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
+ for (i=0; i<where; i++)
+ {
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+ geoms[where] = lwgeom_clone(what);
+ for (i=where; i<to->ngeoms; i++)
+ {
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+
+ if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ to->ngeoms+1, geoms);
+
+ return (LWGEOM *)col;
+
+}
Added: trunk/liblwgeom/lwmpoly.c
===================================================================
--- trunk/liblwgeom/lwmpoly.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwmpoly.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,112 @@
+/**********************************************************************
+ * $Id: lwmpoly.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+
+LWMPOLY *
+lwmpoly_deserialize(uchar *srl)
+{
+ LWMPOLY *result;
+ LWGEOM_INSPECTED *insp;
+ int type = lwgeom_getType(srl[0]);
+ int i;
+
+ LWDEBUG(2, "lwmpoly_deserialize called");
+
+ if ( type != MULTIPOLYGONTYPE )
+ {
+ lwerror("lwmpoly_deserialize called on NON multipoly: %d",
+ type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(srl);
+
+ result = lwalloc(sizeof(LWMPOLY));
+ result->type = insp->type;
+ result->SRID = insp->SRID;
+ result->ngeoms = insp->ngeometries;
+ result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
+
+ if (lwgeom_hasBBOX(srl[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+ for (i=0; i<insp->ngeometries; i++)
+ {
+ result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]);
+ if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
+ {
+ lwerror("Mixed dimensions (multipoly:%d, poly%d:%d)",
+ TYPE_NDIMS(result->type), i,
+ TYPE_NDIMS(result->geoms[i]->type)
+ );
+ return NULL;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Add 'what' to this multiline at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTIPOLY or a COLLECTION
+ */
+LWGEOM *
+lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+ uint32 i;
+
+ if ( where == -1 ) where = to->ngeoms;
+ else if ( where < -1 || where > to->ngeoms )
+ {
+ lwerror("lwmline_add: add position out of range %d..%d",
+ -1, to->ngeoms);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
+ for (i=0; i<where; i++)
+ {
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+ geoms[where] = lwgeom_clone(what);
+ for (i=where; i<to->ngeoms; i++)
+ {
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+
+ if ( TYPE_GETTYPE(what->type) == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ to->ngeoms+1, geoms);
+
+ return (LWGEOM *)col;
+
+}
Added: trunk/liblwgeom/lwmsurface.c
===================================================================
--- trunk/liblwgeom/lwmsurface.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwmsurface.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,129 @@
+/**********************************************************************
+ * $Id$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+
+LWMSURFACE *
+lwmsurface_deserialize(uchar *srl)
+{
+ LWMSURFACE *result;
+ LWGEOM_INSPECTED *insp;
+ int stype;
+ int type = lwgeom_getType(srl[0]);
+ int i;
+
+ LWDEBUG(2, "lwmsurface_deserialize called");
+
+ if(type != MULTISURFACETYPE)
+ {
+ lwerror("lwmsurface_deserialize called on a non-multisurface: %d", type);
+ return NULL;
+ }
+
+ insp = lwgeom_inspect(srl);
+
+ result = lwalloc(sizeof(LWMSURFACE));
+ result->type = insp->type;
+ result->SRID = insp->SRID;
+ result->ngeoms = insp->ngeometries;
+ result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
+
+ if(lwgeom_hasBBOX(srl[0]))
+ {
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4));
+ }
+ else result->bbox = NULL;
+
+ for(i = 0; i < insp->ngeometries; i++)
+ {
+ stype = lwgeom_getType(insp->sub_geoms[i][0]);
+ if(stype == POLYGONTYPE)
+ {
+ result->geoms[i] = (LWGEOM *)lwpoly_deserialize(insp->sub_geoms[i]);
+ }
+ else if(stype == CURVEPOLYTYPE)
+ {
+ result->geoms[i] = (LWGEOM *)lwcurvepoly_deserialize(insp->sub_geoms[i]);
+ }
+ else
+ {
+ lwerror("Only Polygons and Curved Polygons are supported in a MultiSurface.");
+ lwfree(result);
+ lwfree(insp);
+ return NULL;
+ }
+
+ if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
+ {
+ lwerror("Mixed dimensions (multisurface: %d, surface %d:%d",
+ TYPE_NDIMS(result->type), i,
+ TYPE_NDIMS(result->geoms[i]->type));
+ lwfree(result);
+ lwfree(insp);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+/*
+ * Add 'what' to this multisurface at position 'where'
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTISURFACE or a COLLECTION
+ */
+LWGEOM *
+lwmsurface_add(const LWMSURFACE *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+ uint32 i;
+
+ if(where == -1) where = to->ngeoms;
+ else if(where < -1 || where > to->ngeoms)
+ {
+ lwerror("lwmsurface_add: add position out of range %d..%d",
+ -1, to->ngeoms);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
+ for(i = 0; i < where; i++)
+ {
+ geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+ geoms[where] = lwgeom_clone(what);
+ for(i = where; i < to->ngeoms; i++)
+ {
+ geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
+ }
+
+ if(TYPE_GETTYPE(what->type) == POLYGONTYPE
+ || TYPE_GETTYPE(what->type) == CURVEPOLYTYPE)
+ newtype = MULTISURFACETYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL, to->ngeoms + 1, geoms);
+
+ return (LWGEOM *)col;
+}
+
Added: trunk/liblwgeom/lwpoint.c
===================================================================
--- trunk/liblwgeom/lwpoint.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwpoint.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,431 @@
+/**********************************************************************
+ * $Id: lwpoint.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+
+/*
+ * Convert this point into its serialize form
+ * result's first char will be the 8bit type. See serialized form doc
+ */
+uchar *
+lwpoint_serialize(LWPOINT *point)
+{
+ size_t size, retsize;
+ uchar *result;
+
+ size = lwpoint_serialize_size(point);
+ result = lwalloc(size);
+ lwpoint_serialize_buf(point, result, &retsize);
+
+ if ( retsize != size )
+ {
+ lwerror("lwpoint_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
+ }
+
+ return result;
+}
+
+/*
+ * Convert this point into its serialize form writing it into
+ * the given buffer, and returning number of bytes written into
+ * the given int pointer.
+ * result's first char will be the 8bit type. See serialized form doc
+ */
+void
+lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *retsize)
+{
+ int size=1;
+ char hasSRID;
+ uchar *loc;
+ int ptsize = pointArray_ptsize(point->point);
+
+ if ( TYPE_GETZM(point->type) != TYPE_GETZM(point->point->dims) )
+ lwerror("Dimensions mismatch in lwpoint");
+
+ LWDEBUGF(2, "lwpoint_serialize_buf(%p, %p) called", point, buf);
+ /*printLWPOINT(point); */
+
+ hasSRID = (point->SRID != -1);
+
+ if (hasSRID) size +=4; /*4 byte SRID */
+ if (point->bbox) size += sizeof(BOX2DFLOAT4); /* bvol */
+
+ size += sizeof(double)*TYPE_NDIMS(point->type);
+
+ buf[0] = (uchar) lwgeom_makeType_full(
+ TYPE_HASZ(point->type), TYPE_HASM(point->type),
+ hasSRID, POINTTYPE, point->bbox?1:0);
+ loc = buf+1;
+
+ if (point->bbox)
+ {
+ memcpy(loc, point->bbox, sizeof(BOX2DFLOAT4));
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ if (hasSRID)
+ {
+ memcpy(loc, &point->SRID, sizeof(int32));
+ loc += 4;
+ }
+
+ /* copy in points */
+ memcpy(loc, getPoint_internal(point->point, 0), ptsize);
+
+ if (retsize) *retsize = size;
+}
+
+/*
+ * Find bounding box (standard one)
+ * zmin=zmax=NO_Z_VALUE if 2d
+ */
+BOX3D *
+lwpoint_compute_box3d(LWPOINT *point)
+{
+ LWDEBUGF(2, "lwpoint_compute_box3d called with point %p", point);
+
+ if (point == NULL)
+ {
+ LWDEBUG(3, "lwpoint_compute_box3d returning NULL");
+
+ return NULL;
+ }
+
+ LWDEBUG(3, "lwpoint_compute_box3d returning ptarray_compute_box3d return");
+
+ return ptarray_compute_box3d(point->point);
+}
+
+/*
+ * Convenience functions to hide the POINTARRAY
+ * TODO: obsolete this
+ */
+int
+lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out)
+{
+ return getPoint2d_p(point->point, 0, out);
+}
+
+/* convenience functions to hide the POINTARRAY */
+int
+lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out)
+{
+ return getPoint3dz_p(point->point,0,out);
+}
+int
+lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out)
+{
+ return getPoint3dm_p(point->point,0,out);
+}
+int
+lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
+{
+ return getPoint4d_p(point->point,0,out);
+}
+
+/* find length of this deserialized point */
+size_t
+lwpoint_serialize_size(LWPOINT *point)
+{
+ size_t size = 1; /* type */
+
+ LWDEBUG(2, "lwpoint_serialize_size called");
+
+ if ( point->SRID != -1 ) size += 4; /* SRID */
+ if ( point->bbox ) size += sizeof(BOX2DFLOAT4);
+
+ size += TYPE_NDIMS(point->type) * sizeof(double); /* point */
+
+ LWDEBUGF(3, "lwpoint_serialize_size returning %d", size);
+
+ return size;
+}
+
+/*
+ * Construct a new point. point will not be copied
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
+ */
+LWPOINT *
+lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point)
+{
+ LWPOINT *result ;
+
+ if (point == NULL)
+ return NULL; /* error */
+
+ result = lwalloc(sizeof(LWPOINT));
+ result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), POINTTYPE, 0);
+ result->SRID = SRID;
+ result->point = point;
+ result->bbox = bbox;
+
+ return result;
+}
+
+LWPOINT *
+make_lwpoint2d(int SRID, double x, double y)
+{
+ POINT2D p;
+ POINTARRAY *pa = ptarray_construct(0, 0, 1);
+
+ p.x = x;
+ p.y = y;
+
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT2D));
+
+ return lwpoint_construct(SRID, NULL, pa);
+}
+
+LWPOINT *
+make_lwpoint3dz(int SRID, double x, double y, double z)
+{
+ POINT3DZ p;
+ POINTARRAY *pa = ptarray_construct(1, 0, 1);
+
+ p.x = x;
+ p.y = y;
+ p.z = z;
+
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DZ));
+
+ return lwpoint_construct(SRID, NULL, pa);
+}
+
+LWPOINT *
+make_lwpoint3dm(int SRID, double x, double y, double m)
+{
+ POINTARRAY *pa = ptarray_construct(0, 1, 1);
+ POINT3DM p;
+
+ p.x = x;
+ p.y = y;
+ p.m = m;
+
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DM));
+
+ return lwpoint_construct(SRID, NULL, pa);
+}
+
+LWPOINT *
+make_lwpoint4d(int SRID, double x, double y, double z, double m)
+{
+ POINTARRAY *pa = ptarray_construct(1, 1, 1);
+ POINT4D p;
+
+ p.x = x;
+ p.y = y;
+ p.z = z;
+ p.m = m;
+
+ memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT4D));
+
+ return lwpoint_construct(SRID, NULL, pa);
+}
+
+/*
+ * Given the LWPOINT serialized form (or a pointer into a muli* one)
+ * construct a proper LWPOINT.
+ * serialized_form should point to the 8bit type format (with type = 1)
+ * See serialized form doc
+ */
+LWPOINT *
+lwpoint_deserialize(uchar *serialized_form)
+{
+ uchar type;
+ int geom_type;
+ LWPOINT *result;
+ uchar *loc = NULL;
+ POINTARRAY *pa;
+
+ LWDEBUG(2, "lwpoint_deserialize called");
+
+ result = (LWPOINT*) lwalloc(sizeof(LWPOINT)) ;
+
+ type = serialized_form[0];
+ geom_type = lwgeom_getType(type);
+
+ if ( geom_type != POINTTYPE)
+ {
+ lwerror("lwpoint_deserialize: attempt to deserialize a point which is really a %s", lwgeom_typename(geom_type));
+ return NULL;
+ }
+ result->type = type;
+
+ loc = serialized_form+1;
+
+ if (lwgeom_hasBBOX(type))
+ {
+ LWDEBUG(3, "lwpoint_deserialize: input has bbox");
+
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
+ loc += sizeof(BOX2DFLOAT4);
+ }
+ else
+ {
+ result->bbox = NULL;
+ }
+
+ if ( lwgeom_hasSRID(type))
+ {
+ LWDEBUG(3, "lwpoint_deserialize: input has SRID");
+
+ result->SRID = lw_get_int32(loc);
+ loc += 4; /* type + SRID */
+ }
+ else
+ {
+ result->SRID = -1;
+ }
+
+ /* we've read the type (1 byte) and SRID (4 bytes, if present) */
+
+ pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), 1);
+
+ result->point = pa;
+
+ return result;
+}
+
+void pfree_point (LWPOINT *pt)
+{
+ pfree_POINTARRAY(pt->point);
+ lwfree(pt);
+}
+
+void printLWPOINT(LWPOINT *point)
+{
+ lwnotice("LWPOINT {");
+ lwnotice(" ndims = %i", (int)TYPE_NDIMS(point->type));
+ lwnotice(" BBOX = %i", TYPE_HASBBOX(point->type) ? 1 : 0 );
+ lwnotice(" SRID = %i", (int)point->SRID);
+ printPA(point->point);
+ lwnotice("}");
+}
+
+int
+lwpoint_compute_box2d_p(LWPOINT *point, BOX2DFLOAT4 *box)
+{
+ return ptarray_compute_box2d_p(point->point, box);
+}
+
+/* Clone LWPOINT object. POINTARRAY is not copied. */
+LWPOINT *
+lwpoint_clone(const LWPOINT *g)
+{
+ LWPOINT *ret = lwalloc(sizeof(LWPOINT));
+
+ LWDEBUG(2, "lwpoint_clone called");
+
+ memcpy(ret, g, sizeof(LWPOINT));
+ if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
+ return ret;
+}
+
+/*
+ * Add 'what' to this point at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTIPOINT or a GEOMETRYCOLLECTION
+ */
+LWGEOM *
+lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+
+ if ( where != -1 && where != 0 )
+ {
+ lwerror("lwpoint_add only supports 0 or -1 as second argument, got %d", where);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*2);
+ if ( where == -1 ) /* append */
+ {
+ geoms[0] = lwgeom_clone((LWGEOM *)to);
+ geoms[1] = lwgeom_clone(what);
+ }
+ else /* prepend */
+ {
+ geoms[0] = lwgeom_clone(what);
+ geoms[1] = lwgeom_clone((LWGEOM *)to);
+ }
+ /* reset SRID and wantbbox flag from component types */
+ lwgeom_dropSRID(geoms[0]);
+ lwgeom_dropBBOX(geoms[0]);
+ lwgeom_dropSRID(geoms[1]);
+ lwgeom_dropBBOX(geoms[1]);
+
+ /* Find appropriate geom type */
+ if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ 2, geoms);
+
+ return (LWGEOM *)col;
+}
+
+/* Find length of this serialized point */
+size_t
+lwgeom_size_point(const uchar *serialized_point)
+{
+ uint32 result = 1;
+ uchar type;
+ const uchar *loc;
+
+ type = serialized_point[0];
+
+ if ( lwgeom_getType(type) != POINTTYPE) return 0;
+
+ LWDEBUGF(2, "lwgeom_size_point called (%d)", result);
+
+ loc = serialized_point+1;
+
+ if (lwgeom_hasBBOX(type))
+ {
+ loc += sizeof(BOX2DFLOAT4);
+ result +=sizeof(BOX2DFLOAT4);
+
+ LWDEBUGF(3, "lwgeom_size_point: has bbox (%d)", result);
+ }
+
+ if ( lwgeom_hasSRID(type))
+ {
+ LWDEBUGF(3, "lwgeom_size_point: has srid (%d)", result);
+
+ loc +=4; /* type + SRID */
+ result +=4;
+ }
+
+ result += lwgeom_ndims(type)*sizeof(double);
+
+ return result;
+}
+
+/* check coordinate equality */
+char
+lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
+{
+ return ptarray_same(p1->point, p2->point);
+}
Added: trunk/liblwgeom/lwpoly.c
===================================================================
--- trunk/liblwgeom/lwpoly.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwpoly.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,567 @@
+/**********************************************************************
+ * $Id: lwpoly.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+/* basic LWPOLY manipulation */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "liblwgeom.h"
+
+
+#define CHECK_POLY_RINGS_ZM 1
+
+/* construct a new LWPOLY. arrays (points/points per ring) will NOT be copied
+ * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
+ */
+LWPOLY *
+lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox, unsigned int nrings, POINTARRAY **points)
+{
+ LWPOLY *result;
+ int hasz, hasm;
+#ifdef CHECK_POLY_RINGS_ZM
+ char zm;
+ unsigned int i;
+#endif
+
+ if ( nrings < 1 ) lwerror("lwpoly_construct: need at least 1 ring");
+
+ hasz = TYPE_HASZ(points[0]->dims);
+ hasm = TYPE_HASM(points[0]->dims);
+
+#ifdef CHECK_POLY_RINGS_ZM
+ zm = TYPE_GETZM(points[0]->dims);
+ for (i=1; i<nrings; i++)
+ {
+ if ( zm != TYPE_GETZM(points[i]->dims) )
+ lwerror("lwpoly_construct: mixed dimensioned rings");
+ }
+#endif
+
+ result = (LWPOLY*) lwalloc(sizeof(LWPOLY));
+ result->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1), POLYGONTYPE,
+ 0);
+ result->SRID = SRID;
+ result->nrings = nrings;
+ result->rings = points;
+ result->bbox = bbox;
+
+ return result;
+}
+
+
+/*
+ * given the LWPOLY serialized form (or a pointer into a muli* one)
+ * construct a proper LWPOLY.
+ * serialized_form should point to the 8bit type format (with type = 3)
+ * See serialized form doc
+ */
+LWPOLY *
+lwpoly_deserialize(uchar *serialized_form)
+{
+
+ LWPOLY *result;
+ uint32 nrings;
+ int ndims, hasz, hasm;
+ uint32 npoints;
+ uchar type;
+ uchar *loc;
+ int t;
+
+ if (serialized_form == NULL)
+ {
+ lwerror("lwpoly_deserialize called with NULL arg");
+ return NULL;
+ }
+
+ result = (LWPOLY*) lwalloc(sizeof(LWPOLY));
+
+ type = serialized_form[0];
+ result->type = type;
+
+ ndims = TYPE_NDIMS(type);
+ hasz = TYPE_HASZ(type);
+ hasm = TYPE_HASM(type);
+ loc = serialized_form;
+
+ if ( TYPE_GETTYPE(type) != POLYGONTYPE)
+ {
+ lwerror("lwpoly_deserialize: attempt to deserialize a poly which is really a %s", lwgeom_typename(type));
+ return NULL;
+ }
+
+
+ loc = serialized_form+1;
+
+ if (lwgeom_hasBBOX(type)) {
+ LWDEBUG(3, "lwpoly_deserialize: input has bbox");
+
+ result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
+ memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
+ loc += sizeof(BOX2DFLOAT4);
+ } else {
+ result->bbox = NULL;
+ }
+
+ if ( lwgeom_hasSRID(type))
+ {
+ result->SRID = lw_get_int32(loc);
+ loc +=4; /* type + SRID */
+ }
+ else
+ {
+ result->SRID = -1;
+ }
+
+ nrings = lw_get_uint32(loc);
+ result->nrings = nrings;
+ loc +=4;
+ result->rings = (POINTARRAY**) lwalloc(nrings* sizeof(POINTARRAY*));
+
+ for (t =0;t<nrings;t++)
+ {
+ /* read in a single ring and make a PA */
+ npoints = lw_get_uint32(loc);
+ loc +=4;
+
+ result->rings[t] = pointArray_construct(loc, hasz, hasm, npoints);
+ loc += sizeof(double)*ndims*npoints;
+ }
+
+ return result;
+}
+
+/*
+ * create the serialized form of the polygon
+ * result's first char will be the 8bit type. See serialized form doc
+ * points copied
+ */
+uchar *
+lwpoly_serialize(LWPOLY *poly)
+{
+ size_t size, retsize;
+ uchar *result;
+
+ size = lwpoly_serialize_size(poly);
+ result = lwalloc(size);
+ lwpoly_serialize_buf(poly, result, &retsize);
+
+ if ( retsize != size )
+ {
+ lwerror("lwpoly_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
+ }
+
+ return result;
+}
+
+/*
+ * create the serialized form of the polygon writing it into the
+ * given buffer, and returning number of bytes written into
+ * the given int pointer.
+ * result's first char will be the 8bit type. See serialized form doc
+ * points copied
+ */
+void
+lwpoly_serialize_buf(LWPOLY *poly, uchar *buf, size_t *retsize)
+{
+ size_t size=1; /* type byte */
+ char hasSRID;
+ int t;
+ uchar *loc;
+ int ptsize;
+
+ LWDEBUG(2, "lwpoly_serialize_buf called");
+
+ ptsize = sizeof(double)*TYPE_NDIMS(poly->type);
+
+ hasSRID = (poly->SRID != -1);
+
+ size += 4; /* nrings */
+ size += 4*poly->nrings; /* npoints/ring */
+
+ buf[0] = (uchar) lwgeom_makeType_full(
+ TYPE_HASZ(poly->type), TYPE_HASM(poly->type),
+ hasSRID, POLYGONTYPE, poly->bbox ? 1 : 0);
+ loc = buf+1;
+
+ if (poly->bbox)
+ {
+ memcpy(loc, poly->bbox, sizeof(BOX2DFLOAT4));
+ size += sizeof(BOX2DFLOAT4); /* bvol */
+ loc += sizeof(BOX2DFLOAT4);
+ }
+
+ if (hasSRID)
+ {
+ memcpy(loc, &poly->SRID, sizeof(int32));
+ loc += 4;
+ size +=4; /* 4 byte SRID */
+ }
+
+ memcpy(loc, &poly->nrings, sizeof(int32)); /* nrings */
+ loc+=4;
+
+ for (t=0;t<poly->nrings;t++)
+ {
+ POINTARRAY *pa = poly->rings[t];
+ size_t pasize;
+ uint32 npoints;
+
+ if ( TYPE_GETZM(poly->type) != TYPE_GETZM(pa->dims) )
+ lwerror("Dimensions mismatch in lwpoly");
+
+ npoints = pa->npoints;
+
+ memcpy(loc, &npoints, sizeof(uint32)); /* npoints this ring */
+ loc+=4;
+
+ pasize = npoints*ptsize;
+ size += pasize;
+
+ /* copy points */
+ memcpy(loc, getPoint_internal(pa, 0), pasize);
+ loc += pasize;
+
+ }
+
+ if (retsize) *retsize = size;
+}
+
+
+/* find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN) */
+BOX3D *
+lwpoly_compute_box3d(LWPOLY *poly)
+{
+ BOX3D *result;
+
+ /* just need to check outer ring -- interior rings are inside */
+ POINTARRAY *pa = poly->rings[0];
+ result = ptarray_compute_box3d(pa);
+
+ return result;
+}
+
+/* find length of this serialized polygon */
+size_t
+lwgeom_size_poly(const uchar *serialized_poly)
+{
+ uint32 result = 1; /* char type */
+ uint32 nrings;
+ int ndims;
+ int t;
+ uchar type;
+ uint32 npoints;
+ const uchar *loc;
+
+ if (serialized_poly == NULL)
+ return -9999;
+
+
+ type = (uchar) serialized_poly[0];
+ ndims = lwgeom_ndims(type);
+
+ if ( lwgeom_getType(type) != POLYGONTYPE)
+ return -9999;
+
+
+ loc = serialized_poly+1;
+
+ if (lwgeom_hasBBOX(type))
+ {
+ LWDEBUG(3, "lwgeom_size_poly: has bbox");
+
+ loc += sizeof(BOX2DFLOAT4);
+ result +=sizeof(BOX2DFLOAT4);
+ }
+
+
+ if ( lwgeom_hasSRID(type))
+ {
+ LWDEBUG(3, "lwgeom_size_poly: has srid");
+
+ loc +=4; /* type + SRID */
+ result += 4;
+ }
+
+
+ nrings = lw_get_uint32(loc);
+ loc +=4;
+ result +=4;
+
+ LWDEBUGF(3, "lwgeom_size_poly contains %d rings", nrings);
+
+ for (t =0;t<nrings;t++)
+ {
+ /* read in a single ring and make a PA */
+ npoints = lw_get_uint32(loc);
+ loc += 4;
+ result += 4;
+
+ if (ndims == 3)
+ {
+ loc += 24*npoints;
+ result += 24*npoints;
+ }
+ else if (ndims == 2)
+ {
+ loc += 16*npoints;
+ result += 16*npoints;
+ }
+ else if (ndims == 4)
+ {
+ loc += 32*npoints;
+ result += 32*npoints;
+ }
+ }
+
+ LWDEBUGF(3, "lwgeom_size_poly returning %d", result);
+
+ return result;
+}
+
+/* find length of this deserialized polygon */
+size_t
+lwpoly_serialize_size(LWPOLY *poly)
+{
+ size_t size = 1; /* type */
+ uint32 i;
+
+ if ( poly->SRID != -1 ) size += 4; /* SRID */
+ if ( poly->bbox ) size += sizeof(BOX2DFLOAT4);
+
+ LWDEBUGF(2, "lwpoly_serialize_size called with poly[%p] (%d rings)",
+ poly, poly->nrings);
+
+ size += 4; /* nrings */
+
+ for (i=0; i<poly->nrings; i++)
+ {
+ size += 4; /* npoints */
+ size += poly->rings[i]->npoints*TYPE_NDIMS(poly->type)*sizeof(double);
+ }
+
+ LWDEBUGF(3, "lwpoly_serialize_size returning %d", size);
+
+ return size;
+}
+
+void pfree_polygon (LWPOLY *poly)
+{
+ int t;
+
+ for (t=0;t<poly->nrings;t++)
+ {
+ pfree_POINTARRAY(poly->rings[t]);
+ }
+
+ lwfree(poly);
+}
+
+void printLWPOLY(LWPOLY *poly)
+{
+ int t;
+ lwnotice("LWPOLY {");
+ lwnotice(" ndims = %i", (int)TYPE_NDIMS(poly->type));
+ lwnotice(" SRID = %i", (int)poly->SRID);
+ lwnotice(" nrings = %i", (int)poly->nrings);
+ for (t=0;t<poly->nrings;t++)
+ {
+ lwnotice(" RING # %i :",t);
+ printPA(poly->rings[t]);
+ }
+ lwnotice("}");
+}
+
+int
+lwpoly_compute_box2d_p(LWPOLY *poly, BOX2DFLOAT4 *box)
+{
+ BOX2DFLOAT4 boxbuf;
+ uint32 i;
+
+ if ( ! poly->nrings ) return 0;
+ if ( ! ptarray_compute_box2d_p(poly->rings[0], box) ) return 0;
+ for (i=1; i<poly->nrings; i++)
+ {
+ if ( ! ptarray_compute_box2d_p(poly->rings[0], &boxbuf) )
+ return 0;
+ if ( ! box2d_union_p(box, &boxbuf, box) )
+ return 0;
+ }
+ return 1;
+}
+
+/* Clone LWLINE object. POINTARRAY are not copied, it's ring array is. */
+LWPOLY *
+lwpoly_clone(const LWPOLY *g)
+{
+ LWPOLY *ret = lwalloc(sizeof(LWPOLY));
+ memcpy(ret, g, sizeof(LWPOLY));
+ ret->rings = lwalloc(sizeof(POINTARRAY *)*g->nrings);
+ memcpy(ret->rings, g->rings, sizeof(POINTARRAY *)*g->nrings);
+ if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
+ return ret;
+}
+
+/*
+ * Add 'what' to this poly at position 'where'.
+ * where=0 == prepend
+ * where=-1 == append
+ * Returns a MULTIPOLYGON or a GEOMETRYCOLLECTION
+ */
+LWGEOM *
+lwpoly_add(const LWPOLY *to, uint32 where, const LWGEOM *what)
+{
+ LWCOLLECTION *col;
+ LWGEOM **geoms;
+ int newtype;
+
+ if ( where != -1 && where != 0 )
+ {
+ lwerror("lwpoly_add only supports 0 or -1 as second argument, got %d", where);
+ return NULL;
+ }
+
+ /* dimensions compatibility are checked by caller */
+
+ /* Construct geoms array */
+ geoms = lwalloc(sizeof(LWGEOM *)*2);
+ if ( where == -1 ) /* append */
+ {
+ geoms[0] = lwgeom_clone((LWGEOM *)to);
+ geoms[1] = lwgeom_clone(what);
+ }
+ else /* prepend */
+ {
+ geoms[0] = lwgeom_clone(what);
+ geoms[1] = lwgeom_clone((LWGEOM *)to);
+ }
+
+ /* reset SRID and wantbbox flag from component types */
+ geoms[0]->SRID = geoms[1]->SRID = -1;
+ TYPE_SETHASSRID(geoms[0]->type, 0);
+ TYPE_SETHASSRID(geoms[1]->type, 0);
+ TYPE_SETHASBBOX(geoms[0]->type, 0);
+ TYPE_SETHASBBOX(geoms[1]->type, 0);
+
+ /* Find appropriate geom type */
+ if ( TYPE_GETTYPE(what->type) == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE;
+ else newtype = COLLECTIONTYPE;
+
+ col = lwcollection_construct(newtype,
+ to->SRID, NULL,
+ 2, geoms);
+
+ return (LWGEOM *)col;
+}
+
+void
+lwpoly_forceRHR(LWPOLY *poly)
+{
+ int i;
+
+ if ( ptarray_isccw(poly->rings[0]) )
+ {
+ ptarray_reverse(poly->rings[0]);
+ }
+
+ for (i=1; i<poly->nrings; i++)
+ {
+ if ( ! ptarray_isccw(poly->rings[i]) )
+ {
+ ptarray_reverse(poly->rings[i]);
+ }
+ }
+}
+
+
+void
+lwpoly_reverse(LWPOLY *poly)
+{
+ int i;
+
+ for (i=0; i<poly->nrings; i++)
+ ptarray_reverse(poly->rings[i]);
+}
+
+LWPOLY *
+lwpoly_segmentize2d(LWPOLY *poly, double dist)
+{
+ POINTARRAY **newrings;
+ unsigned int i;
+
+ newrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings);
+ for (i=0; i<poly->nrings; i++)
+ {
+ newrings[i] = ptarray_segmentize2d(poly->rings[i], dist);
+ }
+ return lwpoly_construct(poly->SRID, NULL,
+ poly->nrings, newrings);
+}
+
+/*
+ * check coordinate equality
+ * ring and coordinate order is considered
+ */
+char
+lwpoly_same(const LWPOLY *p1, const LWPOLY *p2)
+{
+ unsigned int i;
+
+ if ( p1->nrings != p2->nrings ) return 0;
+ for (i=0; i<p1->nrings; i++)
+ {
+ if ( ! ptarray_same(p1->rings[i], p2->rings[i]) )
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Construct a polygon from a LWLINE being
+ * the shell and an array of LWLINE (possibly NULL) being holes.
+ * Pointarrays from intput geoms are cloned.
+ * SRID must be the same for each input line.
+ * Input lines must have at least 4 points, and be closed.
+ */
+LWPOLY *
+lwpoly_from_lwlines(const LWLINE *shell,
+ unsigned int nholes, const LWLINE **holes)
+{
+ unsigned int nrings;
+ POINTARRAY **rings = lwalloc((nholes+1)*sizeof(POINTARRAY *));
+ int SRID = shell->SRID;
+ LWPOLY *ret;
+
+ if ( shell->points->npoints < 4 )
+ lwerror("lwpoly_from_lwlines: shell must have at least 4 points");
+ if ( ! ptarray_isclosed2d(shell->points) )
+ lwerror("lwpoly_from_lwlines: shell must be closed");
+ rings[0] = ptarray_clone(shell->points);
+
+ for (nrings=1; nrings<=nholes; nrings++)
+ {
+ const LWLINE *hole = holes[nrings-1];
+
+ if ( hole->SRID != SRID )
+ lwerror("lwpoly_from_lwlines: mixed SRIDs in input lines");
+
+ if ( hole->points->npoints < 4 )
+ lwerror("lwpoly_from_lwlines: holes must have at least 4 points");
+ if ( ! ptarray_isclosed2d(hole->points) )
+ lwerror("lwpoly_from_lwlines: holes must be closed");
+
+ rings[nrings] = ptarray_clone(hole->points);
+ }
+
+ ret = lwpoly_construct(SRID, NULL, nrings, rings);
+ return ret;
+}
Added: trunk/liblwgeom/lwutil.c
===================================================================
--- trunk/liblwgeom/lwutil.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/lwutil.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,274 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+/* Global variables */
+#include "../postgis_config.h"
+#include "liblwgeom.h"
+
+void *init_allocator(size_t size);
+void init_freeor(void *mem);
+void *init_reallocator(void *mem, size_t size);
+void init_noticereporter(const char *fmt, ...);
+void init_errorreporter(const char *fmt, ...);
+
+lwallocator lwalloc_var = init_allocator;
+lwreallocator lwrealloc_var = init_reallocator;
+lwfreeor lwfree_var = init_freeor;
+lwreporter lwerror = init_errorreporter;
+lwreporter lwnotice = init_noticereporter;
+
+static char *lwgeomTypeName[] = {
+ "Unknown",
+ "Point",
+ "Line",
+ "Polygon",
+ "MultiPoint",
+ "MultiLine",
+ "MultiPolygon",
+ "GeometryCollection",
+ "Curve",
+ "CompoundString",
+ "Invalid Type", /* POINTTYPEI */
+ "Invalid Type", /* LINETYPEI */
+ "Invalid Type", /* POLYTYPEI */
+ "CurvePolygon",
+ "MultiCurve",
+ "MultiSurface"
+};
+
+
+/*
+ * Initialisation allocators
+ *
+ * These are used the first time any of the allocators are called
+ * to enable executables/libraries that link into liblwgeom to
+ * be able to set up their own allocators. This is mainly useful
+ * for older PostgreSQL versions that don't have functions that
+ * are called upon startup.
+ */
+
+void *
+init_allocator(size_t size)
+{
+ lwgeom_init_allocators();
+
+ return lwalloc_var(size);
+}
+
+void
+init_freeor(void *mem)
+{
+ lwgeom_init_allocators();
+
+ lwfree_var(mem);
+}
+
+void *
+init_reallocator(void *mem, size_t size)
+{
+ lwgeom_init_allocators();
+
+ return lwrealloc_var(mem, size);
+}
+
+void
+init_noticereporter(const char *fmt, ...)
+{
+ va_list ap;
+
+ lwgeom_init_allocators();
+
+ va_start(ap, fmt);
+ lwnotice(fmt, ap);
+ va_end(ap);
+}
+
+void
+init_errorreporter(const char *fmt, ...)
+{
+ va_list ap;
+
+ lwgeom_init_allocators();
+
+ va_start(ap, fmt);
+ lwerror(fmt, ap);
+ va_end(ap);
+}
+
+
+/*
+ * Default allocators
+ *
+ * We include some default allocators that use malloc/free/realloc
+ * along with stdout/stderr since this is the most common use case
+ *
+ */
+
+void *
+default_allocator(size_t size)
+{
+ void *mem = malloc(size);
+ return mem;
+}
+
+void
+default_freeor(void *mem)
+{
+ free(mem);
+}
+
+void *
+default_reallocator(void *mem, size_t size)
+{
+ void *ret = realloc(mem, size);
+ return ret;
+}
+
+void
+default_noticereporter(const char *fmt, ...)
+{
+ char *msg;
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ /*
+ * This is a GNU extension.
+ * Dunno how to handle errors here.
+ */
+ if (!vasprintf (&msg, fmt, ap))
+ {
+ va_end (ap);
+ return;
+ }
+ printf("%s\n", msg);
+ va_end(ap);
+ free(msg);
+}
+
+void
+default_errorreporter(const char *fmt, ...)
+{
+ char *msg;
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ /*
+ * This is a GNU extension.
+ * Dunno how to handle errors here.
+ */
+ if (!vasprintf (&msg, fmt, ap))
+ {
+ va_end (ap);
+ return;
+ }
+ fprintf(stderr, "%s\n", msg);
+ va_end(ap);
+ free(msg);
+ exit(1);
+}
+
+
+/*
+ * This function should be called from lwgeom_init_allocators() by programs
+ * which wish to use the default allocators above
+ */
+
+void lwgeom_install_default_allocators()
+{
+ lwalloc_var = default_allocator;
+ lwrealloc_var = default_reallocator;
+ lwfree_var = default_freeor;
+ lwerror = default_errorreporter;
+ lwnotice = default_noticereporter;
+}
+
+
+const char *
+lwgeom_typename(int type)
+{
+ // something went wrong somewhere
+ if ( type < 0 || type > 12 ) {
+ // assert(0);
+ return "Invalid type";
+ }
+ return lwgeomTypeName[type];
+}
+
+void *
+lwalloc(size_t size)
+{
+ void *mem = lwalloc_var(size);
+ LWDEBUGF(5, "lwalloc: %d@%p", size, mem);
+ return mem;
+}
+
+void *
+lwrealloc(void *mem, size_t size)
+{
+ LWDEBUGF(5, "lwrealloc: %d@%p", size, mem);
+ return lwrealloc_var(mem, size);
+}
+
+void
+lwfree(void *mem)
+{
+ lwfree_var(mem);
+}
+
+/*
+ * Removes trailing zeros and dot for a %f formatted number.
+ * Modifies input.
+ */
+void
+trim_trailing_zeros(char *str)
+{
+ char *ptr, *totrim=NULL;
+ int len;
+ int i;
+
+ LWDEBUGF(3, "input: %s", str);
+
+ ptr = strchr(str, '.');
+ if ( ! ptr ) return; /* no dot, no decimal digits */
+
+ LWDEBUGF(3, "ptr: %s", ptr);
+
+ len = strlen(ptr);
+ for (i=len-1; i; i--)
+ {
+ if ( ptr[i] != '0' ) break;
+ totrim=&ptr[i];
+ }
+ if ( totrim )
+ {
+ if ( ptr == totrim-1 ) *ptr = '\0';
+ else *totrim = '\0';
+ }
+
+ LWDEBUGF(3, "output: %s", str);
+}
+
+char
+getMachineEndian(void)
+{
+ static int endian_check_int = 1; /* dont modify this!!! */
+
+ return *((char *) &endian_check_int); /* 0 = big endian | xdr,
+ * 1 = little endian | ndr
+ */
+}
+
+
+void
+errorIfSRIDMismatch(int srid1, int srid2)
+{
+ if ( srid1 != srid2 )
+ {
+ lwerror("Operation on mixed SRID geometries");
+ }
+}
Added: trunk/liblwgeom/measures.c
===================================================================
--- trunk/liblwgeom/measures.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/measures.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,845 @@
+/**********************************************************************
+ * $Id: measures.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <math.h>
+#include <string.h>
+
+#include "liblwgeom.h"
+
+
+/*
+ * pt_in_ring_2d(): crossing number test for a point in a polygon
+ * input: p = a point,
+ * pa = vertex points of a ring V[n+1] with V[n]=V[0]
+ * returns: 0 = outside, 1 = inside
+ *
+ * Our polygons have first and last point the same,
+ *
+ */
+int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring)
+{
+ int cn = 0; /* the crossing number counter */
+ int i;
+ POINT2D v1, v2;
+
+#if INTEGRITY_CHECKS
+ POINT2D first, last;
+
+ getPoint2d_p(ring, 0, &first);
+ getPoint2d_p(ring, ring->npoints-1, &last);
+ if ( memcmp(&first, &last, sizeof(POINT2D)) )
+ {
+ lwerror("pt_in_ring_2d: V[n] != V[0] (%g %g != %g %g)",
+ first.x, first.y, last.x, last.y);
+
+ }
+#endif
+
+ LWDEBUGF(2, "pt_in_ring_2d called with point: %g %g", p->x, p->y);
+ /* printPA(ring); */
+
+ /* loop through all edges of the polygon */
+ getPoint2d_p(ring, 0, &v1);
+ for (i=0; i<ring->npoints-1; i++)
+ {
+ double vt;
+ getPoint2d_p(ring, i+1, &v2);
+
+ /* edge from vertex i to vertex i+1 */
+ if
+ (
+ /* an upward crossing */
+ ((v1.y <= p->y) && (v2.y > p->y))
+ /* a downward crossing */
+ || ((v1.y > p->y) && (v2.y <= p->y))
+ )
+ {
+
+ vt = (double)(p->y - v1.y) / (v2.y - v1.y);
+
+ /* P.x <intersect */
+ if (p->x < v1.x + vt * (v2.x - v1.x))
+ {
+ /* a valid crossing of y=p.y right of p.x */
+ ++cn;
+ }
+ }
+ v1 = v2;
+ }
+
+ LWDEBUGF(3, "pt_in_ring_2d returning %d", cn&1);
+
+ return (cn&1); /* 0 if even (out), and 1 if odd (in) */
+}
+
+double distance2d_pt_pt(POINT2D *p1, POINT2D *p2)
+{
+ double hside = p2->x - p1->x;
+ double vside = p2->y - p1->y;
+
+ return sqrt ( hside*hside + vside*vside );
+
+ /* the above is more readable
+ return sqrt(
+ (p2->x-p1->x) * (p2->x-p1->x) + (p2->y-p1->y) * (p2->y-p1->y)
+ ); */
+}
+
+/*distance2d from p to line A->B */
+double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B)
+{
+ double r,s;
+
+ /*if start==end, then use pt distance */
+ if ( ( A->x == B->x) && (A->y == B->y) )
+ return distance2d_pt_pt(p,A);
+
+ /*
+ * otherwise, we use comp.graphics.algorithms
+ * Frequently Asked Questions method
+ *
+ * (1) AC dot AB
+ * r = ---------
+ * ||AB||^2
+ * r has the following meaning:
+ * r=0 P = A
+ * r=1 P = B
+ * r<0 P is on the backward extension of AB
+ * r>1 P is on the forward extension of AB
+ * 0<r<1 P is interior to AB
+ */
+
+ r = ( (p->x-A->x) * (B->x-A->x) + (p->y-A->y) * (B->y-A->y) )/( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
+
+ if (r<0) return distance2d_pt_pt(p,A);
+ if (r>1) return distance2d_pt_pt(p,B);
+
+
+ /*
+ * (2)
+ * (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
+ * s = -----------------------------
+ * L^2
+ *
+ * Then the distance from C to P = |s|*L.
+ *
+ */
+
+ s = ( (A->y-p->y)*(B->x-A->x)- (A->x-p->x)*(B->y-A->y) ) /
+ ( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
+
+ return LW_ABS(s) * sqrt(
+ (B->x-A->x)*(B->x-A->x) + (B->y-A->y)*(B->y-A->y)
+ );
+}
+
+/* find the minimum 2d distance from AB to CD */
+double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D)
+{
+
+ double s_top, s_bot,s;
+ double r_top, r_bot,r;
+
+ LWDEBUGF(2, "distance2d_seg_seg [%g,%g]->[%g,%g] by [%g,%g]->[%g,%g]",
+ A->x,A->y,B->x,B->y, C->x,C->y, D->x, D->y);
+
+
+ /*A and B are the same point */
+ if ( ( A->x == B->x) && (A->y == B->y) )
+ return distance2d_pt_seg(A,C,D);
+
+ /*U and V are the same point */
+
+ if ( ( C->x == D->x) && (C->y == D->y) )
+ return distance2d_pt_seg(D,A,B);
+
+ /* AB and CD are line segments */
+ /* from comp.graphics.algo
+
+ Solving the above for r and s yields
+ (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
+ r = ----------------------------- (eqn 1)
+ (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
+
+ (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
+ s = ----------------------------- (eqn 2)
+ (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
+ Let P be the position vector of the intersection point, then
+ P=A+r(B-A) or
+ Px=Ax+r(Bx-Ax)
+ Py=Ay+r(By-Ay)
+ By examining the values of r & s, you can also determine some other limiting conditions:
+ If 0<=r<=1 & 0<=s<=1, intersection exists
+ r<0 or r>1 or s<0 or s>1 line segments do not intersect
+ If the denominator in eqn 1 is zero, AB & CD are parallel
+ If the numerator in eqn 1 is also zero, AB & CD are collinear.
+
+ */
+ r_top = (A->y-C->y)*(D->x-C->x) - (A->x-C->x)*(D->y-C->y) ;
+ r_bot = (B->x-A->x)*(D->y-C->y) - (B->y-A->y)*(D->x-C->x) ;
+
+ s_top = (A->y-C->y)*(B->x-A->x) - (A->x-C->x)*(B->y-A->y);
+ s_bot = (B->x-A->x)*(D->y-C->y) - (B->y-A->y)*(D->x-C->x);
+
+ if ( (r_bot==0) || (s_bot == 0) )
+ {
+ return (
+ LW_MIN(distance2d_pt_seg(A,C,D),
+ LW_MIN(distance2d_pt_seg(B,C,D),
+ LW_MIN(distance2d_pt_seg(C,A,B),
+ distance2d_pt_seg(D,A,B))
+ )
+ )
+ );
+ }
+ s = s_top/s_bot;
+ r= r_top/r_bot;
+
+ if ((r<0) || (r>1) || (s<0) || (s>1) )
+ {
+ /*no intersection */
+ return (
+ LW_MIN(distance2d_pt_seg(A,C,D),
+ LW_MIN(distance2d_pt_seg(B,C,D),
+ LW_MIN(distance2d_pt_seg(C,A,B),
+ distance2d_pt_seg(D,A,B))
+ )
+ )
+ );
+
+ }
+ else
+ return -0; /*intersection exists */
+
+}
+
+/*
+ * search all the segments of pointarray to see which one is closest to p1
+ * Returns minimum distance between point and pointarray
+ */
+double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa)
+{
+ double result = 0;
+ int t;
+ POINT2D start, end;
+
+ getPoint2d_p(pa, 0, &start);
+
+ for (t=1; t<pa->npoints; t++)
+ {
+ double dist;
+ getPoint2d_p(pa, t, &end);
+ dist = distance2d_pt_seg(p, &start, &end);
+ if (t==1) result = dist;
+ else result = LW_MIN(result, dist);
+
+ if ( result == 0 ) return 0;
+
+ start = end;
+ }
+
+ return result;
+}
+
+/* test each segment of l1 against each segment of l2. Return min */
+double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2)
+{
+ double result = 99999999999.9;
+ char result_okay = 0; /*result is a valid min */
+ int t,u;
+ POINT2D start, end;
+ POINT2D start2, end2;
+
+ LWDEBUGF(2, "distance2d_ptarray_ptarray called (points: %d-%d)",
+ l1->npoints, l2->npoints);
+
+ getPoint2d_p(l1, 0, &start);
+ for (t=1; t<l1->npoints; t++) /*for each segment in L1 */
+ {
+ getPoint2d_p(l1, t, &end);
+
+ getPoint2d_p(l2, 0, &start2);
+ for (u=1; u<l2->npoints; u++) /*for each segment in L2 */
+ {
+ double dist;
+
+ getPoint2d_p(l2, u, &end2);
+
+ dist = distance2d_seg_seg(&start, &end, &start2, &end2);
+
+ LWDEBUGF(4, "line_line; seg %i * seg %i, dist = %g\n",t,u,dist);
+
+ if (result_okay)
+ result = LW_MIN(result,dist);
+ else
+ {
+ result_okay = 1;
+ result = dist;
+ }
+
+ LWDEBUGF(3, " seg%d-seg%d dist: %f, mindist: %f",
+ t, u, dist, result);
+
+ if (result <= 0) return 0; /*intersection */
+
+ start2 = end2;
+ }
+ start = end;
+ }
+
+ return result;
+}
+
+/* true if point is in poly (and not in its holes) */
+int pt_in_poly_2d(POINT2D *p, LWPOLY *poly)
+{
+ int i;
+
+ /* Not in outer ring */
+ if ( ! pt_in_ring_2d(p, poly->rings[0]) ) return 0;
+
+ /* Check holes */
+ for (i=1; i<poly->nrings; i++)
+ {
+ /* Inside a hole */
+ if ( pt_in_ring_2d(p, poly->rings[i]) ) return 0;
+ }
+
+ return 1; /* In outer ring, not in holes */
+}
+
+/*
+ * Brute force.
+ * Test line-ring distance against each ring.
+ * If there's an intersection (distance==0) then return 0 (crosses boundary).
+ * Otherwise, test to see if any point is inside outer rings of polygon,
+ * but not in inner rings.
+ * If so, return 0 (line inside polygon),
+ * otherwise return min distance to a ring (could be outside
+ * polygon or inside a hole)
+ */
+double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly)
+{
+ POINT2D pt;
+ int i;
+ double mindist = 0;
+
+ LWDEBUGF(2, "distance2d_ptarray_poly called (%d rings)", poly->nrings);
+
+ for (i=0; i<poly->nrings; i++)
+ {
+ double dist = distance2d_ptarray_ptarray(pa, poly->rings[i]);
+ if (i) mindist = LW_MIN(mindist, dist);
+ else mindist = dist;
+
+ LWDEBUGF(3, " distance from ring %d: %f, mindist: %f",
+ i, dist, mindist);
+
+ if ( mindist <= 0 ) return 0.0; /* intersection */
+ }
+
+ /*
+ * No intersection, have to check if a point is
+ * inside polygon
+ */
+ getPoint2d_p(pa, 0, &pt);
+
+ /*
+ * Outside outer ring, so min distance to a ring
+ * is the actual min distance
+ */
+ if ( ! pt_in_ring_2d(&pt, poly->rings[0]) ) return mindist;
+
+
+ /*
+ * Its in the outer ring.
+ * Have to check if its inside a hole
+ */
+ for (i=1; i<poly->nrings; i++)
+ {
+ if ( pt_in_ring_2d(&pt, poly->rings[i]) )
+ {
+ /*
+ * Its inside a hole, then the actual
+ * distance is the min ring distance
+ */
+ return mindist;
+ }
+ }
+
+ return 0.0; /* Not in hole, so inside polygon */
+}
+
+double distance2d_point_point(LWPOINT *point1, LWPOINT *point2)
+{
+ POINT2D p1;
+ POINT2D p2;
+
+ getPoint2d_p(point1->point, 0, &p1);
+ getPoint2d_p(point2->point, 0, &p2);
+
+ return distance2d_pt_pt(&p1, &p2);
+}
+
+double distance2d_point_line(LWPOINT *point, LWLINE *line)
+{
+ POINT2D p;
+ POINTARRAY *pa = line->points;
+ getPoint2d_p(point->point, 0, &p);
+ return distance2d_pt_ptarray(&p, pa);
+}
+
+double distance2d_line_line(LWLINE *line1, LWLINE *line2)
+{
+ POINTARRAY *pa1 = line1->points;
+ POINTARRAY *pa2 = line2->points;
+ return distance2d_ptarray_ptarray(pa1, pa2);
+}
+
+/*
+ * 1. see if pt in outer boundary. if no, then treat the outer ring like a line
+ * 2. if in the boundary, test to see if its in a hole.
+ * if so, then return dist to hole, else return 0 (point in polygon)
+ */
+double distance2d_point_poly(LWPOINT *point, LWPOLY *poly)
+{
+ POINT2D p;
+ int i;
+
+ getPoint2d_p(point->point, 0, &p);
+
+ LWDEBUG(2, "distance2d_point_poly called");
+
+ /* Return distance to outer ring if not inside it */
+ if ( ! pt_in_ring_2d(&p, poly->rings[0]) )
+ {
+ LWDEBUG(3, " not inside outer-ring");
+
+ return distance2d_pt_ptarray(&p, poly->rings[0]);
+ }
+
+ /*
+ * Inside the outer ring.
+ * Scan though each of the inner rings looking to
+ * see if its inside. If not, distance==0.
+ * Otherwise, distance = pt to ring distance
+ */
+ for (i=1; i<poly->nrings; i++)
+ {
+ /* Inside a hole. Distance = pt -> ring */
+ if ( pt_in_ring_2d(&p, poly->rings[i]) )
+ {
+ LWDEBUG(3, " inside an hole");
+
+ return distance2d_pt_ptarray(&p, poly->rings[i]);
+ }
+ }
+
+ LWDEBUG(3, " inside the polygon");
+
+ return 0.0; /* Is inside the polygon */
+}
+
+/*
+ * Brute force.
+ * Test to see if any rings intersect.
+ * If yes, dist=0.
+ * Test to see if one inside the other and if they are inside holes.
+ * Find min distance ring-to-ring.
+ */
+double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2)
+{
+ POINT2D pt;
+ double mindist = -1;
+ int i;
+
+ LWDEBUG(2, "distance2d_poly_poly called");
+
+ /* if poly1 inside poly2 return 0 */
+ getPoint2d_p(poly1->rings[0], 0, &pt);
+ if ( pt_in_poly_2d(&pt, poly2) ) return 0.0;
+
+ /* if poly2 inside poly1 return 0 */
+ getPoint2d_p(poly2->rings[0], 0, &pt);
+ if ( pt_in_poly_2d(&pt, poly1) ) return 0.0;
+
+ LWDEBUG(3, " polys not inside each other");
+
+ /*
+ * foreach ring in Poly1
+ * foreach ring in Poly2
+ * if intersect, return 0
+ */
+ for (i=0; i<poly1->nrings; i++)
+ {
+ int j;
+ for (j=0; j<poly2->nrings; j++)
+ {
+ double d = distance2d_ptarray_ptarray(poly1->rings[i],
+ poly2->rings[j]);
+ if ( d <= 0 ) return 0.0;
+
+ /* mindist is -1 when not yet set */
+ if (mindist > -1) mindist = LW_MIN(mindist, d);
+ else mindist = d;
+
+ LWDEBUGF(3, " ring%i-%i dist: %f, mindist: %f", i, j, d, mindist);
+ }
+
+ }
+
+ /* otherwise return closest approach of rings (no intersection) */
+ return mindist;
+
+}
+
+double distance2d_line_poly(LWLINE *line, LWPOLY *poly)
+{
+ return distance2d_ptarray_poly(line->points, poly);
+}
+
+
+/*find the 2d length of the given POINTARRAY (even if it's 3d) */
+double lwgeom_pointarray_length2d(POINTARRAY *pts)
+{
+ double dist = 0.0;
+ int i;
+ POINT2D frm;
+ POINT2D to;
+
+ if ( pts->npoints < 2 ) return 0.0;
+ for (i=0; i<pts->npoints-1;i++)
+ {
+ getPoint2d_p(pts, i, &frm);
+ getPoint2d_p(pts, i+1, &to);
+ dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) ) +
+ ((frm.y - to.y)*(frm.y - to.y) ) );
+ }
+ return dist;
+}
+
+/*
+ * Find the 3d/2d length of the given POINTARRAY
+ * (depending on its dimensions)
+ */
+double
+lwgeom_pointarray_length(POINTARRAY *pts)
+{
+ double dist = 0.0;
+ int i;
+ POINT3DZ frm;
+ POINT3DZ to;
+
+ if ( pts->npoints < 2 ) return 0.0;
+
+ /* compute 2d length if 3d is not available */
+ if ( ! TYPE_HASZ(pts->dims) ) return lwgeom_pointarray_length2d(pts);
+
+ for (i=0; i<pts->npoints-1;i++)
+ {
+ getPoint3dz_p(pts, i, &frm);
+ getPoint3dz_p(pts, i+1, &to);
+ dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) ) +
+ ((frm.y - to.y)*(frm.y - to.y) ) +
+ ((frm.z - to.z)*(frm.z - to.z) ) );
+ }
+
+ return dist;
+}
+
+/*
+ * This should be rewritten to make use of the curve itself.
+ */
+double
+lwgeom_curvepolygon_area(LWCURVEPOLY *curvepoly)
+{
+ LWPOLY *poly = (LWPOLY *)lwgeom_segmentize((LWGEOM *)curvepoly, 32);
+ return lwgeom_polygon_area(poly);
+}
+
+/*
+ * Find the area of the outer ring - sum (area of inner rings).
+ * Could use a more numerically stable calculator...
+ */
+double
+lwgeom_polygon_area(LWPOLY *poly)
+{
+ double poly_area=0.0;
+ int i;
+ POINT2D p1;
+ POINT2D p2;
+
+ LWDEBUGF(2, "in lwgeom_polygon_area (%d rings)", poly->nrings);
+
+ for (i=0; i<poly->nrings; i++)
+ {
+ int j;
+ POINTARRAY *ring = poly->rings[i];
+ double ringarea = 0.0;
+
+ LWDEBUGF(4, " rings %d has %d points", i, ring->npoints);
+
+ for (j=0; j<ring->npoints-1; j++)
+ {
+ getPoint2d_p(ring, j, &p1);
+ getPoint2d_p(ring, j+1, &p2);
+ ringarea += ( p1.x * p2.y ) - ( p1.y * p2.x );
+ }
+
+ ringarea /= 2.0;
+
+ LWDEBUGF(4, " ring 1 has area %lf",ringarea);
+
+ ringarea = fabs(ringarea);
+ if (i != 0) /*outer */
+ ringarea = -1.0*ringarea ; /* its a hole */
+
+ poly_area += ringarea;
+ }
+
+ return poly_area;
+}
+
+/*
+ * Compute the sum of polygon rings length.
+ * Could use a more numerically stable calculator...
+ */
+double lwgeom_polygon_perimeter(LWPOLY *poly)
+{
+ double result=0.0;
+ int i;
+
+ LWDEBUGF(2, "in lwgeom_polygon_perimeter (%d rings)", poly->nrings);
+
+ for (i=0; i<poly->nrings; i++)
+ result += lwgeom_pointarray_length(poly->rings[i]);
+
+ return result;
+}
+
+/*
+ * Compute the sum of polygon rings length (forcing 2d computation).
+ * Could use a more numerically stable calculator...
+ */
+double lwgeom_polygon_perimeter2d(LWPOLY *poly)
+{
+ double result=0.0;
+ int i;
+
+ LWDEBUGF(2, "in lwgeom_polygon_perimeter (%d rings)", poly->nrings);
+
+ for (i=0; i<poly->nrings; i++)
+ result += lwgeom_pointarray_length2d(poly->rings[i]);
+
+ return result;
+}
+
+double
+lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2)
+{
+ return lwgeom_mindistance2d_recursive_tolerance( lw1, lw2, 0.0 );
+}
+
+double
+lwgeom_mindistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance)
+{
+ LWGEOM_INSPECTED *in1, *in2;
+ int i, j;
+ double mindist = -1;
+
+ in1 = lwgeom_inspect(lw1);
+ in2 = lwgeom_inspect(lw2);
+
+ for (i=0; i<in1->ngeometries; i++)
+ {
+ uchar *g1 = lwgeom_getsubgeometry_inspected(in1, i);
+ int t1 = lwgeom_getType(g1[0]);
+ double dist=tolerance;
+
+ /* it's a multitype... recurse */
+ if ( t1 >= 4 )
+ {
+ dist = lwgeom_mindistance2d_recursive_tolerance(g1, lw2, tolerance);
+ if ( dist <= tolerance ) return tolerance; /* can't be closer */
+ if ( mindist == -1 ) mindist = dist;
+ else mindist = LW_MIN(dist, mindist);
+ continue;
+ }
+
+ for (j=0; j<in2->ngeometries; j++)
+ {
+ uchar *g2 = lwgeom_getsubgeometry_inspected(in2, j);
+ int t2 = lwgeom_getType(g2[0]);
+
+ if ( t1 == POINTTYPE )
+ {
+ if ( t2 == POINTTYPE )
+ {
+ dist = distance2d_point_point(
+ lwpoint_deserialize(g1),
+ lwpoint_deserialize(g2)
+ );
+ }
+ else if ( t2 == LINETYPE )
+ {
+ dist = distance2d_point_line(
+ lwpoint_deserialize(g1),
+ lwline_deserialize(g2)
+ );
+ }
+ else if ( t2 == POLYGONTYPE )
+ {
+ dist = distance2d_point_poly(
+ lwpoint_deserialize(g1),
+ lwpoly_deserialize(g2)
+ );
+ }
+ }
+ else if ( t1 == LINETYPE )
+ {
+ if ( t2 == POINTTYPE )
+ {
+ dist = distance2d_point_line(
+ lwpoint_deserialize(g2),
+ lwline_deserialize(g1)
+ );
+ }
+ else if ( t2 == LINETYPE )
+ {
+ dist = distance2d_line_line(
+ lwline_deserialize(g1),
+ lwline_deserialize(g2)
+ );
+ }
+ else if ( t2 == POLYGONTYPE )
+ {
+ dist = distance2d_line_poly(
+ lwline_deserialize(g1),
+ lwpoly_deserialize(g2)
+ );
+ }
+ }
+ else if ( t1 == POLYGONTYPE )
+ {
+ if ( t2 == POLYGONTYPE )
+ {
+ dist = distance2d_poly_poly(
+ lwpoly_deserialize(g2),
+ lwpoly_deserialize(g1)
+ );
+ }
+ else if ( t2 == POINTTYPE )
+ {
+ dist = distance2d_point_poly(
+ lwpoint_deserialize(g2),
+ lwpoly_deserialize(g1)
+ );
+ }
+ else if ( t2 == LINETYPE )
+ {
+ dist = distance2d_line_poly(
+ lwline_deserialize(g2),
+ lwpoly_deserialize(g1)
+ );
+ }
+ }
+ else /* it's a multitype... recurse */
+ {
+ dist = lwgeom_mindistance2d_recursive_tolerance(g1, g2, tolerance);
+ }
+
+ if (mindist == -1 ) mindist = dist;
+ else mindist = LW_MIN(dist, mindist);
+
+ LWDEBUGF(3, "dist %d-%d: %f - mindist: %f",
+ i, j, dist, mindist);
+
+
+ if (mindist <= tolerance) return tolerance; /* can't be closer */
+
+ }
+
+ }
+
+ if (mindist<0) mindist = 0;
+
+ return mindist;
+}
+
+
+
+int
+lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad)
+{
+ POINT2D center;
+
+ center.x = cx;
+ center.y = cy;
+
+ if ( distance2d_pt_pt(p, ¢er) < rad ) return 1;
+ else return 0;
+
+}
+
+/*
+ * Compute the azimuth of segment AB in radians.
+ * Return 0 on exception (same point), 1 otherwise.
+ */
+int
+azimuth_pt_pt(POINT2D *A, POINT2D *B, double *d)
+{
+ if ( A->x == B->x )
+ {
+ if ( A->y < B->y ) *d=0.0;
+ else if ( A->y > B->y ) *d=M_PI;
+ else return 0;
+ return 1;
+ }
+
+ if ( A->y == B->y )
+ {
+ if ( A->x < B->x ) *d=M_PI/2;
+ else if ( A->x > B->x ) *d=M_PI+(M_PI/2);
+ else return 0;
+ return 1;
+ }
+
+ if ( A->x < B->x )
+ {
+ if ( A->y < B->y )
+ {
+ *d=atan(fabs(A->x - B->x) / fabs(A->y - B->y) );
+ }
+ else /* ( A->y > B->y ) - equality case handled above */
+ {
+ *d=atan(fabs(A->y - B->y) / fabs(A->x - B->x) )
+ + (M_PI/2);
+ }
+ }
+
+ else /* ( A->x > B->x ) - equality case handled above */
+ {
+ if ( A->y > B->y )
+ {
+ *d=atan(fabs(A->x - B->x) / fabs(A->y - B->y) )
+ + M_PI;
+ }
+ else /* ( A->y < B->y ) - equality case handled above */
+ {
+ *d=atan(fabs(A->y - B->y) / fabs(A->x - B->x) )
+ + (M_PI+(M_PI/2));
+ }
+ }
+
+ return 1;
+}
+
Added: trunk/liblwgeom/ptarray.c
===================================================================
--- trunk/liblwgeom/ptarray.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/ptarray.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,836 @@
+/**********************************************************************
+ * $Id: ptarray.c 2797 2008-05-31 09:56:44Z mcayland $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2006 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "liblwgeom.h"
+
+
+POINTARRAY *
+ptarray_construct(char hasz, char hasm, unsigned int npoints)
+{
+ uchar dims = 0;
+ size_t size;
+ uchar *ptlist;
+ POINTARRAY *pa;
+
+ TYPE_SETZM(dims, hasz?1:0, hasm?1:0);
+ size = TYPE_NDIMS(dims)*npoints*sizeof(double);
+
+ ptlist = (uchar *)lwalloc(size);
+ pa = lwalloc(sizeof(POINTARRAY));
+ pa->dims = dims;
+ pa->serialized_pointlist = ptlist;
+ pa->npoints = npoints;
+
+ return pa;
+
+}
+
+void
+ptarray_reverse(POINTARRAY *pa)
+{
+ POINT4D pbuf;
+ uint32 i;
+ int ptsize = pointArray_ptsize(pa);
+ int last = pa->npoints-1;
+ int mid = last/2;
+
+ for (i=0; i<=mid; i++)
+ {
+ uchar *from, *to;
+ from = getPoint_internal(pa, i);
+ to = getPoint_internal(pa, (last-i));
+ memcpy((uchar *)&pbuf, to, ptsize);
+ memcpy(to, from, ptsize);
+ memcpy(from, (uchar *)&pbuf, ptsize);
+ }
+
+}
+
+/*
+ * calculate the 2d bounding box of a set of points
+ * write result to the provided BOX2DFLOAT4
+ * Return 0 if bounding box is NULL (empty geom)
+ */
+int
+ptarray_compute_box2d_p(const POINTARRAY *pa, BOX2DFLOAT4 *result)
+{
+ int t;
+ POINT2D pt;
+ BOX3D box;
+
+ if (pa->npoints == 0) return 0;
+
+ getPoint2d_p(pa, 0, &pt);
+
+ box.xmin = pt.x;
+ box.xmax = pt.x;
+ box.ymin = pt.y;
+ box.ymax = pt.y;
+
+ for (t=1; t<pa->npoints; t++)
+ {
+ getPoint2d_p(pa, t, &pt);
+ if (pt.x < box.xmin) box.xmin = pt.x;
+ if (pt.y < box.ymin) box.ymin = pt.y;
+ if (pt.x > box.xmax) box.xmax = pt.x;
+ if (pt.y > box.ymax) box.ymax = pt.y;
+ }
+
+ box3d_to_box2df_p(&box, result);
+
+ return 1;
+}
+
+/*
+ * Calculate the 2d bounding box of a set of points.
+ * Return allocated BOX2DFLOAT4 or NULL (for empty array).
+ */
+BOX2DFLOAT4 *
+ptarray_compute_box2d(const POINTARRAY *pa)
+{
+ int t;
+ POINT2D pt;
+ BOX2DFLOAT4 *result;
+
+ if (pa->npoints == 0) return NULL;
+
+ result = lwalloc(sizeof(BOX2DFLOAT4));
+
+ getPoint2d_p(pa, 0, &pt);
+
+ result->xmin = pt.x;
+ result->xmax = pt.x;
+ result->ymin = pt.y;
+ result->ymax = pt.y;
+
+ for (t=1;t<pa->npoints;t++)
+ {
+ getPoint2d_p(pa, t, &pt);
+ if (pt.x < result->xmin) result->xmin = pt.x;
+ if (pt.y < result->ymin) result->ymin = pt.y;
+ if (pt.x > result->xmax) result->xmax = pt.x;
+ if (pt.y > result->ymax) result->ymax = pt.y;
+ }
+
+ return result;
+}
+
+/*
+ * Returns a modified POINTARRAY so that no segment is
+ * longer then the given distance (computed using 2d).
+ * Every input point is kept.
+ * Z and M values for added points (if needed) are set to 0.
+ */
+POINTARRAY *
+ptarray_segmentize2d(POINTARRAY *ipa, double dist)
+{
+ double segdist;
+ POINT4D p1, p2;
+ void *ip, *op;
+ POINT4D pbuf;
+ POINTARRAY *opa;
+ int maxpoints = ipa->npoints;
+ int ptsize = pointArray_ptsize(ipa);
+ int ipoff=0; /* input point offset */
+
+ pbuf.x = pbuf.y = pbuf.z = pbuf.m = 0;
+
+ /* Initial storage */
+ opa = (POINTARRAY *)lwalloc(ptsize * maxpoints);
+ opa->dims = ipa->dims;
+ opa->npoints = 0;
+ opa->serialized_pointlist = (uchar *)lwalloc(maxpoints*ptsize);
+
+ /* Add first point */
+ opa->npoints++;
+ getPoint4d_p(ipa, ipoff, &p1);
+ op = getPoint_internal(opa, opa->npoints-1);
+ memcpy(op, &p1, ptsize);
+ ipoff++;
+
+ while (ipoff<ipa->npoints)
+ {
+ /*
+ * We use these pointers to avoid
+ * "strict-aliasing rules break" warning raised
+ * by gcc (3.3 and up).
+ *
+ * It looks that casting a variable address (also
+ * referred to as "type-punned pointer")
+ * breaks those "strict" rules.
+ *
+ */
+ POINT4D *p1ptr=&p1, *p2ptr=&p2;
+
+ getPoint4d_p(ipa, ipoff, &p2);
+
+ segdist = distance2d_pt_pt((POINT2D *)p1ptr, (POINT2D *)p2ptr);
+
+ if (segdist > dist) /* add an intermediate point */
+ {
+ pbuf.x = p1.x + (p2.x-p1.x)/segdist * dist;
+ pbuf.y = p1.y + (p2.y-p1.y)/segdist * dist;
+ /* might also compute z and m if available... */
+ ip = &pbuf;
+ memcpy(&p1, ip, ptsize);
+ }
+ else /* copy second point */
+ {
+ ip = &p2;
+ p1 = p2;
+ ipoff++;
+ }
+
+ /* Add point */
+ if ( ++(opa->npoints) > maxpoints ) {
+ maxpoints *= 1.5;
+ opa->serialized_pointlist = (uchar *)lwrealloc(
+ opa->serialized_pointlist,
+ maxpoints*ptsize
+ );
+ }
+ op = getPoint_internal(opa, opa->npoints-1);
+ memcpy(op, ip, ptsize);
+ }
+
+ return opa;
+}
+
+char
+ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
+{
+ unsigned int i;
+ size_t ptsize;
+
+ if ( TYPE_GETZM(pa1->dims) != TYPE_GETZM(pa2->dims) ) return 0;
+
+ if ( pa1->npoints != pa2->npoints ) return 0;
+
+ ptsize = pointArray_ptsize(pa1);
+
+ for (i=0; i<pa1->npoints; i++)
+ {
+ if ( memcmp(getPoint_internal(pa1, i), getPoint_internal(pa2, i), ptsize) )
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Add a point in a pointarray.
+ * 'where' is the offset (starting at 0)
+ * if 'where' == -1 append is required.
+ */
+POINTARRAY *
+ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims, unsigned int where)
+{
+ POINTARRAY *ret;
+ POINT4D pbuf;
+ size_t ptsize = pointArray_ptsize(pa);
+
+ LWDEBUGF(3, "pa %x p %x size %d where %d",
+ pa, p, pdims, where);
+
+ if ( pdims < 2 || pdims > 4 )
+ {
+ lwerror("ptarray_addPoint: point dimension out of range (%d)",
+ pdims);
+ return NULL;
+ }
+
+ if ( where > pa->npoints )
+ {
+ lwerror("ptarray_addPoint: offset out of range (%d)",
+ where);
+ return NULL;
+ }
+
+ LWDEBUG(3, "called with a %dD point");
+
+ pbuf.x = pbuf.y = pbuf.z = pbuf.m = 0.0;
+ memcpy((uchar *)&pbuf, p, pdims*sizeof(double));
+
+ LWDEBUG(3, "initialized point buffer");
+
+ ret = ptarray_construct(TYPE_HASZ(pa->dims),
+ TYPE_HASM(pa->dims), pa->npoints+1);
+
+ if ( where == -1 ) where = pa->npoints;
+
+ if ( where )
+ {
+ memcpy(getPoint_internal(ret, 0), getPoint_internal(pa, 0), ptsize*where);
+ }
+
+ memcpy(getPoint_internal(ret, where), (uchar *)&pbuf, ptsize);
+
+ if ( where+1 != ret->npoints )
+ {
+ memcpy(getPoint_internal(ret, where+1),
+ getPoint_internal(pa, where),
+ ptsize*(pa->npoints-where));
+ }
+
+ return ret;
+}
+
+/*
+ * Remove a point from a pointarray.
+ * 'which' is the offset (starting at 0)
+ * Returned pointarray is newly allocated
+ */
+POINTARRAY *
+ptarray_removePoint(POINTARRAY *pa, unsigned int which)
+{
+ POINTARRAY *ret;
+ size_t ptsize = pointArray_ptsize(pa);
+
+ LWDEBUGF(3, "pa %x which %d", pa, which);
+
+#if PARANOIA_LEVEL > 0
+ if ( which > pa->npoints-1 )
+ {
+ lwerror("ptarray_removePoint: offset (%d) out of range (%d..%d)",
+ which, 0, pa->npoints-1);
+ return NULL;
+ }
+
+ if ( pa->npoints < 3 )
+ {
+ lwerror("ptarray_removePointe: can't remove a point from a 2-vertex POINTARRAY");
+ }
+#endif
+
+ ret = ptarray_construct(TYPE_HASZ(pa->dims),
+ TYPE_HASM(pa->dims), pa->npoints-1);
+
+ /* copy initial part */
+ if ( which )
+ {
+ memcpy(getPoint_internal(ret, 0), getPoint_internal(pa, 0), ptsize*which);
+ }
+
+ /* copy final part */
+ if ( which < pa->npoints-1 )
+ {
+ memcpy(getPoint_internal(ret, which), getPoint_internal(pa, which+1),
+ ptsize*(pa->npoints-which-1));
+ }
+
+ return ret;
+}
+
+/*
+ * Clone a pointarray
+ */
+POINTARRAY *
+ptarray_clone(const POINTARRAY *in)
+{
+ POINTARRAY *out = lwalloc(sizeof(POINTARRAY));
+ size_t size;
+
+ LWDEBUG(3, "ptarray_clone called.");
+
+ out->dims = in->dims;
+ out->npoints = in->npoints;
+
+ size = in->npoints*sizeof(double)*TYPE_NDIMS(in->dims);
+ out->serialized_pointlist = lwalloc(size);
+ memcpy(out->serialized_pointlist, in->serialized_pointlist, size);
+
+ return out;
+}
+
+int
+ptarray_isclosed2d(const POINTARRAY *in)
+{
+ if ( memcmp(getPoint_internal(in, 0), getPoint_internal(in, in->npoints-1), sizeof(POINT2D)) ) return 0;
+ return 1;
+}
+
+/*
+ * calculate the BOX3D bounding box of a set of points
+ * returns a lwalloced BOX3D, or NULL on empty array.
+ * zmin/zmax values are set to NO_Z_VALUE if not available.
+ */
+BOX3D *
+ptarray_compute_box3d(const POINTARRAY *pa)
+{
+ BOX3D *result = lwalloc(sizeof(BOX3D));
+
+ if ( ! ptarray_compute_box3d_p(pa, result) )
+ {
+ lwfree(result);
+ return NULL;
+ }
+
+ return result;
+}
+
+/*
+ * calculate the BOX3D bounding box of a set of points
+ * zmin/zmax values are set to NO_Z_VALUE if not available.
+ * write result to the provided BOX3D
+ * Return 0 if bounding box is NULL (empty geom)
+ */
+int
+ptarray_compute_box3d_p(const POINTARRAY *pa, BOX3D *result)
+{
+ int t;
+ POINT3DZ pt;
+
+ LWDEBUGF(3, "ptarray_compute_box3d call (array has %d points)", pa->npoints);
+
+ if (pa->npoints == 0) return 0;
+
+ getPoint3dz_p(pa, 0, &pt);
+
+ LWDEBUG(3, "got point 0");
+
+ result->xmin = pt.x;
+ result->xmax = pt.x;
+ result->ymin = pt.y;
+ result->ymax = pt.y;
+
+ if ( TYPE_HASZ(pa->dims) ) {
+ result->zmin = pt.z;
+ result->zmax = pt.z;
+ } else {
+ result->zmin = NO_Z_VALUE;
+ result->zmax = NO_Z_VALUE;
+ }
+
+ LWDEBUGF(3, "scanning other %d points", pa->npoints);
+
+ for (t=1; t<pa->npoints; t++)
+ {
+ getPoint3dz_p(pa,t,&pt);
+ if (pt.x < result->xmin) result->xmin = pt.x;
+ if (pt.y < result->ymin) result->ymin = pt.y;
+ if (pt.x > result->xmax) result->xmax = pt.x;
+ if (pt.y > result->ymax) result->ymax = pt.y;
+
+ if ( TYPE_HASZ(pa->dims) ) {
+ if (pt.z > result->zmax) result->zmax = pt.z;
+ if (pt.z < result->zmin) result->zmin = pt.z;
+ }
+ }
+
+ LWDEBUG(3, "returning box");
+
+ return 1;
+}
+
+/*
+ * TODO: implement point interpolation
+ */
+POINTARRAY *
+ptarray_substring(POINTARRAY *ipa, double from, double to)
+{
+ DYNPTARRAY *dpa;
+ POINTARRAY *opa;
+ POINT4D pt;
+ POINT4D p1, p2;
+ POINT4D *p1ptr=&p1; /* don't break strict-aliasing rule */
+ POINT4D *p2ptr=&p2;
+ int nsegs, i;
+ double length, slength, tlength;
+ int state = 0; /* 0=before, 1=inside */
+
+ /*
+ * Create a dynamic pointarray with an initial capacity
+ * equal to full copy of input points
+ */
+ dpa = dynptarray_create(ipa->npoints, ipa->dims);
+
+ /* Compute total line length */
+ length = lwgeom_pointarray_length2d(ipa);
+
+
+ LWDEBUGF(3, "Total length: %g", length);
+
+
+ /* Get 'from' and 'to' lengths */
+ from = length*from;
+ to = length*to;
+
+
+ LWDEBUGF(3, "From/To: %g/%g", from, to);
+
+
+ tlength = 0;
+ getPoint4d_p(ipa, 0, &p1);
+ nsegs = ipa->npoints - 1;
+ for( i = 0; i < nsegs; i++ )
+ {
+ double dseg;
+
+ getPoint4d_p(ipa, i+1, &p2);
+
+
+ LWDEBUGF(3 ,"Segment %d: (%g,%g,%g,%g)-(%g,%g,%g,%g)",
+ i, p1.x, p1.y, p1.z, p1.m, p2.x, p2.y, p2.z, p2.m);
+
+
+ /* Find the length of this segment */
+ slength = distance2d_pt_pt((POINT2D *)p1ptr, (POINT2D *)p2ptr);
+
+ /*
+ * We are before requested start.
+ */
+ if ( state == 0 ) /* before */
+ {
+
+ LWDEBUG(3, " Before start");
+
+ /*
+ * Didn't reach the 'from' point,
+ * nothing to do
+ */
+ if ( from > tlength + slength ) goto END;
+
+ else if ( from == tlength + slength )
+ {
+
+ LWDEBUG(3, " Second point is our start");
+
+ /*
+ * Second point is our start
+ */
+ dynptarray_addPoint4d(dpa, &p2, 1);
+ state=1; /* we're inside now */
+ goto END;
+ }
+
+ else if ( from == tlength )
+ {
+
+ LWDEBUG(3, " First point is our start");
+
+ /*
+ * First point is our start
+ */
+ dynptarray_addPoint4d(dpa, &p1, 1);
+
+ /*
+ * We're inside now, but will check
+ * 'to' point as well
+ */
+ state=1;
+ }
+
+ else /* tlength < from < tlength+slength */
+ {
+
+ LWDEBUG(3, " Seg contains first point");
+
+ /*
+ * Our start is between first and
+ * second point
+ */
+ dseg = (from - tlength) / slength;
+ interpolate_point4d(&p1, &p2, &pt, dseg);
+
+ dynptarray_addPoint4d(dpa, &pt, 1);
+
+ /*
+ * We're inside now, but will check
+ * 'to' point as well
+ */
+ state=1;
+ }
+ }
+
+ if ( state == 1 ) /* inside */
+ {
+
+ LWDEBUG(3, " Inside");
+
+ /*
+ * Didn't reach the 'end' point,
+ * just copy second point
+ */
+ if ( to > tlength + slength )
+ {
+ dynptarray_addPoint4d(dpa, &p2, 0);
+ goto END;
+ }
+
+ /*
+ * 'to' point is our second point.
+ */
+ else if ( to == tlength + slength )
+ {
+
+ LWDEBUG(3, " Second point is our end");
+
+ dynptarray_addPoint4d(dpa, &p2, 0);
+ break; /* substring complete */
+ }
+
+ /*
+ * 'to' point is our first point.
+ * (should only happen if 'to' is 0)
+ */
+ else if ( to == tlength )
+ {
+
+ LWDEBUG(3, " First point is our end");
+
+ dynptarray_addPoint4d(dpa, &p1, 0);
+
+ break; /* substring complete */
+ }
+
+ /*
+ * 'to' point falls on this segment
+ * Interpolate and break.
+ */
+ else if ( to < tlength + slength )
+ {
+
+ LWDEBUG(3, " Seg contains our end");
+
+ dseg = (to - tlength) / slength;
+ interpolate_point4d(&p1, &p2, &pt, dseg);
+
+ dynptarray_addPoint4d(dpa, &pt, 0);
+
+ break;
+ }
+
+ else
+ {
+ LWDEBUG(3, "Unhandled case");
+ }
+ }
+
+
+ END:
+
+ tlength += slength;
+ memcpy(&p1, &p2, sizeof(POINT4D));
+ }
+
+ /* Get constructed pointarray and release memory associated
+ * with the dynamic pointarray
+ */
+ opa = dpa->pa;
+ lwfree(dpa);
+
+ LWDEBUGF(3, "Out of loop, ptarray has %d points", opa->npoints);
+
+ return opa;
+}
+
+/*
+ * Write into the *ret argument coordinates of the closes point on
+ * the given segment to the reference input point.
+ */
+void
+closest_point_on_segment(POINT2D *p, POINT2D *A, POINT2D *B, POINT2D *ret)
+{
+ double r;
+
+ if ( ( A->x == B->x) && (A->y == B->y) )
+ {
+ *ret = *A;
+ return;
+ }
+
+ /*
+ * We use comp.graphics.algorithms Frequently Asked Questions method
+ *
+ * (1) AC dot AB
+ * r = ----------
+ * ||AB||^2
+ * r has the following meaning:
+ * r=0 P = A
+ * r=1 P = B
+ * r<0 P is on the backward extension of AB
+ * r>1 P is on the forward extension of AB
+ * 0<r<1 P is interior to AB
+ *
+ */
+ r = ( (p->x-A->x) * (B->x-A->x) + (p->y-A->y) * (B->y-A->y) )/( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
+
+ if (r<0) {
+ *ret = *A; return;
+ }
+ if (r>1) {
+ *ret = *B;
+ return;
+ }
+
+ ret->x = A->x + ( (B->x - A->x) * r );
+ ret->y = A->y + ( (B->y - A->y) * r );
+}
+
+/*
+ * Given a point, returns the location of closest point on pointarray
+ */
+double
+ptarray_locate_point(POINTARRAY *pa, POINT2D *p)
+{
+ double mindist=-1;
+ double tlen, plen;
+ int t, seg=-1;
+ POINT2D start, end;
+ POINT2D proj;
+
+ getPoint2d_p(pa, 0, &start);
+ for (t=1; t<pa->npoints; t++)
+ {
+ double dist;
+ getPoint2d_p(pa, t, &end);
+ dist = distance2d_pt_seg(p, &start, &end);
+
+ if (t==1 || dist < mindist ) {
+ mindist = dist;
+ seg=t-1;
+ }
+
+ if ( mindist == 0 ) break;
+
+ start = end;
+ }
+
+ LWDEBUGF(3, "Closest segment: %d", seg);
+
+ /*
+ * If mindist is not 0 we need to project the
+ * point on the closest segment.
+ */
+ if ( mindist > 0 )
+ {
+ getPoint2d_p(pa, seg, &start);
+ getPoint2d_p(pa, seg+1, &end);
+ closest_point_on_segment(p, &start, &end, &proj);
+ } else {
+ proj = *p;
+ }
+
+ LWDEBUGF(3, "Closest point on segment: %g,%g", proj.x, proj.y);
+
+ tlen = lwgeom_pointarray_length2d(pa);
+
+ LWDEBUGF(3, "tlen %g", tlen);
+
+ plen=0;
+ getPoint2d_p(pa, 0, &start);
+ for (t=0; t<seg; t++, start=end)
+ {
+ getPoint2d_p(pa, t+1, &end);
+ plen += distance2d_pt_pt(&start, &end);
+
+ LWDEBUGF(4, "Segment %d made plen %g", t, plen);
+ }
+
+ plen+=distance2d_pt_pt(&proj, &start);
+
+ LWDEBUGF(3, "plen %g, tlen %g", plen, tlen);
+ LWDEBUGF(3, "mindist: %g", mindist);
+
+ return plen/tlen;
+}
+
+/*
+ * Longitude shift for a pointarray.
+ * Y remains the same
+ * X is converted:
+ * from -180..180 to 0..360
+ * from 0..360 to -180..180
+ * X < 0 becomes X + 360
+ * X > 180 becomes X - 360
+ */
+void
+ptarray_longitude_shift(POINTARRAY *pa)
+{
+ int i;
+ double x;
+
+ for (i=0; i<pa->npoints; i++) {
+ memcpy(&x, getPoint_internal(pa, i), sizeof(double));
+ if ( x < 0 ) x+= 360;
+ else if ( x > 180 ) x -= 360;
+ memcpy(getPoint_internal(pa, i), &x, sizeof(double));
+ }
+}
+
+DYNPTARRAY *
+dynptarray_create(size_t initial_capacity, int dims)
+{
+ DYNPTARRAY *ret=lwalloc(sizeof(DYNPTARRAY));
+
+ LWDEBUGF(3, "dynptarray_create called, dims=%d.", dims);
+
+ if ( initial_capacity < 1 ) initial_capacity=1;
+
+ ret->pa=lwalloc(sizeof(POINTARRAY));
+ ret->pa->dims=dims;
+ ret->ptsize=pointArray_ptsize(ret->pa);
+ ret->capacity=initial_capacity;
+ ret->pa->serialized_pointlist=lwalloc(ret->ptsize*ret->capacity);
+ ret->pa->npoints=0;
+
+ return ret;
+}
+
+/*
+ * Add a POINT4D to the dynamic pointarray.
+ *
+ * The dynamic pointarray may be of any dimension, only
+ * accepted dimensions will be copied.
+ *
+ * If allow_duplicates is set to 0 (false) a check
+ * is performed to see if last point in array is equal to the
+ * provided one. NOTE that the check is 4d based, with missing
+ * ordinates in the pointarray set to NO_Z_VALUE and NO_M_VALUE
+ * respectively.
+ */
+int
+dynptarray_addPoint4d(DYNPTARRAY *dpa, POINT4D *p4d, int allow_duplicates)
+{
+ POINTARRAY *pa=dpa->pa;
+ POINT4D tmp;
+
+ LWDEBUG(3, "dynptarray_addPoint4d called.");
+
+ if ( ! allow_duplicates && pa->npoints > 0 )
+ {
+ getPoint4d_p(pa, pa->npoints-1, &tmp);
+
+ /*
+ * return 0 and do nothing else if previous point in list is
+ * equal to this one (4D equality)
+ */
+ if ( ! memcmp(p4d, &tmp, sizeof(POINT4D)) ) return 0;
+ }
+
+ ++pa->npoints;
+ if ( pa->npoints > dpa->capacity )
+ {
+ dpa->capacity*=2;
+ pa->serialized_pointlist = lwrealloc(
+ pa->serialized_pointlist,
+ dpa->capacity*dpa->ptsize);
+ }
+
+ setPoint4d(pa, pa->npoints-1, p4d);
+
+ return 1;
+}
+
Added: trunk/liblwgeom/vsprintf.c
===================================================================
--- trunk/liblwgeom/vsprintf.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/vsprintf.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,162 @@
+/* Like vsprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1994, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include <math.h>
+
+#ifdef TEST
+int global_total_width;
+#endif
+
+static int
+int_vasprintf (result, format, args)
+ char **result;
+ const char *format;
+ va_list *args;
+{
+ const char *p = format;
+ /* Add one to make sure that it is never zero, which might cause malloc
+ to return NULL. */
+ int total_width = strlen (format) + 1;
+ va_list ap;
+
+ memcpy (&ap, args, sizeof (va_list));
+
+ while (*p != '\0')
+ {
+ if (*p++ == '%')
+ {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, (char **) &p, 10);
+ if (*p == '.')
+ {
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, (char **) &p, 10);
+ }
+ while (strchr ("hlLjtz", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s
+ and floats. */
+ total_width += 30;
+ switch (*p)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ (void) va_arg (ap, int);
+ break;
+ case 'f':
+ {
+ double arg = va_arg (ap, double);
+ if (arg >= 1.0 || arg <= -1.0)
+ /* Since an ieee double can have an exponent of 307, we'll
+ make the buffer wide enough to cover the gross case. */
+ total_width += 307;
+ }
+ break;
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ (void) va_arg (ap, double);
+ break;
+ case 's':
+ total_width += strlen (va_arg (ap, char *));
+ break;
+ case 'p':
+ case 'n':
+ (void) va_arg (ap, char *);
+ break;
+ }
+ p++;
+ }
+ }
+#ifdef TEST
+ global_total_width = total_width;
+#endif
+ *result = malloc (total_width);
+ if (*result != NULL)
+ return vsprintf (*result, format, *args);
+ else
+ return 0;
+}
+
+int
+vasprintf (result, format, args)
+ char **result;
+ const char *format;
+ va_list args;
+{
+ return int_vasprintf (result, format, &args);
+}
+
+int
+asprintf
+#if __STDC__
+ (char **result, const char *format, ...)
+#else
+ (result, va_alist)
+ char **result;
+ va_dcl
+#endif
+{
+ va_list args;
+ int done;
+
+#if __STDC__
+ va_start (args, format);
+#else
+ char *format;
+ va_start (args);
+ format = va_arg (args, char *);
+#endif
+ done = vasprintf (result, format, args);
+ va_end (args);
+
+ return done;
+}
Added: trunk/liblwgeom/wktparse.h
===================================================================
--- trunk/liblwgeom/wktparse.h 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/wktparse.h 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,106 @@
+/*
+ * Written by Ralph Mason ralph.mason<at>telogis.com
+ *
+ * Copyright Telogis 2004
+ * www.telogis.com
+ *
+ */
+
+#ifndef _WKTPARSE_H
+#define _WKTPARSE_H
+
+#include <stdlib.h>
+
+
+#ifndef _LIBLWGEOM_H
+typedef unsigned char uchar;
+
+typedef struct serialized_lwgeom {
+ uchar *lwgeom;
+ int size;
+} SERIALIZED_LWGEOM;
+#endif
+typedef void* (*allocator)(size_t size);
+typedef void (*freeor)(void* mem);
+typedef void (*report_error)(const char* string, ...);
+
+/*typedef unsigned long int4;*/
+
+/* How much memory is allocated at a time(bytes) for tuples */
+#define ALLOC_CHUNKS 8192
+
+/* to shrink ints less than 0x7f to 1 byte */
+/* #define SHRINK_INTS */
+
+#define POINTTYPE 1
+#define LINETYPE 2
+#define POLYGONTYPE 3
+#define MULTIPOINTTYPE 4
+#define MULTILINETYPE 5
+#define MULTIPOLYGONTYPE 6
+#define COLLECTIONTYPE 7
+
+/* Extended lwgeom integer types */
+#define POINTTYPEI 10
+#define LINETYPEI 11
+#define POLYGONTYPEI 12
+
+#define CURVETYPE 8
+#define COMPOUNDTYPE 9
+#define CURVEPOLYTYPE 13
+#define MULTICURVETYPE 14
+#define MULTISURFACETYPE 15
+
+extern int srid;
+
+/*
+
+ These functions are used by the
+ generated parser and are not meant
+ for public use
+
+*/
+
+void set_srid(double srid);
+void alloc_lwgeom(int srid);
+
+void alloc_point_2d(double x,double y);
+void alloc_point_3d(double x,double y,double z);
+void alloc_point_4d(double x,double y,double z,double m);
+
+void alloc_point(void);
+void alloc_linestring(void);
+void alloc_linestring_closed(void);
+void alloc_circularstring(void);
+void alloc_circularstring_closed(void);
+void alloc_polygon(void);
+void alloc_compoundcurve(void);
+void alloc_curvepolygon(void);
+void alloc_multipoint(void);
+void alloc_multilinestring(void);
+void alloc_multicurve(void);
+void alloc_multipolygon(void);
+void alloc_multisurface(void);
+void alloc_geomertycollection(void);
+void alloc_empty();
+void alloc_counter(void);
+
+
+void pop(void);
+void popc(void);
+
+void alloc_wkb(const char* parser);
+
+/*
+ Use these functions to parse and unparse lwgeoms
+ You are responsible for freeing the returned memory.
+*/
+
+SERIALIZED_LWGEOM* parse_lwg(const char* wkt,allocator allocfunc,report_error errfunc);
+SERIALIZED_LWGEOM* parse_lwgi(const char* wkt,allocator allocfunc,report_error errfunc);
+char* unparse_WKT(uchar* serialized, allocator alloc,freeor free);
+char* unparse_WKB(uchar* serialized, allocator alloc,freeor free, char endian, size_t *outsize, uchar hexform);
+int lwg_parse_yyparse(void);
+int lwg_parse_yyerror(char* s);
+
+#endif /* _WKTPARSE_H */
Added: trunk/liblwgeom/wktparse.lex
===================================================================
--- trunk/liblwgeom/wktparse.lex 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/wktparse.lex 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,71 @@
+/*
+ * Written by Ralph Mason ralph.mason<at>telogis.com
+ *
+ * Copyright Telogis 2004
+ * www.telogis.com
+ *
+ */
+
+%x vals_ok
+%{
+#include "wktparse.tab.h"
+#include <unistd.h>
+#include <stdlib.h> // need stdlib for atof() definition
+
+void init_parser(const char *src);
+void close_parser(void);
+int lwg_parse_yywrap(void);
+int lwg_parse_yylex(void);
+
+static YY_BUFFER_STATE buf_state;
+ void init_parser(const char *src) { BEGIN(0);buf_state = lwg_parse_yy_scan_string(src); }
+ void close_parser() { lwg_parse_yy_delete_buffer(buf_state); }
+ int lwg_parse_yywrap(void){ return 1; }
+
+%}
+
+%%
+
+<vals_ok>[-|\+]?[0-9]+(\.[0-9]+)?([Ee](\+|-)?[0-9]+)? { lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
+<vals_ok>[-|\+]?(\.[0-9]+)([Ee](\+|-)?[0-9]+)? { lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
+
+<INITIAL>00[0-9A-F]* { lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
+<INITIAL>01[0-9A-F]* { lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
+
+<*>POINT { return POINT; }
+<*>POINTM { return POINTM; }
+<*>LINESTRING { return LINESTRING; }
+<*>LINESTRINGM { return LINESTRINGM; }
+<*>CIRCULARSTRING { return CIRCULARSTRING; }
+<*>CIRCULARSTRINGM { return CIRCULARSTRINGM; }
+<*>POLYGON { return POLYGON; }
+<*>POLYGONM { return POLYGONM; }
+<*>COMPOUNDCURVE { return COMPOUNDCURVE; }
+<*>COMPOUNDCURVEM { return COMPOUNDCURVEM; }
+<*>CURVEPOLYGON { return CURVEPOLYGON; }
+<*>CURVEPOLYGONM { return CURVEPOLYGONM; }
+<*>MULTIPOINT { return MULTIPOINT; }
+<*>MULTIPOINTM { return MULTIPOINTM; }
+<*>MULTILINESTRING { return MULTILINESTRING; }
+<*>MULTILINESTRINGM { return MULTILINESTRINGM; }
+<*>MULTICURVE { return MULTICURVE; }
+<*>MULTICURVEM { return MULTICURVEM; }
+<*>MULTIPOLYGON { return MULTIPOLYGON; }
+<*>MULTIPOLYGONM { return MULTIPOLYGONM; }
+<*>MULTISURFACE { return MULTISURFACE; }
+<*>MULTISURFACEM { return MULTISURFACEM; }
+<*>GEOMETRYCOLLECTION { return GEOMETRYCOLLECTION; }
+<*>GEOMETRYCOLLECTIONM { return GEOMETRYCOLLECTIONM; }
+<*>SRID { BEGIN(vals_ok); return SRID; }
+<*>EMPTY { return EMPTY; }
+
+<*>\( { BEGIN(vals_ok); return LPAREN; }
+<*>\) { return RPAREN; }
+<*>, { return COMMA ; }
+<*>= { return EQUALS ; }
+<*>; { BEGIN(0); return SEMICOLON; }
+<*>[ \t\n\r]+ /*eat whitespace*/
+<*>. { return lwg_parse_yytext[0]; }
+
+%%
+
Added: trunk/liblwgeom/wktparse.tab.c
===================================================================
--- trunk/liblwgeom/wktparse.tab.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/wktparse.tab.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,1991 @@
+/* A Bison parser, made by GNU Bison 1.875c. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse lwg_parse_yyparse
+#define yylex lwg_parse_yylex
+#define yyerror lwg_parse_yyerror
+#define yylval lwg_parse_yylval
+#define yychar lwg_parse_yychar
+#define yydebug lwg_parse_yydebug
+#define yynerrs lwg_parse_yynerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ POINT = 258,
+ LINESTRING = 259,
+ POLYGON = 260,
+ MULTIPOINT = 261,
+ MULTILINESTRING = 262,
+ MULTIPOLYGON = 263,
+ GEOMETRYCOLLECTION = 264,
+ CIRCULARSTRING = 265,
+ COMPOUNDCURVE = 266,
+ CURVEPOLYGON = 267,
+ MULTICURVE = 268,
+ MULTISURFACE = 269,
+ POINTM = 270,
+ LINESTRINGM = 271,
+ POLYGONM = 272,
+ MULTIPOINTM = 273,
+ MULTILINESTRINGM = 274,
+ MULTIPOLYGONM = 275,
+ GEOMETRYCOLLECTIONM = 276,
+ CIRCULARSTRINGM = 277,
+ COMPOUNDCURVEM = 278,
+ CURVEPOLYGONM = 279,
+ MULTICURVEM = 280,
+ MULTISURFACEM = 281,
+ SRID = 282,
+ EMPTY = 283,
+ VALUE = 284,
+ LPAREN = 285,
+ RPAREN = 286,
+ COMMA = 287,
+ EQUALS = 288,
+ SEMICOLON = 289,
+ WKB = 290
+ };
+#endif
+#define POINT 258
+#define LINESTRING 259
+#define POLYGON 260
+#define MULTIPOINT 261
+#define MULTILINESTRING 262
+#define MULTIPOLYGON 263
+#define GEOMETRYCOLLECTION 264
+#define CIRCULARSTRING 265
+#define COMPOUNDCURVE 266
+#define CURVEPOLYGON 267
+#define MULTICURVE 268
+#define MULTISURFACE 269
+#define POINTM 270
+#define LINESTRINGM 271
+#define POLYGONM 272
+#define MULTIPOINTM 273
+#define MULTILINESTRINGM 274
+#define MULTIPOLYGONM 275
+#define GEOMETRYCOLLECTIONM 276
+#define CIRCULARSTRINGM 277
+#define COMPOUNDCURVEM 278
+#define CURVEPOLYGONM 279
+#define MULTICURVEM 280
+#define MULTISURFACEM 281
+#define SRID 282
+#define EMPTY 283
+#define VALUE 284
+#define LPAREN 285
+#define RPAREN 286
+#define COMMA 287
+#define EQUALS 288
+#define SEMICOLON 289
+#define WKB 290
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 9 "wktparse.y"
+
+#include "wktparse.h"
+#include <unistd.h>
+#include <stdio.h>
+
+void set_zm(char z, char m);
+int lwg_parse_yylex(void);
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 20 "wktparse.y"
+typedef union YYSTYPE {
+ double value;
+ const char* wkb;
+} YYSTYPE;
+/* Line 191 of yacc.c. */
+#line 169 "y.tab.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 214 of yacc.c. */
+#line 181 "y.tab.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# endif
+# else
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined (__GNUC__) && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 6
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 180
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 36
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 107
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 169
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 237
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 290
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short yyprhs[] =
+{
+ 0, 0, 3, 4, 9, 10, 13, 15, 17, 19,
+ 21, 23, 25, 27, 29, 31, 33, 35, 37, 39,
+ 43, 45, 48, 49, 53, 55, 57, 58, 61, 62,
+ 65, 69, 70, 74, 75, 79, 81, 82, 87, 89,
+ 93, 95, 96, 99, 102, 103, 107, 109, 111, 112,
+ 115, 116, 119, 120, 123, 124, 129, 131, 135, 138,
+ 139, 143, 146, 147, 151, 153, 155, 157, 159, 160,
+ 163, 164, 167, 168, 171, 172, 177, 179, 183, 184,
+ 188, 189, 193, 195, 196, 201, 203, 205, 209, 213,
+ 214, 218, 219, 223, 225, 226, 231, 233, 237, 238,
+ 242, 243, 247, 249, 250, 255, 257, 259, 263, 267,
+ 270, 271, 275, 277, 279, 280, 283, 284, 287, 288,
+ 293, 295, 299, 300, 304, 305, 309, 311, 312, 317,
+ 319, 321, 325, 329, 330, 334, 335, 339, 341, 342,
+ 347, 349, 353, 354, 358, 359, 363, 365, 366, 371,
+ 373, 375, 379, 383, 384, 388, 389, 393, 395, 396,
+ 401, 403, 405, 409, 411, 413, 415, 418, 422, 427
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const short yyrhs[] =
+{
+ 37, 0, -1, -1, 41, 34, 38, 40, -1, -1,
+ 39, 40, -1, 42, -1, 43, -1, 59, -1, 71,
+ -1, 104, -1, 86, -1, 114, -1, 51, -1, 92,
+ -1, 98, -1, 120, -1, 126, -1, 132, -1, 27,
+ 33, 29, -1, 35, -1, 3, 45, -1, -1, 15,
+ 44, 45, -1, 46, -1, 48, -1, -1, 47, 142,
+ -1, -1, 49, 50, -1, 30, 138, 31, -1, -1,
+ 6, 52, 54, -1, -1, 18, 53, 54, -1, 142,
+ -1, -1, 55, 30, 56, 31, -1, 57, -1, 56,
+ 32, 57, -1, 48, -1, -1, 58, 138, -1, 4,
+ 61, -1, -1, 16, 60, 61, -1, 62, -1, 64,
+ -1, -1, 63, 142, -1, -1, 65, 68, -1, -1,
+ 67, 68, -1, -1, 69, 30, 70, 31, -1, 138,
+ -1, 70, 32, 138, -1, 10, 75, -1, -1, 22,
+ 72, 75, -1, 10, 76, -1, -1, 22, 74, 76,
+ -1, 77, -1, 79, -1, 77, -1, 81, -1, -1,
+ 78, 142, -1, -1, 80, 83, -1, -1, 82, 83,
+ -1, -1, 84, 30, 85, 31, -1, 138, -1, 85,
+ 32, 138, -1, -1, 11, 87, 89, -1, -1, 23,
+ 88, 89, -1, 142, -1, -1, 90, 30, 91, 31,
+ -1, 64, -1, 71, -1, 91, 32, 64, -1, 91,
+ 32, 71, -1, -1, 7, 93, 95, -1, -1, 19,
+ 94, 95, -1, 142, -1, -1, 96, 30, 97, 31,
+ -1, 64, -1, 97, 32, 64, -1, -1, 13, 99,
+ 101, -1, -1, 25, 100, 101, -1, 142, -1, -1,
+ 102, 30, 103, 31, -1, 64, -1, 71, -1, 103,
+ 32, 64, -1, 103, 32, 71, -1, 5, 106, -1,
+ -1, 17, 105, 106, -1, 107, -1, 109, -1, -1,
+ 108, 142, -1, -1, 110, 111, -1, -1, 112, 30,
+ 113, 31, -1, 68, -1, 113, 32, 68, -1, -1,
+ 12, 115, 117, -1, -1, 24, 116, 117, -1, 142,
+ -1, -1, 118, 30, 119, 31, -1, 66, -1, 73,
+ -1, 119, 32, 66, -1, 119, 32, 73, -1, -1,
+ 8, 121, 123, -1, -1, 20, 122, 123, -1, 142,
+ -1, -1, 124, 30, 125, 31, -1, 109, -1, 125,
+ 32, 109, -1, -1, 14, 127, 129, -1, -1, 26,
+ 128, 129, -1, 142, -1, -1, 130, 30, 131, 31,
+ -1, 109, -1, 114, -1, 131, 32, 109, -1, 131,
+ 32, 114, -1, -1, 9, 133, 135, -1, -1, 21,
+ 134, 135, -1, 142, -1, -1, 136, 30, 137, 31,
+ -1, 142, -1, 40, -1, 137, 32, 40, -1, 139,
+ -1, 140, -1, 141, -1, 29, 29, -1, 29, 29,
+ 29, -1, 29, 29, 29, 29, -1, 28, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short yyrline[] =
+{
+ 0, 36, 36, 36, 38, 38, 41, 43, 45, 47,
+ 49, 51, 53, 55, 57, 59, 61, 63, 65, 68,
+ 71, 77, 79, 79, 82, 84, 87, 87, 90, 90,
+ 93, 98, 98, 100, 100, 103, 105, 105, 108, 110,
+ 113, 116, 116, 122, 124, 124, 127, 129, 132, 132,
+ 135, 135, 138, 138, 141, 141, 144, 146, 151, 153,
+ 153, 156, 158, 158, 161, 163, 166, 168, 171, 171,
+ 174, 174, 177, 177, 180, 180, 183, 185, 190, 190,
+ 192, 192, 195, 197, 197, 200, 202, 204, 206, 211,
+ 211, 214, 214, 218, 220, 220, 223, 225, 230, 230,
+ 233, 233, 237, 239, 239, 242, 244, 246, 248, 253,
+ 255, 255, 258, 260, 263, 263, 266, 266, 269, 269,
+ 272, 274, 279, 279, 281, 281, 285, 287, 287, 290,
+ 292, 294, 296, 301, 301, 303, 303, 307, 309, 309,
+ 312, 314, 319, 319, 321, 321, 325, 327, 327, 330,
+ 332, 334, 336, 341, 341, 344, 344, 348, 350, 350,
+ 354, 356, 358, 362, 364, 366, 369, 372, 375, 378
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "POINT", "LINESTRING", "POLYGON",
+ "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", "GEOMETRYCOLLECTION",
+ "CIRCULARSTRING", "COMPOUNDCURVE", "CURVEPOLYGON", "MULTICURVE",
+ "MULTISURFACE", "POINTM", "LINESTRINGM", "POLYGONM", "MULTIPOINTM",
+ "MULTILINESTRINGM", "MULTIPOLYGONM", "GEOMETRYCOLLECTIONM",
+ "CIRCULARSTRINGM", "COMPOUNDCURVEM", "CURVEPOLYGONM", "MULTICURVEM",
+ "MULTISURFACEM", "SRID", "EMPTY", "VALUE", "LPAREN", "RPAREN", "COMMA",
+ "EQUALS", "SEMICOLON", "WKB", "$accept", "geometry", "@1", "@2",
+ "geometry_int", "srid", "geom_wkb", "geom_point", "@3", "point",
+ "empty_point", "@4", "nonempty_point", "@5", "point_int",
+ "geom_multipoint", "@6", "@7", "multipoint", "@8", "multipoint_int",
+ "mpoint_element", "@9", "geom_linestring", "@10", "linestring",
+ "empty_linestring", "@11", "nonempty_linestring", "@12",
+ "nonempty_linestring_closed", "@13", "linestring_1", "@14",
+ "linestring_int", "geom_circularstring", "@15",
+ "geom_circularstring_closed", "@16", "circularstring",
+ "circularstring_closed", "empty_circularstring", "@17",
+ "nonempty_circularstring", "@18", "nonempty_circularstring_closed",
+ "@19", "circularstring_1", "@20", "circularstring_int",
+ "geom_compoundcurve", "@21", "@22", "compoundcurve", "@23",
+ "compoundcurve_int", "geom_multilinestring", "@24", "@25",
+ "multilinestring", "@26", "multilinestring_int", "geom_multicurve",
+ "@27", "@28", "multicurve", "@29", "multicurve_int", "geom_polygon",
+ "@30", "polygon", "empty_polygon", "@31", "nonempty_polygon", "@32",
+ "polygon_1", "@33", "polygon_int", "geom_curvepolygon", "@34", "@35",
+ "curvepolygon", "@36", "curvepolygon_int", "geom_multipolygon", "@37",
+ "@38", "multipolygon", "@39", "multipolygon_int", "geom_multisurface",
+ "@40", "@41", "multisurface", "@42", "multisurface_int",
+ "geom_geometrycollection", "@43", "@44", "geometrycollection", "@45",
+ "geometrycollection_int", "a_point", "point_2d", "point_3d", "point_4d",
+ "empty", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 36, 38, 37, 39, 37, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 41,
+ 42, 43, 44, 43, 45, 45, 47, 46, 49, 48,
+ 50, 52, 51, 53, 51, 54, 55, 54, 56, 56,
+ 57, 58, 57, 59, 60, 59, 61, 61, 63, 62,
+ 65, 64, 67, 66, 69, 68, 70, 70, 71, 72,
+ 71, 73, 74, 73, 75, 75, 76, 76, 78, 77,
+ 80, 79, 82, 81, 84, 83, 85, 85, 87, 86,
+ 88, 86, 89, 90, 89, 91, 91, 91, 91, 93,
+ 92, 94, 92, 95, 96, 95, 97, 97, 99, 98,
+ 100, 98, 101, 102, 101, 103, 103, 103, 103, 104,
+ 105, 104, 106, 106, 108, 107, 110, 109, 112, 111,
+ 113, 113, 115, 114, 116, 114, 117, 118, 117, 119,
+ 119, 119, 119, 121, 120, 122, 120, 123, 124, 123,
+ 125, 125, 127, 126, 128, 126, 129, 130, 129, 131,
+ 131, 131, 131, 133, 132, 134, 132, 135, 136, 135,
+ 137, 137, 137, 138, 138, 138, 139, 140, 141, 142
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 0, 4, 0, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 1, 2, 0, 3, 1, 1, 0, 2, 0, 2,
+ 3, 0, 3, 0, 3, 1, 0, 4, 1, 3,
+ 1, 0, 2, 2, 0, 3, 1, 1, 0, 2,
+ 0, 2, 0, 2, 0, 4, 1, 3, 2, 0,
+ 3, 2, 0, 3, 1, 1, 1, 1, 0, 2,
+ 0, 2, 0, 2, 0, 4, 1, 3, 0, 3,
+ 0, 3, 1, 0, 4, 1, 1, 3, 3, 0,
+ 3, 0, 3, 1, 0, 4, 1, 3, 0, 3,
+ 0, 3, 1, 0, 4, 1, 1, 3, 3, 2,
+ 0, 3, 1, 1, 0, 2, 0, 2, 0, 4,
+ 1, 3, 0, 3, 0, 3, 1, 0, 4, 1,
+ 1, 3, 3, 0, 3, 0, 3, 1, 0, 4,
+ 1, 3, 0, 3, 0, 3, 1, 0, 4, 1,
+ 1, 3, 3, 0, 3, 0, 3, 1, 0, 4,
+ 1, 1, 3, 1, 1, 1, 2, 3, 4, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 4, 0, 0, 0, 0, 0, 1, 26, 48, 114,
+ 31, 89, 133, 153, 68, 78, 122, 98, 142, 22,
+ 44, 110, 33, 91, 135, 155, 59, 80, 124, 100,
+ 144, 20, 5, 6, 7, 13, 8, 9, 11, 14,
+ 15, 10, 12, 16, 17, 18, 2, 19, 21, 24,
+ 0, 25, 0, 43, 46, 0, 47, 54, 109, 112,
+ 0, 113, 118, 36, 94, 138, 158, 58, 64, 0,
+ 65, 74, 83, 127, 103, 147, 26, 48, 114, 36,
+ 94, 138, 158, 68, 83, 127, 103, 147, 0, 169,
+ 27, 0, 29, 49, 51, 0, 115, 117, 0, 32,
+ 0, 35, 90, 0, 93, 134, 0, 137, 154, 0,
+ 157, 69, 71, 0, 79, 0, 82, 123, 0, 126,
+ 99, 0, 102, 143, 0, 146, 23, 45, 111, 34,
+ 92, 136, 156, 60, 81, 125, 101, 145, 3, 0,
+ 0, 163, 164, 165, 0, 54, 28, 50, 116, 0,
+ 0, 50, 52, 50, 116, 166, 30, 0, 56, 120,
+ 0, 40, 0, 38, 0, 96, 0, 140, 0, 161,
+ 0, 160, 0, 76, 85, 86, 0, 68, 62, 129,
+ 54, 130, 0, 105, 106, 0, 149, 150, 0, 167,
+ 55, 0, 119, 54, 37, 28, 42, 95, 50, 139,
+ 116, 159, 0, 75, 0, 84, 50, 61, 66, 67,
+ 74, 68, 53, 128, 52, 104, 50, 148, 116, 168,
+ 57, 121, 39, 97, 141, 162, 77, 87, 88, 73,
+ 63, 131, 132, 107, 108, 151, 152
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short yydefgoto[] =
+{
+ -1, 2, 88, 3, 32, 4, 33, 34, 76, 48,
+ 49, 50, 51, 52, 92, 35, 63, 79, 99, 100,
+ 162, 163, 164, 36, 77, 53, 54, 55, 56, 57,
+ 179, 180, 94, 95, 157, 37, 83, 181, 211, 67,
+ 207, 68, 69, 70, 71, 209, 210, 112, 113, 172,
+ 38, 72, 84, 114, 115, 176, 39, 64, 80, 102,
+ 103, 166, 40, 74, 86, 120, 121, 185, 41, 78,
+ 58, 59, 60, 61, 62, 97, 98, 160, 42, 73,
+ 85, 117, 118, 182, 43, 65, 81, 105, 106, 168,
+ 44, 75, 87, 123, 124, 188, 45, 66, 82, 108,
+ 109, 170, 140, 141, 142, 143, 101
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -166
+static const short yypact[] =
+{
+ -17, -14, 21, 145, -7, 5, -166, 29, 30, 40,
+ -166, -166, -166, -166, 51, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ 23, -166, 53, -166, -166, 23, -166, -166, -166, -166,
+ 23, -166, -166, 23, 23, 23, 23, -166, -166, 23,
+ -166, -166, 23, 23, 23, 23, 29, 30, 40, 23,
+ 23, 23, 23, 51, 23, 23, 23, 23, 145, -166,
+ -166, 55, -166, -166, -166, 56, -166, -166, 57, -166,
+ 58, -166, -166, 59, -166, -166, 61, -166, -166, 62,
+ -166, -166, -166, 63, -166, 64, -166, -166, 65, -166,
+ -166, 66, -166, -166, 67, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, 70,
+ 54, -166, -166, -166, 55, -166, 72, -166, -166, 112,
+ 55, 8, 19, 8, 28, 73, -166, -18, -166, -166,
+ 16, -166, 18, -166, 55, -166, 24, -166, 31, -166,
+ 33, -166, 35, -166, -166, -166, 42, 74, -166, -166,
+ -166, -166, 44, -166, -166, 46, -166, -166, 48, 76,
+ -166, 55, -166, -166, -166, 72, -166, -166, -166, -166,
+ -166, -166, 145, -166, 55, -166, 8, -166, -166, -166,
+ -166, 74, -166, -166, 19, -166, 8, -166, 28, -166,
+ -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, -166, -166, -166, -166
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short yypgoto[] =
+{
+ -166, -166, -166, -166, -88, -166, -166, -166, -166, 27,
+ -166, -166, -142, -166, -166, -166, -166, -166, 32, -166,
+ -166, -89, -166, -166, -166, 36, -166, -166, -108, -166,
+ -107, -166, -136, -166, -166, -148, -166, -105, -166, 60,
+ -101, -165, -166, -166, -166, -166, -166, -98, -166, -166,
+ -166, -166, -166, 88, -166, -166, -166, -166, -166, 93,
+ -166, -166, -166, -166, -166, 89, -166, -166, -166, -166,
+ 68, -166, -166, -146, -166, -166, -166, -166, -147, -166,
+ -166, 91, -166, -166, -166, -166, -166, 96, -166, -166,
+ -166, -166, -166, 52, -166, -166, -166, -166, -166, 92,
+ -166, -166, -122, -166, -166, -166, -49
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -117
+static const short yytable[] =
+{
+ 138, 90, 167, 175, 161, 184, 93, 187, 186, 159,
+ 1, 96, 208, 190, 191, 104, 107, 110, 14, 5,
+ 111, 6, 158, 116, 119, 122, 125, 46, 173, 177,
+ 26, 104, 107, 110, 47, 116, 119, 122, 125, 165,
+ 16, 178, 196, 174, 212, 183, 208, 192, 193, 194,
+ 195, 89, 28, 161, 224, 197, 198, 221, 228, -28,
+ -50, 169, 199, 200, 201, 202, 203, 204, 234, 220,
+ -116, 236, 235, 205, 206, 213, 214, 215, 216, 217,
+ 218, -70, 226, 91, 139, 156, 144, 145, 146, 147,
+ 223, 148, 149, 150, 151, 152, 153, 154, 227, 155,
+ 171, -41, 189, 126, -72, 219, 222, 231, 233, 232,
+ 230, 129, 229, 127, 225, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 137,
+ 89, 0, 0, 133, 0, 0, 128, 31, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 134, 130, 132, 136, 135, 131, 0, 0,
+ 31
+};
+
+static const short yycheck[] =
+{
+ 88, 50, 148, 151, 146, 153, 55, 154, 154, 145,
+ 27, 60, 177, 31, 32, 64, 65, 66, 10, 33,
+ 69, 0, 144, 72, 73, 74, 75, 34, 150, 10,
+ 22, 80, 81, 82, 29, 84, 85, 86, 87, 147,
+ 12, 22, 164, 151, 180, 153, 211, 31, 32, 31,
+ 32, 28, 24, 195, 200, 31, 32, 193, 206, 30,
+ 30, 149, 31, 32, 31, 32, 31, 32, 216, 191,
+ 30, 218, 218, 31, 32, 31, 32, 31, 32, 31,
+ 32, 30, 204, 30, 29, 31, 30, 30, 30, 30,
+ 198, 30, 30, 30, 30, 30, 30, 30, 206, 29,
+ 149, 29, 29, 76, 30, 29, 195, 214, 216, 214,
+ 211, 79, 210, 77, 202, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 87,
+ 28, -1, -1, 83, -1, -1, 78, 35, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 84, 80, 82, 86, 85, 81, -1, -1,
+ 35
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 27, 37, 39, 41, 33, 0, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 35, 40, 42, 43, 51, 59, 71, 86, 92,
+ 98, 104, 114, 120, 126, 132, 34, 29, 45, 46,
+ 47, 48, 49, 61, 62, 63, 64, 65, 106, 107,
+ 108, 109, 110, 52, 93, 121, 133, 75, 77, 78,
+ 79, 80, 87, 115, 99, 127, 44, 60, 105, 53,
+ 94, 122, 134, 72, 88, 116, 100, 128, 38, 28,
+ 142, 30, 50, 142, 68, 69, 142, 111, 112, 54,
+ 55, 142, 95, 96, 142, 123, 124, 142, 135, 136,
+ 142, 142, 83, 84, 89, 90, 142, 117, 118, 142,
+ 101, 102, 142, 129, 130, 142, 45, 61, 106, 54,
+ 95, 123, 135, 75, 89, 117, 101, 129, 40, 29,
+ 138, 139, 140, 141, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 29, 31, 70, 138, 68,
+ 113, 48, 56, 57, 58, 64, 97, 109, 125, 40,
+ 137, 142, 85, 138, 64, 71, 91, 10, 22, 66,
+ 67, 73, 119, 64, 71, 103, 109, 114, 131, 29,
+ 31, 32, 31, 32, 31, 32, 138, 31, 32, 31,
+ 32, 31, 32, 31, 32, 31, 32, 76, 77, 81,
+ 82, 74, 68, 31, 32, 31, 32, 31, 32, 29,
+ 138, 68, 57, 64, 109, 40, 138, 64, 71, 83,
+ 76, 66, 73, 64, 71, 109, 114
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ ((Current).first_line = (Rhs)[1].first_line, \
+ (Current).first_column = (Rhs)[1].first_column, \
+ (Current).last_line = (Rhs)[N].last_line, \
+ (Current).last_column = (Rhs)[N].last_column)
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short *bottom;
+ short *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 36 "wktparse.y"
+ { alloc_lwgeom(srid); }
+ break;
+
+ case 4:
+#line 38 "wktparse.y"
+ { alloc_lwgeom(-1); }
+ break;
+
+ case 19:
+#line 68 "wktparse.y"
+ { set_srid(yyvsp[0].value); }
+ break;
+
+ case 20:
+#line 71 "wktparse.y"
+ { alloc_wkb(yyvsp[0].wkb); }
+ break;
+
+ case 22:
+#line 79 "wktparse.y"
+ { set_zm(0, 1); }
+ break;
+
+ case 26:
+#line 87 "wktparse.y"
+ { alloc_point(); }
+ break;
+
+ case 27:
+#line 87 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 28:
+#line 90 "wktparse.y"
+ { alloc_point(); }
+ break;
+
+ case 29:
+#line 90 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 31:
+#line 98 "wktparse.y"
+ { alloc_multipoint(); }
+ break;
+
+ case 32:
+#line 98 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 33:
+#line 100 "wktparse.y"
+ { set_zm(0, 1); alloc_multipoint(); }
+ break;
+
+ case 34:
+#line 100 "wktparse.y"
+ {pop(); }
+ break;
+
+ case 36:
+#line 105 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 37:
+#line 105 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 41:
+#line 116 "wktparse.y"
+ { alloc_point(); }
+ break;
+
+ case 42:
+#line 116 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 44:
+#line 124 "wktparse.y"
+ { set_zm(0, 1); }
+ break;
+
+ case 48:
+#line 132 "wktparse.y"
+ { alloc_linestring(); }
+ break;
+
+ case 49:
+#line 132 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 50:
+#line 135 "wktparse.y"
+ { alloc_linestring(); }
+ break;
+
+ case 51:
+#line 135 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 52:
+#line 138 "wktparse.y"
+ { alloc_linestring_closed(); }
+ break;
+
+ case 53:
+#line 138 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 54:
+#line 141 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 55:
+#line 141 "wktparse.y"
+ { popc(); }
+ break;
+
+ case 59:
+#line 153 "wktparse.y"
+ {set_zm(0, 1); }
+ break;
+
+ case 62:
+#line 158 "wktparse.y"
+ {set_zm(0, 1); }
+ break;
+
+ case 68:
+#line 171 "wktparse.y"
+ { alloc_circularstring(); }
+ break;
+
+ case 69:
+#line 171 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 70:
+#line 174 "wktparse.y"
+ { alloc_circularstring(); }
+ break;
+
+ case 71:
+#line 174 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 72:
+#line 177 "wktparse.y"
+ { alloc_circularstring_closed(); }
+ break;
+
+ case 73:
+#line 177 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 74:
+#line 180 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 75:
+#line 180 "wktparse.y"
+ { popc(); }
+ break;
+
+ case 78:
+#line 190 "wktparse.y"
+ { alloc_compoundcurve(); }
+ break;
+
+ case 79:
+#line 190 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 80:
+#line 192 "wktparse.y"
+ {set_zm(0, 1); alloc_compoundcurve(); }
+ break;
+
+ case 81:
+#line 192 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 83:
+#line 197 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 84:
+#line 197 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 89:
+#line 211 "wktparse.y"
+ { alloc_multilinestring(); }
+ break;
+
+ case 90:
+#line 212 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 91:
+#line 214 "wktparse.y"
+ { set_zm(0, 1); alloc_multilinestring(); }
+ break;
+
+ case 92:
+#line 215 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 94:
+#line 220 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 95:
+#line 220 "wktparse.y"
+ { pop();}
+ break;
+
+ case 98:
+#line 230 "wktparse.y"
+ { alloc_multicurve(); }
+ break;
+
+ case 99:
+#line 231 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 100:
+#line 233 "wktparse.y"
+ { set_zm(0, 1); alloc_multicurve(); }
+ break;
+
+ case 101:
+#line 234 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 103:
+#line 239 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 104:
+#line 239 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 110:
+#line 255 "wktparse.y"
+ { set_zm(0, 1); }
+ break;
+
+ case 114:
+#line 263 "wktparse.y"
+ { alloc_polygon(); }
+ break;
+
+ case 115:
+#line 263 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 116:
+#line 266 "wktparse.y"
+ { alloc_polygon(); }
+ break;
+
+ case 117:
+#line 266 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 118:
+#line 269 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 119:
+#line 269 "wktparse.y"
+ { pop();}
+ break;
+
+ case 122:
+#line 279 "wktparse.y"
+ { alloc_curvepolygon(); }
+ break;
+
+ case 123:
+#line 279 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 124:
+#line 281 "wktparse.y"
+ { set_zm(0, 1); alloc_curvepolygon(); }
+ break;
+
+ case 125:
+#line 282 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 127:
+#line 287 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 128:
+#line 287 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 133:
+#line 301 "wktparse.y"
+ { alloc_multipolygon(); }
+ break;
+
+ case 134:
+#line 301 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 135:
+#line 303 "wktparse.y"
+ { set_zm(0, 1); alloc_multipolygon(); }
+ break;
+
+ case 136:
+#line 304 "wktparse.y"
+ { pop();}
+ break;
+
+ case 138:
+#line 309 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 139:
+#line 309 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 142:
+#line 319 "wktparse.y"
+ {alloc_multisurface(); }
+ break;
+
+ case 143:
+#line 319 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 144:
+#line 321 "wktparse.y"
+ { set_zm(0, 1); alloc_multisurface(); }
+ break;
+
+ case 145:
+#line 322 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 147:
+#line 327 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 148:
+#line 327 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 153:
+#line 341 "wktparse.y"
+ { alloc_geomertycollection(); }
+ break;
+
+ case 154:
+#line 342 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 155:
+#line 344 "wktparse.y"
+ { set_zm(0, 1); alloc_geomertycollection(); }
+ break;
+
+ case 156:
+#line 345 "wktparse.y"
+ { pop();}
+ break;
+
+ case 158:
+#line 350 "wktparse.y"
+ { alloc_counter(); }
+ break;
+
+ case 159:
+#line 350 "wktparse.y"
+ { pop(); }
+ break;
+
+ case 166:
+#line 369 "wktparse.y"
+ {alloc_point_2d(yyvsp[-1].value,yyvsp[0].value); }
+ break;
+
+ case 167:
+#line 372 "wktparse.y"
+ {alloc_point_3d(yyvsp[-2].value,yyvsp[-1].value,yyvsp[0].value); }
+ break;
+
+ case 168:
+#line 375 "wktparse.y"
+ {alloc_point_4d(yyvsp[-3].value,yyvsp[-2].value,yyvsp[-1].value,yyvsp[0].value); }
+ break;
+
+ case 169:
+#line 378 "wktparse.y"
+ { alloc_empty(); }
+ break;
+
+
+ }
+
+/* Line 1000 of yacc.c. */
+#line 1761 "y.tab.c"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
+ char *yymsg;
+ int yyx;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yyp = yystpcpy (yyp, yyprefix);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yyprefix = " or ";
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ }
+ }
+ else
+ {
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#ifdef __GNUC__
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
+#endif
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 379 "wktparse.y"
+
+
+
+
+
+
Added: trunk/liblwgeom/wktparse.tab.h
===================================================================
--- trunk/liblwgeom/wktparse.tab.h 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/wktparse.tab.h 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,120 @@
+/* A Bison parser, made by GNU Bison 1.875c. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ POINT = 258,
+ LINESTRING = 259,
+ POLYGON = 260,
+ MULTIPOINT = 261,
+ MULTILINESTRING = 262,
+ MULTIPOLYGON = 263,
+ GEOMETRYCOLLECTION = 264,
+ CIRCULARSTRING = 265,
+ COMPOUNDCURVE = 266,
+ CURVEPOLYGON = 267,
+ MULTICURVE = 268,
+ MULTISURFACE = 269,
+ POINTM = 270,
+ LINESTRINGM = 271,
+ POLYGONM = 272,
+ MULTIPOINTM = 273,
+ MULTILINESTRINGM = 274,
+ MULTIPOLYGONM = 275,
+ GEOMETRYCOLLECTIONM = 276,
+ CIRCULARSTRINGM = 277,
+ COMPOUNDCURVEM = 278,
+ CURVEPOLYGONM = 279,
+ MULTICURVEM = 280,
+ MULTISURFACEM = 281,
+ SRID = 282,
+ EMPTY = 283,
+ VALUE = 284,
+ LPAREN = 285,
+ RPAREN = 286,
+ COMMA = 287,
+ EQUALS = 288,
+ SEMICOLON = 289,
+ WKB = 290
+ };
+#endif
+#define POINT 258
+#define LINESTRING 259
+#define POLYGON 260
+#define MULTIPOINT 261
+#define MULTILINESTRING 262
+#define MULTIPOLYGON 263
+#define GEOMETRYCOLLECTION 264
+#define CIRCULARSTRING 265
+#define COMPOUNDCURVE 266
+#define CURVEPOLYGON 267
+#define MULTICURVE 268
+#define MULTISURFACE 269
+#define POINTM 270
+#define LINESTRINGM 271
+#define POLYGONM 272
+#define MULTIPOINTM 273
+#define MULTILINESTRINGM 274
+#define MULTIPOLYGONM 275
+#define GEOMETRYCOLLECTIONM 276
+#define CIRCULARSTRINGM 277
+#define COMPOUNDCURVEM 278
+#define CURVEPOLYGONM 279
+#define MULTICURVEM 280
+#define MULTISURFACEM 281
+#define SRID 282
+#define EMPTY 283
+#define VALUE 284
+#define LPAREN 285
+#define RPAREN 286
+#define COMMA 287
+#define EQUALS 288
+#define SEMICOLON 289
+#define WKB 290
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 20 "wktparse.y"
+typedef union YYSTYPE {
+ double value;
+ const char* wkb;
+} YYSTYPE;
+/* Line 1275 of yacc.c. */
+#line 112 "y.tab.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE lwg_parse_yylval;
+
+
+
Added: trunk/liblwgeom/wktparse.y
===================================================================
--- trunk/liblwgeom/wktparse.y 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/liblwgeom/wktparse.y 2008-06-29 19:11:48 UTC (rev 2815)
@@ -0,0 +1,383 @@
+/*
+ * Written by Ralph Mason ralph.mason<at>telogis.com
+ *
+ * Copyright Telogis 2004
+ * www.telogis.com
+ *
+ */
+
+%{
+#include "wktparse.h"
+#include <unistd.h>
+#include <stdio.h>
+
+void set_zm(char z, char m);
+int lwg_parse_yylex(void);
+%}
+
+%start geometry
+
+%union {
+ double value;
+ const char* wkb;
+}
+
+%token POINT LINESTRING POLYGON MULTIPOINT MULTILINESTRING MULTIPOLYGON GEOMETRYCOLLECTION CIRCULARSTRING COMPOUNDCURVE CURVEPOLYGON MULTICURVE MULTISURFACE
+%token POINTM LINESTRINGM POLYGONM MULTIPOINTM MULTILINESTRINGM MULTIPOLYGONM GEOMETRYCOLLECTIONM CIRCULARSTRINGM COMPOUNDCURVEM CURVEPOLYGONM MULTICURVEM MULTISURFACEM
+%token SRID
+%token EMPTY
+%token <value> VALUE
+%token LPAREN RPAREN COMMA EQUALS SEMICOLON
+%token <wkb> WKB
+
+%%
+
+geometry :
+ srid SEMICOLON { alloc_lwgeom(srid); } geometry_int
+ |
+ { alloc_lwgeom(-1); } geometry_int
+
+geometry_int :
+ geom_wkb
+ |
+ geom_point
+ |
+ geom_linestring
+ |
+ geom_circularstring
+ |
+ geom_polygon
+ |
+ geom_compoundcurve
+ |
+ geom_curvepolygon
+ |
+ geom_multipoint
+ |
+ geom_multilinestring
+ |
+ geom_multicurve
+ |
+ geom_multipolygon
+ |
+ geom_multisurface
+ |
+ geom_geometrycollection
+
+srid :
+ SRID EQUALS VALUE { set_srid($3); }
+
+geom_wkb :
+ WKB { alloc_wkb($1); }
+
+
+/* POINT */
+
+geom_point :
+ POINT point
+ |
+ POINTM { set_zm(0, 1); } point
+
+point :
+ empty_point
+ |
+ nonempty_point
+
+empty_point :
+ { alloc_point(); } empty { pop(); }
+
+nonempty_point :
+ { alloc_point(); } point_int { pop(); }
+
+point_int :
+ LPAREN a_point RPAREN
+
+/* MULTIPOINT */
+
+geom_multipoint :
+ MULTIPOINT { alloc_multipoint(); } multipoint { pop(); }
+ |
+ MULTIPOINTM { set_zm(0, 1); alloc_multipoint(); } multipoint {pop(); }
+
+multipoint :
+ empty
+ |
+ { alloc_counter(); } LPAREN multipoint_int RPAREN { pop(); }
+
+multipoint_int :
+ mpoint_element
+ |
+ multipoint_int COMMA mpoint_element
+
+mpoint_element :
+ nonempty_point
+ |
+ /* this is to allow MULTIPOINT(0 0, 1 1) */
+ { alloc_point(); } a_point { pop(); }
+
+
+/* LINESTRING */
+
+geom_linestring :
+ LINESTRING linestring
+ |
+ LINESTRINGM { set_zm(0, 1); } linestring
+
+linestring :
+ empty_linestring
+ |
+ nonempty_linestring
+
+empty_linestring :
+ { alloc_linestring(); } empty { pop(); }
+
+nonempty_linestring :
+ { alloc_linestring(); } linestring_1 { pop(); }
+
+nonempty_linestring_closed :
+ { alloc_linestring_closed(); } linestring_1 { pop(); }
+
+linestring_1 :
+ { alloc_counter(); } LPAREN linestring_int RPAREN { popc(); }
+
+linestring_int :
+ a_point
+ |
+ linestring_int COMMA a_point;
+
+/* CIRCULARSTRING */
+
+geom_circularstring :
+ CIRCULARSTRING circularstring
+ |
+ CIRCULARSTRINGM {set_zm(0, 1); } circularstring
+
+geom_circularstring_closed :
+ CIRCULARSTRING circularstring_closed
+ |
+ CIRCULARSTRINGM {set_zm(0, 1); } circularstring_closed
+
+circularstring :
+ empty_circularstring
+ |
+ nonempty_circularstring
+
+circularstring_closed :
+ empty_circularstring
+ |
+ nonempty_circularstring_closed
+
+empty_circularstring :
+ { alloc_circularstring(); } empty { pop(); }
+
+nonempty_circularstring :
+ { alloc_circularstring(); } circularstring_1 { pop(); }
+
+nonempty_circularstring_closed :
+ { alloc_circularstring_closed(); } circularstring_1 { pop(); }
+
+circularstring_1 :
+ { alloc_counter(); } LPAREN circularstring_int RPAREN { popc(); }
+
+circularstring_int :
+ a_point
+ |
+ circularstring_int COMMA a_point;
+
+/* COMPOUNDCURVE */
+
+geom_compoundcurve:
+ COMPOUNDCURVE { alloc_compoundcurve(); } compoundcurve { pop(); }
+ |
+ COMPOUNDCURVEM {set_zm(0, 1); alloc_compoundcurve(); } compoundcurve { pop(); }
+
+compoundcurve:
+ empty
+ |
+ { alloc_counter(); } LPAREN compoundcurve_int RPAREN { pop(); }
+
+compoundcurve_int:
+ nonempty_linestring
+ |
+ geom_circularstring
+ |
+ compoundcurve_int COMMA nonempty_linestring
+ |
+ compoundcurve_int COMMA geom_circularstring
+
+/* MULTILINESTRING */
+
+geom_multilinestring :
+ MULTILINESTRING { alloc_multilinestring(); }
+ multilinestring { pop(); }
+ |
+ MULTILINESTRINGM { set_zm(0, 1); alloc_multilinestring(); }
+ multilinestring { pop(); }
+
+multilinestring :
+ empty
+ |
+ { alloc_counter(); } LPAREN multilinestring_int RPAREN{ pop();}
+
+multilinestring_int :
+ nonempty_linestring
+ |
+ multilinestring_int COMMA nonempty_linestring
+
+/* MULTICURVESTRING */
+
+geom_multicurve :
+ MULTICURVE { alloc_multicurve(); }
+ multicurve { pop(); }
+ |
+ MULTICURVEM { set_zm(0, 1); alloc_multicurve(); }
+ multicurve { pop(); }
+
+multicurve :
+ empty
+ |
+ { alloc_counter(); } LPAREN multicurve_int RPAREN { pop(); }
+
+multicurve_int :
+ nonempty_linestring
+ |
+ geom_circularstring
+ |
+ multicurve_int COMMA nonempty_linestring
+ |
+ multicurve_int COMMA geom_circularstring
+
+/* POLYGON */
+
+geom_polygon :
+ POLYGON polygon
+ |
+ POLYGONM { set_zm(0, 1); } polygon
+
+polygon :
+ empty_polygon
+ |
+ nonempty_polygon
+
+empty_polygon :
+ { alloc_polygon(); } empty { pop(); }
+
+nonempty_polygon :
+ { alloc_polygon(); } polygon_1 { pop(); }
+
+polygon_1 :
+ { alloc_counter(); } LPAREN polygon_int RPAREN { pop();}
+
+polygon_int :
+ linestring_1
+ |
+ polygon_int COMMA linestring_1
+
+/* CURVEPOLYGON */
+
+geom_curvepolygon :
+ CURVEPOLYGON { alloc_curvepolygon(); } curvepolygon { pop(); }
+ |
+ CURVEPOLYGONM { set_zm(0, 1); alloc_curvepolygon(); }
+ curvepolygon { pop(); }
+
+curvepolygon :
+ empty
+ |
+ { alloc_counter(); } LPAREN curvepolygon_int RPAREN { pop(); }
+
+curvepolygon_int :
+ nonempty_linestring_closed
+ |
+ geom_circularstring_closed
+ |
+ curvepolygon_int COMMA nonempty_linestring_closed
+ |
+ curvepolygon_int COMMA geom_circularstring_closed
+
+/* MULTIPOLYGON */
+
+geom_multipolygon :
+ MULTIPOLYGON { alloc_multipolygon(); } multipolygon { pop(); }
+ |
+ MULTIPOLYGONM { set_zm(0, 1); alloc_multipolygon(); }
+ multipolygon { pop();}
+
+multipolygon :
+ empty
+ |
+ { alloc_counter(); } LPAREN multipolygon_int RPAREN { pop(); }
+
+multipolygon_int :
+ nonempty_polygon
+ |
+ multipolygon_int COMMA nonempty_polygon
+
+/* MULTISURFACE */
+
+geom_multisurface :
+ MULTISURFACE {alloc_multisurface(); } multisurface { pop(); }
+ |
+ MULTISURFACEM { set_zm(0, 1); alloc_multisurface(); }
+ multisurface { pop(); }
+
+multisurface :
+ empty
+ |
+ { alloc_counter(); } LPAREN multisurface_int RPAREN { pop(); }
+
+multisurface_int :
+ nonempty_polygon
+ |
+ geom_curvepolygon
+ |
+ multisurface_int COMMA nonempty_polygon
+ |
+ multisurface_int COMMA geom_curvepolygon
+
+/* GEOMETRYCOLLECTION */
+
+geom_geometrycollection :
+ GEOMETRYCOLLECTION { alloc_geomertycollection(); }
+ geometrycollection { pop(); }
+ |
+ GEOMETRYCOLLECTIONM { set_zm(0, 1); alloc_geomertycollection(); }
+ geometrycollection { pop();}
+
+geometrycollection :
+ empty
+ |
+ { alloc_counter(); } LPAREN geometrycollection_int RPAREN { pop(); }
+
+geometrycollection_int :
+ /* to support GEOMETRYCOLLECTION(EMPTY) for backward compatibility */
+ empty
+ |
+ geometry_int
+ |
+ geometrycollection_int COMMA geometry_int
+
+
+a_point :
+ point_2d
+ |
+ point_3d
+ |
+ point_4d
+
+point_2d :
+ VALUE VALUE {alloc_point_2d($1,$2); }
+
+point_3d :
+ VALUE VALUE VALUE {alloc_point_3d($1,$2,$3); }
+
+point_4d :
+ VALUE VALUE VALUE VALUE {alloc_point_4d($1,$2,$3,$4); }
+
+empty :
+ EMPTY { alloc_empty(); }
+%%
+
+
+
+
Modified: trunk/lwgeom/Makefile.in
===================================================================
--- trunk/lwgeom/Makefile.in 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/Makefile.in 2008-06-29 19:11:48 UTC (rev 2815)
@@ -20,33 +20,8 @@
# SQL objects (files requiring C pre-processing)
SQL_OBJS=lwpostgis.sql.in
-# Standalone LWGEOM objects
-SA_OBJS=measures.o \
- box2d.o \
- ptarray.o \
- lwgeom_api.o \
- lwgeom.o \
- lwpoint.o \
- lwline.o \
- lwpoly.o \
- lwmpoint.o \
- lwmline.o \
- lwmpoly.o \
- lwcollection.o \
- lwcurve.o \
- lwcompound.o \
- lwcurvepoly.o \
- lwmcurve.o \
- lwmsurface.o \
- wktunparse.o \
- lwgparse.o \
- wktparse.tab.o \
- lex.yy.o \
- vsprintf.o
-
# PostgreSQL objects
-PG_OBJS=liblwgeom.o \
- lwgeom_pg.o \
+PG_OBJS=lwgeom_pg.o \
lwgeom_debug.o \
lwgeom_spheroid.o \
lwgeom_ogc.o \
@@ -75,10 +50,11 @@
lwgeom_rtree.o
# Objects to build using PGXS
-OBJS=$(SA_OBJS) $(PG_OBJS)
+OBJS=$(PG_OBJS)
# Libraries to link into the module (proj, geos)
-SHLIB_LINK=@SHLIB_LINK@
+PG_CPPFLAGS=@CPPFLAGS@ -I../liblwgeom
+SHLIB_LINK=@SHLIB_LINK@ -L../liblwgeom -llwgeom
# Extra files to remove during 'make clean'
EXTRA_CLEAN=$(SQL_OBJS)
Deleted: trunk/lwgeom/box2d.c
===================================================================
--- trunk/lwgeom/box2d.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/box2d.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,54 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "liblwgeom.h"
-
-#ifndef EPSILON
-#define EPSILON 1.0E-06
-#endif
-#ifndef FPeq
-#define FPeq(A,B) (fabs((A) - (B)) <= EPSILON)
-#endif
-
-
-/* Expand given box of 'd' units in all directions */
-void
-expand_box2d(BOX2DFLOAT4 *box, double d)
-{
- box->xmin -= d;
- box->ymin -= d;
-
- box->xmax += d;
- box->ymax += d;
-}
-
-
-/*
- * This has been changed in PostGIS 1.1.2 to
- * check exact equality of values (rather then using
- * the FPeq macro taking into account coordinate drifts).
- */
-char
-box2d_same(BOX2DFLOAT4 *box1, BOX2DFLOAT4 *box2)
-{
- return( (box1->xmax==box2->xmax) &&
- (box1->xmin==box2->xmin) &&
- (box1->ymax==box2->ymax) &&
- (box1->ymin==box2->ymin));
-#if 0
- return(FPeq(box1->xmax, box2->xmax) &&
- FPeq(box1->xmin, box2->xmin) &&
- FPeq(box1->ymax, box2->ymax) &&
- FPeq(box1->ymin, box2->ymin));
-#endif
-}
-
-BOX2DFLOAT4 *
-box2d_clone(const BOX2DFLOAT4 *in)
-{
- BOX2DFLOAT4 *ret = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(ret, in, sizeof(BOX2DFLOAT4));
- return ret;
-}
Deleted: trunk/lwgeom/lex.yy.c
===================================================================
--- trunk/lwgeom/lex.yy.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lex.yy.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,4562 +0,0 @@
-#define yy_create_buffer lwg_parse_yy_create_buffer
-#define yy_delete_buffer lwg_parse_yy_delete_buffer
-#define yy_scan_buffer lwg_parse_yy_scan_buffer
-#define yy_scan_string lwg_parse_yy_scan_string
-#define yy_scan_bytes lwg_parse_yy_scan_bytes
-#define yy_flex_debug lwg_parse_yy_flex_debug
-#define yy_init_buffer lwg_parse_yy_init_buffer
-#define yy_flush_buffer lwg_parse_yy_flush_buffer
-#define yy_load_buffer_state lwg_parse_yy_load_buffer_state
-#define yy_switch_to_buffer lwg_parse_yy_switch_to_buffer
-#define yyin lwg_parse_yyin
-#define yyleng lwg_parse_yyleng
-#define yylex lwg_parse_yylex
-#define yyout lwg_parse_yyout
-#define yyrestart lwg_parse_yyrestart
-#define yytext lwg_parse_yytext
-#define yywrap lwg_parse_yywrap
-
-#line 20 "lex.yy.c"
-/* A lexical scanner generated by flex */
-
-/* Scanner skeleton version:
- * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
- */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-
-#include <stdio.h>
-#include <unistd.h>
-
-
-/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
-#ifdef c_plusplus
-#ifndef __cplusplus
-#define __cplusplus
-#endif
-#endif
-
-
-#ifdef __cplusplus
-
-#include <stdlib.h>
-
-/* Use prototypes in function declarations. */
-#define YY_USE_PROTOS
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_PROTOS
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef __TURBOC__
- #pragma warn -rch
- #pragma warn -use
-#include <io.h>
-#include <stdlib.h>
-#define YY_USE_CONST
-#define YY_USE_PROTOS
-#endif
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-
-#ifdef YY_USE_PROTOS
-#define YY_PROTO(proto) proto
-#else
-#define YY_PROTO(proto) ()
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#define YY_BUF_SIZE 16384
-
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-
-extern int yyleng;
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-/* The funky do-while in the following #define is used to turn the definition
- * int a single C statement (which needs a semi-colon terminator). This
- * avoids problems with code like:
- *
- * if ( condition_holds )
- * yyless( 5 );
- * else
- * do_something_else();
- *
- * Prior to using the do-while the compiler would get upset at the
- * "else" because it interpreted the "if" statement as being all
- * done when it reached the ';' after the yyless() call.
- */
-
-/* Return all but the first 'n' matched characters back to the input stream. */
-
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- *yy_cp = yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yytext_ptr )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-typedef unsigned int yy_size_t;
-
-
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
- };
-
-static YY_BUFFER_STATE yy_current_buffer = 0;
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- */
-#define YY_CURRENT_BUFFER yy_current_buffer
-
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-
-static int yy_n_chars; /* number of characters read into yy_ch_buf */
-
-
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1; /* whether we need to initialize */
-static int yy_start = 0; /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin. A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart YY_PROTO(( FILE *input_file ));
-
-void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
-void yy_load_buffer_state YY_PROTO(( void ));
-YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
-void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
-void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
-
-YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
-YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
-YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
-
-static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
-static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
-static void yy_flex_free YY_PROTO(( void * ));
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
-
-typedef char YY_CHAR;
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-typedef int yy_state_type;
-extern char *yytext;
-#define yytext_ptr yytext
-static yyconst short yy_nxt[][128] =
- {
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
- },
-
- {
- 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
- 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
- 9, 10, 6, 6, 11, 6, 6, 6, 12, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 13,
- 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
-
- 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
- 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
- 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
- 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6
- },
-
- {
- 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
- 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
-
- 9, 10, 6, 6, 11, 6, 6, 6, 12, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 13,
- 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
- 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
- 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
- 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
- 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6
- },
-
- {
- 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
-
- 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
- 9, 10, 6, 22, 11, 22, 23, 6, 24, 24,
- 24, 24, 24, 24, 24, 24, 24, 24, 6, 13,
- 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
- 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
- 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
- 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
-
- 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
- 6, 6, 6, 6, 22, 6, 6, 6
- },
-
- {
- 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
- 8, 6, 6, 7, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 7, 6, 6, 6, 6, 6, 6, 6,
- 9, 10, 6, 22, 11, 22, 23, 6, 24, 24,
- 24, 24, 24, 24, 24, 24, 24, 24, 6, 13,
- 6, 14, 6, 6, 6, 6, 6, 15, 6, 16,
- 6, 17, 6, 6, 6, 6, 18, 19, 6, 6,
-
- 20, 6, 6, 21, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
- 6, 16, 6, 17, 6, 6, 6, 6, 18, 19,
- 6, 6, 20, 6, 6, 21, 6, 6, 6, 6,
- 6, 6, 6, 6, 22, 6, 6, 6
- },
-
- {
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
-
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
- -5, -5, -5, -5, -5, -5, -5, -5
- },
-
- {
- 5, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
-
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
-
- -6, -6, -6, -6, -6, -6, -6, -6
- },
-
- {
- 5, -7, -7, -7, -7, -7, -7, -7, -7, 25,
- 25, -7, -7, 25, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, 25, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
-
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7
- },
-
- {
- 5, -8, -8, -8, -8, -8, -8, -8, -8, 25,
- 25, -8, -8, 25, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, 25, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
-
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, -8, -8
- },
-
- {
- 5, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
-
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
- -9, -9, -9, -9, -9, -9, -9, -9
-
- },
-
- {
- 5, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
-
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
- -10, -10, -10, -10, -10, -10, -10, -10
- },
-
- {
- 5, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
-
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11
- },
-
- {
- 5, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
-
- -12, -12, -12, -12, -12, -12, -12, -12, 26, 27,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12
- },
-
- {
- 5, -13, -13, -13, -13, -13, -13, -13, -13, -13,
-
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
-
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13
- },
-
- {
- 5, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
-
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14
- },
-
- {
- 5, -15, -15, -15, -15, -15, -15, -15, -15, -15,
- -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
- -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
- -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
- -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
-
- -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
- -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
- -15, -15, -15, 28, -15, -15, -15, -15, -15, 29,
- -15, -15, -15, -15, -15, 30, -15, -15, -15, -15,
- -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
- -15, -15, -15, -15, -15, 28, -15, -15, -15, -15,
- -15, 29, -15, -15, -15, -15, -15, 30, -15, -15,
- -15, -15, -15, -15, -15, -15, -15, -15
- },
-
- {
- 5, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
-
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, 31, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, 31,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
-
- -16, -16, -16, -16, -16, -16, -16, -16
- },
-
- {
- 5, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, 32,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
-
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, 32, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17
- },
-
- {
- 5, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
-
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, 33, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, 33, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, -18, -18, -18, -18, -18
- },
-
- {
- 5, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
-
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, 34, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, 34, -19, -19,
- -19, -19, -19, -19, -19, -19, -19, -19
-
- },
-
- {
- 5, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, 35,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
-
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, 35, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20, -20
- },
-
- {
- 5, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
-
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, 36, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, 36, -21, -21, -21, -21, -21,
- -21, -21, -21, -21, -21, -21, -21, -21
- },
-
- {
- 5, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
-
- -22, -22, -22, -22, -22, -22, 37, -22, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, -22, -22, -22
- },
-
- {
- 5, -23, -23, -23, -23, -23, -23, -23, -23, -23,
-
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
-
- -23, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23, -23
- },
-
- {
- 5, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, 40, -24, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, 41,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
-
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, 41, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24
- },
-
- {
- 5, -25, -25, -25, -25, -25, -25, -25, -25, 25,
- 25, -25, -25, 25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, 25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
-
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -25, -25, -25
- },
-
- {
- 5, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
-
- -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, -26, -26, -26, -26, -26, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, -26, -26,
- -26, -26, -26, -26, -26, 42, 42, 42, 42, 42,
- 42, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, -26, -26, -26, -26, 42, 42, 42,
- 42, 42, 42, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
-
- -26, -26, -26, -26, -26, -26, -26, -26
- },
-
- {
- 5, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27, -27, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, -27, -27,
- -27, -27, -27, -27, -27, 43, 43, 43, 43, 43,
- 43, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
-
- -27, -27, -27, -27, -27, -27, -27, 43, 43, 43,
- 43, 43, 43, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27, -27
- },
-
- {
- 5, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
-
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, 44, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, 44, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, -28, -28, -28, -28
- },
-
- {
- 5, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
-
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, 45, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, 45,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29
-
- },
-
- {
- 5, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, 46, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
-
- -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, 46, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, -30, -30, -30
- },
-
- {
- 5, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
-
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- 47, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, 47, -31, -31, -31, -31, -31, -31, -31,
- -31, -31, -31, -31, -31, -31, -31, -31
- },
-
- {
- 5, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, 48,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, 48, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32
- },
-
- {
- 5, -33, -33, -33, -33, -33, -33, -33, -33, -33,
-
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, 49, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
-
- 49, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33, -33
- },
-
- {
- 5, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, 50, -34, -34, -34,
-
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, 50, -34,
- -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, -34, -34
- },
-
- {
- 5, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
-
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, 51, -35, -35, 52, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, 51, -35, -35, 52, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35
- },
-
- {
- 5, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
-
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, 53, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, 53, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
-
- -36, -36, -36, -36, -36, -36, -36, -36
- },
-
- {
- 5, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
-
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37, -37
- },
-
- {
- 5, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, 40, -38, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38, -38, -38,
-
- -38, -38, -38, -38, -38, -38, -38, -38, -38, 41,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, 41, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38
- },
-
- {
- 5, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
-
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, 54,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, 54, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39
-
- },
-
- {
- 5, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
-
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40
- },
-
- {
- 5, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, 56, -41, 56, -41, -41, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
-
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41
- },
-
- {
- 5, -42, -42, -42, -42, -42, -42, -42, -42, -42,
- -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
- -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
- -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
-
- -42, -42, -42, -42, -42, -42, -42, -42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, -42, -42,
- -42, -42, -42, -42, -42, 42, 42, 42, 42, 42,
- 42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
- -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
- -42, -42, -42, -42, -42, -42, -42, 42, 42, 42,
- 42, 42, 42, -42, -42, -42, -42, -42, -42, -42,
- -42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
- -42, -42, -42, -42, -42, -42, -42, -42
- },
-
- {
- 5, -43, -43, -43, -43, -43, -43, -43, -43, -43,
-
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, -43, -43,
- -43, -43, -43, -43, -43, 43, 43, 43, 43, 43,
- 43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, 43, 43, 43,
- 43, 43, 43, -43, -43, -43, -43, -43, -43, -43,
-
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43
- },
-
- {
- 5, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, 58, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
-
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, 58,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44
- },
-
- {
- 5, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
-
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- 59, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, 59, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45
- },
-
- {
- 5, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
-
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, 60, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46, -46, 60, -46,
-
- -46, -46, -46, -46, -46, -46, -46, -46
- },
-
- {
- 5, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, 61, -47, -47, -47, -47, -47,
-
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, 61, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47
- },
-
- {
- 5, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
-
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, 62, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, 62,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48
- },
-
- {
- 5, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
-
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, 63,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, 63, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49
-
- },
-
- {
- 5, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, 64, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
-
- -50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, 64, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50, -50
- },
-
- {
- 5, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
-
- -51, -51, -51, -51, -51, -51, -51, -51, 65, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- 65, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51, -51
- },
-
- {
- 5, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
-
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, 66,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, 66, -52, -52, -52, -52, -52, -52
- },
-
- {
- 5, -53, -53, -53, -53, -53, -53, -53, -53, -53,
-
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, 67, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- 67, -53, -53, -53, -53, -53, -53, -53, -53, -53,
-
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53
- },
-
- {
- 5, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, 68, -54, 68, -54, -54, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
-
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54
- },
-
- {
- 5, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, 55, 55,
-
- 55, 55, 55, 55, 55, 55, 55, 55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, 41,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, 41, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55, -55
- },
-
- {
- 5, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
-
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -56,
-
- -56, -56, -56, -56, -56, -56, -56, -56
- },
-
- {
- 5, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
-
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57
- },
-
- {
- 5, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
-
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, 70, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, 70, -58, -58,
- -58, -58, -58, -58, -58, -58, -58, -58
- },
-
- {
- 5, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
-
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, 71,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, 71, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59, -59
-
- },
-
- {
- 5, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, 72,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
-
- -60, 72, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -60, -60, -60, -60
- },
-
- {
- 5, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
-
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, 73,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, 73, -61, -61, -61, -61, -61, -61
- },
-
- {
- 5, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
-
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, 74,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, 74, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, -62, -62, -62, -62, -62
- },
-
- {
- 5, -63, -63, -63, -63, -63, -63, -63, -63, -63,
-
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, 75, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63, -63, -63,
-
- -63, -63, -63, -63, -63, 75, -63, -63, -63, -63,
- -63, -63, -63, -63, -63, -63, -63, -63
- },
-
- {
- 5, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, 76, -64, -64, -64, -64, -64, -64,
-
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, 76, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64
- },
-
- {
- 5, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
-
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, 77, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, 77, -65, -65, -65,
- -65, -65, -65, -65, -65, -65, -65, -65
- },
-
- {
- 5, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
-
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, 78, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, 78, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -66, -66, -66, -66, -66,
-
- -66, -66, -66, -66, -66, -66, -66, -66
- },
-
- {
- 5, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
-
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, -67
- },
-
- {
- 5, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, -68, -68,
-
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, -68, -68, -68, -68, -68
- },
-
- {
- 5, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
-
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, -69, -69, -69, -69, -69
-
- },
-
- {
- 5, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, 79, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
-
- -70, -70, -70, -70, -70, -70, -70, -70, 79, -70,
- -70, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -70, -70, -70, -70
- },
-
- {
- 5, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
-
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, 80, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, 80, -71, -71,
- -71, -71, -71, -71, -71, -71, -71, -71
- },
-
- {
- 5, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
-
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- 81, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, 81, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, -72, -72, -72, -72, -72
- },
-
- {
- 5, -73, -73, -73, -73, -73, -73, -73, -73, -73,
-
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
-
- -73, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, -73, -73, -73, -73, -73
- },
-
- {
- 5, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
-
- -74, -74, -74, -74, 82, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, 82, -74, -74, -74,
- -74, -74, -74, -74, -74, -74, -74, -74
- },
-
- {
- 5, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
-
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, 83, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, 83, -75, -75, -75,
- -75, -75, -75, -75, -75, -75, -75, -75
- },
-
- {
- 5, -76, -76, -76, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
-
- -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, -76, -76, -76, -76, 84, -76, -76,
- -76, -76, -76, -76, -76, -76, 85, -76, -76, -76,
- 86, -76, -76, 87, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, -76, -76, -76, -76, -76, -76, 84,
- -76, -76, -76, -76, -76, -76, -76, -76, 85, -76,
- -76, -76, 86, -76, -76, 87, -76, -76, -76, -76,
-
- -76, -76, -76, -76, -76, -76, -76, -76
- },
-
- {
- 5, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, 88, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
-
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, 88,
- -77, -77, -77, -77, -77, -77, -77, -77, -77, -77,
- -77, -77, -77, -77, -77, -77, -77, -77
- },
-
- {
- 5, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
-
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, 89,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, 89, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78
- },
-
- {
- 5, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
-
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, 90, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, 90, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
- -79, -79, -79, -79, -79, -79, -79, -79
-
- },
-
- {
- 5, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, 91, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
-
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- 91, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80
- },
-
- {
- 5, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
-
- -81, -81, -81, -81, -81, -81, -81, -81, -81, 92,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, 92, -81, -81, -81, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, -81
- },
-
- {
- 5, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
-
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, 93, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, 93, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82
- },
-
- {
- 5, -83, -83, -83, -83, -83, -83, -83, -83, -83,
-
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, 94, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
-
- -83, -83, -83, -83, 94, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83
- },
-
- {
- 5, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
-
- -84, -84, -84, -84, -84, 95, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, 95, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84
- },
-
- {
- 5, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
-
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, 96, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, 96, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85
- },
-
- {
- 5, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
-
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, 97,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, -86, -86, -86, -86, -86, -86, -86, -86, -86,
- -86, 97, -86, -86, -86, -86, -86, -86, -86, -86,
-
- -86, -86, -86, -86, -86, -86, -86, -86
- },
-
- {
- 5, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, 98, -87, -87, -87, -87,
-
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, 98, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87
- },
-
- {
- 5, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
-
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88
- },
-
- {
- 5, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
-
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, 99, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- 99, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89
-
- },
-
- {
- 5, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, 100, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
-
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, 100, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90
- },
-
- {
- 5, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, 101, -91,
-
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- 101, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, -91, -91, -91, -91
- },
-
- {
- 5, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
-
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, 102, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, 102, -92,
- -92, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, -92, -92, -92, -92, -92, -92, -92
- },
-
- {
- 5, -93, -93, -93, -93, -93, -93, -93, -93, -93,
-
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, 103,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
-
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, 103, -93, -93, -93, -93, -93, -93
- },
-
- {
- 5, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, 104, -94, -94, -94, -94, -94, -94,
-
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, 104, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, -94, -94, -94, -94, -94
- },
-
- {
- 5, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
-
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, 105, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, 105, -95, -95, -95, -95, -95,
- -95, -95, -95, -95, -95, -95, -95, -95
- },
-
- {
- 5, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
-
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, 106, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- 106, -96, -96, -96, -96, -96, -96, -96, -96, -96,
-
- -96, -96, -96, -96, -96, -96, -96, -96
- },
-
- {
- 5, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, 107, -97, -97, 108, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
-
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, 107, -97, -97, 108, -97,
- -97, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, -97, -97, -97, -97, -97
- },
-
- {
- 5, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
-
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, 109, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, 109, -98, -98, -98, -98, -98,
- -98, -98, -98, -98, -98, -98, -98, -98
- },
-
- {
- 5, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
-
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, 110, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, 110,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99
-
- },
-
- {
- 5, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, 111, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
-
- -100, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, 111, -100, -100, -100, -100,
- -100, -100, -100, -100, -100, -100, -100, -100
- },
-
- {
- 5, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, 112, -101, -101,
-
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, 112,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101
- },
-
- {
- 5, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
-
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, 113,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, 113, -102, -102, -102, -102, -102, -102
- },
-
- {
- 5, -103, -103, -103, -103, -103, -103, -103, -103, -103,
-
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, 114, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, 114,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
-
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103
- },
-
- {
- 5, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, 115, -104,
-
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- 115, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104
- },
-
- {
- 5, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
-
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, 116, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, -105, -105, -105, -105, -105, 116, -105,
- -105, -105, -105, -105, -105, -105, -105, -105
- },
-
- {
- 5, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
-
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, 117,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, 117, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
-
- -106, -106, -106, -106, -106, -106, -106, -106
- },
-
- {
- 5, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, 118, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
-
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- 118, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107
- },
-
- {
- 5, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
-
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, 119,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, 119, -108, -108, -108, -108, -108, -108
- },
-
- {
- 5, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
-
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- 120, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, 120, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, -109, -109, -109, -109, -109
-
- },
-
- {
- 5, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
-
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, -110, -110, -110, -110, -110
- },
-
- {
- 5, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
-
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, 121, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, 121, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111
- },
-
- {
- 5, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
-
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, 122, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, 122, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112
- },
-
- {
- 5, -113, -113, -113, -113, -113, -113, -113, -113, -113,
-
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, 123, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, 123, -113, -113, -113, -113, -113, -113,
-
- -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, -113, -113, -113, -113, -113
- },
-
- {
- 5, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, 124,
-
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, 124, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, -114, -114, -114, -114, -114
- },
-
- {
- 5, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
-
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, 125, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, 125, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, -115, -115, -115, -115, -115, -115, -115
- },
-
- {
- 5, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, 126,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, 126, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-
- -116, -116, -116, -116, -116, -116, -116, -116
- },
-
- {
- 5, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, 127, -117, -117, -117, -117, -117, -117,
-
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, 127, -117, -117, -117, -117,
- -117, -117, -117, -117, -117, -117, -117, -117
- },
-
- {
- 5, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
-
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, 128, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, 128, -118, -118, -118,
- -118, -118, -118, -118, -118, -118, -118, -118
- },
-
- {
- 5, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
-
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, 129, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, 129, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, -119, -119, -119, -119, -119
-
- },
-
- {
- 5, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, 130, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, 130, -120, -120,
-
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -120, -120, -120
- },
-
- {
- 5, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
-
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, 131, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, 131, -121, -121, -121, -121, -121,
- -121, -121, -121, -121, -121, -121, -121, -121
- },
-
- {
- 5, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
-
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, 132, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, 132, -122, -122, -122, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122
- },
-
- {
- 5, -123, -123, -123, -123, -123, -123, -123, -123, -123,
-
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, 133,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123, -123, -123,
-
- -123, 133, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, -123, -123, -123, -123, -123
- },
-
- {
- 5, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, 134, -124, -124, -124,
-
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, 134, -124,
- -124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -124, -124, -124
- },
-
- {
- 5, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
-
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, 135, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, 135,
- -125, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, -125, -125, -125, -125, -125
- },
-
- {
- 5, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
-
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, 136, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, 136,
- -126, -126, -126, -126, -126, -126, -126, -126, -126, -126,
-
- -126, -126, -126, -126, -126, -126, -126, -126
- },
-
- {
- 5, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, 137, -127, -127, -127, -127, -127,
-
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, 137, -127, -127, -127,
- -127, -127, -127, -127, -127, -127, -127, -127
- },
-
- {
- 5, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, 138, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, 138,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128
- },
-
- {
- 5, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
-
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, 139,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, 139, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, -129, -129, -129, -129, -129
-
- },
-
- {
- 5, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, 140, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, 140,
-
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, -130, -130, -130, -130, -130
- },
-
- {
- 5, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
-
- -131, -131, -131, 141, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, 141, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, -131, -131, -131, -131, -131
- },
-
- {
- 5, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
-
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, 142, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, -132, -132, -132, -132, -132, 142, -132,
- -132, -132, -132, -132, -132, -132, -132, -132
- },
-
- {
- 5, -133, -133, -133, -133, -133, -133, -133, -133, -133,
-
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, 143, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133, -133, -133,
-
- 143, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, -133, -133, -133, -133, -133
- },
-
- {
- 5, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, 144, -134, -134, -134,
-
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, 144, -134,
- -134, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, -134, -134, -134, -134, -134
- },
-
- {
- 5, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
-
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135
- },
-
- {
- 5, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
-
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, -136, -136, -136, -136, -136, -136, -136,
-
- -136, -136, -136, -136, -136, -136, -136, -136
- },
-
- {
- 5, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, 145, -137, -137, -137, -137, -137, -137, -137,
-
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, 145, -137, -137, -137, -137, -137,
- -137, -137, -137, -137, -137, -137, -137, -137
- },
-
- {
- 5, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
-
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, -138, -138, -138, -138, -138
- },
-
- {
- 5, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
-
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, 146, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- 146, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, -139, -139, -139, -139, -139
-
- },
-
- {
- 5, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, 147,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
-
- -140, 147, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140
- },
-
- {
- 5, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
-
- -141, -141, -141, -141, -141, -141, -141, -141, 148, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- 148, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, -141, -141, -141, -141, -141
- },
-
- {
- 5, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
-
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, 149,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, 149, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, -142, -142, -142, -142, -142
- },
-
- {
- 5, -143, -143, -143, -143, -143, -143, -143, -143, -143,
-
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, 150, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143, -143, 150,
-
- -143, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, -143, -143, -143, -143, -143
- },
-
- {
- 5, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, 151,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
-
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, 151, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, -144, -144, -144, -144, -144
- },
-
- {
- 5, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
-
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, 152, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, 152, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, -145, -145, -145, -145, -145
- },
-
- {
- 5, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
-
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, 153, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, 153,
- -146, -146, -146, -146, -146, -146, -146, -146, -146, -146,
-
- -146, -146, -146, -146, -146, -146, -146, -146
- },
-
- {
- 5, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, 154, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
-
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, 154,
- -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, -147, -147, -147, -147, -147
- },
-
- {
- 5, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
-
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, 155, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, 155, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, -148, -148, -148, -148, -148
- },
-
- {
- 5, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
-
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, 156, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, 156,
- -149, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, -149, -149, -149, -149, -149
-
- },
-
- {
- 5, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
-
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, -150, -150, -150, -150, -150
- },
-
- {
- 5, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, 157, -151, -151,
-
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, 157,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, -151, -151, -151, -151, -151
- },
-
- {
- 5, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
-
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, 158, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- 158, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, -152, -152, -152, -152, -152
- },
-
- {
- 5, -153, -153, -153, -153, -153, -153, -153, -153, -153,
-
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
-
- -153, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, -153, -153, -153, -153, -153
- },
-
- {
- 5, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
-
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, -154, -154, -154, -154, -154
- },
-
- {
- 5, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
-
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, 159, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, 159,
- -155, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, -155, -155, -155, -155, -155
- },
-
- {
- 5, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
-
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, -156, -156, -156, -156, -156, -156, -156,
-
- -156, -156, -156, -156, -156, -156, -156, -156
- },
-
- {
- 5, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, 160, -157, -157, -157, -157, -157,
-
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, 160, -157, -157, -157,
- -157, -157, -157, -157, -157, -157, -157, -157
- },
-
- {
- 5, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
-
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, 161, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, 161, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, -158, -158, -158, -158, -158
- },
-
- {
- 5, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
-
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, -159, -159, -159, -159, -159
-
- },
-
- {
- 5, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, 162, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
-
- -160, -160, -160, -160, -160, 162, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, -160, -160, -160, -160, -160
- },
-
- {
- 5, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
-
- -161, -161, -161, -161, -161, -161, -161, 163, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, 163,
- -161, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, -161, -161, -161, -161, -161
- },
-
- {
- 5, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
-
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, 164,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, 164, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, -162, -162, -162, -162, -162
- },
-
- {
- 5, -163, -163, -163, -163, -163, -163, -163, -163, -163,
-
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
-
- -163, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, -163, -163, -163, -163, -163
- },
-
- {
- 5, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, 165, -164,
-
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- 165, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, -164, -164, -164, -164, -164
- },
-
- {
- 5, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
-
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, 166, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, 166,
- -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, -165, -165, -165, -165, -165
- },
-
- {
- 5, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
-
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
-
- -166, -166, -166, -166, -166, -166, -166, -166
- },
-
- } ;
-
-
-static yy_state_type yy_get_previous_state YY_PROTO(( void ));
-static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
-static int yy_get_next_buffer YY_PROTO(( void ));
-static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yytext_ptr = yy_bp; \
- yyleng = (int) (yy_cp - yy_bp); \
- yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 38
-#define YY_END_OF_BUFFER 39
-static yyconst short int yy_accept[167] =
- { 0,
- 0, 0, 0, 0, 39, 37, 36, 36, 31, 32,
- 33, 37, 35, 34, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 1, 36, 3, 4, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 0,
- 0, 3, 4, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 29, 0, 2, 0,
- 0, 0, 30, 0, 0, 0, 5, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 11, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 21, 0, 17, 0, 0,
- 0, 0, 0, 0, 8, 22, 0, 18, 0, 0,
- 0, 0, 15, 0, 0, 23, 25, 0, 13, 16,
- 0, 0, 24, 26, 9, 14, 0, 0, 10, 0,
- 19, 0, 20, 0, 27, 28
- } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-static yyconst yy_state_type yy_NUL_trans[167] =
- { 0,
- 6, 6, 6, 6, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0
- } ;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "wktparse.lex"
-#define INITIAL 0
-/*
- * Written by Ralph Mason ralph.mason<at>telogis.com
- *
- * Copyright Telogis 2004
- * www.telogis.com
- *
- */
-#define vals_ok 1
-
-#line 11 "wktparse.lex"
-#include "wktparse.tab.h"
-#include <unistd.h>
-#include <stdlib.h> // need stdlib for atof() definition
-
-void init_parser(const char *src);
-void close_parser(void);
-int lwg_parse_yywrap(void);
-int lwg_parse_yylex(void);
-
-static YY_BUFFER_STATE buf_state;
- void init_parser(const char *src) { BEGIN(0);buf_state = lwg_parse_yy_scan_string(src); }
- void close_parser() { lwg_parse_yy_delete_buffer(buf_state); }
- int lwg_parse_yywrap(void){ return 1; }
-
-#line 3281 "lex.yy.c"
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap YY_PROTO(( void ));
-#else
-extern int yywrap YY_PROTO(( void ));
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-static void yyunput YY_PROTO(( int c, char *buf_ptr ));
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen YY_PROTO(( yyconst char * ));
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-static int yyinput YY_PROTO(( void ));
-#else
-static int input YY_PROTO(( void ));
-#endif
-#endif
-
-#if YY_STACK_USED
-static int yy_start_stack_ptr = 0;
-static int yy_start_stack_depth = 0;
-static int *yy_start_stack = 0;
-#ifndef YY_NO_PUSH_STATE
-static void yy_push_state YY_PROTO(( int new_state ));
-#endif
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state YY_PROTO(( void ));
-#endif
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state YY_PROTO(( void ));
-#endif
-
-#else
-#define YY_NO_PUSH_STATE 1
-#define YY_NO_POP_STATE 1
-#define YY_NO_TOP_STATE 1
-#endif
-
-#ifdef YY_MALLOC_DECL
-YY_MALLOC_DECL
-#else
-#if __STDC__
-#ifndef __cplusplus
-#include <stdlib.h>
-#endif
-#else
-/* Just try to get by without declaring the routines. This will fail
- * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
- * or sizeof(void*) != sizeof(int).
- */
-#endif
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
- YY_FATAL_ERROR( "input in flex scanner failed" );
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL int yylex YY_PROTO(( void ))
-#endif
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-YY_DECL
- {
- register yy_state_type yy_current_state;
- register char *yy_cp = NULL, *yy_bp = NULL;
- register int yy_act;
-
-#line 27 "wktparse.lex"
-
-
-#line 3422 "lex.yy.c"
-
- if ( yy_init )
- {
- yy_init = 0;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yy_start )
- yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! yy_current_buffer )
- yy_current_buffer =
- yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_load_buffer_state();
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yy_start;
-yy_match:
- while ( (yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]) > 0 )
- {
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
-
- ++yy_cp;
- }
-
- yy_current_state = -yy_current_state;
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
-
- YY_DO_BEFORE_ACTION;
-
-
-do_action: /* This label is used only to access EOF actions. */
-
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yy_hold_char;
- yy_cp = yy_last_accepting_cpos + 1;
- yy_current_state = yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 29 "wktparse.lex"
-{ lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 30 "wktparse.lex"
-{ lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 32 "wktparse.lex"
-{ lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 33 "wktparse.lex"
-{ lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 35 "wktparse.lex"
-{ return POINT; }
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 36 "wktparse.lex"
-{ return POINTM; }
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 37 "wktparse.lex"
-{ return LINESTRING; }
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 38 "wktparse.lex"
-{ return LINESTRINGM; }
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 39 "wktparse.lex"
-{ return CIRCULARSTRING; }
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 40 "wktparse.lex"
-{ return CIRCULARSTRINGM; }
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 41 "wktparse.lex"
-{ return POLYGON; }
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 42 "wktparse.lex"
-{ return POLYGONM; }
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 43 "wktparse.lex"
-{ return COMPOUNDCURVE; }
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 44 "wktparse.lex"
-{ return COMPOUNDCURVEM; }
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 45 "wktparse.lex"
-{ return CURVEPOLYGON; }
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 46 "wktparse.lex"
-{ return CURVEPOLYGONM; }
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 47 "wktparse.lex"
-{ return MULTIPOINT; }
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 48 "wktparse.lex"
-{ return MULTIPOINTM; }
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 49 "wktparse.lex"
-{ return MULTILINESTRING; }
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 50 "wktparse.lex"
-{ return MULTILINESTRINGM; }
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 51 "wktparse.lex"
-{ return MULTICURVE; }
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 52 "wktparse.lex"
-{ return MULTICURVEM; }
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 53 "wktparse.lex"
-{ return MULTIPOLYGON; }
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 54 "wktparse.lex"
-{ return MULTIPOLYGONM; }
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 55 "wktparse.lex"
-{ return MULTISURFACE; }
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 56 "wktparse.lex"
-{ return MULTISURFACEM; }
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 57 "wktparse.lex"
-{ return GEOMETRYCOLLECTION; }
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 58 "wktparse.lex"
-{ return GEOMETRYCOLLECTIONM; }
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 59 "wktparse.lex"
-{ BEGIN(vals_ok); return SRID; }
- YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 60 "wktparse.lex"
-{ return EMPTY; }
- YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 62 "wktparse.lex"
-{ BEGIN(vals_ok); return LPAREN; }
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 63 "wktparse.lex"
-{ return RPAREN; }
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-#line 64 "wktparse.lex"
-{ return COMMA ; }
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 65 "wktparse.lex"
-{ return EQUALS ; }
- YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 66 "wktparse.lex"
-{ BEGIN(0); return SEMICOLON; }
- YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 67 "wktparse.lex"
-/*eat whitespace*/
- YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 68 "wktparse.lex"
-{ return lwg_parse_yytext[0]; }
- YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 70 "wktparse.lex"
-ECHO;
- YY_BREAK
-#line 3683 "lex.yy.c"
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(vals_ok):
- yyterminate();
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * yylex(). If so, then we have to assure
- * consistency between yy_current_buffer and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yy_current_buffer->yy_input_file = yyin;
- yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state();
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state );
-
- yy_bp = yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yy_c_buf_p;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer() )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yy_did_buffer_switch_on_eof = 0;
-
- if ( yywrap() )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p =
- yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state();
-
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yy_c_buf_p =
- &yy_current_buffer->yy_ch_buf[yy_n_chars];
-
- yy_current_state = yy_get_previous_state();
-
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
- } /* end of yylex */
-
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-
-static int yy_get_next_buffer()
- {
- register char *dest = yy_current_buffer->yy_ch_buf;
- register char *source = yytext_ptr;
- register int number_to_move, i;
- int ret_val;
-
- if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( yy_current_buffer->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- yy_current_buffer->yy_n_chars = yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- yy_current_buffer->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-#ifdef YY_USES_REJECT
- YY_FATAL_ERROR(
-"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-#else
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = yy_current_buffer;
-
- int yy_c_buf_p_offset =
- (int) (yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- yy_flex_realloc( (void *) b->yy_ch_buf,
- b->yy_buf_size + 2 );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = yy_current_buffer->yy_buf_size -
- number_to_move - 1;
-#endif
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
- yy_n_chars, num_to_read );
-
- yy_current_buffer->yy_n_chars = yy_n_chars;
- }
-
- if ( yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- yyrestart( yyin );
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- yy_current_buffer->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- yy_n_chars += number_to_move;
- yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
-
- return ret_val;
- }
-
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-static yy_state_type yy_get_previous_state()
- {
- register yy_state_type yy_current_state;
- register char *yy_cp;
-
- yy_current_state = yy_start;
-
- for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
- {
- if ( *yy_cp )
- {
- yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)];
- }
- else
- yy_current_state = yy_NUL_trans[yy_current_state];
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- }
-
- return yy_current_state;
- }
-
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
-
-#ifdef YY_USE_PROTOS
-static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
-#else
-static yy_state_type yy_try_NUL_trans( yy_current_state )
-yy_state_type yy_current_state;
-#endif
- {
- register int yy_is_jam;
- register char *yy_cp = yy_c_buf_p;
-
- yy_current_state = yy_NUL_trans[yy_current_state];
- yy_is_jam = (yy_current_state == 0);
-
- if ( ! yy_is_jam )
- {
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- }
-
- return yy_is_jam ? 0 : yy_current_state;
- }
-
-
-#ifndef YY_NO_UNPUT
-#ifdef YY_USE_PROTOS
-static void yyunput( int c, register char *yy_bp )
-#else
-static void yyunput( c, yy_bp )
-int c;
-register char *yy_bp;
-#endif
- {
- register char *yy_cp = yy_c_buf_p;
-
- /* undo effects of setting up yytext */
- *yy_cp = yy_hold_char;
-
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = yy_n_chars + 2;
- register char *dest = &yy_current_buffer->yy_ch_buf[
- yy_current_buffer->yy_buf_size + 2];
- register char *source =
- &yy_current_buffer->yy_ch_buf[number_to_move];
-
- while ( source > yy_current_buffer->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- yy_current_buffer->yy_n_chars =
- yy_n_chars = yy_current_buffer->yy_buf_size;
-
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
-
- yytext_ptr = yy_bp;
- yy_hold_char = *yy_cp;
- yy_c_buf_p = yy_cp;
- }
-#endif /* ifndef YY_NO_UNPUT */
-
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-static int yyinput()
-#else
-static int input()
-#endif
- {
- int c;
-
- *yy_c_buf_p = yy_hold_char;
-
- if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
- /* This was really a NUL. */
- *yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yy_c_buf_p - yytext_ptr;
- ++yy_c_buf_p;
-
- switch ( yy_get_next_buffer() )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- yyrestart( yyin );
-
- /* fall through */
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( yywrap() )
- return EOF;
-
- if ( ! yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput();
-#else
- return input();
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p = yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
- *yy_c_buf_p = '\0'; /* preserve yytext */
- yy_hold_char = *++yy_c_buf_p;
-
-
- return c;
- }
-#endif /* YY_NO_INPUT */
-
-#ifdef YY_USE_PROTOS
-void yyrestart( FILE *input_file )
-#else
-void yyrestart( input_file )
-FILE *input_file;
-#endif
- {
- if ( ! yy_current_buffer )
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_init_buffer( yy_current_buffer, input_file );
- yy_load_buffer_state();
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
-#else
-void yy_switch_to_buffer( new_buffer )
-YY_BUFFER_STATE new_buffer;
-#endif
- {
- if ( yy_current_buffer == new_buffer )
- return;
-
- if ( yy_current_buffer )
- {
- /* Flush out information for old buffer. */
- *yy_c_buf_p = yy_hold_char;
- yy_current_buffer->yy_buf_pos = yy_c_buf_p;
- yy_current_buffer->yy_n_chars = yy_n_chars;
- }
-
- yy_current_buffer = new_buffer;
- yy_load_buffer_state();
-
- /* We don't actually know whether we did this switch during
- * EOF (yywrap()) processing, but the only time this flag
- * is looked at is after yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yy_did_buffer_switch_on_eof = 1;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_load_buffer_state( void )
-#else
-void yy_load_buffer_state()
-#endif
- {
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
- yyin = yy_current_buffer->yy_input_file;
- yy_hold_char = *yy_c_buf_p;
- }
-
-
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
-#else
-YY_BUFFER_STATE yy_create_buffer( file, size )
-FILE *file;
-int size;
-#endif
- {
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- yy_init_buffer( b, file );
-
- return b;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_delete_buffer( YY_BUFFER_STATE b )
-#else
-void yy_delete_buffer( b )
-YY_BUFFER_STATE b;
-#endif
- {
- if ( ! b )
- return;
-
- if ( b == yy_current_buffer )
- yy_current_buffer = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- yy_flex_free( (void *) b->yy_ch_buf );
-
- yy_flex_free( (void *) b );
- }
-
-
-
-#ifdef YY_USE_PROTOS
-void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
-#else
-void yy_init_buffer( b, file )
-YY_BUFFER_STATE b;
-FILE *file;
-#endif
-
-
- {
- yy_flush_buffer( b );
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
-#if YY_ALWAYS_INTERACTIVE
- b->yy_is_interactive = 1;
-#else
-#if YY_NEVER_INTERACTIVE
- b->yy_is_interactive = 0;
-#else
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-#endif
-#endif
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_flush_buffer( YY_BUFFER_STATE b )
-#else
-void yy_flush_buffer( b )
-YY_BUFFER_STATE b;
-#endif
-
- {
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == yy_current_buffer )
- yy_load_buffer_state();
- }
-
-
-#ifndef YY_NO_SCAN_BUFFER
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
-#else
-YY_BUFFER_STATE yy_scan_buffer( base, size )
-char *base;
-yy_size_t size;
-#endif
- {
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- yy_switch_to_buffer( b );
-
- return b;
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_STRING
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
-#else
-YY_BUFFER_STATE yy_scan_string( yy_str )
-yyconst char *yy_str;
-#endif
- {
- int len;
- for ( len = 0; yy_str[len]; ++len )
- ;
-
- return yy_scan_bytes( yy_str, len );
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_BYTES
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
-#else
-YY_BUFFER_STATE yy_scan_bytes( bytes, len )
-yyconst char *bytes;
-int len;
-#endif
- {
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = len + 2;
- buf = (char *) yy_flex_alloc( n );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
- for ( i = 0; i < len; ++i )
- buf[i] = bytes[i];
-
- buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = yy_scan_buffer( buf, n );
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
- }
-#endif
-
-
-#ifndef YY_NO_PUSH_STATE
-#ifdef YY_USE_PROTOS
-static void yy_push_state( int new_state )
-#else
-static void yy_push_state( new_state )
-int new_state;
-#endif
- {
- if ( yy_start_stack_ptr >= yy_start_stack_depth )
- {
- yy_size_t new_size;
-
- yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yy_start_stack_depth * sizeof( int );
-
- if ( ! yy_start_stack )
- yy_start_stack = (int *) yy_flex_alloc( new_size );
-
- else
- yy_start_stack = (int *) yy_flex_realloc(
- (void *) yy_start_stack, new_size );
-
- if ( ! yy_start_stack )
- YY_FATAL_ERROR(
- "out of memory expanding start-condition stack" );
- }
-
- yy_start_stack[yy_start_stack_ptr++] = YY_START;
-
- BEGIN(new_state);
- }
-#endif
-
-
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state()
- {
- if ( --yy_start_stack_ptr < 0 )
- YY_FATAL_ERROR( "start-condition stack underflow" );
-
- BEGIN(yy_start_stack[yy_start_stack_ptr]);
- }
-#endif
-
-
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state()
- {
- return yy_start_stack[yy_start_stack_ptr - 1];
- }
-#endif
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-#ifdef YY_USE_PROTOS
-static void yy_fatal_error( yyconst char msg[] )
-#else
-static void yy_fatal_error( msg )
-char msg[];
-#endif
- {
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
- }
-
-
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- yytext[yyleng] = yy_hold_char; \
- yy_c_buf_p = yytext + n; \
- yy_hold_char = *yy_c_buf_p; \
- *yy_c_buf_p = '\0'; \
- yyleng = n; \
- } \
- while ( 0 )
-
-
-/* Internal utility routines. */
-
-#ifndef yytext_ptr
-#ifdef YY_USE_PROTOS
-static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
-#else
-static void yy_flex_strncpy( s1, s2, n )
-char *s1;
-yyconst char *s2;
-int n;
-#endif
- {
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
- }
-#endif
-
-#ifdef YY_NEED_STRLEN
-#ifdef YY_USE_PROTOS
-static int yy_flex_strlen( yyconst char *s )
-#else
-static int yy_flex_strlen( s )
-yyconst char *s;
-#endif
- {
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
- }
-#endif
-
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_alloc( yy_size_t size )
-#else
-static void *yy_flex_alloc( size )
-yy_size_t size;
-#endif
- {
- return (void *) malloc( size );
- }
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_realloc( void *ptr, yy_size_t size )
-#else
-static void *yy_flex_realloc( ptr, size )
-void *ptr;
-yy_size_t size;
-#endif
- {
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
- }
-
-#ifdef YY_USE_PROTOS
-static void yy_flex_free( void *ptr )
-#else
-static void yy_flex_free( ptr )
-void *ptr;
-#endif
- {
- free( ptr );
- }
-
-#if YY_MAIN
-int main()
- {
- yylex();
- return 0;
- }
-#endif
-#line 70 "wktparse.lex"
-
-
Deleted: trunk/lwgeom/liblwgeom.c
===================================================================
--- trunk/lwgeom/liblwgeom.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/liblwgeom.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,205 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#define CONTEXT_PG 0
-#define CONTEXT_SA 1
-
-
-
-#ifdef STANDALONE
-#define DEFAULT_CONTEXT CONTEXT_SA
-#else
-#define DEFAULT_CONTEXT CONTEXT_PG
-#endif
-
-/* Global variables */
-#include "../postgis_config.h"
-
-#if DEFAULT_CONTEXT == CONTEXT_SA
-#include "liblwgeom.h"
-lwallocator lwalloc_var = default_allocator;
-lwreallocator lwrealloc_var = default_reallocator;
-lwfreeor lwfree_var = default_freeor;
-lwreporter lwerror = default_errorreporter;
-lwreporter lwnotice = default_noticereporter;
-#else
-#include "lwgeom_pg.h"
-#include "liblwgeom.h"
-
-lwallocator lwalloc_var = pg_alloc;
-lwreallocator lwrealloc_var = pg_realloc;
-lwfreeor lwfree_var = pg_free;
-lwreporter lwerror = pg_error;
-lwreporter lwnotice = pg_notice;
-#endif
-
-
-static char *lwgeomTypeName[] = {
- "Unknown",
- "Point",
- "Line",
- "Polygon",
- "MultiPoint",
- "MultiLine",
- "MultiPolygon",
- "GeometryCollection",
- "Curve",
- "CompoundString",
- "Invalid Type", /* POINTTYPEI */
- "Invalid Type", /* LINETYPEI */
- "Invalid Type", /* POLYTYPEI */
- "CurvePolygon",
- "MultiCurve",
- "MultiSurface"
-};
-
-void *
-default_allocator(size_t size)
-{
- void *mem = malloc(size);
- return mem;
-}
-
-void
-default_freeor(void *mem)
-{
- free(mem);
-}
-
-void *
-default_reallocator(void *mem, size_t size)
-{
- void *ret = realloc(mem, size);
- return ret;
-}
-
-void
-default_noticereporter(const char *fmt, ...)
-{
- char *msg;
- va_list ap;
-
- va_start (ap, fmt);
-
- /*
- * This is a GNU extension.
- * Dunno how to handle errors here.
- */
- if (!vasprintf (&msg, fmt, ap))
- {
- va_end (ap);
- return;
- }
- printf("%s\n", msg);
- va_end(ap);
- free(msg);
-}
-
-void
-default_errorreporter(const char *fmt, ...)
-{
- char *msg;
- va_list ap;
-
- va_start (ap, fmt);
-
- /*
- * This is a GNU extension.
- * Dunno how to handle errors here.
- */
- if (!vasprintf (&msg, fmt, ap))
- {
- va_end (ap);
- return;
- }
- fprintf(stderr, "%s\n", msg);
- va_end(ap);
- free(msg);
- exit(1);
-}
-
-const char *
-lwgeom_typename(int type)
-{
- // something went wrong somewhere
- if ( type < 0 || type > 12 ) {
- // assert(0);
- return "Invalid type";
- }
- return lwgeomTypeName[type];
-}
-
-void *
-lwalloc(size_t size)
-{
- void *mem = lwalloc_var(size);
- LWDEBUGF(5, "lwalloc: %d@%p", size, mem);
- return mem;
-}
-
-void *
-lwrealloc(void *mem, size_t size)
-{
- LWDEBUGF(5, "lwrealloc: %d@%p", size, mem);
- return lwrealloc_var(mem, size);
-}
-
-void
-lwfree(void *mem)
-{
- lwfree_var(mem);
-}
-
-/*
- * Removes trailing zeros and dot for a %f formatted number.
- * Modifies input.
- */
-void
-trim_trailing_zeros(char *str)
-{
- char *ptr, *totrim=NULL;
- int len;
- int i;
-
- LWDEBUGF(3, "input: %s", str);
-
- ptr = strchr(str, '.');
- if ( ! ptr ) return; /* no dot, no decimal digits */
-
- LWDEBUGF(3, "ptr: %s", ptr);
-
- len = strlen(ptr);
- for (i=len-1; i; i--)
- {
- if ( ptr[i] != '0' ) break;
- totrim=&ptr[i];
- }
- if ( totrim )
- {
- if ( ptr == totrim-1 ) *ptr = '\0';
- else *totrim = '\0';
- }
-
- LWDEBUGF(3, "output: %s", str);
-}
-
-char
-getMachineEndian(void)
-{
- static int endian_check_int = 1; /* dont modify this!!! */
-
- return *((char *) &endian_check_int); /* 0 = big endian | xdr,
- * 1 = little endian | ndr
- */
-}
-
-
-void
-errorIfSRIDMismatch(int srid1, int srid2)
-{
- if ( srid1 != srid2 )
- {
- lwerror("Operation on mixed SRID geometries");
- }
-}
Deleted: trunk/lwgeom/liblwgeom.h
===================================================================
--- trunk/lwgeom/liblwgeom.h 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/liblwgeom.h 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,1263 +0,0 @@
-#ifndef _LIBLWGEOM_H
-#define _LIBLWGEOM_H 1
-
-#include "../postgis_config.h"
-#include <stdio.h>
-#include "compat.h"
-
-#define INTEGRITY_CHECKS 1
-
-/*
- * Floating point comparitors.
- */
-#define PGIS_EPSILON 1e-12
-#define FP_MAX(A, B) ((A > B) ? A : B)
-#define FP_MIN(A, B) ((A < B) ? A : B)
-#define FP_LT(A, B) ((A + PGIS_EPSILON) < B)
-#define FP_LTEQ(A, B) ((A - PGIS_EPSILON) <= B)
-#define FP_CONTAINS_TOP(A, X, B) (FP_LT(A, X) && FP_LTEQ(X, B))
-#define FP_CONTAINS_BOTTOM(A, X, B) (FP_LTEQ(A, X) && FP_LT(X, B))
-#define FP_CONTAINS_INCL(A, X, B) (FP_LTEQ(A, X) && FP_LTEQ(X, B))
-#define FP_CONTAINS_EXCL(A, X, B) (FP_LT(A, X) && FP_LT(X, B))
-#define FP_CONTAINS(A, X, B) FP_CONTAINS_EXCL(A, X, B)
-
-/*
- * Memory management function types
- */
-typedef void* (*lwallocator)(size_t size);
-typedef void* (*lwreallocator)(void *mem, size_t size);
-typedef void (*lwfreeor)(void* mem);
-typedef void (*lwreporter)(const char* fmt, ...);
-
-#ifndef C_H
-
-typedef unsigned int uint32;
-typedef int int32;
-
-#endif
-
-/*
- * this will change to NaN when I figure out how to
- * get NaN in a platform-independent way
- */
-#define NO_VALUE 0.0
-#define NO_Z_VALUE NO_VALUE
-#define NO_M_VALUE NO_VALUE
-
-
-/* prototypes */
-void *default_allocator(size_t size);
-void *default_reallocator(void *mem, size_t size);
-void default_freeor(void *ptr);
-void default_errorreporter(const char *fmt, ...);
-void default_noticereporter(const char *fmt, ...);
-
-/* globals */
-extern lwreallocator lwrealloc_var;
-extern lwallocator lwalloc_var;
-extern lwfreeor lwfree_var;
-extern lwreporter lwerror;
-extern lwreporter lwnotice;
-
-/* Debug macros */
-#if POSTGIS_DEBUG_LEVEL > 0
-
-/* Display a notice at the given debug level */
-#define LWDEBUG(level, msg) \
- do { \
- if (POSTGIS_DEBUG_LEVEL >= level) \
- lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__); \
- } while (0);
-
-/* Display a formatted notice at the given debug level (like printf, with variadic arguments) */
-#define LWDEBUGF(level, msg, ...) \
- do { \
- if (POSTGIS_DEBUG_LEVEL >= level) \
- lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__, __VA_ARGS__); \
- } while (0);
-
-#else
-
-/* Empty prototype that can be optimised away by the compiler for non-debug builds */
-#define LWDEBUG(level, msg) \
- ((void) 0)
-
-/* Empty prototype that can be optimised away by the compiler for non-debug builds */
-#define LWDEBUGF(level, msg, ...) \
- ((void) 0)
-
-#endif
-
-/******************************************************************/
-
-typedef unsigned char uchar;
-
-typedef struct
-{
- float xmin;
- float ymin;
- float xmax;
- float ymax;
-} BOX2DFLOAT4;
-
-typedef struct
-{
- double xmin, ymin, zmin;
- double xmax, ymax, zmax;
-} BOX3D;
-
-typedef struct chiptag
-{
- int size; /* unused (for use by postgresql) */
-
- int endian_hint; /* the number 1 in the endian of this datastruct */
-
- BOX3D bvol;
- int SRID;
- char future[4];
- float factor; /* Usually 1.0.
- * Integer values are multiplied by this number
- * to get the actual height value
- * (for sub-meter accuracy height data).
- */
-
- int datatype; /* 1 = float32,
- * 5 = 24bit integer,
- * 6 = 16bit integer (short)
- * 7 = 16bit ???
- * 8 = 8bit ???
- * 101 = float32 (NDR),
- * 105 = 24bit integer (NDR),
- * 106 = 16bit int (NDR)
- * 107 = 16bit ??? (NDR)
- * 108 = 8bit ??? (NDR) (this doesn't make sense)
- */
- int height;
- int width;
- int compression; /* 0 = no compression, 1 = differencer
- * 0x80 = new value
- * 0x7F = nodata
- */
-
- /*
- * this is provided for convenience, it should be set to
- * sizeof(chip) bytes into the struct because the serialized form is:
- * <header><data>
- * NULL when serialized
- */
- void *data; /* data[0] = bottm left,
- * data[width] = 1st pixel, 2nd row (uncompressed)
- */
-
-} CHIP;
-
-/*
- * standard definition of an ellipsoid (what wkt calls a spheroid)
- * f = (a-b)/a
- * e_sq = (a*a - b*b)/(a*a)
- * b = a - fa
- */
-typedef struct
-{
- double a; /* semimajor axis */
- double b; /* semiminor axis */
- double f; /* flattening */
- double e; /* eccentricity (first) */
- double e_sq; /* eccentricity (first), squared */
- char name[20]; /* name of ellipse */
-} SPHEROID;
-
-
-/*
- * ALL LWGEOM structures will use POINT3D as an abstract point.
- * This means a 2d geometry will be stored as (x,y) in its serialized
- * form, but all functions will work on (x,y,0). This keeps all the
- * analysis functions simple.
- * NOTE: for GEOS integration, we'll probably set z=NaN
- * so look out - z might be NaN for 2d geometries!
- */
-typedef struct { double x,y,z; } POINT3DZ;
-typedef struct { double x,y,z; } POINT3D; /* alias for POINT3DZ */
-typedef struct { double x,y,m; } POINT3DM;
-
-
-/*
- * type for 2d points. When you convert this to 3d, the
- * z component will be either 0 or NaN.
- */
-typedef struct
-{
- double x;
- double y;
-} POINT2D;
-
-typedef struct
-{
- double x;
- double y;
- double z;
- double m;
-} POINT4D;
-
-/******************************************************************/
-
-/*
- * Point array abstracts a lot of the complexity of points and point lists.
- * It handles miss-alignment in the serialized form, 2d/3d translation
- * (2d points converted to 3d will have z=0 or NaN)
- * DONT MIX 2D and 3D POINTS! *EVERYTHING* is either one or the other
- */
-typedef struct
-{
- /* array of POINT 2D, 3D or 4D. probably missaligned. */
- uchar *serialized_pointlist;
-
- /* use TYPE_* macros to handle */
- uchar dims;
-
- uint32 npoints;
-} POINTARRAY;
-
-
-/*
- * Use the following to build pointarrays
- * when number of points in output is not
- * known in advance
- */
-typedef struct {
- POINTARRAY *pa;
- size_t ptsize;
- size_t capacity; /* given in points */
-} DYNPTARRAY;
-
-/* Create a new dynamic pointarray */
-extern DYNPTARRAY *dynptarray_create(size_t initial_capacity, int dims);
-
-/*
- * Add a POINT4D to the dynamic pointarray.
- *
- * The dynamic pointarray may be of any dimension, only
- * accepted dimensions will be copied.
- *
- * If allow_duplicates is set to 0 (false) a check
- * is performed to see if last point in array is equal to the
- * provided one. NOTE that the check is 4d based, with missing
- * ordinates in the pointarray set to NO_Z_VALUE and NO_M_VALUE
- * respectively.
- */
-extern int dynptarray_addPoint4d(DYNPTARRAY *dpa, POINT4D *p4d,
- int allow_duplicates);
-
-/******************************************************************
- *
- * LWGEOM (any type)
- *
- ******************************************************************/
-
-typedef struct
-{
- uchar type;
- BOX2DFLOAT4 *bbox;
- uint32 SRID; /* -1 == unneeded */
- void *data;
-} LWGEOM;
-
-/* POINTYPE */
-typedef struct
-{
- uchar type; /* POINTTYPE */
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- POINTARRAY *point; /* hide 2d/3d (this will be an array of 1 point) */
-} LWPOINT; /* "light-weight point" */
-
-/* LINETYPE */
-typedef struct
-{
- uchar type; /* LINETYPE */
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- POINTARRAY *points; /* array of POINT3D */
-} LWLINE; /* "light-weight line" */
-
-/* POLYGONTYPE */
-typedef struct
-{
- uchar type; /* POLYGONTYPE */
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int nrings;
- POINTARRAY **rings; /* list of rings (list of points) */
-} LWPOLY; /* "light-weight polygon" */
-
-/* MULTIPOINTTYPE */
-typedef struct
-{
- uchar type;
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int ngeoms;
- LWPOINT **geoms;
-} LWMPOINT;
-
-/* MULTILINETYPE */
-typedef struct
-{
- uchar type;
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int ngeoms;
- LWLINE **geoms;
-} LWMLINE;
-
-/* MULTIPOLYGONTYPE */
-typedef struct
-{
- uchar type;
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int ngeoms;
- LWPOLY **geoms;
-} LWMPOLY;
-
-/* COLLECTIONTYPE */
-typedef struct
-{
- uchar type;
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int ngeoms;
- LWGEOM **geoms;
-} LWCOLLECTION;
-
-/* Casts LWGEOM->LW* (return NULL if cast is illegal) */
-extern LWMPOLY *lwgeom_as_lwmpoly(LWGEOM *lwgeom);
-extern LWMLINE *lwgeom_as_lwmline(LWGEOM *lwgeom);
-extern LWMPOINT *lwgeom_as_lwmpoint(LWGEOM *lwgeom);
-extern LWCOLLECTION *lwgeom_as_lwcollection(LWGEOM *lwgeom);
-extern LWPOLY *lwgeom_as_lwpoly(LWGEOM *lwgeom);
-extern LWLINE *lwgeom_as_lwline(LWGEOM *lwgeom);
-extern LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom);
-
-/* Casts LW*->LWGEOM (always cast) */
-extern LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj);
-extern LWGEOM *lwmline_as_lwgeom(LWMLINE *obj);
-extern LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj);
-extern LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj);
-extern LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj);
-extern LWGEOM *lwline_as_lwgeom(LWLINE *obj);
-extern LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj);
-
-/*
- * Call this function everytime LWGEOM coordinates
- * change so to invalidate bounding box
- */
-extern void lwgeom_changed(LWGEOM *lwgeom);
-
-/*
- * Call this function to drop BBOX and SRID
- * from LWGEOM. If LWGEOM type is *not* flagged
- * with the HASBBOX flag and has a bbox, it
- * will be released.
- */
-extern void lwgeom_dropBBOX(LWGEOM *lwgeom);
-
-/* Compute a bbox if not already computed */
-extern void lwgeom_addBBOX(LWGEOM *lwgeom);
-
-extern void lwgeom_dropSRID(LWGEOM *lwgeom);
-
-/******************************************************************/
-
-/*
- * copies a point from the point array into the parameter point
- * will set point's z=0 (or NaN) if pa is 2d
- * will set point's m=0 (or NaN) if pa is 3d or 2d
- * NOTE: point is a real POINT3D *not* a pointer
- */
-extern POINT4D getPoint4d(const POINTARRAY *pa, int n);
-
-/*
- * copies a point from the point array into the parameter point
- * will set point's z=0 (or NaN) if pa is 2d
- * will set point's m=0 (or NaN) if pa is 3d or 2d
- * NOTE: this will modify the point4d pointed to by 'point'.
- */
-extern int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point);
-
-/*
- * copies a point from the point array into the parameter point
- * will set point's z=0 (or NaN) if pa is 2d
- * NOTE: point is a real POINT3D *not* a pointer
- */
-extern POINT3DZ getPoint3dz(const POINTARRAY *pa, int n);
-extern POINT3DM getPoint3dm(const POINTARRAY *pa, int n);
-
-/*
- * copies a point from the point array into the parameter point
- * will set point's z=0 (or NaN) if pa is 2d
- * NOTE: this will modify the point3d pointed to by 'point'.
- */
-extern int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point);
-extern int getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *point);
-
-
-/*
- * copies a point from the point array into the parameter point
- * z value (if present is not returned)
- * NOTE: point is a real POINT3D *not* a pointer
- */
-extern POINT2D getPoint2d(const POINTARRAY *pa, int n);
-
-/*
- * copies a point from the point array into the parameter point
- * z value (if present is not returned)
- * NOTE: this will modify the point2d pointed to by 'point'.
- */
-extern int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point);
-
-/*
- * set point N to the given value
- * NOTE that the pointarray can be of any
- * dimension, the appropriate ordinate values
- * will be extracted from it
- *
- */
-extern void setPoint4d(POINTARRAY *pa, int n, POINT4D *p4d);
-
-/*
- * get a pointer to nth point of a POINTARRAY
- * You'll need to cast it to appropriate dimensioned point.
- * Note that if you cast to a higher dimensional point you'll
- * possibly corrupt the POINTARRAY.
- *
- * WARNING: Don't cast this to a POINT !
- * it would not be reliable due to memory alignment constraints
- */
-extern uchar *getPoint_internal(const POINTARRAY *pa, int n);
-
-/* --- here is a macro equivalent, for speed... */
-/* #define getPoint(x,n) &( (x)->serialized_pointlist[((x)->ndims*8)*(n)] ) */
-
-
-/*
- * constructs a POINTARRAY.
- * NOTE: points is *not* copied, so be careful about modification
- * (can be aligned/missaligned)
- * NOTE: hasz and hasm are descriptive - it describes what type of data
- * 'points' points to. No data conversion is done.
- */
-extern POINTARRAY *pointArray_construct(uchar *points, char hasz, char hasm,
- uint32 npoints);
-
-/*
- * Calculate the (BOX3D) bounding box of a set of points.
- * Returns an alloced BOX3D or NULL (for empty geom) in the first form.
- * Write result in user-provided BOX3D in second form (return 0 if untouched).
- * If pa is 2d, then box3d's zmin/zmax will be set to NO_Z_VALUE
- */
-extern BOX3D *ptarray_compute_box3d(const POINTARRAY *pa);
-extern int ptarray_compute_box3d_p(const POINTARRAY *pa, BOX3D *out);
-
-/*
- * size of point represeneted in the POINTARRAY
- * 16 for 2d, 24 for 3d, 32 for 4d
- */
-extern int pointArray_ptsize(const POINTARRAY *pa);
-
-
-#define POINTTYPE 1
-#define LINETYPE 2
-#define POLYGONTYPE 3
-#define MULTIPOINTTYPE 4
-#define MULTILINETYPE 5
-#define MULTIPOLYGONTYPE 6
-#define COLLECTIONTYPE 7
-
-#define WKBZOFFSET 0x80000000
-#define WKBMOFFSET 0x40000000
-#define WKBSRIDFLAG 0x20000000
-#define WKBBBOXFLAG 0x10000000
-
-/* These macros work on PG_LWGEOM.type, LWGEOM.type and all its subclasses */
-
-#define TYPE_SETTYPE(c,t) ((c)=(((c)&0xF0)|(t)))
-#define TYPE_SETZM(t,z,m) ((t)=(((t)&0xCF)|((z)<<5)|((m)<<4)))
-#define TYPE_SETHASBBOX(t,b) ((t)=(((t)&0x7F)|((b)<<7)))
-#define TYPE_SETHASSRID(t,s) ((t)=(((t)&0xBF)|((s)<<6)))
-
-#define TYPE_HASZ(t) ( ((t)&0x20)>>5 )
-#define TYPE_HASM(t) ( ((t)&0x10)>>4 )
-#define TYPE_HASBBOX(t) ( ((t)&0x80)>>7 )
-#define TYPE_HASSRID(t) ( (((t)&0x40))>>6 )
-#define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2)
-#define TYPE_GETTYPE(t) ((t)&0x0F)
-
-/* 0x02==Z 0x01==M */
-#define TYPE_GETZM(t) (((t)&0x30)>>4)
-
-extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set */
-extern int lwgeom_ndims(uchar type); /* returns 2,3 or 4 */
-extern int lwgeom_hasZ(uchar type); /* has Z ? */
-extern int lwgeom_hasM(uchar type); /* has M ? */
-extern int lwgeom_getType(uchar type); /* returns the tttt value */
-
-extern uchar lwgeom_makeType(char hasZ, char hasM, char hasSRID, int type);
-extern uchar lwgeom_makeType_full(char hasZ, char hasM, char hasSRID, int type, char hasBBOX);
-extern char lwgeom_hasSRID(uchar type); /* true iff S bit is set */
-extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set */
-
-
-
-/*
- * This is the binary representation of lwgeom compatible
- * with postgresql varlena struct
- */
-typedef struct {
- uint32 size; /* varlena header (do not touch directly!) */
- uchar type; /* encodes ndims, type, bbox presence,
- srid presence */
- uchar data[1];
-} PG_LWGEOM;
-
-/*
- * Construct a full PG_LWGEOM type (including size header)
- * from a serialized form.
- * The constructed PG_LWGEOM object will be allocated using palloc
- * and the serialized form will be copied.
- * If you specify a SRID other then -1 it will be set.
- * If you request bbox (wantbbox=1) it will be extracted or computed
- * from the serialized form.
- */
-extern PG_LWGEOM *PG_LWGEOM_construct(uchar *serialized, int SRID,
- int wantbbox);
-
-/*
- * Compute bbox of serialized geom
- */
-extern int compute_serialized_box2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
-extern BOX3D *compute_serialized_box3d(uchar *serialized_form);
-extern int compute_serialized_box3d_p(uchar *serialized_form, BOX3D *box);
-
-
-/*
- * Evaluate with an heuristic if the provided PG_LWGEOM is worth
- * caching a bbox
- */
-char is_worth_caching_pglwgeom_bbox(const PG_LWGEOM *);
-char is_worth_caching_serialized_bbox(const uchar *);
-char is_worth_caching_lwgeom_bbox(const LWGEOM *);
-
-/*
- * Use this macro to extract the char * required
- * by most functions from an PG_LWGEOM struct.
- * (which is an PG_LWGEOM w/out int32 size casted to char *)
- */
-#define SERIALIZED_FORM(x) ((uchar *)VARDATA((x)))
-
-/*
- This structure is a "glue" structure for returning a serialized
- LWGEOM from the parser, along with its size. By using a separate
- type, we remove the constraint that the output from the
- parser must be PG_LWGEOM format (and hence protect ourselves
- from future varlena changes)
-*/
-typedef struct serialized_lwgeom {
- uchar *lwgeom;
- int size;
-} SERIALIZED_LWGEOM;
-
-/*
- * This function computes the size in bytes
- * of the serialized geometries.
- */
-extern size_t lwgeom_size(const uchar *serialized_form);
-extern size_t lwgeom_size_subgeom(const uchar *serialized_form, int geom_number);
-extern size_t lwgeom_size_line(const uchar *serialized_line);
-extern size_t lwgeom_size_curve(const uchar *serialized_curve);
-extern size_t lwgeom_size_point(const uchar *serialized_point);
-extern size_t lwgeom_size_poly(const uchar *serialized_line);
-
-
-/*--------------------------------------------------------
- * all the base types (point/line/polygon) will have a
- * basic constructor, basic de-serializer, basic serializer,
- * bounding box finder and (TODO) serialized form size finder.
- *--------------------------------------------------------*/
-
-/*
- * given the LWPOINT serialized form (or a pointer into a muli* one)
- * construct a proper LWPOINT.
- * serialized_form should point to the 8bit type format (with type = 1)
- * Returns NULL if serialized form is not a point.
- * See serialized form doc
- */
-extern LWPOINT *lwpoint_deserialize(uchar *serialized_form);
-
-/*
- * Find size this point would get when serialized (no BBOX)
- */
-extern size_t lwpoint_serialize_size(LWPOINT *point);
-
-/*
- * convert this point into its serialize form
- * result's first char will be the 8bit type.
- * See serialized form doc
- */
-extern uchar *lwpoint_serialize(LWPOINT *point);
-
-/* same as above, writes to buf */
-extern void lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *size);
-
-/*
- * find bounding box (standard one)
- * zmin=zmax=0 if 2d (might change to NaN)
- */
-extern BOX3D *lwpoint_compute_box3d(LWPOINT *point);
-
-/*
- * convenience functions to hide the POINTARRAY
- */
-extern int lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out);
-extern int lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out);
-extern int lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out);
-extern int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out);
-
-/******************************************************************
- * LWLINE functions
- ******************************************************************/
-
-/*
- * given the LWGEOM serialized form (or a pointer into a muli* one)
- * construct a proper LWLINE.
- * serialized_form should point to the 8bit type format (with type = 2)
- * See SERIALIZED_FORM doc
- */
-extern LWLINE *lwline_deserialize(uchar *serialized_form);
-
-/* find the size this line would get when serialized */
-extern size_t lwline_serialize_size(LWLINE *line);
-
-/*
- * convert this line into its serialize form
- * result's first char will be the 8bit type. See serialized form doc
- * copies data.
- */
-extern uchar *lwline_serialize(LWLINE *line);
-
-/* same as above, writes to buf */
-extern void lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *size);
-
-/*
- * find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
- */
-extern BOX3D *lwline_compute_box3d(LWLINE *line);
-
-/******************************************************************
- * LWPOLY functions
- ******************************************************************/
-
-/*
- * given the LWPOLY serialized form (or a pointer into a muli* one)
- * construct a proper LWPOLY.
- * serialized_form should point to the 8bit type format (with type = 3)
- * See SERIALIZED_FORM doc
- */
-extern LWPOLY *lwpoly_deserialize(uchar *serialized_form);
-
-/* find the size this polygon would get when serialized */
-extern size_t lwpoly_serialize_size(LWPOLY *poly);
-
-/*
- * create the serialized form of the polygon
- * result's first char will be the 8bit type. See serialized form doc
- * points copied
- */
-extern uchar *lwpoly_serialize(LWPOLY *poly);
-
-/* same as above, writes to buf */
-extern void lwpoly_serialize_buf(LWPOLY *poly, uchar *buf, size_t *size);
-
-/*
- * find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
- */
-extern BOX3D *lwpoly_compute_box3d(LWPOLY *poly);
-
-/******************************************************************
- * LWGEOM functions
- ******************************************************************/
-
-extern size_t lwgeom_serialize_size(LWGEOM *geom);
-extern size_t lwcollection_serialize_size(LWCOLLECTION *coll);
-extern void lwgeom_serialize_buf(LWGEOM *geom, uchar *buf, size_t *size);
-extern uchar *lwgeom_serialize(LWGEOM *geom);
-extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, uchar *buf, size_t *size);
-
-/*
- * Deserialize an lwgeom serialized form.
- * The deserialized (recursive) structure will store
- * pointers to the serialized form (POINTARRAYs).
- */
-LWGEOM *lwgeom_deserialize(uchar *serializedform);
-
-/*
- * Release memory associated with LWGEOM.
- * POINTARRAYs are not released as they are usually
- * pointers to user-managed memory.
- * BBOX is released.
- */
-void lwgeom_release(LWGEOM *lwgeom);
-
-/******************************************************************
- * LWMULTIx and LWCOLLECTION functions
- ******************************************************************/
-
-LWMPOINT *lwmpoint_deserialize(uchar *serializedform);
-LWMLINE *lwmline_deserialize(uchar *serializedform);
-LWMPOLY *lwmpoly_deserialize(uchar *serializedform);
-LWCOLLECTION *lwcollection_deserialize(uchar *serializedform);
-LWGEOM *lwcollection_getsubgeom(LWCOLLECTION *, int);
-
-/******************************************************************
- * SERIALIZED FORM functions
- ******************************************************************/
-
-
-/******************************************************************
- * Multi-geometries
- *
- * These are all handled equivelently so its easy to write iterator code.
- * NOTE NOTE: you can hand in a non-multigeometry to most of these functions
- * and get usual behavior (ie. get geometry 0 on a POINT
- * will return the point).
- * This makes coding even easier since you dont have to necessarily
- * differenciate between the multi* and non-multi geometries.
- *
- * NOTE: these usually work directly off the serialized form, so
- * they're a little more difficult to handle (and slower)
- * NOTE NOTE: the get functions maybe slow, so we may want to have an
- * "analysed" lwgeom that would just have pointer to the start
- * of each sub-geometry.
- *
- ******************************************************************/
-
-/* use this version for speed. READ-ONLY! */
-typedef struct
-{
- int SRID;
- const uchar *serialized_form; /* orginal structure */
- uchar type; /* 8-bit type for the LWGEOM */
- int ngeometries; /* number of sub-geometries */
- uchar **sub_geoms; /* list of pointers (into serialized_form)
- of the sub-geoms */
-} LWGEOM_INSPECTED;
-
-extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected,
- int geom_number);
-
-/*
- * note - for a simple type (ie. point), this will have
- * sub_geom[0] = serialized_form.
- * for multi-geomtries sub_geom[0] will be a few bytes into the
- * serialized form.
- * This function just computes the length of each sub-object and
- * pre-caches this info.
- * For a geometry collection of multi* geometries, you can inspect
- * the sub-components as well.
- */
-extern LWGEOM_INSPECTED *lwgeom_inspect(const uchar *serialized_form);
-
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a point (with geom_num=0), multipoint
- * or geometrycollection
- */
-extern LWPOINT *lwgeom_getpoint(uchar *serialized_form, int geom_number);
-extern LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual geometry isnt a LINE, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a line, multiline or geometrycollection
- */
-extern LWLINE *lwgeom_getline(uchar *serialized_form, int geom_number);
-extern LWLINE *lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a polygon, multipolygon or geometrycollection
- */
-extern LWPOLY *lwgeom_getpoly(uchar *serialized_form, int geom_number);
-extern LWPOLY *lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-extern LWGEOM *lwgeom_getgeom_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-/*
- * this gets the serialized form of a sub-geometry
- * 1st geometry has geom_number = 0
- * if this isnt a multi* geometry, and geom_number ==0 then it returns
- * itself
- * returns null on problems.
- * in the future this is how you would access a muli* portion of a
- * geometry collection.
- * GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1))
- * ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1)
- * --> POINT(1 1)
- * you can inspect the sub-geometry as well if you wish.
- */
-extern uchar *lwgeom_getsubgeometry(const uchar *serialized_form, int geom_number);
-extern uchar *lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-
-/*
- * 1st geometry has geom_number = 0
- * use geom_number = -1 to find the actual type of the serialized form.
- * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
- * --> multipoint
- * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
- * --> point
- * gets the 8bit type of the geometry at location geom_number
- */
-extern uchar lwgeom_getsubtype(uchar *serialized_form, int geom_number);
-extern uchar lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
-
-
-/*
- * how many sub-geometries are there?
- * for point,line,polygon will return 1.
- */
-extern int lwgeom_getnumgeometries(uchar *serialized_form);
-extern int lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected);
-
-
-
-/*
- * set finalType to COLLECTIONTYPE or 0 (0 means choose a best type)
- * (ie. give it 2 points and ask it to be a multipoint)
- * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
- * all subgeometries must have the same SRID
- * if you want to construct an inspected, call this then inspect the result...
- */
-extern uchar *lwgeom_serialized_construct(int SRID, int finalType, char hasz, char hasm, int nsubgeometries, uchar **serialized_subs);
-
-
-/* construct the empty geometry (GEOMETRYCOLLECTION(EMPTY)) */
-extern uchar *lwgeom_constructempty(int SRID, char hasz, char hasm);
-extern void lwgeom_constructempty_buf(int SRID, char hasz, char hasm, uchar *buf, size_t *size);
-size_t lwgeom_empty_length(int SRID);
-
-/*
- * get the SRID from the LWGEOM
- * none present => -1
- */
-extern int lwgeom_getsrid(uchar *serialized);
-
-
-/*------------------------------------------------------
- * other stuff
- *
- * handle the double-to-float conversion. The results of this
- * will usually be a slightly bigger box because of the difference
- * between float8 and float4 representations.
- */
-
-extern BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box);
-extern int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *res);
-
-extern BOX3D box2df_to_box3d(BOX2DFLOAT4 *box);
-extern void box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *box3d);
-
-extern BOX3D *box3d_union(BOX3D *b1, BOX3D *b2);
-extern int box3d_union_p(BOX3D *b1, BOX3D *b2, BOX3D *ubox);
-
-/*
- * Returns a pointer to the BBOX internal to the serialized form.
- * READ-ONLY!
- * Or NULL if serialized form does not have a BBOX
- * OBSOLETED to avoid memory alignment problems.
- */
-/*extern BOX2DFLOAT4 *getbox2d_internal(uchar *serialized_form);*/
-
-/*
- * this function writes to 'box' and returns 0 if serialized_form
- * does not have a bounding box (empty geom)
- */
-extern int getbox2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
-
-/* Expand given box of 'd' units in all directions */
-void expand_box2d(BOX2DFLOAT4 *box, double d);
-void expand_box3d(BOX3D *box, double d);
-
-/* Check if to boxes are equal (considering FLOAT approximations) */
-char box2d_same(BOX2DFLOAT4 *box1, BOX2DFLOAT4 *box2);
-
-/****************************************************************
- * memory management -- these only delete the memory associated
- * directly with the structure - NOT the stuff pointing into
- * the original de-serialized info
- ****************************************************************/
-
-
-extern void pfree_inspected(LWGEOM_INSPECTED *inspected);
-extern void pfree_point (LWPOINT *pt);
-extern void pfree_line (LWLINE *line);
-extern void pfree_polygon (LWPOLY *poly);
-extern void pfree_POINTARRAY(POINTARRAY *pa);
-
-
-/****************************************************************
- * utility
- ****************************************************************/
-
-extern uint32 lw_get_uint32(const uchar *loc);
-extern int32 lw_get_int32(const uchar *loc);
-extern void printBOX3D(BOX3D *b);
-extern void printPA(POINTARRAY *pa);
-extern void printLWPOINT(LWPOINT *point);
-extern void printLWLINE(LWLINE *line);
-extern void printLWPOLY(LWPOLY *poly);
-extern void printBYTES(uchar *a, int n);
-extern void printMULTI(uchar *serialized);
-extern void printType(uchar str);
-
-
-extern float LWGEOM_Minf(float a, float b);
-extern float LWGEOM_Maxf(float a, float b);
-extern double LWGEOM_Mind(double a, double b);
-extern double LWGEOM_Maxd(double a, double b);
-
-extern float nextDown_f(double d);
-extern float nextUp_f(double d);
-extern double nextDown_d(float d);
-extern double nextUp_d(float d);
-
-extern float nextafterf_custom(float x, float y);
-
-
-#define LW_MAX(a,b) ((a) > (b) ? (a) : (b))
-#define LW_MIN(a,b) ((a) <= (b) ? (a) : (b))
-#define LW_ABS(a) ((a) < (0) ? (-a) : (a))
-
-
-/* general utilities */
-extern double lwgeom_polygon_area(LWPOLY *poly);
-extern double lwgeom_polygon_perimeter(LWPOLY *poly);
-extern double lwgeom_polygon_perimeter2d(LWPOLY *poly);
-extern double lwgeom_pointarray_length2d(POINTARRAY *pts);
-extern double lwgeom_pointarray_length(POINTARRAY *pts);
-extern void lwgeom_force2d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
-extern void lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize);
-extern void lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize);
-extern void lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
-extern double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
-extern double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
-extern double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D);
-extern double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa);
-extern double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2);
-extern int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring);
-extern int pt_in_poly_2d(POINT2D *p, LWPOLY *poly);
-extern double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly);
-extern double distance2d_point_point(LWPOINT *point1, LWPOINT *point2);
-extern double distance2d_point_line(LWPOINT *point, LWLINE *line);
-extern double distance2d_line_line(LWLINE *line1, LWLINE *line2);
-extern double distance2d_point_poly(LWPOINT *point, LWPOLY *poly);
-extern double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2);
-extern double distance2d_line_poly(LWLINE *line, LWPOLY *poly);
-extern int azimuth_pt_pt(POINT2D *p1, POINT2D *p2, double *ret);
-extern double lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2);
-extern double lwgeom_mindistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance);
-extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
-extern int32 lwgeom_npoints(uchar *serialized);
-extern char ptarray_isccw(const POINTARRAY *pa);
-extern void lwgeom_reverse(LWGEOM *lwgeom);
-extern void lwline_reverse(LWLINE *line);
-extern void lwpoly_reverse(LWPOLY *poly);
-extern void lwpoly_forceRHR(LWPOLY *poly);
-extern void lwgeom_forceRHR(LWGEOM *lwgeom);
-extern char *lwgeom_summary(LWGEOM *lwgeom, int offset);
-extern const char *lwgeom_typename(int type);
-extern int ptarray_compute_box2d_p(const POINTARRAY *pa, BOX2DFLOAT4 *result);
-extern BOX2DFLOAT4 *ptarray_compute_box2d(const POINTARRAY *pa);
-extern int lwpoint_compute_box2d_p(LWPOINT *point, BOX2DFLOAT4 *box);
-extern int lwline_compute_box2d_p(LWLINE *line, BOX2DFLOAT4 *box);
-extern int lwpoly_compute_box2d_p(LWPOLY *poly, BOX2DFLOAT4 *box);
-extern int lwcollection_compute_box2d_p(LWCOLLECTION *col, BOX2DFLOAT4 *box);
-extern BOX2DFLOAT4 *lwgeom_compute_box2d(LWGEOM *lwgeom);
-
-extern void interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F);
-
-/* return alloced memory */
-extern BOX2DFLOAT4 *box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2);
-
-/* args may overlap ! */
-extern int box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox);
-extern int lwgeom_compute_box2d_p(LWGEOM *lwgeom, BOX2DFLOAT4 *box);
-void lwgeom_longitude_shift(LWGEOM *lwgeom);
-
-/* Is lwgeom1 geometrically equal to lwgeom2 ? */
-char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2);
-char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2);
-char lwpoint_same(const LWPOINT *p1, const LWPOINT *p2);
-char lwline_same(const LWLINE *p1, const LWLINE *p2);
-char lwpoly_same(const LWPOLY *p1, const LWPOLY *p2);
-char lwcollection_same(const LWCOLLECTION *p1, const LWCOLLECTION *p2);
-
-/*
- * Add 'what' to 'to' at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Mix of dimensions is not allowed (TODO: allow it?).
- * Returns a newly allocated LWGEOM (with NO BBOX)
- */
-extern LWGEOM *lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what);
-
-LWGEOM *lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what);
-LWGEOM *lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what);
-LWGEOM *lwpoly_add(const LWPOLY *to, uint32 where, const LWGEOM *what);
-LWGEOM *lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what);
-LWGEOM *lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what);
-LWGEOM *lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what);
-LWGEOM *lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what);
-
-/*
- * Clone an LWGEOM
- * pointarray are not copied.
- * BBOXes are copied
- */
-extern LWGEOM *lwgeom_clone(const LWGEOM *lwgeom);
-extern LWPOINT *lwpoint_clone(const LWPOINT *lwgeom);
-extern LWLINE *lwline_clone(const LWLINE *lwgeom);
-extern LWPOLY *lwpoly_clone(const LWPOLY *lwgeom);
-extern LWCOLLECTION *lwcollection_clone(const LWCOLLECTION *lwgeom);
-extern BOX2DFLOAT4 *box2d_clone(const BOX2DFLOAT4 *lwgeom);
-extern POINTARRAY *ptarray_clone(const POINTARRAY *ptarray);
-
-/*
- * Geometry constructors
- * Take ownership of arguments
- */
-extern LWPOINT *lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox,
- POINTARRAY *point);
-extern LWLINE *lwline_construct(int SRID, BOX2DFLOAT4 *bbox,
- POINTARRAY *points);
-
-/*
- * Construct a new LWPOLY. arrays (points/points per ring) will NOT be copied
- * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
- */
-extern LWPOLY *lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox,
- unsigned int nrings, POINTARRAY **points);
-
-extern LWCOLLECTION *lwcollection_construct(unsigned int type, int SRID,
- BOX2DFLOAT4 *bbox, unsigned int ngeoms, LWGEOM **geoms);
-extern LWCOLLECTION *lwcollection_construct_empty(int SRID,
- char hasZ, char hasM);
-
-/* Other constructors */
-extern LWPOINT *make_lwpoint2d(int SRID, double x, double y);
-extern LWPOINT *make_lwpoint3dz(int SRID, double x, double y, double z);
-extern LWPOINT *make_lwpoint3dm(int SRID, double x, double y, double m);
-extern LWPOINT *make_lwpoint4d(int SRID, double x, double y, double z, double m);
-extern LWLINE *lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points);
-extern LWLINE *lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint);
-extern LWLINE *lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where);
-extern LWLINE *lwline_removepoint(LWLINE *line, unsigned int which);
-extern void lwline_setPoint4d(LWLINE *line, unsigned int which, POINT4D *newpoint);
-extern LWPOLY *lwpoly_from_lwlines(const LWLINE *shell, unsigned int nholes, const LWLINE **holes);
-
-/* Return a char string with ASCII versionf of type flags */
-extern const char *lwgeom_typeflags(uchar type);
-
-/* Construct an empty pointarray */
-extern POINTARRAY *ptarray_construct(char hasz, char hasm,
- unsigned int npoints);
-
-/*
- * extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts);
- * extern POINTARRAY *ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts);
- * extern POINTARRAY *ptarray_construct3dm(uint32 npoints, const POINT3DM *pts);
- * extern POINTARRAY *ptarray_construct4d(uint32 npoints, const POINT4D *pts);
- */
-
-extern POINTARRAY *ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims,
- unsigned int where);
-extern POINTARRAY *ptarray_removePoint(POINTARRAY *pa, unsigned int where);
-
-extern int ptarray_isclosed2d(const POINTARRAY *pa);
-
-extern void ptarray_longitude_shift(POINTARRAY *pa);
-
-extern int32 lwgeom_nrings_recursive(uchar *serialized);
-extern void ptarray_reverse(POINTARRAY *pa);
-extern POINTARRAY *ptarray_substring(POINTARRAY *, double, double);
-extern double ptarray_locate_point(POINTARRAY *, POINT2D *);
-extern void closest_point_on_segment(POINT2D *p, POINT2D *A, POINT2D *B, POINT2D *ret);
-
-/*
- * Ensure every segment is at most 'dist' long.
- * Returned LWGEOM might is unchanged if a POINT.
- */
-extern LWGEOM *lwgeom_segmentize2d(LWGEOM *line, double dist);
-extern POINTARRAY *ptarray_segmentize2d(POINTARRAY *ipa, double dist);
-extern LWLINE *lwline_segmentize2d(LWLINE *line, double dist);
-extern LWPOLY *lwpoly_segmentize2d(LWPOLY *line, double dist);
-extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
-
-extern uchar parse_hex(char *str);
-extern void deparse_hex(uchar str, char *result);
-extern SERIALIZED_LWGEOM *parse_lwgeom_wkt(char *wkt_input);
-
-extern char *lwgeom_to_ewkt(LWGEOM *lwgeom);
-extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder);
-extern LWGEOM *lwgeom_from_ewkb(uchar *ewkb, size_t ewkblen);
-extern uchar *lwgeom_to_ewkb(LWGEOM *lwgeom, char byteorder, size_t *ewkblen);
-
-extern void *lwalloc(size_t size);
-extern void *lwrealloc(void *mem, size_t size);
-extern void lwfree(void *mem);
-
-/* Utilities */
-extern void trim_trailing_zeros(char *num);
-
-/* Machine endianness */
-#define XDR 0
-#define NDR 1
-extern char getMachineEndian(void);
-
-void errorIfSRIDMismatch(int srid1, int srid2);
-
-/* CURVETYPE */
-typedef struct
-{
- uchar type; /* CURVETYPE */
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- POINTARRAY *points; /* array of POINT(3D/3DM) */
-} LWCURVE; /* "light-weight arcline" */
-
-/* COMPOUNDTYPE */
-typedef struct
-{
- uchar type; /* COMPOUNDTYPE */
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int ngeoms;
- LWGEOM **geoms;
-} LWCOMPOUND; /* "light-weight compound line" */
-
-/* CURVEPOLYTYPE */
-typedef struct
-{
- uchar type; /* CURVEPOLYTYPE */
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int nrings;
- LWGEOM **rings; /* list of rings (list of points) */
-} LWCURVEPOLY; /* "light-weight polygon" */
-
-/* MULTICURVE */
-typedef struct
-{
- uchar type;
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int ngeoms;
- LWGEOM **geoms;
-} LWMCURVE;
-
-/* MULTISURFACETYPE */
-typedef struct
-{
- uchar type;
- BOX2DFLOAT4 *bbox;
- uint32 SRID;
- int ngeoms;
- LWGEOM **geoms;
-} LWMSURFACE;
-
-#define CURVETYPE 8
-#define COMPOUNDTYPE 9
-#define CURVEPOLYTYPE 13
-#define MULTICURVETYPE 14
-#define MULTISURFACETYPE 15
-
-/******************************************************************
- * LWCURVE functions
- ******************************************************************/
-
-/* Casts LWGEOM->LW* (return NULL if cast is illegal) */
-extern LWCURVE *lwgeom_as_lwcurve(LWGEOM *lwgeom);
-
-
-LWCURVE *lwcurve_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points);
-
-/*
- * given the LWGEOM serialized form (or a pointer into a muli* one)
- * construct a proper LWCURVE.
- * serialized_form should point to the 8bit type format (with type = 2)
- * See SERIALIZED_FORM doc
- */
-extern LWCURVE *lwcurve_deserialize(uchar *serialized_form);
-
-/* find the size this curve would get when serialized */
-extern size_t lwcurve_serialize_size(LWCURVE *curve);
-
-/*
- * convert this curve into its serialize form
- * result's first char will be the 8bit type. See serialized form doc
- * copies data.
- */
-extern uchar *lwcurve_serialize(LWCURVE *curve);
-
-/* same as above, writes to buf */
-extern void lwcurve_serialize_buf(LWCURVE *curve, uchar *buf, size_t *size);
-
-/*
- * find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN)
- */
-extern BOX3D *lwcurve_compute_box3d(LWCURVE *curve);
-
-LWGEOM *lwcurve_add(const LWCURVE *to, uint32 where, const LWGEOM *what);
-extern int lwcurve_compute_box2d_p(LWCURVE *curve, BOX2DFLOAT4 *box);
-extern BOX3D *lwcurve_compute_box3d(LWCURVE *curve);
-extern void pfree_curve(LWCURVE *curve);
-LWCURVE *lwcurve_clone(const LWCURVE *curve);
-
-/******************************************************************
- * LWMULTIx and LWCOLLECTION functions
- ******************************************************************/
-
-LWCOMPOUND *lwcompound_deserialize(uchar *serialized_form);
-
-LWGEOM *lwcompound_add(const LWCOMPOUND *to, uint32 where, const LWGEOM *what);
-
-LWCURVEPOLY *lwcurvepoly_deserialize(uchar *serialized_form);
-
-LWGEOM *lwcurvepoly_add(const LWCURVEPOLY *to, uint32 where, const LWGEOM *what);
-
-LWMCURVE *lwmcurve_deserialize(uchar *serialized_form);
-
-LWGEOM *lwmcurve_add(const LWMCURVE *to, uint32 where, const LWGEOM *what);
-
-LWMSURFACE *lwmsurface_deserialize(uchar *serialized_form);
-
-LWGEOM *lwmsurface_add(const LWMSURFACE *to, uint32 where, const LWGEOM *what);
-
-/*******************************************************************************
- * SQLMM internal functions
- ******************************************************************************/
-
-uint32 has_arc(LWGEOM *geom);
-double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
-LWGEOM *lwgeom_segmentize(LWGEOM *geom, uint32 perQuad);
-extern double lwgeom_curvepolygon_area(LWCURVEPOLY *curvepoly);
-double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
-
-#endif /* !defined _LIBLWGEOM_H */
-
Deleted: trunk/lwgeom/lwcollection.c
===================================================================
--- trunk/lwgeom/lwcollection.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwcollection.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,356 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-
-#define CHECK_LWGEOM_ZM 1
-
-LWCOLLECTION *
-lwcollection_construct(unsigned int type, int SRID, BOX2DFLOAT4 *bbox,
- unsigned int ngeoms, LWGEOM **geoms)
-{
- LWCOLLECTION *ret;
- int hasz, hasm;
-#ifdef CHECK_LWGEOM_ZM
- char zm;
- unsigned int i;
-#endif
-
- LWDEBUGF(2, "lwcollection_construct called with %d, %d, %p, %d, %p.", type, SRID, bbox, ngeoms, geoms);
-
- hasz = 0;
- hasm = 0;
- if ( ngeoms > 0 )
- {
- hasz = TYPE_HASZ(geoms[0]->type);
- hasm = TYPE_HASM(geoms[0]->type);
-#ifdef CHECK_LWGEOM_ZM
- zm = TYPE_GETZM(geoms[0]->type);
-
- LWDEBUGF(3, "lwcollection_construct type[0]=%d", geoms[0]->type);
-
- for (i=1; i<ngeoms; i++)
- {
- LWDEBUGF(3, "lwcollection_construct type=[%d]=%d", i, geoms[i]->type);
-
- if ( zm != TYPE_GETZM(geoms[i]->type) )
- lwerror("lwcollection_construct: mixed dimension geometries: %d/%d", zm, TYPE_GETZM(geoms[i]->type));
- }
-#endif
- }
-
-
- ret = lwalloc(sizeof(LWCOLLECTION));
- ret->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1),
- type, 0);
- ret->SRID = SRID;
- ret->ngeoms = ngeoms;
- ret->geoms = geoms;
- ret->bbox = bbox;
-
- return ret;
-}
-
-LWCOLLECTION *
-lwcollection_construct_empty(int SRID, char hasz, char hasm)
-{
- LWCOLLECTION *ret;
-
- ret = lwalloc(sizeof(LWCOLLECTION));
- ret->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1),
- COLLECTIONTYPE, 0);
- ret->SRID = SRID;
- ret->ngeoms = 0;
- ret->geoms = NULL;
- ret->bbox = NULL;
-
- return ret;
-}
-
-
-LWCOLLECTION *
-lwcollection_deserialize(uchar *srl)
-{
- LWCOLLECTION *result;
- LWGEOM_INSPECTED *insp;
- char typefl = srl[0];
- int type = lwgeom_getType(typefl);
- int i;
-
- if ( type != COLLECTIONTYPE )
- {
- lwerror("lwcollection_deserialize called on NON geometrycollection: %d", type);
- return NULL;
- }
-
- insp = lwgeom_inspect(srl);
-
- result = lwalloc(sizeof(LWCOLLECTION));
- result->type = typefl;
- result->SRID = insp->SRID;
- result->ngeoms = insp->ngeometries;
-
- if (lwgeom_hasBBOX(srl[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
-
- if ( insp->ngeometries )
- {
- result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
- for (i=0; i<insp->ngeometries; i++)
- {
- result->geoms[i] =
- lwgeom_deserialize(insp->sub_geoms[i]);
- }
- }
-
- return result;
-}
-
-LWGEOM *
-lwcollection_getsubgeom(LWCOLLECTION *col, int gnum)
-{
- return (LWGEOM *)col->geoms[gnum];
-}
-
-/* find serialized size of this collection */
-size_t
-lwcollection_serialize_size(LWCOLLECTION *col)
-{
- size_t size = 5; /* type + nsubgeoms */
- int i;
-
- if ( col->SRID != -1 ) size += 4; /* SRID */
- if ( col->bbox ) size += sizeof(BOX2DFLOAT4);
-
- LWDEBUGF(2, "lwcollection_serialize_size[%p]: start size: %d", col, size);
-
-
- for (i=0; i<col->ngeoms; i++)
- {
- size += lwgeom_serialize_size(col->geoms[i]);
-
- LWDEBUGF(3, "lwcollection_serialize_size[%p]: with geom%d: %d", col, i, size);
- }
-
- LWDEBUGF(3, "lwcollection_serialize_size[%p]: returning %d", col, size);
-
- return size;
-}
-
-/*
- * convert this collectoin into its serialize form writing it into
- * the given buffer, and returning number of bytes written into
- * the given int pointer.
- */
-void
-lwcollection_serialize_buf(LWCOLLECTION *coll, uchar *buf, size_t *retsize)
-{
- size_t size=1; /* type */
- size_t subsize=0;
- char hasSRID;
- uchar *loc;
- int i;
-
- LWDEBUGF(2, "lwcollection_serialize_buf called (%s with %d elems)",
- lwgeom_typename(TYPE_GETTYPE(coll->type)), coll->ngeoms);
-
- hasSRID = (coll->SRID != -1);
-
- buf[0] = lwgeom_makeType_full(
- TYPE_HASZ(coll->type), TYPE_HASM(coll->type),
- hasSRID, TYPE_GETTYPE(coll->type), coll->bbox ? 1 : 0);
- loc = buf+1;
-
- /* Add BBOX if requested */
- if ( coll->bbox )
- {
- memcpy(loc, coll->bbox, sizeof(BOX2DFLOAT4));
- size += sizeof(BOX2DFLOAT4);
- loc += sizeof(BOX2DFLOAT4);
- }
-
- /* Add SRID if requested */
- if (hasSRID)
- {
- memcpy(loc, &coll->SRID, 4);
- size += 4;
- loc += 4;
- }
-
- /* Write number of subgeoms */
- memcpy(loc, &coll->ngeoms, 4);
- size += 4;
- loc += 4;
-
- /* Serialize subgeoms */
- for (i=0; i<coll->ngeoms; i++)
- {
- lwgeom_serialize_buf(coll->geoms[i], loc, &subsize);
- size += subsize;
- loc += subsize;
- }
-
- if (retsize) *retsize = size;
-
- LWDEBUG(3, "lwcollection_serialize_buf returning");
-}
-
-int
-lwcollection_compute_box2d_p(LWCOLLECTION *col, BOX2DFLOAT4 *box)
-{
- BOX2DFLOAT4 boxbuf;
- uint32 i;
-
- if ( ! col->ngeoms ) return 0;
- if ( ! lwgeom_compute_box2d_p(col->geoms[0], box) ) return 0;
- for (i=1; i<col->ngeoms; i++)
- {
- if ( ! lwgeom_compute_box2d_p(col->geoms[i], &boxbuf) )
- return 0;
- if ( ! box2d_union_p(box, &boxbuf, box) ) return 0;
- }
- return 1;
-}
-
-/*
- * Clone LWCOLLECTION object. POINTARRAY are not copied.
- * Bbox is cloned if present in input.
- */
-LWCOLLECTION *
-lwcollection_clone(const LWCOLLECTION *g)
-{
- uint32 i;
- LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
- memcpy(ret, g, sizeof(LWCOLLECTION));
- if ( g->ngeoms > 0 )
- {
- ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
- for (i=0; i<g->ngeoms; i++)
- {
- ret->geoms[i] = lwgeom_clone(g->geoms[i]);
- }
- if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
- }
- else
- {
- ret->bbox = NULL; /* empty collection */
- ret->geoms = NULL;
- }
- return ret;
-}
-
-/*
- * Add 'what' to this collection at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a GEOMETRYCOLLECTION
- */
-LWGEOM *
-lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- uint32 i;
-
- if ( where == -1 ) where = to->ngeoms;
- else if ( where < -1 || where > to->ngeoms )
- {
- lwerror("lwcollection_add: add position out of range %d..%d",
- -1, to->ngeoms);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
- for (i=0; i<where; i++)
- {
- geoms[i] = lwgeom_clone(to->geoms[i]);
- lwgeom_dropSRID(geoms[i]);
- lwgeom_dropBBOX(geoms[i]);
- }
- geoms[where] = lwgeom_clone(what);
- lwgeom_dropSRID(geoms[where]);
- lwgeom_dropBBOX(geoms[where]);
- for (i=where; i<to->ngeoms; i++)
- {
- geoms[i+1] = lwgeom_clone(to->geoms[i]);
- lwgeom_dropSRID(geoms[i+1]);
- lwgeom_dropBBOX(geoms[i+1]);
- }
-
- col = lwcollection_construct(COLLECTIONTYPE,
- to->SRID, NULL,
- to->ngeoms+1, geoms);
-
- return (LWGEOM *)col;
-
-}
-
-LWCOLLECTION *
-lwcollection_segmentize2d(LWCOLLECTION *col, double dist)
-{
- unsigned int i;
- LWGEOM **newgeoms;
-
- if ( ! col->ngeoms ) return col;
-
- newgeoms = lwalloc(sizeof(LWGEOM *)*col->ngeoms);
- for (i=0; i<col->ngeoms; i++)
- newgeoms[i] = lwgeom_segmentize2d(col->geoms[i], dist);
-
- return lwcollection_construct(col->type, col->SRID, NULL,
- col->ngeoms, newgeoms);
-}
-
-/* check for same geometry composition */
-char
-lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2)
-{
- unsigned int i, j;
- unsigned int *hit;
-
- LWDEBUG(2, "lwcollection_same called");
-
- if ( TYPE_GETTYPE(c1->type) != TYPE_GETTYPE(c2->type) ) return 0;
- if ( c1->ngeoms != c2->ngeoms ) return 0;
-
- hit = lwalloc(sizeof(unsigned int)*c1->ngeoms);
- memset(hit, 0, sizeof(unsigned int)*c1->ngeoms);
-
- for (i=0; i<c1->ngeoms; i++)
- {
- char found=0;
- for (j=0; j<c2->ngeoms; j++)
- {
- if ( hit[j] ) continue;
- if ( lwgeom_same(c1->geoms[i], c2->geoms[j]) )
- {
- hit[j] = 1;
- found=1;
- break;
- }
- }
- if ( ! found ) return 0;
- }
- return 1;
-}
Deleted: trunk/lwgeom/lwcompound.c
===================================================================
--- trunk/lwgeom/lwcompound.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwcompound.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,118 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-LWCOMPOUND *
-lwcompound_deserialize(uchar *serialized)
-{
- LWCOMPOUND *result;
- LWGEOM_INSPECTED *insp;
- int type = lwgeom_getType(serialized[0]);
- int i;
-
- if(type != COMPOUNDTYPE)
- {
- lwerror("lwcompound_deserialize called on non compound: %d", type);
- return NULL;
- }
-
- insp = lwgeom_inspect(serialized);
-
- result = lwalloc(sizeof(LWCOMPOUND));
- result->type = insp->type;
- result->SRID = insp->SRID;
- result->ngeoms = insp->ngeometries;
- result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
-
- if(lwgeom_hasBBOX(serialized[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, serialized + 1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
- for(i = 0; i < insp->ngeometries; i++)
- {
- if(lwgeom_getType(insp->sub_geoms[i][0]) == LINETYPE)
- result->geoms[i] = (LWGEOM *)lwline_deserialize(insp->sub_geoms[i]);
- else
- result->geoms[i] = (LWGEOM *)lwcurve_deserialize(insp->sub_geoms[i]);
- if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
- {
- lwerror("Mixed dimensions (compound:%d, line/curve%d:%d)",
- TYPE_NDIMS(result->type), i,
- TYPE_NDIMS(result->geoms[i]->type)
- );
- lwfree(result);
- return NULL;
- }
- }
- return result;
-}
-
-/*
- * Add 'what' to this string at position 'where'
- * where=0 == prepend
- * where=-1 == append
- * Returns a COMPOUND or a GEOMETRYCOLLECTION
- */
-LWGEOM *
-lwcompound_add(const LWCOMPOUND *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
-
- LWDEBUG(2, "lwcompound_add called.");
-
- if(where != -1 && where != 0)
- {
- lwerror("lwcompound_add only supports 0 or -1 as a second argument, not %d", where);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*2);
- if(where == -1) /* append */
- {
- geoms[0] = lwgeom_clone((LWGEOM *)to);
- geoms[1] = lwgeom_clone(what);
- }
- else /* prepend */
- {
- geoms[0] = lwgeom_clone(what);
- geoms[1] = lwgeom_clone((LWGEOM *)to);
- }
-
- /* reset SRID and wantbbox flag from component types */
- geoms[0]->SRID = geoms[1]->SRID = -1;
- TYPE_SETHASSRID(geoms[0]->type, 0);
- TYPE_SETHASSRID(geoms[1]->type, 0);
- TYPE_SETHASBBOX(geoms[0]->type, 0);
- TYPE_SETHASBBOX(geoms[1]->type, 0);
-
- /* Find appropriate geom type */
- if(TYPE_GETTYPE(what->type) == LINETYPE || TYPE_GETTYPE(what->type) == CURVETYPE) newtype = COMPOUNDTYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL, 2, geoms);
-
- return (LWGEOM *)col;
-}
-
Deleted: trunk/lwgeom/lwcurve.c
===================================================================
--- trunk/lwgeom/lwcurve.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwcurve.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,707 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-/* basic LWCURVE functions */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "liblwgeom.h"
-
-BOX3D *lwcircle_compute_box3d(POINT4D *p1, POINT4D *p2, POINT4D *p3);
-void printLWCURVE(LWCURVE *curve);
-void lwcurve_reverse(LWCURVE *curve);
-LWCURVE *lwcurve_segmentize2d(LWCURVE *curve, double dist);
-char lwcurve_same(const LWCURVE *me, const LWCURVE *you);
-LWCURVE *lwcurve_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points);
-LWCURVE *lwcurve_from_lwmpoint(int SRID, LWMPOINT *mpoint);
-LWCURVE *lwcurve_addpoint(LWCURVE *curve, LWPOINT *point, unsigned int where);
-LWCURVE *lwcurve_removepoint(LWCURVE *curve, unsigned int index);
-void lwcurve_setPoint4d(LWCURVE *curve, unsigned int index, POINT4D *newpoint);
-
-
-
-#ifndef MAXFLOAT
- #define MAXFLOAT 3.402823466e+38F
-#endif
-
-/*
- * Construct a new LWCURVE. points will *NOT* be copied
- * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
- */
-LWCURVE *
-lwcurve_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points)
-{
- LWCURVE *result;
-
- /*
- * The first arc requires three points. Each additional
- * arc requires two more points. Thus the minimum point count
- * is three, and the count must be odd.
- */
- if(points->npoints % 2 != 1 || points->npoints < 3)
- {
- lwerror("lwcurve_construct: invalid point count %d", points->npoints);
- return NULL;
- }
-
- result = (LWCURVE*) lwalloc(sizeof(LWCURVE));
-
- result->type = lwgeom_makeType_full(
- TYPE_HASZ(points->dims),
- TYPE_HASM(points->dims),
- (SRID!=-1), CURVETYPE, 0);
- result->SRID = SRID;
- result->points = points;
- result->bbox = bbox;
-
- return result;
-}
-
-/*
- * given the LWGEOM serialized form (or a point into a multi* one)
- * construct a propert LWCURVE.
- * serialized_form should point to the 8bit type format (with type = 8)
- * See serialized form doc
- */
-LWCURVE *
-lwcurve_deserialize(uchar *serialized_form)
-{
- uchar type;
- LWCURVE *result;
- uchar *loc=NULL;
- uint32 npoints;
- POINTARRAY *pa;
-
- type = (uchar)serialized_form[0];
- if(lwgeom_getType(type) != CURVETYPE)
- {
- lwerror("lwcurve_deserialize: attempt to deserialize a curve which is really a %s", lwgeom_typename(type));
- return NULL;
- }
-
- result = (LWCURVE*) lwalloc(sizeof(LWCURVE));
- result->type = type;
-
- loc = serialized_form + 1;
-
- if(lwgeom_hasBBOX(type))
- {
- LWDEBUG(3, "lwcurve_deserialize: input has bbox");
-
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
- loc += sizeof(BOX2DFLOAT4);
- }
- else
- {
- LWDEBUG(3, "lwcurve_deserialize: input lacks bbox");
-
- result->bbox = NULL;
- }
-
- if(lwgeom_hasSRID(type))
- {
- LWDEBUG(3, "lwcurve_deserialize: input has srid");
-
- result->SRID = lw_get_int32(loc);
- loc += 4; /* type + SRID */
- }
- else
- {
- LWDEBUG(3, "lwcurve_deserialize: input lacks srid");
-
- result->SRID = -1;
- }
-
- /* we've read the type (1 byte) and SRID (4 bytes, if present) */
-
- npoints = lw_get_uint32(loc);
-
- LWDEBUGF(3, "curve npoints = %d", npoints);
-
- loc += 4;
- pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints);
- result->points = pa;
- return result;
-}
-
-/*
- * convert this curve into its serialized form
- * result's first char will be the 8bit type. See serialized form doc
- */
-uchar *
-lwcurve_serialize(LWCURVE *curve)
-{
- size_t size, retsize;
- uchar * result;
-
- if(curve == NULL) {
- lwerror("lwcurve_serialize:: given null curve");
- return NULL;
- }
-
- size = lwcurve_serialize_size(curve);
- result = lwalloc(size);
- lwcurve_serialize_buf(curve, result, &retsize);
- if(retsize != size)
- lwerror("lwcurve_serialize_size returned %d, ..selialize_buf returned %d", size, retsize);
- return result;
-}
-
-/*
- * convert this curve into its serialized form writing it into
- * the given buffer, and returning number of bytes written into
- * the given int pointer.
- * result's first char will be the 8bit type. See serialized form doc
- */
-void lwcurve_serialize_buf(LWCURVE *curve, uchar *buf, size_t *retsize)
-{
- char hasSRID;
- uchar *loc;
- int ptsize;
- size_t size;
-
- LWDEBUGF(2, "lwcurve_serialize_buf(%p, %p, %p) called",
- curve, buf, retsize);
-
- if(curve == NULL)
- {
- lwerror("lwcurve_serialize:: given null curve");
- return;
- }
-
- if(TYPE_GETZM(curve->type) != TYPE_GETZM(curve->points->dims))
- {
- lwerror("Dimensions mismatch in lwcurve");
- return;
- }
-
- ptsize = pointArray_ptsize(curve->points);
-
- hasSRID = (curve->SRID != -1);
-
- buf[0] = (uchar)lwgeom_makeType_full(
- TYPE_HASZ(curve->type), TYPE_HASM(curve->type),
- hasSRID, CURVETYPE, curve->bbox ? 1 : 0);
- loc = buf+1;
-
- LWDEBUGF(3, "lwcurve_serialize_buf added type (%d)", curve->type);
-
- if(curve->bbox)
- {
- memcpy(loc, curve->bbox, sizeof(BOX2DFLOAT4));
- loc += sizeof(BOX2DFLOAT4);
-
- LWDEBUG(3, "lwcurve_serialize_buf added BBOX");
- }
-
- if(hasSRID)
- {
- memcpy(loc, &curve->SRID, sizeof(int32));
- loc += sizeof(int32);
-
- LWDEBUG(3, "lwcurve_serialize_buf added SRID");
- }
-
- memcpy(loc, &curve->points->npoints, sizeof(uint32));
- loc += sizeof(uint32);
-
- LWDEBUGF(3, "lwcurve_serialize_buf added npoints (%d)",
- curve->points->npoints);
-
- /* copy in points */
- size = curve->points->npoints * ptsize;
- memcpy(loc, getPoint_internal(curve->points, 0), size);
- loc += size;
-
- LWDEBUGF(3, "lwcurve_serialize_buf copied serialized_pointlist (%d bytes)",
- ptsize * curve->points->npoints);
-
- if(retsize) *retsize = loc-buf;
-
- LWDEBUGF(3, "lwcurve_serialize_buf returning (loc: %p, size: %d)",
- loc, loc-buf);
-}
-
-/* find length of this deserialized curve */
-size_t
-lwcurve_serialize_size(LWCURVE *curve)
-{
- size_t size = 1; /* type */
-
- LWDEBUG(2, "lwcurve_serialize_size called");
-
- if(curve->SRID != -1) size += 4; /* SRID */
- if(curve->bbox) size += sizeof(BOX2DFLOAT4);
-
- size += 4; /* npoints */
- size += pointArray_ptsize(curve->points) * curve->points->npoints;
-
- LWDEBUGF(3, "lwcurve_serialize_size returning %d", size);
-
- return size;
-}
-
-BOX3D *
-lwcircle_compute_box3d(POINT4D *p1, POINT4D *p2, POINT4D *p3)
-{
- double x1, x2, y1, y2, z1, z2;
- double angle, radius, sweep;
- /*
- double top, left;
- */
- double a1, a2, a3;
- double xe = 0.0, ye = 0.0;
- POINT4D *center;
- int i;
- BOX3D *box;
-
- LWDEBUG(2, "lwcircle_compute_box3d called.");
-
- center = lwalloc(sizeof(POINT4D));
- radius = lwcircle_center(p1, p2, p3, ¢er);
- if(radius < 0.0) return NULL;
-
- /*
- top = center->y + radius;
- left = center->x - radius;
-
- LWDEBUGF(3, "lwcircle_compute_box3d: top=%.16f, left=%.16f", top, left);
- */
-
- x1 = MAXFLOAT;
- x2 = -1 * MAXFLOAT;
- y1 = MAXFLOAT;
- y2 = -1 * MAXFLOAT;
-
- a1 = atan2(p1->y - center->y, p1->x - center->x);
- a2 = atan2(p2->y - center->y, p2->x - center->x);
- a3 = atan2(p3->y - center->y, p3->x - center->x);
-
- /* Determine sweep angle */
- if(a1 > a2 && a2 > a3)
- {
- sweep = a3 - a1;
- }
- /* Counter-clockwise */
- else if(a1 < a2 && a2 < a3)
- {
- sweep = a3 - a1;
- }
- /* Clockwise, wrap */
- else if((a1 < a2 && a1 > a3) || (a2 < a3 && a1 > a3))
- {
- sweep = a3 - a1 + 2*M_PI;
- }
- /* Counter-clockwise, wrap */
- else if((a1 > a2 && a1 < a3) || (a2 > a3 && a1 < a3))
- {
- sweep = a3 - a1 - 2*M_PI;
- }
- else
- {
- sweep = 0.0;
- }
-
- LWDEBUGF(3, "a1 %.16f, a2 %.16f, a3 %.16f, sweep %.16f", a1, a2, a3, sweep);
-
- angle = 0.0;
- for(i=0; i < 6; i++)
- {
- switch(i) {
- case 0:
- angle = 0.0;
- xe = center->x + radius;
- ye = center->y;
- break;
- case 1:
- angle = M_PI_2;
- xe = center->x;
- ye = center->y + radius;
- break;
- case 2:
- angle = M_PI;
- xe = center->x - radius;
- ye = center->y;
- break;
- case 3:
- angle = -1 * M_PI_2;
- xe = center->x;
- ye = center->y - radius;
- break;
- case 4:
- angle = a1;
- xe = p1->x;
- ye = p1->y;
- break;
- case 5:
- angle = a3;
- xe = p3->x;
- ye = p3->y;
- break;
- }
- if(i < 4)
- {
- if(sweep > 0.0 && (angle > a3 || angle < a1)) continue;
- if(sweep < 0.0 && (angle < a3 || angle > a1)) continue;
- }
-
- LWDEBUGF(3, "lwcircle_compute_box3d: potential extreame %d (%.16f, %.16f)", i, xe, ye);
-
- x1 = (x1 < xe) ? x1 : xe;
- y1 = (y1 < ye) ? y1 : ye;
- x2 = (x2 > xe) ? x2 : xe;
- y2 = (y2 > ye) ? y2 : ye;
- }
-
- LWDEBUGF(3, "lwcircle_compute_box3d: extreames found (%.16f %.16f, %.16f %.16f)", x1, y1, x2, y2);
-
- /*
- x1 = center->x + x1 * radius;
- x2 = center->x + x2 * radius;
- y1 = center->y + y1 * radius;
- y2 = center->y + y2 * radius;
- */
- z1 = (p1->z < p2->z) ? p1->z : p2->z;
- z1 = (z1 < p3->z) ? z1 : p3->z;
- z2 = (p1->z > p2->z) ? p1->z : p2->z;
- z2 = (z2 > p3->z) ? z2 : p3->z;
-
- box = lwalloc(sizeof(BOX3D));
- box->xmin = x1; box->xmax = x2;
- box->ymin = y1; box->ymax = y2;
- box->zmin = z1; box->zmax = z2;
-
- lwfree(center);
-
- return box;
-}
-
-/*
- * Find bounding box (standard one)
- * zmin=zmax=NO_Z_VALUE if 2d
- * TODO: This ignores curvature, which should be taken into account.
- */
-BOX3D *
-lwcurve_compute_box3d(LWCURVE *curve)
-{
- BOX3D *box, *tmp;
- int i;
- POINT4D *p1 = lwalloc(sizeof(POINT4D));
- POINT4D *p2 = lwalloc(sizeof(POINT4D));
- POINT4D *p3 = lwalloc(sizeof(POINT4D));
-
- LWDEBUG(2, "lwcurve_compute_box3d called.");
-
- /* initialize box values */
- box = lwalloc(sizeof(BOX3D));
- box->xmin = MAXFLOAT; box->xmax = -1 * MAXFLOAT;
- box->ymin = MAXFLOAT; box->ymax = -1 * MAXFLOAT;
- box->zmin = MAXFLOAT; box->zmax = -1 * MAXFLOAT;
-
- for(i = 2; i < curve->points->npoints; i+=2)
- {
- getPoint4d_p(curve->points, i-2, p1);
- getPoint4d_p(curve->points, i-1, p2);
- getPoint4d_p(curve->points, i, p3);
- tmp = lwcircle_compute_box3d(p1, p2, p3);
- if(tmp == NULL) continue;
- box->xmin = (box->xmin < tmp->xmin) ? box->xmin : tmp->xmin;
- box->xmax = (box->xmax > tmp->xmax) ? box->xmax : tmp->xmax;
- box->ymin = (box->ymin < tmp->ymin) ? box->ymin : tmp->ymin;
- box->ymax = (box->ymax > tmp->ymax) ? box->ymax : tmp->ymax;
- box->zmin = (box->zmin < tmp->zmin) ? box->zmin : tmp->zmin;
- box->zmax = (box->zmax > tmp->zmax) ? box->zmax : tmp->zmax;
-
- LWDEBUGF(4, "curve %d x=(%.16f,%.16f) y=(%.16f,%.16f) z=(%.16f,%.16f)", i/2, box->xmin, box->xmax, box->ymin, box->ymax, box->zmin, box->zmax);
- }
-
-
- return box;
-}
-
-int
-lwcurve_compute_box2d_p(LWCURVE *curve, BOX2DFLOAT4 *result)
-{
- BOX3D *box = lwcurve_compute_box3d(curve);
- LWDEBUG(2, "lwcurve_compute_box2d_p called.");
-
- if(box == NULL) return 0;
- box3d_to_box2df_p(box, result);
- return 1;
-}
-
-void pfree_curve(LWCURVE *curve)
-{
- lwfree(curve->points);
- lwfree(curve);
-}
-
-/* find length of this serialized curve */
-size_t
-lwgeom_size_curve(const uchar *serialized_curve)
-{
- int type = (uchar)serialized_curve[0];
- uint32 result = 1; /* type */
- const uchar *loc;
- uint32 npoints;
-
- LWDEBUG(2, "lwgeom_size_curve called");
-
- if(lwgeom_getType(type) != CURVETYPE)
- lwerror("lwgeom_size_curve::attempt to find the length of a non-curve");
-
- loc = serialized_curve + 1;
- if(lwgeom_hasBBOX(type))
- {
- loc += sizeof(BOX2DFLOAT4);
- result += sizeof(BOX2DFLOAT4);
- }
-
- if(lwgeom_hasSRID(type))
- {
- loc += 4; /* type + SRID */
- result += 4;
- }
-
- /* we've read the type (1 byte) and SRID (4 bytes, if present) */
- npoints = lw_get_uint32(loc);
- result += sizeof(uint32); /* npoints */
-
- result += TYPE_NDIMS(type) * sizeof(double) * npoints;
-
- LWDEBUGF(3, "lwgeom_size_curve returning %d", result);
-
- return result;
-}
-
-void printLWCURVE(LWCURVE *curve)
-{
- lwnotice("LWCURVE {");
- lwnotice(" ndims = %i", (int)TYPE_NDIMS(curve->type));
- lwnotice(" SRID = %i", (int)curve->SRID);
- printPA(curve->points);
- lwnotice("}");
-}
-
-/* Clone LWCURVE object. POINTARRAY is not copied. */
-LWCURVE *
-lwcurve_clone(const LWCURVE *g)
-{
- LWCURVE *ret = lwalloc(sizeof(LWCURVE));
- memcpy(ret, g, sizeof(LWCURVE));
- if(g->bbox) ret->bbox = box2d_clone(g->bbox);
- return ret;
-}
-
-/*
- * Add 'what' to this curve at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTICURVE or a GEOMETRYCOLLECTION
- */
-LWGEOM *
-lwcurve_add(const LWCURVE *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
-
- if(where != -1 && where != 0)
- {
- lwerror("lwcurve_add only supports 0 or -1 as second argument %d", where);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*2);
- if(where == -1) /* append */
- {
- geoms[0] = lwgeom_clone((LWGEOM *)to);
- geoms[1] = lwgeom_clone(what);
- }
- else /* prepend */
- {
- geoms[0] = lwgeom_clone(what);
- geoms[1] = lwgeom_clone((LWGEOM *)to);
- }
-
- /* reset SRID and wantbbox flag from component types */
- geoms[0]->SRID = geoms[1]->SRID = -1;
- TYPE_SETHASSRID(geoms[0]->type, 0);
- TYPE_SETHASSRID(geoms[1]->type, 0);
- TYPE_SETHASBBOX(geoms[0]->type, 0);
- TYPE_SETHASBBOX(geoms[1]->type, 0);
-
- /* Find appropriate geom type */
- if(TYPE_GETTYPE(what->type) == CURVETYPE || TYPE_GETTYPE(what->type) == LINETYPE) newtype = MULTICURVETYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- 2, geoms);
-
- return (LWGEOM *)col;
-}
-
-void lwcurve_reverse(LWCURVE *curve)
-{
- ptarray_reverse(curve->points);
-}
-
-/*
- * TODO: Invalid segmentization. This should accomodate the curvature.
- */
-LWCURVE *
-lwcurve_segmentize2d(LWCURVE *curve, double dist)
-{
- return lwcurve_construct(curve->SRID, NULL,
- ptarray_segmentize2d(curve->points, dist));
-}
-
-/* check coordinate equality */
-char
-lwcurve_same(const LWCURVE *me, const LWCURVE *you)
-{
- return ptarray_same(me->points, you->points);
-}
-
-/*
- * Construct a LWCURVE from an array of LWPOINTs
- * LWCURVE dimensions are large enough to host all input dimensions.
- */
-LWCURVE *
-lwcurve_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points)
-{
- int zmflag=0;
- unsigned int i;
- POINTARRAY *pa;
- uchar *newpoints, *ptr;
- size_t ptsize, size;
-
- /*
- * Find output dimensions, check integrity
- */
- for(i = 0; i < npoints; i++)
- {
- if(TYPE_GETTYPE(points[i]->type) != POINTTYPE)
- {
- lwerror("lwcurve_from_lwpointarray: invalid input type: %s",
- lwgeom_typename(TYPE_GETTYPE(points[i]->type)));
- return NULL;
- }
- if(TYPE_HASZ(points[i]->type)) zmflag |= 2;
- if(TYPE_HASM(points[i]->type)) zmflag |=1;
- if(zmflag == 3) break;
- }
-
- if(zmflag == 0) ptsize = 2 * sizeof(double);
- else if(zmflag == 3) ptsize = 4 * sizeof(double);
- else ptsize = 3 * sizeof(double);
-
- /*
- * Allocate output points array
- */
- size = ptsize * npoints;
- newpoints = lwalloc(size);
- memset(newpoints, 0, size);
-
- ptr = newpoints;
- for(i = 0; i < npoints; i++)
- {
- size = pointArray_ptsize(points[i]->point);
- memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
- ptr += ptsize;
- }
- pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints);
-
- return lwcurve_construct(SRID, NULL, pa);
-}
-
-/*
- * Construct a LWCURVE from a LWMPOINT
- */
-LWCURVE *
-lwcurve_from_lwmpoint(int SRID, LWMPOINT *mpoint)
-{
- unsigned int i;
- POINTARRAY *pa;
- char zmflag = TYPE_GETZM(mpoint->type);
- size_t ptsize, size;
- uchar *newpoints, *ptr;
-
- if(zmflag == 0) ptsize = 2 * sizeof(double);
- else if(zmflag == 3) ptsize = 4 * sizeof(double);
- else ptsize = 3 * sizeof(double);
-
- /* Allocate space for output points */
- size = ptsize * mpoint->ngeoms;
- newpoints = lwalloc(size);
- memset(newpoints, 0, size);
-
- ptr = newpoints;
- for(i = 0; i < mpoint->ngeoms; i++)
- {
- memcpy(ptr,
- getPoint_internal(mpoint->geoms[i]->point, 0),
- ptsize);
- ptr += ptsize;
- }
-
- pa = pointArray_construct(newpoints, zmflag&2, zmflag&1,
- mpoint->ngeoms);
-
- LWDEBUGF(3, "lwcurve_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);
-
- return lwcurve_construct(SRID, NULL, pa);
-}
-
-LWCURVE *
-lwcurve_addpoint(LWCURVE *curve, LWPOINT *point, unsigned int where)
-{
- POINTARRAY *newpa;
- LWCURVE *ret;
-
- newpa = ptarray_addPoint(curve->points,
- getPoint_internal(point->point, 0),
- TYPE_NDIMS(point->type), where);
- ret = lwcurve_construct(curve->SRID, NULL, newpa);
-
- return ret;
-}
-
-LWCURVE *
-lwcurve_removepoint(LWCURVE *curve, unsigned int index)
-{
- POINTARRAY *newpa;
- LWCURVE *ret;
-
- newpa = ptarray_removePoint(curve->points, index);
- ret = lwcurve_construct(curve->SRID, NULL, newpa);
-
- return ret;
-}
-
-/*
- * Note: input will be changed, make sure you have permissions for this.
- * */
-void
-lwcurve_setPoint4d(LWCURVE *curve, unsigned int index, POINT4D *newpoint)
-{
- setPoint4d(curve->points, index, newpoint);
-}
-
-
Deleted: trunk/lwgeom/lwcurvepoly.c
===================================================================
--- trunk/lwgeom/lwcurvepoly.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwcurvepoly.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,86 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-/* basic LWCURVEPOLY manipulation */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-
-LWCURVEPOLY *
-lwcurvepoly_deserialize(uchar *srl)
-{
- LWCURVEPOLY *result;
- LWGEOM_INSPECTED *insp;
- int type = lwgeom_getType(srl[0]);
- int i;
-
- LWDEBUG(3, "lwcurvepoly_deserialize called.");
-
- if(type != CURVEPOLYTYPE)
- {
- lwerror("lwcurvepoly_deserialize called on NON curvepoly: %d",
- type);
- return NULL;
- }
-
- insp = lwgeom_inspect(srl);
-
- result = lwalloc(sizeof(LWCURVEPOLY));
- result->type = insp->type;
- result->SRID = insp->SRID;
- result->nrings = insp->ngeometries;
- result->rings = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
-
- if(lwgeom_hasBBOX(srl[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
- for(i = 0; i < insp->ngeometries; i++)
- {
- result->rings[i] = lwgeom_deserialize(insp->sub_geoms[i]);
- if(lwgeom_getType(result->rings[i]->type) != CURVETYPE
- && lwgeom_getType(result->rings[i]->type) != LINETYPE)
- {
- lwerror("Only Circular curves and Linestrings are currently supported as rings, not %s (%d)", lwgeom_typename(result->rings[i]->type), result->rings[i]->type);
- lwfree(result);
- lwfree(insp);
- return NULL;
- }
- if(TYPE_NDIMS(result->rings[i]->type) != TYPE_NDIMS(result->type))
- {
- lwerror("Mixed dimensions (curvepoly %d, ring %d)",
- TYPE_NDIMS(result->type), i,
- TYPE_NDIMS(result->rings[i]->type));
- lwfree(result);
- lwfree(insp);
- return NULL;
- }
- }
- return result;
-}
-
-LWGEOM *
-lwcurvepoly_add(const LWCURVEPOLY *to, uint32 where, const LWGEOM *what)
-{
- /* TODO */
- lwerror("lwcurvepoly_add not yet implemented.");
- return NULL;
-}
-
-
-
Deleted: trunk/lwgeom/lwgeom.c
===================================================================
--- trunk/lwgeom/lwgeom.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,696 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-/*#include "lwgeom_pg.h"*/
-#include "liblwgeom.h"
-#include "wktparse.h"
-
-
-LWGEOM *
-lwgeom_deserialize(uchar *srl)
-{
- int type = lwgeom_getType(srl[0]);
-
- LWDEBUGF(2, "lwgeom_deserialize got %d - %s", type, lwgeom_typename(type));
-
- switch (type)
- {
- case POINTTYPE:
- return (LWGEOM *)lwpoint_deserialize(srl);
- case LINETYPE:
- return (LWGEOM *)lwline_deserialize(srl);
- case CURVETYPE:
- return (LWGEOM *)lwcurve_deserialize(srl);
- case POLYGONTYPE:
- return (LWGEOM *)lwpoly_deserialize(srl);
- case MULTIPOINTTYPE:
- return (LWGEOM *)lwmpoint_deserialize(srl);
- case MULTILINETYPE:
- return (LWGEOM *)lwmline_deserialize(srl);
- case MULTIPOLYGONTYPE:
- return (LWGEOM *)lwmpoly_deserialize(srl);
- case COLLECTIONTYPE:
- return (LWGEOM *)lwcollection_deserialize(srl);
- case COMPOUNDTYPE:
- return (LWGEOM *)lwcompound_deserialize(srl);
- case CURVEPOLYTYPE:
- return (LWGEOM *)lwcurvepoly_deserialize(srl);
- case MULTICURVETYPE:
- return (LWGEOM *)lwmcurve_deserialize(srl);
- case MULTISURFACETYPE:
- return (LWGEOM *)lwmsurface_deserialize(srl);
- default:
- lwerror("Unknown geometry type: %d", type);
-
- return NULL;
- }
-
-}
-
-size_t
-lwgeom_serialize_size(LWGEOM *lwgeom)
-{
- int type = TYPE_GETTYPE(lwgeom->type);
-
- LWDEBUGF(2, "lwgeom_serialize_size(%s) called", lwgeom_typename(type));
-
- switch (type)
- {
- case POINTTYPE:
- return lwpoint_serialize_size((LWPOINT *)lwgeom);
- case LINETYPE:
- return lwline_serialize_size((LWLINE *)lwgeom);
- case POLYGONTYPE:
- return lwpoly_serialize_size((LWPOLY *)lwgeom);
- case CURVETYPE:
- return lwcurve_serialize_size((LWCURVE *)lwgeom);
- case CURVEPOLYTYPE:
- case COMPOUNDTYPE:
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTICURVETYPE:
- case MULTIPOLYGONTYPE:
- case MULTISURFACETYPE:
- case COLLECTIONTYPE:
- return lwcollection_serialize_size((LWCOLLECTION *)lwgeom);
- default:
- lwerror("Unknown geometry type: %d", type);
-
- return 0;
- }
-}
-
-void
-lwgeom_serialize_buf(LWGEOM *lwgeom, uchar *buf, size_t *retsize)
-{
- int type = TYPE_GETTYPE(lwgeom->type);
-
- LWDEBUGF(2, "lwgeom_serialize_buf called with a %s",
- lwgeom_typename(type));
-
- switch (type)
- {
- case POINTTYPE:
- lwpoint_serialize_buf((LWPOINT *)lwgeom, buf, retsize);
- break;
- case LINETYPE:
- lwline_serialize_buf((LWLINE *)lwgeom, buf, retsize);
- break;
- case POLYGONTYPE:
- lwpoly_serialize_buf((LWPOLY *)lwgeom, buf, retsize);
- break;
- case CURVETYPE:
- lwcurve_serialize_buf((LWCURVE *)lwgeom, buf, retsize);
- break;
- case CURVEPOLYTYPE:
- case COMPOUNDTYPE:
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTICURVETYPE:
- case MULTIPOLYGONTYPE:
- case MULTISURFACETYPE:
- case COLLECTIONTYPE:
- lwcollection_serialize_buf((LWCOLLECTION *)lwgeom, buf,
- retsize);
- break;
- default:
- lwerror("Unknown geometry type: %d", type);
- return;
- }
- return;
-}
-
-uchar *
-lwgeom_serialize(LWGEOM *lwgeom)
-{
- size_t size = lwgeom_serialize_size(lwgeom);
- size_t retsize;
- uchar *serialized = lwalloc(size);
-
- lwgeom_serialize_buf(lwgeom, serialized, &retsize);
-
-#if POSTGIS_DEBUG_LEVEL > 0
- if ( retsize != size )
- {
- lwerror("lwgeom_serialize: computed size %d, returned size %d",
- size, retsize);
- }
-#endif
-
- return serialized;
-}
-
-/* Force Right-hand-rule on LWGEOM polygons */
-void
-lwgeom_forceRHR(LWGEOM *lwgeom)
-{
- LWCOLLECTION *coll;
- int i;
-
- switch (TYPE_GETTYPE(lwgeom->type))
- {
- case POLYGONTYPE:
- lwpoly_forceRHR((LWPOLY *)lwgeom);
- return;
-
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- coll = (LWCOLLECTION *)lwgeom;
- for (i=0; i<coll->ngeoms; i++)
- lwgeom_forceRHR(coll->geoms[i]);
- return;
- }
-}
-
-/* Reverse vertex order of LWGEOM */
-void
-lwgeom_reverse(LWGEOM *lwgeom)
-{
- int i;
- LWCOLLECTION *col;
-
- switch (TYPE_GETTYPE(lwgeom->type))
- {
- case LINETYPE:
- lwline_reverse((LWLINE *)lwgeom);
- return;
- case POLYGONTYPE:
- lwpoly_reverse((LWPOLY *)lwgeom);
- return;
- case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- col = (LWCOLLECTION *)lwgeom;
- for (i=0; i<col->ngeoms; i++)
- lwgeom_reverse(col->geoms[i]);
- return;
- }
-}
-
-int
-lwgeom_compute_box2d_p(LWGEOM *lwgeom, BOX2DFLOAT4 *buf)
-{
- LWDEBUGF(2, "lwgeom_compute_box2d_p called of %p of type %d.", lwgeom, TYPE_GETTYPE(lwgeom->type));
-
- switch(TYPE_GETTYPE(lwgeom->type))
- {
- case POINTTYPE:
- return lwpoint_compute_box2d_p((LWPOINT *)lwgeom, buf);
- case LINETYPE:
- return lwline_compute_box2d_p((LWLINE *)lwgeom, buf);
- case CURVETYPE:
- return lwcurve_compute_box2d_p((LWCURVE *)lwgeom, buf);
- case POLYGONTYPE:
- return lwpoly_compute_box2d_p((LWPOLY *)lwgeom, buf);
- case COMPOUNDTYPE:
- case CURVEPOLYTYPE:
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTICURVETYPE:
- case MULTIPOLYGONTYPE:
- case MULTISURFACETYPE:
- case COLLECTIONTYPE:
- return lwcollection_compute_box2d_p((LWCOLLECTION *)lwgeom, buf);
- }
- return 0;
-}
-
-/*
- * dont forget to lwfree() result
- */
-BOX2DFLOAT4 *
-lwgeom_compute_box2d(LWGEOM *lwgeom)
-{
- BOX2DFLOAT4 *result = lwalloc(sizeof(BOX2DFLOAT4));
- if ( lwgeom_compute_box2d_p(lwgeom, result) ) return result;
- else {
- lwfree(result);
- return NULL;
- }
-}
-
-LWPOINT *
-lwgeom_as_lwpoint(LWGEOM *lwgeom)
-{
- if ( TYPE_GETTYPE(lwgeom->type) == POINTTYPE )
- return (LWPOINT *)lwgeom;
- else return NULL;
-}
-
-LWLINE *
-lwgeom_as_lwline(LWGEOM *lwgeom)
-{
- if ( TYPE_GETTYPE(lwgeom->type) == LINETYPE )
- return (LWLINE *)lwgeom;
- else return NULL;
-}
-
-LWCURVE *
-lwgeom_as_lwcurve(LWGEOM *lwgeom)
-{
- if( TYPE_GETTYPE(lwgeom->type) == CURVETYPE )
- return (LWCURVE *)lwgeom;
- else return NULL;
-}
-
-LWPOLY *
-lwgeom_as_lwpoly(LWGEOM *lwgeom)
-{
- if ( TYPE_GETTYPE(lwgeom->type) == POLYGONTYPE )
- return (LWPOLY *)lwgeom;
- else return NULL;
-}
-
-LWCOLLECTION *
-lwgeom_as_lwcollection(LWGEOM *lwgeom)
-{
- if ( TYPE_GETTYPE(lwgeom->type) >= MULTIPOINTTYPE
- && TYPE_GETTYPE(lwgeom->type) <= COLLECTIONTYPE)
- return (LWCOLLECTION *)lwgeom;
- else return NULL;
-}
-
-LWMPOINT *
-lwgeom_as_lwmpoint(LWGEOM *lwgeom)
-{
- if ( TYPE_GETTYPE(lwgeom->type) == MULTIPOINTTYPE )
- return (LWMPOINT *)lwgeom;
- else return NULL;
-}
-
-LWMLINE *
-lwgeom_as_lwmline(LWGEOM *lwgeom)
-{
- if ( TYPE_GETTYPE(lwgeom->type) == MULTILINETYPE )
- return (LWMLINE *)lwgeom;
- else return NULL;
-}
-
-LWMPOLY *
-lwgeom_as_lwmpoly(LWGEOM *lwgeom)
-{
- if ( TYPE_GETTYPE(lwgeom->type) == MULTIPOLYGONTYPE )
- return (LWMPOLY *)lwgeom;
- else return NULL;
-}
-
-LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj) { return (LWGEOM *)obj; }
-LWGEOM *lwmline_as_lwgeom(LWMLINE *obj) { return (LWGEOM *)obj; }
-LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj) { return (LWGEOM *)obj; }
-LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj) { return (LWGEOM *)obj; }
-LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj) { return (LWGEOM *)obj; }
-LWGEOM *lwline_as_lwgeom(LWLINE *obj) { return (LWGEOM *)obj; }
-LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj) { return (LWGEOM *)obj; }
-
-void
-lwgeom_release(LWGEOM *lwgeom)
-{
- uint32 i;
- LWCOLLECTION *col;
-
-#ifdef INTEGRITY_CHECKS
- if ( ! lwgeom )
- lwerror("lwgeom_release: someone called on 0x0");
-#endif
-
- /* Drop bounding box (always a copy) */
- if ( lwgeom->bbox ) {
- LWDEBUG(3, "lwgeom_release: releasing bbox.");
-
- lwfree(lwgeom->bbox);
- }
-
- /* Collection */
- if ( (col=lwgeom_as_lwcollection(lwgeom)) )
- {
- LWDEBUG(3, "lwgeom_release: Releasing collection.");
-
- for (i=0; i<col->ngeoms; i++)
- {
- lwgeom_release(col->geoms[i]);
- }
- lwfree(lwgeom);
- }
-
- /* Single element */
- else lwfree(lwgeom);
-
-}
-
-/* Clone an LWGEOM object. POINTARRAY are not copied. */
-LWGEOM *
-lwgeom_clone(const LWGEOM *lwgeom)
-{
- LWDEBUGF(2, "lwgeom_clone called with %p, %d", lwgeom, TYPE_GETTYPE(lwgeom->type));
-
- switch(TYPE_GETTYPE(lwgeom->type))
- {
- case POINTTYPE:
- return (LWGEOM *)lwpoint_clone((LWPOINT *)lwgeom);
- case LINETYPE:
- return (LWGEOM *)lwline_clone((LWLINE *)lwgeom);
- case CURVETYPE:
- return (LWGEOM *)lwcurve_clone((LWCURVE *)lwgeom);
- case POLYGONTYPE:
- return (LWGEOM *)lwpoly_clone((LWPOLY *)lwgeom);
- case COMPOUNDTYPE:
- case CURVEPOLYTYPE:
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTICURVETYPE:
- case MULTIPOLYGONTYPE:
- case MULTISURFACETYPE:
- case COLLECTIONTYPE:
- return (LWGEOM *)lwcollection_clone((LWCOLLECTION *)lwgeom);
- default:
- return NULL;
- }
-}
-
-/*
- * Add 'what' to 'to' at position 'where'
- *
- * where=0 == prepend
- * where=-1 == append
- * Appended-to LWGEOM gets a new type based on new condition.
- * Mix of dimensions is not allowed (TODO: allow it?).
- */
-LWGEOM *
-lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what)
-{
- if ( TYPE_NDIMS(what->type) != TYPE_NDIMS(to->type) )
- {
- lwerror("lwgeom_add: mixed dimensions not supported");
- return NULL;
- }
-
- LWDEBUGF(2, "lwgeom_add(%s, %d, %s) called",
- lwgeom_typename(TYPE_GETTYPE(to->type)),
- where,
- lwgeom_typename(TYPE_GETTYPE(what->type)));
-
- switch(TYPE_GETTYPE(to->type))
- {
- case POINTTYPE:
- return (LWGEOM *)lwpoint_add((const LWPOINT *)to, where, what);
- case LINETYPE:
- return (LWGEOM *)lwline_add((const LWLINE *)to, where, what);
-
- case CURVETYPE:
- return (LWGEOM *)lwcurve_add((const LWCURVE *)to, where, what);
-
- case POLYGONTYPE:
- return (LWGEOM *)lwpoly_add((const LWPOLY *)to, where, what);
-
- case COMPOUNDTYPE:
- return (LWGEOM *)lwcompound_add((const LWCOMPOUND *)to, where, what);
-
- case CURVEPOLYTYPE:
- return (LWGEOM *)lwcurvepoly_add((const LWCURVEPOLY *)to, where, what);
-
- case MULTIPOINTTYPE:
- return (LWGEOM *)lwmpoint_add((const LWMPOINT *)to,
- where, what);
-
- case MULTILINETYPE:
- return (LWGEOM *)lwmline_add((const LWMLINE *)to,
- where, what);
-
- case MULTICURVETYPE:
- return (LWGEOM *)lwmcurve_add((const LWMCURVE *)to,
- where, what);
-
- case MULTIPOLYGONTYPE:
- return (LWGEOM *)lwmpoly_add((const LWMPOLY *)to,
- where, what);
-
- case MULTISURFACETYPE:
- return (LWGEOM *)lwmsurface_add((const LWMSURFACE *)to,
- where, what);
-
- case COLLECTIONTYPE:
- return (LWGEOM *)lwcollection_add(
- (const LWCOLLECTION *)to, where, what);
-
- default:
- lwerror("lwgeom_add: unknown geometry type: %d",
- TYPE_GETTYPE(to->type));
- return NULL;
- }
-}
-
-/*
- * Return an alloced string
- */
-char *
-lwgeom_to_ewkt(LWGEOM *lwgeom)
-{
- uchar *serialized = lwgeom_serialize(lwgeom);
- char *ret;
- if ( ! serialized ) {
- lwerror("Error serializing geom %p", lwgeom);
- }
- ret = unparse_WKT(serialized, lwalloc, lwfree);
- lwfree(serialized);
- return ret;
-}
-
-/*
- * Return an alloced string
- */
-char *
-lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder)
-{
- uchar *serialized = lwgeom_serialize(lwgeom);
- char *hexwkb = unparse_WKB(serialized, lwalloc, lwfree, byteorder,NULL,1);
- lwfree(serialized);
- return hexwkb;
-}
-
-/*
- * Return an alloced string
- */
-uchar *
-lwgeom_to_ewkb(LWGEOM *lwgeom, char byteorder, size_t *outsize)
-{
- uchar *serialized = lwgeom_serialize(lwgeom);
-
- /*
- * We cast return to "unsigned" char as we are
- * requesting a "binary" output, not HEX
- * (last argument set to 0)
- */
- uchar *hexwkb = (uchar *)unparse_WKB(serialized, lwalloc, lwfree,
- byteorder, outsize, 0);
- lwfree(serialized);
- return hexwkb;
-}
-
-/*
- * Make an LWGEOM object from a EWKB binary representation.
- * Currently highly unoptimized as it:
- * - convert EWKB to HEXEWKB
- * - construct PG_LWGEOM
- * - deserialize it
- */
-LWGEOM *
-lwgeom_from_ewkb(uchar *ewkb, size_t size)
-{
- size_t hexewkblen = size*2;
- char *hexewkb;
- long int i;
- LWGEOM *ret;
- SERIALIZED_LWGEOM *serialized_lwgeom;
-
- /* "HEXify" the EWKB */
- hexewkb = lwalloc(hexewkblen+1);
- for (i=0; i<size; ++i) deparse_hex(ewkb[i], &hexewkb[i*2]);
- hexewkb[hexewkblen] = '\0';
-
- /* Rely on grammar parser to construct a LWGEOM */
- serialized_lwgeom = parse_lwgeom_wkt(hexewkb);
-
- /* Free intermediate HEXified representation */
- lwfree(hexewkb);
-
- /* Deserialize */
- ret = lwgeom_deserialize(serialized_lwgeom->lwgeom);
-
- return ret;
-}
-
-/*
- * geom1 same as geom2
- * iff
- * + have same type
- * + have same # objects
- * + have same bvol
- * + each object in geom1 has a corresponding object in geom2 (see above)
- */
-char
-lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
-{
- LWDEBUGF(2, "lwgeom_same(%s, %s) called",
- lwgeom_typename(TYPE_GETTYPE(lwgeom1->type)),
- lwgeom_typename(TYPE_GETTYPE(lwgeom2->type)));
-
- if ( TYPE_GETTYPE(lwgeom1->type) != TYPE_GETTYPE(lwgeom2->type) )
- {
- LWDEBUG(3, " type differ");
-
- return 0;
- }
-
- if ( TYPE_GETZM(lwgeom1->type) != TYPE_GETZM(lwgeom2->type) )
- {
- LWDEBUG(3, " ZM flags differ");
-
- return 0;
- }
-
- /* Check boxes if both already computed */
- if ( lwgeom1->bbox && lwgeom2->bbox )
- {
- /*lwnotice("bbox1:%p, bbox2:%p", lwgeom1->bbox, lwgeom2->bbox);*/
- if ( ! box2d_same(lwgeom1->bbox, lwgeom2->bbox) )
- {
- LWDEBUG(3, " bounding boxes differ");
-
- return 0;
- }
- }
-
- /* geoms have same type, invoke type-specific function */
- switch(TYPE_GETTYPE(lwgeom1->type))
- {
- case POINTTYPE:
- return lwpoint_same((LWPOINT *)lwgeom1,
- (LWPOINT *)lwgeom2);
- case LINETYPE:
- return lwline_same((LWLINE *)lwgeom1,
- (LWLINE *)lwgeom2);
- case POLYGONTYPE:
- return lwpoly_same((LWPOLY *)lwgeom1,
- (LWPOLY *)lwgeom2);
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- return lwcollection_same((LWCOLLECTION *)lwgeom1,
- (LWCOLLECTION *)lwgeom2);
- default:
- lwerror("lwgeom_same: unknown geometry type: %d",
- TYPE_GETTYPE(lwgeom1->type));
- return 0;
- }
-
-}
-
-void
-lwgeom_changed(LWGEOM *lwgeom)
-{
- if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
- lwgeom->bbox = NULL;
- TYPE_SETHASBBOX(lwgeom->type, 0);
-}
-
-void
-lwgeom_dropBBOX(LWGEOM *lwgeom)
-{
- if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
- lwgeom->bbox = NULL;
- TYPE_SETHASBBOX(lwgeom->type, 0);
-}
-
-/*
- * Ensure there's a box in the LWGEOM.
- * If the box is already there just return,
- * else compute it.
- */
-void
-lwgeom_addBBOX(LWGEOM *lwgeom)
-{
- if ( lwgeom->bbox ) return;
- lwgeom->bbox = lwgeom_compute_box2d(lwgeom);
- TYPE_SETHASBBOX(lwgeom->type, 1);
-}
-
-void
-lwgeom_dropSRID(LWGEOM *lwgeom)
-{
- TYPE_SETHASSRID(lwgeom->type, 0);
- lwgeom->SRID = -1;
-}
-
-LWGEOM *
-lwgeom_segmentize2d(LWGEOM *lwgeom, double dist)
-{
- switch(TYPE_GETTYPE(lwgeom->type))
- {
- case LINETYPE:
- return (LWGEOM *)lwline_segmentize2d((LWLINE *)lwgeom,
- dist);
- case POLYGONTYPE:
- return (LWGEOM *)lwpoly_segmentize2d((LWPOLY *)lwgeom,
- dist);
- case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- return (LWGEOM *)lwcollection_segmentize2d(
- (LWCOLLECTION *)lwgeom, dist);
-
- default:
- return lwgeom_clone(lwgeom);
- }
-}
-
-void
-lwgeom_longitude_shift(LWGEOM *lwgeom)
-{
- int i;
- switch(TYPE_GETTYPE(lwgeom->type))
- {
- LWPOINT *point;
- LWLINE *line;
- LWPOLY *poly;
- LWCOLLECTION *coll;
-
- case POINTTYPE:
- point = (LWPOINT *)lwgeom;
- ptarray_longitude_shift(point->point);
- return;
- case LINETYPE:
- line = (LWLINE *)lwgeom;
- ptarray_longitude_shift(line->points);
- return;
- case POLYGONTYPE:
- poly = (LWPOLY *)lwgeom;
- for (i=0; i<poly->nrings; i++)
- ptarray_longitude_shift(poly->rings[i]);
- return;
- case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- coll = (LWCOLLECTION *)lwgeom;
- for (i=0; i<coll->ngeoms; i++)
- lwgeom_longitude_shift(coll->geoms[i]);
- return;
- default:
- lwerror("%s:%d: unknown geom type: %d",
- __FILE__, __LINE__,
- TYPE_GETTYPE(lwgeom->type));
- }
-}
Deleted: trunk/lwgeom/lwgeom_api.c
===================================================================
--- trunk/lwgeom/lwgeom_api.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_api.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,2185 +0,0 @@
-
-#include <math.h>
-#include <float.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "liblwgeom.h"
-#include "wktparse.h"
-
-/*
- * Lower this to reduce integrity checks
- */
-#define PARANOIA_LEVEL 1
-
-
-
-/**********************************************************************
- * BOX routines
- *
- * returns the float thats very close to the input, but <=
- * handles the funny differences in float4 and float8 reps.
- **********************************************************************/
-
-
-/*
- * These are taken from glibc
- * some machines do *not* have these functions defined, so we give
- * an implementation of them here.
- */
-typedef int int32_tt;
-typedef unsigned int u_int32_tt;
-
-typedef union
-{
- float value;
- u_int32_tt word;
-} ieee_float_shape_type;
-
-#define GET_FLOAT_WORD(i,d) \
- do { \
- ieee_float_shape_type gf_u; \
- gf_u.value = (d); \
- (i) = gf_u.word; \
- } while (0)
-
-
-#define SET_FLOAT_WORD(d,i) \
- do { \
- ieee_float_shape_type sf_u; \
- sf_u.word = (i); \
- (d) = sf_u.value; \
- } while (0)
-
-
-/*
- * Returns the next smaller or next larger float
- * from x (in direction of y).
- */
-float
-nextafterf_custom(float x, float y)
-{
- int32_tt hx,hy,ix,iy;
-
- GET_FLOAT_WORD(hx,x);
- GET_FLOAT_WORD(hy,y);
- ix = hx&0x7fffffff; /* |x| */
- iy = hy&0x7fffffff; /* |y| */
-
- if((ix>0x7f800000) || /* x is nan */
- (iy>0x7f800000)) /* y is nan */
- return x+y;
- if(x==y) return y; /* x=y, return y */
- if(ix==0) { /* x == 0 */
- SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
- }
- if(hx>=0) { /* x > 0 */
- if(hx>hy) { /* x > y, x -= ulp */
- hx -= 1;
- } else { /* x < y, x += ulp */
- hx += 1;
- }
- } else { /* x < 0 */
- if(hy>=0||hx>hy){ /* x < y, x -= ulp */
- hx -= 1;
- } else { /* x > y, x += ulp */
- hx += 1;
- }
- }
- hy = hx&0x7f800000;
- if(hy>=0x7f800000) return x+x; /* overflow */
- if(hy<0x00800000) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
- SET_FLOAT_WORD(y,hx);
- return y;
- }
- }
- SET_FLOAT_WORD(x,hx);
- return x;
-}
-
-
-float nextDown_f(double d)
-{
- float result = d;
-
- if ( ((double) result) <=d)
- return result;
-
- return nextafterf_custom(result, result - 1000000);
-
-}
-
-/*
- * Returns the float thats very close to the input, but >=.
- * handles the funny differences in float4 and float8 reps.
- */
-float
-nextUp_f(double d)
-{
- float result = d;
-
- if ( ((double) result) >=d)
- return result;
-
- return nextafterf_custom(result, result + 1000000);
-}
-
-
-/*
- * Returns the double thats very close to the input, but <.
- * handles the funny differences in float4 and float8 reps.
- */
-double
-nextDown_d(float d)
-{
- double result = d;
-
- if ( result < d)
- return result;
-
- return nextafterf_custom(result, result - 1000000);
-}
-
-/*
- * Returns the double thats very close to the input, but >
- * handles the funny differences in float4 and float8 reps.
- */
-double
-nextUp_d(float d)
-{
- double result = d;
-
- if ( result > d)
- return result;
-
- return nextafterf_custom(result, result + 1000000);
-}
-
-
-
-/*
- * Convert BOX3D to BOX2D
- * returned box2d is allocated with 'lwalloc'
- */
-BOX2DFLOAT4 *
-box3d_to_box2df(BOX3D *box)
-{
- BOX2DFLOAT4 *result = (BOX2DFLOAT4*) lwalloc(sizeof(BOX2DFLOAT4));
-
-#if PARANOIA_LEVEL > 0
- if (box == NULL)
- {
- lwerror("box3d_to_box2df got NUL box");
- return NULL;
- }
-#endif
-
- result->xmin = nextDown_f(box->xmin);
- result->ymin = nextDown_f(box->ymin);
-
- result->xmax = nextUp_f(box->xmax);
- result->ymax = nextUp_f(box->ymax);
-
- return result;
-}
-
-/*
- * Convert BOX3D to BOX2D using pre-allocated BOX2D
- * returned box2d is allocated with 'lwalloc'
- * return 0 on error (NULL input box)
- */
-int
-box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *result)
-{
-#if PARANOIA_LEVEL > 0
- if (box == NULL)
- {
- lwerror("box3d_to_box2df got NUL box");
- return 0;
- }
-#endif
-
- result->xmin = nextDown_f(box->xmin);
- result->ymin = nextDown_f(box->ymin);
-
- result->xmax = nextUp_f(box->xmax);
- result->ymax = nextUp_f(box->ymax);
-
- return 1;
-}
-
-
-
-/*
- * Convert BOX2D to BOX3D
- * zmin and zmax are set to NO_Z_VALUE
- */
-BOX3D
-box2df_to_box3d(BOX2DFLOAT4 *box)
-{
- BOX3D result;
-
-#if PARANOIA_LEVEL > 0
- if (box == NULL)
- lwerror("box2df_to_box3d got NULL box");
-#endif
-
- result.xmin = box->xmin;
- result.ymin = box->ymin;
-
- result.xmax = box->xmax;
- result.ymax = box->ymax;
-
- result.zmin = result.zmax = NO_Z_VALUE;
-
- return result;
-}
-
-/*
- * Convert BOX2D to BOX3D, using pre-allocated BOX3D as output
- * Z values are set to NO_Z_VALUE.
- */
-void
-box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *out)
-{
- if (box == NULL) return;
-
- out->xmin = box->xmin;
- out->ymin = box->ymin;
-
- out->xmax = box->xmax;
- out->ymax = box->ymax;
-
- out->zmin = out->zmax = NO_Z_VALUE;
-}
-
-
-
-/*
- * Returns a BOX3D that encloses b1 and b2
- * box3d_union(NULL,A) --> A
- * box3d_union(A,NULL) --> A
- * box3d_union(A,B) --> A union B
- */
-BOX3D *
-box3d_union(BOX3D *b1, BOX3D *b2)
-{
- BOX3D *result;
-
- result = lwalloc(sizeof(BOX3D));
-
- if ( (b1 == NULL) && (b2 == NULL) )
- {
- return NULL;
- }
-
- if (b1 == NULL)
- {
- /*return b2 */
- memcpy(result, b2, sizeof(BOX3D));
- return result;
- }
- if (b2 == NULL)
- {
- /*return b1 */
- memcpy(result, b1, sizeof(BOX3D));
- return result;
- }
-
- if (b1->xmin < b2->xmin)
- result->xmin = b1->xmin;
- else
- result->xmin = b2->xmin;
-
- if (b1->ymin < b2->ymin)
- result->ymin = b1->ymin;
- else
- result->ymin = b2->ymin;
-
-
- if (b1->xmax > b2->xmax)
- result->xmax = b1->xmax;
- else
- result->xmax = b2->xmax;
-
- if (b1->ymax > b2->ymax)
- result->ymax = b1->ymax;
- else
- result->ymax = b2->ymax;
-
- if (b1->zmax > b2->zmax)
- result->zmax = b1->zmax;
- else
- result->zmax = b2->zmax;
-
- if (b1->zmin > b2->zmin)
- result->zmin = b1->zmin;
- else
- result->zmin = b2->zmin;
-
- return result;
-}
-
-/* Make given ubox a union of b1 and b2 */
-int
-box3d_union_p(BOX3D *b1, BOX3D *b2, BOX3D *ubox)
-{
-
- LWDEBUG(2, "box3d_union_p called: (xmin, xmax), (ymin, ymax), (zmin, zmax)");
- LWDEBUGF(4, "b1: (%.16f, %.16f),(%.16f, %.16f),(%.16f, %.16f)", b1->xmin, b1->xmax, b1->ymin, b1->ymax, b1->zmin, b1->zmax);
- LWDEBUGF(4, "b2: (%.16f, %.16f),(%.16f, %.16f),(%.16f, %.16f)", b2->xmin, b2->xmax, b2->ymin, b2->ymax, b2->zmin, b2->zmax);
-
- if ( (b1 == NULL) && (b2 == NULL) )
- {
- return 0;
- }
-
- if (b1 == NULL)
- {
- memcpy(ubox, b2, sizeof(BOX3D));
- return 1;
- }
- if (b2 == NULL)
- {
- memcpy(ubox, b1, sizeof(BOX3D));
- return 1;
- }
-
- if (b1->xmin < b2->xmin)
- ubox->xmin = b1->xmin;
- else
- ubox->xmin = b2->xmin;
-
- if (b1->ymin < b2->ymin)
- ubox->ymin = b1->ymin;
- else
- ubox->ymin = b2->ymin;
-
-
- if (b1->xmax > b2->xmax)
- ubox->xmax = b1->xmax;
- else
- ubox->xmax = b2->xmax;
-
- if (b1->ymax > b2->ymax)
- ubox->ymax = b1->ymax;
- else
- ubox->ymax = b2->ymax;
-
- if (b1->zmax > b2->zmax)
- ubox->zmax = b1->zmax;
- else
- ubox->zmax = b2->zmax;
-
- if (b1->zmin < b2->zmin)
- ubox->zmin = b1->zmin;
- else
- ubox->zmin = b2->zmin;
-
- return 1;
-}
-
-#if 0 /* UNUSED */
-/*
- * Returns a pointer to internal storage, or NULL
- * if the serialized form does not have a BBOX.
- */
-BOX2DFLOAT4 *
-getbox2d_internal(uchar *srl)
-{
- if (TYPE_HASBBOX(srl[0])) return (BOX2DFLOAT4 *)(srl+1);
- else return NULL;
-}
-#endif /* UNUSED */
-
-/*
- * Same as getbox2d, but modifies box instead of returning result on the stack
- */
-int
-getbox2d_p(uchar *srl, BOX2DFLOAT4 *box)
-{
- uchar type = srl[0];
- uchar *loc;
- BOX3D box3d;
-
- LWDEBUG(2, "getbox2d_p call");
-
- loc = srl+1;
-
- if (lwgeom_hasBBOX(type))
- {
- /*woot - this is easy */
- LWDEBUG(4, "getbox2d_p: has box");
- memcpy(box, loc, sizeof(BOX2DFLOAT4));
- return 1;
- }
-
- LWDEBUG(4, "getbox2d_p: has no box - computing");
-
- /* We have to actually compute it! */
- if ( ! compute_serialized_box3d_p(srl, &box3d) ) return 0;
-
- LWDEBUGF(4, "getbox2d_p: compute_serialized_box3d returned %p", box3d);
-
- if ( ! box3d_to_box2df_p(&box3d, box) ) return 0;
-
- LWDEBUG(4, "getbox2d_p: box3d converted to box2d");
-
- return 1;
-}
-
-/************************************************************************
- * POINTARRAY support functions
- *
- * TODO: should be moved to ptarray.c probably
- *
- ************************************************************************/
-
-/*
- * Copies a point from the point array into the parameter point
- * will set point's z=NO_Z_VALUE if pa is 2d
- * will set point's m=NO_M_VALUE if pa is 3d or 2d
- *
- * NOTE: point is a real POINT3D *not* a pointer
- */
-POINT4D
-getPoint4d(const POINTARRAY *pa, int n)
-{
- POINT4D result;
- getPoint4d_p(pa, n, &result);
- return result;
-}
-
-/*
- * Copies a point from the point array into the parameter point
- * will set point's z=NO_Z_VALUE if pa is 2d
- * will set point's m=NO_M_VALUE if pa is 3d or 2d
- *
- * NOTE: this will modify the point4d pointed to by 'point'.
- */
-int
-getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *op)
-{
- uchar *ptr;
- int zmflag;
-
-#if PARANOIA_LEVEL > 0
- if ( ! pa ) lwerror("getPoint4d_p: NULL pointarray");
-
- if ( (n<0) || (n>=pa->npoints))
- {
- lwerror("getPoint4d_p: point offset out of range");
- }
-#endif
-
- LWDEBUG(4, "getPoint4d_p called.");
-
- /* Get a pointer to nth point offset and zmflag */
- ptr=getPoint_internal(pa, n);
- zmflag=TYPE_GETZM(pa->dims);
-
- LWDEBUGF(4, "ptr %p, zmflag %d", ptr, zmflag);
-
- switch (zmflag)
- {
- case 0: /* 2d */
- memcpy(op, ptr, sizeof(POINT2D));
- op->m=NO_M_VALUE;
- op->z=NO_Z_VALUE;
- break;
-
- case 3: /* ZM */
- memcpy(op, ptr, sizeof(POINT4D));
- break;
-
- case 2: /* Z */
- memcpy(op, ptr, sizeof(POINT3DZ));
- op->m=NO_M_VALUE;
- break;
-
- case 1: /* M */
- memcpy(op, ptr, sizeof(POINT3DM));
- op->m=op->z; /* we use Z as temporary storage */
- op->z=NO_Z_VALUE;
- break;
-
- default:
- lwerror("Unknown ZM flag ??");
- }
- return 1;
-
-}
-
-
-
-/*
- * Copy a point from the point array into the parameter point
- * will set point's z=NO_Z_VALUE if pa is 2d
- * NOTE: point is a real POINT3DZ *not* a pointer
- */
-POINT3DZ
-getPoint3dz(const POINTARRAY *pa, int n)
-{
- POINT3DZ result;
- getPoint3dz_p(pa, n, &result);
- return result;
-}
-
-/*
- * Copy a point from the point array into the parameter point
- * will set point's z=NO_Z_VALUE if pa is 2d
- *
- * NOTE: point is a real POINT3DZ *not* a pointer
- */
-POINT3DM
-getPoint3dm(const POINTARRAY *pa, int n)
-{
- POINT3DM result;
- getPoint3dm_p(pa, n, &result);
- return result;
-}
-
-/*
- * Copy a point from the point array into the parameter point
- * will set point's z=NO_Z_VALUE if pa is 2d
- *
- * NOTE: this will modify the point3dz pointed to by 'point'.
- */
-int
-getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *op)
-{
- uchar *ptr;
-
-#if PARANOIA_LEVEL > 0
- if ( ! pa ) return 0;
-
- if ( (n<0) || (n>=pa->npoints))
- {
- LWDEBUGF(4, "%d out of numpoint range (%d)", n, pa->npoints);
- return 0; /*error */
- }
-#endif
-
- LWDEBUGF(2, "getPoint3dz_p called on array of %d-dimensions / %u pts",
- TYPE_NDIMS(pa->dims), pa->npoints);
-
- /* Get a pointer to nth point offset */
- ptr=getPoint_internal(pa, n);
-
- /*
- * if input POINTARRAY has the Z, it is always
- * at third position so make a single copy
- */
- if ( TYPE_HASZ(pa->dims) )
- {
- memcpy(op, ptr, sizeof(POINT3DZ));
- }
-
- /*
- * Otherwise copy the 2d part and initialize
- * Z to NO_Z_VALUE
- */
- else
- {
- memcpy(op, ptr, sizeof(POINT2D));
- op->z=NO_Z_VALUE;
- }
-
- return 1;
-
-}
-
-/*
- * Copy a point from the point array into the parameter point
- * will set point's m=NO_Z_VALUE if pa has no M
- *
- * NOTE: this will modify the point3dm pointed to by 'point'.
- */
-int
-getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *op)
-{
- uchar *ptr;
- int zmflag;
-
-#if PARANOIA_LEVEL > 0
- if ( ! pa ) return 0;
-
- if ( (n<0) || (n>=pa->npoints))
- {
- lwerror("%d out of numpoint range (%d)", n, pa->npoints);
- return 0; /*error */
- }
-#endif
-
- LWDEBUGF(2, "getPoint3dm_p(%d) called on array of %d-dimensions / %u pts",
- n, TYPE_NDIMS(pa->dims), pa->npoints);
-
-
- /* Get a pointer to nth point offset and zmflag */
- ptr=getPoint_internal(pa, n);
- zmflag=TYPE_GETZM(pa->dims);
-
- /*
- * if input POINTARRAY has the M and NO Z,
- * we can issue a single memcpy
- */
- if ( zmflag == 1 )
- {
- memcpy(op, ptr, sizeof(POINT3DM));
- return 1;
- }
-
- /*
- * Otherwise copy the 2d part and
- * initialize M to NO_M_VALUE
- */
- memcpy(op, ptr, sizeof(POINT2D));
-
- /*
- * Then, if input has Z skip it and
- * copy next double, otherwise initialize
- * M to NO_M_VALUE
- */
- if ( zmflag == 3 )
- {
- ptr+=sizeof(POINT3DZ);
- memcpy(&(op->m), ptr, sizeof(double));
- }
- else
- {
- op->m=NO_M_VALUE;
- }
-
- return 1;
-}
-
-
-/*
- * Copy a point from the point array into the parameter point
- * z value (if present) is not returned.
- *
- * NOTE: point is a real POINT2D *not* a pointer
- */
-POINT2D
-getPoint2d(const POINTARRAY *pa, int n)
-{
- POINT2D result;
- getPoint2d_p(pa, n, &result);
- return result;
-}
-
-/*
- * Copy a point from the point array into the parameter point
- * z value (if present) is not returned.
- *
- * NOTE: this will modify the point2d pointed to by 'point'.
- */
-int
-getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
-{
-#if PARANOIA_LEVEL > 0
- if ( ! pa ) return 0;
-
- if ( (n<0) || (n>=pa->npoints))
- {
- lwerror("getPoint2d_p: point offset out of range");
- return 0; /*error */
- }
-#endif
-
- /* this does x,y */
- memcpy(point, getPoint_internal(pa, n), sizeof(POINT2D));
- return 1;
-}
-
-/*
- * set point N to the given value
- * NOTE that the pointarray can be of any
- * dimension, the appropriate ordinate values
- * will be extracted from it
- *
- */
-void
-setPoint4d(POINTARRAY *pa, int n, POINT4D *p4d)
-{
- uchar *ptr=getPoint_internal(pa, n);
- switch ( TYPE_GETZM(pa->dims) )
- {
- case 3:
- memcpy(ptr, p4d, sizeof(POINT4D));
- break;
- case 2:
- memcpy(ptr, p4d, sizeof(POINT3DZ));
- break;
- case 1:
- memcpy(ptr, p4d, sizeof(POINT2D));
- ptr+=sizeof(POINT2D);
- memcpy(ptr, &(p4d->m), sizeof(double));
- break;
- case 0:
- memcpy(ptr, p4d, sizeof(POINT2D));
- break;
- }
-}
-
-
-/*
- * Get a pointer to nth point of a POINTARRAY.
- * You cannot safely cast this to a real POINT, due to memory alignment
- * constraints. Use getPoint*_p for that.
- */
-uchar *
-getPoint_internal(const POINTARRAY *pa, int n)
-{
- int size;
-
-#if PARANOIA_LEVEL > 0
- if ( pa == NULL ) {
- lwerror("getPoint got NULL pointarray");
- return NULL;
- }
-
- if ( (n<0) || (n>=pa->npoints))
- {
- return NULL; /*error */
- }
-#endif
-
- size = pointArray_ptsize(pa);
-
- return &(pa->serialized_pointlist[size*n]);
-}
-
-
-
-/*
- * Constructs a POINTARRAY.
- *
- * NOTE: points is *not* copied, so be careful about modification
- * (can be aligned/missaligned).
- *
- * NOTE: ndims is descriptive - it describes what type of data 'points'
- * points to. No data conversion is done.
- */
-POINTARRAY *
-pointArray_construct(uchar *points, char hasz, char hasm,
- uint32 npoints)
-{
- POINTARRAY *pa;
-
- LWDEBUG(2, "pointArray_construct called.");
-
- pa = (POINTARRAY*)lwalloc(sizeof(POINTARRAY));
-
- pa->dims = 0;
- TYPE_SETZM(pa->dims, hasz?1:0, hasm?1:0);
- pa->npoints = npoints;
-
- pa->serialized_pointlist = points;
-
- LWDEBUGF(4, "pointArray_construct returning %p", pa);
-
- return pa;
-}
-
-
-/*
- * Size of point represeneted in the POINTARRAY
- * 16 for 2d, 24 for 3d, 32 for 4d
- */
-int
-pointArray_ptsize(const POINTARRAY *pa)
-{
- LWDEBUGF(2, "pointArray_ptsize: TYPE_NDIMS(pa->dims)=%x\n",
- TYPE_NDIMS(pa->dims));
-
- return sizeof(double)*TYPE_NDIMS(pa->dims);
-}
-
-
-/***************************************************************************
- * Basic type handling
- ***************************************************************************/
-
-
-/* Returns true if this type says it has an SRID (S bit set) */
-char
-lwgeom_hasSRID(uchar type)
-{
- return TYPE_HASSRID(type);
-}
-
-/* Returns either 2,3, or 4 -- 2=2D, 3=3D, 4=4D */
-int
-lwgeom_ndims(uchar type)
-{
- return TYPE_NDIMS(type);
-}
-
-/* has M ? */
-int lwgeom_hasM(uchar type)
-{
- return ( (type & 0x10) >>4);
-}
-
-/* has Z ? */
-int lwgeom_hasZ(uchar type)
-{
- return ( (type & 0x20) >>5);
-}
-
-
-/* get base type (ie. POLYGONTYPE) */
-int
-lwgeom_getType(uchar type)
-{
- LWDEBUGF(2, "lwgeom_getType %d", type);
-
- return (type & 0x0F);
-}
-
-
-/* Construct a type (hasBOX=false) */
-uchar
-lwgeom_makeType(char hasz, char hasm, char hasSRID, int type)
-{
- return lwgeom_makeType_full(hasz, hasm, hasSRID, type, 0);
-}
-
-/*
- * Construct a type
- * TODO: needs to be expanded to accept explicit MZ type
- */
-uchar
-lwgeom_makeType_full(char hasz, char hasm, char hasSRID, int type, char hasBBOX)
-{
- uchar result = (char)type;
-
- TYPE_SETZM(result, hasz, hasm);
- TYPE_SETHASSRID(result, hasSRID);
- TYPE_SETHASBBOX(result, hasBBOX);
-
- return result;
-}
-
-/* Returns true if there's a bbox in this LWGEOM (B bit set) */
-char
-lwgeom_hasBBOX(uchar type)
-{
- return TYPE_HASBBOX(type);
-}
-
-/*****************************************************************************
- * Basic sub-geometry types
- *****************************************************************************/
-
-/* handle missaligned unsigned int32 data */
-uint32
-lw_get_uint32(const uchar *loc)
-{
- uint32 result;
-
- memcpy(&result, loc, sizeof(uint32));
- return result;
-}
-
-/* handle missaligned signed int32 data */
-int32
-lw_get_int32(const uchar *loc)
-{
- int32 result;
-
- memcpy(&result,loc, sizeof(int32));
- return result;
-}
-
-
-/*************************************************************************
- *
- * Multi-geometry support
- *
- * Note - for a simple type (ie. point), this will have
- * sub_geom[0] = serialized_form.
- *
- * For multi-geomtries sub_geom[0] will be a few bytes
- * into the serialized form.
- *
- * This function just computes the length of each sub-object and
- * pre-caches this info.
- *
- * For a geometry collection of multi* geometries, you can inspect
- * the sub-components
- * as well.
- */
-LWGEOM_INSPECTED *
-lwgeom_inspect(const uchar *serialized_form)
-{
- LWGEOM_INSPECTED *result = lwalloc(sizeof(LWGEOM_INSPECTED));
- uchar typefl = (uchar)serialized_form[0];
- uchar type;
- uchar **sub_geoms;
- const uchar *loc;
- int t;
-
- LWDEBUGF(2, "lwgeom_inspect: serialized@%p", serialized_form);
-
- if (serialized_form == NULL)
- return NULL;
-
- result->serialized_form = serialized_form;
- result->type = (uchar) serialized_form[0];
- result->SRID = -1; /* assume */
-
- type = lwgeom_getType(typefl);
-
- loc = serialized_form+1;
-
- if ( lwgeom_hasBBOX(typefl) )
- {
- loc += sizeof(BOX2DFLOAT4);
- }
-
- if ( lwgeom_hasSRID(typefl) )
- {
- result->SRID = lw_get_int32(loc);
- loc += 4;
- }
-
- if ( (type==POINTTYPE) || (type==LINETYPE) || (type==POLYGONTYPE) || (type == CURVETYPE))
- {
- /* simple geometry (point/line/polygon)-- not multi! */
- result->ngeometries = 1;
- sub_geoms = (uchar**) lwalloc(sizeof(char*));
- sub_geoms[0] = (uchar *)serialized_form;
- result->sub_geoms = (uchar **)sub_geoms;
- return result;
- }
-
- /* its a GeometryCollection or multi* geometry */
-
- result->ngeometries = lw_get_uint32(loc);
- loc +=4;
-
- LWDEBUGF(3, "lwgeom_inspect: geometry is a collection of %d elements",
- result->ngeometries);
-
- if ( ! result->ngeometries ) return result;
-
- sub_geoms = lwalloc(sizeof(uchar*) * result->ngeometries );
- result->sub_geoms = sub_geoms;
- sub_geoms[0] = (uchar *)loc;
-
- LWDEBUGF(3, "subgeom[0] @ %p (+%d)", sub_geoms[0], sub_geoms[0]-serialized_form);
-
- for (t=1;t<result->ngeometries; t++)
- {
- /* -1 = entire object */
- int sub_length = lwgeom_size_subgeom(sub_geoms[t-1], -1);
- sub_geoms[t] = sub_geoms[t-1] + sub_length;
-
- LWDEBUGF(3, "subgeom[%d] @ %p (+%d)",
- t, sub_geoms[t], sub_geoms[0]-serialized_form);
- }
-
- return result;
-
-}
-
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a point (with geom_num=0),
- * multipoint or geometrycollection
- */
-LWPOINT *
-lwgeom_getpoint(uchar *serialized_form, int geom_number)
-{
- int type = lwgeom_getType((uchar)serialized_form[0]);
- uchar *sub_geom;
-
- if ((type == POINTTYPE) && (geom_number == 0))
- {
- /* Be nice and do as they want instead of what they say */
- return lwpoint_deserialize(serialized_form);
- }
-
- if ((type != MULTIPOINTTYPE) && (type != COLLECTIONTYPE) )
- return NULL;
-
- sub_geom = lwgeom_getsubgeometry(serialized_form, geom_number);
- if (sub_geom == NULL)
- return NULL;
-
- type = lwgeom_getType(sub_geom[0]);
- if (type != POINTTYPE)
- return NULL;
-
- return lwpoint_deserialize(sub_geom);
-}
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a point (with geom_num=0), multipoint
- * or geometrycollection
- */
-LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
-{
- uchar *sub_geom;
- uchar type;
-
- sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
-
- if (sub_geom == NULL) return NULL;
-
- type = lwgeom_getType(sub_geom[0]);
- if (type != POINTTYPE) return NULL;
-
- return lwpoint_deserialize(sub_geom);
-}
-
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual geometry isnt a LINE, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a line, multiline or geometrycollection
- */
-LWLINE *
-lwgeom_getline(uchar *serialized_form, int geom_number)
-{
- uchar type = lwgeom_getType( (uchar) serialized_form[0]);
- uchar *sub_geom;
-
- if ((type == LINETYPE) && (geom_number == 0))
- {
- /* be nice and do as they want instead of what they say */
- return lwline_deserialize(serialized_form);
- }
-
- if ((type != MULTILINETYPE) && (type != COLLECTIONTYPE) )
- return NULL;
-
- sub_geom = lwgeom_getsubgeometry(serialized_form, geom_number);
- if (sub_geom == NULL) return NULL;
-
- type = lwgeom_getType((uchar) sub_geom[0]);
- if (type != LINETYPE) return NULL;
-
- return lwline_deserialize(sub_geom);
-}
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual geometry isnt a LINE, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a line, multiline or geometrycollection
- */
-LWLINE *
-lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
-{
- uchar *sub_geom;
- uchar type;
-
- sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
-
- if (sub_geom == NULL) return NULL;
-
- type = lwgeom_getType((uchar) sub_geom[0]);
- if (type != LINETYPE) return NULL;
-
- return lwline_deserialize(sub_geom);
-}
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a polygon, multipolygon or geometrycollection
- */
-LWPOLY *
-lwgeom_getpoly(uchar *serialized_form, int geom_number)
-{
- uchar type = lwgeom_getType((uchar)serialized_form[0]);
- uchar *sub_geom;
-
- if ((type == POLYGONTYPE) && (geom_number == 0))
- {
- /* Be nice and do as they want instead of what they say */
- return lwpoly_deserialize(serialized_form);
- }
-
- if ((type != MULTIPOLYGONTYPE) && (type != COLLECTIONTYPE) )
- return NULL;
-
- sub_geom = lwgeom_getsubgeometry(serialized_form, geom_number);
- if (sub_geom == NULL) return NULL;
-
- type = lwgeom_getType(sub_geom[0]);
- if (type != POLYGONTYPE) return NULL;
-
- return lwpoly_deserialize(sub_geom);
-}
-
-/*
- * 1st geometry has geom_number = 0
- * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
- * if there arent enough geometries, return null.
- * this is fine to call on a polygon, multipolygon or geometrycollection
- */
-LWPOLY *
-lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
-{
- uchar *sub_geom;
- uchar type;
-
- sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
-
- if (sub_geom == NULL) return NULL;
-
- type = lwgeom_getType(sub_geom[0]);
- if (type != POLYGONTYPE) return NULL;
-
- return lwpoly_deserialize(sub_geom);
-}
-
-/*
- * 1st geometry has geom_number = 0
- * if there arent enough geometries, return null.
- */
-LWGEOM *lwgeom_getgeom_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
-{
- uchar *sub_geom;
- uchar type;
-
- sub_geom = lwgeom_getsubgeometry_inspected(inspected, geom_number);
-
- if (sub_geom == NULL) return NULL;
-
- type = lwgeom_getType(sub_geom[0]);
-
- return lwgeom_deserialize(sub_geom);
-}
-
-
-/*
- * This gets the serialized form of a sub-geometry
- *
- * 1st geometry has geom_number = 0
- * if this isnt a multi* geometry, and geom_number ==0 then it returns
- * itself.
- *
- * Returns null on problems.
- *
- * In the future this is how you would access a muli* portion of a
- * geometry collection.
- * GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1))
- * ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1)
- * --> POINT(1 1)
- *
- * You can inspect the sub-geometry as well if you wish.
- *
- */
-uchar *
-lwgeom_getsubgeometry(const uchar *serialized_form, int geom_number)
-{
- uchar *result;
- /*major cheat!! */
- LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized_form);
-
- result = lwgeom_getsubgeometry_inspected(inspected, geom_number);
- pfree_inspected(inspected);
- return result;
-}
-
-uchar *
-lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
-{
- if ((geom_number <0) || (geom_number >= inspected->ngeometries) )
- {
- lwerror("lwgeom_getsubgeometry_inspected: geom_number out of range");
- return NULL;
- }
-
- return inspected->sub_geoms[geom_number];
-}
-
-
-/*
- * 1st geometry has geom_number = 0
- * use geom_number = -1 to find the actual type of the serialized form.
- * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
- * --> multipoint
- * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
- * --> point
- * gets the 8bit type of the geometry at location geom_number
- */
-uchar
-lwgeom_getsubtype(uchar *serialized_form, int geom_number)
-{
- char result;
- /*major cheat!! */
- LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized_form);
-
- result = lwgeom_getsubtype_inspected(inspected, geom_number);
- pfree_inspected(inspected);
- return result;
-}
-
-uchar
-lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number)
-{
- if ((geom_number <0) || (geom_number >= inspected->ngeometries) )
- return 99;
-
- return inspected->sub_geoms[geom_number][0]; /* 1st byte is type */
-}
-
-
-/*
- * How many sub-geometries are there?
- * for point,line,polygon will return 1.
- */
-int
-lwgeom_getnumgeometries(uchar *serialized_form)
-{
- uchar type = lwgeom_getType((uchar)serialized_form[0]);
- uchar *loc;
-
- if ( (type==POINTTYPE) || (type==LINETYPE) || (type==POLYGONTYPE) ||
- (type==CURVETYPE) || (type==COMPOUNDTYPE) || (type==CURVEPOLYTYPE) )
- {
- return 1;
- }
-
- loc = serialized_form+1;
-
- if (lwgeom_hasBBOX((uchar) serialized_form[0]))
- {
- loc += sizeof(BOX2DFLOAT4);
- }
-
- if (lwgeom_hasSRID((uchar) serialized_form[0]) )
- {
- loc += 4;
- }
- /* its a GeometryCollection or multi* geometry */
- return lw_get_uint32(loc);
-}
-
-/*
- * How many sub-geometries are there?
- * for point,line,polygon will return 1.
- */
-int
-lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected)
-{
- return inspected->ngeometries;
-}
-
-
-/*
- * Set finalType to COLLECTIONTYPE or 0 (0 means choose a best type)
- * (ie. give it 2 points and ask it to be a multipoint)
- * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
- * all subgeometries must have the same SRID
- * if you want to construct an inspected, call this then inspect the result...
- */
-uchar *
-lwgeom_serialized_construct(int SRID, int finalType, char hasz, char hasm,
- int nsubgeometries, uchar **serialized_subs)
-{
- uint32 *lengths;
- int t;
- int total_length = 0;
- char type = (char)-1;
- char this_type = -1;
- uchar *result;
- uchar *loc;
-
- if (nsubgeometries == 0)
- return lwgeom_constructempty(SRID, hasz, hasm);
-
- lengths = lwalloc(sizeof(int32) * nsubgeometries);
-
- for (t=0;t<nsubgeometries;t++)
- {
- lengths[t] = lwgeom_size_subgeom(serialized_subs[t],-1);
- total_length += lengths[t];
- this_type = lwgeom_getType((uchar) (serialized_subs[t][0]));
- if (type == (char)-1)
- {
- type = this_type;
- }
- else if (type == COLLECTIONTYPE)
- {
- /* still a collection type... */
- }
- else
- {
- if ( (this_type == MULTIPOINTTYPE) || (this_type == MULTILINETYPE) || (this_type == MULTIPOLYGONTYPE) || (this_type == COLLECTIONTYPE) )
- {
- type = COLLECTIONTYPE;
- }
- else
- {
- if ( (this_type == POINTTYPE) && (type==POINTTYPE) )
- type=MULTIPOINTTYPE;
- else if ( (this_type == LINETYPE) && (type==LINETYPE) )
- type=MULTILINETYPE;
- else if ( (this_type == POLYGONTYPE) && (type==POLYGONTYPE) )
- type=MULTIPOLYGONTYPE;
- else if ( (this_type == POLYGONTYPE) && (type==MULTIPOLYGONTYPE) )
- ; /* nop */
- else if ( (this_type == LINETYPE) && (type==MULTILINETYPE) )
- ; /* nop */
- else if ( (this_type == POINTTYPE) && (type==MULTIPOINTTYPE) )
- ; /* nop */
- else
- type = COLLECTIONTYPE;
- }
- }
- }
-
- if (type == POINTTYPE)
- type = MULTIPOINTTYPE;
- if (type == LINETYPE)
- type = MULTILINETYPE;
- if (type == POINTTYPE)
- type = MULTIPOINTTYPE;
-
- if (finalType == COLLECTIONTYPE)
- type = COLLECTIONTYPE;
-
- /* now we have a multi* or GEOMETRYCOLLECTION, let's serialize it */
-
- if (SRID != -1)
- total_length +=4; /* space for SRID */
-
- total_length +=1 ; /* main type; */
- total_length +=4 ; /* nsubgeometries */
-
- result = lwalloc(total_length);
- result[0] = (uchar) lwgeom_makeType(hasz, hasm, SRID != -1, type);
- if (SRID != -1)
- {
- memcpy(&result[1],&SRID,4);
- loc = result+5;
- }
- else
- loc = result+1;
-
- memcpy(loc,&nsubgeometries,4);
- loc +=4;
-
- for (t=0;t<nsubgeometries;t++)
- {
- memcpy(loc, serialized_subs[t], lengths[t] );
- loc += lengths[t] ;
- }
-
- lwfree(lengths);
- return result;
-}
-
-
-/*
- * Construct the empty geometry (GEOMETRYCOLLECTION(EMPTY)).
- *
- * Returns serialized form
- */
-uchar *
-lwgeom_constructempty(int SRID, char hasz, char hasm)
-{
- int size = 0;
- uchar *result;
- int ngeoms = 0;
- uchar *loc;
-
- if (SRID != -1)
- size +=4;
-
- size += 5;
-
- result = lwalloc(size);
-
- result[0] = lwgeom_makeType(hasz, hasm, SRID != -1, COLLECTIONTYPE);
- if (SRID != -1)
- {
- memcpy(&result[1],&SRID,4);
- loc = result+5;
- }
- else
- loc = result+1;
-
- memcpy(loc,&ngeoms,4);
- return result;
-}
-
-size_t
-lwgeom_empty_length(int SRID)
-{
- int size = 5;
- if ( SRID != 1 ) size += 4;
- return size;
-}
-
-/*
- * Construct the empty geometry (GEOMETRYCOLLECTION(EMPTY))
- * writing it into the provided buffer.
- */
-void
-lwgeom_constructempty_buf(int SRID, char hasz, char hasm,
- uchar *buf, size_t *retsize)
-{
- int ngeoms = 0;
-
- buf[0] =(uchar) lwgeom_makeType( hasz, hasm, SRID != -1, COLLECTIONTYPE);
- if (SRID != -1)
- {
- memcpy(&buf[1],&SRID,4);
- buf += 5;
- }
- else
- buf += 1;
-
- memcpy(buf, &ngeoms, 4);
-
- if (retsize) *retsize = lwgeom_empty_length(SRID);
-}
-
-/*
- * helper function (not for general use)
- * find the size a geometry (or a sub-geometry)
- * 1st geometry has geom_number = 0
- * use geom_number = -1 to find the actual type of the serialized form.
- * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
- * --> size of the multipoint
- * ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
- * --> size of the point
- * take a geometry, and find its length
- */
-size_t
-lwgeom_size(const uchar *serialized_form)
-{
- uchar type = lwgeom_getType((uchar) serialized_form[0]);
- int t;
- const uchar *loc;
- uint32 ngeoms;
- int sub_size;
- int result = 1; /* type */
-
- LWDEBUG(2, "lwgeom_size called");
-
- if (type == POINTTYPE)
- {
- LWDEBUG(3, "lwgeom_size: is a point");
-
- return lwgeom_size_point(serialized_form);
- }
- else if (type == LINETYPE)
- {
- LWDEBUG(3, "lwgeom_size: is a line");
-
- return lwgeom_size_line(serialized_form);
- }
- else if(type == CURVETYPE)
- {
- LWDEBUG(3, "lwgeom_size: is a curve");
-
- return lwgeom_size_curve(serialized_form);
- }
- else if (type == POLYGONTYPE)
- {
- LWDEBUG(3, "lwgeom_size: is a polygon");
-
- return lwgeom_size_poly(serialized_form);
- }
- else if (type == COMPOUNDTYPE)
- {
- LWDEBUG(3, "lwgeom_size: is a compound curve");
- }
-
- if ( type == 0 )
- {
- lwerror("lwgeom_size called with unknown-typed serialized geometry");
- return 0;
- }
-
- /*
- * Handle all the multi* and geometrycollections the same
- *
- * NOTE: for a geometry collection of GC of GC of GC we will
- * be recursing...
- */
-
- LWDEBUGF(3, "lwgeom_size called on a geoemtry with type %d", type);
-
- loc = serialized_form+1;
-
- if (lwgeom_hasBBOX((uchar) serialized_form[0]))
- {
- LWDEBUG(3, "lwgeom_size: has bbox");
-
- loc += sizeof(BOX2DFLOAT4);
- result +=sizeof(BOX2DFLOAT4);
- }
-
- if (lwgeom_hasSRID( (uchar) serialized_form[0]) )
- {
- LWDEBUG(3, "lwgeom_size: has srid");
-
- result +=4;
- loc +=4;
- }
-
-
- ngeoms = lw_get_uint32(loc);
- loc +=4;
- result += 4; /* numgeoms */
-
- LWDEBUGF(3, "lwgeom_size called on a geoemtry with %d elems (result so far: %d)", ngeoms, result);
-
- for (t=0;t<ngeoms;t++)
- {
- sub_size = lwgeom_size(loc);
-
- LWDEBUGF(3, " subsize %d", sub_size);
-
- loc += sub_size;
- result += sub_size;
- }
-
- LWDEBUGF(3, "lwgeom_size returning %d", result);
-
- return result;
-}
-
-size_t
-lwgeom_size_subgeom(const uchar *serialized_form, int geom_number)
-{
- if (geom_number == -1)
- {
- return lwgeom_size(serialized_form);
- }
- return lwgeom_size( lwgeom_getsubgeometry(serialized_form,geom_number));
-}
-
-
-
-int
-lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number)
-{
- return lwgeom_size(inspected->sub_geoms[geom_number]);
-}
-
-int
-compute_serialized_box3d_p(uchar *srl, BOX3D *out)
-{
- BOX3D *box = compute_serialized_box3d(srl);
- if ( ! box ) return 0;
- out->xmin = box->xmin;
- out->ymin = box->ymin;
- out->zmin = box->zmin;
- out->xmax = box->xmax;
- out->ymax = box->ymax;
- out->zmax = box->zmax;
- lwfree(box);
-
- return 1;
-}
-
-/*
- * Compute bounding box of a serialized LWGEOM, even if it is
- * already cached. The computed BOX2DFLOAT4 is stored at
- * the given location, the function returns 0 is the geometry
- * does not have a bounding box (EMPTY GEOM)
- */
-int
-compute_serialized_box2d_p(uchar *srl, BOX2DFLOAT4 *out)
-{
- BOX3D *result = compute_serialized_box3d(srl);
- if ( ! result ) return 0;
- out->xmin = result->xmin;
- out->xmax = result->xmax;
- out->ymin = result->ymin;
- out->ymax = result->ymax;
- lwfree(result);
-
- return 1;
-}
-
-/*
- * Don't forget to lwfree() result !
- */
-BOX3D *
-compute_serialized_box3d(uchar *srl)
-{
- int type = lwgeom_getType(srl[0]);
- int t;
- uchar *loc;
- uint32 ngeoms;
- BOX3D *result;
- BOX3D b1;
- int sub_size;
- char nboxes=0;
-
- LWDEBUGF(2, "compute_serialized_box3d called on type %d", type);
-
- if (type == POINTTYPE)
- {
- LWPOINT *pt = lwpoint_deserialize(srl);
-
- LWDEBUG(3, "compute_serialized_box3d: lwpoint deserialized");
-
- result = lwpoint_compute_box3d(pt);
-
- LWDEBUG(3, "compute_serialized_box3d: bbox found");
-
- pfree_point(pt);
- return result;
- }
-
- else if (type == LINETYPE)
- {
- LWLINE *line = lwline_deserialize(srl);
- result = lwline_compute_box3d(line);
- pfree_line(line);
- return result;
-
- }
- else if (type == CURVETYPE)
- {
- LWCURVE *curve = lwcurve_deserialize(srl);
- result = lwcurve_compute_box3d(curve);
- pfree_curve(curve);
- return result;
- }
- else if (type == POLYGONTYPE)
- {
- LWPOLY *poly = lwpoly_deserialize(srl);
- result = lwpoly_compute_box3d(poly);
- pfree_polygon(poly);
- return result;
- }
-
- if ( ! ( type == MULTIPOINTTYPE || type == MULTILINETYPE ||
- type == MULTIPOLYGONTYPE || type == COLLECTIONTYPE ||
- type == COMPOUNDTYPE || type == CURVEPOLYTYPE ||
- type == MULTICURVETYPE || type == MULTISURFACETYPE) )
- {
- lwnotice("compute_serialized_box3d called on unknown type %d", type);
- return NULL;
- }
-
- loc = srl+1;
-
- if (lwgeom_hasBBOX(srl[0]))
- {
- loc += sizeof(BOX2DFLOAT4);
- }
-
- if (lwgeom_hasSRID(srl[0]) )
- {
- loc +=4;
- }
-
- ngeoms = lw_get_uint32(loc);
- loc += 4;
-
- /* each sub-type */
- result = NULL;
- for (t=0; t<ngeoms; t++)
- {
- if ( compute_serialized_box3d_p(loc, &b1) )
- {
- LWDEBUG(3, "Geom %d have box:");
-#if POSTGIS_DEBUG_LEVEL >= 3
- printBOX3D(&b1);
-#endif
-
- if (result)
- {
- nboxes += box3d_union_p(result, &b1, result);
- }
- else
- {
- result = lwalloc(sizeof(BOX3D));
- memcpy(result, &b1, sizeof(BOX3D));
- }
- }
-
- sub_size = lwgeom_size(loc);
- loc += sub_size;
- }
-
- return result;
-
-}
-
-/****************************************************************
- * memory management
- *
- * these only delete the memory associated
- * directly with the structure - NOT the stuff pointing into
- * the original de-serialized info
- *
- ****************************************************************/
-
-void
-pfree_inspected(LWGEOM_INSPECTED *inspected)
-{
- if ( inspected->ngeometries )
- lwfree(inspected->sub_geoms);
- lwfree(inspected);
-}
-
-
-void pfree_POINTARRAY(POINTARRAY *pa)
-{
- lwfree(pa);
-}
-
-
-
-
-/************************************************
- * debugging routines
- ************************************************/
-
-
-void printBOX3D(BOX3D *box)
-{
- lwnotice("BOX3D: %g %g, %g %g", box->xmin, box->ymin,
- box->xmax, box->ymax);
-}
-
-void printPA(POINTARRAY *pa)
-{
- int t;
- POINT4D pt;
- char *mflag;
-
-
- if ( TYPE_HASM(pa->dims) ) mflag = "M";
- else mflag = "";
-
- lwnotice(" POINTARRAY%s{", mflag);
- lwnotice(" ndims=%i, ptsize=%i",
- TYPE_NDIMS(pa->dims), pointArray_ptsize(pa));
- lwnotice(" npoints = %i", pa->npoints);
-
- for (t =0; t<pa->npoints;t++)
- {
- getPoint4d_p(pa, t, &pt);
- if (TYPE_NDIMS(pa->dims) == 2)
- {
- lwnotice(" %i : %lf,%lf",t,pt.x,pt.y);
- }
- if (TYPE_NDIMS(pa->dims) == 3)
- {
- lwnotice(" %i : %lf,%lf,%lf",t,pt.x,pt.y,pt.z);
- }
- if (TYPE_NDIMS(pa->dims) == 4)
- {
- lwnotice(" %i : %lf,%lf,%lf,%lf",t,pt.x,pt.y,pt.z,pt.m);
- }
- }
-
- lwnotice(" }");
-}
-
-void printBYTES(uchar *a, int n)
-{
- int t;
- char buff[3];
-
- buff[2] = 0; /* null terminate */
-
- lwnotice(" BYTE ARRAY (n=%i) IN HEX: {", n);
- for (t=0;t<n;t++)
- {
- deparse_hex(a[t], buff);
- lwnotice(" %i : %s", t,buff );
- }
- lwnotice(" }");
-}
-
-
-void
-printMULTI(uchar *serialized)
-{
- LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized);
- LWLINE *line;
- LWPOINT *point;
- LWPOLY *poly;
- int t;
-
- lwnotice("MULTI* geometry (type = %i), with %i sub-geoms",lwgeom_getType((uchar)serialized[0]), inspected->ngeometries);
-
- for (t=0;t<inspected->ngeometries;t++)
- {
- lwnotice(" sub-geometry %i:", t);
- line = NULL; point = NULL; poly = NULL;
-
- line = lwgeom_getline_inspected(inspected,t);
- if (line !=NULL)
- {
- printLWLINE(line);
- }
- poly = lwgeom_getpoly_inspected(inspected,t);
- if (poly !=NULL)
- {
- printLWPOLY(poly);
- }
- point = lwgeom_getpoint_inspected(inspected,t);
- if (point !=NULL)
- {
- printPA(point->point);
- }
- }
-
- lwnotice("end multi*");
-
- pfree_inspected(inspected);
-}
-
-void
-printType(uchar type)
-{
- lwnotice("type 0x%x ==> hasBBOX=%i, hasSRID=%i, ndims=%i, type=%i",(unsigned int) type, lwgeom_hasBBOX(type), lwgeom_hasSRID(type),lwgeom_ndims(type), lwgeom_getType(type));
-}
-
-/*
- * Get the SRID from the LWGEOM.
- * None present => -1
- */
-int
-lwgeom_getsrid(uchar *serialized)
-{
- uchar type = serialized[0];
- uchar *loc = serialized+1;
-
- if ( ! lwgeom_hasSRID(type)) return -1;
-
- if (lwgeom_hasBBOX(type))
- {
- loc += sizeof(BOX2DFLOAT4);
- }
-
- return lw_get_int32(loc);
-}
-
-char
-ptarray_isccw(const POINTARRAY *pa)
-{
- int i;
- double area = 0;
- POINT2D p1, p2;
-
- for (i=0; i<pa->npoints-1; i++)
- {
- getPoint2d_p(pa, i, &p1);
- getPoint2d_p(pa, i+1, &p2);
- area += (p1.y * p2.x) - (p1.x * p2.y);
- }
- if ( area > 0 ) return 0;
- else return 1;
-}
-
-/*
- * Returns a BOX2DFLOAT4 that encloses b1 and b2
- *
- * box2d_union(NULL,A) --> A
- * box2d_union(A,NULL) --> A
- * box2d_union(A,B) --> A union B
- */
-BOX2DFLOAT4 *
-box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2)
-{
- BOX2DFLOAT4 *result;
-
- if ( (b1 == NULL) && (b2 == NULL) )
- {
- return NULL;
- }
-
- result = lwalloc(sizeof(BOX2DFLOAT4));
-
- if (b1 == NULL)
- {
- memcpy(result, b2, sizeof(BOX2DFLOAT4));
- return result;
- }
- if (b2 == NULL)
- {
- memcpy(result, b1, sizeof(BOX2DFLOAT4));
- return result;
- }
-
- if (b1->xmin < b2->xmin) result->xmin = b1->xmin;
- else result->xmin = b2->xmin;
-
- if (b1->ymin < b2->ymin) result->ymin = b1->ymin;
- else result->ymin = b2->ymin;
-
- if (b1->xmax > b2->xmax) result->xmax = b1->xmax;
- else result->xmax = b2->xmax;
-
- if (b1->ymax > b2->ymax) result->ymax = b1->ymax;
- else result->ymax = b2->ymax;
-
- return result;
-}
-
-/*
- * ubox may be one of the two args...
- * return 1 if done something to ubox, 0 otherwise.
- */
-int
-box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox)
-{
- if ( (b1 == NULL) && (b2 == NULL) )
- {
- return 0;
- }
-
- if (b1 == NULL)
- {
- memcpy(ubox, b2, sizeof(BOX2DFLOAT4));
- return 1;
- }
- if (b2 == NULL)
- {
- memcpy(ubox, b1, sizeof(BOX2DFLOAT4));
- return 1;
- }
-
- if (b1->xmin < b2->xmin) ubox->xmin = b1->xmin;
- else ubox->xmin = b2->xmin;
-
- if (b1->ymin < b2->ymin) ubox->ymin = b1->ymin;
- else ubox->ymin = b2->ymin;
-
- if (b1->xmax > b2->xmax) ubox->xmax = b1->xmax;
- else ubox->xmax = b2->xmax;
-
- if (b1->ymax > b2->ymax) ubox->ymax = b1->ymax;
- else ubox->ymax = b2->ymax;
-
- return 1;
-}
-
-const char *
-lwgeom_typeflags(uchar type)
-{
- static char flags[5];
- int flagno=0;
- if ( TYPE_HASZ(type) ) flags[flagno++] = 'Z';
- if ( TYPE_HASM(type) ) flags[flagno++] = 'M';
- if ( TYPE_HASBBOX(type) ) flags[flagno++] = 'B';
- if ( TYPE_HASSRID(type) ) flags[flagno++] = 'S';
- flags[flagno] = '\0';
-
- LWDEBUGF(4, "Flags: %s - returning %p", flags, flags);
-
- return flags;
-}
-
-/*
- * Given a string with at least 2 chars in it, convert them to
- * a byte value. No error checking done!
- */
-uchar
-parse_hex(char *str)
-{
- /* do this a little brute force to make it faster */
-
- uchar result_high = 0;
- uchar result_low = 0;
-
- switch (str[0])
- {
- case '0' :
- result_high = 0;
- break;
- case '1' :
- result_high = 1;
- break;
- case '2' :
- result_high = 2;
- break;
- case '3' :
- result_high = 3;
- break;
- case '4' :
- result_high = 4;
- break;
- case '5' :
- result_high = 5;
- break;
- case '6' :
- result_high = 6;
- break;
- case '7' :
- result_high = 7;
- break;
- case '8' :
- result_high = 8;
- break;
- case '9' :
- result_high = 9;
- break;
- case 'A' :
- result_high = 10;
- break;
- case 'B' :
- result_high = 11;
- break;
- case 'C' :
- result_high = 12;
- break;
- case 'D' :
- result_high = 13;
- break;
- case 'E' :
- result_high = 14;
- break;
- case 'F' :
- result_high = 15;
- break;
- }
- switch (str[1])
- {
- case '0' :
- result_low = 0;
- break;
- case '1' :
- result_low = 1;
- break;
- case '2' :
- result_low = 2;
- break;
- case '3' :
- result_low = 3;
- break;
- case '4' :
- result_low = 4;
- break;
- case '5' :
- result_low = 5;
- break;
- case '6' :
- result_low = 6;
- break;
- case '7' :
- result_low = 7;
- break;
- case '8' :
- result_low = 8;
- break;
- case '9' :
- result_low = 9;
- break;
- case 'A' :
- result_low = 10;
- break;
- case 'B' :
- result_low = 11;
- break;
- case 'C' :
- result_low = 12;
- break;
- case 'D' :
- result_low = 13;
- break;
- case 'E' :
- result_low = 14;
- break;
- case 'F' :
- result_low = 15;
- break;
- }
- return (uchar) ((result_high<<4) + result_low);
-}
-
-
-/*
- * Given one byte, populate result with two byte representing
- * the hex number.
- *
- * Ie. deparse_hex( 255, mystr)
- * -> mystr[0] = 'F' and mystr[1] = 'F'
- *
- * No error checking done
- */
-void
-deparse_hex(uchar str, char *result)
-{
- int input_high;
- int input_low;
- static char outchr[]={"0123456789ABCDEF" };
-
- input_high = (str>>4);
- input_low = (str & 0x0F);
-
- result[0] = outchr[input_high];
- result[1] = outchr[input_low];
-
-}
-
-SERIALIZED_LWGEOM *
-parse_lwgeom_wkt(char *wkt_input)
-{
- SERIALIZED_LWGEOM *serialized_form = parse_lwg(wkt_input,
- lwalloc, lwerror);
-
-
- LWDEBUGF(2, "parse_lwgeom_wkt with %s",wkt_input);
-
- if (serialized_form == NULL)
- {
- lwerror("parse_WKT:: couldnt parse!");
- return NULL;
- }
-
- return serialized_form;
-
-}
-
-/*
- * Find interpolation point I
- * between point A and point B
- * so that the len(AI) == len(AB)*F
- * and I falls on AB segment.
- *
- * Example:
- *
- * F=0.5 : A----I----B
- * F=1 : A---------B==I
- * F=0 : A==I---------B
- * F=.2 : A-I-------B
- */
-void
-interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F)
-{
-#if PARANOIA_LEVEL > 0
- double absF=fabs(F);
- if ( absF < 0 || absF > 1 )
- {
- lwerror("interpolate_point4d: invalid F (%g)", F);
- }
-#endif
- I->x=A->x+((B->x-A->x)*F);
- I->y=A->y+((B->y-A->y)*F);
- I->z=A->z+((B->z-A->z)*F);
- I->m=A->m+((B->m-A->m)*F);
-}
Modified: trunk/lwgeom/lwgeom_dump.c
===================================================================
--- trunk/lwgeom/lwgeom_dump.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_dump.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -17,9 +17,7 @@
#include "liblwgeom.h"
#include "lwgeom_pg.h"
#include "profile.h"
-#include "wktparse.h"
-
Datum LWGEOM_dump(PG_FUNCTION_ARGS);
Datum LWGEOM_dump_rings(PG_FUNCTION_ARGS);
Modified: trunk/lwgeom/lwgeom_functions_basic.c
===================================================================
--- trunk/lwgeom/lwgeom_functions_basic.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_functions_basic.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -25,9 +25,7 @@
#include "liblwgeom.h"
#include "lwgeom_pg.h"
#include "profile.h"
-#include "wktparse.h"
-
Datum LWGEOM_mem_size(PG_FUNCTION_ARGS);
Datum LWGEOM_summary(PG_FUNCTION_ARGS);
Datum LWGEOM_npoints(PG_FUNCTION_ARGS);
@@ -112,8 +110,6 @@
text *mytext;
LWGEOM *lwgeom;
- init_pg_func();
-
lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom));
result = lwgeom_summary(lwgeom, 0);
@@ -2910,11 +2906,9 @@
PG_LWGEOM *lwgeom;
char *result_cstring;
int len;
- char *result,*loc_wkt;
+ char *result,*loc_wkt;
/*char *semicolonLoc; */
- init_pg_func();
-
lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
result_cstring = unparse_WKT(SERIALIZED_FORM(lwgeom),lwalloc,lwfree);
@@ -2954,8 +2948,6 @@
double result;
int SRID;
- init_pg_func();
-
/* Extract first point */
geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
lwpoint = lwpoint_deserialize(SERIALIZED_FORM(geom));
Modified: trunk/lwgeom/lwgeom_geos_c.c
===================================================================
--- trunk/lwgeom/lwgeom_geos_c.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_geos_c.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -8,7 +8,7 @@
#include "lwgeom_pg.h"
#include "liblwgeom.h"
#include "profile.h"
-#include "wktparse.h"
+
#include "geos_c.h"
#include "lwgeom_rtree.h"
Modified: trunk/lwgeom/lwgeom_gist.c
===================================================================
--- trunk/lwgeom/lwgeom_gist.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_gist.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -19,11 +19,7 @@
#include "lwgeom_pg.h"
#include "stringBuffer.h"
-#if POSTGIS_DEBUG_LEVEL > 0
-#include "wktparse.h"
-#endif
-
/*
* implementation GiST support and basic LWGEOM operations (like &&)
*/
Modified: trunk/lwgeom/lwgeom_inout.c
===================================================================
--- trunk/lwgeom/lwgeom_inout.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_inout.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -24,7 +24,6 @@
#include "lwgeom_pg.h"
-#include "wktparse.h"
#include "profile.h"
void elog_ERROR(const char* string);
@@ -97,8 +96,6 @@
PG_LWGEOM *lwgeom;
char *result;
- init_pg_func();
-
lwgeom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1,NULL,1);
@@ -118,8 +115,6 @@
text *type;
unsigned int byteorder=-1;
- init_pg_func();
-
lwgeom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
@@ -169,8 +164,6 @@
text *text_result;
size_t size;
- init_pg_func();
-
lwgeom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1,&size,1);
@@ -250,8 +243,6 @@
profstart(PROF_QRUN);
#endif
- init_pg_func();
-
if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
{
type = PG_GETARG_TEXT_P(1);
@@ -479,8 +470,6 @@
char *wkt;
int wkt_size ;
- init_pg_func();
-
wkt_size = VARSIZE(wkt_input)-VARHDRSZ; /* actual letters */
wkt = palloc( wkt_size+1); /* +1 for null */
@@ -490,7 +479,7 @@
POSTGIS_DEBUGF(3, "in parse_WKT_lwgeom with input: '%s'",wkt);
- serialized_lwgeom = parse_lwg((const char *)wkt, (allocator)lwalloc, (report_error)elog_ERROR);
+ serialized_lwgeom = parse_lwgeom_wkt(wkt);
lwgeom = lwgeom_deserialize(serialized_lwgeom->lwgeom);
ret = pglwgeom_serialize(lwgeom);
Modified: trunk/lwgeom/lwgeom_ogc.c
===================================================================
--- trunk/lwgeom/lwgeom_ogc.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_ogc.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -28,9 +28,6 @@
#include "lwgeom_pg.h"
-
-#include "wktparse.h"
-
/* ---- SRID(geometry) */
Datum LWGEOM_getSRID(PG_FUNCTION_ARGS);
/* ---- SetSRID(geometry, integer) */
@@ -121,8 +118,6 @@
int32 size;
uchar type;
- init_pg_func();
-
lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
text_ob = lwalloc(20+VARHDRSZ);
result = text_ob+VARHDRSZ;
@@ -1077,8 +1072,6 @@
POSTGIS_DEBUG(2, "LWGEOM_asText called.");
- init_pg_func();
-
lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
/* Force to 2d */
@@ -1113,8 +1106,6 @@
PG_LWGEOM *ogclwgeom;
char *result;
- init_pg_func();
-
/* Force to 2d */
ogclwgeom = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
LWGEOM_force_2d, PG_GETARG_DATUM(0)));
Modified: trunk/lwgeom/lwgeom_pg.c
===================================================================
--- trunk/lwgeom/lwgeom_pg.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_pg.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -8,16 +8,13 @@
#include <executor/spi.h>
#include "liblwgeom.h"
#include "lwgeom_pg.h"
-#include "wktparse.h"
-
#define PARANOIA_LEVEL 1
/*
* This is required for builds against pgsql 8.2
*/
-/*#include "pgmagic.h"*/
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
@@ -100,8 +97,9 @@
}
void
-init_pg_func(void)
+lwgeom_init_allocators(void)
{
+ /* liblwgeom callback - install PostgreSQL handlers */
lwalloc_var = pg_alloc;
lwrealloc_var = pg_realloc;
lwfree_var = pg_free;
Modified: trunk/lwgeom/lwgeom_pg.h
===================================================================
--- trunk/lwgeom/lwgeom_pg.h 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_pg.h 2008-06-29 19:11:48 UTC (rev 2815)
@@ -67,9 +67,6 @@
extern Oid getGeometryOID(void);
-/* call this as first thing of any PG function */
-void init_pg_func(void);
-
/* PG-dependant */
/* BOX is postgresql standard type */
extern void box_to_box2df_p(BOX *box, BOX2DFLOAT4 *out);
Modified: trunk/lwgeom/lwgeom_sqlmm.c
===================================================================
--- trunk/lwgeom/lwgeom_sqlmm.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgeom_sqlmm.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -19,7 +19,7 @@
#include "postgres.h"
#include "liblwgeom.h"
#include "fmgr.h"
-#include "wktparse.h"
+
#include "lwgeom_pg.h"
Deleted: trunk/lwgeom/lwgparse.c
===================================================================
--- trunk/lwgeom/lwgparse.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwgparse.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,1153 +0,0 @@
-/*
- * Written by Ralph Mason ralph.mason<at>telogis.com
- *
- * Copyright Telogis 2004
- * www.telogis.com
- *
- */
-#include <string.h>
-#include <stdio.h>
-/* Solaris9 does not provide stdint.h */
-/* #include <stdint.h> */
-#include <inttypes.h>
-
-#include "liblwgeom.h"
-#include "wktparse.h"
-
-/*
- * To get byte order
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-*/
-
-void set_zm(char z, char m);
-void close_parser(void);
-
-typedef uint32_t int4;
-
-typedef struct tag_tuple tuple;
-
-struct tag_outputstate{
- uchar* pos;
-};
-
-typedef struct tag_outputstate output_state;
-typedef void (*output_func)(tuple* this, output_state* out);
-typedef void (*read_col_func)(const char **f);
-
-
-
-/* Globals */
-
-int srid=-1;
-
-static int ferror_occured;
-static allocator local_malloc;
-static report_error error_func;
-
-struct tag_tuple{
- output_func of;
- union union_tag {
- double points[4];
- int4 pointsi[4];
-
- struct struct_tag {
- tuple* stack_next;
- int type;
- int num;
- int size_here;
- } nn;
- } uu;
- struct tag_tuple *next;
-};
-
-struct {
- int type;
- int flags;
- int srid;
- int ndims;
- int hasZ;
- int hasM;
- /* create integer version */
- int lwgi;
- /* input is integer (wkb only)*/
- int from_lwgi;
-
- int4 alloc_size;
-
- /*
- linked list of all tuples
- */
- tuple* first;
- tuple* last;
-
- /*
- stack of open geometries
- */
- tuple* stack;
-
-} the_geom;
-
-tuple* free_list=0;
-int minpoints;
-int checkclosed;
-
-/*
- * This inicates if the number of points in the geometry is required to
- * be odd (one) or even (zero, currently not enforced) or whatever (-one)
- */
-int isodd;
-double *first_point=NULL;
-double *last_point=NULL;
-
-/* External functions */
-extern void init_parser(const char *);
-
-/* Prototypes */
-tuple* alloc_tuple(output_func of,size_t size);
-static void error(const char* err);
-void free_tuple(tuple* to_free);
-void inc_num(void);
-void alloc_stack_tuple(int type,output_func of,size_t size);
-void check_dims(int num);
-void WRITE_DOUBLES(output_state* out,double* points, int cnt);
-#ifdef SHRINK_INTS
-void WRITE_INT4(output_state * out,int4 val);
-#endif
-void empty_stack(tuple* this,output_state* out);
-void alloc_lwgeom(int srid);
-void write_point_2(tuple* this,output_state* out);
-void write_point_3(tuple* this,output_state* out);
-void write_point_4(tuple* this,output_state* out);
-void write_point_2i(tuple* this,output_state* out);
-void write_point_3i(tuple* this,output_state* out);
-void write_point_4i(tuple* this,output_state* out);
-void alloc_point_2d(double x,double y);
-void alloc_point_3d(double x,double y,double z);
-void alloc_point_4d(double x,double y,double z,double m);
-void write_type(tuple* this,output_state* out);
-void write_count(tuple* this,output_state* out);
-void write_type_count(tuple* this,output_state* out);
-void alloc_point(void);
-void alloc_linestring(void);
-void alloc_linestring_closed(void);
-void alloc_circularstring(void);
-void alloc_circularstring_closed(void);
-void alloc_polygon(void);
-void alloc_multipoint(void);
-void alloc_multilinestring(void);
-void alloc_multicurve(void);
-void alloc_multipolygon(void);
-void alloc_multisurface(void);
-void alloc_geomertycollection(void);
-void alloc_counter(void);
-void alloc_empty(void);
-SERIALIZED_LWGEOM* make_serialized_lwgeom(void);
-uchar strhex_readbyte(const char *in);
-uchar read_wkb_byte(const char **in);
-void read_wkb_bytes(const char **in, uchar* out, int cnt);
-int4 read_wkb_int(const char **in);
-double read_wkb_double(const char **in, int convert_from_int);
-void read_wkb_point(const char **b);
-void read_wkb_polygon(const char **b);
-void read_wkb_linestring(const char **b);
-void read_wkb_curve(const char **b);
-void read_wkb_ordinate_array(const char **b);
-void read_collection(const char **b, read_col_func f);
-void parse_wkb(const char **b);
-void alloc_wkb(const char *parser);
-SERIALIZED_LWGEOM* parse_it(const char* geometry, allocator allocfunc, report_error errfunc);
-SERIALIZED_LWGEOM* parse_lwg(const char* geometry, allocator allocfunc, report_error errfunc);
-SERIALIZED_LWGEOM* parse_lwgi(const char* geometry, allocator allocfunc, report_error errfunc);
-
-void
-set_srid(double d_srid)
-{
- if ( d_srid >= 0 )
- d_srid+=0.1;
- else
- d_srid-=0.1;
-
-
- srid=(int)(d_srid+0.1);
-}
-
-tuple *
-alloc_tuple(output_func of,size_t size)
-{
- tuple* ret = free_list;
-
- if ( ! ret ){
- int toalloc = (ALLOC_CHUNKS /sizeof(tuple));
- ret = malloc( toalloc *sizeof(tuple) );
-
- free_list = ret;
-
- while(--toalloc){
- ret->next = ret+1;
- ret++;
- }
-
- ret->next = NULL;
-
- return alloc_tuple(of,size);
- }
-
- free_list = ret->next;
- ret->of = of;
- ret->next = NULL;
-
- if ( the_geom.last ) {
- the_geom.last->next = ret;
- the_geom.last = ret;
- }
- else {
- the_geom.first = the_geom.last = ret;
- }
-
- the_geom.alloc_size += size;
- return ret;
-}
-
-static void
-error(const char* err)
-{
- error_func(err);
- ferror_occured=1;
-}
-
-void
-free_tuple(tuple* to_free)
-{
-
- tuple* list_end = to_free;
-
- if( !to_free)
- return;
-
- while(list_end->next){
- list_end=list_end->next;
- }
-
- list_end->next = free_list;
- free_list = to_free;
-}
-
-void
-inc_num(void)
-{
- the_geom.stack->uu.nn.num++;
-}
-
-/*
- Allocate a 'counting' tuple
-*/
-void
-alloc_stack_tuple(int type,output_func of,size_t size)
-{
- tuple* p;
- inc_num();
-
- LWDEBUGF(2, "alloc_stack_tuple %d, %d", type, size);
-
- p = alloc_tuple(of,size);
- p->uu.nn.stack_next = the_geom.stack;
- p->uu.nn.type = type;
- p->uu.nn.size_here = the_geom.alloc_size;
- p->uu.nn.num = 0;
- the_geom.stack = p;
-}
-
-void
-pop(void)
-{
- the_geom.stack = the_geom.stack->uu.nn.stack_next;
-}
-
-void
-popc(void)
-{
-
- if ( the_geom.stack->uu.nn.num < minpoints){
- error("geometry requires more points");
- }
- if(isodd != -1 && the_geom.stack->uu.nn.num % 2 != isodd) {
- error("geometry must have an odd number of points");
- }
- if ( checkclosed && first_point && last_point) {
- if ( memcmp(first_point, last_point,
- sizeof(double)*the_geom.ndims) )
- {
- error("geometry contains non-closed rings");
- }
- }
-
- the_geom.stack = the_geom.stack->uu.nn.stack_next;
-}
-
-
-void
-check_dims(int num)
-{
- LWDEBUGF(2, "check_dims the_geom.ndims = %d, num = %d", the_geom.ndims, num);
-
- if( the_geom.ndims != num){
- if (the_geom.ndims) {
- error("Can not mix dimensionality in a geometry");
- } else {
-
- LWDEBUGF(3, "check_dims: setting dim %d", num);
-
- the_geom.ndims = num;
- if ( num > 2 ) the_geom.hasZ = 1;
- if ( num > 3 ) the_geom.hasM = 1;
- }
- }
-}
-
-#define WRITE_INT4_REAL(x,y) { memcpy(x->pos,&y,4); x->pos+=4;}
-#define WRITE_INT4_REAL_MULTIPLE(x,y,z) { memcpy(x->pos,&y,z*4); x->pos+=(z*4);}
-
-/*
- we can shrink ints to one byte if they are less than 127
- by setting the extra bit. Because if the different byte
- ordering possibilities we need to set the lsb on little
- endian to show a packed one and the msb on a big endian
- machine
-*/
-#ifdef SHRINK_INTS
-void
-WRITE_INT4(output_state * out,int4 val)
-{
- if ( val <= 0x7f ){
- if ( getMachineEndian() == NDR ){
- val = (val<<1) | 1;
- }
- else{
- val |=0x80;
- }
-
- *out->pos++ = (uchar)val;
- the_geom.alloc_size-=3;
- }
- else{
- if ( getMachineEndian() == NDR ){
- val <<=1;
- }
- WRITE_INT4_REAL(out,val);
- }
-}
-#else
-#define WRITE_INT4 WRITE_INT4_REAL
-#endif
-
-
-void
-WRITE_DOUBLES(output_state* out,double* points, int cnt)
-{
- if ( the_geom.lwgi){
- int4 vals[4];
- int i;
-
- for(i=0; i<cnt;i++){
- vals[i] = (int4)(((points[i]+180.0)*0xB60B60)+.5);
- }
- memcpy(out->pos,vals,sizeof(int4)*cnt);
- out->pos+=sizeof(int4)*cnt;
- }
- else{
- memcpy(out->pos,points,sizeof(double)*cnt);
- out->pos+=sizeof(double)*cnt;
- }
-
-}
-
-void
-empty_stack(tuple *this,output_state* out)
-{
- /* Do nothing but provide an empty base for the geometry stack */
-}
-
-void
-alloc_lwgeom(int srid)
-{
- LWDEBUGF(2, "alloc_lwgeom %d", srid);
-
- the_geom.srid=srid;
- the_geom.alloc_size=0;
- the_geom.stack=NULL;
- the_geom.ndims=0;
- the_geom.hasZ=0;
- the_geom.hasM=0;
-
- /* Free if used already */
- if ( the_geom.first ){
- free_tuple(the_geom.first);
- the_geom.first=the_geom.last=NULL;
- }
-
- if ( srid != -1 ){
- the_geom.alloc_size+=4;
- }
-
- /* Setup up an empty tuple as the stack base */
- the_geom.stack = alloc_tuple(empty_stack, 0);
-}
-
-void
-write_point_2(tuple* this,output_state* out)
-{
- WRITE_DOUBLES(out,this->uu.points,2);
-}
-
-void
-write_point_3(tuple* this,output_state* out)
-{
- WRITE_DOUBLES(out,this->uu.points,3);
-}
-
-void
-write_point_4(tuple* this,output_state* out)
-{
- WRITE_DOUBLES(out,this->uu.points,4);
-}
-
-void
-write_point_2i(tuple* this,output_state* out)
-{
- WRITE_INT4_REAL_MULTIPLE(out,this->uu.points,2);
-}
-
-void
-write_point_3i(tuple* this,output_state* out)
-{
- WRITE_INT4_REAL_MULTIPLE(out,this->uu.points,3);
-}
-
-void
-write_point_4i(tuple* this,output_state* out)
-{
- WRITE_INT4_REAL_MULTIPLE(out,this->uu.points,4);
-}
-
-void
-alloc_point_2d(double x,double y)
-{
- tuple* p = alloc_tuple(write_point_2,the_geom.lwgi?8:16);
- p->uu.points[0] = x;
- p->uu.points[1] = y;
-
- LWDEBUGF(2, "alloc_point_2d %f,%f", x, y);
-
- /* keep track of point */
- if ( checkclosed ) {
- if ( ! the_geom.stack->uu.nn.num )
- first_point = p->uu.points;
- last_point = p->uu.points;
- }
-
- inc_num();
- check_dims(2);
-}
-
-void
-alloc_point_3d(double x,double y,double z)
-{
- tuple* p = alloc_tuple(write_point_3,the_geom.lwgi?12:24);
- p->uu.points[0] = x;
- p->uu.points[1] = y;
- p->uu.points[2] = z;
-
- LWDEBUGF(2, "alloc_point_3d %f, %f, %f", x, y, z);
-
- /* keep track of point */
- if ( checkclosed ) {
- if ( ! the_geom.stack->uu.nn.num )
- first_point = p->uu.points;
- last_point = p->uu.points;
- }
-
- inc_num();
- check_dims(3);
-}
-
-void
-alloc_point_4d(double x,double y,double z,double m)
-{
- tuple* p = alloc_tuple(write_point_4,the_geom.lwgi?16:32);
- p->uu.points[0] = x;
- p->uu.points[1] = y;
- p->uu.points[2] = z;
- p->uu.points[3] = m;
-
- LWDEBUGF(2, "alloc_point_4d %f, %f, %f, %f", x, y, z, m);
-
- /* keep track of point */
- if ( checkclosed ) {
- if ( ! the_geom.stack->uu.nn.num )
- first_point = p->uu.points;
- last_point = p->uu.points;
- }
-
- inc_num();
- check_dims(4);
-}
-
-void
-write_type(tuple* this,output_state* out)
-{
- uchar type=0;
-
- /* Empty handler - switch back */
- if ( this->uu.nn.type == 0xff )
- this->uu.nn.type = COLLECTIONTYPE;
-
- type |= this->uu.nn.type;
-
- if (the_geom.ndims) /* Support empty */
- {
- TYPE_SETZM(type, the_geom.hasZ, the_geom.hasM);
- }
-
- if ( the_geom.srid != -1 ){
- type |= 0x40;
- }
-
- *(out->pos)=type;
- out->pos++;
-
- if ( the_geom.srid != -1 ){
- /* Only the first geometry will have a srid attached */
- WRITE_INT4(out,the_geom.srid);
- the_geom.srid = -1;
- }
-}
-
-void
-write_count(tuple* this,output_state* out)
-{
- int num = this->uu.nn.num;
- WRITE_INT4(out,num);
-}
-
-void
-write_type_count(tuple* this,output_state* out)
-{
- write_type(this,out);
- write_count(this,out);
-}
-
-void
-alloc_point(void)
-{
- LWDEBUG(2, "alloc_point");
-
- if( the_geom.lwgi)
- alloc_stack_tuple(POINTTYPEI,write_type,1);
- else
- alloc_stack_tuple(POINTTYPE,write_type,1);
-
- minpoints=1;
- checkclosed=0;
- isodd=-1;
-}
-
-void
-alloc_linestring(void)
-{
- LWDEBUG(2, "alloc_linestring");
-
- if( the_geom.lwgi)
- alloc_stack_tuple(LINETYPEI,write_type,1);
- else
- alloc_stack_tuple(LINETYPE,write_type,1);
-
- minpoints=2;
- checkclosed=0;
- isodd=-1;
-}
-
-void alloc_linestring_closed(void)
-{
- LWDEBUG(2, "alloc_linestring_closed called.");
-
- alloc_linestring();
- checkclosed=1;
-}
-
-void
-alloc_circularstring(void)
-{
- LWDEBUG(2, "alloc_circularstring");
-
- alloc_stack_tuple(CURVETYPE,write_type,1);
- minpoints=3;
- checkclosed=0;
- isodd=1;
-}
-
-void alloc_circularstring_closed(void)
-{
- LWDEBUG(2, "alloc_circularstring_closed");
-
- alloc_circularstring();
- checkclosed=1;
-}
-
-void
-alloc_polygon(void)
-{
- LWDEBUG(2, "alloc_polygon");
-
- if( the_geom.lwgi)
- alloc_stack_tuple(POLYGONTYPEI, write_type,1);
- else
- alloc_stack_tuple(POLYGONTYPE, write_type,1);
-
- minpoints=3;
- checkclosed=1;
- isodd=-1;
-
-}
-
-void
-alloc_curvepolygon(void)
-{
- LWDEBUG(2, "alloc_curvepolygon called.");
-
- alloc_stack_tuple(CURVEPOLYTYPE, write_type, 1);
- minpoints=3;
- checkclosed=1;
- isodd=-1;
-}
-
-void
-alloc_compoundcurve(void)
-{
- LWDEBUG(2, "alloc_compoundcurve called.");
-
- alloc_stack_tuple(COMPOUNDTYPE, write_type, 1);
-}
-
-void
-alloc_multipoint(void)
-{
- LWDEBUG(2, "alloc_multipoint");
-
- alloc_stack_tuple(MULTIPOINTTYPE,write_type,1);
-}
-
-void
-alloc_multilinestring(void)
-{
- LWDEBUG(2, "alloc_multilinestring");
-
- alloc_stack_tuple(MULTILINETYPE,write_type,1);
-}
-
-void
-alloc_multicurve(void)
-{
- LWDEBUG(2, "alloc_multicurve");
-
- alloc_stack_tuple(MULTICURVETYPE,write_type,1);
-}
-
-void
-alloc_multipolygon(void)
-{
- LWDEBUG(2, "alloc_multipolygon");
-
- alloc_stack_tuple(MULTIPOLYGONTYPE,write_type,1);
-}
-
-void
-alloc_multisurface(void)
-{
- LWDEBUG(2, "alloc_multisurface called");
-
- alloc_stack_tuple(MULTISURFACETYPE,write_type,1);
-}
-
-void
-alloc_geomertycollection(void)
-{
- LWDEBUG(2, "alloc_geometrycollection");
-
- alloc_stack_tuple(COLLECTIONTYPE,write_type,1);
-}
-
-void
-alloc_counter(void)
-{
- LWDEBUG(2, "alloc_counter");
-
- alloc_stack_tuple(0,write_count,4);
-}
-
-void
-alloc_empty(void)
-{
- tuple* st = the_geom.stack;
-
- LWDEBUG(2, "alloc_empty");
-
- /* Find the last geometry */
- while(st->uu.nn.type == 0){
- st =st->uu.nn.stack_next;
- }
-
- /* Reclaim memory */
- free_tuple(st->next);
-
- /* Put an empty geometry collection on the top of the stack */
- st->next=NULL;
- the_geom.stack=st;
- the_geom.alloc_size=st->uu.nn.size_here;
-
- /* Mark as a empty stop */
- if (st->uu.nn.type != 0xFF){
- st->uu.nn.type=0xFF;
- st->of = write_type_count;
- the_geom.alloc_size+=4;
- st->uu.nn.size_here=the_geom.alloc_size;
- }
-
- st->uu.nn.num=0;
-}
-
-SERIALIZED_LWGEOM *
-make_serialized_lwgeom(void)
-{
- SERIALIZED_LWGEOM *out_serialized_lwgeom;
- uchar* out_c;
- output_state out;
- tuple* cur;
-
- LWDEBUG(2, "make_serialized_lwgeom");
-
- /* Allocate the SERIALIZED_LWGEOM structure */
- out_serialized_lwgeom = (SERIALIZED_LWGEOM *)local_malloc(sizeof(SERIALIZED_LWGEOM));
-
- /* Allocate the LWGEOM itself */
- out_c = (uchar*)local_malloc(the_geom.alloc_size);
- out.pos = out_c;
- cur = the_geom.first ;
-
- while(cur){
- cur->of(cur,&out);
- cur=cur->next;
- }
-
- /* Setup the SERIALIZED_LWGEOM structure */
- out_serialized_lwgeom->lwgeom = out_c;
- out_serialized_lwgeom->size = the_geom.alloc_size;
-
- return out_serialized_lwgeom;
-}
-
-void
-lwg_parse_yynotice(char* s)
-{
- lwnotice(s);
-}
-
-int
-lwg_parse_yyerror(char* s)
-{
- error("parse error - invalid geometry");
- /* error_func("parse error - invalid geometry"); */
- return 1;
-}
-
-/*
- Table below generated using this ruby.
-
- a=(0..0xff).to_a.collect{|x|0xff};('0'..'9').each{|x|a[x[0]]=x[0]-'0'[0]}
- ('a'..'f').each{|x|v=x[0]-'a'[0]+10;a[x[0]]=a[x.upcase[0]]=v}
- puts '{'+a.join(",")+'}'
-
- */
-static const uchar to_hex[] = {
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 0,1,2,3,4,5,6,7,8,9,255,255,255,255,255,255,255,10,11,12,13,14,
- 15,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,10,11,12,13,14,15,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255};
-
-uchar
-strhex_readbyte(const char* in)
-{
- if ( *in == 0 ){
- if ( ! ferror_occured){
- error("invalid wkb");
- }
- return 0;
- }
- return to_hex[(int)*in]<<4 | to_hex[(int)*(in+1)];
-}
-
-uchar
-read_wkb_byte(const char** in)
-{
- uchar ret = strhex_readbyte(*in);
- (*in)+=2;
- return ret;
-}
-
-int swap_order;
-
-void
-read_wkb_bytes(const char** in, uchar* out, int cnt)
-{
- if ( ! swap_order ){
- while(cnt--) *out++ = read_wkb_byte(in);
- }
- else{
- out += (cnt-1);
- while(cnt--) *out-- = read_wkb_byte(in);
- }
-}
-
-int4
-read_wkb_int(const char** in)
-{
- int4 ret=0;
- read_wkb_bytes(in,(uchar*)&ret,4);
- return ret;
-}
-
-double
-read_wkb_double(const char** in, int convert_from_int)
-{
- double ret=0;
-
- if ( ! convert_from_int){
- read_wkb_bytes(in,(uchar*)&ret,8);
- return ret;
- }else{
- ret = read_wkb_int(in);
- ret /= 0xb60b60;
- return ret-180.0;
- }
-}
-
-void
-read_wkb_point(const char **b)
-{
- int i;
- tuple* p = NULL;
-
-
- if(the_geom.lwgi && the_geom.from_lwgi ){
- /*
- * Special case - reading from lwgi to lwgi
- * we don't want to go via doubles in the middle.
- */
- switch(the_geom.ndims){
- case 2: p=alloc_tuple(write_point_2i,8); break;
- case 3: p=alloc_tuple(write_point_3i,12); break;
- case 4: p=alloc_tuple(write_point_4i,16); break;
- }
-
- for(i=0;i<the_geom.ndims;i++){
- p->uu.pointsi[i]=read_wkb_int(b);
- }
- }
- else{
- int mul = the_geom.lwgi ? 1 : 2;
-
- switch(the_geom.ndims){
- case 2: p=alloc_tuple(write_point_2,8*mul); break;
- case 3: p=alloc_tuple(write_point_3,12*mul); break;
- case 4: p=alloc_tuple(write_point_4,16*mul); break;
- }
-
- for(i=0;i<the_geom.ndims;i++){
- p->uu.points[i]=read_wkb_double(b,the_geom.from_lwgi);
- }
- }
-
-
- /* keep track of point */
- if ( checkclosed ) {
- if ( ! the_geom.stack->uu.nn.num )
- first_point = p->uu.points;
- last_point = p->uu.points;
- }
-
- inc_num();
- check_dims(the_geom.ndims);
-}
-
-void
-read_wkb_polygon(const char **b)
-{
- /* Stack the number of ORDINATE_ARRAYs (rings) */
- int4 cnt=read_wkb_int(b);
- alloc_counter();
-
- /* Read through each ORDINATE_ARRAY in turn */
- while(cnt--){
- if ( ferror_occured ) return;
-
- /* Things to check for POLYGON ORDINATE_ARRAYs */
- minpoints=3;
- checkclosed=1;
- isodd=-1;
-
- read_wkb_ordinate_array(b);
- }
-
- pop();
-}
-
-void
-read_wkb_linestring(const char **b)
-{
-
- /* Things to check for LINESTRING ORDINATE_ARRAYs */
- minpoints=2;
- checkclosed=0;
- isodd=-1;
-
- read_wkb_ordinate_array(b);
-}
-
-
-void
-read_wkb_curve(const char **b)
-{
-
- /* Things to check for CURVE ORDINATE_ARRAYs */
- minpoints=3;
- checkclosed=0;
- isodd=-1;
-
- read_wkb_ordinate_array(b);
-}
-
-void
-read_wkb_ordinate_array(const char **b)
-{
- /* Read through a WKB ordinate array */
- int4 cnt=read_wkb_int(b);
- alloc_counter();
-
- while(cnt--){
- if ( ferror_occured ) return;
- read_wkb_point(b);
- }
-
- /* Perform a check of the ordinate array */
- popc();
-}
-
-void
-read_collection(const char **b, read_col_func f)
-{
- /* Read through a COLLECTION or an EWKB */
- int4 cnt=read_wkb_int(b);
- alloc_counter();
-
- while(cnt--){
- if ( ferror_occured ) return;
- f(b);
- }
-
- pop();
-}
-
-void
-parse_wkb(const char **b)
-{
- int4 type;
- uchar xdr = read_wkb_byte(b);
- int4 localsrid;
-
- LWDEBUG(2, "parse_wkb");
-
- swap_order=0;
-
- if ( xdr != getMachineEndian() )
- {
- swap_order=1;
- }
-
- type = read_wkb_int(b);
-
- /* quick exit on error */
- if ( ferror_occured ) return;
-
- the_geom.ndims=2;
- if (type & WKBZOFFSET)
- {
- the_geom.hasZ = 1;
- the_geom.ndims++;
- }
- else the_geom.hasZ = 0;
- if (type & WKBMOFFSET)
- {
- the_geom.hasM = 1;
- the_geom.ndims++;
- }
- else the_geom.hasM = 0;
-
- if (type & WKBSRIDFLAG )
- {
- /* local (in-EWKB) srid spec overrides SRID=#; */
- localsrid = read_wkb_int(b);
- if ( localsrid != -1 )
- {
- if ( the_geom.srid == -1 ) the_geom.alloc_size += 4;
- the_geom.srid = localsrid;
- }
- }
-
- type &=0x0f;
-
- if ( the_geom.lwgi ){
-
- if ( type<= POLYGONTYPE )
- alloc_stack_tuple(type +9,write_type,1);
- else
- alloc_stack_tuple(type,write_type,1);
- }
- else{
- /* If we are writing lwg and are reading wbki */
- int4 towrite=type;
- if (towrite >= POINTTYPEI && towrite <= POLYGONTYPEI){
- towrite-=9;
- }
- alloc_stack_tuple(towrite,write_type,1);
- }
-
- switch(type ){
- case POINTTYPE:
- read_wkb_point(b);
- break;
-
- case LINETYPE:
- read_wkb_linestring(b);
- break;
-
- case CURVETYPE:
- read_wkb_curve(b);
- break;
-
- case POLYGONTYPE:
- read_wkb_polygon(b);
- break;
-
- case COMPOUNDTYPE:
- read_collection(b,parse_wkb);
- break;
-
- case CURVEPOLYTYPE:
- read_collection(b,parse_wkb);
- break;
-
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTICURVETYPE:
- case MULTIPOLYGONTYPE:
- case MULTISURFACETYPE:
- case COLLECTIONTYPE:
- read_collection(b,parse_wkb);
- break;
-
- case POINTTYPEI:
- the_geom.from_lwgi=1;
- read_wkb_point(b);
- break;
-
- case LINETYPEI:
- the_geom.from_lwgi=1;
- read_wkb_linestring(b);
- break;
-
- case POLYGONTYPEI:
- the_geom.from_lwgi=1;
- read_wkb_polygon(b);
- break;
-
- default:
- error("Invalid type in wbk");
- }
-
- the_geom.from_lwgi=0;
-
- pop();
-}
-
-
-void
-alloc_wkb(const char *parser)
-{
- LWDEBUG(2, "alloc_wkb");
-
- parse_wkb(&parser);
-}
-
-/*
- Parse a string and return a LW_GEOM
-*/
-SERIALIZED_LWGEOM *
-parse_it(const char *geometry, allocator allocfunc, report_error errfunc)
-{
- LWDEBUGF(2, "parse_it: %s", geometry);
-
- local_malloc = allocfunc;
- error_func=errfunc;
-
- ferror_occured = 0;
-
- init_parser(geometry);
-
- lwg_parse_yyparse();
-
- close_parser();
-
- if (ferror_occured)
- return NULL;
-
- return make_serialized_lwgeom();
-}
-
-SERIALIZED_LWGEOM *
-parse_lwg(const char* geometry,allocator allocfunc,report_error errfunc)
-{
- the_geom.lwgi=0;
- return parse_it(geometry,allocfunc,errfunc);
-}
-
-SERIALIZED_LWGEOM *
-parse_lwgi(const char* geometry,allocator allocfunc,report_error errfunc)
-{
- the_geom.lwgi=1;
- return parse_it(geometry,allocfunc,errfunc);
-}
-
-void
-set_zm(char z, char m)
-{
- LWDEBUGF(2, "set_zm %d, %d", z, m);
-
- the_geom.hasZ = z;
- the_geom.hasM = m;
- the_geom.ndims = 2+z+m;
-}
-
Deleted: trunk/lwgeom/lwline.c
===================================================================
--- trunk/lwgeom/lwline.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwline.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,516 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-/* basic LWLINE functions */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-
-
-/*
- * Construct a new LWLINE. points will *NOT* be copied
- * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
- */
-LWLINE *
-lwline_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points)
-{
- LWLINE *result;
- result = (LWLINE*) lwalloc(sizeof(LWLINE));
-
- LWDEBUG(2, "lwline_construct called.");
-
- result->type = lwgeom_makeType_full(
- TYPE_HASZ(points->dims),
- TYPE_HASM(points->dims),
- (SRID!=-1), LINETYPE,
- 0);
-
- LWDEBUGF(3, "lwline_construct type=%d", result->type);
-
- result->SRID = SRID;
- result->points = points;
- result->bbox = bbox;
-
- return result;
-}
-
-/*
- * given the LWGEOM serialized form (or a pointer into a muli* one)
- * construct a proper LWLINE.
- * serialized_form should point to the 8bit type format (with type = 2)
- * See serialized form doc
- */
-LWLINE *
-lwline_deserialize(uchar *serialized_form)
-{
- uchar type;
- LWLINE *result;
- uchar *loc =NULL;
- uint32 npoints;
- POINTARRAY *pa;
-
- type = (uchar) serialized_form[0];
-
- if ( lwgeom_getType(type) != LINETYPE)
- {
- lwerror("lwline_deserialize: attempt to deserialize a line which is really a %s", lwgeom_typename(type));
- return NULL;
- }
-
- result = (LWLINE*) lwalloc(sizeof(LWLINE)) ;
- result->type = type;
-
- loc = serialized_form+1;
-
- if (lwgeom_hasBBOX(type))
- {
- LWDEBUG(3, "lwline_deserialize: input has bbox");
-
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
- loc += sizeof(BOX2DFLOAT4);
- }
- else
- {
- result->bbox = NULL;
- /*lwnotice("line has NO bbox"); */
- }
-
- if ( lwgeom_hasSRID(type))
- {
- /*lwnotice("line has srid"); */
- result->SRID = lw_get_int32(loc);
- loc +=4; /* type + SRID */
- }
- else
- {
- /*lwnotice("line has NO srid"); */
- result->SRID = -1;
- }
-
- /* we've read the type (1 byte) and SRID (4 bytes, if present) */
-
- npoints = lw_get_uint32(loc);
- /*lwnotice("line npoints = %d", npoints); */
- loc +=4;
- pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints);
- result->points = pa;
-
- return result;
-}
-
-/*
- * convert this line into its serialize form
- * result's first char will be the 8bit type. See serialized form doc
- */
-uchar *
-lwline_serialize(LWLINE *line)
-{
- size_t size, retsize;
- uchar * result;
-
- if (line == NULL) lwerror("lwline_serialize:: given null line");
-
- size = lwline_serialize_size(line);
- result = lwalloc(size);
- lwline_serialize_buf(line, result, &retsize);
-
- if ( retsize != size )
- {
- lwerror("lwline_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
- }
-
- return result;
-}
-
-/*
- * convert this line into its serialize form writing it into
- * the given buffer, and returning number of bytes written into
- * the given int pointer.
- * result's first char will be the 8bit type. See serialized form doc
- */
-void
-lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *retsize)
-{
- char hasSRID;
- uchar *loc;
- int ptsize;
- size_t size;
-
- LWDEBUGF(2, "lwline_serialize_buf(%p, %p, %p) called",
- line, buf, retsize);
-
- if (line == NULL)
- lwerror("lwline_serialize:: given null line");
-
- if ( TYPE_GETZM(line->type) != TYPE_GETZM(line->points->dims) )
- lwerror("Dimensions mismatch in lwline");
-
- ptsize = pointArray_ptsize(line->points);
-
- hasSRID = (line->SRID != -1);
-
- buf[0] = (uchar) lwgeom_makeType_full(
- TYPE_HASZ(line->type), TYPE_HASM(line->type),
- hasSRID, LINETYPE, line->bbox ? 1 : 0);
- loc = buf+1;
-
- LWDEBUGF(3, "lwline_serialize_buf added type (%d)", line->type);
-
- if (line->bbox)
- {
- memcpy(loc, line->bbox, sizeof(BOX2DFLOAT4));
- loc += sizeof(BOX2DFLOAT4);
-
- LWDEBUG(3, "lwline_serialize_buf added BBOX");
- }
-
- if (hasSRID)
- {
- memcpy(loc, &line->SRID, sizeof(int32));
- loc += sizeof(int32);
-
- LWDEBUG(3, "lwline_serialize_buf added SRID");
- }
-
- memcpy(loc, &line->points->npoints, sizeof(uint32));
- loc += sizeof(uint32);
-
- LWDEBUGF(3, "lwline_serialize_buf added npoints (%d)",
- line->points->npoints);
-
- /*copy in points */
- size = line->points->npoints*ptsize;
- memcpy(loc, getPoint_internal(line->points, 0), size);
- loc += size;
-
- LWDEBUGF(3, "lwline_serialize_buf copied serialized_pointlist (%d bytes)",
- ptsize * line->points->npoints);
-
- if (retsize) *retsize = loc-buf;
-
- /*printBYTES((uchar *)result, loc-buf); */
-
- LWDEBUGF(3, "lwline_serialize_buf returning (loc: %p, size: %d)",
- loc, loc-buf);
-}
-
-/*
- * Find bounding box (standard one)
- * zmin=zmax=NO_Z_VALUE if 2d
- */
-BOX3D *
-lwline_compute_box3d(LWLINE *line)
-{
- BOX3D *ret;
-
- if (line == NULL) return NULL;
-
- ret = ptarray_compute_box3d(line->points);
- return ret;
-}
-
-/* find length of this deserialized line */
-size_t
-lwline_serialize_size(LWLINE *line)
-{
- size_t size = 1; /* type */
-
- LWDEBUG(2, "lwline_serialize_size called");
-
- if ( line->SRID != -1 ) size += 4; /* SRID */
- if ( line->bbox ) size += sizeof(BOX2DFLOAT4);
-
- size += 4; /* npoints */
- size += pointArray_ptsize(line->points)*line->points->npoints;
-
- LWDEBUGF(3, "lwline_serialize_size returning %d", size);
-
- return size;
-}
-
-void pfree_line (LWLINE *line)
-{
- lwfree(line->points);
- lwfree(line);
-}
-
-/* find length of this serialized line */
-size_t
-lwgeom_size_line(const uchar *serialized_line)
-{
- int type = (uchar) serialized_line[0];
- uint32 result = 1; /*type */
- const uchar *loc;
- uint32 npoints;
-
- LWDEBUG(2, "lwgeom_size_line called");
-
- if ( lwgeom_getType(type) != LINETYPE)
- lwerror("lwgeom_size_line::attempt to find the length of a non-line");
-
-
- loc = serialized_line+1;
-
- if (lwgeom_hasBBOX(type))
- {
- loc += sizeof(BOX2DFLOAT4);
- result +=sizeof(BOX2DFLOAT4);
- }
-
- if ( lwgeom_hasSRID(type))
- {
- loc += 4; /* type + SRID */
- result +=4;
- }
-
- /* we've read the type (1 byte) and SRID (4 bytes, if present) */
- npoints = lw_get_uint32(loc);
- result += sizeof(uint32); /* npoints */
-
- result += TYPE_NDIMS(type) * sizeof(double) * npoints;
-
- LWDEBUGF(3, "lwgeom_size_line returning %d", result);
-
- return result;
-}
-
-void printLWLINE(LWLINE *line)
-{
- lwnotice("LWLINE {");
- lwnotice(" ndims = %i", (int)TYPE_NDIMS(line->type));
- lwnotice(" SRID = %i", (int)line->SRID);
- printPA(line->points);
- lwnotice("}");
-}
-
-int
-lwline_compute_box2d_p(LWLINE *line, BOX2DFLOAT4 *box)
-{
- return ptarray_compute_box2d_p(line->points, box);
-}
-
-/* Clone LWLINE object. POINTARRAY is not copied. */
-LWLINE *
-lwline_clone(const LWLINE *g)
-{
- LWLINE *ret = lwalloc(sizeof(LWLINE));
-
- LWDEBUGF(2, "lwline_clone called with %p", g);
-
- memcpy(ret, g, sizeof(LWLINE));
- if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
- return ret;
-}
-
-/*
- * Add 'what' to this line at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTILINE or a GEOMETRYCOLLECTION
- */
-LWGEOM *
-lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
-
- if ( where != -1 && where != 0 )
- {
- lwerror("lwline_add only supports 0 or -1 as second argument, got %d", where);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*2);
- if ( where == -1 ) /* append */
- {
- geoms[0] = lwgeom_clone((LWGEOM *)to);
- geoms[1] = lwgeom_clone(what);
- }
- else /* prepend */
- {
- geoms[0] = lwgeom_clone(what);
- geoms[1] = lwgeom_clone((LWGEOM *)to);
- }
-
- /* reset SRID and wantbbox flag from component types */
- geoms[0]->SRID = geoms[1]->SRID = -1;
- TYPE_SETHASSRID(geoms[0]->type, 0);
- TYPE_SETHASSRID(geoms[1]->type, 0);
- TYPE_SETHASBBOX(geoms[0]->type, 0);
- TYPE_SETHASBBOX(geoms[1]->type, 0);
-
- /* Find appropriate geom type */
- if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- 2, geoms);
-
- return (LWGEOM *)col;
-}
-
-void
-lwline_reverse(LWLINE *line)
-{
- ptarray_reverse(line->points);
-}
-
-LWLINE *
-lwline_segmentize2d(LWLINE *line, double dist)
-{
- return lwline_construct(line->SRID, NULL,
- ptarray_segmentize2d(line->points, dist));
-}
-
-/* check coordinate equality */
-char
-lwline_same(const LWLINE *l1, const LWLINE *l2)
-{
- return ptarray_same(l1->points, l2->points);
-}
-
-/*
- * Construct a LWLINE from an array of LWPOINTs
- * LWLINE dimensions are large enough to host all input dimensions.
- */
-LWLINE *
-lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points)
-{
- int zmflag=0;
- unsigned int i;
- POINTARRAY *pa;
- uchar *newpoints, *ptr;
- size_t ptsize, size;
-
- /*
- * Find output dimensions, check integrity
- */
- for (i=0; i<npoints; i++)
- {
- if ( TYPE_GETTYPE(points[i]->type) != POINTTYPE )
- {
- lwerror("lwline_from_lwpointarray: invalid input type: %s",
- lwgeom_typename(TYPE_GETTYPE(points[i]->type)));
- return NULL;
- }
- if ( TYPE_HASZ(points[i]->type) ) zmflag |= 2;
- if ( TYPE_HASM(points[i]->type) ) zmflag |= 1;
- if ( zmflag == 3 ) break;
- }
-
- if ( zmflag == 0 ) ptsize=2*sizeof(double);
- else if ( zmflag == 3 ) ptsize=4*sizeof(double);
- else ptsize=3*sizeof(double);
-
- /*
- * Allocate output points array
- */
- size = ptsize*npoints;
- newpoints = lwalloc(size);
- memset(newpoints, 0, size);
-
- ptr=newpoints;
- for (i=0; i<npoints; i++)
- {
- size=pointArray_ptsize(points[i]->point);
- memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
- ptr+=ptsize;
- }
-
- pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints);
-
- return lwline_construct(SRID, NULL, pa);
-}
-
-/*
- * Construct a LWLINE from a LWMPOINT
- */
-LWLINE *
-lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint)
-{
- unsigned int i;
- POINTARRAY *pa;
- char zmflag = TYPE_GETZM(mpoint->type);
- size_t ptsize, size;
- uchar *newpoints, *ptr;
-
- if ( zmflag == 0 ) ptsize=2*sizeof(double);
- else if ( zmflag == 3 ) ptsize=4*sizeof(double);
- else ptsize=3*sizeof(double);
-
- /* Allocate space for output points */
- size = ptsize*mpoint->ngeoms;
- newpoints = lwalloc(size);
- memset(newpoints, 0, size);
-
- ptr=newpoints;
- for (i=0; i<mpoint->ngeoms; i++)
- {
- memcpy(ptr,
- getPoint_internal(mpoint->geoms[i]->point, 0),
- ptsize);
- ptr+=ptsize;
- }
-
- pa = pointArray_construct(newpoints, zmflag&2, zmflag&1,
- mpoint->ngeoms);
-
- LWDEBUGF(3, "lwline_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);
-
- return lwline_construct(SRID, NULL, pa);
-}
-
-LWLINE *
-lwline_addpoint(LWLINE *line, LWPOINT *point, unsigned int where)
-{
- POINTARRAY *newpa;
- LWLINE *ret;
-
- newpa = ptarray_addPoint(line->points,
- getPoint_internal(point->point, 0),
- TYPE_NDIMS(point->type), where);
-
- ret = lwline_construct(line->SRID, NULL, newpa);
-
- return ret;
-}
-
-LWLINE *
-lwline_removepoint(LWLINE *line, unsigned int index)
-{
- POINTARRAY *newpa;
- LWLINE *ret;
-
- newpa = ptarray_removePoint(line->points, index);
-
- ret = lwline_construct(line->SRID, NULL, newpa);
-
- return ret;
-}
-
-/*
- * Note: input will be changed, make sure you have permissions for this.
- */
-void
-lwline_setPoint4d(LWLINE *line, unsigned int index, POINT4D *newpoint)
-{
- setPoint4d(line->points, index, newpoint);
-}
Deleted: trunk/lwgeom/lwmcurve.c
===================================================================
--- trunk/lwgeom/lwmcurve.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwmcurve.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,125 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-LWMCURVE *
-lwmcurve_deserialize(uchar *srl)
-{
- LWMCURVE *result;
- LWGEOM_INSPECTED *insp;
- int stype;
- int type = lwgeom_getType(srl[0]);
- int i;
-
- if(type != MULTICURVETYPE)
- {
- lwerror("lwmcurve_deserialize called on NON multicurve: %d", type);
- return NULL;
- }
-
- insp = lwgeom_inspect(srl);
-
- result = lwalloc(sizeof(LWMCURVE));
- result->type = insp->type;
- result->SRID = insp->SRID;
- result->ngeoms = insp->ngeometries;
- result->geoms = lwalloc(sizeof(LWCURVE *)*insp->ngeometries);
-
- if(lwgeom_hasBBOX(srl[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
- for(i = 0; i < insp->ngeometries; i++)
- {
- stype = lwgeom_getType(insp->sub_geoms[i][0]);
- if(stype == CURVETYPE)
- {
- result->geoms[i] = (LWGEOM *)lwcurve_deserialize(insp->sub_geoms[i]);
- }
- else if(stype == LINETYPE)
- {
- result->geoms[i] = (LWGEOM *)lwline_deserialize(insp->sub_geoms[i]);
- }
- else
- {
- lwerror("Only Circular and Line strings are currenly permitted in a MultiCurve.");
- free(result);
- free(insp);
- return NULL;
- }
-
- if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
- {
- lwerror("Mixed diminsions (multicurve: %d, curve %d:%d)",
- TYPE_NDIMS(result->type), i,
- TYPE_NDIMS(result->geoms[i]->type));
- free(result);
- free(insp);
- return NULL;
- }
- }
- return result;
-}
-
-/*
- * Add 'what' to this multicurve at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTICURVE or a COLLECTION
- */
-LWGEOM *
-lwmcurve_add(const LWMCURVE *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
- uint32 i;
-
- if(where == -1) where = to->ngeoms;
- else if(where < -1 || where > to->ngeoms)
- {
- lwerror("lwmcurve_add: add position out of range %d..%d",
- -1, to->ngeoms);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
- for(i = 0; i < where; i++)
- {
- geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
- geoms[where] = lwgeom_clone(what);
- for(i = where; i < to->ngeoms; i++)
- {
- geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
-
- if(TYPE_GETTYPE(what->type) == CURVETYPE) newtype = MULTICURVETYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- to->ngeoms + 1, geoms);
-
- return (LWGEOM *)col;
-}
-
Deleted: trunk/lwgeom/lwmline.c
===================================================================
--- trunk/lwgeom/lwmline.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwmline.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,110 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-LWMLINE *
-lwmline_deserialize(uchar *srl)
-{
- LWMLINE *result;
- LWGEOM_INSPECTED *insp;
- int type = lwgeom_getType(srl[0]);
- int i;
-
- if ( type != MULTILINETYPE )
- {
- lwerror("lwmline_deserialize called on NON multiline: %d",
- type);
- return NULL;
- }
-
- insp = lwgeom_inspect(srl);
-
- result = lwalloc(sizeof(LWMLINE));
- result->type = insp->type;
- result->SRID = insp->SRID;
- result->ngeoms = insp->ngeometries;
- result->geoms = lwalloc(sizeof(LWLINE *)*insp->ngeometries);
-
- if (lwgeom_hasBBOX(srl[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
-
- for (i=0; i<insp->ngeometries; i++)
- {
- result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]);
- if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
- {
- lwerror("Mixed dimensions (multiline:%d, line%d:%d)",
- TYPE_NDIMS(result->type), i,
- TYPE_NDIMS(result->geoms[i]->type)
- );
- return NULL;
- }
- }
-
- return result;
-}
-
-/*
- * Add 'what' to this multiline at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTILINE or a COLLECTION
- */
-LWGEOM *
-lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
- uint32 i;
-
- if ( where == -1 ) where = to->ngeoms;
- else if ( where < -1 || where > to->ngeoms )
- {
- lwerror("lwmline_add: add position out of range %d..%d",
- -1, to->ngeoms);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
- for (i=0; i<where; i++)
- {
- geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
- geoms[where] = lwgeom_clone(what);
- for (i=where; i<to->ngeoms; i++)
- {
- geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
-
- if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- to->ngeoms+1, geoms);
-
- return (LWGEOM *)col;
-
-}
Deleted: trunk/lwgeom/lwmpoint.c
===================================================================
--- trunk/lwgeom/lwmpoint.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwmpoint.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,109 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-LWMPOINT *
-lwmpoint_deserialize(uchar *srl)
-{
- LWMPOINT *result;
- LWGEOM_INSPECTED *insp;
- int type = lwgeom_getType(srl[0]);
- int i;
-
- if ( type != MULTIPOINTTYPE )
- {
- lwerror("lwmpoint_deserialize called on NON multipoint: %d",
- type);
- return NULL;
- }
-
- insp = lwgeom_inspect(srl);
-
- result = lwalloc(sizeof(LWMPOINT));
- result->type = insp->type;
- result->SRID = insp->SRID;
- result->ngeoms = insp->ngeometries;
- result->geoms = lwalloc(sizeof(LWPOINT *)*result->ngeoms);
-
- if (lwgeom_hasBBOX(srl[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
- for (i=0; i<insp->ngeometries; i++)
- {
- result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]);
- if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
- {
- lwerror("Mixed dimensions (multipoint:%d, point%d:%d)",
- TYPE_NDIMS(result->type), i,
- TYPE_NDIMS(result->geoms[i]->type)
- );
- return NULL;
- }
- }
-
- return result;
-}
-
-/*
- * Add 'what' to this multipoint at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTIPOINT or a COLLECTION
- */
-LWGEOM *
-lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
- uint32 i;
-
- if ( where == -1 ) where = to->ngeoms;
- else if ( where < -1 || where > to->ngeoms )
- {
- lwerror("lwmpoint_add: add position out of range %d..%d",
- -1, to->ngeoms);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
- for (i=0; i<where; i++)
- {
- geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
- geoms[where] = lwgeom_clone(what);
- for (i=where; i<to->ngeoms; i++)
- {
- geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
-
- if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- to->ngeoms+1, geoms);
-
- return (LWGEOM *)col;
-
-}
Deleted: trunk/lwgeom/lwmpoly.c
===================================================================
--- trunk/lwgeom/lwmpoly.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwmpoly.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,112 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-
-LWMPOLY *
-lwmpoly_deserialize(uchar *srl)
-{
- LWMPOLY *result;
- LWGEOM_INSPECTED *insp;
- int type = lwgeom_getType(srl[0]);
- int i;
-
- LWDEBUG(2, "lwmpoly_deserialize called");
-
- if ( type != MULTIPOLYGONTYPE )
- {
- lwerror("lwmpoly_deserialize called on NON multipoly: %d",
- type);
- return NULL;
- }
-
- insp = lwgeom_inspect(srl);
-
- result = lwalloc(sizeof(LWMPOLY));
- result->type = insp->type;
- result->SRID = insp->SRID;
- result->ngeoms = insp->ngeometries;
- result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
-
- if (lwgeom_hasBBOX(srl[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, srl+1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
- for (i=0; i<insp->ngeometries; i++)
- {
- result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]);
- if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) )
- {
- lwerror("Mixed dimensions (multipoly:%d, poly%d:%d)",
- TYPE_NDIMS(result->type), i,
- TYPE_NDIMS(result->geoms[i]->type)
- );
- return NULL;
- }
- }
-
- return result;
-}
-
-/*
- * Add 'what' to this multiline at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTIPOLY or a COLLECTION
- */
-LWGEOM *
-lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
- uint32 i;
-
- if ( where == -1 ) where = to->ngeoms;
- else if ( where < -1 || where > to->ngeoms )
- {
- lwerror("lwmline_add: add position out of range %d..%d",
- -1, to->ngeoms);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
- for (i=0; i<where; i++)
- {
- geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
- geoms[where] = lwgeom_clone(what);
- for (i=where; i<to->ngeoms; i++)
- {
- geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
-
- if ( TYPE_GETTYPE(what->type) == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- to->ngeoms+1, geoms);
-
- return (LWGEOM *)col;
-
-}
Deleted: trunk/lwgeom/lwmsurface.c
===================================================================
--- trunk/lwgeom/lwmsurface.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwmsurface.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,129 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-
-LWMSURFACE *
-lwmsurface_deserialize(uchar *srl)
-{
- LWMSURFACE *result;
- LWGEOM_INSPECTED *insp;
- int stype;
- int type = lwgeom_getType(srl[0]);
- int i;
-
- LWDEBUG(2, "lwmsurface_deserialize called");
-
- if(type != MULTISURFACETYPE)
- {
- lwerror("lwmsurface_deserialize called on a non-multisurface: %d", type);
- return NULL;
- }
-
- insp = lwgeom_inspect(srl);
-
- result = lwalloc(sizeof(LWMSURFACE));
- result->type = insp->type;
- result->SRID = insp->SRID;
- result->ngeoms = insp->ngeometries;
- result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
-
- if(lwgeom_hasBBOX(srl[0]))
- {
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, srl + 1, sizeof(BOX2DFLOAT4));
- }
- else result->bbox = NULL;
-
- for(i = 0; i < insp->ngeometries; i++)
- {
- stype = lwgeom_getType(insp->sub_geoms[i][0]);
- if(stype == POLYGONTYPE)
- {
- result->geoms[i] = (LWGEOM *)lwpoly_deserialize(insp->sub_geoms[i]);
- }
- else if(stype == CURVEPOLYTYPE)
- {
- result->geoms[i] = (LWGEOM *)lwcurvepoly_deserialize(insp->sub_geoms[i]);
- }
- else
- {
- lwerror("Only Polygons and Curved Polygons are supported in a MultiSurface.");
- lwfree(result);
- lwfree(insp);
- return NULL;
- }
-
- if(TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type))
- {
- lwerror("Mixed dimensions (multisurface: %d, surface %d:%d",
- TYPE_NDIMS(result->type), i,
- TYPE_NDIMS(result->geoms[i]->type));
- lwfree(result);
- lwfree(insp);
- return NULL;
- }
- }
- return result;
-}
-
-/*
- * Add 'what' to this multisurface at position 'where'
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTISURFACE or a COLLECTION
- */
-LWGEOM *
-lwmsurface_add(const LWMSURFACE *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
- uint32 i;
-
- if(where == -1) where = to->ngeoms;
- else if(where < -1 || where > to->ngeoms)
- {
- lwerror("lwmsurface_add: add position out of range %d..%d",
- -1, to->ngeoms);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*(to->ngeoms+1));
- for(i = 0; i < where; i++)
- {
- geoms[i] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
- geoms[where] = lwgeom_clone(what);
- for(i = where; i < to->ngeoms; i++)
- {
- geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]);
- }
-
- if(TYPE_GETTYPE(what->type) == POLYGONTYPE
- || TYPE_GETTYPE(what->type) == CURVEPOLYTYPE)
- newtype = MULTISURFACETYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL, to->ngeoms + 1, geoms);
-
- return (LWGEOM *)col;
-}
-
Deleted: trunk/lwgeom/lwpoint.c
===================================================================
--- trunk/lwgeom/lwpoint.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwpoint.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,431 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-
-/*
- * Convert this point into its serialize form
- * result's first char will be the 8bit type. See serialized form doc
- */
-uchar *
-lwpoint_serialize(LWPOINT *point)
-{
- size_t size, retsize;
- uchar *result;
-
- size = lwpoint_serialize_size(point);
- result = lwalloc(size);
- lwpoint_serialize_buf(point, result, &retsize);
-
- if ( retsize != size )
- {
- lwerror("lwpoint_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
- }
-
- return result;
-}
-
-/*
- * Convert this point into its serialize form writing it into
- * the given buffer, and returning number of bytes written into
- * the given int pointer.
- * result's first char will be the 8bit type. See serialized form doc
- */
-void
-lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *retsize)
-{
- int size=1;
- char hasSRID;
- uchar *loc;
- int ptsize = pointArray_ptsize(point->point);
-
- if ( TYPE_GETZM(point->type) != TYPE_GETZM(point->point->dims) )
- lwerror("Dimensions mismatch in lwpoint");
-
- LWDEBUGF(2, "lwpoint_serialize_buf(%p, %p) called", point, buf);
- /*printLWPOINT(point); */
-
- hasSRID = (point->SRID != -1);
-
- if (hasSRID) size +=4; /*4 byte SRID */
- if (point->bbox) size += sizeof(BOX2DFLOAT4); /* bvol */
-
- size += sizeof(double)*TYPE_NDIMS(point->type);
-
- buf[0] = (uchar) lwgeom_makeType_full(
- TYPE_HASZ(point->type), TYPE_HASM(point->type),
- hasSRID, POINTTYPE, point->bbox?1:0);
- loc = buf+1;
-
- if (point->bbox)
- {
- memcpy(loc, point->bbox, sizeof(BOX2DFLOAT4));
- loc += sizeof(BOX2DFLOAT4);
- }
-
- if (hasSRID)
- {
- memcpy(loc, &point->SRID, sizeof(int32));
- loc += 4;
- }
-
- /* copy in points */
- memcpy(loc, getPoint_internal(point->point, 0), ptsize);
-
- if (retsize) *retsize = size;
-}
-
-/*
- * Find bounding box (standard one)
- * zmin=zmax=NO_Z_VALUE if 2d
- */
-BOX3D *
-lwpoint_compute_box3d(LWPOINT *point)
-{
- LWDEBUGF(2, "lwpoint_compute_box3d called with point %p", point);
-
- if (point == NULL)
- {
- LWDEBUG(3, "lwpoint_compute_box3d returning NULL");
-
- return NULL;
- }
-
- LWDEBUG(3, "lwpoint_compute_box3d returning ptarray_compute_box3d return");
-
- return ptarray_compute_box3d(point->point);
-}
-
-/*
- * Convenience functions to hide the POINTARRAY
- * TODO: obsolete this
- */
-int
-lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out)
-{
- return getPoint2d_p(point->point, 0, out);
-}
-
-/* convenience functions to hide the POINTARRAY */
-int
-lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out)
-{
- return getPoint3dz_p(point->point,0,out);
-}
-int
-lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out)
-{
- return getPoint3dm_p(point->point,0,out);
-}
-int
-lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
-{
- return getPoint4d_p(point->point,0,out);
-}
-
-/* find length of this deserialized point */
-size_t
-lwpoint_serialize_size(LWPOINT *point)
-{
- size_t size = 1; /* type */
-
- LWDEBUG(2, "lwpoint_serialize_size called");
-
- if ( point->SRID != -1 ) size += 4; /* SRID */
- if ( point->bbox ) size += sizeof(BOX2DFLOAT4);
-
- size += TYPE_NDIMS(point->type) * sizeof(double); /* point */
-
- LWDEBUGF(3, "lwpoint_serialize_size returning %d", size);
-
- return size;
-}
-
-/*
- * Construct a new point. point will not be copied
- * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
- */
-LWPOINT *
-lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point)
-{
- LWPOINT *result ;
-
- if (point == NULL)
- return NULL; /* error */
-
- result = lwalloc(sizeof(LWPOINT));
- result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), POINTTYPE, 0);
- result->SRID = SRID;
- result->point = point;
- result->bbox = bbox;
-
- return result;
-}
-
-LWPOINT *
-make_lwpoint2d(int SRID, double x, double y)
-{
- POINT2D p;
- POINTARRAY *pa = ptarray_construct(0, 0, 1);
-
- p.x = x;
- p.y = y;
-
- memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT2D));
-
- return lwpoint_construct(SRID, NULL, pa);
-}
-
-LWPOINT *
-make_lwpoint3dz(int SRID, double x, double y, double z)
-{
- POINT3DZ p;
- POINTARRAY *pa = ptarray_construct(1, 0, 1);
-
- p.x = x;
- p.y = y;
- p.z = z;
-
- memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DZ));
-
- return lwpoint_construct(SRID, NULL, pa);
-}
-
-LWPOINT *
-make_lwpoint3dm(int SRID, double x, double y, double m)
-{
- POINTARRAY *pa = ptarray_construct(0, 1, 1);
- POINT3DM p;
-
- p.x = x;
- p.y = y;
- p.m = m;
-
- memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT3DM));
-
- return lwpoint_construct(SRID, NULL, pa);
-}
-
-LWPOINT *
-make_lwpoint4d(int SRID, double x, double y, double z, double m)
-{
- POINTARRAY *pa = ptarray_construct(1, 1, 1);
- POINT4D p;
-
- p.x = x;
- p.y = y;
- p.z = z;
- p.m = m;
-
- memcpy(getPoint_internal(pa, 0), &p, sizeof(POINT4D));
-
- return lwpoint_construct(SRID, NULL, pa);
-}
-
-/*
- * Given the LWPOINT serialized form (or a pointer into a muli* one)
- * construct a proper LWPOINT.
- * serialized_form should point to the 8bit type format (with type = 1)
- * See serialized form doc
- */
-LWPOINT *
-lwpoint_deserialize(uchar *serialized_form)
-{
- uchar type;
- int geom_type;
- LWPOINT *result;
- uchar *loc = NULL;
- POINTARRAY *pa;
-
- LWDEBUG(2, "lwpoint_deserialize called");
-
- result = (LWPOINT*) lwalloc(sizeof(LWPOINT)) ;
-
- type = serialized_form[0];
- geom_type = lwgeom_getType(type);
-
- if ( geom_type != POINTTYPE)
- {
- lwerror("lwpoint_deserialize: attempt to deserialize a point which is really a %s", lwgeom_typename(geom_type));
- return NULL;
- }
- result->type = type;
-
- loc = serialized_form+1;
-
- if (lwgeom_hasBBOX(type))
- {
- LWDEBUG(3, "lwpoint_deserialize: input has bbox");
-
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
- loc += sizeof(BOX2DFLOAT4);
- }
- else
- {
- result->bbox = NULL;
- }
-
- if ( lwgeom_hasSRID(type))
- {
- LWDEBUG(3, "lwpoint_deserialize: input has SRID");
-
- result->SRID = lw_get_int32(loc);
- loc += 4; /* type + SRID */
- }
- else
- {
- result->SRID = -1;
- }
-
- /* we've read the type (1 byte) and SRID (4 bytes, if present) */
-
- pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), 1);
-
- result->point = pa;
-
- return result;
-}
-
-void pfree_point (LWPOINT *pt)
-{
- pfree_POINTARRAY(pt->point);
- lwfree(pt);
-}
-
-void printLWPOINT(LWPOINT *point)
-{
- lwnotice("LWPOINT {");
- lwnotice(" ndims = %i", (int)TYPE_NDIMS(point->type));
- lwnotice(" BBOX = %i", TYPE_HASBBOX(point->type) ? 1 : 0 );
- lwnotice(" SRID = %i", (int)point->SRID);
- printPA(point->point);
- lwnotice("}");
-}
-
-int
-lwpoint_compute_box2d_p(LWPOINT *point, BOX2DFLOAT4 *box)
-{
- return ptarray_compute_box2d_p(point->point, box);
-}
-
-/* Clone LWPOINT object. POINTARRAY is not copied. */
-LWPOINT *
-lwpoint_clone(const LWPOINT *g)
-{
- LWPOINT *ret = lwalloc(sizeof(LWPOINT));
-
- LWDEBUG(2, "lwpoint_clone called");
-
- memcpy(ret, g, sizeof(LWPOINT));
- if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
- return ret;
-}
-
-/*
- * Add 'what' to this point at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTIPOINT or a GEOMETRYCOLLECTION
- */
-LWGEOM *
-lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
-
- if ( where != -1 && where != 0 )
- {
- lwerror("lwpoint_add only supports 0 or -1 as second argument, got %d", where);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*2);
- if ( where == -1 ) /* append */
- {
- geoms[0] = lwgeom_clone((LWGEOM *)to);
- geoms[1] = lwgeom_clone(what);
- }
- else /* prepend */
- {
- geoms[0] = lwgeom_clone(what);
- geoms[1] = lwgeom_clone((LWGEOM *)to);
- }
- /* reset SRID and wantbbox flag from component types */
- lwgeom_dropSRID(geoms[0]);
- lwgeom_dropBBOX(geoms[0]);
- lwgeom_dropSRID(geoms[1]);
- lwgeom_dropBBOX(geoms[1]);
-
- /* Find appropriate geom type */
- if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- 2, geoms);
-
- return (LWGEOM *)col;
-}
-
-/* Find length of this serialized point */
-size_t
-lwgeom_size_point(const uchar *serialized_point)
-{
- uint32 result = 1;
- uchar type;
- const uchar *loc;
-
- type = serialized_point[0];
-
- if ( lwgeom_getType(type) != POINTTYPE) return 0;
-
- LWDEBUGF(2, "lwgeom_size_point called (%d)", result);
-
- loc = serialized_point+1;
-
- if (lwgeom_hasBBOX(type))
- {
- loc += sizeof(BOX2DFLOAT4);
- result +=sizeof(BOX2DFLOAT4);
-
- LWDEBUGF(3, "lwgeom_size_point: has bbox (%d)", result);
- }
-
- if ( lwgeom_hasSRID(type))
- {
- LWDEBUGF(3, "lwgeom_size_point: has srid (%d)", result);
-
- loc +=4; /* type + SRID */
- result +=4;
- }
-
- result += lwgeom_ndims(type)*sizeof(double);
-
- return result;
-}
-
-/* check coordinate equality */
-char
-lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
-{
- return ptarray_same(p1->point, p2->point);
-}
Deleted: trunk/lwgeom/lwpoly.c
===================================================================
--- trunk/lwgeom/lwpoly.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/lwpoly.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,567 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-/* basic LWPOLY manipulation */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "liblwgeom.h"
-
-
-#define CHECK_POLY_RINGS_ZM 1
-
-/* construct a new LWPOLY. arrays (points/points per ring) will NOT be copied
- * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
- */
-LWPOLY *
-lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox, unsigned int nrings, POINTARRAY **points)
-{
- LWPOLY *result;
- int hasz, hasm;
-#ifdef CHECK_POLY_RINGS_ZM
- char zm;
- unsigned int i;
-#endif
-
- if ( nrings < 1 ) lwerror("lwpoly_construct: need at least 1 ring");
-
- hasz = TYPE_HASZ(points[0]->dims);
- hasm = TYPE_HASM(points[0]->dims);
-
-#ifdef CHECK_POLY_RINGS_ZM
- zm = TYPE_GETZM(points[0]->dims);
- for (i=1; i<nrings; i++)
- {
- if ( zm != TYPE_GETZM(points[i]->dims) )
- lwerror("lwpoly_construct: mixed dimensioned rings");
- }
-#endif
-
- result = (LWPOLY*) lwalloc(sizeof(LWPOLY));
- result->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1), POLYGONTYPE,
- 0);
- result->SRID = SRID;
- result->nrings = nrings;
- result->rings = points;
- result->bbox = bbox;
-
- return result;
-}
-
-
-/*
- * given the LWPOLY serialized form (or a pointer into a muli* one)
- * construct a proper LWPOLY.
- * serialized_form should point to the 8bit type format (with type = 3)
- * See serialized form doc
- */
-LWPOLY *
-lwpoly_deserialize(uchar *serialized_form)
-{
-
- LWPOLY *result;
- uint32 nrings;
- int ndims, hasz, hasm;
- uint32 npoints;
- uchar type;
- uchar *loc;
- int t;
-
- if (serialized_form == NULL)
- {
- lwerror("lwpoly_deserialize called with NULL arg");
- return NULL;
- }
-
- result = (LWPOLY*) lwalloc(sizeof(LWPOLY));
-
- type = serialized_form[0];
- result->type = type;
-
- ndims = TYPE_NDIMS(type);
- hasz = TYPE_HASZ(type);
- hasm = TYPE_HASM(type);
- loc = serialized_form;
-
- if ( TYPE_GETTYPE(type) != POLYGONTYPE)
- {
- lwerror("lwpoly_deserialize: attempt to deserialize a poly which is really a %s", lwgeom_typename(type));
- return NULL;
- }
-
-
- loc = serialized_form+1;
-
- if (lwgeom_hasBBOX(type)) {
- LWDEBUG(3, "lwpoly_deserialize: input has bbox");
-
- result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
- memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
- loc += sizeof(BOX2DFLOAT4);
- } else {
- result->bbox = NULL;
- }
-
- if ( lwgeom_hasSRID(type))
- {
- result->SRID = lw_get_int32(loc);
- loc +=4; /* type + SRID */
- }
- else
- {
- result->SRID = -1;
- }
-
- nrings = lw_get_uint32(loc);
- result->nrings = nrings;
- loc +=4;
- result->rings = (POINTARRAY**) lwalloc(nrings* sizeof(POINTARRAY*));
-
- for (t =0;t<nrings;t++)
- {
- /* read in a single ring and make a PA */
- npoints = lw_get_uint32(loc);
- loc +=4;
-
- result->rings[t] = pointArray_construct(loc, hasz, hasm, npoints);
- loc += sizeof(double)*ndims*npoints;
- }
-
- return result;
-}
-
-/*
- * create the serialized form of the polygon
- * result's first char will be the 8bit type. See serialized form doc
- * points copied
- */
-uchar *
-lwpoly_serialize(LWPOLY *poly)
-{
- size_t size, retsize;
- uchar *result;
-
- size = lwpoly_serialize_size(poly);
- result = lwalloc(size);
- lwpoly_serialize_buf(poly, result, &retsize);
-
- if ( retsize != size )
- {
- lwerror("lwpoly_serialize_size returned %d, ..serialize_buf returned %d", size, retsize);
- }
-
- return result;
-}
-
-/*
- * create the serialized form of the polygon writing it into the
- * given buffer, and returning number of bytes written into
- * the given int pointer.
- * result's first char will be the 8bit type. See serialized form doc
- * points copied
- */
-void
-lwpoly_serialize_buf(LWPOLY *poly, uchar *buf, size_t *retsize)
-{
- size_t size=1; /* type byte */
- char hasSRID;
- int t;
- uchar *loc;
- int ptsize;
-
- LWDEBUG(2, "lwpoly_serialize_buf called");
-
- ptsize = sizeof(double)*TYPE_NDIMS(poly->type);
-
- hasSRID = (poly->SRID != -1);
-
- size += 4; /* nrings */
- size += 4*poly->nrings; /* npoints/ring */
-
- buf[0] = (uchar) lwgeom_makeType_full(
- TYPE_HASZ(poly->type), TYPE_HASM(poly->type),
- hasSRID, POLYGONTYPE, poly->bbox ? 1 : 0);
- loc = buf+1;
-
- if (poly->bbox)
- {
- memcpy(loc, poly->bbox, sizeof(BOX2DFLOAT4));
- size += sizeof(BOX2DFLOAT4); /* bvol */
- loc += sizeof(BOX2DFLOAT4);
- }
-
- if (hasSRID)
- {
- memcpy(loc, &poly->SRID, sizeof(int32));
- loc += 4;
- size +=4; /* 4 byte SRID */
- }
-
- memcpy(loc, &poly->nrings, sizeof(int32)); /* nrings */
- loc+=4;
-
- for (t=0;t<poly->nrings;t++)
- {
- POINTARRAY *pa = poly->rings[t];
- size_t pasize;
- uint32 npoints;
-
- if ( TYPE_GETZM(poly->type) != TYPE_GETZM(pa->dims) )
- lwerror("Dimensions mismatch in lwpoly");
-
- npoints = pa->npoints;
-
- memcpy(loc, &npoints, sizeof(uint32)); /* npoints this ring */
- loc+=4;
-
- pasize = npoints*ptsize;
- size += pasize;
-
- /* copy points */
- memcpy(loc, getPoint_internal(pa, 0), pasize);
- loc += pasize;
-
- }
-
- if (retsize) *retsize = size;
-}
-
-
-/* find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN) */
-BOX3D *
-lwpoly_compute_box3d(LWPOLY *poly)
-{
- BOX3D *result;
-
- /* just need to check outer ring -- interior rings are inside */
- POINTARRAY *pa = poly->rings[0];
- result = ptarray_compute_box3d(pa);
-
- return result;
-}
-
-/* find length of this serialized polygon */
-size_t
-lwgeom_size_poly(const uchar *serialized_poly)
-{
- uint32 result = 1; /* char type */
- uint32 nrings;
- int ndims;
- int t;
- uchar type;
- uint32 npoints;
- const uchar *loc;
-
- if (serialized_poly == NULL)
- return -9999;
-
-
- type = (uchar) serialized_poly[0];
- ndims = lwgeom_ndims(type);
-
- if ( lwgeom_getType(type) != POLYGONTYPE)
- return -9999;
-
-
- loc = serialized_poly+1;
-
- if (lwgeom_hasBBOX(type))
- {
- LWDEBUG(3, "lwgeom_size_poly: has bbox");
-
- loc += sizeof(BOX2DFLOAT4);
- result +=sizeof(BOX2DFLOAT4);
- }
-
-
- if ( lwgeom_hasSRID(type))
- {
- LWDEBUG(3, "lwgeom_size_poly: has srid");
-
- loc +=4; /* type + SRID */
- result += 4;
- }
-
-
- nrings = lw_get_uint32(loc);
- loc +=4;
- result +=4;
-
- LWDEBUGF(3, "lwgeom_size_poly contains %d rings", nrings);
-
- for (t =0;t<nrings;t++)
- {
- /* read in a single ring and make a PA */
- npoints = lw_get_uint32(loc);
- loc += 4;
- result += 4;
-
- if (ndims == 3)
- {
- loc += 24*npoints;
- result += 24*npoints;
- }
- else if (ndims == 2)
- {
- loc += 16*npoints;
- result += 16*npoints;
- }
- else if (ndims == 4)
- {
- loc += 32*npoints;
- result += 32*npoints;
- }
- }
-
- LWDEBUGF(3, "lwgeom_size_poly returning %d", result);
-
- return result;
-}
-
-/* find length of this deserialized polygon */
-size_t
-lwpoly_serialize_size(LWPOLY *poly)
-{
- size_t size = 1; /* type */
- uint32 i;
-
- if ( poly->SRID != -1 ) size += 4; /* SRID */
- if ( poly->bbox ) size += sizeof(BOX2DFLOAT4);
-
- LWDEBUGF(2, "lwpoly_serialize_size called with poly[%p] (%d rings)",
- poly, poly->nrings);
-
- size += 4; /* nrings */
-
- for (i=0; i<poly->nrings; i++)
- {
- size += 4; /* npoints */
- size += poly->rings[i]->npoints*TYPE_NDIMS(poly->type)*sizeof(double);
- }
-
- LWDEBUGF(3, "lwpoly_serialize_size returning %d", size);
-
- return size;
-}
-
-void pfree_polygon (LWPOLY *poly)
-{
- int t;
-
- for (t=0;t<poly->nrings;t++)
- {
- pfree_POINTARRAY(poly->rings[t]);
- }
-
- lwfree(poly);
-}
-
-void printLWPOLY(LWPOLY *poly)
-{
- int t;
- lwnotice("LWPOLY {");
- lwnotice(" ndims = %i", (int)TYPE_NDIMS(poly->type));
- lwnotice(" SRID = %i", (int)poly->SRID);
- lwnotice(" nrings = %i", (int)poly->nrings);
- for (t=0;t<poly->nrings;t++)
- {
- lwnotice(" RING # %i :",t);
- printPA(poly->rings[t]);
- }
- lwnotice("}");
-}
-
-int
-lwpoly_compute_box2d_p(LWPOLY *poly, BOX2DFLOAT4 *box)
-{
- BOX2DFLOAT4 boxbuf;
- uint32 i;
-
- if ( ! poly->nrings ) return 0;
- if ( ! ptarray_compute_box2d_p(poly->rings[0], box) ) return 0;
- for (i=1; i<poly->nrings; i++)
- {
- if ( ! ptarray_compute_box2d_p(poly->rings[0], &boxbuf) )
- return 0;
- if ( ! box2d_union_p(box, &boxbuf, box) )
- return 0;
- }
- return 1;
-}
-
-/* Clone LWLINE object. POINTARRAY are not copied, it's ring array is. */
-LWPOLY *
-lwpoly_clone(const LWPOLY *g)
-{
- LWPOLY *ret = lwalloc(sizeof(LWPOLY));
- memcpy(ret, g, sizeof(LWPOLY));
- ret->rings = lwalloc(sizeof(POINTARRAY *)*g->nrings);
- memcpy(ret->rings, g->rings, sizeof(POINTARRAY *)*g->nrings);
- if ( g->bbox ) ret->bbox = box2d_clone(g->bbox);
- return ret;
-}
-
-/*
- * Add 'what' to this poly at position 'where'.
- * where=0 == prepend
- * where=-1 == append
- * Returns a MULTIPOLYGON or a GEOMETRYCOLLECTION
- */
-LWGEOM *
-lwpoly_add(const LWPOLY *to, uint32 where, const LWGEOM *what)
-{
- LWCOLLECTION *col;
- LWGEOM **geoms;
- int newtype;
-
- if ( where != -1 && where != 0 )
- {
- lwerror("lwpoly_add only supports 0 or -1 as second argument, got %d", where);
- return NULL;
- }
-
- /* dimensions compatibility are checked by caller */
-
- /* Construct geoms array */
- geoms = lwalloc(sizeof(LWGEOM *)*2);
- if ( where == -1 ) /* append */
- {
- geoms[0] = lwgeom_clone((LWGEOM *)to);
- geoms[1] = lwgeom_clone(what);
- }
- else /* prepend */
- {
- geoms[0] = lwgeom_clone(what);
- geoms[1] = lwgeom_clone((LWGEOM *)to);
- }
-
- /* reset SRID and wantbbox flag from component types */
- geoms[0]->SRID = geoms[1]->SRID = -1;
- TYPE_SETHASSRID(geoms[0]->type, 0);
- TYPE_SETHASSRID(geoms[1]->type, 0);
- TYPE_SETHASBBOX(geoms[0]->type, 0);
- TYPE_SETHASBBOX(geoms[1]->type, 0);
-
- /* Find appropriate geom type */
- if ( TYPE_GETTYPE(what->type) == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE;
- else newtype = COLLECTIONTYPE;
-
- col = lwcollection_construct(newtype,
- to->SRID, NULL,
- 2, geoms);
-
- return (LWGEOM *)col;
-}
-
-void
-lwpoly_forceRHR(LWPOLY *poly)
-{
- int i;
-
- if ( ptarray_isccw(poly->rings[0]) )
- {
- ptarray_reverse(poly->rings[0]);
- }
-
- for (i=1; i<poly->nrings; i++)
- {
- if ( ! ptarray_isccw(poly->rings[i]) )
- {
- ptarray_reverse(poly->rings[i]);
- }
- }
-}
-
-
-void
-lwpoly_reverse(LWPOLY *poly)
-{
- int i;
-
- for (i=0; i<poly->nrings; i++)
- ptarray_reverse(poly->rings[i]);
-}
-
-LWPOLY *
-lwpoly_segmentize2d(LWPOLY *poly, double dist)
-{
- POINTARRAY **newrings;
- unsigned int i;
-
- newrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings);
- for (i=0; i<poly->nrings; i++)
- {
- newrings[i] = ptarray_segmentize2d(poly->rings[i], dist);
- }
- return lwpoly_construct(poly->SRID, NULL,
- poly->nrings, newrings);
-}
-
-/*
- * check coordinate equality
- * ring and coordinate order is considered
- */
-char
-lwpoly_same(const LWPOLY *p1, const LWPOLY *p2)
-{
- unsigned int i;
-
- if ( p1->nrings != p2->nrings ) return 0;
- for (i=0; i<p1->nrings; i++)
- {
- if ( ! ptarray_same(p1->rings[i], p2->rings[i]) )
- return 0;
- }
- return 1;
-}
-
-/*
- * Construct a polygon from a LWLINE being
- * the shell and an array of LWLINE (possibly NULL) being holes.
- * Pointarrays from intput geoms are cloned.
- * SRID must be the same for each input line.
- * Input lines must have at least 4 points, and be closed.
- */
-LWPOLY *
-lwpoly_from_lwlines(const LWLINE *shell,
- unsigned int nholes, const LWLINE **holes)
-{
- unsigned int nrings;
- POINTARRAY **rings = lwalloc((nholes+1)*sizeof(POINTARRAY *));
- int SRID = shell->SRID;
- LWPOLY *ret;
-
- if ( shell->points->npoints < 4 )
- lwerror("lwpoly_from_lwlines: shell must have at least 4 points");
- if ( ! ptarray_isclosed2d(shell->points) )
- lwerror("lwpoly_from_lwlines: shell must be closed");
- rings[0] = ptarray_clone(shell->points);
-
- for (nrings=1; nrings<=nholes; nrings++)
- {
- const LWLINE *hole = holes[nrings-1];
-
- if ( hole->SRID != SRID )
- lwerror("lwpoly_from_lwlines: mixed SRIDs in input lines");
-
- if ( hole->points->npoints < 4 )
- lwerror("lwpoly_from_lwlines: holes must have at least 4 points");
- if ( ! ptarray_isclosed2d(hole->points) )
- lwerror("lwpoly_from_lwlines: holes must be closed");
-
- rings[nrings] = ptarray_clone(hole->points);
- }
-
- ret = lwpoly_construct(SRID, NULL, nrings, rings);
- return ret;
-}
Deleted: trunk/lwgeom/measures.c
===================================================================
--- trunk/lwgeom/measures.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/measures.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,845 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <math.h>
-#include <string.h>
-
-#include "liblwgeom.h"
-
-
-/*
- * pt_in_ring_2d(): crossing number test for a point in a polygon
- * input: p = a point,
- * pa = vertex points of a ring V[n+1] with V[n]=V[0]
- * returns: 0 = outside, 1 = inside
- *
- * Our polygons have first and last point the same,
- *
- */
-int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring)
-{
- int cn = 0; /* the crossing number counter */
- int i;
- POINT2D v1, v2;
-
-#if INTEGRITY_CHECKS
- POINT2D first, last;
-
- getPoint2d_p(ring, 0, &first);
- getPoint2d_p(ring, ring->npoints-1, &last);
- if ( memcmp(&first, &last, sizeof(POINT2D)) )
- {
- lwerror("pt_in_ring_2d: V[n] != V[0] (%g %g != %g %g)",
- first.x, first.y, last.x, last.y);
-
- }
-#endif
-
- LWDEBUGF(2, "pt_in_ring_2d called with point: %g %g", p->x, p->y);
- /* printPA(ring); */
-
- /* loop through all edges of the polygon */
- getPoint2d_p(ring, 0, &v1);
- for (i=0; i<ring->npoints-1; i++)
- {
- double vt;
- getPoint2d_p(ring, i+1, &v2);
-
- /* edge from vertex i to vertex i+1 */
- if
- (
- /* an upward crossing */
- ((v1.y <= p->y) && (v2.y > p->y))
- /* a downward crossing */
- || ((v1.y > p->y) && (v2.y <= p->y))
- )
- {
-
- vt = (double)(p->y - v1.y) / (v2.y - v1.y);
-
- /* P.x <intersect */
- if (p->x < v1.x + vt * (v2.x - v1.x))
- {
- /* a valid crossing of y=p.y right of p.x */
- ++cn;
- }
- }
- v1 = v2;
- }
-
- LWDEBUGF(3, "pt_in_ring_2d returning %d", cn&1);
-
- return (cn&1); /* 0 if even (out), and 1 if odd (in) */
-}
-
-double distance2d_pt_pt(POINT2D *p1, POINT2D *p2)
-{
- double hside = p2->x - p1->x;
- double vside = p2->y - p1->y;
-
- return sqrt ( hside*hside + vside*vside );
-
- /* the above is more readable
- return sqrt(
- (p2->x-p1->x) * (p2->x-p1->x) + (p2->y-p1->y) * (p2->y-p1->y)
- ); */
-}
-
-/*distance2d from p to line A->B */
-double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B)
-{
- double r,s;
-
- /*if start==end, then use pt distance */
- if ( ( A->x == B->x) && (A->y == B->y) )
- return distance2d_pt_pt(p,A);
-
- /*
- * otherwise, we use comp.graphics.algorithms
- * Frequently Asked Questions method
- *
- * (1) AC dot AB
- * r = ---------
- * ||AB||^2
- * r has the following meaning:
- * r=0 P = A
- * r=1 P = B
- * r<0 P is on the backward extension of AB
- * r>1 P is on the forward extension of AB
- * 0<r<1 P is interior to AB
- */
-
- r = ( (p->x-A->x) * (B->x-A->x) + (p->y-A->y) * (B->y-A->y) )/( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
-
- if (r<0) return distance2d_pt_pt(p,A);
- if (r>1) return distance2d_pt_pt(p,B);
-
-
- /*
- * (2)
- * (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
- * s = -----------------------------
- * L^2
- *
- * Then the distance from C to P = |s|*L.
- *
- */
-
- s = ( (A->y-p->y)*(B->x-A->x)- (A->x-p->x)*(B->y-A->y) ) /
- ( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
-
- return LW_ABS(s) * sqrt(
- (B->x-A->x)*(B->x-A->x) + (B->y-A->y)*(B->y-A->y)
- );
-}
-
-/* find the minimum 2d distance from AB to CD */
-double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D)
-{
-
- double s_top, s_bot,s;
- double r_top, r_bot,r;
-
- LWDEBUGF(2, "distance2d_seg_seg [%g,%g]->[%g,%g] by [%g,%g]->[%g,%g]",
- A->x,A->y,B->x,B->y, C->x,C->y, D->x, D->y);
-
-
- /*A and B are the same point */
- if ( ( A->x == B->x) && (A->y == B->y) )
- return distance2d_pt_seg(A,C,D);
-
- /*U and V are the same point */
-
- if ( ( C->x == D->x) && (C->y == D->y) )
- return distance2d_pt_seg(D,A,B);
-
- /* AB and CD are line segments */
- /* from comp.graphics.algo
-
- Solving the above for r and s yields
- (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
- r = ----------------------------- (eqn 1)
- (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
-
- (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
- s = ----------------------------- (eqn 2)
- (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
- Let P be the position vector of the intersection point, then
- P=A+r(B-A) or
- Px=Ax+r(Bx-Ax)
- Py=Ay+r(By-Ay)
- By examining the values of r & s, you can also determine some other limiting conditions:
- If 0<=r<=1 & 0<=s<=1, intersection exists
- r<0 or r>1 or s<0 or s>1 line segments do not intersect
- If the denominator in eqn 1 is zero, AB & CD are parallel
- If the numerator in eqn 1 is also zero, AB & CD are collinear.
-
- */
- r_top = (A->y-C->y)*(D->x-C->x) - (A->x-C->x)*(D->y-C->y) ;
- r_bot = (B->x-A->x)*(D->y-C->y) - (B->y-A->y)*(D->x-C->x) ;
-
- s_top = (A->y-C->y)*(B->x-A->x) - (A->x-C->x)*(B->y-A->y);
- s_bot = (B->x-A->x)*(D->y-C->y) - (B->y-A->y)*(D->x-C->x);
-
- if ( (r_bot==0) || (s_bot == 0) )
- {
- return (
- LW_MIN(distance2d_pt_seg(A,C,D),
- LW_MIN(distance2d_pt_seg(B,C,D),
- LW_MIN(distance2d_pt_seg(C,A,B),
- distance2d_pt_seg(D,A,B))
- )
- )
- );
- }
- s = s_top/s_bot;
- r= r_top/r_bot;
-
- if ((r<0) || (r>1) || (s<0) || (s>1) )
- {
- /*no intersection */
- return (
- LW_MIN(distance2d_pt_seg(A,C,D),
- LW_MIN(distance2d_pt_seg(B,C,D),
- LW_MIN(distance2d_pt_seg(C,A,B),
- distance2d_pt_seg(D,A,B))
- )
- )
- );
-
- }
- else
- return -0; /*intersection exists */
-
-}
-
-/*
- * search all the segments of pointarray to see which one is closest to p1
- * Returns minimum distance between point and pointarray
- */
-double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa)
-{
- double result = 0;
- int t;
- POINT2D start, end;
-
- getPoint2d_p(pa, 0, &start);
-
- for (t=1; t<pa->npoints; t++)
- {
- double dist;
- getPoint2d_p(pa, t, &end);
- dist = distance2d_pt_seg(p, &start, &end);
- if (t==1) result = dist;
- else result = LW_MIN(result, dist);
-
- if ( result == 0 ) return 0;
-
- start = end;
- }
-
- return result;
-}
-
-/* test each segment of l1 against each segment of l2. Return min */
-double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2)
-{
- double result = 99999999999.9;
- char result_okay = 0; /*result is a valid min */
- int t,u;
- POINT2D start, end;
- POINT2D start2, end2;
-
- LWDEBUGF(2, "distance2d_ptarray_ptarray called (points: %d-%d)",
- l1->npoints, l2->npoints);
-
- getPoint2d_p(l1, 0, &start);
- for (t=1; t<l1->npoints; t++) /*for each segment in L1 */
- {
- getPoint2d_p(l1, t, &end);
-
- getPoint2d_p(l2, 0, &start2);
- for (u=1; u<l2->npoints; u++) /*for each segment in L2 */
- {
- double dist;
-
- getPoint2d_p(l2, u, &end2);
-
- dist = distance2d_seg_seg(&start, &end, &start2, &end2);
-
- LWDEBUGF(4, "line_line; seg %i * seg %i, dist = %g\n",t,u,dist);
-
- if (result_okay)
- result = LW_MIN(result,dist);
- else
- {
- result_okay = 1;
- result = dist;
- }
-
- LWDEBUGF(3, " seg%d-seg%d dist: %f, mindist: %f",
- t, u, dist, result);
-
- if (result <= 0) return 0; /*intersection */
-
- start2 = end2;
- }
- start = end;
- }
-
- return result;
-}
-
-/* true if point is in poly (and not in its holes) */
-int pt_in_poly_2d(POINT2D *p, LWPOLY *poly)
-{
- int i;
-
- /* Not in outer ring */
- if ( ! pt_in_ring_2d(p, poly->rings[0]) ) return 0;
-
- /* Check holes */
- for (i=1; i<poly->nrings; i++)
- {
- /* Inside a hole */
- if ( pt_in_ring_2d(p, poly->rings[i]) ) return 0;
- }
-
- return 1; /* In outer ring, not in holes */
-}
-
-/*
- * Brute force.
- * Test line-ring distance against each ring.
- * If there's an intersection (distance==0) then return 0 (crosses boundary).
- * Otherwise, test to see if any point is inside outer rings of polygon,
- * but not in inner rings.
- * If so, return 0 (line inside polygon),
- * otherwise return min distance to a ring (could be outside
- * polygon or inside a hole)
- */
-double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly)
-{
- POINT2D pt;
- int i;
- double mindist = 0;
-
- LWDEBUGF(2, "distance2d_ptarray_poly called (%d rings)", poly->nrings);
-
- for (i=0; i<poly->nrings; i++)
- {
- double dist = distance2d_ptarray_ptarray(pa, poly->rings[i]);
- if (i) mindist = LW_MIN(mindist, dist);
- else mindist = dist;
-
- LWDEBUGF(3, " distance from ring %d: %f, mindist: %f",
- i, dist, mindist);
-
- if ( mindist <= 0 ) return 0.0; /* intersection */
- }
-
- /*
- * No intersection, have to check if a point is
- * inside polygon
- */
- getPoint2d_p(pa, 0, &pt);
-
- /*
- * Outside outer ring, so min distance to a ring
- * is the actual min distance
- */
- if ( ! pt_in_ring_2d(&pt, poly->rings[0]) ) return mindist;
-
-
- /*
- * Its in the outer ring.
- * Have to check if its inside a hole
- */
- for (i=1; i<poly->nrings; i++)
- {
- if ( pt_in_ring_2d(&pt, poly->rings[i]) )
- {
- /*
- * Its inside a hole, then the actual
- * distance is the min ring distance
- */
- return mindist;
- }
- }
-
- return 0.0; /* Not in hole, so inside polygon */
-}
-
-double distance2d_point_point(LWPOINT *point1, LWPOINT *point2)
-{
- POINT2D p1;
- POINT2D p2;
-
- getPoint2d_p(point1->point, 0, &p1);
- getPoint2d_p(point2->point, 0, &p2);
-
- return distance2d_pt_pt(&p1, &p2);
-}
-
-double distance2d_point_line(LWPOINT *point, LWLINE *line)
-{
- POINT2D p;
- POINTARRAY *pa = line->points;
- getPoint2d_p(point->point, 0, &p);
- return distance2d_pt_ptarray(&p, pa);
-}
-
-double distance2d_line_line(LWLINE *line1, LWLINE *line2)
-{
- POINTARRAY *pa1 = line1->points;
- POINTARRAY *pa2 = line2->points;
- return distance2d_ptarray_ptarray(pa1, pa2);
-}
-
-/*
- * 1. see if pt in outer boundary. if no, then treat the outer ring like a line
- * 2. if in the boundary, test to see if its in a hole.
- * if so, then return dist to hole, else return 0 (point in polygon)
- */
-double distance2d_point_poly(LWPOINT *point, LWPOLY *poly)
-{
- POINT2D p;
- int i;
-
- getPoint2d_p(point->point, 0, &p);
-
- LWDEBUG(2, "distance2d_point_poly called");
-
- /* Return distance to outer ring if not inside it */
- if ( ! pt_in_ring_2d(&p, poly->rings[0]) )
- {
- LWDEBUG(3, " not inside outer-ring");
-
- return distance2d_pt_ptarray(&p, poly->rings[0]);
- }
-
- /*
- * Inside the outer ring.
- * Scan though each of the inner rings looking to
- * see if its inside. If not, distance==0.
- * Otherwise, distance = pt to ring distance
- */
- for (i=1; i<poly->nrings; i++)
- {
- /* Inside a hole. Distance = pt -> ring */
- if ( pt_in_ring_2d(&p, poly->rings[i]) )
- {
- LWDEBUG(3, " inside an hole");
-
- return distance2d_pt_ptarray(&p, poly->rings[i]);
- }
- }
-
- LWDEBUG(3, " inside the polygon");
-
- return 0.0; /* Is inside the polygon */
-}
-
-/*
- * Brute force.
- * Test to see if any rings intersect.
- * If yes, dist=0.
- * Test to see if one inside the other and if they are inside holes.
- * Find min distance ring-to-ring.
- */
-double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2)
-{
- POINT2D pt;
- double mindist = -1;
- int i;
-
- LWDEBUG(2, "distance2d_poly_poly called");
-
- /* if poly1 inside poly2 return 0 */
- getPoint2d_p(poly1->rings[0], 0, &pt);
- if ( pt_in_poly_2d(&pt, poly2) ) return 0.0;
-
- /* if poly2 inside poly1 return 0 */
- getPoint2d_p(poly2->rings[0], 0, &pt);
- if ( pt_in_poly_2d(&pt, poly1) ) return 0.0;
-
- LWDEBUG(3, " polys not inside each other");
-
- /*
- * foreach ring in Poly1
- * foreach ring in Poly2
- * if intersect, return 0
- */
- for (i=0; i<poly1->nrings; i++)
- {
- int j;
- for (j=0; j<poly2->nrings; j++)
- {
- double d = distance2d_ptarray_ptarray(poly1->rings[i],
- poly2->rings[j]);
- if ( d <= 0 ) return 0.0;
-
- /* mindist is -1 when not yet set */
- if (mindist > -1) mindist = LW_MIN(mindist, d);
- else mindist = d;
-
- LWDEBUGF(3, " ring%i-%i dist: %f, mindist: %f", i, j, d, mindist);
- }
-
- }
-
- /* otherwise return closest approach of rings (no intersection) */
- return mindist;
-
-}
-
-double distance2d_line_poly(LWLINE *line, LWPOLY *poly)
-{
- return distance2d_ptarray_poly(line->points, poly);
-}
-
-
-/*find the 2d length of the given POINTARRAY (even if it's 3d) */
-double lwgeom_pointarray_length2d(POINTARRAY *pts)
-{
- double dist = 0.0;
- int i;
- POINT2D frm;
- POINT2D to;
-
- if ( pts->npoints < 2 ) return 0.0;
- for (i=0; i<pts->npoints-1;i++)
- {
- getPoint2d_p(pts, i, &frm);
- getPoint2d_p(pts, i+1, &to);
- dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) ) +
- ((frm.y - to.y)*(frm.y - to.y) ) );
- }
- return dist;
-}
-
-/*
- * Find the 3d/2d length of the given POINTARRAY
- * (depending on its dimensions)
- */
-double
-lwgeom_pointarray_length(POINTARRAY *pts)
-{
- double dist = 0.0;
- int i;
- POINT3DZ frm;
- POINT3DZ to;
-
- if ( pts->npoints < 2 ) return 0.0;
-
- /* compute 2d length if 3d is not available */
- if ( ! TYPE_HASZ(pts->dims) ) return lwgeom_pointarray_length2d(pts);
-
- for (i=0; i<pts->npoints-1;i++)
- {
- getPoint3dz_p(pts, i, &frm);
- getPoint3dz_p(pts, i+1, &to);
- dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) ) +
- ((frm.y - to.y)*(frm.y - to.y) ) +
- ((frm.z - to.z)*(frm.z - to.z) ) );
- }
-
- return dist;
-}
-
-/*
- * This should be rewritten to make use of the curve itself.
- */
-double
-lwgeom_curvepolygon_area(LWCURVEPOLY *curvepoly)
-{
- LWPOLY *poly = (LWPOLY *)lwgeom_segmentize((LWGEOM *)curvepoly, 32);
- return lwgeom_polygon_area(poly);
-}
-
-/*
- * Find the area of the outer ring - sum (area of inner rings).
- * Could use a more numerically stable calculator...
- */
-double
-lwgeom_polygon_area(LWPOLY *poly)
-{
- double poly_area=0.0;
- int i;
- POINT2D p1;
- POINT2D p2;
-
- LWDEBUGF(2, "in lwgeom_polygon_area (%d rings)", poly->nrings);
-
- for (i=0; i<poly->nrings; i++)
- {
- int j;
- POINTARRAY *ring = poly->rings[i];
- double ringarea = 0.0;
-
- LWDEBUGF(4, " rings %d has %d points", i, ring->npoints);
-
- for (j=0; j<ring->npoints-1; j++)
- {
- getPoint2d_p(ring, j, &p1);
- getPoint2d_p(ring, j+1, &p2);
- ringarea += ( p1.x * p2.y ) - ( p1.y * p2.x );
- }
-
- ringarea /= 2.0;
-
- LWDEBUGF(4, " ring 1 has area %lf",ringarea);
-
- ringarea = fabs(ringarea);
- if (i != 0) /*outer */
- ringarea = -1.0*ringarea ; /* its a hole */
-
- poly_area += ringarea;
- }
-
- return poly_area;
-}
-
-/*
- * Compute the sum of polygon rings length.
- * Could use a more numerically stable calculator...
- */
-double lwgeom_polygon_perimeter(LWPOLY *poly)
-{
- double result=0.0;
- int i;
-
- LWDEBUGF(2, "in lwgeom_polygon_perimeter (%d rings)", poly->nrings);
-
- for (i=0; i<poly->nrings; i++)
- result += lwgeom_pointarray_length(poly->rings[i]);
-
- return result;
-}
-
-/*
- * Compute the sum of polygon rings length (forcing 2d computation).
- * Could use a more numerically stable calculator...
- */
-double lwgeom_polygon_perimeter2d(LWPOLY *poly)
-{
- double result=0.0;
- int i;
-
- LWDEBUGF(2, "in lwgeom_polygon_perimeter (%d rings)", poly->nrings);
-
- for (i=0; i<poly->nrings; i++)
- result += lwgeom_pointarray_length2d(poly->rings[i]);
-
- return result;
-}
-
-double
-lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2)
-{
- return lwgeom_mindistance2d_recursive_tolerance( lw1, lw2, 0.0 );
-}
-
-double
-lwgeom_mindistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance)
-{
- LWGEOM_INSPECTED *in1, *in2;
- int i, j;
- double mindist = -1;
-
- in1 = lwgeom_inspect(lw1);
- in2 = lwgeom_inspect(lw2);
-
- for (i=0; i<in1->ngeometries; i++)
- {
- uchar *g1 = lwgeom_getsubgeometry_inspected(in1, i);
- int t1 = lwgeom_getType(g1[0]);
- double dist=tolerance;
-
- /* it's a multitype... recurse */
- if ( t1 >= 4 )
- {
- dist = lwgeom_mindistance2d_recursive_tolerance(g1, lw2, tolerance);
- if ( dist <= tolerance ) return tolerance; /* can't be closer */
- if ( mindist == -1 ) mindist = dist;
- else mindist = LW_MIN(dist, mindist);
- continue;
- }
-
- for (j=0; j<in2->ngeometries; j++)
- {
- uchar *g2 = lwgeom_getsubgeometry_inspected(in2, j);
- int t2 = lwgeom_getType(g2[0]);
-
- if ( t1 == POINTTYPE )
- {
- if ( t2 == POINTTYPE )
- {
- dist = distance2d_point_point(
- lwpoint_deserialize(g1),
- lwpoint_deserialize(g2)
- );
- }
- else if ( t2 == LINETYPE )
- {
- dist = distance2d_point_line(
- lwpoint_deserialize(g1),
- lwline_deserialize(g2)
- );
- }
- else if ( t2 == POLYGONTYPE )
- {
- dist = distance2d_point_poly(
- lwpoint_deserialize(g1),
- lwpoly_deserialize(g2)
- );
- }
- }
- else if ( t1 == LINETYPE )
- {
- if ( t2 == POINTTYPE )
- {
- dist = distance2d_point_line(
- lwpoint_deserialize(g2),
- lwline_deserialize(g1)
- );
- }
- else if ( t2 == LINETYPE )
- {
- dist = distance2d_line_line(
- lwline_deserialize(g1),
- lwline_deserialize(g2)
- );
- }
- else if ( t2 == POLYGONTYPE )
- {
- dist = distance2d_line_poly(
- lwline_deserialize(g1),
- lwpoly_deserialize(g2)
- );
- }
- }
- else if ( t1 == POLYGONTYPE )
- {
- if ( t2 == POLYGONTYPE )
- {
- dist = distance2d_poly_poly(
- lwpoly_deserialize(g2),
- lwpoly_deserialize(g1)
- );
- }
- else if ( t2 == POINTTYPE )
- {
- dist = distance2d_point_poly(
- lwpoint_deserialize(g2),
- lwpoly_deserialize(g1)
- );
- }
- else if ( t2 == LINETYPE )
- {
- dist = distance2d_line_poly(
- lwline_deserialize(g2),
- lwpoly_deserialize(g1)
- );
- }
- }
- else /* it's a multitype... recurse */
- {
- dist = lwgeom_mindistance2d_recursive_tolerance(g1, g2, tolerance);
- }
-
- if (mindist == -1 ) mindist = dist;
- else mindist = LW_MIN(dist, mindist);
-
- LWDEBUGF(3, "dist %d-%d: %f - mindist: %f",
- i, j, dist, mindist);
-
-
- if (mindist <= tolerance) return tolerance; /* can't be closer */
-
- }
-
- }
-
- if (mindist<0) mindist = 0;
-
- return mindist;
-}
-
-
-
-int
-lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad)
-{
- POINT2D center;
-
- center.x = cx;
- center.y = cy;
-
- if ( distance2d_pt_pt(p, ¢er) < rad ) return 1;
- else return 0;
-
-}
-
-/*
- * Compute the azimuth of segment AB in radians.
- * Return 0 on exception (same point), 1 otherwise.
- */
-int
-azimuth_pt_pt(POINT2D *A, POINT2D *B, double *d)
-{
- if ( A->x == B->x )
- {
- if ( A->y < B->y ) *d=0.0;
- else if ( A->y > B->y ) *d=M_PI;
- else return 0;
- return 1;
- }
-
- if ( A->y == B->y )
- {
- if ( A->x < B->x ) *d=M_PI/2;
- else if ( A->x > B->x ) *d=M_PI+(M_PI/2);
- else return 0;
- return 1;
- }
-
- if ( A->x < B->x )
- {
- if ( A->y < B->y )
- {
- *d=atan(fabs(A->x - B->x) / fabs(A->y - B->y) );
- }
- else /* ( A->y > B->y ) - equality case handled above */
- {
- *d=atan(fabs(A->y - B->y) / fabs(A->x - B->x) )
- + (M_PI/2);
- }
- }
-
- else /* ( A->x > B->x ) - equality case handled above */
- {
- if ( A->y > B->y )
- {
- *d=atan(fabs(A->x - B->x) / fabs(A->y - B->y) )
- + M_PI;
- }
- else /* ( A->y < B->y ) - equality case handled above */
- {
- *d=atan(fabs(A->y - B->y) / fabs(A->x - B->x) )
- + (M_PI+(M_PI/2));
- }
- }
-
- return 1;
-}
-
Deleted: trunk/lwgeom/ptarray.c
===================================================================
--- trunk/lwgeom/ptarray.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/ptarray.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,836 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2001-2006 Refractions Research Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU General Public Licence. See the COPYING file.
- *
- **********************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-
-#include "liblwgeom.h"
-
-
-POINTARRAY *
-ptarray_construct(char hasz, char hasm, unsigned int npoints)
-{
- uchar dims = 0;
- size_t size;
- uchar *ptlist;
- POINTARRAY *pa;
-
- TYPE_SETZM(dims, hasz?1:0, hasm?1:0);
- size = TYPE_NDIMS(dims)*npoints*sizeof(double);
-
- ptlist = (uchar *)lwalloc(size);
- pa = lwalloc(sizeof(POINTARRAY));
- pa->dims = dims;
- pa->serialized_pointlist = ptlist;
- pa->npoints = npoints;
-
- return pa;
-
-}
-
-void
-ptarray_reverse(POINTARRAY *pa)
-{
- POINT4D pbuf;
- uint32 i;
- int ptsize = pointArray_ptsize(pa);
- int last = pa->npoints-1;
- int mid = last/2;
-
- for (i=0; i<=mid; i++)
- {
- uchar *from, *to;
- from = getPoint_internal(pa, i);
- to = getPoint_internal(pa, (last-i));
- memcpy((uchar *)&pbuf, to, ptsize);
- memcpy(to, from, ptsize);
- memcpy(from, (uchar *)&pbuf, ptsize);
- }
-
-}
-
-/*
- * calculate the 2d bounding box of a set of points
- * write result to the provided BOX2DFLOAT4
- * Return 0 if bounding box is NULL (empty geom)
- */
-int
-ptarray_compute_box2d_p(const POINTARRAY *pa, BOX2DFLOAT4 *result)
-{
- int t;
- POINT2D pt;
- BOX3D box;
-
- if (pa->npoints == 0) return 0;
-
- getPoint2d_p(pa, 0, &pt);
-
- box.xmin = pt.x;
- box.xmax = pt.x;
- box.ymin = pt.y;
- box.ymax = pt.y;
-
- for (t=1; t<pa->npoints; t++)
- {
- getPoint2d_p(pa, t, &pt);
- if (pt.x < box.xmin) box.xmin = pt.x;
- if (pt.y < box.ymin) box.ymin = pt.y;
- if (pt.x > box.xmax) box.xmax = pt.x;
- if (pt.y > box.ymax) box.ymax = pt.y;
- }
-
- box3d_to_box2df_p(&box, result);
-
- return 1;
-}
-
-/*
- * Calculate the 2d bounding box of a set of points.
- * Return allocated BOX2DFLOAT4 or NULL (for empty array).
- */
-BOX2DFLOAT4 *
-ptarray_compute_box2d(const POINTARRAY *pa)
-{
- int t;
- POINT2D pt;
- BOX2DFLOAT4 *result;
-
- if (pa->npoints == 0) return NULL;
-
- result = lwalloc(sizeof(BOX2DFLOAT4));
-
- getPoint2d_p(pa, 0, &pt);
-
- result->xmin = pt.x;
- result->xmax = pt.x;
- result->ymin = pt.y;
- result->ymax = pt.y;
-
- for (t=1;t<pa->npoints;t++)
- {
- getPoint2d_p(pa, t, &pt);
- if (pt.x < result->xmin) result->xmin = pt.x;
- if (pt.y < result->ymin) result->ymin = pt.y;
- if (pt.x > result->xmax) result->xmax = pt.x;
- if (pt.y > result->ymax) result->ymax = pt.y;
- }
-
- return result;
-}
-
-/*
- * Returns a modified POINTARRAY so that no segment is
- * longer then the given distance (computed using 2d).
- * Every input point is kept.
- * Z and M values for added points (if needed) are set to 0.
- */
-POINTARRAY *
-ptarray_segmentize2d(POINTARRAY *ipa, double dist)
-{
- double segdist;
- POINT4D p1, p2;
- void *ip, *op;
- POINT4D pbuf;
- POINTARRAY *opa;
- int maxpoints = ipa->npoints;
- int ptsize = pointArray_ptsize(ipa);
- int ipoff=0; /* input point offset */
-
- pbuf.x = pbuf.y = pbuf.z = pbuf.m = 0;
-
- /* Initial storage */
- opa = (POINTARRAY *)lwalloc(ptsize * maxpoints);
- opa->dims = ipa->dims;
- opa->npoints = 0;
- opa->serialized_pointlist = (uchar *)lwalloc(maxpoints*ptsize);
-
- /* Add first point */
- opa->npoints++;
- getPoint4d_p(ipa, ipoff, &p1);
- op = getPoint_internal(opa, opa->npoints-1);
- memcpy(op, &p1, ptsize);
- ipoff++;
-
- while (ipoff<ipa->npoints)
- {
- /*
- * We use these pointers to avoid
- * "strict-aliasing rules break" warning raised
- * by gcc (3.3 and up).
- *
- * It looks that casting a variable address (also
- * referred to as "type-punned pointer")
- * breaks those "strict" rules.
- *
- */
- POINT4D *p1ptr=&p1, *p2ptr=&p2;
-
- getPoint4d_p(ipa, ipoff, &p2);
-
- segdist = distance2d_pt_pt((POINT2D *)p1ptr, (POINT2D *)p2ptr);
-
- if (segdist > dist) /* add an intermediate point */
- {
- pbuf.x = p1.x + (p2.x-p1.x)/segdist * dist;
- pbuf.y = p1.y + (p2.y-p1.y)/segdist * dist;
- /* might also compute z and m if available... */
- ip = &pbuf;
- memcpy(&p1, ip, ptsize);
- }
- else /* copy second point */
- {
- ip = &p2;
- p1 = p2;
- ipoff++;
- }
-
- /* Add point */
- if ( ++(opa->npoints) > maxpoints ) {
- maxpoints *= 1.5;
- opa->serialized_pointlist = (uchar *)lwrealloc(
- opa->serialized_pointlist,
- maxpoints*ptsize
- );
- }
- op = getPoint_internal(opa, opa->npoints-1);
- memcpy(op, ip, ptsize);
- }
-
- return opa;
-}
-
-char
-ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
-{
- unsigned int i;
- size_t ptsize;
-
- if ( TYPE_GETZM(pa1->dims) != TYPE_GETZM(pa2->dims) ) return 0;
-
- if ( pa1->npoints != pa2->npoints ) return 0;
-
- ptsize = pointArray_ptsize(pa1);
-
- for (i=0; i<pa1->npoints; i++)
- {
- if ( memcmp(getPoint_internal(pa1, i), getPoint_internal(pa2, i), ptsize) )
- return 0;
- }
-
- return 1;
-}
-
-/*
- * Add a point in a pointarray.
- * 'where' is the offset (starting at 0)
- * if 'where' == -1 append is required.
- */
-POINTARRAY *
-ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims, unsigned int where)
-{
- POINTARRAY *ret;
- POINT4D pbuf;
- size_t ptsize = pointArray_ptsize(pa);
-
- LWDEBUGF(3, "pa %x p %x size %d where %d",
- pa, p, pdims, where);
-
- if ( pdims < 2 || pdims > 4 )
- {
- lwerror("ptarray_addPoint: point dimension out of range (%d)",
- pdims);
- return NULL;
- }
-
- if ( where > pa->npoints )
- {
- lwerror("ptarray_addPoint: offset out of range (%d)",
- where);
- return NULL;
- }
-
- LWDEBUG(3, "called with a %dD point");
-
- pbuf.x = pbuf.y = pbuf.z = pbuf.m = 0.0;
- memcpy((uchar *)&pbuf, p, pdims*sizeof(double));
-
- LWDEBUG(3, "initialized point buffer");
-
- ret = ptarray_construct(TYPE_HASZ(pa->dims),
- TYPE_HASM(pa->dims), pa->npoints+1);
-
- if ( where == -1 ) where = pa->npoints;
-
- if ( where )
- {
- memcpy(getPoint_internal(ret, 0), getPoint_internal(pa, 0), ptsize*where);
- }
-
- memcpy(getPoint_internal(ret, where), (uchar *)&pbuf, ptsize);
-
- if ( where+1 != ret->npoints )
- {
- memcpy(getPoint_internal(ret, where+1),
- getPoint_internal(pa, where),
- ptsize*(pa->npoints-where));
- }
-
- return ret;
-}
-
-/*
- * Remove a point from a pointarray.
- * 'which' is the offset (starting at 0)
- * Returned pointarray is newly allocated
- */
-POINTARRAY *
-ptarray_removePoint(POINTARRAY *pa, unsigned int which)
-{
- POINTARRAY *ret;
- size_t ptsize = pointArray_ptsize(pa);
-
- LWDEBUGF(3, "pa %x which %d", pa, which);
-
-#if PARANOIA_LEVEL > 0
- if ( which > pa->npoints-1 )
- {
- lwerror("ptarray_removePoint: offset (%d) out of range (%d..%d)",
- which, 0, pa->npoints-1);
- return NULL;
- }
-
- if ( pa->npoints < 3 )
- {
- lwerror("ptarray_removePointe: can't remove a point from a 2-vertex POINTARRAY");
- }
-#endif
-
- ret = ptarray_construct(TYPE_HASZ(pa->dims),
- TYPE_HASM(pa->dims), pa->npoints-1);
-
- /* copy initial part */
- if ( which )
- {
- memcpy(getPoint_internal(ret, 0), getPoint_internal(pa, 0), ptsize*which);
- }
-
- /* copy final part */
- if ( which < pa->npoints-1 )
- {
- memcpy(getPoint_internal(ret, which), getPoint_internal(pa, which+1),
- ptsize*(pa->npoints-which-1));
- }
-
- return ret;
-}
-
-/*
- * Clone a pointarray
- */
-POINTARRAY *
-ptarray_clone(const POINTARRAY *in)
-{
- POINTARRAY *out = lwalloc(sizeof(POINTARRAY));
- size_t size;
-
- LWDEBUG(3, "ptarray_clone called.");
-
- out->dims = in->dims;
- out->npoints = in->npoints;
-
- size = in->npoints*sizeof(double)*TYPE_NDIMS(in->dims);
- out->serialized_pointlist = lwalloc(size);
- memcpy(out->serialized_pointlist, in->serialized_pointlist, size);
-
- return out;
-}
-
-int
-ptarray_isclosed2d(const POINTARRAY *in)
-{
- if ( memcmp(getPoint_internal(in, 0), getPoint_internal(in, in->npoints-1), sizeof(POINT2D)) ) return 0;
- return 1;
-}
-
-/*
- * calculate the BOX3D bounding box of a set of points
- * returns a lwalloced BOX3D, or NULL on empty array.
- * zmin/zmax values are set to NO_Z_VALUE if not available.
- */
-BOX3D *
-ptarray_compute_box3d(const POINTARRAY *pa)
-{
- BOX3D *result = lwalloc(sizeof(BOX3D));
-
- if ( ! ptarray_compute_box3d_p(pa, result) )
- {
- lwfree(result);
- return NULL;
- }
-
- return result;
-}
-
-/*
- * calculate the BOX3D bounding box of a set of points
- * zmin/zmax values are set to NO_Z_VALUE if not available.
- * write result to the provided BOX3D
- * Return 0 if bounding box is NULL (empty geom)
- */
-int
-ptarray_compute_box3d_p(const POINTARRAY *pa, BOX3D *result)
-{
- int t;
- POINT3DZ pt;
-
- LWDEBUGF(3, "ptarray_compute_box3d call (array has %d points)", pa->npoints);
-
- if (pa->npoints == 0) return 0;
-
- getPoint3dz_p(pa, 0, &pt);
-
- LWDEBUG(3, "got point 0");
-
- result->xmin = pt.x;
- result->xmax = pt.x;
- result->ymin = pt.y;
- result->ymax = pt.y;
-
- if ( TYPE_HASZ(pa->dims) ) {
- result->zmin = pt.z;
- result->zmax = pt.z;
- } else {
- result->zmin = NO_Z_VALUE;
- result->zmax = NO_Z_VALUE;
- }
-
- LWDEBUGF(3, "scanning other %d points", pa->npoints);
-
- for (t=1; t<pa->npoints; t++)
- {
- getPoint3dz_p(pa,t,&pt);
- if (pt.x < result->xmin) result->xmin = pt.x;
- if (pt.y < result->ymin) result->ymin = pt.y;
- if (pt.x > result->xmax) result->xmax = pt.x;
- if (pt.y > result->ymax) result->ymax = pt.y;
-
- if ( TYPE_HASZ(pa->dims) ) {
- if (pt.z > result->zmax) result->zmax = pt.z;
- if (pt.z < result->zmin) result->zmin = pt.z;
- }
- }
-
- LWDEBUG(3, "returning box");
-
- return 1;
-}
-
-/*
- * TODO: implement point interpolation
- */
-POINTARRAY *
-ptarray_substring(POINTARRAY *ipa, double from, double to)
-{
- DYNPTARRAY *dpa;
- POINTARRAY *opa;
- POINT4D pt;
- POINT4D p1, p2;
- POINT4D *p1ptr=&p1; /* don't break strict-aliasing rule */
- POINT4D *p2ptr=&p2;
- int nsegs, i;
- double length, slength, tlength;
- int state = 0; /* 0=before, 1=inside */
-
- /*
- * Create a dynamic pointarray with an initial capacity
- * equal to full copy of input points
- */
- dpa = dynptarray_create(ipa->npoints, ipa->dims);
-
- /* Compute total line length */
- length = lwgeom_pointarray_length2d(ipa);
-
-
- LWDEBUGF(3, "Total length: %g", length);
-
-
- /* Get 'from' and 'to' lengths */
- from = length*from;
- to = length*to;
-
-
- LWDEBUGF(3, "From/To: %g/%g", from, to);
-
-
- tlength = 0;
- getPoint4d_p(ipa, 0, &p1);
- nsegs = ipa->npoints - 1;
- for( i = 0; i < nsegs; i++ )
- {
- double dseg;
-
- getPoint4d_p(ipa, i+1, &p2);
-
-
- LWDEBUGF(3 ,"Segment %d: (%g,%g,%g,%g)-(%g,%g,%g,%g)",
- i, p1.x, p1.y, p1.z, p1.m, p2.x, p2.y, p2.z, p2.m);
-
-
- /* Find the length of this segment */
- slength = distance2d_pt_pt((POINT2D *)p1ptr, (POINT2D *)p2ptr);
-
- /*
- * We are before requested start.
- */
- if ( state == 0 ) /* before */
- {
-
- LWDEBUG(3, " Before start");
-
- /*
- * Didn't reach the 'from' point,
- * nothing to do
- */
- if ( from > tlength + slength ) goto END;
-
- else if ( from == tlength + slength )
- {
-
- LWDEBUG(3, " Second point is our start");
-
- /*
- * Second point is our start
- */
- dynptarray_addPoint4d(dpa, &p2, 1);
- state=1; /* we're inside now */
- goto END;
- }
-
- else if ( from == tlength )
- {
-
- LWDEBUG(3, " First point is our start");
-
- /*
- * First point is our start
- */
- dynptarray_addPoint4d(dpa, &p1, 1);
-
- /*
- * We're inside now, but will check
- * 'to' point as well
- */
- state=1;
- }
-
- else /* tlength < from < tlength+slength */
- {
-
- LWDEBUG(3, " Seg contains first point");
-
- /*
- * Our start is between first and
- * second point
- */
- dseg = (from - tlength) / slength;
- interpolate_point4d(&p1, &p2, &pt, dseg);
-
- dynptarray_addPoint4d(dpa, &pt, 1);
-
- /*
- * We're inside now, but will check
- * 'to' point as well
- */
- state=1;
- }
- }
-
- if ( state == 1 ) /* inside */
- {
-
- LWDEBUG(3, " Inside");
-
- /*
- * Didn't reach the 'end' point,
- * just copy second point
- */
- if ( to > tlength + slength )
- {
- dynptarray_addPoint4d(dpa, &p2, 0);
- goto END;
- }
-
- /*
- * 'to' point is our second point.
- */
- else if ( to == tlength + slength )
- {
-
- LWDEBUG(3, " Second point is our end");
-
- dynptarray_addPoint4d(dpa, &p2, 0);
- break; /* substring complete */
- }
-
- /*
- * 'to' point is our first point.
- * (should only happen if 'to' is 0)
- */
- else if ( to == tlength )
- {
-
- LWDEBUG(3, " First point is our end");
-
- dynptarray_addPoint4d(dpa, &p1, 0);
-
- break; /* substring complete */
- }
-
- /*
- * 'to' point falls on this segment
- * Interpolate and break.
- */
- else if ( to < tlength + slength )
- {
-
- LWDEBUG(3, " Seg contains our end");
-
- dseg = (to - tlength) / slength;
- interpolate_point4d(&p1, &p2, &pt, dseg);
-
- dynptarray_addPoint4d(dpa, &pt, 0);
-
- break;
- }
-
- else
- {
- LWDEBUG(3, "Unhandled case");
- }
- }
-
-
- END:
-
- tlength += slength;
- memcpy(&p1, &p2, sizeof(POINT4D));
- }
-
- /* Get constructed pointarray and release memory associated
- * with the dynamic pointarray
- */
- opa = dpa->pa;
- lwfree(dpa);
-
- LWDEBUGF(3, "Out of loop, ptarray has %d points", opa->npoints);
-
- return opa;
-}
-
-/*
- * Write into the *ret argument coordinates of the closes point on
- * the given segment to the reference input point.
- */
-void
-closest_point_on_segment(POINT2D *p, POINT2D *A, POINT2D *B, POINT2D *ret)
-{
- double r;
-
- if ( ( A->x == B->x) && (A->y == B->y) )
- {
- *ret = *A;
- return;
- }
-
- /*
- * We use comp.graphics.algorithms Frequently Asked Questions method
- *
- * (1) AC dot AB
- * r = ----------
- * ||AB||^2
- * r has the following meaning:
- * r=0 P = A
- * r=1 P = B
- * r<0 P is on the backward extension of AB
- * r>1 P is on the forward extension of AB
- * 0<r<1 P is interior to AB
- *
- */
- r = ( (p->x-A->x) * (B->x-A->x) + (p->y-A->y) * (B->y-A->y) )/( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
-
- if (r<0) {
- *ret = *A; return;
- }
- if (r>1) {
- *ret = *B;
- return;
- }
-
- ret->x = A->x + ( (B->x - A->x) * r );
- ret->y = A->y + ( (B->y - A->y) * r );
-}
-
-/*
- * Given a point, returns the location of closest point on pointarray
- */
-double
-ptarray_locate_point(POINTARRAY *pa, POINT2D *p)
-{
- double mindist=-1;
- double tlen, plen;
- int t, seg=-1;
- POINT2D start, end;
- POINT2D proj;
-
- getPoint2d_p(pa, 0, &start);
- for (t=1; t<pa->npoints; t++)
- {
- double dist;
- getPoint2d_p(pa, t, &end);
- dist = distance2d_pt_seg(p, &start, &end);
-
- if (t==1 || dist < mindist ) {
- mindist = dist;
- seg=t-1;
- }
-
- if ( mindist == 0 ) break;
-
- start = end;
- }
-
- LWDEBUGF(3, "Closest segment: %d", seg);
-
- /*
- * If mindist is not 0 we need to project the
- * point on the closest segment.
- */
- if ( mindist > 0 )
- {
- getPoint2d_p(pa, seg, &start);
- getPoint2d_p(pa, seg+1, &end);
- closest_point_on_segment(p, &start, &end, &proj);
- } else {
- proj = *p;
- }
-
- LWDEBUGF(3, "Closest point on segment: %g,%g", proj.x, proj.y);
-
- tlen = lwgeom_pointarray_length2d(pa);
-
- LWDEBUGF(3, "tlen %g", tlen);
-
- plen=0;
- getPoint2d_p(pa, 0, &start);
- for (t=0; t<seg; t++, start=end)
- {
- getPoint2d_p(pa, t+1, &end);
- plen += distance2d_pt_pt(&start, &end);
-
- LWDEBUGF(4, "Segment %d made plen %g", t, plen);
- }
-
- plen+=distance2d_pt_pt(&proj, &start);
-
- LWDEBUGF(3, "plen %g, tlen %g", plen, tlen);
- LWDEBUGF(3, "mindist: %g", mindist);
-
- return plen/tlen;
-}
-
-/*
- * Longitude shift for a pointarray.
- * Y remains the same
- * X is converted:
- * from -180..180 to 0..360
- * from 0..360 to -180..180
- * X < 0 becomes X + 360
- * X > 180 becomes X - 360
- */
-void
-ptarray_longitude_shift(POINTARRAY *pa)
-{
- int i;
- double x;
-
- for (i=0; i<pa->npoints; i++) {
- memcpy(&x, getPoint_internal(pa, i), sizeof(double));
- if ( x < 0 ) x+= 360;
- else if ( x > 180 ) x -= 360;
- memcpy(getPoint_internal(pa, i), &x, sizeof(double));
- }
-}
-
-DYNPTARRAY *
-dynptarray_create(size_t initial_capacity, int dims)
-{
- DYNPTARRAY *ret=lwalloc(sizeof(DYNPTARRAY));
-
- LWDEBUGF(3, "dynptarray_create called, dims=%d.", dims);
-
- if ( initial_capacity < 1 ) initial_capacity=1;
-
- ret->pa=lwalloc(sizeof(POINTARRAY));
- ret->pa->dims=dims;
- ret->ptsize=pointArray_ptsize(ret->pa);
- ret->capacity=initial_capacity;
- ret->pa->serialized_pointlist=lwalloc(ret->ptsize*ret->capacity);
- ret->pa->npoints=0;
-
- return ret;
-}
-
-/*
- * Add a POINT4D to the dynamic pointarray.
- *
- * The dynamic pointarray may be of any dimension, only
- * accepted dimensions will be copied.
- *
- * If allow_duplicates is set to 0 (false) a check
- * is performed to see if last point in array is equal to the
- * provided one. NOTE that the check is 4d based, with missing
- * ordinates in the pointarray set to NO_Z_VALUE and NO_M_VALUE
- * respectively.
- */
-int
-dynptarray_addPoint4d(DYNPTARRAY *dpa, POINT4D *p4d, int allow_duplicates)
-{
- POINTARRAY *pa=dpa->pa;
- POINT4D tmp;
-
- LWDEBUG(3, "dynptarray_addPoint4d called.");
-
- if ( ! allow_duplicates && pa->npoints > 0 )
- {
- getPoint4d_p(pa, pa->npoints-1, &tmp);
-
- /*
- * return 0 and do nothing else if previous point in list is
- * equal to this one (4D equality)
- */
- if ( ! memcmp(p4d, &tmp, sizeof(POINT4D)) ) return 0;
- }
-
- ++pa->npoints;
- if ( pa->npoints > dpa->capacity )
- {
- dpa->capacity*=2;
- pa->serialized_pointlist = lwrealloc(
- pa->serialized_pointlist,
- dpa->capacity*dpa->ptsize);
- }
-
- setPoint4d(pa, pa->npoints-1, p4d);
-
- return 1;
-}
-
Deleted: trunk/lwgeom/vsprintf.c
===================================================================
--- trunk/lwgeom/vsprintf.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/vsprintf.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,162 +0,0 @@
-/* Like vsprintf but provides a pointer to malloc'd storage, which must
- be freed by the caller.
- Copyright (C) 1994, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#if __STDC__
-# include <stdarg.h>
-#else
-# include <varargs.h>
-#endif
-
-#include <math.h>
-
-#ifdef TEST
-int global_total_width;
-#endif
-
-static int
-int_vasprintf (result, format, args)
- char **result;
- const char *format;
- va_list *args;
-{
- const char *p = format;
- /* Add one to make sure that it is never zero, which might cause malloc
- to return NULL. */
- int total_width = strlen (format) + 1;
- va_list ap;
-
- memcpy (&ap, args, sizeof (va_list));
-
- while (*p != '\0')
- {
- if (*p++ == '%')
- {
- while (strchr ("-+ #0", *p))
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- if (*p == '.')
- {
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- }
- while (strchr ("hlLjtz", *p))
- ++p;
- /* Should be big enough for any format specifier except %s
- and floats. */
- total_width += 30;
- switch (*p)
- {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'c':
- (void) va_arg (ap, int);
- break;
- case 'f':
- {
- double arg = va_arg (ap, double);
- if (arg >= 1.0 || arg <= -1.0)
- /* Since an ieee double can have an exponent of 307, we'll
- make the buffer wide enough to cover the gross case. */
- total_width += 307;
- }
- break;
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- (void) va_arg (ap, double);
- break;
- case 's':
- total_width += strlen (va_arg (ap, char *));
- break;
- case 'p':
- case 'n':
- (void) va_arg (ap, char *);
- break;
- }
- p++;
- }
- }
-#ifdef TEST
- global_total_width = total_width;
-#endif
- *result = malloc (total_width);
- if (*result != NULL)
- return vsprintf (*result, format, *args);
- else
- return 0;
-}
-
-int
-vasprintf (result, format, args)
- char **result;
- const char *format;
- va_list args;
-{
- return int_vasprintf (result, format, &args);
-}
-
-int
-asprintf
-#if __STDC__
- (char **result, const char *format, ...)
-#else
- (result, va_alist)
- char **result;
- va_dcl
-#endif
-{
- va_list args;
- int done;
-
-#if __STDC__
- va_start (args, format);
-#else
- char *format;
- va_start (args);
- format = va_arg (args, char *);
-#endif
- done = vasprintf (result, format, args);
- va_end (args);
-
- return done;
-}
Deleted: trunk/lwgeom/wktparse.h
===================================================================
--- trunk/lwgeom/wktparse.h 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/wktparse.h 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,106 +0,0 @@
-/*
- * Written by Ralph Mason ralph.mason<at>telogis.com
- *
- * Copyright Telogis 2004
- * www.telogis.com
- *
- */
-
-#ifndef _WKTPARSE_H
-#define _WKTPARSE_H
-
-#include <stdlib.h>
-
-
-#ifndef _LIBLWGEOM_H
-typedef unsigned char uchar;
-
-typedef struct serialized_lwgeom {
- uchar *lwgeom;
- int size;
-} SERIALIZED_LWGEOM;
-#endif
-typedef void* (*allocator)(size_t size);
-typedef void (*freeor)(void* mem);
-typedef void (*report_error)(const char* string, ...);
-
-/*typedef unsigned long int4;*/
-
-/* How much memory is allocated at a time(bytes) for tuples */
-#define ALLOC_CHUNKS 8192
-
-/* to shrink ints less than 0x7f to 1 byte */
-/* #define SHRINK_INTS */
-
-#define POINTTYPE 1
-#define LINETYPE 2
-#define POLYGONTYPE 3
-#define MULTIPOINTTYPE 4
-#define MULTILINETYPE 5
-#define MULTIPOLYGONTYPE 6
-#define COLLECTIONTYPE 7
-
-/* Extended lwgeom integer types */
-#define POINTTYPEI 10
-#define LINETYPEI 11
-#define POLYGONTYPEI 12
-
-#define CURVETYPE 8
-#define COMPOUNDTYPE 9
-#define CURVEPOLYTYPE 13
-#define MULTICURVETYPE 14
-#define MULTISURFACETYPE 15
-
-extern int srid;
-
-/*
-
- These functions are used by the
- generated parser and are not meant
- for public use
-
-*/
-
-void set_srid(double srid);
-void alloc_lwgeom(int srid);
-
-void alloc_point_2d(double x,double y);
-void alloc_point_3d(double x,double y,double z);
-void alloc_point_4d(double x,double y,double z,double m);
-
-void alloc_point(void);
-void alloc_linestring(void);
-void alloc_linestring_closed(void);
-void alloc_circularstring(void);
-void alloc_circularstring_closed(void);
-void alloc_polygon(void);
-void alloc_compoundcurve(void);
-void alloc_curvepolygon(void);
-void alloc_multipoint(void);
-void alloc_multilinestring(void);
-void alloc_multicurve(void);
-void alloc_multipolygon(void);
-void alloc_multisurface(void);
-void alloc_geomertycollection(void);
-void alloc_empty();
-void alloc_counter(void);
-
-
-void pop(void);
-void popc(void);
-
-void alloc_wkb(const char* parser);
-
-/*
- Use these functions to parse and unparse lwgeoms
- You are responsible for freeing the returned memory.
-*/
-
-SERIALIZED_LWGEOM* parse_lwg(const char* wkt,allocator allocfunc,report_error errfunc);
-SERIALIZED_LWGEOM* parse_lwgi(const char* wkt,allocator allocfunc,report_error errfunc);
-char* unparse_WKT(uchar* serialized, allocator alloc,freeor free);
-char* unparse_WKB(uchar* serialized, allocator alloc,freeor free, char endian, size_t *outsize, uchar hexform);
-int lwg_parse_yyparse(void);
-int lwg_parse_yyerror(char* s);
-
-#endif /* _WKTPARSE_H */
Deleted: trunk/lwgeom/wktparse.lex
===================================================================
--- trunk/lwgeom/wktparse.lex 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/wktparse.lex 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,71 +0,0 @@
-/*
- * Written by Ralph Mason ralph.mason<at>telogis.com
- *
- * Copyright Telogis 2004
- * www.telogis.com
- *
- */
-
-%x vals_ok
-%{
-#include "wktparse.tab.h"
-#include <unistd.h>
-#include <stdlib.h> // need stdlib for atof() definition
-
-void init_parser(const char *src);
-void close_parser(void);
-int lwg_parse_yywrap(void);
-int lwg_parse_yylex(void);
-
-static YY_BUFFER_STATE buf_state;
- void init_parser(const char *src) { BEGIN(0);buf_state = lwg_parse_yy_scan_string(src); }
- void close_parser() { lwg_parse_yy_delete_buffer(buf_state); }
- int lwg_parse_yywrap(void){ return 1; }
-
-%}
-
-%%
-
-<vals_ok>[-|\+]?[0-9]+(\.[0-9]+)?([Ee](\+|-)?[0-9]+)? { lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
-<vals_ok>[-|\+]?(\.[0-9]+)([Ee](\+|-)?[0-9]+)? { lwg_parse_yylval.value=atof(lwg_parse_yytext); return VALUE; }
-
-<INITIAL>00[0-9A-F]* { lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
-<INITIAL>01[0-9A-F]* { lwg_parse_yylval.wkb=lwg_parse_yytext; return WKB;}
-
-<*>POINT { return POINT; }
-<*>POINTM { return POINTM; }
-<*>LINESTRING { return LINESTRING; }
-<*>LINESTRINGM { return LINESTRINGM; }
-<*>CIRCULARSTRING { return CIRCULARSTRING; }
-<*>CIRCULARSTRINGM { return CIRCULARSTRINGM; }
-<*>POLYGON { return POLYGON; }
-<*>POLYGONM { return POLYGONM; }
-<*>COMPOUNDCURVE { return COMPOUNDCURVE; }
-<*>COMPOUNDCURVEM { return COMPOUNDCURVEM; }
-<*>CURVEPOLYGON { return CURVEPOLYGON; }
-<*>CURVEPOLYGONM { return CURVEPOLYGONM; }
-<*>MULTIPOINT { return MULTIPOINT; }
-<*>MULTIPOINTM { return MULTIPOINTM; }
-<*>MULTILINESTRING { return MULTILINESTRING; }
-<*>MULTILINESTRINGM { return MULTILINESTRINGM; }
-<*>MULTICURVE { return MULTICURVE; }
-<*>MULTICURVEM { return MULTICURVEM; }
-<*>MULTIPOLYGON { return MULTIPOLYGON; }
-<*>MULTIPOLYGONM { return MULTIPOLYGONM; }
-<*>MULTISURFACE { return MULTISURFACE; }
-<*>MULTISURFACEM { return MULTISURFACEM; }
-<*>GEOMETRYCOLLECTION { return GEOMETRYCOLLECTION; }
-<*>GEOMETRYCOLLECTIONM { return GEOMETRYCOLLECTIONM; }
-<*>SRID { BEGIN(vals_ok); return SRID; }
-<*>EMPTY { return EMPTY; }
-
-<*>\( { BEGIN(vals_ok); return LPAREN; }
-<*>\) { return RPAREN; }
-<*>, { return COMMA ; }
-<*>= { return EQUALS ; }
-<*>; { BEGIN(0); return SEMICOLON; }
-<*>[ \t\n\r]+ /*eat whitespace*/
-<*>. { return lwg_parse_yytext[0]; }
-
-%%
-
Deleted: trunk/lwgeom/wktparse.tab.c
===================================================================
--- trunk/lwgeom/wktparse.tab.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/wktparse.tab.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,1991 +0,0 @@
-/* A Bison parser, made by GNU Bison 1.875c. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* Written by Richard Stallman by simplifying the original so called
- ``semantic'' parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 0
-
-/* Using locations. */
-#define YYLSP_NEEDED 0
-
-/* If NAME_PREFIX is specified substitute the variables and functions
- names. */
-#define yyparse lwg_parse_yyparse
-#define yylex lwg_parse_yylex
-#define yyerror lwg_parse_yyerror
-#define yylval lwg_parse_yylval
-#define yychar lwg_parse_yychar
-#define yydebug lwg_parse_yydebug
-#define yynerrs lwg_parse_yynerrs
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- POINT = 258,
- LINESTRING = 259,
- POLYGON = 260,
- MULTIPOINT = 261,
- MULTILINESTRING = 262,
- MULTIPOLYGON = 263,
- GEOMETRYCOLLECTION = 264,
- CIRCULARSTRING = 265,
- COMPOUNDCURVE = 266,
- CURVEPOLYGON = 267,
- MULTICURVE = 268,
- MULTISURFACE = 269,
- POINTM = 270,
- LINESTRINGM = 271,
- POLYGONM = 272,
- MULTIPOINTM = 273,
- MULTILINESTRINGM = 274,
- MULTIPOLYGONM = 275,
- GEOMETRYCOLLECTIONM = 276,
- CIRCULARSTRINGM = 277,
- COMPOUNDCURVEM = 278,
- CURVEPOLYGONM = 279,
- MULTICURVEM = 280,
- MULTISURFACEM = 281,
- SRID = 282,
- EMPTY = 283,
- VALUE = 284,
- LPAREN = 285,
- RPAREN = 286,
- COMMA = 287,
- EQUALS = 288,
- SEMICOLON = 289,
- WKB = 290
- };
-#endif
-#define POINT 258
-#define LINESTRING 259
-#define POLYGON 260
-#define MULTIPOINT 261
-#define MULTILINESTRING 262
-#define MULTIPOLYGON 263
-#define GEOMETRYCOLLECTION 264
-#define CIRCULARSTRING 265
-#define COMPOUNDCURVE 266
-#define CURVEPOLYGON 267
-#define MULTICURVE 268
-#define MULTISURFACE 269
-#define POINTM 270
-#define LINESTRINGM 271
-#define POLYGONM 272
-#define MULTIPOINTM 273
-#define MULTILINESTRINGM 274
-#define MULTIPOLYGONM 275
-#define GEOMETRYCOLLECTIONM 276
-#define CIRCULARSTRINGM 277
-#define COMPOUNDCURVEM 278
-#define CURVEPOLYGONM 279
-#define MULTICURVEM 280
-#define MULTISURFACEM 281
-#define SRID 282
-#define EMPTY 283
-#define VALUE 284
-#define LPAREN 285
-#define RPAREN 286
-#define COMMA 287
-#define EQUALS 288
-#define SEMICOLON 289
-#define WKB 290
-
-
-
-
-/* Copy the first part of user declarations. */
-#line 9 "wktparse.y"
-
-#include "wktparse.h"
-#include <unistd.h>
-#include <stdio.h>
-
-void set_zm(char z, char m);
-int lwg_parse_yylex(void);
-
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 20 "wktparse.y"
-typedef union YYSTYPE {
- double value;
- const char* wkb;
-} YYSTYPE;
-/* Line 191 of yacc.c. */
-#line 169 "y.tab.c"
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-/* Copy the second part of user declarations. */
-
-
-/* Line 214 of yacc.c. */
-#line 181 "y.tab.c"
-
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
-
-# ifndef YYFREE
-# define YYFREE free
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# endif
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
-# endif
-# else
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
-# else
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# endif
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
-
-
-#if (! defined (yyoverflow) \
- && (! defined (__cplusplus) \
- || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- short yyss;
- YYSTYPE yyvs;
- };
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
- + YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined (__GNUC__) && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- register YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (0)
-# endif
-# endif
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack, Stack, yysize); \
- Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (0)
-
-#endif
-
-#if defined (__STDC__) || defined (__cplusplus)
- typedef signed char yysigned_char;
-#else
- typedef short yysigned_char;
-#endif
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 6
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 180
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 36
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 107
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 169
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 237
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 290
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const unsigned char yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const unsigned short yyprhs[] =
-{
- 0, 0, 3, 4, 9, 10, 13, 15, 17, 19,
- 21, 23, 25, 27, 29, 31, 33, 35, 37, 39,
- 43, 45, 48, 49, 53, 55, 57, 58, 61, 62,
- 65, 69, 70, 74, 75, 79, 81, 82, 87, 89,
- 93, 95, 96, 99, 102, 103, 107, 109, 111, 112,
- 115, 116, 119, 120, 123, 124, 129, 131, 135, 138,
- 139, 143, 146, 147, 151, 153, 155, 157, 159, 160,
- 163, 164, 167, 168, 171, 172, 177, 179, 183, 184,
- 188, 189, 193, 195, 196, 201, 203, 205, 209, 213,
- 214, 218, 219, 223, 225, 226, 231, 233, 237, 238,
- 242, 243, 247, 249, 250, 255, 257, 259, 263, 267,
- 270, 271, 275, 277, 279, 280, 283, 284, 287, 288,
- 293, 295, 299, 300, 304, 305, 309, 311, 312, 317,
- 319, 321, 325, 329, 330, 334, 335, 339, 341, 342,
- 347, 349, 353, 354, 358, 359, 363, 365, 366, 371,
- 373, 375, 379, 383, 384, 388, 389, 393, 395, 396,
- 401, 403, 405, 409, 411, 413, 415, 418, 422, 427
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const short yyrhs[] =
-{
- 37, 0, -1, -1, 41, 34, 38, 40, -1, -1,
- 39, 40, -1, 42, -1, 43, -1, 59, -1, 71,
- -1, 104, -1, 86, -1, 114, -1, 51, -1, 92,
- -1, 98, -1, 120, -1, 126, -1, 132, -1, 27,
- 33, 29, -1, 35, -1, 3, 45, -1, -1, 15,
- 44, 45, -1, 46, -1, 48, -1, -1, 47, 142,
- -1, -1, 49, 50, -1, 30, 138, 31, -1, -1,
- 6, 52, 54, -1, -1, 18, 53, 54, -1, 142,
- -1, -1, 55, 30, 56, 31, -1, 57, -1, 56,
- 32, 57, -1, 48, -1, -1, 58, 138, -1, 4,
- 61, -1, -1, 16, 60, 61, -1, 62, -1, 64,
- -1, -1, 63, 142, -1, -1, 65, 68, -1, -1,
- 67, 68, -1, -1, 69, 30, 70, 31, -1, 138,
- -1, 70, 32, 138, -1, 10, 75, -1, -1, 22,
- 72, 75, -1, 10, 76, -1, -1, 22, 74, 76,
- -1, 77, -1, 79, -1, 77, -1, 81, -1, -1,
- 78, 142, -1, -1, 80, 83, -1, -1, 82, 83,
- -1, -1, 84, 30, 85, 31, -1, 138, -1, 85,
- 32, 138, -1, -1, 11, 87, 89, -1, -1, 23,
- 88, 89, -1, 142, -1, -1, 90, 30, 91, 31,
- -1, 64, -1, 71, -1, 91, 32, 64, -1, 91,
- 32, 71, -1, -1, 7, 93, 95, -1, -1, 19,
- 94, 95, -1, 142, -1, -1, 96, 30, 97, 31,
- -1, 64, -1, 97, 32, 64, -1, -1, 13, 99,
- 101, -1, -1, 25, 100, 101, -1, 142, -1, -1,
- 102, 30, 103, 31, -1, 64, -1, 71, -1, 103,
- 32, 64, -1, 103, 32, 71, -1, 5, 106, -1,
- -1, 17, 105, 106, -1, 107, -1, 109, -1, -1,
- 108, 142, -1, -1, 110, 111, -1, -1, 112, 30,
- 113, 31, -1, 68, -1, 113, 32, 68, -1, -1,
- 12, 115, 117, -1, -1, 24, 116, 117, -1, 142,
- -1, -1, 118, 30, 119, 31, -1, 66, -1, 73,
- -1, 119, 32, 66, -1, 119, 32, 73, -1, -1,
- 8, 121, 123, -1, -1, 20, 122, 123, -1, 142,
- -1, -1, 124, 30, 125, 31, -1, 109, -1, 125,
- 32, 109, -1, -1, 14, 127, 129, -1, -1, 26,
- 128, 129, -1, 142, -1, -1, 130, 30, 131, 31,
- -1, 109, -1, 114, -1, 131, 32, 109, -1, 131,
- 32, 114, -1, -1, 9, 133, 135, -1, -1, 21,
- 134, 135, -1, 142, -1, -1, 136, 30, 137, 31,
- -1, 142, -1, 40, -1, 137, 32, 40, -1, 139,
- -1, 140, -1, 141, -1, 29, 29, -1, 29, 29,
- 29, -1, 29, 29, 29, 29, -1, 28, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short yyrline[] =
-{
- 0, 36, 36, 36, 38, 38, 41, 43, 45, 47,
- 49, 51, 53, 55, 57, 59, 61, 63, 65, 68,
- 71, 77, 79, 79, 82, 84, 87, 87, 90, 90,
- 93, 98, 98, 100, 100, 103, 105, 105, 108, 110,
- 113, 116, 116, 122, 124, 124, 127, 129, 132, 132,
- 135, 135, 138, 138, 141, 141, 144, 146, 151, 153,
- 153, 156, 158, 158, 161, 163, 166, 168, 171, 171,
- 174, 174, 177, 177, 180, 180, 183, 185, 190, 190,
- 192, 192, 195, 197, 197, 200, 202, 204, 206, 211,
- 211, 214, 214, 218, 220, 220, 223, 225, 230, 230,
- 233, 233, 237, 239, 239, 242, 244, 246, 248, 253,
- 255, 255, 258, 260, 263, 263, 266, 266, 269, 269,
- 272, 274, 279, 279, 281, 281, 285, 287, 287, 290,
- 292, 294, 296, 301, 301, 303, 303, 307, 309, 309,
- 312, 314, 319, 319, 321, 321, 325, 327, 327, 330,
- 332, 334, 336, 341, 341, 344, 344, 348, 350, 350,
- 354, 356, 358, 362, 364, 366, 369, 372, 375, 378
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE
-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "POINT", "LINESTRING", "POLYGON",
- "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", "GEOMETRYCOLLECTION",
- "CIRCULARSTRING", "COMPOUNDCURVE", "CURVEPOLYGON", "MULTICURVE",
- "MULTISURFACE", "POINTM", "LINESTRINGM", "POLYGONM", "MULTIPOINTM",
- "MULTILINESTRINGM", "MULTIPOLYGONM", "GEOMETRYCOLLECTIONM",
- "CIRCULARSTRINGM", "COMPOUNDCURVEM", "CURVEPOLYGONM", "MULTICURVEM",
- "MULTISURFACEM", "SRID", "EMPTY", "VALUE", "LPAREN", "RPAREN", "COMMA",
- "EQUALS", "SEMICOLON", "WKB", "$accept", "geometry", "@1", "@2",
- "geometry_int", "srid", "geom_wkb", "geom_point", "@3", "point",
- "empty_point", "@4", "nonempty_point", "@5", "point_int",
- "geom_multipoint", "@6", "@7", "multipoint", "@8", "multipoint_int",
- "mpoint_element", "@9", "geom_linestring", "@10", "linestring",
- "empty_linestring", "@11", "nonempty_linestring", "@12",
- "nonempty_linestring_closed", "@13", "linestring_1", "@14",
- "linestring_int", "geom_circularstring", "@15",
- "geom_circularstring_closed", "@16", "circularstring",
- "circularstring_closed", "empty_circularstring", "@17",
- "nonempty_circularstring", "@18", "nonempty_circularstring_closed",
- "@19", "circularstring_1", "@20", "circularstring_int",
- "geom_compoundcurve", "@21", "@22", "compoundcurve", "@23",
- "compoundcurve_int", "geom_multilinestring", "@24", "@25",
- "multilinestring", "@26", "multilinestring_int", "geom_multicurve",
- "@27", "@28", "multicurve", "@29", "multicurve_int", "geom_polygon",
- "@30", "polygon", "empty_polygon", "@31", "nonempty_polygon", "@32",
- "polygon_1", "@33", "polygon_int", "geom_curvepolygon", "@34", "@35",
- "curvepolygon", "@36", "curvepolygon_int", "geom_multipolygon", "@37",
- "@38", "multipolygon", "@39", "multipolygon_int", "geom_multisurface",
- "@40", "@41", "multisurface", "@42", "multisurface_int",
- "geom_geometrycollection", "@43", "@44", "geometrycollection", "@45",
- "geometrycollection_int", "a_point", "point_2d", "point_3d", "point_4d",
- "empty", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const unsigned short yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const unsigned char yyr1[] =
-{
- 0, 36, 38, 37, 39, 37, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 41,
- 42, 43, 44, 43, 45, 45, 47, 46, 49, 48,
- 50, 52, 51, 53, 51, 54, 55, 54, 56, 56,
- 57, 58, 57, 59, 60, 59, 61, 61, 63, 62,
- 65, 64, 67, 66, 69, 68, 70, 70, 71, 72,
- 71, 73, 74, 73, 75, 75, 76, 76, 78, 77,
- 80, 79, 82, 81, 84, 83, 85, 85, 87, 86,
- 88, 86, 89, 90, 89, 91, 91, 91, 91, 93,
- 92, 94, 92, 95, 96, 95, 97, 97, 99, 98,
- 100, 98, 101, 102, 101, 103, 103, 103, 103, 104,
- 105, 104, 106, 106, 108, 107, 110, 109, 112, 111,
- 113, 113, 115, 114, 116, 114, 117, 118, 117, 119,
- 119, 119, 119, 121, 120, 122, 120, 123, 124, 123,
- 125, 125, 127, 126, 128, 126, 129, 130, 129, 131,
- 131, 131, 131, 133, 132, 134, 132, 135, 136, 135,
- 137, 137, 137, 138, 138, 138, 139, 140, 141, 142
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const unsigned char yyr2[] =
-{
- 0, 2, 0, 4, 0, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
- 1, 2, 0, 3, 1, 1, 0, 2, 0, 2,
- 3, 0, 3, 0, 3, 1, 0, 4, 1, 3,
- 1, 0, 2, 2, 0, 3, 1, 1, 0, 2,
- 0, 2, 0, 2, 0, 4, 1, 3, 2, 0,
- 3, 2, 0, 3, 1, 1, 1, 1, 0, 2,
- 0, 2, 0, 2, 0, 4, 1, 3, 0, 3,
- 0, 3, 1, 0, 4, 1, 1, 3, 3, 0,
- 3, 0, 3, 1, 0, 4, 1, 3, 0, 3,
- 0, 3, 1, 0, 4, 1, 1, 3, 3, 2,
- 0, 3, 1, 1, 0, 2, 0, 2, 0, 4,
- 1, 3, 0, 3, 0, 3, 1, 0, 4, 1,
- 1, 3, 3, 0, 3, 0, 3, 1, 0, 4,
- 1, 3, 0, 3, 0, 3, 1, 0, 4, 1,
- 1, 3, 3, 0, 3, 0, 3, 1, 0, 4,
- 1, 1, 3, 1, 1, 1, 2, 3, 4, 1
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const unsigned char yydefact[] =
-{
- 4, 0, 0, 0, 0, 0, 1, 26, 48, 114,
- 31, 89, 133, 153, 68, 78, 122, 98, 142, 22,
- 44, 110, 33, 91, 135, 155, 59, 80, 124, 100,
- 144, 20, 5, 6, 7, 13, 8, 9, 11, 14,
- 15, 10, 12, 16, 17, 18, 2, 19, 21, 24,
- 0, 25, 0, 43, 46, 0, 47, 54, 109, 112,
- 0, 113, 118, 36, 94, 138, 158, 58, 64, 0,
- 65, 74, 83, 127, 103, 147, 26, 48, 114, 36,
- 94, 138, 158, 68, 83, 127, 103, 147, 0, 169,
- 27, 0, 29, 49, 51, 0, 115, 117, 0, 32,
- 0, 35, 90, 0, 93, 134, 0, 137, 154, 0,
- 157, 69, 71, 0, 79, 0, 82, 123, 0, 126,
- 99, 0, 102, 143, 0, 146, 23, 45, 111, 34,
- 92, 136, 156, 60, 81, 125, 101, 145, 3, 0,
- 0, 163, 164, 165, 0, 54, 28, 50, 116, 0,
- 0, 50, 52, 50, 116, 166, 30, 0, 56, 120,
- 0, 40, 0, 38, 0, 96, 0, 140, 0, 161,
- 0, 160, 0, 76, 85, 86, 0, 68, 62, 129,
- 54, 130, 0, 105, 106, 0, 149, 150, 0, 167,
- 55, 0, 119, 54, 37, 28, 42, 95, 50, 139,
- 116, 159, 0, 75, 0, 84, 50, 61, 66, 67,
- 74, 68, 53, 128, 52, 104, 50, 148, 116, 168,
- 57, 121, 39, 97, 141, 162, 77, 87, 88, 73,
- 63, 131, 132, 107, 108, 151, 152
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const short yydefgoto[] =
-{
- -1, 2, 88, 3, 32, 4, 33, 34, 76, 48,
- 49, 50, 51, 52, 92, 35, 63, 79, 99, 100,
- 162, 163, 164, 36, 77, 53, 54, 55, 56, 57,
- 179, 180, 94, 95, 157, 37, 83, 181, 211, 67,
- 207, 68, 69, 70, 71, 209, 210, 112, 113, 172,
- 38, 72, 84, 114, 115, 176, 39, 64, 80, 102,
- 103, 166, 40, 74, 86, 120, 121, 185, 41, 78,
- 58, 59, 60, 61, 62, 97, 98, 160, 42, 73,
- 85, 117, 118, 182, 43, 65, 81, 105, 106, 168,
- 44, 75, 87, 123, 124, 188, 45, 66, 82, 108,
- 109, 170, 140, 141, 142, 143, 101
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -166
-static const short yypact[] =
-{
- -17, -14, 21, 145, -7, 5, -166, 29, 30, 40,
- -166, -166, -166, -166, 51, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- 23, -166, 53, -166, -166, 23, -166, -166, -166, -166,
- 23, -166, -166, 23, 23, 23, 23, -166, -166, 23,
- -166, -166, 23, 23, 23, 23, 29, 30, 40, 23,
- 23, 23, 23, 51, 23, 23, 23, 23, 145, -166,
- -166, 55, -166, -166, -166, 56, -166, -166, 57, -166,
- 58, -166, -166, 59, -166, -166, 61, -166, -166, 62,
- -166, -166, -166, 63, -166, 64, -166, -166, 65, -166,
- -166, 66, -166, -166, 67, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, 70,
- 54, -166, -166, -166, 55, -166, 72, -166, -166, 112,
- 55, 8, 19, 8, 28, 73, -166, -18, -166, -166,
- 16, -166, 18, -166, 55, -166, 24, -166, 31, -166,
- 33, -166, 35, -166, -166, -166, 42, 74, -166, -166,
- -166, -166, 44, -166, -166, 46, -166, -166, 48, 76,
- -166, 55, -166, -166, -166, 72, -166, -166, -166, -166,
- -166, -166, 145, -166, 55, -166, 8, -166, -166, -166,
- -166, 74, -166, -166, 19, -166, 8, -166, 28, -166,
- -166, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, -166, -166, -166, -166
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const short yypgoto[] =
-{
- -166, -166, -166, -166, -88, -166, -166, -166, -166, 27,
- -166, -166, -142, -166, -166, -166, -166, -166, 32, -166,
- -166, -89, -166, -166, -166, 36, -166, -166, -108, -166,
- -107, -166, -136, -166, -166, -148, -166, -105, -166, 60,
- -101, -165, -166, -166, -166, -166, -166, -98, -166, -166,
- -166, -166, -166, 88, -166, -166, -166, -166, -166, 93,
- -166, -166, -166, -166, -166, 89, -166, -166, -166, -166,
- 68, -166, -166, -146, -166, -166, -166, -166, -147, -166,
- -166, 91, -166, -166, -166, -166, -166, 96, -166, -166,
- -166, -166, -166, 52, -166, -166, -166, -166, -166, 92,
- -166, -166, -122, -166, -166, -166, -49
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -117
-static const short yytable[] =
-{
- 138, 90, 167, 175, 161, 184, 93, 187, 186, 159,
- 1, 96, 208, 190, 191, 104, 107, 110, 14, 5,
- 111, 6, 158, 116, 119, 122, 125, 46, 173, 177,
- 26, 104, 107, 110, 47, 116, 119, 122, 125, 165,
- 16, 178, 196, 174, 212, 183, 208, 192, 193, 194,
- 195, 89, 28, 161, 224, 197, 198, 221, 228, -28,
- -50, 169, 199, 200, 201, 202, 203, 204, 234, 220,
- -116, 236, 235, 205, 206, 213, 214, 215, 216, 217,
- 218, -70, 226, 91, 139, 156, 144, 145, 146, 147,
- 223, 148, 149, 150, 151, 152, 153, 154, 227, 155,
- 171, -41, 189, 126, -72, 219, 222, 231, 233, 232,
- 230, 129, 229, 127, 225, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 137,
- 89, 0, 0, 133, 0, 0, 128, 31, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 134, 130, 132, 136, 135, 131, 0, 0,
- 31
-};
-
-static const short yycheck[] =
-{
- 88, 50, 148, 151, 146, 153, 55, 154, 154, 145,
- 27, 60, 177, 31, 32, 64, 65, 66, 10, 33,
- 69, 0, 144, 72, 73, 74, 75, 34, 150, 10,
- 22, 80, 81, 82, 29, 84, 85, 86, 87, 147,
- 12, 22, 164, 151, 180, 153, 211, 31, 32, 31,
- 32, 28, 24, 195, 200, 31, 32, 193, 206, 30,
- 30, 149, 31, 32, 31, 32, 31, 32, 216, 191,
- 30, 218, 218, 31, 32, 31, 32, 31, 32, 31,
- 32, 30, 204, 30, 29, 31, 30, 30, 30, 30,
- 198, 30, 30, 30, 30, 30, 30, 30, 206, 29,
- 149, 29, 29, 76, 30, 29, 195, 214, 216, 214,
- 211, 79, 210, 77, 202, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 87,
- 28, -1, -1, 83, -1, -1, 78, 35, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 84, 80, 82, 86, 85, 81, -1, -1,
- 35
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const unsigned char yystos[] =
-{
- 0, 27, 37, 39, 41, 33, 0, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 35, 40, 42, 43, 51, 59, 71, 86, 92,
- 98, 104, 114, 120, 126, 132, 34, 29, 45, 46,
- 47, 48, 49, 61, 62, 63, 64, 65, 106, 107,
- 108, 109, 110, 52, 93, 121, 133, 75, 77, 78,
- 79, 80, 87, 115, 99, 127, 44, 60, 105, 53,
- 94, 122, 134, 72, 88, 116, 100, 128, 38, 28,
- 142, 30, 50, 142, 68, 69, 142, 111, 112, 54,
- 55, 142, 95, 96, 142, 123, 124, 142, 135, 136,
- 142, 142, 83, 84, 89, 90, 142, 117, 118, 142,
- 101, 102, 142, 129, 130, 142, 45, 61, 106, 54,
- 95, 123, 135, 75, 89, 117, 101, 129, 40, 29,
- 138, 139, 140, 141, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 29, 31, 70, 138, 68,
- 113, 48, 56, 57, 58, 64, 97, 109, 125, 40,
- 137, 142, 85, 138, 64, 71, 91, 10, 22, 66,
- 67, 73, 119, 64, 71, 103, 109, 114, 131, 29,
- 31, 32, 31, 32, 31, 32, 138, 31, 32, 31,
- 32, 31, 32, 31, 32, 31, 32, 76, 77, 81,
- 82, 74, 68, 31, 32, 31, 32, 31, 32, 29,
- 138, 68, 57, 64, 109, 40, 138, 64, 71, 83,
- 76, 66, 73, 64, 71, 109, 114
-};
-
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
-#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
-#endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# endif
-#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
-#endif
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-
-#define YYFAIL goto yyerrlab
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror ("syntax error: cannot back up");\
- YYERROR; \
- } \
-while (0)
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run). */
-
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- ((Current).first_line = (Rhs)[1].first_line, \
- (Current).first_column = (Rhs)[1].first_column, \
- (Current).last_line = (Rhs)[N].last_line, \
- (Current).last_column = (Rhs)[N].last_column)
-#endif
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (YYLEX_PARAM)
-#else
-# define YYLEX yylex ()
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (0)
-
-# define YYDSYMPRINT(Args) \
-do { \
- if (yydebug) \
- yysymprint Args; \
-} while (0)
-
-# define YYDSYMPRINTF(Title, Token, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yysymprint (stderr, \
- Token, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (0)
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yy_stack_print (short *bottom, short *top)
-#else
-static void
-yy_stack_print (bottom, top)
- short *bottom;
- short *top;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (/* Nothing. */; bottom <= top; ++bottom)
- YYFPRINTF (stderr, " %d", *bottom);
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (0)
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yy_reduce_print (int yyrule)
-#else
-static void
-yy_reduce_print (yyrule)
- int yyrule;
-#endif
-{
- int yyi;
- unsigned int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
- yyrule - 1, yylno);
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
- YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
- YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (Rule); \
-} while (0)
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YYDSYMPRINT(Args)
-# define YYDSYMPRINTF(Title, Token, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined (__GLIBC__) && defined (_STRING_H)
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-static YYSIZE_T
-# if defined (__STDC__) || defined (__cplusplus)
-yystrlen (const char *yystr)
-# else
-yystrlen (yystr)
- const char *yystr;
-# endif
-{
- register const char *yys = yystr;
-
- while (*yys++ != '\0')
- continue;
-
- return yys - yystr - 1;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-static char *
-# if defined (__STDC__) || defined (__cplusplus)
-yystpcpy (char *yydest, const char *yysrc)
-# else
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-# endif
-{
- register char *yyd = yydest;
- register const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-#endif /* !YYERROR_VERBOSE */
-
-
-
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yysymprint (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
-{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
-
- if (yytype < YYNTOKENS)
- {
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-# ifdef YYPRINT
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- }
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- switch (yytype)
- {
- default:
- break;
- }
- YYFPRINTF (yyoutput, ")");
-}
-
-#endif /* ! YYDEBUG */
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yytype, yyvaluep)
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
-{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
-
- switch (yytype)
- {
-
- default:
- break;
- }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes. */
-
-#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM);
-# else
-int yyparse ();
-# endif
-#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-/* The lookahead symbol. */
-int yychar;
-
-/* The semantic value of the lookahead symbol. */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far. */
-int yynerrs;
-
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-# endif
-#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
-
- register int yystate;
- register int yyn;
- int yyresult;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken = 0;
-
- /* Three stacks and their tools:
- `yyss': related to states,
- `yyvs': related to semantic values,
- `yyls': related to locations.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- short yyssa[YYINITDEPTH];
- short *yyss = yyssa;
- register short *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- register YYSTYPE *yyvsp;
-
-
-
-#define YYPOPSTACK (yyvsp--, yyssp--)
-
- YYSIZE_T yystacksize = YYINITDEPTH;
-
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
-
- /* When reducing, the number of symbols on the RHS of the reduced
- rule. */
- int yylen;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss;
- yyvsp = yyvs;
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks.
- */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
-
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow ("parser stack overflow",
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
-
- &yystacksize);
-
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyoverflowlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyoverflowlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- short *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyoverflowlab;
- YYSTACK_RELOCATE (yyss);
- YYSTACK_RELOCATE (yyvs);
-
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
-
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
-/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
-/* yyresume: */
-
- /* First try to decide what to do without reference to lookahead token. */
-
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Shift the lookahead token. */
- YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
-
- /* Discard the token being shifted unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- *++yyvsp = yylval;
-
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
-
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 2:
-#line 36 "wktparse.y"
- { alloc_lwgeom(srid); }
- break;
-
- case 4:
-#line 38 "wktparse.y"
- { alloc_lwgeom(-1); }
- break;
-
- case 19:
-#line 68 "wktparse.y"
- { set_srid(yyvsp[0].value); }
- break;
-
- case 20:
-#line 71 "wktparse.y"
- { alloc_wkb(yyvsp[0].wkb); }
- break;
-
- case 22:
-#line 79 "wktparse.y"
- { set_zm(0, 1); }
- break;
-
- case 26:
-#line 87 "wktparse.y"
- { alloc_point(); }
- break;
-
- case 27:
-#line 87 "wktparse.y"
- { pop(); }
- break;
-
- case 28:
-#line 90 "wktparse.y"
- { alloc_point(); }
- break;
-
- case 29:
-#line 90 "wktparse.y"
- { pop(); }
- break;
-
- case 31:
-#line 98 "wktparse.y"
- { alloc_multipoint(); }
- break;
-
- case 32:
-#line 98 "wktparse.y"
- { pop(); }
- break;
-
- case 33:
-#line 100 "wktparse.y"
- { set_zm(0, 1); alloc_multipoint(); }
- break;
-
- case 34:
-#line 100 "wktparse.y"
- {pop(); }
- break;
-
- case 36:
-#line 105 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 37:
-#line 105 "wktparse.y"
- { pop(); }
- break;
-
- case 41:
-#line 116 "wktparse.y"
- { alloc_point(); }
- break;
-
- case 42:
-#line 116 "wktparse.y"
- { pop(); }
- break;
-
- case 44:
-#line 124 "wktparse.y"
- { set_zm(0, 1); }
- break;
-
- case 48:
-#line 132 "wktparse.y"
- { alloc_linestring(); }
- break;
-
- case 49:
-#line 132 "wktparse.y"
- { pop(); }
- break;
-
- case 50:
-#line 135 "wktparse.y"
- { alloc_linestring(); }
- break;
-
- case 51:
-#line 135 "wktparse.y"
- { pop(); }
- break;
-
- case 52:
-#line 138 "wktparse.y"
- { alloc_linestring_closed(); }
- break;
-
- case 53:
-#line 138 "wktparse.y"
- { pop(); }
- break;
-
- case 54:
-#line 141 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 55:
-#line 141 "wktparse.y"
- { popc(); }
- break;
-
- case 59:
-#line 153 "wktparse.y"
- {set_zm(0, 1); }
- break;
-
- case 62:
-#line 158 "wktparse.y"
- {set_zm(0, 1); }
- break;
-
- case 68:
-#line 171 "wktparse.y"
- { alloc_circularstring(); }
- break;
-
- case 69:
-#line 171 "wktparse.y"
- { pop(); }
- break;
-
- case 70:
-#line 174 "wktparse.y"
- { alloc_circularstring(); }
- break;
-
- case 71:
-#line 174 "wktparse.y"
- { pop(); }
- break;
-
- case 72:
-#line 177 "wktparse.y"
- { alloc_circularstring_closed(); }
- break;
-
- case 73:
-#line 177 "wktparse.y"
- { pop(); }
- break;
-
- case 74:
-#line 180 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 75:
-#line 180 "wktparse.y"
- { popc(); }
- break;
-
- case 78:
-#line 190 "wktparse.y"
- { alloc_compoundcurve(); }
- break;
-
- case 79:
-#line 190 "wktparse.y"
- { pop(); }
- break;
-
- case 80:
-#line 192 "wktparse.y"
- {set_zm(0, 1); alloc_compoundcurve(); }
- break;
-
- case 81:
-#line 192 "wktparse.y"
- { pop(); }
- break;
-
- case 83:
-#line 197 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 84:
-#line 197 "wktparse.y"
- { pop(); }
- break;
-
- case 89:
-#line 211 "wktparse.y"
- { alloc_multilinestring(); }
- break;
-
- case 90:
-#line 212 "wktparse.y"
- { pop(); }
- break;
-
- case 91:
-#line 214 "wktparse.y"
- { set_zm(0, 1); alloc_multilinestring(); }
- break;
-
- case 92:
-#line 215 "wktparse.y"
- { pop(); }
- break;
-
- case 94:
-#line 220 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 95:
-#line 220 "wktparse.y"
- { pop();}
- break;
-
- case 98:
-#line 230 "wktparse.y"
- { alloc_multicurve(); }
- break;
-
- case 99:
-#line 231 "wktparse.y"
- { pop(); }
- break;
-
- case 100:
-#line 233 "wktparse.y"
- { set_zm(0, 1); alloc_multicurve(); }
- break;
-
- case 101:
-#line 234 "wktparse.y"
- { pop(); }
- break;
-
- case 103:
-#line 239 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 104:
-#line 239 "wktparse.y"
- { pop(); }
- break;
-
- case 110:
-#line 255 "wktparse.y"
- { set_zm(0, 1); }
- break;
-
- case 114:
-#line 263 "wktparse.y"
- { alloc_polygon(); }
- break;
-
- case 115:
-#line 263 "wktparse.y"
- { pop(); }
- break;
-
- case 116:
-#line 266 "wktparse.y"
- { alloc_polygon(); }
- break;
-
- case 117:
-#line 266 "wktparse.y"
- { pop(); }
- break;
-
- case 118:
-#line 269 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 119:
-#line 269 "wktparse.y"
- { pop();}
- break;
-
- case 122:
-#line 279 "wktparse.y"
- { alloc_curvepolygon(); }
- break;
-
- case 123:
-#line 279 "wktparse.y"
- { pop(); }
- break;
-
- case 124:
-#line 281 "wktparse.y"
- { set_zm(0, 1); alloc_curvepolygon(); }
- break;
-
- case 125:
-#line 282 "wktparse.y"
- { pop(); }
- break;
-
- case 127:
-#line 287 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 128:
-#line 287 "wktparse.y"
- { pop(); }
- break;
-
- case 133:
-#line 301 "wktparse.y"
- { alloc_multipolygon(); }
- break;
-
- case 134:
-#line 301 "wktparse.y"
- { pop(); }
- break;
-
- case 135:
-#line 303 "wktparse.y"
- { set_zm(0, 1); alloc_multipolygon(); }
- break;
-
- case 136:
-#line 304 "wktparse.y"
- { pop();}
- break;
-
- case 138:
-#line 309 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 139:
-#line 309 "wktparse.y"
- { pop(); }
- break;
-
- case 142:
-#line 319 "wktparse.y"
- {alloc_multisurface(); }
- break;
-
- case 143:
-#line 319 "wktparse.y"
- { pop(); }
- break;
-
- case 144:
-#line 321 "wktparse.y"
- { set_zm(0, 1); alloc_multisurface(); }
- break;
-
- case 145:
-#line 322 "wktparse.y"
- { pop(); }
- break;
-
- case 147:
-#line 327 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 148:
-#line 327 "wktparse.y"
- { pop(); }
- break;
-
- case 153:
-#line 341 "wktparse.y"
- { alloc_geomertycollection(); }
- break;
-
- case 154:
-#line 342 "wktparse.y"
- { pop(); }
- break;
-
- case 155:
-#line 344 "wktparse.y"
- { set_zm(0, 1); alloc_geomertycollection(); }
- break;
-
- case 156:
-#line 345 "wktparse.y"
- { pop();}
- break;
-
- case 158:
-#line 350 "wktparse.y"
- { alloc_counter(); }
- break;
-
- case 159:
-#line 350 "wktparse.y"
- { pop(); }
- break;
-
- case 166:
-#line 369 "wktparse.y"
- {alloc_point_2d(yyvsp[-1].value,yyvsp[0].value); }
- break;
-
- case 167:
-#line 372 "wktparse.y"
- {alloc_point_3d(yyvsp[-2].value,yyvsp[-1].value,yyvsp[0].value); }
- break;
-
- case 168:
-#line 375 "wktparse.y"
- {alloc_point_4d(yyvsp[-3].value,yyvsp[-2].value,yyvsp[-1].value,yyvsp[0].value); }
- break;
-
- case 169:
-#line 378 "wktparse.y"
- { alloc_empty(); }
- break;
-
-
- }
-
-/* Line 1000 of yacc.c. */
-#line 1761 "y.tab.c"
-
- yyvsp -= yylen;
- yyssp -= yylen;
-
-
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
-
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (YYPACT_NINF < yyn && yyn < YYLAST)
- {
- YYSIZE_T yysize = 0;
- int yytype = YYTRANSLATE (yychar);
- const char* yyprefix;
- char *yymsg;
- int yyx;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 0;
-
- yyprefix = ", expecting ";
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
- yycount += 1;
- if (yycount == 5)
- {
- yysize = 0;
- break;
- }
- }
- yysize += (sizeof ("syntax error, unexpected ")
- + yystrlen (yytname[yytype]));
- yymsg = (char *) YYSTACK_ALLOC (yysize);
- if (yymsg != 0)
- {
- char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
- yyp = yystpcpy (yyp, yytname[yytype]);
-
- if (yycount < 5)
- {
- yyprefix = ", expecting ";
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- yyp = yystpcpy (yyp, yyprefix);
- yyp = yystpcpy (yyp, yytname[yyx]);
- yyprefix = " or ";
- }
- }
- yyerror (yymsg);
- YYSTACK_FREE (yymsg);
- }
- else
- yyerror ("syntax error; also virtual memory exhausted");
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror ("syntax error");
- }
-
-
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse lookahead token after an
- error, discard it. */
-
- if (yychar <= YYEOF)
- {
- /* If at end of input, pop the error token,
- then the rest of the stack, then return failure. */
- if (yychar == YYEOF)
- for (;;)
- {
- YYPOPSTACK;
- if (yyssp == yyss)
- YYABORT;
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[*yyssp], yyvsp);
- }
- }
- else
- {
- YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
- yydestruct (yytoken, &yylval);
- yychar = YYEMPTY;
-
- }
- }
-
- /* Else will try to reuse lookahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
-
-#ifdef __GNUC__
- /* Pacify GCC when the user code never invokes YYERROR and the label
- yyerrorlab therefore never appears in user code. */
- if (0)
- goto yyerrorlab;
-#endif
-
- yyvsp -= yylen;
- yyssp -= yylen;
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[yystate], yyvsp);
- YYPOPSTACK;
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- YYDPRINTF ((stderr, "Shifting error token, "));
-
- *++yyvsp = yylval;
-
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#ifndef yyoverflow
-/*----------------------------------------------.
-| yyoverflowlab -- parser overflow comes here. |
-`----------------------------------------------*/
-yyoverflowlab:
- yyerror ("parser stack overflow");
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
- return yyresult;
-}
-
-
-#line 379 "wktparse.y"
-
-
-
-
-
-
Deleted: trunk/lwgeom/wktparse.tab.h
===================================================================
--- trunk/lwgeom/wktparse.tab.h 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/wktparse.tab.h 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,120 +0,0 @@
-/* A Bison parser, made by GNU Bison 1.875c. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- POINT = 258,
- LINESTRING = 259,
- POLYGON = 260,
- MULTIPOINT = 261,
- MULTILINESTRING = 262,
- MULTIPOLYGON = 263,
- GEOMETRYCOLLECTION = 264,
- CIRCULARSTRING = 265,
- COMPOUNDCURVE = 266,
- CURVEPOLYGON = 267,
- MULTICURVE = 268,
- MULTISURFACE = 269,
- POINTM = 270,
- LINESTRINGM = 271,
- POLYGONM = 272,
- MULTIPOINTM = 273,
- MULTILINESTRINGM = 274,
- MULTIPOLYGONM = 275,
- GEOMETRYCOLLECTIONM = 276,
- CIRCULARSTRINGM = 277,
- COMPOUNDCURVEM = 278,
- CURVEPOLYGONM = 279,
- MULTICURVEM = 280,
- MULTISURFACEM = 281,
- SRID = 282,
- EMPTY = 283,
- VALUE = 284,
- LPAREN = 285,
- RPAREN = 286,
- COMMA = 287,
- EQUALS = 288,
- SEMICOLON = 289,
- WKB = 290
- };
-#endif
-#define POINT 258
-#define LINESTRING 259
-#define POLYGON 260
-#define MULTIPOINT 261
-#define MULTILINESTRING 262
-#define MULTIPOLYGON 263
-#define GEOMETRYCOLLECTION 264
-#define CIRCULARSTRING 265
-#define COMPOUNDCURVE 266
-#define CURVEPOLYGON 267
-#define MULTICURVE 268
-#define MULTISURFACE 269
-#define POINTM 270
-#define LINESTRINGM 271
-#define POLYGONM 272
-#define MULTIPOINTM 273
-#define MULTILINESTRINGM 274
-#define MULTIPOLYGONM 275
-#define GEOMETRYCOLLECTIONM 276
-#define CIRCULARSTRINGM 277
-#define COMPOUNDCURVEM 278
-#define CURVEPOLYGONM 279
-#define MULTICURVEM 280
-#define MULTISURFACEM 281
-#define SRID 282
-#define EMPTY 283
-#define VALUE 284
-#define LPAREN 285
-#define RPAREN 286
-#define COMMA 287
-#define EQUALS 288
-#define SEMICOLON 289
-#define WKB 290
-
-
-
-
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 20 "wktparse.y"
-typedef union YYSTYPE {
- double value;
- const char* wkb;
-} YYSTYPE;
-/* Line 1275 of yacc.c. */
-#line 112 "y.tab.h"
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-extern YYSTYPE lwg_parse_yylval;
-
-
-
Deleted: trunk/lwgeom/wktparse.y
===================================================================
--- trunk/lwgeom/wktparse.y 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/wktparse.y 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,383 +0,0 @@
-/*
- * Written by Ralph Mason ralph.mason<at>telogis.com
- *
- * Copyright Telogis 2004
- * www.telogis.com
- *
- */
-
-%{
-#include "wktparse.h"
-#include <unistd.h>
-#include <stdio.h>
-
-void set_zm(char z, char m);
-int lwg_parse_yylex(void);
-%}
-
-%start geometry
-
-%union {
- double value;
- const char* wkb;
-}
-
-%token POINT LINESTRING POLYGON MULTIPOINT MULTILINESTRING MULTIPOLYGON GEOMETRYCOLLECTION CIRCULARSTRING COMPOUNDCURVE CURVEPOLYGON MULTICURVE MULTISURFACE
-%token POINTM LINESTRINGM POLYGONM MULTIPOINTM MULTILINESTRINGM MULTIPOLYGONM GEOMETRYCOLLECTIONM CIRCULARSTRINGM COMPOUNDCURVEM CURVEPOLYGONM MULTICURVEM MULTISURFACEM
-%token SRID
-%token EMPTY
-%token <value> VALUE
-%token LPAREN RPAREN COMMA EQUALS SEMICOLON
-%token <wkb> WKB
-
-%%
-
-geometry :
- srid SEMICOLON { alloc_lwgeom(srid); } geometry_int
- |
- { alloc_lwgeom(-1); } geometry_int
-
-geometry_int :
- geom_wkb
- |
- geom_point
- |
- geom_linestring
- |
- geom_circularstring
- |
- geom_polygon
- |
- geom_compoundcurve
- |
- geom_curvepolygon
- |
- geom_multipoint
- |
- geom_multilinestring
- |
- geom_multicurve
- |
- geom_multipolygon
- |
- geom_multisurface
- |
- geom_geometrycollection
-
-srid :
- SRID EQUALS VALUE { set_srid($3); }
-
-geom_wkb :
- WKB { alloc_wkb($1); }
-
-
-/* POINT */
-
-geom_point :
- POINT point
- |
- POINTM { set_zm(0, 1); } point
-
-point :
- empty_point
- |
- nonempty_point
-
-empty_point :
- { alloc_point(); } empty { pop(); }
-
-nonempty_point :
- { alloc_point(); } point_int { pop(); }
-
-point_int :
- LPAREN a_point RPAREN
-
-/* MULTIPOINT */
-
-geom_multipoint :
- MULTIPOINT { alloc_multipoint(); } multipoint { pop(); }
- |
- MULTIPOINTM { set_zm(0, 1); alloc_multipoint(); } multipoint {pop(); }
-
-multipoint :
- empty
- |
- { alloc_counter(); } LPAREN multipoint_int RPAREN { pop(); }
-
-multipoint_int :
- mpoint_element
- |
- multipoint_int COMMA mpoint_element
-
-mpoint_element :
- nonempty_point
- |
- /* this is to allow MULTIPOINT(0 0, 1 1) */
- { alloc_point(); } a_point { pop(); }
-
-
-/* LINESTRING */
-
-geom_linestring :
- LINESTRING linestring
- |
- LINESTRINGM { set_zm(0, 1); } linestring
-
-linestring :
- empty_linestring
- |
- nonempty_linestring
-
-empty_linestring :
- { alloc_linestring(); } empty { pop(); }
-
-nonempty_linestring :
- { alloc_linestring(); } linestring_1 { pop(); }
-
-nonempty_linestring_closed :
- { alloc_linestring_closed(); } linestring_1 { pop(); }
-
-linestring_1 :
- { alloc_counter(); } LPAREN linestring_int RPAREN { popc(); }
-
-linestring_int :
- a_point
- |
- linestring_int COMMA a_point;
-
-/* CIRCULARSTRING */
-
-geom_circularstring :
- CIRCULARSTRING circularstring
- |
- CIRCULARSTRINGM {set_zm(0, 1); } circularstring
-
-geom_circularstring_closed :
- CIRCULARSTRING circularstring_closed
- |
- CIRCULARSTRINGM {set_zm(0, 1); } circularstring_closed
-
-circularstring :
- empty_circularstring
- |
- nonempty_circularstring
-
-circularstring_closed :
- empty_circularstring
- |
- nonempty_circularstring_closed
-
-empty_circularstring :
- { alloc_circularstring(); } empty { pop(); }
-
-nonempty_circularstring :
- { alloc_circularstring(); } circularstring_1 { pop(); }
-
-nonempty_circularstring_closed :
- { alloc_circularstring_closed(); } circularstring_1 { pop(); }
-
-circularstring_1 :
- { alloc_counter(); } LPAREN circularstring_int RPAREN { popc(); }
-
-circularstring_int :
- a_point
- |
- circularstring_int COMMA a_point;
-
-/* COMPOUNDCURVE */
-
-geom_compoundcurve:
- COMPOUNDCURVE { alloc_compoundcurve(); } compoundcurve { pop(); }
- |
- COMPOUNDCURVEM {set_zm(0, 1); alloc_compoundcurve(); } compoundcurve { pop(); }
-
-compoundcurve:
- empty
- |
- { alloc_counter(); } LPAREN compoundcurve_int RPAREN { pop(); }
-
-compoundcurve_int:
- nonempty_linestring
- |
- geom_circularstring
- |
- compoundcurve_int COMMA nonempty_linestring
- |
- compoundcurve_int COMMA geom_circularstring
-
-/* MULTILINESTRING */
-
-geom_multilinestring :
- MULTILINESTRING { alloc_multilinestring(); }
- multilinestring { pop(); }
- |
- MULTILINESTRINGM { set_zm(0, 1); alloc_multilinestring(); }
- multilinestring { pop(); }
-
-multilinestring :
- empty
- |
- { alloc_counter(); } LPAREN multilinestring_int RPAREN{ pop();}
-
-multilinestring_int :
- nonempty_linestring
- |
- multilinestring_int COMMA nonempty_linestring
-
-/* MULTICURVESTRING */
-
-geom_multicurve :
- MULTICURVE { alloc_multicurve(); }
- multicurve { pop(); }
- |
- MULTICURVEM { set_zm(0, 1); alloc_multicurve(); }
- multicurve { pop(); }
-
-multicurve :
- empty
- |
- { alloc_counter(); } LPAREN multicurve_int RPAREN { pop(); }
-
-multicurve_int :
- nonempty_linestring
- |
- geom_circularstring
- |
- multicurve_int COMMA nonempty_linestring
- |
- multicurve_int COMMA geom_circularstring
-
-/* POLYGON */
-
-geom_polygon :
- POLYGON polygon
- |
- POLYGONM { set_zm(0, 1); } polygon
-
-polygon :
- empty_polygon
- |
- nonempty_polygon
-
-empty_polygon :
- { alloc_polygon(); } empty { pop(); }
-
-nonempty_polygon :
- { alloc_polygon(); } polygon_1 { pop(); }
-
-polygon_1 :
- { alloc_counter(); } LPAREN polygon_int RPAREN { pop();}
-
-polygon_int :
- linestring_1
- |
- polygon_int COMMA linestring_1
-
-/* CURVEPOLYGON */
-
-geom_curvepolygon :
- CURVEPOLYGON { alloc_curvepolygon(); } curvepolygon { pop(); }
- |
- CURVEPOLYGONM { set_zm(0, 1); alloc_curvepolygon(); }
- curvepolygon { pop(); }
-
-curvepolygon :
- empty
- |
- { alloc_counter(); } LPAREN curvepolygon_int RPAREN { pop(); }
-
-curvepolygon_int :
- nonempty_linestring_closed
- |
- geom_circularstring_closed
- |
- curvepolygon_int COMMA nonempty_linestring_closed
- |
- curvepolygon_int COMMA geom_circularstring_closed
-
-/* MULTIPOLYGON */
-
-geom_multipolygon :
- MULTIPOLYGON { alloc_multipolygon(); } multipolygon { pop(); }
- |
- MULTIPOLYGONM { set_zm(0, 1); alloc_multipolygon(); }
- multipolygon { pop();}
-
-multipolygon :
- empty
- |
- { alloc_counter(); } LPAREN multipolygon_int RPAREN { pop(); }
-
-multipolygon_int :
- nonempty_polygon
- |
- multipolygon_int COMMA nonempty_polygon
-
-/* MULTISURFACE */
-
-geom_multisurface :
- MULTISURFACE {alloc_multisurface(); } multisurface { pop(); }
- |
- MULTISURFACEM { set_zm(0, 1); alloc_multisurface(); }
- multisurface { pop(); }
-
-multisurface :
- empty
- |
- { alloc_counter(); } LPAREN multisurface_int RPAREN { pop(); }
-
-multisurface_int :
- nonempty_polygon
- |
- geom_curvepolygon
- |
- multisurface_int COMMA nonempty_polygon
- |
- multisurface_int COMMA geom_curvepolygon
-
-/* GEOMETRYCOLLECTION */
-
-geom_geometrycollection :
- GEOMETRYCOLLECTION { alloc_geomertycollection(); }
- geometrycollection { pop(); }
- |
- GEOMETRYCOLLECTIONM { set_zm(0, 1); alloc_geomertycollection(); }
- geometrycollection { pop();}
-
-geometrycollection :
- empty
- |
- { alloc_counter(); } LPAREN geometrycollection_int RPAREN { pop(); }
-
-geometrycollection_int :
- /* to support GEOMETRYCOLLECTION(EMPTY) for backward compatibility */
- empty
- |
- geometry_int
- |
- geometrycollection_int COMMA geometry_int
-
-
-a_point :
- point_2d
- |
- point_3d
- |
- point_4d
-
-point_2d :
- VALUE VALUE {alloc_point_2d($1,$2); }
-
-point_3d :
- VALUE VALUE VALUE {alloc_point_3d($1,$2,$3); }
-
-point_4d :
- VALUE VALUE VALUE VALUE {alloc_point_4d($1,$2,$3,$4); }
-
-empty :
- EMPTY { alloc_empty(); }
-%%
-
-
-
-
Deleted: trunk/lwgeom/wktunparse.c
===================================================================
--- trunk/lwgeom/wktunparse.c 2008-06-28 05:34:59 UTC (rev 2814)
+++ trunk/lwgeom/wktunparse.c 2008-06-29 19:11:48 UTC (rev 2815)
@@ -1,765 +0,0 @@
-/*
- * Written by Ralph Mason ralph.mason<at>telogis.com
- *
- * Copyright Telogis 2004
- * www.telogis.com
- *
- * $Id$
- */
-
-
-#include <string.h>
-#include <math.h>
-#include <stdio.h>
-/* TO get byte order */
-#include <sys/types.h>
-#include <sys/param.h>
-/* Solaris9 does not provide stdint.h */
-/* #include <stdint.h> */
-#include <inttypes.h>
-
-#include "liblwgeom.h"
-#include "wktparse.h"
-
-
-/*-- Typedefs ---------------------------------------------- */
-
-typedef uint32_t int4;
-typedef uchar* (*outfunc)(uchar*,int);
-typedef uchar* (*outwkbfunc)(uchar*);
-
-/*-- Prototypes -------------------------------------------- */
-
-void ensure(int chars);
-void to_end(void);
-void write_str(const char* str);
-void write_double(double val);
-void write_int(int i);
-int4 read_int(uchar** geom);
-double read_double(uchar** geom);
-uchar* output_point(uchar* geom,int supress);
-uchar* output_single(uchar* geom,int supress);
-uchar* output_collection(uchar* geom,outfunc func,int supress);
-uchar* output_collection_2(uchar* geom,int suppress);
-uchar* output_multipoint(uchar* geom,int suppress);
-uchar* output_compound(uchar* geom, int suppress);
-uchar* output_multisurface(uchar* geom, int suppress);
-
-void write_wkb_hex_bytes(uchar* ptr, unsigned int cnt, size_t size);
-void write_wkb_bin_bytes(uchar* ptr, unsigned int cnt, size_t size);
-void write_wkb_bin_flip_bytes(uchar* ptr, unsigned int cnt, size_t size);
-void write_wkb_hex_flip_bytes(uchar* ptr, unsigned int cnt, size_t size);
-
-void write_wkb_int(int i);
-uchar* output_wkb_collection(uchar* geom,outwkbfunc func);
-uchar* output_wkb_collection_2(uchar* geom);
-uchar* output_wkb_point(uchar* geom);
-uchar* output_wkb(uchar* geom);
-
-/*-- Globals ----------------------------------------------- */
-
-static int dims;
-static allocator local_malloc;
-static freeor local_free;
-static char* out_start;
-static char* out_pos;
-static int len;
-static int lwgi;
-static uchar endianbyte;
-void (*write_wkb_bytes)(uchar* ptr,unsigned int cnt,size_t size);
-
-/*---------------------------------------------------------- */
-
-
-
-/*
- * Ensure there is enough space for chars bytes.
- * Reallocate memory is this is not the case.
- */
-void
-ensure(int chars){
-
- int pos = out_pos - out_start;
-
- if ( (pos + chars) >= len ){
- char* newp =(char*)local_malloc(len*2);
- memcpy(newp,out_start,len);
- local_free(out_start);
- out_start = newp;
- out_pos = newp + pos;
- len *=2;
- }
-}
-
-void
-to_end(void)
-{
- while(*out_pos){
- out_pos++;
- }
-}
-
-void
-write_str(const char* str)
-{
- ensure(32);
- strcpy(out_pos,str);
- to_end();
-}
-
-void
-write_double(double val){
- ensure(32);
- if (lwgi)
- sprintf(out_pos,"%.8g",val);
- else
- sprintf(out_pos,"%.15g",val);
- to_end();
-}
-
-void
-write_int(int i){
- ensure(32);
- sprintf(out_pos,"%i",i);
- to_end();
-}
-
-int4
-read_int(uchar** geom)
-{
- int4 ret;
-#ifdef SHRINK_INTS
- if ( getMachineEndian() == NDR ){
- if( (**geom)& 0x01){
- ret = **geom >>1;
- (*geom)++;
- return ret;
- }
- }
- else{
- if( (**geom)& 0x80){
- ret = **geom & ~0x80;
- (*geom)++;
- return ret;
- }
- }
-#endif
- memcpy(&ret,*geom,4);
-
-#ifdef SHRINK_INTS
- if ( getMachineEndian() == NDR ){
- ret >>= 1;
- }
-#endif
-
- (*geom)+=4;
- return ret;
-}
-
-double round(double);
-
-double read_double(uchar** geom){
- if (lwgi){
- double ret = *((int4*)*geom);
- ret /= 0xb60b60;
- (*geom)+=4;
- return ret-180.0;
- }
- else{
- double ret;
- memcpy(&ret, *geom, 8);
- (*geom)+=8;
- return ret;
- }
-}
-
-uchar *
-output_point(uchar* geom,int supress)
-{
- int i;
-
- for( i = 0 ; i < dims ; i++ ){
- write_double(read_double(&geom));
- if (i +1 < dims )
- write_str(" ");
- }
- return geom;
-}
-
-uchar *
-output_single(uchar* geom,int supress)
-{
- write_str("(");
- geom=output_point(geom,supress);
- write_str(")");
- return geom;
-}
-
-uchar *
-output_collection(uchar* geom,outfunc func,int supress)
-{
- int cnt = read_int(&geom);
- if ( cnt == 0 ){
- write_str(" EMPTY");
- }
- else{
- write_str("(");
- while(cnt--){
- geom=func(geom,supress);
- if ( cnt ){
- write_str(",");
- }
- }
- write_str(")");
- }
- return geom;
-}
-
-uchar *
-output_collection_2(uchar* geom,int suppress)
-{
- return output_collection(geom,output_point,suppress);
-}
-
-uchar *output_wkt(uchar* geom, int supress);
-
-/* special case for multipoint to supress extra brackets */
-uchar *output_multipoint(uchar* geom,int suppress){
- unsigned type = *geom & 0x0f;
-
- if ( type == POINTTYPE )
- return output_point(++geom,suppress);
- else if ( type == POINTTYPEI ){
- lwgi++;
- geom=output_point(++geom,0);
- lwgi--;
- return geom;
- }
-
- return output_wkt(geom,suppress);
-}
-
-/* special case for compound to suppress linestring but not circularstring */
-uchar *output_compound(uchar* geom, int suppress) {
- unsigned type;
-
-#ifdef PGIS_DEBUG_CALLS
- lwnotice("output_compound called.");
-#endif
-
- type=*geom++;
- switch(TYPE_GETTYPE(type))
- {
- case LINETYPE:
- geom = output_collection(geom,output_point,0);
- break;
- case CURVETYPE:
- write_str("CIRCULARSTRING");
- geom = output_collection(geom,output_point,1);
- break;
- }
- return geom;
-}
-
-uchar *output_multisurface(uchar* geom, int suppress) {
- unsigned type;
-
-#ifdef PGIS_DEBUG_CALLS
- lwnotice("output_multisurface called.");
-#endif
-
- type=*geom++;
- switch(TYPE_GETTYPE(type))
- {
- case POLYGONTYPE:
- geom = output_collection(geom, output_collection_2,0);
- break;
- case CURVEPOLYTYPE:
- write_str("CURVEPOLYGON");
- geom = output_collection(geom, output_compound,1);
- break;
- }
- return geom;
-}
-
-/*
- * Suppress=0 -- write TYPE, M, coords
- * Suppress=1 -- write TYPE, coords
- * Suppress=2 -- write only coords
- */
-uchar *
-output_wkt(uchar* geom, int supress)
-{
-
- unsigned type=*geom++;
- char writeM=0;
- dims = TYPE_NDIMS(type); /* ((type & 0x30) >> 4)+2; */
-
-#ifdef PGIS_DEBUG_CALLS
- lwnotice("output_wkt called.");
-#endif
-
- if ( ! supress && !TYPE_HASZ(type) && TYPE_HASM(type) ) writeM=1;
-
-
- /* Skip the bounding box if there is one */
- if ( TYPE_HASBBOX(type) )
- {
- geom+=16;
- }
-
- if ( TYPE_HASSRID(type) ) {
- write_str("SRID=");write_int(read_int(&geom));write_str(";");
- }
-
- switch(TYPE_GETTYPE(type)) {
- case POINTTYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("POINTM");
- else write_str("POINT");
- }
- geom=output_single(geom,0);
- break;
- case LINETYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("LINESTRINGM");
- else write_str("LINESTRING");
- }
- geom = output_collection(geom,output_point,0);
- break;
- case CURVETYPE:
- if ( supress < 2 )
- {
- if(writeM) write_str("CIRCULARSTRINGM");
- else write_str("CIRCULARSTRING");
- }
- geom = output_collection(geom,output_point,0);
- break;
- case POLYGONTYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("POLYGONM");
- else write_str("POLYGON");
- }
- geom = output_collection(geom,output_collection_2,0);
- break;
- case COMPOUNDTYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("COMPOUNDCURVEM");
- else write_str("COMPOUNDCURVE");
- }
- geom = output_collection(geom, output_compound,1);
- break;
- case CURVEPOLYTYPE:
- if (supress < 2)
- {
- if(writeM) write_str("CURVEPOLYGONM");
- else write_str("CURVEPOLYGON");
- }
- geom = output_collection(geom, output_compound,0);
- break;
- case MULTIPOINTTYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("MULTIPOINTM");
- else write_str("MULTIPOINT");
- }
- geom = output_collection(geom,output_multipoint,2);
- break;
- case MULTILINETYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("MULTILINESTRINGM");
- else write_str("MULTILINESTRING");
- }
- geom = output_collection(geom,output_wkt,2);
- break;
- case MULTICURVETYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("MULTICURVEM");
- else write_str("MULTICURVE");
- }
- geom = output_collection(geom,output_compound,2);
- break;
- case MULTIPOLYGONTYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("MULTIPOLYGONM");
- else write_str("MULTIPOLYGON");
- }
- geom = output_collection(geom,output_wkt,2);
- break;
- case MULTISURFACETYPE:
- if ( supress < 2)
- {
- if (writeM) write_str("MULTISURFACEM");
- else write_str("MULTISURFACE");
- }
- geom = output_collection(geom,output_multisurface,2);
- break;
- case COLLECTIONTYPE:
- if ( supress < 2 )
- {
- if (writeM) write_str("GEOMETRYCOLLECTIONM");
- else write_str("GEOMETRYCOLLECTION");
- }
- geom = output_collection(geom,output_wkt,1);
- break;
-
- case POINTTYPEI:
- if ( supress < 2 )
- {
- if (writeM) write_str("POINTM");
- else write_str("POINT");
- }
- lwgi++;
- geom=output_single(geom,0);
- lwgi--;
- break;
- case LINETYPEI:
- if ( supress < 2 )
- {
- if (writeM) write_str("LINESTRINGM");
- else write_str("LINESTRING");
- }
- lwgi++;
- geom = output_collection(geom,output_point,0);
- lwgi--;
- break;
- case POLYGONTYPEI:
- if ( supress < 2 )
- {
- if (writeM) write_str("POLYGONM");
- else write_str("POLYGON");
- }
- lwgi++;
- geom =output_collection(geom,output_collection_2,0);
- lwgi--;
- break;
- }
- return geom;
-}
-
-char *
-unparse_WKT(uchar* serialized, allocator alloc, freeor free)
-{
-
-#ifdef PGIS_DEBUG_CALLS
- lwnotice("unparse_WKT called.");
-#endif
-
- if (serialized==NULL)
- return NULL;
-
- local_malloc=alloc;
- local_free=free;
- len = 128;
- out_start = out_pos = alloc(len);
- lwgi=0;
-
- output_wkt(serialized, 0);
-
- return out_start;
-}
-
-static char outchr[]={"0123456789ABCDEF" };
-
-/* Write HEX bytes flipping */
-void
-write_wkb_hex_flip_bytes(uchar* ptr, unsigned int cnt, size_t size)
-{
- unsigned int bc; /* byte count */
-
- ensure(cnt*2*size);
-
- while(cnt--){
- for(bc=size; bc; bc--)
- {
- *out_pos++ = outchr[ptr[bc-1]>>4];
- *out_pos++ = outchr[ptr[bc-1]&0x0F];
- }
- ptr+=size;
- }
-}
-
-/* Write HEX bytes w/out flipping */
-void
-write_wkb_hex_bytes(uchar* ptr, unsigned int cnt, size_t size)
-{
- unsigned int bc; /* byte count */
-
- ensure(cnt*2*size);
-
- while(cnt--){
- for(bc=0; bc<size; bc++)
- {
- *out_pos++ = outchr[ptr[bc]>>4];
- *out_pos++ = outchr[ptr[bc]&0x0F];
- }
- ptr+=size;
- }
-}
-
-/* Write BIN bytes flipping */
-void
-write_wkb_bin_flip_bytes(uchar* ptr, unsigned int cnt, size_t size)
-{
- unsigned int bc; /* byte count */
-
- ensure(cnt*size);
-
- while(cnt--)
- {
- for(bc=size; bc; bc--)
- *out_pos++ = ptr[bc-1];
- ptr+=size;
- }
-}
-
-
-/* Write BIN bytes w/out flipping */
-void
-write_wkb_bin_bytes(uchar* ptr, unsigned int cnt, size_t size)
-{
- unsigned int bc; /* byte count */
-
- ensure(cnt*size);
-
- /* Could just use a memcpy here ... */
- while(cnt--)
- {
- for(bc=0; bc<size; bc++)
- *out_pos++ = ptr[bc];
- ptr+=size;
- }
-}
-
-uchar *
-output_wkb_point(uchar* geom)
-{
- if ( lwgi ){
- write_wkb_bytes(geom,dims,4);
- return geom + (4*dims);
- }
- else{
- write_wkb_bytes(geom,dims,8);
- return geom + (8*dims);
- }
-}
-
-void
-write_wkb_int(int i){
- write_wkb_bytes((uchar*)&i,1,4);
-}
-
-uchar *
-output_wkb_collection(uchar* geom,outwkbfunc func)
-{
- int cnt = read_int(&geom);
-#ifdef PGIS_DEBUG
- lwnotice("output_wkb_collection: %d iterations loop", cnt);
-#endif
- write_wkb_int(cnt);
- while(cnt--) geom=func(geom);
- return geom;
-}
-
-uchar *
-output_wkb_collection_2(uchar* geom){
- return output_wkb_collection(geom,output_wkb_point);
-}
-
-uchar *
-output_wkb(uchar* geom)
-{
- unsigned char type=*geom++;
- int4 wkbtype;
-
- dims = TYPE_NDIMS(type);
-#ifdef PGIS_DEBUG
- lwnotice("output_wkb: dims set to %d", dims);
-#endif
-
- /* Skip the bounding box */
- if ( TYPE_HASBBOX(type) ) {
- geom+=16;
- }
-
- wkbtype = TYPE_GETTYPE(type);
-
- if ( TYPE_HASZ(type) )
- wkbtype |= WKBZOFFSET;
- if ( TYPE_HASM(type) )
- wkbtype |= WKBMOFFSET;
- if ( TYPE_HASSRID(type) ) {
- wkbtype |= WKBSRIDFLAG;
- }
-
-
- /* Write byteorder (as from WKB specs...) */
- write_wkb_bytes(&endianbyte,1,1);
-
- write_wkb_int(wkbtype);
-
- if ( TYPE_HASSRID(type) ) {
- write_wkb_int(read_int(&geom));
- }
-
- switch(TYPE_GETTYPE(type)){
- case POINTTYPE:
- geom=output_wkb_point(geom);
- break;
- case LINETYPE:
- geom=output_wkb_collection(geom,output_wkb_point);
- break;
- case CURVETYPE:
- geom=output_wkb_collection(geom,output_wkb_point);
- break;
- case POLYGONTYPE:
- geom=output_wkb_collection(geom,output_wkb_collection_2);
- break;
- case COMPOUNDTYPE:
- geom=output_wkb_collection(geom,output_wkb);
- break;
- case CURVEPOLYTYPE:
- geom=output_wkb_collection(geom,output_wkb);
- break;
- case MULTICURVETYPE:
- case MULTISURFACETYPE:
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- geom = output_wkb_collection(geom,output_wkb);
- break;
-
- /*
- These don't output standard wkb at the moment
- the output and integer version.
-
- however you could run it through the wkt parser
- for a lwg and then output that. There should
- also be a force_to_real_(lwgi)
- */
- case POINTTYPEI:
- lwgi++;
- geom=output_wkb_point(geom);
- lwgi--;
- break;
- case LINETYPEI:
- lwgi++;
- geom = output_wkb_collection(geom,output_wkb_point);
- lwgi--;
- break;
- case POLYGONTYPEI:
- lwgi++;
- geom = output_wkb_collection(geom,output_wkb_collection_2);
- lwgi--;
- break;
- }
- return geom;
-}
-
-char *
-unparse_WKB(uchar* serialized, allocator alloc, freeor free, char endian, size_t *outsize, uchar hex)
-{
-#ifdef PGIS_DEBUG
- lwnotice("unparse_WKB(%p,...) called", serialized);
-#endif
-
- if (serialized==NULL)
- return NULL;
-
- local_malloc=alloc;
- local_free=free;
- len = 128;
- out_start = out_pos = alloc(len);
- lwgi=0;
-
- if ( endian == (char)-1 )
- {
- endianbyte = getMachineEndian();
- if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
- else write_wkb_bytes = write_wkb_bin_bytes;
- }
- else
- {
- endianbyte = endian;
- if ( endianbyte != getMachineEndian() )
- {
- if ( hex ) write_wkb_bytes = write_wkb_hex_flip_bytes;
- else write_wkb_bytes = write_wkb_bin_flip_bytes;
- }
- else
- {
- if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
- else write_wkb_bytes = write_wkb_bin_bytes;
- }
- }
-
- output_wkb(serialized);
-
- if ( hex ) {
- ensure(1);
- *out_pos=0;
- }
-
- if ( outsize ) *outsize = (out_pos-out_start);
-
- return out_start;
-}
-
-
-/******************************************************************
- * $Log$
- * Revision 1.23 2006/02/06 11:12:22 strk
- * uint32_t typedef moved back from wktparse.h to lwgparse.c and wktunparse.c
- *
- * Revision 1.22 2006/02/03 20:53:37 strk
- * Swapped stdint.h (unavailable on Solaris9) with inttypes.h
- *
- * Revision 1.21 2006/02/03 09:52:14 strk
- * Changed int4 typedefs to use POSIX uint32_t
- *
- * Revision 1.20 2006/01/09 15:12:02 strk
- * ISO C90 comments
- *
- * Revision 1.19 2005/03/10 18:19:16 strk
- * Made void args explicit to make newer compilers happy
- *
- * Revision 1.18 2005/02/21 16:16:14 strk
- * Changed byte to uchar to avoid clashes with win32 headers.
- *
- * Revision 1.17 2005/02/07 13:21:10 strk
- * Replaced DEBUG* macros with PGIS_DEBUG*, to avoid clashes with postgresql DEBUG
- *
- * Revision 1.16 2005/01/18 09:32:03 strk
- * Changed unparse_WKB interface to take an output size pointer and an HEXFORM
- * specifier. Reworked code in wktunparse to use function pointers.
- *
- * Revision 1.15 2004/12/21 15:19:01 strk
- * Canonical binary reverted back to EWKB, now supporting SRID inclusion.
- *
- * Revision 1.14 2004/12/17 11:08:53 strk
- * Moved getMachineEndian from parser to liblwgeom.{h,c}.
- * Added XDR and NDR defines.
- * Fixed all usage of them.
- *
- * Revision 1.13 2004/10/25 12:27:33 strk
- * Removed useless network type includes,
- * Added param.h include for BYTE_ORDER defines under win32.
- *
- * Revision 1.12 2004/10/21 19:48:34 strk
- * Stricter syntax fixes. Reported by Sébastien NICAISE <snicaise at iciatechnologies.com>
- *
- * Revision 1.11 2004/10/15 07:35:41 strk
- * Fixed a bug introduced by me (byteorder skipped for inner geoms in WKB)
- *
- * Revision 1.10 2004/10/11 14:03:33 strk
- * Added endiannes specification to unparse_WKB, AsBinary, lwgeom_to_wkb.
- *
- ******************************************************************/
More information about the postgis-commits
mailing list