Woohoo! Now I can meaningfully search a superstructure!

This commit is contained in:
Simon Brooke 2020-06-03 19:12:08 +01:00
parent 4b76eb5e4f
commit 9687e57666
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
5 changed files with 60 additions and 2 deletions

View file

@ -5,6 +5,7 @@
:output-path "docs/codox"
:source-uri "https://github.com/simon-brooke/walkmap/blob/master/{filepath}#L{line}"}
:dependencies [[org.clojure/algo.generic "0.1.3"]
[org.clojure/core.memoize "1.0.236"]
[org.clojure/clojure "1.8.0"]
[org.clojure/data.zip "1.0.0"]
[org.clojure/math.numeric-tower "0.0.4"]

View file

@ -92,4 +92,6 @@
polys)
polys))))
;; (load-microworld-edn "../MicroWorld/mw-cli/isle_of_man.edn" nil {})

View file

@ -73,7 +73,14 @@
vse (vertex (:x vne)
(:y vsw)
(/ (reduce + (map #(or (:z %) 0) [vsw vne])) 2))]
(t/tag (polygon vsw vnw vne vse) :rectangle)))
(t/tag
(assoc
(polygon vsw vnw vne vse)
:centre
(vertex (+ (:x vsw) (/ (- (:x vne) (:x vsw)) 2))
(+ (:x vsw) (/ (- (:y vne) (:y vsw)) 2))
(:z vse)))
:rectangle)))
;; (rectangle (vertex 1 2 3) (vertex 7 9 4))

View file

@ -2,6 +2,7 @@
"single indexing structure for walkmap objects"
(:require [clojure.walk :refer [postwalk]]
[taoensso.timbre :as l]
[walkmap.edge :refer [edge length]]
[walkmap.path :as p]
[walkmap.polygon :as q]
[walkmap.utils :as u]
@ -180,4 +181,41 @@
#(v/within-box? % minv maxv)
(filter #(= (:kind %) :vertex) (vals s))))))
(defn find-nearest
"Search superstructure `s` for the nearest object matching `filter-fn` to
the `target` vertex. Searches only with `radius` (slight misnomer, area
actually searched is a cube). Returns one object, or `nil` if no matching
object found.
WARNING: currently only returns objects which have a defined `:centre`
(but most of the significant objects we have do)."
[s target filter-fn radius]
(let [minv (v/vertex
(- (:x (v/check-vertex target)) radius)
(- (:y target) radius) (- (or (:z target) 0) radius))
maxv (v/vertex
(+ (:x target) 0.5) (+ (:y target) 0.5)
(+ (or (:z target) 0) 0.5))]
;; filter those objects with the filter function, then sort that list
;; by the edge distance from the target to the `:centre` of the object
;; and take the first
(first
(sort-by
#(length (edge target (:centre %)))
(filter
:centre
(map #(retrieve % s)
;; for each vertex id in vids, get the objects associated with that id
;; in the vertex index as a single flat list
(reduce
concat
(remove
nil?
(map
#(-> s ::vertex-index % keys)
;; get all the vertex ids within radius of the target
(set
(map
:walkmap.id/id
(search-vertices s minv maxv))))))))))))

View file

@ -99,3 +99,13 @@
")"])))
~s)))
(defn load-edn
"Load edn from an io/reader source (filename or io/resource)."
[source]
(try
(with-open [r (io/reader source)]
(edn/read (java.io.PushbackReader. r)))
(catch java.io.IOException e
(printf "Couldn't open '%s': %s\n" source (.getMessage e)))
(catch RuntimeException e
(printf "Error parsing edn file '%s': %s\n" source (.getMessage e)))))