Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
GeohashPrefixTree.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using System.Collections.Generic;
20 using Spatial4n.Core.Context;
21 using Spatial4n.Core.Shapes;
22 using Spatial4n.Core.Util;
23 
24 namespace Lucene.Net.Spatial.Prefix.Tree
25 {
30  {
35  {
36  protected override int GetLevelForDistance(double degrees)
37  {
39  return grid.GetLevelForDistance(degrees);
40  }
41 
42  protected override SpatialPrefixTree NewSPT()
43  {
44  return new GeohashPrefixTree(ctx, maxLevels != null ? maxLevels.Value : GeohashPrefixTree.GetMaxLevelsPossible());
45  }
46  }
47 
48 
49  public GeohashPrefixTree(SpatialContext ctx, int maxLevels)
50  : base(ctx, maxLevels)
51  {
52  Rectangle bounds = ctx.GetWorldBounds();
53  if (bounds.GetMinX() != -180)
54  throw new ArgumentException("Geohash only supports lat-lon world bounds. Got " + bounds);
55  int MAXP = GetMaxLevelsPossible();
56  if (maxLevels <= 0 || maxLevels > MAXP)
57  throw new ArgumentException("maxLen must be [1-" + MAXP + "] but got " + maxLevels);
58 
59  }
60 
65  public static int GetMaxLevelsPossible()
66  {
67  return GeohashUtils.MAX_PRECISION;
68  }
69 
70  public override int GetLevelForDistance(double dist)
71  {
72  if (dist == 0)
73  return maxLevels;//short circuit
74  int level = GeohashUtils.LookupHashLenForWidthHeight(dist, dist);
75  return Math.Max(Math.Min(level, maxLevels), 1);
76  }
77 
78  protected override Node GetNode(Point p, int level)
79  {
80  return new GhCell(GeohashUtils.EncodeLatLon(p.GetY(), p.GetX(), level), this);//args are lat,lon (y,x)
81  }
82 
83  public override Node GetNode(string token)
84  {
85  return new GhCell(token, this);
86  }
87 
88  public override Node GetNode(byte[] bytes, int offset, int len)
89  {
90  throw new System.NotImplementedException();
91  }
92 
93  public override IList<Node> GetNodes(Shape shape, int detailLevel, bool inclParents)
94  {
95  var s = shape as Point;
96  return (s != null) ? base.GetNodesAltPoint(s, detailLevel, inclParents) : base.GetNodes(shape, detailLevel, inclParents);
97  }
98 
99  public class GhCell : Node
100  {
101  public GhCell(String token, GeohashPrefixTree enclosingInstance)
102  : base(enclosingInstance, token)
103  {
104  }
105 
106  public override void Reset(string newToken)
107  {
108  base.Reset(newToken);
109  shape = null;
110  }
111 
112  public override IList<Node> GetSubCells()
113  {
114  String[] hashes = GeohashUtils.GetSubGeohashes(GetGeohash());//sorted
115  var cells = new List<Node>(hashes.Length);
116 
117  var enclosingInstance = (GeohashPrefixTree)spatialPrefixTree;
118  foreach (String hash in hashes)
119  {
120  cells.Add(new GhCell(hash, enclosingInstance));
121  }
122  return cells;
123  }
124 
125  public override int GetSubCellsSize()
126  {
127  return 32;//8x4
128  }
129 
130  public override Node GetSubCell(Point p)
131  {
132  return ((GeohashPrefixTree)spatialPrefixTree).GetNode(p, GetLevel() + 1); //not performant!
133  }
134 
135  private Shape shape;//cache
136 
137  public override Shape GetShape()
138  {
139  if (shape == null)
140  {
141  shape = GeohashUtils.DecodeBoundary(GetGeohash(), ((GeohashPrefixTree)spatialPrefixTree).ctx);
142  }
143  return shape;
144  }
145 
146  public override Point GetCenter()
147  {
148  return GeohashUtils.Decode(GetGeohash(), ((GeohashPrefixTree)spatialPrefixTree).ctx);
149  }
150 
151  private String GetGeohash()
152  {
153  return GetTokenString();
154  }
155 
156  }//class GhCell
157  }
158 }