[postgis-users] st_distance accuracy?
Sufficool, Stanley
ssufficool at sbcounty.gov
Tue Oct 20 13:57:27 PDT 2009
Correction inline
> -----Original Message-----
> From: postgis-users-bounces at postgis.refractions.net
> [mailto:postgis-users-bounces at postgis.refractions.net] On
> Behalf Of Sufficool, Stanley
> Sent: Tuesday, October 20, 2009 1:47 PM
> To: PostGIS Users Discussion
> Subject: [postgis-users] st_distance accuracy?
>
>
> I am attempting to get the last vertex index of a line for a
> given measure using the following:
>
> idx := max(np) from generate_series(1,st_npoints(m_geom)) as
> np where st_distance(st_pointn(m_geom,1),
> st_pointn(m_geom,np)) <= m_distance;
>
> However, some of my queries are returning the last point on
> the linestring when "m_distance" is less than the st_length()
> of the given geometry.
>
> Is this an issue with st_distance? I don't get the same issue
> when using Lat/Lon and st_distance_spheroid().
>
> select postgis_version()
> 1.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
>
> select version()
> PostgreSQL 8.4.0, compiled by Visual C++ build 1400, 32-bit
>
>
> FULL FUNCTION TEXT
> ------------------------
> CREATE OR REPLACE FUNCTION st_line_interpolate_point(m_geom
> geometry, m_percent double precision, m_offset double precision)
> RETURNS geometry AS
> $BODY$
>
> declare idx int;
> declare m_distance double precision;
> declare p1 geometry;
> declare p2 geometry;
>
> BEGIN
>
> IF (m_distance > 1 or m_distance < 0) THEN
> raise exception 'Percentage must be between 0 and 1';
> END IF;
Should read:
IF (m_percent > 1 or m_percent < 0) THEN
raise exception 'Percentage must be between 0 and 1';
END IF;
But it still errors at "Attempt to seek beyond..."
>
> /* Convert percentage to actual distance measure */
> m_distance := st_length(m_geom) * m_percent;
>
> /* Get the last point number on the line that is less than
> the requested distance */
>
> /* For Feet (NAD1983) */
> idx := max(np) from generate_series(1,st_npoints(m_geom)) as
> np where st_distance(st_pointn(m_geom,1),
> st_pointn(m_geom,np)) <= m_distance;
>
> /* For Lat/Long (TIGER Lines) */
> --idx := max(np) from generate_series(1,st_npoints(m_geom))
> as np where st_distance_sphere(st_pointn(m_geom,1),
> st_pointn(m_geom,np)) < m_distance;
>
> /* Past the end of the line segment return exception (this
> should never
> happen) */
> if idx = st_npoints(m_geom) then
> raise exception 'st_line_interpolate_point(geom, dbl, dbl):
> Attempt to seek beyond end of line.'; end if;
>
> /* Grab the 2 points of the matching line segment */
> p1:=st_pointn(m_geom,idx); p2:=st_pointn(m_geom,idx + 1);
>
> /* get the delta of the line segment and offset the
> interpolated point */
> /* Rotate deltas by 90 degrees (invert dx/dy ) */
> /* spheroid projections will need the offset to vary based on
> lat/lon */ return st_translate(
> line_interpolate_point(m_geom, m_percent),
> ((st_y(p2) - st_y(p1)) / st_distance(p1,p2)) * m_offset,
> ((st_x(p2) - st_x(p1)) / st_distance(p1,p2)) * (-m_offset)
> );
>
> END;
>
> $BODY$
> LANGUAGE 'plpgsql' VOLATILE
> COST 100;
> ALTER FUNCTION st_line_interpolate_point(geometry, double
> precision, double precision) OWNER TO postgres;
>
> _______________________________________________
> postgis-users mailing list postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users
>
More information about the postgis-users
mailing list