# Create array of hexagons, place in index, and search by point

**URL:** <https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325>\
**Category:** Geo\
**Created:** [April 11, 2023, 3:19am UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325 "2023-04-11T03:19:34Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![thk686](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thk686/32/48926_2.png) [@thk686](https://discourse.julialang.org/u/thk686)\
**Post date:** [April 11, 2023, 3:19am UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/1 "2023-04-11T03:19:34Z")

</div>

I’ve been looking at JuliaGeo to how I might do the following: 1) create a tiled array of hexagons, 2) put them in a spatial index, and 3) be able to find which hexagon intersects a point. I have written this code in Boost Geometry and would like to see how it looks in Julia.

I assume I can use a LineString or LinearRing to build the hexagons. Can you give an example of constructing these that uses pure Julia (ie not pointers into eg GDAL)?

How would I then go about bulk-loading these into an rstar tree and doing point queries?

Thanks.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 11, 2023, 11:44am UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/2 "2023-04-11T11:44:13Z")

</div>

@thk686 if you are interested in a pure Julia solution, I recommend checking the [GeoStats.jl](https://juliaearth.github.io/GeoStats.jl/stable) stack instead, particularly the [Meshes.jl](https://juliageometry.github.io/Meshes.jl/stable) submodule.

You can create an hexagon given a list of vertices in counter-clockwise orientation:

```julia
julia> using Meshes

julia> points = [(cos(θ),sin(θ)) for θ in range(0, 2π-π/3, length=6)]
6-element Vector{Tuple{Float64, Float64}}:
 (1.0, 0.0)
 (0.4999999999999999, 0.8660254037844387)
 (-0.5000000000000002, 0.8660254037844386)
 (-1.0, 1.2246467991473532e-16)
 (-0.4999999999999996, -0.8660254037844388)
 (0.5000000000000001, -0.8660254037844386)

julia> hexagon = Hexagon(points)
Hexagon{2,Float64}
  └─Point(1.0, 0.0)
  └─Point(0.4999999999999999, 0.8660254037844387)
  └─Point(-0.5000000000000002, 0.8660254037844386)
  └─Point(-1.0, 1.2246467991473532e-16)
  └─Point(-0.4999999999999996, -0.8660254037844388)
  └─Point(0.5000000000000001, -0.8660254037844386)

```

and can visualize for debugging purposes:

```julia
using MeshViz
import GLMakie as Mke

viz(hexagon)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/f/9ff346765ade8918543d18f2cf0a7a3516881f06.png)

If you are interested in finding out which hexagon is closest to a given point, you can place the hexagons inside a `Collection`, which is a “domain” in our jargon:

```julia
gset = Collection([hexagon1, hexagon2, ...])

```

Then use the [KNearestSearch](https://juliageometry.github.io/Meshes.jl/stable/algorithms/neighborsearch.html#Meshes.KNearestSearch) method to query points. Keep in mind that we are actively working on adding new methods, geometries and domain types. Contributions are very welcome.

---

<div class="post-metadata">

**Author:** ![thk686](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thk686/32/48926_2.png) [@thk686](https://discourse.julialang.org/u/thk686)\
**Post date:** [April 11, 2023, 2:27pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/3 "2023-04-11T14:27:19Z")

</div>

Sweet. Very nice. I will try this. I can use nn search to find the enclosing polygon when the point falls inside the area of interest, but more generally, I will also need an intersects predicate to know when the point falls outside any polygon. Is that planned or should I use eg GEOS for that part? I’d be happy to help out if I can.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 11, 2023, 2:37pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/4 "2023-04-11T14:37:01Z")

</div>

We already have intersection algorithms, and algorithms to check the relative position of a point in a geometry. Check

[https://juliageometry.github.io/Meshes.jl/stable/algorithms/intersection.html](https://juliageometry.github.io/Meshes.jl/stable/algorithms/intersection.html)

You can also use

```julia
point ∈ hexagon

```

to check if a point is in a polygon, and also

```julia
sideof(point, boundary(hexagon))

```

to check if it is `:INSIDE`, `:OUTSIDE` or `:ON` the boundary.

---

<div class="post-metadata">

**Author:** ![pitsianis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pitsianis/32/26588_2.png) [@pitsianis](https://discourse.julialang.org/u/pitsianis)\
**Post date:** [April 11, 2023, 4:48pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/5 "2023-04-11T16:48:36Z")

</div>

Since this question concerns hexagons, floor and parity operations on the transformed point coordinates should identify the hexagon it belongs to without forming an array of hexagons and intersecting with each one as a point-to-polygon query.

The hexagon tiles consist of triangle tiles whose vertices form a grid with regular unit steps and a 60-degree angle instead of a right angle at the origin. That is how I would do it.

Welcome to the Julia language discourse!

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 11, 2023, 5:00pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/6 "2023-04-11T17:00:43Z")

</div>

Agree 100% @pitsianis , we could exploit the regularity of the tessellation to perform the queries. Unfortunately, we don’t have a HexagonGrid domain implemented yet. Or mechanisms to operate on these tilings. People have shared comments about this on Zulip, and I welcome everyone to join our forum over there.

---

<div class="post-metadata">

**Author:** ![thk686](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thk686/32/48926_2.png) [@thk686](https://discourse.julialang.org/u/thk686)\
**Post date:** [April 11, 2023, 8:58pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/7 "2023-04-11T20:58:06Z")

</div>

Thanks for the comment. Yes, I know I could implement this as a type of grid. I want the code to be generalizable to any set of polygons, so it make sense to have a generalized spatial index.

---

<div class="post-metadata">

**Author:** ![thk686](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thk686/32/48926_2.png) [@thk686](https://discourse.julialang.org/u/thk686)\
**Post date:** [April 12, 2023, 2:01am UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/8 "2023-04-12T02:01:36Z")

</div>

My function generates a vector of hexagons. Is there a way to plot all at once? Also, it seems a Collection takes an array. Can I initialize a Collection from a vector?

---

<div class="post-metadata">

**Author:** ![thk686](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thk686/32/48926_2.png) [@thk686](https://discourse.julialang.org/u/thk686)\
**Post date:** [April 12, 2023, 2:20am UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/9 "2023-04-12T02:20:03Z")

</div>

Figured it out… `[myvec[i] for i in eachindex(myvec)]`

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 12, 2023, 12:04pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/10 "2023-04-12T12:04:40Z")

</div>

> [@thk686](#):
>
> My function generates a vector of hexagons. Is there a way to plot all at once? Also, it seems a Collection takes an array. Can I initialize a Collection from a vector?

You can simply pass the vector of geometries to the `viz` function and it will recognize each individual geometry. The `Collection` takes a `AbstractVector` of geometries, you can `Collection(collect(list))` if your list is not already a `Vector`.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 12, 2023, 12:05pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/11 "2023-04-12T12:05:46Z")

</div>

What is the type of `myvec`? You can check if `myvec isa AbstractVector`. If it is not, you can `collect(myvec)`, which is basically equivalent to the list comprehension syntax.

---

<div class="post-metadata">

**Author:** ![thk686](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thk686/32/48926_2.png) [@thk686](https://discourse.julialang.org/u/thk686)\
**Post date:** [April 12, 2023, 2:31pm UTC](https://discourse.julialang.org/t/create-array-of-hexagons-place-in-index-and-search-by-point/97325/12 "2023-04-12T14:31:11Z")

</div>

Thanks. Getting used to the type system. I realized after posting that it was a type issue and modified the function to return a concrete type.
