Example #1
0
static LWGEOM*
lwgeom_clean(LWGEOM* lwgeom_in)
{
	LWGEOM* lwgeom_out;

	lwgeom_out = lwgeom_make_valid(lwgeom_in);
	if ( ! lwgeom_out )
	{
		return NULL;
	}

	/* Check dimensionality is the same as input */
	if ( lwgeom_dimensionality(lwgeom_in) != lwgeom_dimensionality(lwgeom_out) )
	{
		lwnotice("lwgeom_clean: dimensional collapse (%d to %d)",
		         lwgeom_dimensionality(lwgeom_in), lwgeom_dimensionality(lwgeom_out));

		return NULL;
	}

	/* Check that the output is not a collection if the input wasn't */
	if ( lwgeom_out->type == COLLECTIONTYPE &&
	        lwgeom_in->type != COLLECTIONTYPE )
	{
		lwnotice("lwgeom_clean: mixed-type output (%s) "
		         "from single-type input (%s)",
		         lwtype_name(lwgeom_out->type),
		         lwtype_name(lwgeom_in->type));
		return NULL;
	}

	/* Force right-hand-rule (will only affect polygons) */
	/* gout := ST_ForceRHR(gout); */

	/* Remove repeated duplicated points ? */
	/* gout = ST_RemoveRepeatedPoints(gout); */

	return lwgeom_out;
}
Example #2
0
void
lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
{
	int type = geom->type;
	int i;

	switch(type) 
	{
		/* Take advantage of fact tht pt/ln/circ/tri have same memory structure */
		case POINTTYPE:
		case LINETYPE:
		case CIRCSTRINGTYPE:
		case TRIANGLETYPE:
		{
			LWLINE *l = (LWLINE*)geom;
			ptarray_affine(l->points, affine);
			break;
		}
		case POLYGONTYPE:
		{
			LWPOLY *p = (LWPOLY*)geom;
			for( i = 0; i < p->nrings; i++ )
				ptarray_affine(p->rings[i], affine);
			break;
		}
		case CURVEPOLYTYPE:
		{
			LWCURVEPOLY *c = (LWCURVEPOLY*)geom;
			for( i = 0; i < c->nrings; i++ )
				lwgeom_affine(c->rings[i], affine);
			break;
		}
		default:
		{
			if( lwgeom_is_collection(geom) )
			{
				LWCOLLECTION *c = (LWCOLLECTION*)geom;
				for( i = 0; i < c->ngeoms; i++ )
				{
					lwgeom_affine(c->geoms[i], affine);
				}
			}
			else 
			{
				lwerror("lwgeom_affine: unable to handle type '%s'", lwtype_name(type));
			}
		}
	}

}
Datum postgis_typmod_out(PG_FUNCTION_ARGS)
{
	char *s = (char*)palloc(64);
	char *str = s;
	uint32 typmod = PG_GETARG_INT32(0);
	uint32 srid = TYPMOD_GET_SRID(typmod);
	uint32 type = TYPMOD_GET_TYPE(typmod);
	uint32 hasz = TYPMOD_GET_Z(typmod);
	uint32 hasm = TYPMOD_GET_M(typmod);

	POSTGIS_DEBUGF(3, "Got typmod(srid = %d, type = %d, hasz = %d, hasm = %d)", srid, type, hasz, hasm);

	/* No SRID or type or dimensionality? Then no typmod at all. Return empty string. */
	if ( ! ( srid || type || hasz || hasm ) )
	{
		*str = '\0';
		PG_RETURN_CSTRING(str);
	}

	/* Opening bracket. */
	str += sprintf(str, "(");

	/* Has type? */
	if ( type )
		str += sprintf(str, "%s", lwtype_name(type));
  else if ( (!type) &&  ( srid || hasz || hasm ) )
    str += sprintf(str, "Geometry");

	/* Has Z? */
	if ( hasz )
		str += sprintf(str, "%s", "Z");

	/* Has M? */
	if ( hasm )
		str += sprintf(str, "%s", "M");

	/* Comma? */
	if ( srid )
		str += sprintf(str, ",");

	/* Has SRID? */
	if ( srid )
		str += sprintf(str, "%d", srid);

	/* Closing bracket. */
	str += sprintf(str, ")");

	PG_RETURN_CSTRING(s);

}
static LWGEOM*
lwpoly_split(const LWPOLY* lwpoly_in, const LWGEOM* blade_in)
{
	switch (blade_in->type)
	{
	case LINETYPE:
		return lwpoly_split_by_line(lwpoly_in, (LWLINE*)blade_in);
	default:
		lwerror("Splitting a Polygon by a %s is unsupported",
		        lwtype_name(blade_in->type));
		return NULL;
	}
	return NULL;
}
Example #5
0
/**
* LINESTRING
* Read a WKB linestring, starting just after the endian byte, 
* type number and optional srid number. Advance the parse state 
* forward appropriately. 
* There is only one pointarray in a linestring. Optionally
* check for minimal following of rules (two point minimum).
*/
static LWLINE* lwline_from_wkb_state(wkb_parse_state *s)
{
	POINTARRAY *pa = ptarray_from_wkb_state(s);

	if( pa == NULL || pa->npoints == 0 )
		return lwline_construct_empty(s->srid, s->has_z, s->has_m);

	if( s->check & LW_PARSER_CHECK_MINPOINTS && pa->npoints < 2 )
	{
		lwerror("%s must have at least two points", lwtype_name(s->lwtype));
		return NULL;
	}

	return lwline_construct(s->srid, NULL, pa);
}
Example #6
0
/**

Here the geometries are distributed for the new faster distance-calculations
*/
int
lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl)
{
	POINTARRAY *pa1, *pa2;
	int	type1 = lwg1->type;
	int	type2 = lwg2->type;

	LWDEBUGF(2, "lw_dist2d_distribute_fast is called with typ1=%d, type2=%d", lwg1->type, lwg2->type);

	switch (type1)
	{
	case LINETYPE:
		pa1 = ((LWLINE *)lwg1)->points;
		break;
	case POLYGONTYPE:
		pa1 = ((LWPOLY *)lwg1)->rings[0];
		break;
	default:
		lwerror("Unsupported geometry1 type: %s", lwtype_name(type1));
		return LW_FALSE;
	}
	switch (type2)
	{
	case LINETYPE:
		pa2 = ((LWLINE *)lwg2)->points;
		break;
	case POLYGONTYPE:
		pa2 = ((LWPOLY *)lwg2)->rings[0];
		break;
	default:
		lwerror("Unsupported geometry2 type: %s", lwtype_name(type1));
		return LW_FALSE;
	}
	dl->twisted=1;
	return lw_dist2d_fast_ptarray_ptarray(pa1, pa2, dl, lwg1->bbox, lwg2->bbox);
}
Example #7
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);
}
Example #8
0
/*
 * Construct a LWCIRCSTRING from an array of LWPOINTs
 * LWCIRCSTRING dimensions are large enough to host all input dimensions.
 */
LWCIRCSTRING *
lwcircstring_from_lwpointarray(int srid, uint32_t npoints, LWPOINT **points)
{
	int zmflag=0;
	uint32_t i;
	POINTARRAY *pa;
	uint8_t *newpoints, *ptr;
	size_t ptsize, size;

	/*
	 * Find output dimensions, check integrity
	 */
	for (i = 0; i < npoints; i++)
	{
		if (points[i]->type != POINTTYPE)
		{
			lwerror("lwcurve_from_lwpointarray: invalid input type: %s",
			        lwtype_name(points[i]->type));
			return NULL;
		}
		if (FLAGS_GET_Z(points[i]->flags)) zmflag |= 2;
		if (FLAGS_GET_M(points[i]->flags)) zmflag |= 1;
		if (zmflag == 3) break;
	}

	if (zmflag == 0) ptsize = 2 * sizeof(double);
	else if (zmflag == 3) ptsize = 4 * sizeof(double);
	else ptsize = 3 * sizeof(double);

	/*
	 * Allocate output points array
	 */
	size = ptsize * npoints;
	newpoints = lwalloc(size);
	memset(newpoints, 0, size);

	ptr = newpoints;
	for (i = 0; i < npoints; i++)
	{
		size = ptarray_point_size(points[i]->point);
		memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
		ptr += ptsize;
	}
	pa = ptarray_construct_reference_data(zmflag&2, zmflag&1, npoints, newpoints);
	
	return lwcircstring_construct(srid, NULL, pa);
}
Example #9
0
/**
* Count rings in an #LWGEOM.
*/
int lwgeom_count_rings(const LWGEOM *geom)
{
	int result = 0;
	
	/* Null? Empty? Zero. */
	if( ! geom || lwgeom_is_empty(geom) ) 
		return 0;

	switch (geom->type)
	{
	case POINTTYPE:
	case CIRCSTRINGTYPE: 
	case COMPOUNDTYPE:
	case MULTICURVETYPE:
	case MULTIPOINTTYPE:
	case MULTILINETYPE:
	case LINETYPE:
		result = 0;
		break;
	case TRIANGLETYPE:
		result = 1;
		break;
	case POLYGONTYPE:
		result = ((LWPOLY *)geom)->nrings;
		break;
	case CURVEPOLYTYPE:
		result = ((LWCURVEPOLY *)geom)->nrings;
		break;
	case MULTISURFACETYPE:
	case MULTIPOLYGONTYPE:
	case POLYHEDRALSURFACETYPE:
	case TINTYPE:
	case COLLECTIONTYPE:
	{
		LWCOLLECTION *col = (LWCOLLECTION*)geom;
		int i = 0;
		for( i = 0; i < col->ngeoms; i++ )
			result += lwgeom_count_rings(col->geoms[i]);
		break;
	}
	default:
		lwerror("lwgeom_count_rings: unsupported input geometry type: %s", lwtype_name(geom->type));
		break;
	}
	LWDEBUGF(3, "counted %d rings", result);
	return result;
}
Example #10
0
LWGEOM* lwgeom_from_gserialized(const GSERIALIZED *g)
{
	uint8_t g_flags = 0;
	int32_t g_srid = 0;
	uint32_t g_type = 0;
	uint8_t *data_ptr = NULL;
	LWGEOM *lwgeom = NULL;
	GBOX bbox;
	size_t g_size = 0;

	assert(g);

	g_srid = gserialized_get_srid(g);
	g_flags = g->flags;
	g_type = gserialized_get_type(g);
	LWDEBUGF(4, "Got type %d (%s), srid=%d", g_type, lwtype_name(g_type), g_srid);

	data_ptr = (uint8_t*)g->data;
	if ( FLAGS_GET_BBOX(g_flags) )
		data_ptr += gbox_serialized_size(g_flags);

	lwgeom = lwgeom_from_gserialized_buffer(data_ptr, g_flags, &g_size);

	if ( ! lwgeom ) 
		lwerror("lwgeom_from_gserialized: unable create geometry"); /* Ooops! */

	lwgeom->type = g_type;
	lwgeom->flags = g_flags;

	if ( gserialized_read_gbox_p(g, &bbox) == LW_SUCCESS )
	{
		lwgeom->bbox = gbox_copy(&bbox);
	}
	else if ( lwgeom_needs_bbox(lwgeom) && (lwgeom_calculate_gbox(lwgeom, &bbox) == LW_SUCCESS) )
	{
		lwgeom->bbox = gbox_copy(&bbox);
	}
	else
	{
		lwgeom->bbox = NULL;
	}

	lwgeom_set_srid(lwgeom, g_srid);

	return lwgeom;
}
Example #11
0
/**
* Free the containing LWGEOM and the associated BOX. Leave the underlying 
* geoms/points/point objects intact. Useful for functions that are stripping
* out subcomponents of complex objects, or building up new temporary objects
* on top of subcomponents.
*/
void
lwgeom_release(LWGEOM *lwgeom)
{
	if ( ! lwgeom )
		lwerror("lwgeom_release: someone called on 0x0");

	LWDEBUGF(3, "releasing type %s", lwtype_name(lwgeom->type));

	/* Drop bounding box (always a copy) */
	if ( lwgeom->bbox )
	{
		LWDEBUGF(3, "lwgeom_release: releasing bbox. %p", lwgeom->bbox);
		lwfree(lwgeom->bbox);
	}
	lwfree(lwgeom);

}
Example #12
0
/* takes a GEOMETRY and returns an X3D representation */
extern char *
lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid)
{
	int type = geom->type;

	switch (type)
	{
	case POINTTYPE:
		return asx3d3_point((LWPOINT*)geom, srs, precision, opts, defid);

	case LINETYPE:
		return asx3d3_line((LWLINE*)geom, srs, precision, opts, defid);

	case POLYGONTYPE:
	{
		/** We might change this later, but putting a polygon in an indexed face set
		* seems like the simplest way to go so treat just like a mulitpolygon
		*/
		LWCOLLECTION *tmp = (LWCOLLECTION*)lwgeom_as_multi(geom);
		char *ret = asx3d3_multi(tmp, srs, precision, opts, defid);
		lwcollection_free(tmp);
		return ret;
	}

	case TRIANGLETYPE:
		return asx3d3_triangle((LWTRIANGLE*)geom, srs, precision, opts, defid);

	case MULTIPOINTTYPE:
	case MULTILINETYPE:
	case MULTIPOLYGONTYPE:
		return asx3d3_multi((LWCOLLECTION*)geom, srs, precision, opts, defid);

	case POLYHEDRALSURFACETYPE:
		return asx3d3_psurface((LWPSURFACE*)geom, srs, precision, opts, defid);

	case TINTYPE:
		return asx3d3_tin((LWTIN*)geom, srs, precision, opts, defid);

	case COLLECTIONTYPE:
		return asx3d3_collection((LWCOLLECTION*)geom, srs, precision, opts, defid);

	default:
		lwerror("lwgeom_to_x3d3: '%s' geometry type not supported", lwtype_name(type));
		return NULL;
	}
}
Example #13
0
/**
 * Takes a GEOMETRY and returns a SVG representation
 */
char *
lwgeom_to_svg(const LWGEOM *geom, int precision, int relative)
{
	char *ret = NULL;
	int type = geom->type;

	/* Empty string for empties */
	if( lwgeom_is_empty(geom) )
	{
		ret = lwalloc(1);
		ret[0] = '\0';
		return ret;
	}
	
	switch (type)
	{
	case POINTTYPE:
		ret = assvg_point((LWPOINT*)geom, relative, precision);
		break;
	case LINETYPE:
		ret = assvg_line((LWLINE*)geom, relative, precision);
		break;
	case POLYGONTYPE:
		ret = assvg_polygon((LWPOLY*)geom, relative, precision);
		break;
	case MULTIPOINTTYPE:
		ret = assvg_multipoint((LWMPOINT*)geom, relative, precision);
		break;
	case MULTILINETYPE:
		ret = assvg_multiline((LWMLINE*)geom, relative, precision);
		break;
	case MULTIPOLYGONTYPE:
		ret = assvg_multipolygon((LWMPOLY*)geom, relative, precision);
		break;
	case COLLECTIONTYPE:
		ret = assvg_collection((LWCOLLECTION*)geom, relative, precision);
		break;

	default:
		lwerror("lwgeom_to_svg: '%s' geometry type not supported",
		        lwtype_name(type));
	}

	return ret;
}
Example #14
0
static LWGEOM*
lwline_split(const LWLINE* lwline_in, const LWGEOM* blade_in)
{
	switch (blade_in->type)
	{
	case POINTTYPE:
		return lwline_split_by_point(lwline_in, (LWPOINT*)blade_in);

	case LINETYPE:
		return lwline_split_by_line(lwline_in, (LWLINE*)blade_in);

	default:
		lwerror("Splitting a Line by a %s is unsupported",
		        lwtype_name(blade_in->type));
		return NULL;
	}
	return NULL;
}
/**
* The geography type only support POINT, LINESTRING, POLYGON, MULTI* variants
* of same, and GEOMETRYCOLLECTION. If the input type is not one of those, shut
* down the query.
*/
void geography_valid_type(uint8_t type)
{
	if ( ! (
	            type == POINTTYPE ||
	            type == LINETYPE ||
	            type == POLYGONTYPE ||
	            type == MULTIPOINTTYPE ||
	            type == MULTILINETYPE ||
	            type == MULTIPOLYGONTYPE ||
	            type == COLLECTIONTYPE
	        ) )
	{
		ereport(ERROR, (
		            errcode(ERRCODE_INVALID_PARAMETER_VALUE),
		            errmsg("Geography type does not support %s", lwtype_name(type) )));

	}
}
Example #16
0
void
lwgeom_longitude_shift(LWGEOM *lwgeom)
{
	int i;
	switch (lwgeom->type)
	{
		LWPOINT *point;
		LWLINE *line;
		LWPOLY *poly;
		LWTRIANGLE *triangle;
		LWCOLLECTION *coll;

	case POINTTYPE:
		point = (LWPOINT *)lwgeom;
		ptarray_longitude_shift(point->point);
		return;
	case LINETYPE:
		line = (LWLINE *)lwgeom;
		ptarray_longitude_shift(line->points);
		return;
	case POLYGONTYPE:
		poly = (LWPOLY *)lwgeom;
		for (i=0; i<poly->nrings; i++)
			ptarray_longitude_shift(poly->rings[i]);
		return;
	case TRIANGLETYPE:
		triangle = (LWTRIANGLE *)lwgeom;
		ptarray_longitude_shift(triangle->points);
		return;
	case MULTIPOINTTYPE:
	case MULTILINETYPE:
	case MULTIPOLYGONTYPE:
	case POLYHEDRALSURFACETYPE:
	case TINTYPE:
	case COLLECTIONTYPE:
		coll = (LWCOLLECTION *)lwgeom;
		for (i=0; i<coll->ngeoms; i++)
			lwgeom_longitude_shift(coll->geoms[i]);
		return;
	default:
		lwerror("lwgeom_longitude_shift: unsupported geom type: %s",
		        lwtype_name(lwgeom->type));
	}
}
Example #17
0
static int lwgeom_to_twkb_buf(const LWGEOM *geom, TWKB_GLOBALS *globals, TWKB_STATE *ts)
{
	LWDEBUGF(2, "Entered %s", __func__);

	switch ( geom->type )
	{
		case POINTTYPE:
		{
			LWDEBUGF(4,"Type found is Point, %d", geom->type);
			return lwpoint_to_twkb_buf((LWPOINT*) geom, globals, ts);
		}
		case LINETYPE:
		{
			LWDEBUGF(4,"Type found is Linestring, %d", geom->type);
			return lwline_to_twkb_buf((LWLINE*) geom, globals, ts);
		}
		/* Polygon has 'nrings' and 'rings' elements */
		case POLYGONTYPE:
		{
			LWDEBUGF(4,"Type found is Polygon, %d", geom->type);
			return lwpoly_to_twkb_buf((LWPOLY*)geom, globals, ts);
		}

		/* All these Collection types have 'ngeoms' and 'geoms' elements */
		case MULTIPOINTTYPE:
		case MULTILINETYPE:
		case MULTIPOLYGONTYPE:
		{
			LWDEBUGF(4,"Type found is Multi, %d", geom->type);
			return lwmulti_to_twkb_buf((LWCOLLECTION*)geom, globals, ts);
		}
		case COLLECTIONTYPE:
		{
			LWDEBUGF(4,"Type found is collection, %d", geom->type);
			return lwcollection_to_twkb_buf((LWCOLLECTION*) geom, globals, ts);
		}
		/* Unknown type! */
		default:
			lwerror("Unsupported geometry type: %s [%d]", lwtype_name((geom)->type), (geom)->type);
	}

	return 0;
}
Example #18
0
Datum ST_MakeValid(PG_FUNCTION_ARGS)
{
#if POSTGIS_GEOS_VERSION < 33
	elog(ERROR, "You need GEOS-3.3.0 or up for ST_MakeValid");
	PG_RETURN_NULL();
#else /* POSTGIS_GEOS_VERSION >= 33 */

	GSERIALIZED *in, *out;
	LWGEOM *lwgeom_in, *lwgeom_out;

	in = PG_GETARG_GSERIALIZED_P(0);
	lwgeom_in = lwgeom_from_gserialized(in);

	switch ( lwgeom_in->type )
	{
	case POINTTYPE:
	case MULTIPOINTTYPE:
	case LINETYPE:
	case POLYGONTYPE:
	case MULTILINETYPE:
	case MULTIPOLYGONTYPE:
	case COLLECTIONTYPE:
		break;

	default:
		lwerror("ST_MakeValid: unsupported geometry type %s",
		        lwtype_name(lwgeom_in->type));
		PG_RETURN_NULL();
		break;
	}

	lwgeom_out = lwgeom_make_valid(lwgeom_in);
	if ( ! lwgeom_out )
	{
		PG_FREE_IF_COPY(in, 0);
		PG_RETURN_NULL();
	}

	out = geometry_serialize(lwgeom_out);

	PG_RETURN_POINTER(out);
#endif /* POSTGIS_GEOS_VERSION >= 33 */
}
Example #19
0
void
lwgeom_set_geodetic(LWGEOM *geom, int value)
{
	LWPOINT *pt;
	LWLINE *ln;
	LWPOLY *ply;
	LWCOLLECTION *col;
	int i;
	
	FLAGS_SET_GEODETIC(geom->flags, value);
	if ( geom->bbox )
		FLAGS_SET_GEODETIC(geom->bbox->flags, value);
	
	switch(geom->type)
	{
		case POINTTYPE:
			pt = (LWPOINT*)geom;
			if ( pt->point )
				FLAGS_SET_GEODETIC(pt->point->flags, value);
			break;
		case LINETYPE:
			ln = (LWLINE*)geom;
			if ( ln->points )
				FLAGS_SET_GEODETIC(ln->points->flags, value);
			break;
		case POLYGONTYPE:
			ply = (LWPOLY*)geom;
			for ( i = 0; i < ply->nrings; i++ )
				FLAGS_SET_GEODETIC(ply->rings[i]->flags, value);
			break;
		case MULTIPOINTTYPE:
		case MULTILINETYPE:
		case MULTIPOLYGONTYPE:
		case COLLECTIONTYPE:
			col = (LWCOLLECTION*)geom;
			for ( i = 0; i < col->ngeoms; i++ )
				lwgeom_set_geodetic(col->geoms[i], value);
			break;
		default:
			lwerror("lwgeom_set_geodetic: unsupported geom type: %s", lwtype_name(geom->type));
			return;
	}
}
Example #20
0
LWGEOM* lwgeom_simplify(const LWGEOM *igeom, double dist)
{
	switch (igeom->type)
	{
	case POINTTYPE:
	case MULTIPOINTTYPE:
		return lwgeom_clone(igeom);
	case LINETYPE:
		return (LWGEOM*)lwline_simplify((LWLINE*)igeom, dist);
	case POLYGONTYPE:
		return (LWGEOM*)lwpoly_simplify((LWPOLY*)igeom, dist);
	case MULTILINETYPE:
	case MULTIPOLYGONTYPE:
	case COLLECTIONTYPE:
		return (LWGEOM*)lwcollection_simplify((LWCOLLECTION *)igeom, dist);
	default:
		lwerror("lwgeom_simplify: unsupported geometry type: %s",lwtype_name(igeom->type));
	}
	return NULL;
}
Example #21
0
/*
* Multi-curves provide type information for their curved sub-geometries
* but not their linear sub-geometries.
*   MULTICURVE((0 0, 1 1), CURVESTRING(0 0, 1 1, 2 2))
*/
static void lwmcurve_to_wkt_sb(const LWMCURVE *mcurv, stringbuffer_t *sb, int precision, uint8_t variant)
{
    int i = 0;

    if ( ! (variant & WKT_NO_TYPE) )
    {
        stringbuffer_append(sb, "MULTICURVE"); /* "MULTICURVE" */
        dimension_qualifiers_to_wkt_sb((LWGEOM*)mcurv, sb, variant);
    }
    if ( mcurv->ngeoms < 1 )
    {
        empty_to_wkt_sb(sb);
        return;
    }
    stringbuffer_append(sb, "(");
    variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
    for ( i = 0; i < mcurv->ngeoms; i++ )
    {
        int type = mcurv->geoms[i]->type;
        if ( i > 0 )
            stringbuffer_append(sb, ",");
        switch (type)
        {
        case LINETYPE:
            /* Linestring subgeoms don't get type identifiers */
            lwline_to_wkt_sb((LWLINE*)mcurv->geoms[i], sb, precision, variant | WKT_NO_TYPE );
            break;
        case CIRCSTRINGTYPE:
            /* But circstring subgeoms *do* get type identifiers */
            lwcircstring_to_wkt_sb((LWCIRCSTRING*)mcurv->geoms[i], sb, precision, variant );
            break;
        case COMPOUNDTYPE:
            /* And compoundcurve subgeoms *do* get type identifiers */
            lwcompound_to_wkt_sb((LWCOMPOUND*)mcurv->geoms[i], sb, precision, variant );
            break;
        default:
            lwerror("lwmcurve_to_wkt_sb: Unknown type recieved %d - %s", type, lwtype_name(type));
        }
    }
    stringbuffer_append(sb, ")");
}
Example #22
0
/**
 * Takes a GEOMETRY and returns a GeoJson representation
 */
char *
lwgeom_to_geojson(const LWGEOM *geom, char *srs, int precision, int has_bbox)
{
	int type = geom->type;
	GBOX *bbox = NULL;
	GBOX tmp;

	if ( precision > OUT_MAX_DOUBLE_PRECISION ) precision = OUT_MAX_DOUBLE_PRECISION;

	if (has_bbox) 
	{
		/* Whether these are geography or geometry, 
		   the GeoJSON expects a cartesian bounding box */
		lwgeom_calculate_gbox_cartesian(geom, &tmp);
		bbox = &tmp;
	}		

	switch (type)
	{
	case POINTTYPE:
		return asgeojson_point((LWPOINT*)geom, srs, bbox, precision);
	case LINETYPE:
		return asgeojson_line((LWLINE*)geom, srs, bbox, precision);
	case POLYGONTYPE:
		return asgeojson_poly((LWPOLY*)geom, srs, bbox, precision);
	case MULTIPOINTTYPE:
		return asgeojson_multipoint((LWMPOINT*)geom, srs, bbox, precision);
	case MULTILINETYPE:
		return asgeojson_multiline((LWMLINE*)geom, srs, bbox, precision);
	case MULTIPOLYGONTYPE:
		return asgeojson_multipolygon((LWMPOLY*)geom, srs, bbox, precision);
	case COLLECTIONTYPE:
		return asgeojson_collection((LWCOLLECTION*)geom, srs, bbox, precision);
	default:
		lwerror("lwgeom_to_geojson: '%s' geometry type not supported",
		        lwtype_name(type));
	}

	/* Never get here */
	return NULL;
}
Example #23
0
LWGEOM* lwgeom_set_effective_area(const LWGEOM *igeom,int set_area, double trshld)
{
	LWDEBUG(2, "Entered  lwgeom_set_effective_area");
	switch (igeom->type)
	{
	case POINTTYPE:
	case MULTIPOINTTYPE:
		return lwgeom_clone(igeom);
	case LINETYPE:
		return (LWGEOM*)lwline_set_effective_area((LWLINE*)igeom,set_area, trshld);
	case POLYGONTYPE:
		return (LWGEOM*)lwpoly_set_effective_area((LWPOLY*)igeom,set_area, trshld);
	case MULTILINETYPE:
	case MULTIPOLYGONTYPE:
	case COLLECTIONTYPE:
		return (LWGEOM*)lwcollection_set_effective_area((LWCOLLECTION *)igeom,set_area, trshld);
	default:
		lwerror("lwgeom_simplify: unsupported geometry type: %s",lwtype_name(igeom->type));
	}
	return NULL;
}
Example #24
0
static size_t
assvg_geom_buf(const LWGEOM *geom, char *output, int relative, int precision)
{
    int type = geom->type;
	char *ptr=output;

	switch (type)
	{
	case POINTTYPE:
		ptr += assvg_point_buf((LWPOINT*)geom, ptr, relative, precision);
		break;

	case LINETYPE:
		ptr += assvg_line_buf((LWLINE*)geom, ptr, relative, precision);
		break;

	case POLYGONTYPE:
		ptr += assvg_polygon_buf((LWPOLY*)geom, ptr, relative, precision);
		break;

	case MULTIPOINTTYPE:
		ptr += assvg_multipoint_buf((LWMPOINT*)geom, ptr, relative, precision);
		break;

	case MULTILINETYPE:
		ptr += assvg_multiline_buf((LWMLINE*)geom, ptr, relative, precision);
		break;

	case MULTIPOLYGONTYPE:
		ptr += assvg_multipolygon_buf((LWMPOLY*)geom, ptr, relative, precision);
		break;

	default:
		lwerror("assvg_geom_buf: '%s' geometry type not supported.",
		        lwtype_name(type));
	}

	return (ptr-output);
}
Example #25
0
/*
* Compound curves provide type information for their curved sub-geometries
* but not their linestring sub-geometries.
*   COMPOUNDCURVE((0 0, 1 1), CURVESTRING(1 1, 2 2, 3 3))
*/
static void lwcompound_to_wkt_sb(const LWCOMPOUND *comp, stringbuffer_t *sb, int precision, uint8_t variant)
{
    int i = 0;

    if ( ! (variant & WKT_NO_TYPE) )
    {
        stringbuffer_append(sb, "COMPOUNDCURVE"); /* "COMPOUNDCURVE" */
        dimension_qualifiers_to_wkt_sb((LWGEOM*)comp, sb, variant);
    }
    if ( comp->ngeoms < 1 )
    {
        empty_to_wkt_sb(sb);
        return;
    }

    stringbuffer_append(sb, "(");
    variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
    for ( i = 0; i < comp->ngeoms; i++ )
    {
        int type = comp->geoms[i]->type;
        if ( i > 0 )
            stringbuffer_append(sb, ",");
        /* Linestring subgeoms don't get type identifiers */
        if ( type == LINETYPE )
        {
            lwline_to_wkt_sb((LWLINE*)comp->geoms[i], sb, precision, variant | WKT_NO_TYPE );
        }
        /* But circstring subgeoms *do* get type identifiers */
        else if ( type == CIRCSTRINGTYPE )
        {
            lwcircstring_to_wkt_sb((LWCIRCSTRING*)comp->geoms[i], sb, precision, variant );
        }
        else
        {
            lwerror("lwcompound_to_wkt_sb: Unknown type recieved %d - %s", type, lwtype_name(type));
        }
    }
    stringbuffer_append(sb, ")");
}
Example #26
0
static size_t
assvg_geom_size(const LWGEOM *geom, int relative, int precision)
{
    int type = geom->type;
	size_t size = 0;

	switch (type)
	{
	case POINTTYPE:
		size = assvg_point_size((LWPOINT*)geom, relative, precision);
		break;

	case LINETYPE:
		size = assvg_line_size((LWLINE*)geom, relative, precision);
		break;

	case POLYGONTYPE:
		size = assvg_polygon_size((LWPOLY*)geom, relative, precision);
		break;

	case MULTIPOINTTYPE:
		size = assvg_multipoint_size((LWMPOINT*)geom, relative, precision);
		break;

	case MULTILINETYPE:
		size = assvg_multiline_size((LWMLINE*)geom, relative, precision);
		break;

	case MULTIPOLYGONTYPE:
		size = assvg_multipolygon_size((LWMPOLY*)geom, relative, precision);
		break;

	default:
		lwerror("assvg_geom_size: '%s' geometry type not supported.",
		        lwtype_name(type));
	}

	return size;
}
Example #27
0
Datum geometry_geometrytype(PG_FUNCTION_ARGS)
{
	GSERIALIZED *lwgeom;
	text *type_text;
	char *type_str = palloc(32);

	lwgeom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));

	/* Make it empty string to start */
	*type_str = 0;

	/* Build up the output string */
	strncat(type_str, "ST_", 32);
	strncat(type_str, lwtype_name(gserialized_get_type(lwgeom)), 32);
	
	/* Build a text type to store things in */
	type_text = cstring2text(type_str);
	pfree(type_str);

	PG_FREE_IF_COPY(lwgeom, 0);
	PG_RETURN_TEXT_P(type_text);
}
/* exported */
LWGEOM*
lwgeom_split(const LWGEOM* lwgeom_in, const LWGEOM* blade_in)
{
	switch (lwgeom_in->type)
	{
	case LINETYPE:
		return lwline_split((const LWLINE*)lwgeom_in, blade_in);

	case POLYGONTYPE:
		return lwpoly_split((const LWPOLY*)lwgeom_in, blade_in);

	case MULTIPOLYGONTYPE:
	case MULTILINETYPE:
	case COLLECTIONTYPE:
		return lwcollection_split((const LWCOLLECTION*)lwgeom_in, blade_in);

	default:
		lwerror("Splitting of %s geometries is unsupported",
		        lwtype_name(lwgeom_in->type));
		return NULL;
	}

}
Example #29
0
Datum geometry_geometrytype(PG_FUNCTION_ARGS)
{
	GSERIALIZED *gser;
	text *type_text;
	static int type_str_len = 32;
	char type_str[type_str_len];

	/* Read just the header from the toasted tuple */
	gser = PG_GETARG_GSERIALIZED_P_SLICE(0, 0, gserialized_max_header_size());

	/* Make it empty string to start */
	type_str[0] = 0;

	/* Build up the output string */
	strncat(type_str, "ST_", type_str_len);
	strncat(type_str, lwtype_name(gserialized_get_type(gser)), type_str_len - 3);
	
	/* Build a text type to store things in */
	type_text = cstring2text(type_str);

	PG_FREE_IF_COPY(gser, 0);
	PG_RETURN_TEXT_P(type_text);
}
Example #30
0
/*
* Multi-surfaces provide type information for their curved sub-geometries
* but not their linear sub-geometries.
*   MULTISURFACE(((0 0, 1 1, 1 0, 0 0)), CURVEPOLYGON(CURVESTRING(0 0, 1 1, 2 2, 0 1, 0 0)))
*/
static void lwmsurface_to_wkt_sb(const LWMSURFACE *msurf, stringbuffer_t *sb, int precision, uint8_t variant)
{
    int i = 0;

    if ( ! (variant & WKT_NO_TYPE) )
    {
        stringbuffer_append(sb, "MULTISURFACE"); /* "MULTISURFACE" */
        dimension_qualifiers_to_wkt_sb((LWGEOM*)msurf, sb, variant);
    }
    if ( msurf->ngeoms < 1 )
    {
        empty_to_wkt_sb(sb);
        return;
    }
    stringbuffer_append(sb, "(");
    variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
    for ( i = 0; i < msurf->ngeoms; i++ )
    {
        int type = msurf->geoms[i]->type;
        if ( i > 0 )
            stringbuffer_append(sb, ",");
        switch (type)
        {
        case POLYGONTYPE:
            /* Linestring subgeoms don't get type identifiers */
            lwpoly_to_wkt_sb((LWPOLY*)msurf->geoms[i], sb, precision, variant | WKT_NO_TYPE );
            break;
        case CURVEPOLYTYPE:
            /* But circstring subgeoms *do* get type identifiers */
            lwcurvepoly_to_wkt_sb((LWCURVEPOLY*)msurf->geoms[i], sb, precision, variant);
            break;
        default:
            lwerror("lwmsurface_to_wkt_sb: Unknown type recieved %d - %s", type, lwtype_name(type));
        }
    }
    stringbuffer_append(sb, ")");
}