Advertisement
Guest User

Untitled

a guest
Dec 18th, 2014
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.38 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. using GeoAPI.Geometries;
  6. using NetTopologySuite.Geometries.Utilities;
  7.  
  8. namespace NetTopologySuite.Algorithm.Locate
  9. {
  10. public class OptimizedIndexedPointInAreaLocator : IPointOnGeometryLocator
  11. {
  12. private readonly CustomIntervalRTree tree;
  13.  
  14. public OptimizedIndexedPointInAreaLocator(IGeometry g)
  15. {
  16. if (!(g is IPolygonal))
  17. {
  18. throw new ArgumentException("Argument must be Polygonal");
  19. }
  20.  
  21. this.tree = new CustomIntervalRTree(g);
  22. }
  23.  
  24. public Location Locate(Coordinate p)
  25. {
  26. RayCrossingCounter rcc = new RayCrossingCounter(p);
  27. this.tree.Count(p.Y, rcc);
  28. /*
  29. Coordinate p0 = new Coordinate();
  30. Coordinate p1 = new Coordinate();
  31. foreach (var ln in this.tree.leafNodes)
  32. {
  33. if (!ln.Range.Contains(p.Y))
  34. {
  35. continue;
  36. }
  37.  
  38. p0.Y = ln.Range.MinY;
  39. p0.X = ln.ForMinY;
  40.  
  41. p1.Y = ln.Range.MaxY;
  42. p1.X = ln.ForMaxY;
  43. rcc.CountSegment(p0, p1);
  44. }*/
  45.  
  46. return rcc.Location;
  47. }
  48.  
  49. private sealed class CustomIntervalRTree
  50. {
  51. internal readonly LeafNode[] leafNodes;
  52.  
  53. private readonly BranchNode[] branchNodes;
  54.  
  55. public CustomIntervalRTree(IGeometry geometry)
  56. {
  57. List<LeafNode> leafNodes = new List<LeafNode>();
  58. foreach (ILineString line in LinearComponentExtracter.GetLines(geometry))
  59. {
  60. Coordinate[] pts = line.Coordinates;
  61. for (int i = 1; i < pts.Length; i++)
  62. {
  63. Coordinate p0 = pts[i - 1];
  64. Coordinate p1 = pts[i];
  65.  
  66. LeafNode leafNode;
  67. if (p0.Y <= p1.Y)
  68. {
  69. leafNode = new LeafNode
  70. {
  71. Range =
  72. {
  73. MinY = p0.Y,
  74. MaxY = p1.Y
  75. },
  76. ForMinY = p0.X,
  77. ForMaxY = p1.X
  78. };
  79. }
  80. else
  81. {
  82. leafNode = new LeafNode
  83. {
  84. Range =
  85. {
  86. MinY = p1.Y,
  87. MaxY = p0.Y
  88. },
  89. ForMinY = p1.X,
  90. ForMaxY = p0.X
  91. };
  92. }
  93.  
  94. leafNodes.Add(leafNode);
  95. }
  96. }
  97.  
  98. if (leafNodes.Count % 2 > 0)
  99. {
  100. leafNodes.Add(new LeafNode
  101. {
  102. Range =
  103. {
  104. MaxY = Double.NegativeInfinity,
  105. MinY = Double.PositiveInfinity
  106. }
  107. });
  108. }
  109.  
  110. this.leafNodes = leafNodes.ToArray();
  111. Array.Sort(this.leafNodes, LeafNodeComparer.Instance);
  112.  
  113. // Optimal would be leafNodes.Count - 1.
  114. // Current implementation is up to ceil(log2(leafNodes.Count)) higher than optimal.
  115. List<BranchNode> branchNodes = new List<BranchNode>();
  116. int savedB = 0;
  117. for (int i = 0; i < leafNodes.Count; i += 2)
  118. {
  119. BranchNode branchNode = new BranchNode
  120. {
  121. LeftChildIndex = ~(i),
  122. RightChildIndex = ~(i + 1),
  123. Range =
  124. {
  125. MinY = Math.Min(leafNodes[i].Range.MinY, leafNodes[i + 1].Range.MinY),
  126. MaxY = Math.Max(leafNodes[i].Range.MaxY, leafNodes[i + 1].Range.MaxY)
  127. }
  128. };
  129.  
  130. branchNodes.Add(branchNode);
  131. }
  132.  
  133. BranchNode[] lastRound = branchNodes.ToArray();
  134. while (true)
  135. {
  136. int endRange = branchNodes.Count;
  137.  
  138. for (int i = savedB; i < endRange; i += 2)
  139. {
  140. BranchNode branchNode = new BranchNode
  141. {
  142. LeftChildIndex = i,
  143. RightChildIndex = i + 1,
  144. Range =
  145. {
  146. MinY = Math.Min(branchNodes[i].Range.MinY, branchNodes[i + 1].Range.MinY),
  147. MaxY = Math.Max(branchNodes[i].Range.MaxY, branchNodes[i + 1].Range.MaxY)
  148. }
  149. };
  150.  
  151. branchNodes.Add(branchNode);
  152. }
  153.  
  154. if (lastRound.Length == 2)
  155. {
  156. break;
  157. }
  158.  
  159. if (branchNodes.Count % 2 > 0)
  160. {
  161. BranchNode branchNode = new BranchNode
  162. {
  163. Range =
  164. {
  165. MaxY = Double.NegativeInfinity,
  166. MinY = Double.PositiveInfinity
  167. }
  168. };
  169.  
  170. branchNodes.Add(branchNode);
  171. }
  172.  
  173. lastRound = branchNodes.GetRange(savedB, (endRange - savedB + 1) / 2).ToArray();
  174. savedB = endRange;
  175. }
  176.  
  177. this.branchNodes = branchNodes.ToArray();
  178. }
  179.  
  180. public void Count(double y, RayCrossingCounter c)
  181. {
  182. this.Count(y, c, this.branchNodes.Length - 1, new Coordinate(), new Coordinate());
  183. }
  184.  
  185. private void Count(double y, RayCrossingCounter c, int i, Coordinate p0, Coordinate p1)
  186. {
  187. if (i < 0)
  188. {
  189. LeafNode l = this.leafNodes[~i];
  190. if (!l.Range.Contains(y))
  191. {
  192. return;
  193. }
  194.  
  195. p0.Y = l.Range.MinY;
  196. p0.X = l.ForMinY;
  197.  
  198. p1.Y = l.Range.MaxY;
  199. p1.X = l.ForMaxY;
  200.  
  201. c.CountSegment(p0, p1);
  202. }
  203. else
  204. {
  205. BranchNode b = this.branchNodes[i];
  206. if (!b.Range.Contains(y))
  207. {
  208. return;
  209. }
  210.  
  211. this.Count(y, c, b.LeftChildIndex, p0, p1);
  212. this.Count(y, c, b.RightChildIndex, p0, p1);
  213. }
  214. }
  215. }
  216.  
  217. private sealed class LeafNodeComparer : Comparer<LeafNode>
  218. {
  219. internal static readonly LeafNodeComparer Instance = new LeafNodeComparer();
  220.  
  221. public override int Compare(LeafNode x, LeafNode y)
  222. {
  223. double xRange = x.Range.MinY + x.Range.MaxY;
  224. double yRange = y.Range.MinY + y.Range.MaxY;
  225. return xRange.CompareTo(yRange);
  226. }
  227. }
  228.  
  229. private struct BranchNode
  230. {
  231. internal Range Range;
  232.  
  233. internal int LeftChildIndex;
  234.  
  235. internal int RightChildIndex;
  236.  
  237. public override string ToString()
  238. {
  239. return "Range: [" + Range + "], L: " + LeftChildIndex + ", R: " + RightChildIndex;
  240. }
  241. }
  242.  
  243. private struct LeafNode
  244. {
  245. internal Range Range;
  246.  
  247. internal double ForMinY;
  248.  
  249. internal double ForMaxY;
  250.  
  251. public override string ToString()
  252. {
  253. return "P0: (x = " + ForMinY + ", y = " + Range.MinY + "), P1: (x = " + ForMaxY + ", y = " + Range.MaxY + ")";
  254. }
  255. }
  256.  
  257. private struct Range
  258. {
  259. internal double MinY;
  260.  
  261. internal double MaxY;
  262.  
  263. internal bool Contains(double y)
  264. {
  265. return y >= MinY &&
  266. y <= MaxY;
  267. }
  268.  
  269. public override string ToString()
  270. {
  271. return "MinY: " + MinY + ", MaxY: " + MaxY;
  272. }
  273. }
  274. }
  275. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement