Example #1
0
Datum geometry_distance_spheroid(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P(0);
	GSERIALIZED *geom2 = PG_GETARG_GSERIALIZED_P(1);
	SPHEROID *sphere = (SPHEROID *)PG_GETARG_POINTER(2);
	int type1 = gserialized_get_type(geom1);
	int type2 = gserialized_get_type(geom2);
	bool use_spheroid = PG_GETARG_BOOL(3);
	LWGEOM *lwgeom1, *lwgeom2;
	double distance;

	/* Calculate some other parameters on the spheroid */
	spheroid_init(sphere, sphere->a, sphere->b);

	/* Catch sphere special case and re-jig spheroid appropriately */
	if ( ! use_spheroid )
	{
		sphere->a = sphere->b = sphere->radius;
	}

	if ( ! ( type1 == POINTTYPE || type1 == LINETYPE || type1 == POLYGONTYPE ||
	         type1 == MULTIPOINTTYPE || type1 == MULTILINETYPE || type1 == MULTIPOLYGONTYPE ))
	{
		elog(ERROR, "geometry_distance_spheroid: Only point/line/polygon supported.\n");
		PG_RETURN_NULL();
	}

	if ( ! ( type2 == POINTTYPE || type2 == LINETYPE || type2 == POLYGONTYPE ||
	         type2 == MULTIPOINTTYPE || type2 == MULTILINETYPE || type2 == MULTIPOLYGONTYPE ))
	{
		elog(ERROR, "geometry_distance_spheroid: Only point/line/polygon supported.\n");
		PG_RETURN_NULL();
	}


	if (gserialized_get_srid(geom1) != gserialized_get_srid(geom2))
	{
		elog(ERROR, "geometry_distance_spheroid: Operation on two GEOMETRIES with different SRIDs\n");
		PG_RETURN_NULL();
	}

	/* Get #LWGEOM structures */
	lwgeom1 = lwgeom_from_gserialized(geom1);
	lwgeom2 = lwgeom_from_gserialized(geom2);
	
	/* We are going to be calculating geodetic distances */
	lwgeom_set_geodetic(lwgeom1, LW_TRUE);
	lwgeom_set_geodetic(lwgeom2, LW_TRUE);

	distance = lwgeom_distance_spheroid(lwgeom1, lwgeom2, sphere, 0.0);

	PG_RETURN_FLOAT8(distance);

}
Example #2
0
static void test_tree_circ_distance(void)
{
	LWGEOM *lwg1, *lwg2;
	CIRC_NODE *c1, *c2;
	SPHEROID s;
	double d1, d2, d3, d4;
	double threshold = 0.0;
	
	spheroid_init(&s, 1.0, 1.0);

	/* Ticket #1958 */
	lwg1 = lwgeom_from_wkt("LINESTRING(22.88333 41.96667,21.32667 42.13667)", LW_PARSER_CHECK_NONE);
	lwg2 = lwgeom_from_wkt("POLYGON((22.94472 41.34667,22.87528 41.99028,22.87389 41.98472,22.87472 41.98333,22.94472 41.34667))", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
//	printf("d1 = %g   d2 = %g\n", d1 * WGS84_RADIUS, d2 * WGS84_RADIUS);
//	printf("line\n");
//	circ_tree_print(c1, 0);
//	printf("poly\n");
//	circ_tree_print(c2, 0);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.0000001);
	
	/* Ticket #1951 */
	lwg1 = lwgeom_from_wkt("LINESTRING(0 0, 0 0)", LW_PARSER_CHECK_NONE);
	lwg2 = lwgeom_from_wkt("POINT(0.1 0.1)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(-2 0)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(2 2)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(1 1)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(1 0.5)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
//	printf("distance_tree %g\n", distance_tree);
//	printf("distance_geom %g\n", distance_geom);
//	circ_tree_print(cline, 0);
//	circ_tree_print(cpoint, 0);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);


	/* Ticket #2351 */
	lwg1 = lwgeom_from_wkt("LINESTRING(149.386990599235 -26.3567415843982,149.386990599247 -26.3567415843965)", LW_PARSER_CHECK_NONE);
	lwg2 = lwgeom_from_wkt("POINT(149.386990599235 -26.3567415843982)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
//	printf("d1 = %g   d2 = %g\n", d1 * WGS84_RADIUS, d2 * WGS84_RADIUS);
//	printf("line\n");
//	circ_tree_print(c1, 0);
//	printf("point\n");
//	circ_tree_print(c2, 0);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.0000001);
	
	/* Ticket #2634 */
	lwg1 = lwgeom_from_wkt("MULTIPOINT (-10 40,-10 65,10 40,10 65,30 40,30 65,50 40,50 65)", LW_PARSER_CHECK_NONE);
	lwg2 = lwgeom_from_wkt("POLYGON((-9.1111111 40,-9.14954053919354 39.6098193559677,-9.26335203497743 39.2346331352698,-9.44817187539491 38.8888595339608,-9.6968975376269 38.5857864376269,-9.99997063396079 38.3370607753949,-10.3457442352698 38.1522409349774,-10.7209304559677 38.0384294391935,-11.1111111 38,-11.5012917440323 38.0384294391935,-11.8764779647302 38.1522409349774,-12.2222515660392 38.3370607753949,-12.5253246623731 38.5857864376269,-12.7740503246051 38.8888595339608,-12.9588701650226 39.2346331352698,-13.0726816608065 39.6098193559677,-13.1111111 40,-13.0726816608065 40.3901806440322,-12.9588701650226 40.7653668647302,-12.7740503246051 41.1111404660392,-12.5253246623731 41.4142135623731,-12.2222515660392 41.6629392246051,-11.8764779647302 41.8477590650226,-11.5012917440323 41.9615705608065,-11.1111111 42,-10.7209304559678 41.9615705608065,-10.3457442352698 41.8477590650226,-9.9999706339608 41.6629392246051,-9.69689753762691 41.4142135623731,-9.44817187539491 41.1111404660392,-9.26335203497743 40.7653668647302,-9.14954053919354 40.3901806440323,-9.1111111 40))", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
//	printf("d1 = %g   d2 = %g\n", d1 * WGS84_RADIUS, d2 * WGS84_RADIUS);
//	printf("multipoint\n");
//	circ_tree_print(c1, 0);
//	printf("polygon\n");
//	circ_tree_print(c2, 0);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.0000001);

	/* Ticket #2634 */
	lwg1 = lwgeom_from_wkt("MULTIPOINT Z (-10 40 1,-10 65 1,10 40 1,10 65 1,30 40 1,30 65 1,50 40 1,50 65 1,-10 40 2,-10 65 2,10 40 2,10 65 2,30 40 2,30 65 2,50 40 2,50 65 2,-10 40 3,-10 65 3,10 40 3,10 65 3,30 40 3,30 65 3,50 40 3,50 65 3)", LW_PARSER_CHECK_NONE);
	lwg2 = lwgeom_from_wkt("MULTIPOLYGON(((-9.1111111 40,-9.14954053919354 39.6098193559677,-9.26335203497743 39.2346331352698,-9.44817187539491 38.8888595339608,-9.6968975376269 38.5857864376269,-9.99997063396079 38.3370607753949,-10.3457442352698 38.1522409349774,-10.7209304559677 38.0384294391935,-11.1111111 38,-11.5012917440323 38.0384294391935,-11.8764779647302 38.1522409349774,-12.2222515660392 38.3370607753949,-12.5253246623731 38.5857864376269,-12.7740503246051 38.8888595339608,-12.9588701650226 39.2346331352698,-13.0726816608065 39.6098193559677,-13.1111111 40,-13.0726816608065 40.3901806440322,-12.9588701650226 40.7653668647302,-12.7740503246051 41.1111404660392,-12.5253246623731 41.4142135623731,-12.2222515660392 41.6629392246051,-11.8764779647302 41.8477590650226,-11.5012917440323 41.9615705608065,-11.1111111 42,-10.7209304559678 41.9615705608065,-10.3457442352698 41.8477590650226,-9.9999706339608 41.6629392246051,-9.69689753762691 41.4142135623731,-9.44817187539491 41.1111404660392,-9.26335203497743 40.7653668647302,-9.14954053919354 40.3901806440323,-9.1111111 40)))", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
//	printf("\n");
//	circ_tree_print(c1, 0);
//	printf("\n");
//	circ_tree_print(c2, 0);	
//	printf("\n");
	d1 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	d2 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d3 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d4 = circ_tree_distance_tree(c1, c2, &s, threshold);
//	printf("\n d1-no-tree %20.20g\n d2 %20.20g\n d3 %20.20g\n d4 %20.20g\n", d1, d2, d3, d4);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00000001);
	CU_ASSERT_DOUBLE_EQUAL(d1, d3, 0.00000001);
	CU_ASSERT_DOUBLE_EQUAL(d1, d4, 0.00000001);

}
Example #3
0
static void test_tree_circ_distance(void)
{
	LWGEOM *lwg1, *lwg2;
	CIRC_NODE *c1, *c2;
	SPHEROID s;
	double d1, d2;
	double threshold = 0.0;
	
	spheroid_init(&s, 1.0, 1.0);

	/* Ticket #1958 */
	lwg1 = lwgeom_from_wkt("LINESTRING(22.88333 41.96667,21.32667 42.13667)", LW_PARSER_CHECK_NONE);
	lwg2 = lwgeom_from_wkt("POLYGON((22.94472 41.34667,22.87528 41.99028,22.87389 41.98472,22.87472 41.98333,22.94472 41.34667))", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
//	printf("d1 = %g   d2 = %g\n", d1 * WGS84_RADIUS, d2 * WGS84_RADIUS);
//	printf("line\n");
//	circ_tree_print(c1, 0);
//	printf("poly\n");
//	circ_tree_print(c2, 0);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.0000001);
	
	/* Ticket #1951 */
	lwg1 = lwgeom_from_wkt("LINESTRING(0 0, 0 0)", LW_PARSER_CHECK_NONE);
	lwg2 = lwgeom_from_wkt("POINT(0.1 0.1)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(-2 0)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(2 2)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(1 1)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);

	lwg1 = 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);
	lwg2 = lwgeom_from_wkt("POINT(1 0.5)", LW_PARSER_CHECK_NONE);
	c1 = lwgeom_calculate_circ_tree(lwg1);
	c2 = lwgeom_calculate_circ_tree(lwg2);
	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
//	printf("distance_tree %g\n", distance_tree);
//	printf("distance_geom %g\n", distance_geom);
//	circ_tree_print(cline, 0);
//	circ_tree_print(cpoint, 0);
	circ_tree_free(c1);
	circ_tree_free(c2);
	lwgeom_free(lwg1);
	lwgeom_free(lwg2);
	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.00001);
}