#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
shift;;
-T) no_target_directory=true;;
fi
shift # arg
dst_arg=$arg
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
done
fi
fi
if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
for src
do
- # Protect names starting with `-'.
+ # Protect names problematic for `test' and other utilities.
case $src in
- -*) src=./$src;;
+ -* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
-
dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
case $dstdir in
/*) prefix='/';;
- -*) prefix='./';;
+ [-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
for d
do
- test -z "$d" && continue
+ test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
lwpoly_free(poly);
}
+static void test_ptarray_desegmentize()
+{
+ LWGEOM *in, *out;
+ char *str;
+
+ in = lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1)");
+ out = lwgeom_desegmentize(in);
+ str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
+ CU_ASSERT_STRING_EQUAL(str, "CIRCULARSTRING(-1 0,0 1,0 -1)");
+ lwgeom_free(in);
+ lwgeom_free(out);
+ lwfree(str);
+
+ in = lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1, -1 -1)");
+ out = lwgeom_desegmentize(in);
+ str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
+ CU_ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,-1 -1))");
+ lwgeom_free(in);
+ lwgeom_free(out);
+ lwfree(str);
+
+ in = lwgeom_from_text("LINESTRING(-3 -3,-1 0, 0 1, 1 0, 0 -1, 0 -1.5, 0 -2, -1 -3, 0 -4, 1 -3,5 5)");
+ out = lwgeom_desegmentize(in);
+ str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
+ CU_ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE((-3 -3,-1 0),CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,0 -1.5,0 -2),CIRCULARSTRING(0 -2,-1 -3,1 -3),(1 -3,5 5))");
+ lwgeom_free(in);
+ lwgeom_free(out);
+ lwfree(str);
+
+ in = lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1, -1 -2, 0 -3, 1 -2)");
+ out = lwgeom_desegmentize(in);
+ str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
+ CU_ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),CIRCULARSTRING(0 -1,-1 -2,1 -2))");
+ lwgeom_free(in);
+ lwgeom_free(out);
+ lwfree(str);
+
+ in = lwgeom_segmentize(lwgeom_from_text("COMPOUNDCURVE((0 0, 1 1), CIRCULARSTRING(1 1, 2 2, 3 1), (3 1, 4 4))"),8);
+ out = lwgeom_desegmentize(in);
+ str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
+ CU_ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE((0 0,1 1,1 1),CIRCULARSTRING(1 1,1.8049097 1.9807853,3 1),(3 1,4 4))");
+ lwgeom_free(in);
+ lwgeom_free(out);
+// printf("%s\n", str);
+ lwfree(str);
+
+}
/*
** Used by the test harness to register the tests in this file.
PG_TEST(test_ptarray_append_ptarray),
PG_TEST(test_ptarray_locate_point),
PG_TEST(test_ptarray_isccw),
+ PG_TEST(test_ptarray_desegmentize),
CU_TEST_INFO_NULL
};
CU_SuiteInfo ptarray_suite = {"ptarray", NULL, NULL, ptarray_tests };
}
/* Apply check for minimum number of points, if requested. */
- if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) &&
- (lwgeom_count_vertices(ring) < 4) )
+ if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) )
{
- LWDEBUG(4,"number of points is incorrect");
- lwgeom_free(ring);
- lwgeom_free(poly);
- SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
- return NULL;
+ int vertices_needed = 3;
+
+ if ( ring->type == LINETYPE )
+ vertices_needed = 4;
+
+ if (lwgeom_count_vertices(ring) < vertices_needed)
+ {
+ LWDEBUG(4,"number of points is incorrect");
+ lwgeom_free(ring);
+ lwgeom_free(poly);
+ SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
+ return NULL;
+ }
}
/* Apply check for not closed rings, if requested. */
lwcompound_segmentize(const LWCOMPOUND *icompound, uint32_t perQuad)
{
LWGEOM *geom;
- POINTARRAY *ptarray = NULL;
+ POINTARRAY *ptarray = NULL, *ptarray_out = NULL;
LWLINE *tmp = NULL;
uint32_t i, j;
POINT4D p;
return NULL;
}
}
- return lwline_construct(icompound->srid, NULL, ptarray);
+ ptarray_out = ptarray_remove_repeated_points(ptarray);
+ ptarray_free(ptarray);
+ return lwline_construct(icompound->srid, NULL, ptarray_out);
}
LWPOLY *
return NULL;
}
-LWGEOM *
+/**
+* Returns LW_TRUE if b is on the arc formed by a1/a2/a3, but not within
+* that portion already described by a1/a2/a3
+*/
+static int pt_continues_arc(const POINT4D *a1, const POINT4D *a2, const POINT4D *a3, const POINT4D *b)
+{
+ POINT4D center;
+ POINT4D *centerptr=¢er;
+ double radius = lwcircle_center(a1, a2, a3, ¢er);
+
+ /* Co-linear a1/a2/a3 */
+ if ( radius < 0.0 )
+ return LW_FALSE;
+
+ /* Is the point b on the circle? */
+ if ( fabs(radius - distance2d_pt_pt((POINT2D*)b, (POINT2D*)centerptr)) < EPSILON_SQLMM )
+// if ( FP_EQUALS(radius, distance2d_pt_pt((POINT2D*)b, (POINT2D*)centerptr)) )
+ {
+ int a2_side = signum(lw_segment_side((POINT2D*)a1, (POINT2D*)a3, (POINT2D*)a2));
+ int b_side = signum(lw_segment_side((POINT2D*)a1, (POINT2D*)a3, (POINT2D*)b));
+
+ /* Is the point b on the same side of a1/a3 as the mid-point a2 is? */
+ /* If not, it's in the unbounded part of the circle, so it continues the arc, return true. */
+ if ( b_side != a2_side )
+ return LW_TRUE;
+ }
+ return LW_FALSE;
+}
+
+LWGEOM* pta_desegmentize2(POINTARRAY *points, int type, int srid);
+
+static LWGEOM*
+linestring_from_pa(const POINTARRAY *pa, int srid, int start, int end)
+{
+ int i = 0, j = 0;
+ POINT4D p;
+ POINTARRAY *pao = ptarray_construct(ptarray_has_z(pa), ptarray_has_m(pa), end-start+2);
+ LWDEBUGF(4, "srid=%d, start=%d, end=%d", srid, start, end);
+ for( i = start; i < end + 2; i++ )
+ {
+ getPoint4d_p(pa, i, &p);
+ ptarray_set_point4d(pao, j++, &p);
+ }
+ return lwline_as_lwgeom(lwline_construct(srid, NULL, pao));
+}
+
+static LWGEOM*
+circstring_from_pa(const POINTARRAY *pa, int srid, int start, int end)
+{
+
+ POINT4D p0, p1, p2;
+ POINTARRAY *pao = ptarray_construct(ptarray_has_z(pa), ptarray_has_m(pa), 3);
+ LWDEBUGF(4, "srid=%d, start=%d, end=%d", srid, start, end);
+ getPoint4d_p(pa, start, &p0);
+ ptarray_set_point4d(pao, 0, &p0);
+ getPoint4d_p(pa, (start+end)/2, &p1);
+ ptarray_set_point4d(pao, 1, &p1);
+ getPoint4d_p(pa, end+1, &p2);
+ ptarray_set_point4d(pao, 2, &p2);
+ return lwcircstring_as_lwgeom(lwcircstring_construct(srid, NULL, pao));
+}
+
+static LWGEOM*
+geom_from_pa(const POINTARRAY *pa, int srid, int is_arc, int start, int end)
+{
+ LWDEBUGF(4, "srid=%d, is_arc=%d, start=%d, end=%d", srid, is_arc, start, end);
+ if ( is_arc )
+ return circstring_from_pa(pa, srid, start, end);
+ else
+ return linestring_from_pa(pa, srid, start, end);
+}
+
+LWGEOM*
pta_desegmentize(POINTARRAY *points, int type, int srid)
+{
+ int i = 0, j, k;
+ POINT4D a1, a2, a3, b;
+ char *edges_in_arcs;
+ int found_arc = LW_FALSE;
+ int current_arc = 1;
+ int num_edges;
+ int edge_type = -1;
+ int start, end;
+ LWCOLLECTION *outcol;
+
+ /* Die on null input */
+ if ( ! points )
+ lwerror("pta_desegmentize called with null pointarray");
+
+ /* Null on empty input? */
+ if ( points->npoints == 0 )
+ return NULL;
+
+ /* We can't desegmentize anything shorter than four points */
+ if ( points->npoints < 4 )
+ {
+ /* Return a linestring here*/
+ lwerror("pta_desegmentize needs implementation for npoints < 4");
+ }
+
+ /* Allocate our result array of vertices that are part of arcs */
+ num_edges = points->npoints - 1;
+ edges_in_arcs = lwalloc(num_edges);
+ memset(edges_in_arcs, 0, num_edges);
+
+ /* We make a candidate arc of the first two edges, */
+ /* And then see if the next edge follows it */
+ while( i < num_edges-2 )
+ {
+ found_arc = LW_FALSE;
+ /* Make candidate arc */
+ getPoint4d_p(points, i , &a1);
+ getPoint4d_p(points, i+1, &a2);
+ getPoint4d_p(points, i+2, &a3);
+ for( j = i+3; j < num_edges+1; j++ )
+ {
+ LWDEBUGF(4, "i=%d, j=%d", i, j);
+ getPoint4d_p(points, j, &b);
+ /* Does this point fall on our candidate arc? */
+ if ( pt_continues_arc(&a1, &a2, &a3, &b) )
+ {
+ /* Yes. Mark this edge and the two preceding it as arc components */
+ LWDEBUGF(4, "pt_continues_arc #%d", current_arc);
+ found_arc = LW_TRUE;
+ for ( k = j-1; k > j-4; k-- )
+ edges_in_arcs[k] = current_arc;
+ }
+ else
+ {
+ /* No. So we're done with this candidate arc */
+ LWDEBUG(4, "pt_continues_arc = false");
+ current_arc++;
+ break;
+ }
+ }
+ /* Jump past all the edges that were added to the arc */
+ if ( found_arc )
+ {
+ i = j-1;
+ }
+ else
+ {
+ /* Mark this edge as a linear edge */
+ edges_in_arcs[i] = 0;
+ i = i+1;
+ }
+ }
+
+#if POSTGIS_DEBUG_LEVEL > 3
+ {
+ char *edgestr = lwalloc(num_edges+1);
+ for ( i = 0; i < num_edges; i++ )
+ {
+ if ( edges_in_arcs[i] )
+ edgestr[i] = 48 + edges_in_arcs[i];
+ else
+ edgestr[i] = '.';
+ }
+ edgestr[num_edges] = 0;
+ LWDEBUGF(3, "edge pattern %s", edgestr);
+ lwfree(edgestr);
+ }
+#endif
+
+ start = 0;
+ edge_type = edges_in_arcs[0];
+ outcol = lwcollection_construct_empty(COMPOUNDTYPE, srid, ptarray_has_z(points), ptarray_has_m(points));
+ for( i = 1; i < num_edges; i++ )
+ {
+ if( edge_type != edges_in_arcs[i] )
+ {
+ end = i - 1;
+ lwcollection_add_lwgeom(outcol, geom_from_pa(points, srid, edge_type, start, end));
+ start = i;
+ edge_type = edges_in_arcs[i];
+ }
+ }
+ /* Roll out last item */
+ end = num_edges - 1;
+ lwcollection_add_lwgeom(outcol, geom_from_pa(points, srid, edge_type, start, end));
+
+ /* Strip down to singleton if only one entry */
+ if ( outcol->ngeoms == 1 )
+ {
+ LWGEOM *outgeom = outcol->geoms[0];
+ lwfree(outcol);
+ return outgeom;
+ }
+ return lwcollection_as_lwgeom(outcol);
+}
+
+LWGEOM *
+pta_desegmentize2(POINTARRAY *points, int type, int srid)
{
int i, j, commit, isline, count;
double last_angle, last_length;
SAOffset SADFSeek( SAFile file, SAOffset offset, int whence )
{
- return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
+ return (SAOffset) fseeko( (FILE *) file, (off_t) offset, whence );
}
/************************************************************************/
SAOffset SADFTell( SAFile file )
{
- return (SAOffset) ftell( (FILE *) file );
+ return (SAOffset) ftello( (FILE *) file );
}
/************************************************************************/
* try to improve SHPAPI_CALL docs
*/
+#define _FILE_OFFSET_BITS 64
#include <stdio.h>
+#include <sys/types.h>
#ifdef USE_DBMALLOC
#include <dbmalloc.h>
SELECT 'valid ewkb curve polygon 3', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000001000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec0', 'hex')));\r
SELECT 'valid ewkb curve polygon 4', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00102000000060000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex')));\r
SELECT 'valid ewkb curve polygon 5', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00109000000030000000108000000030000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c001020000000200000000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c0010800000003000000000000e0107f6240000000c0a10440c04e1c0c14624c6240bf3fb6405c793fc06844c4fe011b6240342e2993e0423fc0', 'hex')));\r
-SELECT ST_GeomFromEWKT('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )');\r
-SELECT ST_GeomFromEWKT('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), (1.7 1, 1.4 0.4, 1.7 1) )');\r
-SELECT ST_GeomFromEWKT('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )');\r
+SELECT 'valid curve 6', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )');\r
+SELECT 'valid curve 7', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), (1.7 1, 1.4 0.4, 1.7 1) )');\r
+SELECT 'valid curve 8', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )');\r
SELECT 'null response', ST_NumPoints(ST_GeomFromEWKT('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'));\r
valid ewkb curve polygon 3|CURVEPOLYGON(CIRCULARSTRING(143.620251668383 -30.0374973560768,142.928571472997 -32.751011968744,145.961323098919 -34.9856710615288,149.575653076172 -33.4115333557129,149.419724075848 -29.8246726805735,146.120941605547 -30.1971158627043,143.620251668383 -30.0374973560768))
valid ewkb curve polygon 4|CURVEPOLYGON(CIRCULARSTRING(143.620251668383 -30.0374973560768,142.928571472997 -32.751011968744,145.961323098919 -34.9856710615288,149.575653076172 -33.4115333557129,149.419724075848 -29.8246726805735,146.120941605547 -30.1971158627043,143.620251668383 -30.0374973560768),(144.843993552527 -31.2612392402209,144.205519526017 -32.2721564488616,145.552307128906 -33.4920387268066,147.970809936523 -32.0361862182617,146.386972449926 -31.4740639157242,144.843993552527 -31.2612392402209))
valid ewkb curve polygon 5|CURVEPOLYGON((143.620251668383 -30.0374973560768,142.928571472997 -32.751011968744,145.961323098919 -34.9856710615288,149.575653076172 -33.4115333557129,149.419724075848 -29.8246726805735,146.120941605547 -30.1971158627043,143.620251668383 -30.0374973560768),COMPOUNDCURVE(CIRCULARSTRING(144.843993552527 -31.2612392402209,144.205519526017 -32.2721564488616,145.552307128906 -33.4920387268066),(145.552307128906 -33.4920387268066,147.970809936523 -32.0361862182617),CIRCULARSTRING(147.970809936523 -32.0361862182617,146.386972449926 -31.4740639157242,144.843993552527 -31.2612392402209)))
-ERROR: geometry requires more points
-HINT: "...CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1)" <-- parse error at position 126 within geometry
+valid curve 6|010A0000000200000001090000000200000001080000000500000000000000000000000000000000000000000000000000004000000000000000000000000000000040000000000000F03F00000000000000400000000000000840000000000000104000000000000008400102000000040000000000000000001040000000000000084000000000000010400000000000001440000000000000F03F000000000000104000000000000000000000000000000000010800000003000000333333333333FB3F000000000000F03F666666666666F63F9A9999999999D93F333333333333FB3F000000000000F03F
ERROR: geometry requires more points
HINT: "..., 1 4, 0 0)), (1.7 1, 1.4 0.4, 1.7 1)" <-- parse error at position 112 within geometry
-ERROR: geometry requires more points
-HINT: "...CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1)" <-- parse error at position 116 within geometry
-ERROR: geometry requires more points
-HINT: "...CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1)" <-- parse error at position 126 within geometry
+valid curve 8|010A0000000200000001090000000200000001080000000500000000000000000000000000000000000000000000000000004000000000000000000000000000000040000000000000F03F00000000000000400000000000000840000000000000104000000000000008400102000000020000000000000000001040000000000000084000000000000000000000000000000000010800000003000000333333333333FB3F000000000000F03F666666666666F63F9A9999999999D93F333333333333FB3F000000000000F03F
+null response|
#68a|MULTIPOINT(1 3,4 5)
ERROR: lwgeom_longitude_shift: unsupported geom type: CircularString
#69|CIRCULARSTRING(220269 150417,220228 150507,220228 150408)
-#70|5
+#70|3
#73|GEOMETRYCOLLECTION(CIRCULARSTRING(1 1,2 3,4 5,6 7,5 6))
#80|MULTILINESTRING((0 0,1 1))
#83|MULTICURVE(CIRCULARSTRING(220268 150415,220227 150505,220227 150406))
#179a|
NOTICE: No points or linestrings in input array
#179b|
-#183|COMPOUNDCURVE(CIRCULARSTRING(0 0,0.5 1.2071067812,1 0),(1 0,0 1))
+#183|CIRCULARSTRING(0 0,0.5 1.2071067812,0 1)
#210a|
NOTICE: No points or linestrings in input array
#210b|
#835.11|MULTILINESTRING EMPTY
#835.12|MULTIPOLYGON EMPTY
#650|MULTIPOINT(0 0,1 1,2 2)
-#667|SRID=4326;CURVEPOLYGON(CIRCULARSTRING(30 40,18.2842712474619 11.7157287525381,-9.99999999999994 0,-38.284271247462 68.2842712474618,30 40))
+#667|SRID=4326;CURVEPOLYGON(CIRCULARSTRING(30 40,-49.2314112161292 32.1963871193548,30 40))
#677|1121395
#680|01d107000000000000000024c000000000000049400000000000000040
#682|0103000020E610000000000000