Datum geography_recv(PG_FUNCTION_ARGS)
{
	StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
	int32 geog_typmod = -1;
	LWGEOM *lwgeom = NULL;
	GSERIALIZED *g_ser = NULL;

	if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
		geog_typmod = PG_GETARG_INT32(2);
	}

	lwgeom = lwgeom_from_wkb((uint8_t*)buf->data, buf->len, LW_PARSER_CHECK_ALL);

	/* Error on any SRID != default */
	srid_is_latlong(fcinfo, lwgeom->srid);

	g_ser = gserialized_geography_from_lwgeom(lwgeom, geog_typmod);

	/* Clean up temporary object */
	lwgeom_free(lwgeom);

	/* Set cursor to the end of buffer (so the backend is happy) */
	buf->cursor = buf->len;

	PG_RETURN_POINTER(g_ser);
}
示例#2
0
Datum geography_typmod_in(PG_FUNCTION_ARGS)
{
	ArrayType *arr = (ArrayType *) DatumGetPointer(PG_GETARG_DATUM(0));
	uint32 typmod = gserialized_typmod_in(arr, LW_TRUE);
	int srid = TYPMOD_GET_SRID(typmod);
	/* Check the SRID is legal (geographic coordinates) */
	srid_is_latlong(fcinfo, srid);
	
	PG_RETURN_INT32(typmod);
}
Datum geography_in(PG_FUNCTION_ARGS)
{
	char *str = PG_GETARG_CSTRING(0);
	/* Datum geog_oid = PG_GETARG_OID(1); Not needed. */
	int32 geog_typmod = -1;
	LWGEOM_PARSER_RESULT lwg_parser_result;
	LWGEOM *lwgeom = NULL;
	GSERIALIZED *g_ser = NULL;

	if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) {
		geog_typmod = PG_GETARG_INT32(2);
	}

	lwgeom_parser_result_init(&lwg_parser_result);

	/* Empty string. */
	if ( str[0] == '\0' )
		ereport(ERROR,(errmsg("parse error - invalid geometry")));

	/* WKB? Let's find out. */
	if ( str[0] == '0' )
	{
		/* TODO: 20101206: No parser checks! This is inline with current 1.5 behavior, but needs discussion */
		lwgeom = lwgeom_from_hexwkb(str, LW_PARSER_CHECK_NONE);
		/* Error out if something went sideways */
		if ( ! lwgeom ) 
			ereport(ERROR,(errmsg("parse error - invalid geometry")));
	}
	/* WKT then. */
	else
	{
		if ( lwgeom_parse_wkt(&lwg_parser_result, str, LW_PARSER_CHECK_ALL) == LW_FAILURE )
			PG_PARSER_ERROR(lwg_parser_result);

		lwgeom = lwg_parser_result.geom;
	}

	/* Error on any SRID != default */
	srid_is_latlong(fcinfo, lwgeom->srid);
	
	/* Convert to gserialized */
	g_ser = gserialized_geography_from_lwgeom(lwgeom, geog_typmod);

	/* Clean up temporary object */
	lwgeom_free(lwgeom);


	PG_RETURN_POINTER(g_ser);
}
Datum geography_from_geometry(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	LWGEOM *lwgeom = NULL;
	GSERIALIZED *g_ser = NULL;

	geography_valid_type(gserialized_get_type(geom));

	lwgeom = lwgeom_from_gserialized(geom);

	/* Force default SRID */
	if ( (int)lwgeom->srid <= 0 )
	{
		lwgeom->srid = SRID_DEFAULT;
	}

	/* Error on any SRID != default */
	srid_is_latlong(fcinfo, lwgeom->srid);

	/* Check if the geography has valid coordinate range. */
	if ( lwgeom_check_geodetic(lwgeom) == LW_FALSE )
	{
		if ( (! lwgeom_nudge_geodetic(lwgeom)) || lwgeom_check_geodetic(lwgeom) == LW_FALSE )
		{
			ereport(ERROR, (
			        errcode(ERRCODE_INVALID_PARAMETER_VALUE),
			        errmsg("Coordinate values are out of range [-180 -90, 180 90] for GEOGRAPHY type" )));
		}
	}

	/*
	** Serialize our lwgeom and set the geodetic flag so subsequent
	** functions do the right thing.
	*/
	lwgeom_set_geodetic(lwgeom, true);
	/* Recalculate the boxes after re-setting the geodetic bit */
	lwgeom_drop_bbox(lwgeom);
	lwgeom_add_bbox(lwgeom);
	g_ser = geography_serialize(lwgeom);

	/*
	** Replace the unaligned lwgeom with a new aligned one based on GSERIALIZED.
	*/
	lwgeom_free(lwgeom);

	PG_FREE_IF_COPY(geom, 0);
	PG_RETURN_POINTER(g_ser);

}
示例#5
0
Datum geography_from_geometry(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
	LWGEOM *lwgeom = NULL;
	GSERIALIZED *g_ser = NULL;

	geography_valid_type(gserialized_get_type(geom));

	lwgeom = lwgeom_from_gserialized(geom);

	/* Force default SRID */
	if ( (int)lwgeom->srid <= 0 )
	{
		lwgeom->srid = SRID_DEFAULT;
	}

	/* Error on any SRID != default */
	srid_is_latlong(fcinfo, lwgeom->srid);

	/* Force the geometry to have valid geodetic coordinate range. */
	lwgeom_nudge_geodetic(lwgeom);
	if ( lwgeom_force_geodetic(lwgeom) == LW_TRUE )
	{
		ereport(NOTICE, (
		        errmsg_internal("Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ))
		);
	}

	/*
	** Serialize our lwgeom and set the geodetic flag so subsequent
	** functions do the right thing.
	*/
	lwgeom_set_geodetic(lwgeom, true);
	/* Recalculate the boxes after re-setting the geodetic bit */
	lwgeom_drop_bbox(lwgeom);
	lwgeom_add_bbox(lwgeom);
	g_ser = geography_serialize(lwgeom);

	/*
	** Replace the unaligned lwgeom with a new aligned one based on GSERIALIZED.
	*/
	lwgeom_free(lwgeom);

	PG_FREE_IF_COPY(geom, 0);
	PG_RETURN_POINTER(g_ser);

}