Class Key

 1  
 2 /*
 3  * Copyright (c) 2016 Vivid Solutions.
 4  *
 5  * All rights reserved. This program and the accompanying materials
 6  * are made available under the terms of the Eclipse Public License 2.0
 7  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 8  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 9  * and the Eclipse Distribution License is available at
10  *
11  * http://www.eclipse.org/org/documents/edl-v10.php.
12  */
13 package org.locationtech.jts.index.quadtree;
14  
15 import org.locationtech.jts.geom.Coordinate;
16 import org.locationtech.jts.geom.Envelope;
17  
18 /**
19  * A Key is a unique identifier for a node in a quadtree.
20  * It contains a lower-left point and a level number. The level number
21  * is the power of two for the size of the node envelope
22  *
23  * @version 1.7
24  */
25 public class Key {
26  
27   public static int computeQuadLevel(Envelope env)
28   {
29     double dx = env.getWidth();
30     double dy = env.getHeight();
31     double dMax = dx > dy ? dx : dy;
32     int level = DoubleBits.exponent(dMax) + 1;
33     return level;
34   }
35  
36   // the fields which make up the key
37   private Coordinate pt = new Coordinate();
38   private int level = 0;
39   // auxiliary data which is derived from the key for use in computation
40   private Envelope env = null;
41  
42   public Key(Envelope itemEnv)
43   {
44     computeKey(itemEnv);
45   }
46  
47   public Coordinate getPoint() { return pt; }
48   public int getLevel() { return level; }
49   public Envelope getEnvelope() { return env; }
50  
51   public Coordinate getCentre()
52   {
53     return new Coordinate(
54       (env.getMinX() + env.getMaxX()) / 2,
55       (env.getMinY() + env.getMaxY()) / 2
56       );
57   }
58   /**
59    * return a square envelope containing the argument envelope,
60    * whose extent is a power of two and which is based at a power of 2
61    */
62   public void computeKey(Envelope itemEnv)
63   {
64     level = computeQuadLevel(itemEnv);
65     env = new Envelope();
66     computeKey(level, itemEnv);
67     // MD - would be nice to have a non-iterative form of this algorithm
68     while (! env.contains(itemEnv)) {
69       level += 1;
70       computeKey(level, itemEnv);
71     }
72   }
73  
74   private void computeKey(int level, Envelope itemEnv)
75   {
76     double quadSize = DoubleBits.powerOf2(level);
77     pt.x = Math.floor(itemEnv.getMinX() / quadSize) * quadSize;
78     pt.y = Math.floor(itemEnv.getMinY() / quadSize) * quadSize;
79     env.init(pt.x, pt.x + quadSize, pt.y, pt.y + quadSize);
80   }
81 }
82