From: Sandro Santilli Date: Fri, 27 Aug 2004 08:13:16 +0000 (+0000) Subject: Added point_inside_circle() and translate() X-Git-Tag: pgis_0_9_1~36 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35a44b851813cbf9cdaa4be3f3b55da4cb0e762b;p=postgis Added point_inside_circle() and translate() git-svn-id: http://svn.osgeo.org/postgis/trunk@758 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/MISSING_OBJECTS b/lwgeom/MISSING_OBJECTS index 82df60b63..119bd0666 100644 --- a/lwgeom/MISSING_OBJECTS +++ b/lwgeom/MISSING_OBJECTS @@ -1,9 +1,7 @@ # This is a list of objects still missing lwgeom support AGGREGATE: KEEPING AGGREGATE [collect(geometry)] -AGGREGATE: KEEPING AGGREGATE [geomunion(geometry)] AGGREGATE: KEEPING AGGREGATE [memcollect(geometry)] -AGGREGATE: KEEPING AGGREGATE [memgeomunion(geometry)] FNCAST: KEEPING FNCAST geometry(text) (see CAST) FUNC: KEEPING FUNCTION: [line_interpolate_point(geometry, double precision)] FUNC: KEEPING FUNCTION: [simplify(geometry, double precision)] @@ -17,16 +15,18 @@ FUNC: KEEPING FUNCTION: [envelope(geometry)] FUNC: KEEPING FUNCTION: [equals(geometry, geometry)] FUNC: KEEPING FUNCTION: [expand(geometry, double precision)] FUNC: KEEPING FUNCTION: [geom_accum(geometry[], geometry)] -FUNC: KEEPING FUNCTION: [geometry_size(geometry, internal)] FUNC: KEEPING FUNCTION: [isempty(geometry)] -FUNC: KEEPING FUNCTION: [optimistic_overlap(geometry, geometry, double precision)] -FUNC: KEEPING FUNCTION: [point_inside_circle(geometry, double precision, double precision, double precision)] FUNC: KEEPING FUNCTION: [segmentize(geometry, double precision)] -FUNC: KEEPING FUNCTION: [translate(geometry, double precision, double precision, double precision)] FUNC: KEEPING FUNCTION: [unite_garray(geometry[])] +--- OBSOLETED ? +FUNC: KEEPING FUNCTION: [geometry_size(geometry, internal)] +FUNC: KEEPING FUNCTION: [optimistic_overlap(geometry, geometry, double precision)] + --- GEOS FUNC: KEEPING FUNCTION: [centroid(geometry)] (Also !GEOS implementation) +AGGREGATE: KEEPING AGGREGATE [memgeomunion(geometry)] +AGGREGATE: KEEPING AGGREGATE [geomunion(geometry)] FUNC: KEEPING FUNCTION: [isring(geometry)] FUNC: KEEPING FUNCTION: [pointonsurface(geometry)] FUNC: KEEPING FUNCTION: [buffer(geometry, double precision)] diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index a530af10a..0e614ebf2 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -32,6 +32,8 @@ Datum LWGEOM_force_collection(PG_FUNCTION_ARGS); Datum LWGEOM_force_multi(PG_FUNCTION_ARGS); Datum LWGEOM_mindistance2d(PG_FUNCTION_ARGS); Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS); +Datum LWGEOM_translate(PG_FUNCTION_ARGS); +Datum LWGEOM_inside_circle_point(PG_FUNCTION_ARGS); // internal char * lwgeom_summary_recursive(char *serialized, int offset); @@ -61,6 +63,9 @@ double distance2d_point_poly(LWPOINT *point, LWPOLY *poly); double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2); double distance2d_line_poly(LWLINE *line, LWPOLY *poly); double lwgeom_mindistance2d_recursive(char *lw1, char *lw2); +void lwgeom_translate_recursive(char *serialized, double xoff, double yoff, double zoff); +void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff); +int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad); /*------------------------------------------------------------------*/ @@ -751,6 +756,19 @@ lwgeom_mindistance2d_recursive(char *lw1, char *lw2) return mindist; } +int +lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad) +{ + POINT2D center; + + center.x = cx; + center.y = cy; + + if ( distance2d_pt_pt(p, ¢er) < rad ) return 1; + else return 0; + +} + /*------------------------------------------------------------------*/ PG_FUNCTION_INFO_V1(combine_box2d); @@ -909,6 +927,85 @@ lwgeom_summary_recursive(char *serialized, int offset) return result; } +/* + * Translate a pointarray. + */ +void +lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff) +{ + int i; + + if ( pa->ndims > 2 ) { + for (i=0; inpoints; i++) { + POINT3D *p = (POINT3D *)getPoint(pa, i); + p->x += xoff; + p->y += yoff; + p->z += zoff; + } + } else { + for (i=0; inpoints; i++) { + POINT2D *p = (POINT2D *)getPoint(pa, i); + p->x += xoff; + p->y += yoff; + } + } +} + +void +lwgeom_translate_recursive(char *serialized, + double xoff, double yoff, double zoff) +{ + LWGEOM_INSPECTED *inspected; + int i, j; + + inspected = lwgeom_inspect(serialized); + + // scan each object translating it + for (i=0; ingeometries; i++) + { + LWLINE *line=NULL; + LWPOINT *point=NULL; + LWPOLY *poly=NULL; + char *subgeom=NULL; + + point = lwgeom_getpoint_inspected(inspected, i); + if (point !=NULL) + { + lwgeom_translate_ptarray(point->point, + xoff, yoff, zoff); + continue; + } + + poly = lwgeom_getpoly_inspected(inspected, i); + if (poly !=NULL) + { + for (j=0; jnrings; j++) + { + lwgeom_translate_ptarray(poly->rings[j], + xoff, yoff, zoff); + } + continue; + } + + line = lwgeom_getline_inspected(inspected, i); + if (line != NULL) + { + lwgeom_translate_ptarray(line->points, + xoff, yoff, zoff); + continue; + } + + subgeom = lwgeom_getsubgeometry_inspected(inspected, i); + if ( subgeom == NULL ) + { + elog(ERROR, "lwgeom_getsubgeometry_inspected returned NULL??"); + } + lwgeom_translate_recursive(subgeom, xoff, yoff, zoff); + } + + pfree_inspected(inspected); +} + //get summary info on a GEOMETRY PG_FUNCTION_INFO_V1(LWGEOM_summary); Datum LWGEOM_summary(PG_FUNCTION_ARGS) @@ -1763,3 +1860,35 @@ Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(maxdist); } +//translate geometry +PG_FUNCTION_INFO_V1(LWGEOM_translate); +Datum LWGEOM_translate(PG_FUNCTION_ARGS) +{ + LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)); + double xoff = PG_GETARG_FLOAT8(1); + double yoff = PG_GETARG_FLOAT8(2); + double zoff = PG_GETARG_FLOAT8(3); + + lwgeom_translate_recursive(SERIALIZED_FORM(geom), xoff, yoff, zoff); + + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(LWGEOM_inside_circle_point); +Datum LWGEOM_inside_circle_point(PG_FUNCTION_ARGS) +{ + LWGEOM *geom; + double cx = PG_GETARG_FLOAT8(1); + double cy = PG_GETARG_FLOAT8(2); + double rr = PG_GETARG_FLOAT8(3); + LWPOINT *point; + POINT2D *pt; + + geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + point = lwpoint_deserialize(SERIALIZED_FORM(geom)); + if ( point == NULL ) PG_RETURN_NULL(); // not a point + + pt = (POINT2D *)getPoint(point->point, 0); + + PG_RETURN_BOOL(lwgeom_pt_inside_circle(pt, cx, cy, rr)); +} diff --git a/lwgeom/lwpostgis.sql.in b/lwgeom/lwpostgis.sql.in index d844b1eef..480583006 100644 --- a/lwgeom/lwpostgis.sql.in +++ b/lwgeom/lwpostgis.sql.in @@ -783,6 +783,17 @@ CREATEFUNCTION getbbox(geometry) AS '@MODULE_FILENAME@','LWGEOM_to_BOX2DFLOAT4' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATEFUNCTION translate(geometry,float8,float8,float8) + RETURNS geometry + AS '@MODULE_FILENAME@', 'LWGEOM_translate' + LANGUAGE 'C' WITH (isstrict) ; + +CREATEFUNCTION translate(geometry,float8,float8) +RETURNS geometry +AS ' + SELECT translate($1, $2, $3, 0) +' LANGUAGE 'SQL' WITH (isstrict); + ------------------------------------------------------------------------ -- DEBUG ------------------------------------------------------------------------ @@ -1145,6 +1156,10 @@ CREATEFUNCTION max_distance(geometry,geometry) AS '@MODULE_FILENAME@', 'LWGEOM_maxdistance2d_linestring' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATEFUNCTION point_inside_circle(geometry,float8,float8,float8) + RETURNS bool + AS '@MODULE_FILENAME@', 'LWGEOM_inside_circle_point' + LANGUAGE 'C' WITH (isstrict); ------------------------------------------------------------------------