Class HausdorffSimilarityMeasure

 1 /*
 2  * Copyright (c) 2016 Vivid Solutions.
 3  *
 4  * All rights reserved. This program and the accompanying materials
 5  * are made available under the terms of the Eclipse Public License 2.0
 6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 8  * and the Eclipse Distribution License is available at
 9  *
10  * http://www.eclipse.org/org/documents/edl-v10.php.
11  */
12  
13 package org.locationtech.jts.algorithm.match;
14  
15 import org.locationtech.jts.algorithm.distance.DiscreteHausdorffDistance;
16 import org.locationtech.jts.geom.Envelope;
17 import org.locationtech.jts.geom.Geometry;
18  
19 /**
20  * Measures the degree of similarity between two {@link Geometry}s
21  * using the Hausdorff distance metric.
22  * The measure is normalized to lie in the range [0, 1].
23  * Higher measures indicate a great degree of similarity.
24  * <p>
25  * The measure is computed by computing the Hausdorff distance
26  * between the input geometries, and then normalizing
27  * this by dividing it by the diagonal distance across 
28  * the envelope of the combined geometries.
29  * 
30  * @author mbdavis
31  *
32  */
33 public class HausdorffSimilarityMeasure 
34     implements SimilarityMeasure
35 {
36     /*
37     public static double measure(Geometry a, Geometry b)
38     {
39         HausdorffSimilarityMeasure gv = new HausdorffSimilarityMeasure(a, b);
40         return gv.measure();
41     }
42     */
43     
44     public HausdorffSimilarityMeasure()
45     {
46     }
47     
48     /*
49      * Densify a small amount to increase accuracy of Hausdorff distance
50      */
51     private static final double DENSIFY_FRACTION = 0.25;
52     
53     public double measure(Geometry g1, Geometry g2)
54     {        
55         double distance = DiscreteHausdorffDistance.distance(g1, g2, DENSIFY_FRACTION);
56         
57         Envelope env = new Envelope(g1.getEnvelopeInternal());
58         env.expandToInclude(g2.getEnvelopeInternal());
59         double envSize = diagonalSize(env);
60         // normalize so that more similarity produces a measure closer to 1
61         double measure = 1 - distance / envSize;
62         
63         //System.out.println("Hausdorff distance = " + distance + ", measure = " + measure);
64         return measure;
65     }
66     
67     public static double diagonalSize(Envelope env)
68     {
69         if (env.isNull()) return 0.0;
70         
71         double width = env.getWidth(); 
72         double hgt = env.getHeight();
73         return Math.sqrt(width * width + hgt * hgt);
74     }
75 }
76