Changeset 4208
- Timestamp:
- 06/24/09 15:08:33 (3 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 modified
-
doc/reference.xml (modified) (1 diff)
-
postgis/lwgeom_geos.c (modified) (2 diffs)
-
postgis/postgis.sql.in.c (modified) (1 diff)
-
postgis/uninstall_postgis.sql.in.c (modified) (1 diff)
-
regress/hausdorff_expected (added)
-
regress/hausdorff.sql (added)
-
regress/Makefile.in (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/reference.xml
r4205 r4208 9819 9819 </refentry> 9820 9820 9821 <refentry id="ST_HausdorffDistance"> 9822 <refnamediv> 9823 <refname>ST_HausdorffDistance</refname> 9824 9825 <refpurpose>Returns the Hausdorff distance between two geometries.</refpurpose> 9826 </refnamediv> 9827 9828 <refsynopsisdiv> 9829 <funcsynopsis> 9830 <funcprototype> 9831 <funcdef>float <function>ST_HausdorffDistance</function></funcdef> 9832 9833 <paramdef><type>geometry </type> 9834 <parameter>g1</parameter></paramdef> 9835 9836 <paramdef><type>geometry </type> 9837 <parameter>g2</parameter></paramdef> 9838 </funcprototype> 9839 <funcprototype> 9840 <funcdef>float <function>ST_HausdorffDistance</function></funcdef> 9841 9842 <paramdef><type>geometry </type> 9843 <parameter>g1</parameter></paramdef> 9844 9845 <paramdef><type>geometry </type> 9846 <parameter>g2</parameter></paramdef> 9847 9848 <paramdef><type>float</type> 9849 <parameter>densifyFrac</parameter></paramdef> 9850 </funcprototype> 9851 </funcsynopsis> 9852 </refsynopsisdiv> 9853 9854 <refsection> 9855 <title>Description</title> 9856 9857 <para>Implements algorithm for computing a distance metric which can be thought of as the "Discrete Hausdorff Distance". 9858 This is the Hausdorff distance restricted to discrete points for one of the geometries.</para> 9859 <para> 9860 When densifyFrac is specified, this function performs a segment densification before computing the discrete hausdorff distance. The densifyFrac parameter sets the fraction by which to densify each segment. Each segment will be split into a number of equal-length subsegments, whose fraction of the total length is closest to the given fraction. 9861 </para> 9862 9863 <note> 9864 <para> 9865 The current implementation supports only vertices as the discrete locations. This could be extended to allow an arbitrary density of points to be used. 9866 </para> 9867 </note> 9868 <note> 9869 <para> 9870 This algorithm is NOT equivalent to the standard Hausdorff distance. However, it computes an approximation that is correct for a large subset of useful cases. 9871 One important part of this subset is Linestrings that are roughly parallel to each other, and roughly equal in length. This is a useful metric for line matching. 9872 </para> 9873 </note> 9874 9875 </refsection> 9876 9877 <refsection> 9878 <title>Examples</title> 9879 9880 <programlisting>postgis=# SELECT st_HausdorffDistance( 9881 'LINESTRING (0 0, 2 0)'::geometry, 9882 'MULTIPOINT (0 1, 1 0, 2 1)'::geometry); 9883 st_hausdorffdistance 9884 ---------------------- 9885 1 9886 (1 row) 9887 </programlisting> 9888 <programlisting>postgis=# SELECT st_hausdorffdistance('LINESTRING (130 0, 0 0, 0 150)'::geometry, 'LINESTRING (10 10, 10 150, 130 10)'::geometry, 0.5); 9889 st_hausdorffdistance 9890 ---------------------- 9891 70 9892 (1 row) 9893 </programlisting> 9894 9895 </refsection> 9896 </refentry> 9897 9821 9898 <refentry id="ST_Distance_Sphere"> 9822 9899 <refnamediv> -
trunk/postgis/lwgeom_geos.c
r4198 r4208 63 63 Datum linemerge(PG_FUNCTION_ARGS); 64 64 Datum coveredby(PG_FUNCTION_ARGS); 65 Datum hausdorffdistance(PG_FUNCTION_ARGS); 66 Datum hausdorffdistancedensify(PG_FUNCTION_ARGS); 65 67 66 68 Datum pgis_union_geometry_array_old(PG_FUNCTION_ARGS); … … 89 91 memcpy(VARDATA(result), ver, strlen(ver)); 90 92 PG_RETURN_POINTER(result); 93 } 94 95 /** 96 * @brief Compute the Hausdorff distance thanks to the corresponding GEOS function 97 * @example hausdorffdistance {@link #hausdorffdistance} - SELECT st_hausdorffdistance( 98 * 'POLYGON((0 0, 0 2, 1 2, 2 2, 2 0, 0 0))'::geometry, 99 * 'POLYGON((0.5 0.5, 0.5 2.5, 1.5 2.5, 2.5 2.5, 2.5 0.5, 0.5 0.5))'::geometry); 100 */ 101 102 PG_FUNCTION_INFO_V1(hausdorffdistance); 103 Datum hausdorffdistance(PG_FUNCTION_ARGS) 104 { 105 PG_LWGEOM *geom1; 106 PG_LWGEOM *geom2; 107 GEOSGeometry *g1; 108 GEOSGeometry *g2; 109 double result; 110 int retcode; 111 112 POSTGIS_DEBUG(2, "hausdorff_distance called"); 113 114 geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); 115 geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); 116 117 initGEOS(lwnotice, lwnotice); 118 119 g1 = (GEOSGeometry *)POSTGIS2GEOS(geom1); 120 g2 = (GEOSGeometry *)POSTGIS2GEOS(geom2); 121 retcode = GEOSHausdorffDistance(g1, g2, &result); 122 GEOSGeom_destroy(g1); 123 GEOSGeom_destroy(g2); 124 125 if (retcode == 0) 126 { 127 elog(ERROR,"GEOS HausdorffDistance() threw an error!"); 128 PG_RETURN_NULL(); /*never get here */ 129 } 130 131 PG_FREE_IF_COPY(geom1, 0); 132 PG_FREE_IF_COPY(geom2, 0); 133 134 PG_RETURN_FLOAT8(result); 135 } 136 137 /** 138 * @brief Compute the Hausdorff distance with densification thanks to the corresponding GEOS function 139 * @example hausdorffdistancedensify {@link #hausdorffdistancedensify} - SELECT st_hausdorffdistancedensify( 140 * 'POLYGON((0 0, 0 2, 1 2, 2 2, 2 0, 0 0))'::geometry, 141 * 'POLYGON((0.5 0.5, 0.5 2.5, 1.5 2.5, 2.5 2.5, 2.5 0.5, 0.5 0.5))'::geometry, 0.5); 142 */ 143 144 PG_FUNCTION_INFO_V1(hausdorffdistancedensify); 145 Datum hausdorffdistancedensify(PG_FUNCTION_ARGS) 146 { 147 PG_LWGEOM *geom1; 148 PG_LWGEOM *geom2; 149 GEOSGeometry *g1; 150 GEOSGeometry *g2; 151 double densifyFrac; 152 double result; 153 int retcode; 154 155 156 geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); 157 geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); 158 densifyFrac = *(double *) PG_DETOAST_DATUM(PG_GETARG_DATUM(2)); 159 160 initGEOS(lwnotice, lwnotice); 161 162 g1 = (GEOSGeometry *)POSTGIS2GEOS(geom1); 163 g2 = (GEOSGeometry *)POSTGIS2GEOS(geom2); 164 retcode = GEOSHausdorffDistanceDensify(g1, g2, densifyFrac, &result); 165 GEOSGeom_destroy(g1); 166 GEOSGeom_destroy(g2); 167 168 if (retcode == 0) 169 { 170 elog(ERROR,"GEOS HausdorffDistanceDensify() threw an error!"); 171 PG_RETURN_NULL(); /*never get here */ 172 } 173 174 PG_FREE_IF_COPY(geom1, 0); 175 PG_FREE_IF_COPY(geom2, 0); 176 177 PG_RETURN_FLOAT8(result); 91 178 } 92 179 -
trunk/postgis/postgis.sql.in.c
r4200 r4208 3919 3919 #endif 3920 3920 3921 #if POSTGIS_GEOS_VERSION >= 32 3922 -- Requires GEOS >= 3.2.0 3923 -- Availability: 1.5.0 3924 CREATE OR REPLACE FUNCTION ST_HausdorffDistance(geometry, geometry) 3925 RETURNS FLOAT8 3926 AS 'MODULE_PATHNAME', 'hausdorffdistance' 3927 LANGUAGE 'C' IMMUTABLE STRICT; 3928 #endif 3929 3930 #if POSTGIS_GEOS_VERSION >= 32 3931 -- Requires GEOS >= 3.2.0 3932 -- Availability: 1.5.0 3933 CREATE OR REPLACE FUNCTION ST_HausdorffDistance(geometry, geometry, float8) 3934 RETURNS FLOAT8 3935 AS 'MODULE_PATHNAME', 'hausdorffdistancedensify' 3936 LANGUAGE 'C' IMMUTABLE STRICT; 3937 #endif 3938 3921 3939 -- Deprecation in 1.2.3 3922 3940 CREATE OR REPLACE FUNCTION difference(geometry,geometry) -
trunk/postgis/uninstall_postgis.sql.in.c
r4207 r4208 400 400 DROP FUNCTION ST_Intersection(geometry,geometry); 401 401 DROP FUNCTION intersection(geometry,geometry); 402 #if POSTGIS_GEOS_VERSION >= 32 403 DROP FUNCTION ST_HausdorffDistance(geometry, geometry) 404 #endif 405 #if POSTGIS_GEOS_VERSION >= 32 406 DROP FUNCTION ST_HausdorffDistance(geometry, geometry, float8) 407 #endif 402 408 403 409 -
trunk/regress/Makefile.in
r4206 r4208 53 53 regress_ogc \ 54 54 regress_bdpoly \ 55 regress_proj 55 regress_proj \ 56 hausdorff 56 57 57 58 # Covers/CoveredBy only if GEOS >= 3.0
