示例#1
0
static void test_ptarray_signed_area() 
{
	LWLINE *line;
	double area;

	/* parallelogram */
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,1 1, 2 1, 1 0, 0 0)"));
	area = ptarray_signed_area(line->points);
	CU_ASSERT_DOUBLE_EQUAL(area, 1.0, 0.0000001);
	lwline_free(line);

	/* square */
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 2, 2 2, 2 0, 0 0)"));
	area = ptarray_signed_area(line->points);
	CU_ASSERT_DOUBLE_EQUAL(area, 4.0, 0.0000001);
	lwline_free(line);

	/* square backwares*/
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,2 0, 2 2, 0 2, 0 0)"));
	area = ptarray_signed_area(line->points);
	//printf("%g\n",area);
	CU_ASSERT_DOUBLE_EQUAL(area, -4.0, 0.0000001);
	lwline_free(line);
	
}
示例#2
0
static void test_lwline_crossing_long_lines(void)
{
	LWLINE *l51;
	LWLINE *l52;
	/*
	** More complex test, longer lines and multiple crossings
	*/
	/* Vertical line with vertices at y integers */
	l51 = (LWLINE*)lwgeom_from_wkt("LINESTRING(0 0, 0 1, 0 2, 0 3, 0 4)", LW_PARSER_CHECK_NONE);

	/* Two crossings at segment midpoints */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1, -1 1.5, 1 3, 1 4, 1 5)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_MULTICROSS_END_SAME_FIRST_LEFT );
	lwline_free(l52);

	/* One crossing at interior vertex */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1, 0 1, -1 1, -1 2, -1 3)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_CROSS_LEFT );
	lwline_free(l52);

	/* Two crossings at interior vertices */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1, 0 1, -1 1, 0 3, 1 3)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_MULTICROSS_END_SAME_FIRST_LEFT );
	lwline_free(l52);

	/* Two crossings, one at the first vertex on at interior vertex */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 0, 0 0, -1 1, 0 3, 1 3)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_MULTICROSS_END_SAME_FIRST_LEFT );
	lwline_free(l52);

	/* Two crossings, one at the first vertex on the next interior vertex */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 0, 0 0, -1 1, 0 1, 1 2)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_MULTICROSS_END_SAME_FIRST_LEFT );
	lwline_free(l52);

	/* Three crossings, two at midpoints, one at vertex */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(0.5 1, -1 0.5, 1 2, -1 2, -1 3)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_MULTICROSS_END_LEFT );
	lwline_free(l52);

	/* One mid-point co-linear crossing */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1, 0 1.5, 0 2.5, -1 3, -1 4)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_CROSS_LEFT );
	lwline_free(l52);

	/* One on-vertices co-linear crossing */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1, 0 1, 0 2, -1 4, -1 4)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_CROSS_LEFT );
	lwline_free(l52);

	/* No crossing, but end on a co-linearity. */
	l52 = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1, 1 2, 1 3, 0 3, 0 4)", LW_PARSER_CHECK_NONE);
	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_NO_CROSS );
	lwline_free(l52);

	lwline_free(l51);

}
示例#3
0
static void test_ptarray_locate_point(void)
{
	LWLINE *line;
	double loc, dist;
	POINT4D p, l;

	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 3,20 4)"));

	p = getPoint4d(line->points, 0);
	loc = ptarray_locate_point(line->points, &p, &dist, &l);
	CU_ASSERT_EQUAL(loc, 0);
	CU_ASSERT_EQUAL(dist, 0.0);

	p = getPoint4d(line->points, 1);
	loc = ptarray_locate_point(line->points, &p, &dist, &l);
	CU_ASSERT_EQUAL(loc, 1);
	CU_ASSERT_EQUAL(dist, 0.0);

	p.x = 21; p.y = 4;
	loc = ptarray_locate_point(line->points, &p, &dist, NULL);
	CU_ASSERT_EQUAL(loc, 1);
	CU_ASSERT_EQUAL(dist, 1.0);

	p.x = 0; p.y = 2;
	loc = ptarray_locate_point(line->points, &p, &dist, &l);
	CU_ASSERT_EQUAL(loc, 0);
	CU_ASSERT_EQUAL(dist, 1.0);

	lwline_free(line);
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,20 0,40 0)"));

	p.x = 20; p.y = 0;
	loc = ptarray_locate_point(line->points, &p, &dist, &l);
	CU_ASSERT_EQUAL(loc, 0.5);
	CU_ASSERT_EQUAL(dist, 0.0);

	lwline_free(line);
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-40 0,0 0,20 0,40 0)"));

	p.x = 20; p.y = 0;
	loc = ptarray_locate_point(line->points, &p, &dist, &l);
	CU_ASSERT_EQUAL(loc, 0.75);
	CU_ASSERT_EQUAL(dist, 0.0);

	lwline_free(line);
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING M (0 0 0, 10 0 20)"));

	p.x = 5; p.y = 0;
	loc = ptarray_locate_point(line->points, &p, &dist, &l);
	CU_ASSERT_EQUAL(loc, 0.5);
	CU_ASSERT_EQUAL(dist, 0.0);
	CU_ASSERT_EQUAL(l.m, 10.0);	

	lwline_free(line);

}
示例#4
0
static void test_lwline_crossing_bugs(void)
{
	LWLINE *l1;
	LWLINE *l2;

	l1 = (LWLINE*)lwgeom_from_wkt("LINESTRING(2.99 90.16,71 74,20 140,171 154)", LW_PARSER_CHECK_NONE);
	l2 = (LWLINE*)lwgeom_from_wkt("LINESTRING(25 169,89 114,40 70,86 43)", LW_PARSER_CHECK_NONE);

	CU_ASSERT( lwline_crossing_direction(l1, l2) == LINE_MULTICROSS_END_RIGHT );
	lwline_free(l1);
	lwline_free(l2);

}
示例#5
0
static void do_test_lwgeom_effectivearea_lines(void)
{
	LWLINE *the_geom;
	int avoid_collaps=2;
	/*Line 1*/
	the_geom = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1, 0 1, 0 2, -1 4, -1 4)", LW_PARSER_CHECK_NONE);
	double the_areas1[]={FLT_MAX,0.5,0.5,0,FLT_MAX};
	do_test_lwgeom_effectivearea(the_geom->points,the_areas1,avoid_collaps);
	lwline_free(the_geom);
	/*Line 2*/
	the_geom = (LWLINE*)lwgeom_from_wkt("LINESTRING(10 10,12 8, 15 7, 18 7, 20 20, 15 21, 18 22, 10 30, 40 100)", LW_PARSER_CHECK_NONE);
	double the_areas2[]={FLT_MAX,5,1.5,55,100,4,4,300,FLT_MAX};
	do_test_lwgeom_effectivearea(the_geom->points,the_areas2,avoid_collaps);
	lwline_free(the_geom);
}
示例#6
0
static void test_lwline_clip_big(void)
{
	POINTARRAY *pa = ptarray_construct(1, 0, 3);
	LWLINE *line = lwline_construct(SRID_UNKNOWN, NULL, pa);
	LWCOLLECTION *c;
	char *ewkt;
	POINT4D p;

	p.x = 0.0;
	p.y = 0.0;
	p.z = 0.0;
	ptarray_set_point4d(pa, 0, &p);

	p.x = 1.0;
	p.y = 1.0;
	p.z = 1.0;
	ptarray_set_point4d(pa, 1, &p);

	p.x = 2.0;
	p.y = 2.0;
	p.z = 2.0;
	ptarray_set_point4d(pa, 2, &p);

	c = lwline_clip_to_ordinate_range(line, 'Z', 0.5, 1.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0.5 0.5 0.5,1 1 1,1.5 1.5 1.5))" );

	lwfree(ewkt);
	lwcollection_free(c);
	lwline_free(line);
}
示例#7
0
/*
 * @param icompound input curve polygon
 * @param tol tolerance, semantic driven by tolerance_type
 * @param tolerance_type see LW_LINEARIZE_TOLERANCE_TYPE
 * @param flags see flags in lwarc_linearize
 *
 * @return a newly allocated LWPOLY
 */
static LWPOLY *
lwcurvepoly_linearize(const LWCURVEPOLY *curvepoly, double tol,
                       LW_LINEARIZE_TOLERANCE_TYPE tolerance_type,
                       int flags)
{
	LWPOLY *ogeom;
	LWGEOM *tmp;
	LWLINE *line;
	POINTARRAY **ptarray;
	int i;

	LWDEBUG(2, "lwcurvepoly_linearize called.");

	ptarray = lwalloc(sizeof(POINTARRAY *)*curvepoly->nrings);

	for (i = 0; i < curvepoly->nrings; i++)
	{
		tmp = curvepoly->rings[i];
		if (tmp->type == CIRCSTRINGTYPE)
		{
			line = lwcircstring_linearize((LWCIRCSTRING *)tmp, tol, tolerance_type, flags);
			ptarray[i] = ptarray_clone_deep(line->points);
			lwline_free(line);
		}
		else if (tmp->type == LINETYPE)
		{
			line = (LWLINE *)tmp;
			ptarray[i] = ptarray_clone_deep(line->points);
		}
		else if (tmp->type == COMPOUNDTYPE)
		{
			line = lwcompound_linearize((LWCOMPOUND *)tmp, tol, tolerance_type, flags);
			ptarray[i] = ptarray_clone_deep(line->points);
			lwline_free(line);
		}
		else
		{
			lwerror("Invalid ring type found in CurvePoly.");
			return NULL;
		}
	}

	ogeom = lwpoly_construct(curvepoly->srid, NULL, curvepoly->nrings, ptarray);
	return ogeom;
}
示例#8
0
static void test_geohash(void)
{
	LWPOINT *lwpoint = NULL;
	LWLINE *lwline = NULL;
	LWMLINE *lwmline = NULL;
	char *geohash = NULL;

	lwpoint = (LWPOINT*)lwgeom_from_wkt("POINT(23.0 25.2)", LW_PARSER_CHECK_NONE);
	geohash = lwgeom_geohash((LWGEOM*)lwpoint,0);
	//printf("\ngeohash %s\n",geohash);
	CU_ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx");
	lwpoint_free(lwpoint);
	lwfree(geohash);

	lwpoint = (LWPOINT*)lwgeom_from_wkt("POINT(23.0 25.2 2.0)", LW_PARSER_CHECK_NONE);
	geohash = lwgeom_geohash((LWGEOM*)lwpoint,0);
	//printf("geohash %s\n",geohash);
	CU_ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx");
	lwpoint_free(lwpoint);
	lwfree(geohash);

	lwline = (LWLINE*)lwgeom_from_wkt("LINESTRING(23.0 23.0,23.1 23.1)", LW_PARSER_CHECK_NONE);
	geohash = lwgeom_geohash((LWGEOM*)lwline,0);
	//printf("geohash %s\n",geohash);
	CU_ASSERT_STRING_EQUAL(geohash, "ss0");
	lwline_free(lwline);
	lwfree(geohash);

	lwline = (LWLINE*)lwgeom_from_wkt("LINESTRING(23.0 23.0,23.001 23.001)", LW_PARSER_CHECK_NONE);
	geohash = lwgeom_geohash((LWGEOM*)lwline,0);
	//printf("geohash %s\n",geohash);
	CU_ASSERT_STRING_EQUAL(geohash, "ss06g7");
	lwline_free(lwline);
	lwfree(geohash);

	lwmline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((23.0 23.0,23.1 23.1),(23.0 23.0,23.1 23.1))", LW_PARSER_CHECK_NONE);
	geohash = lwgeom_geohash((LWGEOM*)lwmline,0);
	//printf("geohash %s\n",geohash);
	CU_ASSERT_STRING_EQUAL(geohash, "ss0");
	lwmline_free(lwmline);
	lwfree(geohash);
}
示例#9
0
static void test_ptarray_isccw(void)
{
	LWLINE *line;
	LWPOLY* poly;
	int ccw;

	/* clockwise rectangle */
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 10,10 10,10 0, 0 0)"));
	ccw = ptarray_isccw(line->points);
	CU_ASSERT_EQUAL(ccw, 0);
	lwline_free(line);

	/* clockwise triangle */
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 3,20 4,20 3, 0 3)"));
	ccw = ptarray_isccw(line->points);
	CU_ASSERT_EQUAL(ccw, 0);
	lwline_free(line);

	/* counterclockwise triangle */
	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 3,20 3,20 4, 0 3)"));
	ccw = ptarray_isccw(line->points);
	CU_ASSERT_EQUAL(ccw, 1);
	lwline_free(line);

	/* counterclockwise narrow ring (see ticket #1302) */
	line = lwgeom_as_lwline(lwgeom_from_hexwkb("01020000000500000000917E9BA468294100917E9B8AEA284137894120A4682941C976BE9F8AEA2841B39ABE1FA46829415ACCC29F8AEA2841C976BE1FA4682941C976BE9F8AEA284100917E9BA468294100917E9B8AEA2841", LW_PARSER_CHECK_NONE));
	ccw = ptarray_isccw(line->points);
	CU_ASSERT_EQUAL(ccw, 1);
	lwline_free(line);

	/* clockwise narrow ring (see ticket #1302) */
	line = lwgeom_as_lwline(lwgeom_from_hexwkb("01020000000500000000917E9BA468294100917E9B8AEA2841C976BE1FA4682941C976BE9F8AEA2841B39ABE1FA46829415ACCC29F8AEA284137894120A4682941C976BE9F8AEA284100917E9BA468294100917E9B8AEA2841", LW_PARSER_CHECK_NONE));
	ccw = ptarray_isccw(line->points);
	CU_ASSERT_EQUAL(ccw, 0);
	lwline_free(line);

	/* Clockwise narrow ring (see ticket #1302) */
	poly = lwgeom_as_lwpoly(lwgeom_from_hexwkb("0103000000010000000500000000917E9BA468294100917E9B8AEA2841C976BE1FA4682941C976BE9F8AEA2841B39ABE1FA46829415ACCC29F8AEA284137894120A4682941C976BE9F8AEA284100917E9BA468294100917E9B8AEA2841", LW_PARSER_CHECK_NONE));
	ccw = ptarray_isccw(poly->rings[0]);
	CU_ASSERT_EQUAL(ccw, 0);
	lwpoly_free(poly);
}
示例#10
0
double lwcompound_length_2d(const LWCOMPOUND *comp)
{
	double length = 0.0;
	LWLINE *line;
	if ( lwgeom_is_empty((LWGEOM*)comp) )
		return 0.0;
	line = lwcompound_stroke(comp, 32);
	length = lwline_length_2d(line);
	lwline_free(line);
	return length;
}
示例#11
0
double lwcircstring_length_2d(const LWCIRCSTRING *circ)
{
	double length = 0.0;
	LWLINE *line;
	if ( lwcircstring_is_empty(circ) )
		return 0.0;
	line = lwcircstring_segmentize(circ, 32);
	length = lwline_length_2d(line);
	lwline_free(line);
	return length;
}
示例#12
0
void lwgeom_free(LWGEOM *lwgeom)
{

	/* There's nothing here to free... */
	if( ! lwgeom ) return;

	LWDEBUGF(5,"freeing a %s",lwtype_name(lwgeom->type));
	
	switch (lwgeom->type)
	{
	case POINTTYPE:
		lwpoint_free((LWPOINT *)lwgeom);
		break;
	case LINETYPE:
		lwline_free((LWLINE *)lwgeom);
		break;
	case POLYGONTYPE:
		lwpoly_free((LWPOLY *)lwgeom);
		break;
	case CIRCSTRINGTYPE:
		lwcircstring_free((LWCIRCSTRING *)lwgeom);
		break;
	case TRIANGLETYPE:
		lwtriangle_free((LWTRIANGLE *)lwgeom);
		break;
	case MULTIPOINTTYPE:
		lwmpoint_free((LWMPOINT *)lwgeom);
		break;
	case MULTILINETYPE:
		lwmline_free((LWMLINE *)lwgeom);
		break;
	case MULTIPOLYGONTYPE:
		lwmpoly_free((LWMPOLY *)lwgeom);
		break;
	case POLYHEDRALSURFACETYPE:
		lwpsurface_free((LWPSURFACE *)lwgeom);
		break;
	case TINTYPE:
		lwtin_free((LWTIN *)lwgeom);
		break;
	case CURVEPOLYTYPE:
	case COMPOUNDTYPE:
	case MULTICURVETYPE:
	case MULTISURFACETYPE:
	case COLLECTIONTYPE:
		lwcollection_free((LWCOLLECTION *)lwgeom);
		break;
	default:
		lwerror("lwgeom_free called with unknown type (%d) %s", lwgeom->type, lwtype_name(lwgeom->type));
	}
	return;
}
示例#13
0
void lwmline_free(LWMLINE *mline)
{
	int i;
	if ( mline->bbox )
		lwfree(mline->bbox);

	for ( i = 0; i < mline->ngeoms; i++ )
		if ( mline->geoms && mline->geoms[i] )
			lwline_free(mline->geoms[i]);

	if ( mline->geoms )
		lwfree(mline->geoms);

	lwfree(mline);
}
示例#14
0
/*
 * @param icompound input compound curve
 * @param tol tolerance, semantic driven by tolerance_type
 * @param tolerance_type see LW_LINEARIZE_TOLERANCE_TYPE
 * @param flags see flags in lwarc_linearize
 *
 * @return a newly allocated LWLINE
 */
static LWLINE *
lwcompound_linearize(const LWCOMPOUND *icompound, double tol,
                      LW_LINEARIZE_TOLERANCE_TYPE tolerance_type,
                      int flags)
{
	LWGEOM *geom;
	POINTARRAY *ptarray = NULL, *ptarray_out = NULL;
	LWLINE *tmp = NULL;
	uint32_t i, j;
	POINT4D p;

	LWDEBUG(2, "lwcompound_stroke called.");

	ptarray = ptarray_construct_empty(FLAGS_GET_Z(icompound->flags), FLAGS_GET_M(icompound->flags), 64);

	for (i = 0; i < icompound->ngeoms; i++)
	{
		geom = icompound->geoms[i];
		if (geom->type == CIRCSTRINGTYPE)
		{
			tmp = lwcircstring_linearize((LWCIRCSTRING *)geom, tol, tolerance_type, flags);
			for (j = 0; j < tmp->points->npoints; j++)
			{
				getPoint4d_p(tmp->points, j, &p);
				ptarray_append_point(ptarray, &p, LW_TRUE);
			}
			lwline_free(tmp);
		}
		else if (geom->type == LINETYPE)
		{
			tmp = (LWLINE *)geom;
			for (j = 0; j < tmp->points->npoints; j++)
			{
				getPoint4d_p(tmp->points, j, &p);
				ptarray_append_point(ptarray, &p, LW_TRUE);
			}
		}
		else
		{
			lwerror("Unsupported geometry type %d found.",
			        geom->type, lwtype_name(geom->type));
			return NULL;
		}
	}
	ptarray_out = ptarray_remove_repeated_points(ptarray, 0.0);
	ptarray_free(ptarray);
	return lwline_construct(icompound->srid, NULL, ptarray_out);
}
示例#15
0
static void test_ptarray_insert_point(void)
{
	LWLINE *line;
	char *wkt;
	POINT4D p;

	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY"));
	p.x = 1; 
	p.y = 1;
	ptarray_insert_point(line->points, &p, 0);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line));
	CU_ASSERT_STRING_EQUAL(wkt,"LINESTRING(1 1)");
	lwfree(wkt);

	p.x = 2; 
	p.y = 20;
	ptarray_insert_point(line->points, &p, 0);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line));
	CU_ASSERT_STRING_EQUAL(wkt,"LINESTRING(2 20,1 1)");
	lwfree(wkt);

	p.x = 3; 
	p.y = 30;
	ptarray_insert_point(line->points, &p, 1);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line));
	CU_ASSERT_STRING_EQUAL(wkt,"LINESTRING(2 20,3 30,1 1)");
	lwfree(wkt);

	p.x = 4; 
	p.y = 40;
	ptarray_insert_point(line->points, &p, 0);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line));
	CU_ASSERT_STRING_EQUAL(wkt,"LINESTRING(4 40,2 20,3 30,1 1)");
	lwfree(wkt);

	p.x = 5; 
	p.y = 50;
	ptarray_insert_point(line->points, &p, 4);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line));
	CU_ASSERT_STRING_EQUAL(wkt,"LINESTRING(4 40,2 20,3 30,1 1,5 50)");
	lwfree(wkt);

	lwline_free(line);
}
示例#16
0
static void test_ptarray_append_point(void)
{
	LWLINE *line;
	char *wkt;
	POINT4D p;

	line = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,1 1)"));
	p.x = 1; 
	p.y = 1;
	ptarray_append_point(line->points, &p, LW_TRUE);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line));
	CU_ASSERT_STRING_EQUAL(wkt,"LINESTRING(0 0,1 1,1 1)");
	lwfree(wkt);

	ptarray_append_point(line->points, &p, LW_FALSE);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line));
	CU_ASSERT_STRING_EQUAL(wkt,"LINESTRING(0 0,1 1,1 1)");
	lwfree(wkt);

	lwline_free(line);
}
示例#17
0
static void test_tree_circ_create(void)
{
	LWLINE *g;
	CIRC_NODE *c;
	/* Line with 4 edges */
	g = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(0 88,0 89,0 90,180 89,180 88)", LW_PARSER_CHECK_NONE));
	c = circ_tree_new(g->points);
	//circ_tree_print(c, 0);

	if ( CIRC_NODE_SIZE > 4 )
	{
		CU_ASSERT(c->num_nodes == 4);
	}
	else
	{
		CU_ASSERT(c->num_nodes  == ( 4 % CIRC_NODE_SIZE ? 1 : 0 ) + 4 / CIRC_NODE_SIZE);
	}
		
	circ_tree_free(c);
	lwline_free(g);
}
示例#18
0
static LWMPOINT*
lwline_locate_along(const LWLINE *lwline, double m, double offset)
{
	POINTARRAY *opa = NULL;
	LWMPOINT *mp = NULL;
	LWGEOM *lwg = lwline_as_lwgeom(lwline);
	int hasz, hasm, srid;

	/* Return degenerates upwards */
	if ( ! lwline ) return NULL;
	
	/* Create empty return shell */
	srid = lwgeom_get_srid(lwg);
	hasz = lwgeom_has_z(lwg);
	hasm = lwgeom_has_m(lwg);

	if ( hasm )
	{
		/* Find points along */
		opa = ptarray_locate_along(lwline->points, m, offset);
	}
	else 
	{
		LWLINE *lwline_measured = lwline_measured_from_lwline(lwline, 0.0, 1.0);
		opa = ptarray_locate_along(lwline_measured->points, m, offset);
		lwline_free(lwline_measured);
	}

	/* Return NULL as EMPTY */
	if ( ! opa ) 
		return lwmpoint_construct_empty(srid, hasz, hasm);
	
	/* Convert pointarray into a multipoint */
	mp = lwmpoint_construct(srid, opa);
	ptarray_free(opa);
	return mp;
}
示例#19
0
static LWGEOM*
lwline_split_by_mpoint(const LWLINE* lwline_in, const LWMPOINT* mp)
{
  LWMLINE* out;
  int i, j;

  out = lwmline_construct_empty(lwline_in->srid,
          FLAGS_GET_Z(lwline_in->flags),
          FLAGS_GET_M(lwline_in->flags));
  lwmline_add_lwline(out, lwline_clone_deep(lwline_in));

  for (i=0; i<mp->ngeoms; ++i)
  {
    for (j=0; j<out->ngeoms; ++j)
    {
      lwline_in = out->geoms[j];
      LWPOINT *blade_in = mp->geoms[i];
      int ret = lwline_split_by_point_to(lwline_in, blade_in, out);
      if ( 2 == ret )
      {
        /* the point splits this line,
         * 2 splits were added to collection.
         * We'll move the latest added into
         * the slot of the current one.
         */
        lwline_free(out->geoms[j]);
        out->geoms[j] = out->geoms[--out->ngeoms];
      }
    }
  }

  /* Turn multiline into collection */
  out->type = COLLECTIONTYPE;

  return (LWGEOM*)out;
}
示例#20
0
Datum BOX2D_to_LWGEOM(PG_FUNCTION_ARGS)
{
	GBOX *box = (GBOX *)PG_GETARG_POINTER(0);
	POINTARRAY *pa = ptarray_construct_empty(0, 0, 5);
	POINT4D pt;
	GSERIALIZED *result;


	/*
	 * Alter BOX2D cast so that a valid geometry is always
	 * returned depending upon the size of the BOX2D. The
	 * code makes the following assumptions:
	 *     - If the BOX2D is a single point then return a
	 *     POINT geometry
	 *     - If the BOX2D represents either a horizontal or
	 *     vertical line, return a LINESTRING geometry
	 *     - Otherwise return a POLYGON
	 */

	if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) )
	{
		/* Construct and serialize point */
		LWPOINT *point = lwpoint_make2d(SRID_UNKNOWN, box->xmin, box->ymin);
		result = geometry_serialize(lwpoint_as_lwgeom(point));
		lwpoint_free(point);
	}
	else if ( (box->xmin == box->xmax) || (box->ymin == box->ymax) )
	{
		LWLINE *line;

		/* Assign coordinates to point array */
		pt.x = box->xmin;
		pt.y = box->ymin;
		ptarray_append_point(pa, &pt, LW_TRUE);
		pt.x = box->xmax;
		pt.y = box->ymax;
		ptarray_append_point(pa, &pt, LW_TRUE);

		/* Construct and serialize linestring */
		line = lwline_construct(SRID_UNKNOWN, NULL, pa);
		result = geometry_serialize(lwline_as_lwgeom(line));
		lwline_free(line);
	}
	else
	{
		LWPOLY *poly;
		POINTARRAY **ppa = lwalloc(sizeof(POINTARRAY*));

		/* Assign coordinates to point array */
		pt.x = box->xmin;
		pt.y = box->ymin;
		ptarray_append_point(pa, &pt, LW_TRUE);
		pt.x = box->xmin;
		pt.y = box->ymax;
		ptarray_append_point(pa, &pt, LW_TRUE);
		pt.x = box->xmax;
		pt.y = box->ymax;
		ptarray_append_point(pa, &pt, LW_TRUE);
		pt.x = box->xmax;
		pt.y = box->ymin;
		ptarray_append_point(pa, &pt, LW_TRUE);
		pt.x = box->xmin;
		pt.y = box->ymin;
		ptarray_append_point(pa, &pt, LW_TRUE);

		/* Construct polygon */
		ppa[0] = pa;
		poly = lwpoly_construct(SRID_UNKNOWN, NULL, 1, ppa);
		result = geometry_serialize(lwpoly_as_lwgeom(poly));
		lwpoly_free(poly);
	}

	PG_RETURN_POINTER(result);
}
示例#21
0
static void test_ptarrayarc_contains_point() 
{
	/* int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) */

	LWLINE *lwline;
	POINTARRAY *pa;
	POINT2D pt;
	int rv;

	/*** Collection of semi-circles surrounding unit square ***/
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)"));
	pa = lwline->points;

	/* Point in middle of square */
	pt.x = 0;
	pt.y = 0;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);
	
	/* Point in left lobe */
	pt.x = -1.1;
	pt.y = 0.1;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);	

	/* Point on boundary of left lobe */
	pt.x = -1;
	pt.y = 0;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);	

	/* Point on boundary vertex */
	pt.x = -1;
	pt.y = 1;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_BOUNDARY);	

	/* Point outside */
	pt.x = -1.5;
	pt.y = 1.5;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);	

	/*** Two-edge ring made up of semi-circles (really, a circle) ***/
	lwline_free(lwline);
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)"));
	pa = lwline->points;

	/* Point outside */
	pt.x = -1.5;
	pt.y = 1.5;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);	

	/* Point more outside */
	pt.x = 2.5;
	pt.y = 1.5;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);	

	/* Point more outside */
	pt.x = 2.5;
	pt.y = 2.5;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);	

	/* Point inside at middle */
	pt.x = 0;
	pt.y = 0;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);	

	/* Point inside offset from middle */
	pt.x = 0.01;
	pt.y = 0.01;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);	

	/* Point on edge vertex */
	pt.x = 0;
	pt.y = 1;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_BOUNDARY);	

	/*** Two-edge ring, closed ***/
	lwline_free(lwline);
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(1 6, 6 1, 9 7, 6 10, 1 6)"));
	pa = lwline->points;

	/* Point to left of ring */
	pt.x = 20;
	pt.y = 4;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);	

	/*** One-edge ring, closed circle ***/
	lwline_free(lwline);
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, -1 0)"));
	pa = lwline->points;

	/* Point inside */
	pt.x = 0;
	pt.y = 0;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);	

	/* Point outside */
	pt.x = 0;
	pt.y = 2;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);	

	/* Point on boundary */
	pt.x = 0;
	pt.y = 1;
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_BOUNDARY);	

	/*** Overshort ring ***/
	lwline_free(lwline);
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0)"));
	pa = lwline->points;
	cu_error_msg_reset();
	rv = ptarrayarc_contains_point(pa, &pt);
	//printf("%s\n", cu_error_msg);
	CU_ASSERT_STRING_EQUAL("ptarrayarc_contains_point called with even number of points", cu_error_msg);

	/*** Unclosed ring ***/
	lwline_free(lwline);
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, 2 0)"));
	pa = lwline->points;
	cu_error_msg_reset();
	rv = ptarrayarc_contains_point(pa, &pt);
	CU_ASSERT_STRING_EQUAL("ptarrayarc_contains_point called on unclosed ring", cu_error_msg);

	lwline_free(lwline);
}
示例#22
0
static void test_ptarray_contains_point() 
{
/* int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt, int *winding_number) */

	LWLINE *lwline;
	POINTARRAY *pa;
	POINT2D pt;
	int rv;
	
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)"));
	pa = lwline->points;

	/* Point in middle of square */
	pt.x = 0.5;
	pt.y = 0.5;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);
	
	/* Point on left edge of square */
	pt.x = 0;
	pt.y = 0.5;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_BOUNDARY);

	/* Point on top edge of square */
	pt.x = 0.5;
	pt.y = 1;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_BOUNDARY);

	/* Point on bottom left corner of square */
	pt.x = 0;
	pt.y = 0;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_BOUNDARY);

	/* Point on top left corner of square */
	pt.x = 0;
	pt.y = 1;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_BOUNDARY);

	/* Point outside top left corner of square */
	pt.x = -0.1;
	pt.y = 1;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);

	/* Point outside top left corner of square */
	pt.x = 0;
	pt.y = 1.1;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);

	/* Point outside left side of square */
	pt.x = -0.2;
	pt.y = 0.5;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);
	
	lwline_free(lwline);
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 1 1, 2 0, 0 0)"));
	pa = lwline->points;
	
	/* Point outside grazing top of triangle */
	pt.x = 0;
	pt.y = 1;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_OUTSIDE);

	lwline_free(lwline);
	lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 0 4, 1 4, 2 2, 3 4, 4 4, 4 0, 0 0)"));
	pa = lwline->points;

	/* Point outside grazing top of triangle */
	pt.x = 1;
	pt.y = 2;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);

	/* Point outside grazing top of triangle */
	pt.x = 3;
	pt.y = 2;
	rv = ptarray_contains_point(pa, &pt);
	CU_ASSERT_EQUAL(rv, LW_INSIDE);

	lwline_free(lwline);
}
示例#23
0
static void test_lwline_clip(void)
{
	LWCOLLECTION *c;
	LWLINE *line = NULL;
	LWLINE *l51 = NULL;
	char *ewkt;

	/* Vertical line with vertices at y integers */
	l51 = (LWLINE*)lwgeom_from_wkt("LINESTRING(0 0, 0 1, 0 2, 0 3, 0 4)", LW_PARSER_CHECK_NONE);

	/* Clip in the middle, mid-range. */
	c = lwline_clip_to_ordinate_range(l51, 'Y', 1.5, 2.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))");
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip off the top. */
	c = lwline_clip_to_ordinate_range(l51, 'Y', 3.5, 5.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 3.5,0 4))");
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip off the bottom. */
	c = lwline_clip_to_ordinate_range(l51, 'Y', -1.5, 2.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 2.5))" );
	lwfree(ewkt);
	lwcollection_free(c);

	/* Range holds entire object. */
	c = lwline_clip_to_ordinate_range(l51, 'Y', -1.5, 5.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 3,0 4))" );
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip on vertices. */
	c = lwline_clip_to_ordinate_range(l51, 'Y', 1.0, 2.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1,0 2))" );
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip on vertices off the bottom. */
	c = lwline_clip_to_ordinate_range(l51, 'Y', -1.0, 2.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2))" );
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip on top. */
	c = lwline_clip_to_ordinate_range(l51, 'Y', -1.0, 0.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(0 0))" );
	lwfree(ewkt);
	lwcollection_free(c);

	/* ST_LocateBetweenElevations(ST_GeomFromEWKT('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)'), 1, 2)) */
	line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", LW_PARSER_CHECK_NONE);
	c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 2.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" );
	lwfree(ewkt);
	lwcollection_free(c);
	lwline_free(line);

	/* ST_LocateBetweenElevations('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)', 1, 2)) */
	line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", LW_PARSER_CHECK_NONE);
	c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 2.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("a = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" );
	lwfree(ewkt);
	lwcollection_free(c);
	lwline_free(line);

	/* ST_LocateBetweenElevations('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)', 1, 1)) */
	line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", LW_PARSER_CHECK_NONE);
	c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 1.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("b = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" );
	lwfree(ewkt);
	lwcollection_free(c);
	lwline_free(line);

	/* ST_LocateBetweenElevations('LINESTRING(1 1 1, 1 2 2)', 1,1) */
	line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1 1, 1 2 2)", LW_PARSER_CHECK_NONE);
	c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 1.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" );
	lwfree(ewkt);
	lwcollection_free(c);
	lwline_free(line);

	lwline_free(l51);

}
示例#24
0
/*
** The suite cleanup function.
** Frees any global objects.
*/
static int clean_cg_suite(void)
{
	if ( l21 ) lwline_free(l21);
	if ( l22 ) lwline_free(l22);
	return 0;
}
示例#25
0
static void test_lwmline_clip(void)
{
	LWCOLLECTION *c;
	char *ewkt;
	LWMLINE *mline = NULL;
	LWLINE *line = NULL;

	/*
	** Set up the input line. Trivial one-member case.
	*/
	mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE);

	/* Clip in the middle, mid-range. */
	c = lwmline_clip_to_ordinate_range(mline, 'Y', 1.5, 2.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))");
	lwfree(ewkt);
	lwcollection_free(c);

	lwmline_free(mline);

	/*
	** Set up the input line. Two-member case.
	*/
	mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((1 0,1 1,1 2,1 3,1 4), (0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE);

	/* Clip off the top. */
	c = lwmline_clip_to_ordinate_range(mline, 'Y', 3.5, 5.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((1 3.5,1 4),(0 3.5,0 4))");
	lwfree(ewkt);
	lwcollection_free(c);

	lwmline_free(mline);

	/*
	** Set up staggered input line to create multi-type output.
	*/
	mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((1 0,1 -1,1 -2,1 -3,1 -4), (0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE);

	/* Clip from 0 upwards.. */
	c = lwmline_clip_to_ordinate_range(mline, 'Y', 0.0, 2.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 0),LINESTRING(0 0,0 1,0 2,0 2.5))");
	lwfree(ewkt);
	lwcollection_free(c);

	lwmline_free(mline);

	/*
	** Set up input line from MAC
	*/
	line = (LWLINE*)lwgeom_from_wkt("LINESTRING(0 0 0 0,1 1 1 1,2 2 2 2,3 3 3 3,4 4 4 4,3 3 3 5,2 2 2 6,1 1 1 7,0 0 0 8)", LW_PARSER_CHECK_NONE);

	/* Clip from 3 to 3.5 */
	c = lwline_clip_to_ordinate_range(line, 'Z', 3.0, 3.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5))");
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip from 2 to 3.5 */
	c = lwline_clip_to_ordinate_range(line, 'Z', 2.0, 3.5);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2 2,3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5,2 2 2 6))");
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip from 3 to 4 */
	c = lwline_clip_to_ordinate_range(line, 'Z', 3.0, 4.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,4 4 4 4,3 3 3 5))");
	lwfree(ewkt);
	lwcollection_free(c);

	/* Clip from 2 to 3 */
	c = lwline_clip_to_ordinate_range(line, 'Z', 2.0, 3.0);
	ewkt = lwgeom_to_ewkt((LWGEOM*)c);
	//printf("c = %s\n", ewkt);
	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2 2,3 3 3 3),(3 3 3 5,2 2 2 6))");
	lwfree(ewkt);
	lwcollection_free(c);


	lwline_free(line);

}
示例#26
0
static void test_ptarray_append_ptarray(void)
{
	LWLINE *line1, *line2;
	int ret;
	char *wkt;

	/* Empty first line */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 10,5 5)"));
	ret = ptarray_append_ptarray(line1->points, line2->points, -1);
	CU_ASSERT(ret == LW_SUCCESS);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line1));
	CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 0,0 10,5 5)");
	lwfree(wkt);
	lwline_free(line2);
	lwline_free(line1);

	/* Empty second line */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 5 5, 6 3)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY"));
	ret = ptarray_append_ptarray(line1->points, line2->points, -1);
	CU_ASSERT(ret == LW_SUCCESS);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line1));
	CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 0,5 5,6 3)");
	lwfree(wkt);
	lwline_free(line2);
	lwline_free(line1);

	/* Both lines empty */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY"));
	ret = ptarray_append_ptarray(line1->points, line2->points, -1);
	CU_ASSERT(ret == LW_SUCCESS);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line1));
	CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING EMPTY");
	lwfree(wkt);
	lwline_free(line2);
	lwline_free(line1);

	/* Sane sewing */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 4, 0 0,5 7)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(5 7,12 43, 42 15)"));
	ret = ptarray_append_ptarray(line1->points, line2->points, 0);
	CU_ASSERT(ret == LW_SUCCESS);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line1));
	CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(10 4,0 0,5 7,12 43,42 15)");
	lwfree(wkt);
	lwline_free(line2);
	lwline_free(line1);

	/* Untolerated sewing */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 4, 0 0,5 7)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(5.5 7,12 43, 42 15)"));
	ret = ptarray_append_ptarray(line1->points, line2->points, 0);
	CU_ASSERT(ret == LW_FAILURE);
	lwline_free(line2);
	lwline_free(line1);

	/* Tolerated sewing */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 4, 0 0,5 7)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(5.5 7,12 43, 42 15)"));
	ret = ptarray_append_ptarray(line1->points, line2->points, .7);
	CU_ASSERT(ret == LW_SUCCESS);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line1));
	CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(10 4,0 0,5 7,5.5 7,12 43,42 15)");
	lwfree(wkt);
	lwline_free(line2);
	lwline_free(line1);

	/* Check user input trust (creates non-simple line */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 10)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 10)"));
	ret = ptarray_append_ptarray(line1->points, line2->points, -1);
	CU_ASSERT(ret == LW_SUCCESS);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line1));
	CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 0,0 10,0 0,0 10)");
	lwfree(wkt);
	lwline_free(line2);
	lwline_free(line1);

	/* Mixed dimensionality is not allowed */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 10 0, 10 0 0)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 0,11 0)"));
	ret = ptarray_append_ptarray(line1->points, line2->points, -1);
	CU_ASSERT(ret == LW_FAILURE);
	lwline_free(line2);
	lwline_free(line1);

	/* Appending a read-only pointarray is allowed */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 10, 10 0)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 0,11 0)"));
	FLAGS_SET_READONLY(line2->points->flags, 1);
	ret = ptarray_append_ptarray(line1->points, line2->points, -1);
	CU_ASSERT(ret == LW_SUCCESS);
	wkt = lwgeom_to_text(lwline_as_lwgeom(line1));
	CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 10,10 0,11 0)");
	lwfree(wkt);
	FLAGS_SET_READONLY(line2->points->flags, 0); /* for lwline_free */
	lwline_free(line2);
	lwline_free(line1);

	/* Appending to a read-only pointarray is forbidden */
	line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 10, 10 0)"));
	line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 0,11 0)"));
	FLAGS_SET_READONLY(line1->points->flags, 1);
	ret = ptarray_append_ptarray(line1->points, line2->points, -1);
	CU_ASSERT(ret == LW_FAILURE);
	lwline_free(line2);
	FLAGS_SET_READONLY(line1->points->flags, 0); /* for lwline_free */
	lwline_free(line1);

}
示例#27
0
文件: unparser.c 项目: Vlczech/vtapi
int main()
{
	/*
	 * An example to show how to call the WKT/WKB unparsers in liblwgeom
	 */
	LWGEOM_UNPARSER_RESULT lwg_unparser_result;
	int result;

	LWGEOM *lwgeom;
	uchar *serialized_lwgeom;

	DYNPTARRAY *dpa;
	POINT4D point4d;
	POINTARRAY **rings;

	LWPOINT *testpoint;
	LWLINE *testline;
	LWPOLY *testpoly;


	/*
	 * Construct a geometry equivalent to POINT(0 51)
	 */

	dpa = dynptarray_create(10, 2);
	point4d.x = 0;
	point4d.y = 51;

	dynptarray_addPoint4d(dpa, &point4d, 0);

	testpoint = lwpoint_construct(-1, NULL, dpa->pa);

	/* Generate the LWGEOM from LWPOINT, then serialize it ready for the parser */
	lwgeom = lwpoint_as_lwgeom(testpoint);
	serialized_lwgeom = lwgeom_serialize(lwgeom);

	/* Output the geometry in WKT and WKB */
	result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_ALL);
	printf("WKT format    : %s\n", lwg_unparser_result.wkoutput);
	result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_ALL, NDR);
	printf("HEXWKB format : %s\n\n", lwg_unparser_result.wkoutput);

	/* Free all of the allocated items */
	lwfree(lwg_unparser_result.wkoutput);
	lwfree(serialized_lwgeom);
	lwpoint_free(testpoint);
	lwfree(dpa);


	/*
	 * Construct a geometry equivalent to LINESTRING(0 0, 2 2, 4 1)
	 */

	dpa = dynptarray_create(10, 2);
	point4d.x = 0;
	point4d.y = 0;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 2;
	point4d.y = 2;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 4;
	point4d.y = 1;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	testline = lwline_construct(-1, NULL, dpa->pa);

	/* Generate the LWGEOM from LWLINE, then serialize it ready for the parser */
	lwgeom = lwline_as_lwgeom(testline);
	serialized_lwgeom = lwgeom_serialize(lwgeom);

	/* Output the geometry in WKT and WKB */
	result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_ALL);
	printf("WKT format    : %s\n", lwg_unparser_result.wkoutput);
	result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_ALL, NDR);
	printf("HEXWKB format : %s\n\n", lwg_unparser_result.wkoutput);

	/* Free all of the allocated items */
	lwfree(lwg_unparser_result.wkoutput);
	lwfree(serialized_lwgeom);
	lwline_free(testline);
	lwfree(dpa);


	/*
	 * Construct a geometry equivalent to POLYGON((0 0, 0 10, 10 10, 10 0, 0 0)(3 3, 3 6, 6 6, 6 3, 3 3))
	 */

	/* Allocate memory for the rings */
	rings = lwalloc(sizeof(POINTARRAY) * 2);

	/* Construct the first ring */
	dpa = dynptarray_create(10, 2);
	point4d.x = 0;
	point4d.y = 0;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 0;
	point4d.y = 10;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 10;
	point4d.y = 10;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 10;
	point4d.y = 0;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 0;
	point4d.y = 0;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	rings[0] = dpa->pa;
	lwfree(dpa);

	/* Construct the second ring */
	dpa = dynptarray_create(10, 2);
	point4d.x = 3;
	point4d.y = 3;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 3;
	point4d.y = 6;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 6;
	point4d.y = 6;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 6;
	point4d.y = 3;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	point4d.x = 3;
	point4d.y = 3;
	dynptarray_addPoint4d(dpa, &point4d, 0);

	rings[1] = dpa->pa;
	lwfree(dpa);

	testpoly = lwpoly_construct(-1, NULL, 2, rings);

	/* Generate the LWGEOM from LWPOLY, then serialize it ready for the parser */
	lwgeom = lwpoly_as_lwgeom(testpoly);
	serialized_lwgeom = lwgeom_serialize(lwgeom);

	/* Output the geometry in WKT and WKB */
	result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_NONE);
	printf("WKT format    : %s\n", lwg_unparser_result.wkoutput);
	result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_NONE, NDR);
	printf("HEXWKB format : %s\n\n", lwg_unparser_result.wkoutput);

	/* Free all of the allocated items */
	lwfree(lwg_unparser_result.wkoutput);
	lwfree(serialized_lwgeom);
	lwpoly_free(testpoly);

}
示例#28
0
static void test_lwline_split_by_point_to(void)
{
#if POSTGIS_GEOS_VERSION >= 33
	LWLINE *line;
	LWPOINT *point;
	LWMLINE *coll;
	int ret;

	/* Because i don't trust that much prior tests...  ;) */
	cu_error_msg_reset();

	coll = lwmline_construct_empty(SRID_UNKNOWN, 0, 0);
	CU_ASSERT_EQUAL(coll->ngeoms, 0);

	line = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(0 0,5 5, 10 0)",
		LW_PARSER_CHECK_NONE));
	CU_ASSERT(line != NULL);

	point = lwgeom_as_lwpoint(lwgeom_from_wkt(
		"POINT(0 0)",
		LW_PARSER_CHECK_NONE));
	ret = lwline_split_by_point_to(line, point, coll);
	CU_ASSERT_EQUAL(ret, 1);
	CU_ASSERT_EQUAL(coll->ngeoms, 0);
	lwpoint_free(point);

	point = lwgeom_as_lwpoint(lwgeom_from_wkt(
		"POINT(10 0)",
		LW_PARSER_CHECK_NONE));
	ret = lwline_split_by_point_to(line, point, coll);
	CU_ASSERT_EQUAL(ret, 1);
	CU_ASSERT_EQUAL(coll->ngeoms, 0);
	lwpoint_free(point);

	point = lwgeom_as_lwpoint(lwgeom_from_wkt(
		"POINT(5 0)",
		LW_PARSER_CHECK_NONE));
	ret = lwline_split_by_point_to(line, point, coll);
	CU_ASSERT_EQUAL(ret, 0);
	CU_ASSERT_EQUAL(coll->ngeoms, 0);
	lwpoint_free(point);

	point = lwgeom_as_lwpoint(lwgeom_from_wkt(
		"POINT(5 5)",
		LW_PARSER_CHECK_NONE));
	ret = lwline_split_by_point_to(line, point, coll);
	CU_ASSERT_EQUAL(ret, 2);
	CU_ASSERT_EQUAL(coll->ngeoms, 2);
	lwpoint_free(point);

	point = lwgeom_as_lwpoint(lwgeom_from_wkt(
		"POINT(2 2)",
		LW_PARSER_CHECK_NONE));
	ret = lwline_split_by_point_to(line, point, coll);
	CU_ASSERT_EQUAL(ret, 2);
	CU_ASSERT_EQUAL(coll->ngeoms, 4);
	lwpoint_free(point);

	lwcollection_free((LWCOLLECTION*)coll);
	lwline_free(line);

#endif /* POSTGIS_GEOS_VERSION >= 33 */
}
示例#29
0
/**
 * @brief Generate an allocated geometry string for shapefile object obj using the state parameters
 */
int
GenerateLineStringGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry)
{
	LWCOLLECTION *lwcollection = NULL;

	LWGEOM **lwmultilinestrings;
	uchar *serialized_lwgeom;
	LWGEOM_UNPARSER_RESULT lwg_unparser_result;

	DYNPTARRAY **dpas;
	POINT4D point4d;

	int dims = 0, hasz = 0, hasm = 0;
	int result;
	int u, v, start_vertex, end_vertex;

	char *mem;


	/* Determine the correct dimensions: note that in hwgeom-compatible mode we cannot use
	   the M coordinate */
	if (state->wkbtype & WKBZOFFSET)
		hasz = 1;

	if (!state->config->hwgeom)
		if (state->wkbtype & WKBMOFFSET)
			hasm = 1;

	TYPE_SETZM(dims, hasz, hasm);

	if (state->config->simple_geometries == 1 && obj->nParts > 1)
	{
		snprintf(state->message, SHPLOADERMSGLEN, "We have a Multilinestring with %d parts, can't use -S switch!", obj->nParts);

		return SHPLOADERERR;
	}

	/* Allocate memory for our array of LWLINEs and our dynptarrays */
	lwmultilinestrings = malloc(sizeof(LWPOINT *) * obj->nParts);
	dpas = malloc(sizeof(DYNPTARRAY *) * obj->nParts);

	/* We need an array of pointers to each of our sub-geometries */
	for (u = 0; u < obj->nParts; u++)
	{
		/* Create a dynptarray containing the line points */
		dpas[u] = dynptarray_create(obj->nParts, dims);

		/* Set the start/end vertices depending upon whether this is
		a MULTILINESTRING or not */
		if ( u == obj->nParts-1 )
			end_vertex = obj->nVertices;
		else
			end_vertex = obj->panPartStart[u + 1];

		start_vertex = obj->panPartStart[u];

		for (v = start_vertex; v < end_vertex; v++)
		{
			/* Generate the point */
			point4d.x = obj->padfX[v];
			point4d.y = obj->padfY[v];

			if (state->wkbtype & WKBZOFFSET)
				point4d.z = obj->padfZ[v];
			if (state->wkbtype & WKBMOFFSET)
				point4d.m = obj->padfM[v];

			dynptarray_addPoint4d(dpas[u], &point4d, 0);
		}

		/* Generate the LWLINE */
		lwmultilinestrings[u] = lwline_as_lwgeom(lwline_construct(state->config->sr_id, NULL, dpas[u]->pa));
	}

	/* If using MULTILINESTRINGs then generate the serialized collection, otherwise just a single LINESTRING */
	if (state->config->simple_geometries == 0)
	{
		lwcollection = lwcollection_construct(MULTILINETYPE, state->config->sr_id, NULL, obj->nParts, lwmultilinestrings);

		/* When outputting wkt rather than wkb, we need to remove the SRID from the inner geometries */
		if (state->config->hwgeom)
		{
			for (u = 0; u < obj->nParts; u++)
				lwmultilinestrings[u]->SRID = -1;
		}

		serialized_lwgeom = lwgeom_serialize(lwcollection_as_lwgeom(lwcollection));
	}
	else
	{
		serialized_lwgeom = lwgeom_serialize(lwmultilinestrings[0]);
	}

	if (!state->config->hwgeom)
		result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_NONE, -1);
	else
		result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, serialized_lwgeom, PARSER_CHECK_NONE);

	/* Return the error message if we failed */
	if (result)
	{
		snprintf(state->message, SHPLOADERMSGLEN, "%s", lwg_unparser_result.message);

		return SHPLOADERERR;
	}

	/* Allocate a string containing the resulting geometry */
	mem = malloc(strlen(lwg_unparser_result.wkoutput) + 1);
	strcpy(mem, lwg_unparser_result.wkoutput);

	/* Free all of the allocated items */
	lwfree(lwg_unparser_result.wkoutput);
	lwfree(serialized_lwgeom);

	for (u = 0; u < obj->nParts; u++)
	{
		lwfree(dpas[u]->pa->serialized_pointlist);
		lwline_free(lwgeom_as_lwline(lwmultilinestrings[u]));
		lwfree(dpas[u]);
	}

	lwfree(dpas);
	lwfree(lwmultilinestrings);
	if (lwcollection)
		lwfree(lwcollection);

	/* Return the string - everything ok */
	*geometry = mem;

	return SHPLOADEROK;
}
示例#30
0
static void test_tree_circ_pip(void)
{
	LWLINE *g;
	CIRC_NODE *c;
	POINT2D pt, pt_outside;
	int rv, on_boundary;
	
	pt.x = 0.0;
	pt.y = 0.0;
	pt_outside.x = -2.0;
	pt_outside.y = 0.0;
	
	/* Point in square */
	g = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(-1 -1,1 -1,1 1,-1 1,-1 -1)", LW_PARSER_CHECK_NONE));
	c = circ_tree_new(g->points);
	rv = circ_tree_contains_point(c, &pt, &pt_outside, &on_boundary);
	CU_ASSERT_EQUAL(rv, 1);

	/* Point on other side of square */
	pt.x = 2.0;
	pt.y = 0.0;
	rv = circ_tree_contains_point(c, &pt, &pt_outside, &on_boundary);
	CU_ASSERT_EQUAL(rv, 0);

	/* Clean and do new shape */
	circ_tree_free(c);
	lwline_free(g);

	/* Point in square, stab passing through vertex */
	pt.x = 0.0;
	pt.y = 0.0;
	g = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(-1 -1,0 -1,1 -1,1 0,1 1,0 1,-1 1,-1 0,-1 -1)", LW_PARSER_CHECK_NONE));
	c = circ_tree_new(g->points);
	//circ_tree_print(c, 0);
	rv = circ_tree_contains_point(c, &pt, &pt_outside, &on_boundary);
	CU_ASSERT_EQUAL(rv, 1);

	/* Point on other side of square, stab passing through vertex */
	pt.x = 2.0;
	pt.y = 0.0;
	rv = circ_tree_contains_point(c, &pt, &pt_outside, &on_boundary);
	CU_ASSERT_EQUAL(rv, 0);

	/* Clean and do new shape */
	circ_tree_free(c);
	lwline_free(g);

	/* Point outside "w" thing, stab passing through vertexes and grazing pointy thing */
	pt.x = 2.0;
	pt.y = 0.0;
	g = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(-1 -1,0 -1,1 -1,1 0,1 1,0 0,-1 1,-1 0,-1 -1)", LW_PARSER_CHECK_NONE));
	c = circ_tree_new(g->points);
	//circ_tree_print(c, 0);
	rv = circ_tree_contains_point(c, &pt, &pt_outside, &on_boundary);
	//printf("rv %d\n", rv);
	CU_ASSERT_EQUAL(rv, 0);

	/* Point inside "w" thing, stab passing through vertexes and grazing pointy thing */
	pt.x = 0.8;
	pt.y = 0.0;
	rv = circ_tree_contains_point(c, &pt, &pt_outside, &on_boundary);
	//printf("rv %d\n", rv);
	CU_ASSERT_EQUAL(rv, 1);

	/* Clean and do new shape */
	circ_tree_free(c);
	lwline_free(g);

}