extern double ptarray_length_2d(const POINTARRAY *pts);
extern double ptarray_length(const POINTARRAY *pts);
+extern double ptarray_arc_length_2d(const POINTARRAY *pts);
extern int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring);
/* Co-linear! Return linear distance! */
if ( radius_A < 0 )
{
- return sqrt((A1->x-A3->x)*(A1->x-A3->x) + (A1->y-A3->y)*(A1->y-A3->y));
+ double dx = A1->x - A3->x;
+ double dy = A1->y - A3->y;
+ return sqrt(dx*dx + dy*dy);
}
/* Closed circle! Return the circumference! */
double lwcircstring_length(const LWCIRCSTRING *circ)
{
- double length = 0.0;
- LWLINE *line;
- if ( lwcircstring_is_empty(circ) )
- return 0.0;
- line = lwcircstring_segmentize(circ, 32);
- length = lwline_length(line);
- lwline_free(line);
- return length;
+ return lwcircstring_length_2d(circ);
}
double lwcircstring_length_2d(const LWCIRCSTRING *circ)
{
double length = 0.0;
- LWLINE *line;
if ( lwcircstring_is_empty(circ) )
return 0.0;
- line = lwcircstring_segmentize(circ, 32);
- length = lwline_length_2d(line);
- lwline_free(line);
- return length;
+
+ return ptarray_arc_length_2d(circ->points);
}
/*
return outpts;
}
+/**
+* Find the 2d length of the given #POINTARRAY, using circular
+* arc interpolation between each coordinate triple.
+* Length(A1, A2, A3, A4, A5) = Length(A1, A2, A3)+Length(A3, A4, A5)
+*/
+double
+ptarray_arc_length_2d(const POINTARRAY *pts)
+{
+ double dist = 0.0;
+ int i;
+ const POINT2D *a1;
+ const POINT2D *a2;
+ const POINT2D *a3;
+
+ if ( pts->npoints % 2 != 1 )
+ lwerror("arc point array with even number of points");
+
+ a1 = getPoint2d_cp(pts, 0);
+
+ for ( i=2; i < pts->npoints; i += 2 )
+ {
+ a2 = getPoint2d_cp(pts, i-1);
+ a3 = getPoint2d_cp(pts, i);
+ dist += lw_arc_length(a1, a2, a3);
+ a1 = a3;
+ }
+ return dist;
+}
/**
* Find the 2d length of the given #POINTARRAY (even if it's 3d)
ERROR: ST_Segmentize: invalid max_distance 0 (must be >= 0)
ERROR: invalid GML representation
#1957|1
-#1978|3.1413
+#1978|3.1416
#1996|{"type":"Point","coordinates":[]}
#2001|POLYGON((0 0,0 1,1 1,0 0))
#2028|TIN(((0 0,0 1,1 1,0 0)))