For example, construct a new tree where each point is represented as a two-dimensional array in the form [x, y], where x and y are numbers (such as Int32, Float64, etc).
+
kd =Kd::Tree(Array(Int32)).new(points)
+
Find the nearest point to [x, y]. Returns an array with one point:
+
kd.nearest([x, y])
+
Find the nearest k points to [x, y]. Returns an array of points:
Kd::Tree(T) can accept any object that responds to #size and #[](i : Int) methods.
+
classGeoLocation
+ property name : String
+ property longitude : Float64
+ property latitude : Float64
+
+ definitialize(@name : String, @longitude : Float64, @latitude : Float64)
+ end
+
+ # Define an indexer to allow easy access by index for longitude and latitude
+ def[](index : Int32) : Float64
+ case index
+ when0then @longitude
+ when1then @latitude
+ else raise "Index out of bounds"
+ end
+ end
+
+ # Assuming all GeoLocation objects are 2-dimensional
+ defsize
+ 2
+ end
+end
+
+# Create an array of GeoLocation points
+points = [
+ GeoLocation.new("New York", -73.935242, 40.730610),
+ GeoLocation.new("Los Angeles", -118.243683, 34.052235),
+ GeoLocation.new("London", -0.127647, 51.507322),
+ GeoLocation.new("Tokyo", 139.691711, 35.689487),
+]
+
+# Initialize the KD-tree with these points
+kd_tree =Kd::Tree(GeoLocation).new(points)
+
+# Find the nearest point to London
+target =GeoLocation.new("Near London", -0.125740, 51.508530)
+nearest_point = kd_tree.nearest(target, 1)
+puts "Nearest to London: #{nearest_point.first.name} (longitude #{nearest_point.first.longitude}, latitude #{nearest_point.first.latitude})"
+# Nearest to London: London (longitude -0.127647, latitude 51.507322)
'
+ );
+
+ function handleShortkeys(event) {
+ var element = event.target || event.srcElement;
+
+ if(element.tagName == "INPUT" || element.tagName == "TEXTAREA" || element.parentElement.tagName == "TEXTAREA"){
+ return;
+ }
+
+ switch(event.key) {
+ case "?":
+ usageModal.show();
+ break;
+
+ case "Escape":
+ usageModal.hide();
+ break;
+
+ case "s":
+ case "/":
+ if(usageModal.isVisible()) {
+ return;
+ }
+ event.stopPropagation();
+ navigator.focus();
+ performSearch();
+ break;
+ }
+ }
+
+ document.addEventListener('keyup', handleShortkeys);
+
+ var scrollToEntryFromLocationHash = function() {
+ var hash = window.location.hash;
+ if (hash) {
+ var targetAnchor = decodeURI(hash.substr(1));
+ var targetEl = document.getElementById(targetAnchor)
+ if (targetEl) {
+ targetEl.offsetParent.scrollTop = targetEl.offsetTop;
+ }
+ }
+ };
+ window.addEventListener("hashchange", scrollToEntryFromLocationHash, false);
+ scrollToEntryFromLocationHash();
+});
diff --git a/search-index.js b/search-index.js
new file mode 100644
index 0000000..02fefef
--- /dev/null
+++ b/search-index.js
@@ -0,0 +1 @@
+crystal_doc_search_index_callback({"repository_name":"kd_tree","body":"# Kd::Tree\n\n[![Crystal CI](https://github.com/geocrystal/kd_tree/actions/workflows/crystal.yml/badge.svg)](https://github.com/geocrystal/kd_tree/actions/workflows/crystal.yml)\n[![GitHub release](https://img.shields.io/github/release/geocrystal/kd_tree.svg)](https://github.com/geocrystal/kd_tree/releases)\n[![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://geocrystal.github.io/kd_tree/)\n[![License](https://img.shields.io/github/license/geocrystal/kd_tree.svg)](https://github.com/geocrystal/kd_tree/blob/master/LICENSE)\n\nCrystal implementation of \"K-Dimensional Tree\" and \"N-Nearest Neighbors\"\nbased on .\n\n## Installation\n\nAdd this to your application's `shard.yml`:\n\n```yaml\ndependencies:\n kd_tree:\n github: geocrystal/kd_tree\n```\n\n## Usage\n\n```crystal\nrequire \"kd_tree\"\n```\n\nFor example, construct a new tree where each point is represented as a two-dimensional array in the form [x, y], where x and y are numbers (such as Int32, Float64, etc).\n\n```crystal\nkd = Kd::Tree(Array(Int32)).new(points)\n```\n\nFind the nearest point to `[x, y]`. Returns an array with one point:\n\n```crystal\nkd.nearest([x, y])\n```\n\nFind the nearest `k` points to `[x, y]`. Returns an array of points:\n\n```crystal\nkd.nearest([x, y], k)\n```\n\n## Example\n\n```crystal\nrequire \"kd_tree\"\n\npoints = [\n [2.0, 3.0],\n [5.0, 4.0],\n [4.0, 7.0],\n [7.0, 2.0],\n [8.0, 1.0],\n [9.0, 6.0],\n]\n\nkd = Kd::Tree(Array(Float64)).new(points)\n\nkd.nearest([1.0, 1.0])\n# => [[2.0, 3.0]])\n\nkd_tree.nearest([1.0, 1.0], 2)\n# => [[2.0, 3.0], [5.0, 4.0]])\n```\n\n### Complex objects\n\n`Kd::Tree(T)` can accept any object that responds to `#size` and `#[](i : Int)` methods.\n\n```crystal\nclass GeoLocation\n property name : String\n property longitude : Float64\n property latitude : Float64\n\n def initialize(@name : String, @longitude : Float64, @latitude : Float64)\n end\n\n # Define an indexer to allow easy access by index for longitude and latitude\n def [](index : Int32) : Float64\n case index\n when 0 then @longitude\n when 1 then @latitude\n else raise \"Index out of bounds\"\n end\n end\n\n # Assuming all GeoLocation objects are 2-dimensional\n def size\n 2\n end\nend\n\n# Create an array of GeoLocation points\npoints = [\n GeoLocation.new(\"New York\", -73.935242, 40.730610),\n GeoLocation.new(\"Los Angeles\", -118.243683, 34.052235),\n GeoLocation.new(\"London\", -0.127647, 51.507322),\n GeoLocation.new(\"Tokyo\", 139.691711, 35.689487),\n]\n\n# Initialize the KD-tree with these points\nkd_tree = Kd::Tree(GeoLocation).new(points)\n\n# Find the nearest point to London\ntarget = GeoLocation.new(\"Near London\", -0.125740, 51.508530)\nnearest_point = kd_tree.nearest(target, 1)\nputs \"Nearest to London: #{nearest_point.first.name} (longitude #{nearest_point.first.longitude}, latitude #{nearest_point.first.latitude})\"\n# Nearest to London: London (longitude -0.127647, latitude 51.507322)\n```\n\n## Performance\n\nUsing a tree with 1 million points `[x, y] of Float64` on my i7-8550U CPU @ 1.80GHz:\n\n`crystal run benchmark/benchmark.cr --release`\n\n```console\nBenchmarking KD-Tree with 1 million points\nbuild(init): 3.43 seconds\n user system total real\nnearest point 1 0.000021 0.000000 0.000021 ( 0.000022)\nnearest point 5 0.000014 0.000000 0.000014 ( 0.000014)\nnearest point 10 0.000011 0.000000 0.000011 ( 0.000012)\nnearest point 50 0.000061 0.000000 0.000061 ( 0.000061)\nnearest point 100 0.000083 0.000001 0.000084 ( 0.000084)\nnearest point 255 0.000238 0.000002 0.000240 ( 0.000240)\nnearest point 999 0.000981 0.000009 0.000990 ( 0.000990)\n```\n\n## Contributing\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [mamantoha](https://github.com/mamantoha) Anton Maminov - creator, maintainer\n","program":{"html_id":"kd_tree/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"kd_tree","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"kd_tree/Kd","path":"Kd.html","kind":"module","full_name":"Kd","name":"Kd","abstract":false,"locations":[{"filename":"src/kd_tree.cr","line_number":4,"url":null},{"filename":"src/kd_tree/version.cr","line_number":1,"url":null}],"repository_name":"kd_tree","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VERSION","name":"VERSION","value":"{{ (`shards version /__w/kd_tree/kd_tree/src/kd_tree`).chomp.stringify }}"}],"types":[{"html_id":"kd_tree/Kd/Tree","path":"Kd/Tree.html","kind":"class","full_name":"Kd::Tree(T)","name":"Tree","abstract":false,"superclass":{"html_id":"kd_tree/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"kd_tree/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"kd_tree/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/kd_tree.cr","line_number":5,"url":null}],"repository_name":"kd_tree","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"kd_tree/Kd","kind":"module","full_name":"Kd","name":"Kd"},"constructors":[{"html_id":"new(points:Array(T))-class-method","name":"new","abstract":false,"args":[{"name":"points","external_name":"points","restriction":"Array(T)"}],"args_string":"(points : Array(T))","args_html":"(points : Array(T))","location":{"filename":"src/kd_tree.cr","line_number":16,"url":null},"def":{"name":"new","args":[{"name":"points","external_name":"points","restriction":"Array(T)"}],"visibility":"Public","body":"_ = Tree(T).allocate\n_.initialize(points)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"nearest(target:T,n:Int32=1):Array(T)-instance-method","name":"nearest","abstract":false,"args":[{"name":"target","external_name":"target","restriction":"T"},{"name":"n","default_value":"1","external_name":"n","restriction":"Int32"}],"args_string":"(target : T, n : Int32 = 1) : Array(T)","args_html":"(target : T, n : Int32 = 1) : Array(T)","location":{"filename":"src/kd_tree.cr","line_number":37,"url":null},"def":{"name":"nearest","args":[{"name":"target","external_name":"target","restriction":"T"},{"name":"n","default_value":"1","external_name":"n","restriction":"Int32"}],"return_type":"Array(T)","visibility":"Public","body":"if n < 1\n return [] of T\nend\nbest_nodes = Priority::Queue(Node(T)).new\nfind_n_nearest(@root, target, 0, best_nodes, n)\nbest_nodes.map() do |__arg1|\n __arg1.value.pivot\nend\n"}},{"html_id":"root:Node(T)|Nil-instance-method","name":"root","abstract":false,"location":{"filename":"src/kd_tree.cr","line_number":13,"url":null},"def":{"name":"root","return_type":"Node(T) | ::Nil","visibility":"Public","body":"@root"}}],"types":[{"html_id":"kd_tree/Kd/Tree/Node","path":"Kd/Tree/Node.html","kind":"class","full_name":"Kd::Tree::Node(T)","name":"Node","abstract":false,"superclass":{"html_id":"kd_tree/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"kd_tree/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"kd_tree/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/kd_tree.cr","line_number":6,"url":null}],"repository_name":"kd_tree","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"kd_tree/Kd/Tree","kind":"class","full_name":"Kd::Tree(T)","name":"Tree"},"constructors":[{"html_id":"new(pivot:T,split:Int32,left:self|Nil,right:self|Nil)-class-method","name":"new","abstract":false,"args":[{"name":"pivot","external_name":"pivot","restriction":"T"},{"name":"split","external_name":"split","restriction":"Int32"},{"name":"left","external_name":"left","restriction":"self | ::Nil"},{"name":"right","external_name":"right","restriction":"self | ::Nil"}],"args_string":"(pivot : T, split : Int32, left : self | Nil, right : self | Nil)","args_html":"(pivot : T, split : Int32, left : self | Nil, right : self | Nil)","location":{"filename":"src/kd_tree.cr","line_number":9,"url":null},"def":{"name":"new","args":[{"name":"pivot","external_name":"pivot","restriction":"T"},{"name":"split","external_name":"split","restriction":"Int32"},{"name":"left","external_name":"left","restriction":"self | ::Nil"},{"name":"right","external_name":"right","restriction":"self | ::Nil"}],"visibility":"Public","body":"_ = Node(T).allocate\n_.initialize(pivot, split, left, right)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"left-instance-method","name":"left","abstract":false,"location":{"filename":"src/kd_tree.cr","line_number":7,"url":null},"def":{"name":"left","visibility":"Public","body":"@left"}},{"html_id":"pivot-instance-method","name":"pivot","abstract":false,"location":{"filename":"src/kd_tree.cr","line_number":7,"url":null},"def":{"name":"pivot","visibility":"Public","body":"@pivot"}},{"html_id":"right-instance-method","name":"right","abstract":false,"location":{"filename":"src/kd_tree.cr","line_number":7,"url":null},"def":{"name":"right","visibility":"Public","body":"@right"}},{"html_id":"split-instance-method","name":"split","abstract":false,"location":{"filename":"src/kd_tree.cr","line_number":7,"url":null},"def":{"name":"split","visibility":"Public","body":"@split"}}]}]}]}]}})
\ No newline at end of file