Scale function

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Scale function

Markus Schaber-7
Hello,

The attached patch against HEAD implements a scale function that works
equally to the translate function (and such has a very similarly looking
code).

If there are no objections in the next days, I'll apply it to HEAD.

Btw, Strk, are you going to apply the configure patches from Alex?

Markus

Index: CHANGES
===================================================================
RCS file: /home/cvs/postgis/postgis/CHANGES,v
retrieving revision 1.91
diff -u -r1.91 CHANGES
--- CHANGES 24 May 2005 17:19:46 -0000 1.91
+++ CHANGES 1 Jun 2005 16:00:43 -0000
@@ -7,6 +7,7 @@
   + Support for (Hex)(E)wkb
   + Autoprobing DriverWrapper for HexWKB / EWKT switching
  - full autoconf-based configuration
+ - added scale() companion method to translate()
 
 PostGIS 1.0.1
 2005/05/24
Index: doc/postgis.xml
===================================================================
RCS file: /home/cvs/postgis/postgis/doc/postgis.xml,v
retrieving revision 1.156
diff -u -r1.156 postgis.xml
--- doc/postgis.xml 24 May 2005 14:02:05 -0000 1.156
+++ doc/postgis.xml 1 Jun 2005 16:00:48 -0000
@@ -4415,6 +4415,15 @@
         </varlistentry>
 
         <varlistentry>
+          <term>scale(geometry,float8,float8,float8)</term>
+
+          <listitem>
+            <para>scales the geometry to a new size by multiplying the
+            ordinates with the parameters. Ie: scale(geom,X,Y,Z).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
           <term>Reverse(geometry)</term>
           <listitem>
             <para>Returns the geometry with vertex order reversed.</para>
Index: lwgeom/BBOXCACHE_BEHAVIOURS
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/BBOXCACHE_BEHAVIOURS,v
retrieving revision 1.16
diff -u -r1.16 BBOXCACHE_BEHAVIOURS
--- lwgeom/BBOXCACHE_BEHAVIOURS 23 Feb 2005 09:58:16 -0000 1.16
+++ lwgeom/BBOXCACHE_BEHAVIOURS 1 Jun 2005 16:00:48 -0000
@@ -103,6 +103,7 @@
  ## transform eventually present box in input
  apply_grid(geometry, float8, float8, float8, float8); *LWG*
  translate(geometry,float8,float8,[float8]) *SRL*
+ scale(geometry,float8,float8,[float8]) *SRL*
 
  ## These use LWGEOM as a mean to access and modify SERIALIZED form
  reverse(geometry) *LWG*
Index: lwgeom/liblwgeom.h
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/liblwgeom.h,v
retrieving revision 1.43
diff -u -r1.43 liblwgeom.h
--- lwgeom/liblwgeom.h 23 Mar 2005 16:23:45 -0000 1.43
+++ lwgeom/liblwgeom.h 1 Jun 2005 16:00:49 -0000
@@ -907,6 +907,8 @@
 extern double lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2);
 extern void lwgeom_translate_recursive(uchar *serialized, double xoff, double yoff, double zoff);
 extern void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff);
+extern void lwgeom_scale_recursive(uchar *serialized, double xoff, double yoff, double zoff);
+extern void lwgeom_scale_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff);
 extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
 extern int32 lwgeom_npoints(uchar *serialized);
 extern char ptarray_isccw(const POINTARRAY *pa);
Index: lwgeom/lwgeom_functions_basic.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_functions_basic.c,v
retrieving revision 1.116
diff -u -r1.116 lwgeom_functions_basic.c
--- lwgeom/lwgeom_functions_basic.c 6 Apr 2005 08:53:20 -0000 1.116
+++ lwgeom/lwgeom_functions_basic.c 1 Jun 2005 16:00:50 -0000
@@ -171,6 +171,97 @@
  pfree_inspected(inspected);
 }
 
+/*
+ * Scale a pointarray.
+ */
+void
+lwgeom_scale_ptarray(POINTARRAY *pa, double xfac, double yfac, double zfac)
+{
+ int i;
+ POINT3DZ p3d;
+ POINT2D p2d;
+
+ if ( TYPE_HASZ(pa->dims) )
+ {
+ for (i=0; i<pa->npoints; i++) {
+ getPoint3dz_p(pa, i, &p3d);
+ p3d.x *= xfac;
+ p3d.y *= yfac;
+ p3d.z *= zfac;
+ memcpy(getPoint_internal(pa, i), &p3d,
+ sizeof(POINT3DZ));
+ }
+ }
+ else
+ {
+ for (i=0; i<pa->npoints; i++) {
+ getPoint2d_p(pa, i, &p2d);
+ p2d.x *= xfac;
+ p2d.y *= yfac;
+ memcpy(getPoint_internal(pa, i), &p2d,
+ sizeof(POINT2D));
+ }
+ }
+}
+
+void
+lwgeom_scale_recursive(uchar *serialized,
+ double xfac, double yfac, double zfac)
+{
+ LWGEOM_INSPECTED *inspected;
+ int i, j;
+
+ inspected = lwgeom_inspect(serialized);
+
+ // scan each object translating it
+ for (i=0; i<inspected->ngeometries; i++)
+ {
+ LWLINE *line=NULL;
+ LWPOINT *point=NULL;
+ LWPOLY *poly=NULL;
+ uchar *subgeom=NULL;
+
+ point = lwgeom_getpoint_inspected(inspected, i);
+ if (point !=NULL)
+ {
+ lwgeom_scale_ptarray(point->point,
+ xfac, yfac, zfac);
+ lwgeom_release((LWGEOM *)point);
+ continue;
+ }
+
+ poly = lwgeom_getpoly_inspected(inspected, i);
+ if (poly !=NULL)
+ {
+ for (j=0; j<poly->nrings; j++)
+ {
+ lwgeom_scale_ptarray(poly->rings[j],
+ xfac, yfac, zfac);
+ }
+ lwgeom_release((LWGEOM *)poly);
+ continue;
+ }
+
+ line = lwgeom_getline_inspected(inspected, i);
+ if (line != NULL)
+ {
+ lwgeom_scale_ptarray(line->points,
+ xfac, yfac, zfac);
+ lwgeom_release((LWGEOM *)line);
+ continue;
+ }
+
+ subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
+ if ( subgeom == NULL )
+ {
+ elog(ERROR, "lwgeom_getsubgeometry_inspected returned NULL??");
+ }
+ lwgeom_scale_recursive(subgeom, xfac, yfac, zfac);
+ }
+
+ pfree_inspected(inspected);
+}
+
 //get summary info on a GEOMETRY
 PG_FUNCTION_INFO_V1(LWGEOM_summary);
 Datum LWGEOM_summary(PG_FUNCTION_ARGS)
@@ -1518,6 +1609,41 @@
  PG_RETURN_POINTER(ret);
 }
 
+//translate geometry
+PG_FUNCTION_INFO_V1(LWGEOM_scale);
+Datum LWGEOM_scale(PG_FUNCTION_ARGS)
+{
+ PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
+ PG_LWGEOM *ret;
+ uchar *srl = SERIALIZED_FORM(geom);
+ BOX2DFLOAT4 box;
+ int hasbbox;
+
+ double xfac =  PG_GETARG_FLOAT8(1);
+ double yfac =  PG_GETARG_FLOAT8(2);
+ double zfac =  PG_GETARG_FLOAT8(3);
+
+ lwgeom_scale_recursive(srl, xfac, yfac, zfac);
+
+ /* COMPUTE_BBOX WHEN_SIMPLE */
+ hasbbox=getbox2d_p(srl, &box);
+ if ( hasbbox )
+ {
+ box.xmin *= xfac;
+ box.xmax *= xfac;
+ box.ymin *= yfac;
+ box.ymax *= yfac;
+ }
+
+ // Construct PG_LWGEOM
+ ret = PG_LWGEOM_construct(srl, lwgeom_getsrid(srl), hasbbox);
+
+ // Release copy of detoasted input.
+ pfree(geom);
+
+ PG_RETURN_POINTER(ret);
+}
+
 PG_FUNCTION_INFO_V1(LWGEOM_inside_circle_point);
 Datum LWGEOM_inside_circle_point(PG_FUNCTION_ARGS)
 {
Index: lwgeom/lwpostgis.sql.in
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwpostgis.sql.in,v
retrieving revision 1.123
diff -u -r1.123 lwpostgis.sql.in
--- lwgeom/lwpostgis.sql.in 10 May 2005 12:52:02 -0000 1.123
+++ lwgeom/lwpostgis.sql.in 1 Jun 2005 16:00:53 -0000
@@ -870,6 +870,16 @@
  AS ' SELECT translate($1, $2, $3, 0) '
  LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict);
 
+CREATEFUNCTION scale(geometry,float8,float8,float8)
+ RETURNS geometry
+ AS '@MODULE_FILENAME@', 'LWGEOM_scale'
+ LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict) ;
+
+CREATEFUNCTION scale(geometry,float8,float8)
+ RETURNS geometry
+ AS ' SELECT scale($1, $2, $3, 1) '
+ LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict);
+
 --- CHIP functions
 
 CREATEFUNCTION srid(chip)

_______________________________________________
postgis-devel mailing list
[hidden email]
http://postgis.refractions.net/mailman/listinfo/postgis-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Scale function

Markus Schaber-7
Good morning,

The attached version also contains a transscale() function that
efficiently combines scale() and translate() for 2D geometries.

As my patch seems to generate some similar code duplication, I tend to
refactor the traversal functions lwgeom_xx_recursive and
lwgeom_xx_ptarray into generic ones (lwgeom_traversal_recursive and
lwgeom_traversal_ptarray) that use function and context pointers to
manipulate the actual ordinates. What do you think about it?

Markus
_______________________________________________
postgis-devel mailing list
[hidden email]
http://postgis.refractions.net/mailman/listinfo/postgis-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Scale function

strk
In reply to this post by Markus Schaber-7
On Wed, Jun 01, 2005 at 06:04:23PM +0200, Markus Schaber wrote:
> Hello,
>
> The attached patch against HEAD implements a scale function that works
> equally to the translate function (and such has a very similarly looking
> code).
>
> If there are no objections in the next days, I'll apply it to HEAD.

It is ok for me (just got back from vacation).
Note that I'd like to separate replacable functions from unreplaceable
ones to allow for a smoother upgrade procedure.

> Btw, Strk, are you going to apply the configure patches from Alex?

Haven't had time to test them yet. My primary concern is with
compatibility with all postgresql installations. For what I
understood Alex approach is parsing the flags passed to ./configure
of pgsql, what happen if no flags are given, are all pgsql defaults
compatible between versions ?

--strk;
_______________________________________________
postgis-devel mailing list
[hidden email]
http://postgis.refractions.net/mailman/listinfo/postgis-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Scale function

strk
In reply to this post by Markus Schaber-7
On Thu, Jun 02, 2005 at 11:06:14AM +0200, Markus Schaber wrote:

> Good morning,
>
> The attached version also contains a transscale() function that
> efficiently combines scale() and translate() for 2D geometries.
>
> As my patch seems to generate some similar code duplication, I tend to
> refactor the traversal functions lwgeom_xx_recursive and
> lwgeom_xx_ptarray into generic ones (lwgeom_traversal_recursive and
> lwgeom_traversal_ptarray) that use function and context pointers to
> manipulate the actual ordinates. What do you think about it?

IIRC the *_recursive ones are not the latest ones ;)
New code is all recursive, but in a double recursive manner:
lwgeom -> lwpoint, lwline, lwpoly, lwcollection -> *lwgeom

Good to have *_ptarray versions

--strk;
_______________________________________________
postgis-devel mailing list
[hidden email]
http://postgis.refractions.net/mailman/listinfo/postgis-devel
Loading...