Skip to content

Instantly share code, notes, and snippets.

@darrell
Created November 21, 2017 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrell/8faf7ea9573d3d515e0aa90a90e2aef7 to your computer and use it in GitHub Desktop.
Save darrell/8faf7ea9573d3d515e0aa90a90e2aef7 to your computer and use it in GitHub Desktop.
How to calculate the similarty of two polygons, located in different locations
-- how to calculate the similarty of two polygons, located in different locations
-- requires PostGIS
-- the idea here is to translate both polygons to the origin, then calculate the hausdorff distance
-- between them. We can't do them at their original locations, because.. well, that's not how Hausdorff works.
-- see https://en.wikipedia.org/wiki/Hausdorff_distance#Related_concepts
-- create a sample table with
DROP TABLE IF EXISTS example_hausdorff;
CREATE TABLE example_hausdorff(
id integer,
orig_geom geometry(Polygon),
translated_geom geometry(Polygon)
);
-- Add two polygons to it.
-- these polygons are the same shape, but translated (i.e. they are 10x10 squares)
-- the first has one more point (100, 105) than the second.
INSERT INTO example_hausdorff(id, orig_geom) VALUES
(1, st_geomfromtext('POLYGON((100 100,100 105,100 110,110 110,110 100,100 100))')),
(2, st_geomfromtext('POLYGON((200 200,200 210,210 210,210 200,200 200))'));
-- same polygons, rotated 45º
INSERT INTO example_hausdorff(id, orig_geom) VALUES
(3, st_rotate(st_geomfromtext('POLYGON((100 100,100 105,100 110,110 110,110 100,100 100))'), pi()/4)),
(4, st_rotate(st_geomfromtext('POLYGON((200 200,200 210,210 210,210 200,200 200))'), pi()/4));
-- Now translate all those geometries so that their centroid is on the origin:
UPDATE example_hausdorff
SET translated_geom =
st_translate(orig_geom,
st_x(st_centroid(orig_geom))*-1.0,
st_y(st_centroid(orig_geom))*-1.0
);
-- have a look at what we got.
-- the translated geometries
SELECT
st_astext(orig_geom),
st_astext(translated_geom)
FROM example_hausdorff;
-- the translated origins
SELECT
st_astext(st_centroid(orig_geom)),
st_astext(st_centroid(translated_geom))
FROM example_hausdorff ;
-- these should be same (i.e. distance is 0) despite the polygons themselves not being identical
-- that is one has five points, the other has four.
SELECT st_hausdorffdistance(
(SELECT translated_geom FROM example_hausdorff WHERE id=1),
(SELECT translated_geom FROM example_hausdorff WHERE id=2)
);
-- these should be different, though the exact magnitude depends on the geometries themselves.
SELECT st_hausdorffdistance(
(SELECT translated_geom FROM example_hausdorff WHERE id=1),
(SELECT translated_geom FROM example_hausdorff WHERE id=3)
);
-- these will be very close, but not identical because floats
SELECT st_hausdorffdistance(
(SELECT translated_geom FROM example_hausdorff WHERE id=3),
(SELECT translated_geom FROM example_hausdorff WHERE id=4)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment