From: Paul Ramsey Date: Tue, 23 Dec 2008 20:20:48 +0000 (+0000) Subject: Rename new functions to ST_LineCrossingDirection and ST_LocateBetweenElevations for... X-Git-Tag: 1.4.0b1~359 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6331a0570850679731ad4474f0b30c580d57fb88;p=postgis Rename new functions to ST_LineCrossingDirection and ST_LocateBetweenElevations for more explicitness and closer correspondance to SQL/MM, respectively. Add a new geometry counter for collections. git-svn-id: http://svn.osgeo.org/postgis/trunk@3474 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/lex.yy.c b/liblwgeom/lex.yy.c index d78371fb6..540f1eb03 100644 --- a/liblwgeom/lex.yy.c +++ b/liblwgeom/lex.yy.c @@ -6,29 +6,10 @@ /* A lexical scanner generated by flex */ -#define yy_create_buffer lwg_parse_yy_create_buffer -#define yy_delete_buffer lwg_parse_yy_delete_buffer -#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 yylineno lwg_parse_yylineno -#define yyout lwg_parse_yyout -#define yyrestart lwg_parse_yyrestart -#define yytext lwg_parse_yytext -#define yywrap lwg_parse_yywrap -#define yyalloc lwg_parse_yyalloc -#define yyrealloc lwg_parse_yyrealloc -#define yyfree lwg_parse_yyfree - #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 33 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -50,7 +31,7 @@ /* C99 systems have . Non-C99 systems may or may not. */ -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#if __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. @@ -73,6 +54,7 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -103,8 +85,6 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif -#endif /* ! C99 */ - #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -114,12 +94,11 @@ typedef unsigned int flex_uint32_t; #else /* ! __cplusplus */ -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) +#if __STDC__ #define YY_USE_CONST -#endif /* defined (__STDC__) */ +#endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST @@ -199,9 +178,14 @@ extern FILE *lwg_parse_yyin, *lwg_parse_yyout; #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). + */ + #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; +typedef unsigned int yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE @@ -3351,7 +3335,7 @@ char *lwg_parse_yytext; #line 11 "wktparse.lex" #include "wktparse.tab.h" #include -#include // need stdlib for atof() definition +#include /* need stdlib for atof() definition */ void init_parser(const char *src); void close_parser(void); @@ -3366,7 +3350,7 @@ static YY_BUFFER_STATE buf_state; /* Macro to keep track of the current parse position */ #define UPDATE_YYLLOC() (lwg_parse_yylloc.last_column += lwg_parse_yyleng) -#line 3370 "lex.yy.c" +#line 3354 "lex.yy.c" #define INITIAL 0 #define vals_ok 1 @@ -3385,35 +3369,6 @@ static YY_BUFFER_STATE buf_state; static int yy_init_globals (void ); -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int lwg_parse_yylex_destroy (void ); - -int lwg_parse_yyget_debug (void ); - -void lwg_parse_yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE lwg_parse_yyget_extra (void ); - -void lwg_parse_yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *lwg_parse_yyget_in (void ); - -void lwg_parse_yyset_in (FILE * in_str ); - -FILE *lwg_parse_yyget_out (void ); - -void lwg_parse_yyset_out (FILE * out_str ); - -int lwg_parse_yyget_leng (void ); - -char *lwg_parse_yyget_text (void ); - -int lwg_parse_yyget_lineno (void ); - -void lwg_parse_yyset_lineno (int line_number ); - /* Macros after this point can all be overridden by user definitions in * section 1. */ @@ -3456,7 +3411,7 @@ static int input (void ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( lwg_parse_yytext, lwg_parse_yyleng, 1, lwg_parse_yyout ) +#define ECHO (void) fwrite( lwg_parse_yytext, lwg_parse_yyleng, 1, lwg_parse_yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -3536,7 +3491,7 @@ YY_DECL #line 30 "wktparse.lex" -#line 3540 "lex.yy.c" +#line 3495 "lex.yy.c" if ( !(yy_init) ) { @@ -3798,7 +3753,7 @@ YY_RULE_SETUP #line 73 "wktparse.lex" ECHO; YY_BREAK -#line 3802 "lex.yy.c" +#line 3757 "lex.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(vals_ok): yyterminate(); @@ -4030,7 +3985,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); + (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -4054,14 +4009,6 @@ static int yy_get_next_buffer (void) else ret_val = EOB_ACT_CONTINUE_SCAN; - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) lwg_parse_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; @@ -4208,7 +4155,7 @@ static int yy_get_next_buffer (void) case EOB_ACT_END_OF_FILE: { if ( lwg_parse_yywrap( ) ) - return EOF; + return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; @@ -4472,9 +4419,7 @@ static void lwg_parse_yyensure_buffer_stack (void) (yy_buffer_stack) = (struct yy_buffer_state**)lwg_parse_yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in lwg_parse_yyensure_buffer_stack()" ); - + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; @@ -4492,8 +4437,6 @@ static void lwg_parse_yyensure_buffer_stack (void) ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in lwg_parse_yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); @@ -4538,7 +4481,7 @@ YY_BUFFER_STATE lwg_parse_yy_scan_buffer (char * base, yy_size_t size ) /** Setup the input buffer state to scan a string. The next call to lwg_parse_yylex() will * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan + * @param str a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index 0f73a35da..514587b58 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -731,6 +731,7 @@ 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); +extern int lwcollection_ngeoms(const LWCOLLECTION *col); /* * Deserialize an lwgeom serialized form. diff --git a/liblwgeom/lwcollection.c b/liblwgeom/lwcollection.c index fecbcf19a..897d1a7a9 100644 --- a/liblwgeom/lwcollection.c +++ b/liblwgeom/lwcollection.c @@ -355,6 +355,86 @@ lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2) return 1; } +int lwcollection_ngeoms(const LWCOLLECTION *col) +{ + int i; + int ngeoms = 0; + + if( ! col ) { + lwerror("Null input geometry."); + return 0; + } + + for( i = 0; i < col->ngeoms; i++ ) + { + if( col->geoms[i]) { + switch(TYPE_GETTYPE(col->geoms[i]->type)) { + case POINTTYPE: + case LINETYPE: + case CURVETYPE: + case POLYGONTYPE: + ngeoms += 1; + break; + case MULTIPOINTTYPE: + case MULTILINETYPE: + case MULTICURVETYPE: + case MULTIPOLYGONTYPE: + ngeoms += col->ngeoms; + break; + case COLLECTIONTYPE: + ngeoms += lwcollection_ngeoms((LWCOLLECTION*)col->geoms[i]); + break; + } + } + } + return ngeoms; +} + +/* +** Given a generic collection, return the "simplest" form. +** eg: GEOMETRYCOLLECTION(MULTILINESTRING()) => MULTELINESTRING() +** GEOMETRYCOLLECTION(MULTILINESTRING(), MULTILINESTRING(), POINT()) => GEOMETRYCOLLECTION(MULTILINESTRING(), MULTIPOINT()) +** +** In general, if the subcomponents are homogeneous, return a properly typed collection. +** Otherwise, return a generic collection, with the subtypes in minimal typed collections. +LWCOLLECTION *lwcollection_homogenize(const LWCOLLECTION *c1) +{ +TODO: pramsey +} +*/ + +/* +** Given a generic collection, extract and return just the desired types. +LWGEOM *lwcollection_extract(const LWCOLLECTION *col, char type) +{ + LWGEOM **extracted_geoms; + extracted_geoms = lwalloc(sizeof(void*)*col->ngeoms); + extracted_curgeom = 0; + char reqtype = TYPE_GETTYPE(type); + for ( i = 0; i < col->ngeoms; i++ ) + { + if( col->geoms[i] ) + char geomtype = TYPE_GETTYPE(col->geoms[i]->type); + if ( geomtype == reqtype ) { + extracted_geoms[extracted_curgeom] = col->geoms[i]; + extracted_curgeom++; + continue; + } + else { + if ( geomtype == COLLECTIONTYPE ) { + LWGEOM *colgeom; + colgeom = lwcollection_extract(col->geoms[i], type); + extracted_geoms[extracted_curgeom] = colgeom->geoms; + extracted_curgeom++; + if( colgeom->bbox ) lwfree(colgeom->bbox); + lwfree(colgeom); + continue; + } + } +TODO: pramsey +} +*/ + void lwfree_collection(LWCOLLECTION *col) { diff --git a/lwgeom/lwgeom_functions_analytic.c b/lwgeom/lwgeom_functions_analytic.c index 6700782c0..5fdadcd7f 100644 --- a/lwgeom/lwgeom_functions_analytic.c +++ b/lwgeom/lwgeom_functions_analytic.c @@ -36,8 +36,8 @@ LWPOLY *simplify2d_lwpoly(const LWPOLY *ipoly, double dist); LWCOLLECTION *simplify2d_collection(const LWCOLLECTION *igeom, double dist); LWGEOM *simplify2d_lwgeom(const LWGEOM *igeom, double dist); Datum LWGEOM_simplify2d(PG_FUNCTION_ARGS); -Datum crossingDirection(PG_FUNCTION_ARGS); -Datum ST_LineClipZ(PG_FUNCTION_ARGS); +Datum ST_LineCrossingDirection(PG_FUNCTION_ARGS); +Datum ST_LocateBetweenElevations(PG_FUNCTION_ARGS); double determineSide(POINT2D *seg1, POINT2D *seg2, POINT2D *point); int isOnSegment(POINT2D *seg1, POINT2D *seg2, POINT2D *point); @@ -947,8 +947,8 @@ Datum LWGEOM_snaptogrid_pointoff(PG_FUNCTION_ARGS) ** Determines crossing direction of line2 relative to line1. ** Only accepts LINESTRING ass parameters! */ -PG_FUNCTION_INFO_V1(crossingDirection); -Datum crossingDirection(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(ST_LineCrossingDirection); +Datum ST_LineCrossingDirection(PG_FUNCTION_ARGS) { int type1, type2, rv; BOX2DFLOAT4 box1, box2; @@ -994,8 +994,8 @@ Datum crossingDirection(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(ST_LineClipZ); -Datum ST_LineClipZ(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(ST_LocateBetweenElevations); +Datum ST_LocateBetweenElevations(PG_FUNCTION_ARGS) { PG_LWGEOM *geom_in = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); double from = PG_GETARG_FLOAT8(1); diff --git a/lwgeom/lwpostgis.sql.in.c b/lwgeom/lwpostgis.sql.in.c index 4668876f3..799795c39 100644 --- a/lwgeom/lwpostgis.sql.in.c +++ b/lwgeom/lwpostgis.sql.in.c @@ -3967,16 +3967,23 @@ CREATEFUNCTION ST_ConvexHull(geometry) -- Only accepts LINESTRING as parameters. -- Availability: 1.4.0 -CREATEFUNCTION ST_CrossingDirection(geometry, geometry) +CREATEFUNCTION _ST_LineCrossingDirection(geometry, geometry) RETURNS integer - AS 'MODULE_PATHNAME', 'crossingDirection' + AS 'MODULE_PATHNAME', 'ST_LineCrossingDirection' LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable); +-- Availability: 1.4.0 +CREATE OR REPLACE FUNCTION ST_LineCrossingDirection(geometry, geometry) + RETURNS integer AS + $$ SELECT CASE WHEN NOT $1 && $2 THEN 0 ELSE _ST_LineCrossingDirection($1,$2) END $$ + LANGUAGE 'sql' IMMUTABLE; + + -- Only accepts LINESTRING as parameters. -- Availability: 1.4.0 -CREATEFUNCTION ST_LineClipZ(geometry, float8, float8) +CREATEFUNCTION ST_LocateBetweenElevations(geometry, float8, float8) RETURNS geometry - AS 'MODULE_PATHNAME', 'ST_LineClipZ' + AS 'MODULE_PATHNAME', 'ST_LocateBetweenElevations' LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable); #if POSTGIS_GEOS_VERSION >= 30