feat: compute sha1 checksum of extended grids
This commit is contained in:
132
src/Grid.fs
132
src/Grid.fs
@@ -6,6 +6,7 @@ open FSharpPlus.Control
|
||||
open ProjNet.CoordinateSystems
|
||||
open Serilog
|
||||
open ProjNet.FSharp
|
||||
open MessagePack
|
||||
open MBrace.FsPickler
|
||||
//open FsKDTree
|
||||
open KdTree // C# version
|
||||
@@ -40,14 +41,14 @@ type Grid =
|
||||
BBox: BBox
|
||||
}
|
||||
interface IGrid with
|
||||
member x.getVertex n = x.Nodes[n]
|
||||
member x.getCell n = x.Elem[n]
|
||||
member x.getCellVertices n =
|
||||
let a, b, c = x.Elem[n]
|
||||
x.Nodes[a], x.Nodes[b], x.Nodes[c]
|
||||
member x.getVertices() = x.Nodes
|
||||
member x.getCells() = x.Elem
|
||||
member x.getBoundingBox() = x.BBox
|
||||
member this.getVertex n = this.Nodes[n]
|
||||
member this.getCell n = this.Elem[n]
|
||||
member this.getCellVertices n =
|
||||
let a, b, c = this.Elem[n]
|
||||
this.Nodes[a], this.Nodes[b], this.Nodes[c]
|
||||
member this.getVertices() = this.Nodes
|
||||
member this.getCells() = this.Elem
|
||||
member this.getBoundingBox() = this.BBox
|
||||
static member empty =
|
||||
{
|
||||
Elem = Array.empty
|
||||
@@ -506,11 +507,25 @@ module Util =
|
||||
type private IdxTree = KdTree<float, int>
|
||||
type private NodeIdxTree = KdTree<float, int>
|
||||
|
||||
[<MessagePackObject>]
|
||||
type BinGrid = {
|
||||
[<Key(0)>] hash : byte[]
|
||||
[<Key(1)>] vertices : (float * float)[]
|
||||
[<Key(2)>] cells : (int * int * int)[]
|
||||
} with
|
||||
member this.toGrid (): Grid =
|
||||
{
|
||||
Nodes = this.vertices
|
||||
Elem = this.cells
|
||||
BBox = calcBBox this.vertices
|
||||
}
|
||||
|
||||
type ExtendedGrid(grid: IGrid) =
|
||||
let mutable nodeTree: NodeIdxTree option = None
|
||||
let mutable elementTree: IdxTree option = None
|
||||
let mutable neighborIndex: NeighborIndex option = None
|
||||
let mutable centroids: Vertex [] option = None
|
||||
let mutable gridHash: byte[] = [||]
|
||||
|
||||
let getNeighborIdx () =
|
||||
match neighborIndex with
|
||||
@@ -520,35 +535,35 @@ type ExtendedGrid(grid: IGrid) =
|
||||
neighborIndex.Value
|
||||
|
||||
interface IGrid with
|
||||
member x.getVertex n = grid.getVertex n
|
||||
member x.getCell n = grid.getCell n
|
||||
member x.getCellVertices n = grid.getCellVertices n
|
||||
member x.getVertices() = grid.getVertices ()
|
||||
member x.getCells() = grid.getCells ()
|
||||
member x.getBoundingBox() = grid.getBoundingBox ()
|
||||
member this.getVertex n = grid.getVertex n
|
||||
member this.getCell n = grid.getCell n
|
||||
member this.getCellVertices n = grid.getCellVertices n
|
||||
member this.getVertices() = grid.getVertices ()
|
||||
member this.getCells() = grid.getCells ()
|
||||
member this.getBoundingBox() = grid.getBoundingBox ()
|
||||
|
||||
member x.NeighborIndex = neighborIndex
|
||||
member x.NodeTree = nodeTree
|
||||
member x.ElementTree = elementTree
|
||||
member this.NeighborIndex = neighborIndex
|
||||
member this.NodeTree = nodeTree
|
||||
member this.ElementTree = elementTree
|
||||
|
||||
member x.Grid = grid
|
||||
member this.Grid = grid
|
||||
|
||||
member x.initNeighborIndex(?cache: string) =
|
||||
member this.initNeighborIndex(?cache: string) =
|
||||
match neighborIndex with
|
||||
| Some _ -> ()
|
||||
| None -> neighborIndex <- makeNeighborIndex grid |> Some
|
||||
|
||||
member x.initNodeTree() =
|
||||
member this.initNodeTree() =
|
||||
match nodeTree with
|
||||
| Some _ -> ()
|
||||
| None -> nodeTree <- Util.buildNearestNodeTree grid |> Some
|
||||
|
||||
member x.initElementTree() =
|
||||
member this.initElementTree() =
|
||||
match elementTree with
|
||||
| Some _ -> ()
|
||||
| None -> elementTree <- Util.buildNearestElementTree grid |> Some
|
||||
|
||||
member x.nearestNode(p0: float, p1: float) =
|
||||
member this.nearestNode(p0: float, p1: float) =
|
||||
let nearest (tree: KdTree<_, _>) =
|
||||
tree.GetNearestNeighbours([| p0; p1 |], 1)
|
||||
|> Array.tryHead
|
||||
@@ -556,49 +571,64 @@ type ExtendedGrid(grid: IGrid) =
|
||||
match nodeTree with
|
||||
| Some tree -> nearest tree
|
||||
| None ->
|
||||
x.initNodeTree ()
|
||||
this.initNodeTree ()
|
||||
nearest nodeTree.Value
|
||||
|
||||
member x.tryGetNode(p: float * float) =
|
||||
x.nearestNode p
|
||||
member this.tryGetNode(p: float * float) =
|
||||
this.nearestNode p
|
||||
|> Option.bind (fun n ->
|
||||
x.getElemsSurroundingNode n
|
||||
this.getElemsSurroundingNode n
|
||||
|> Array.fold (fun (a: int option) e ->
|
||||
if a.IsNone then
|
||||
let vx = x.Grid.getCellVertices e
|
||||
let vx = this.Grid.getCellVertices e
|
||||
if Util.isInsideTriangle vx p then Some n else None
|
||||
else a) None
|
||||
)
|
||||
|
||||
member private x.tryFindElementTwice (grid: IGrid) (tree: IdxTree) ((p0, p1): float * float as p) =
|
||||
member private this.tryFindElementTwice (grid: IGrid) (tree: IdxTree) ((p0, p1): float * float as p) =
|
||||
Util.tryFindElement grid tree p
|
||||
|> Option.orElse (
|
||||
tree.GetNearestNeighbours([| p0; p1 |], 1)
|
||||
|> Array.tryHead
|
||||
|> Option.bind (fun leaf ->
|
||||
x.getElemsSurroundingElem leaf.Value
|
||||
this.getElemsSurroundingElem leaf.Value
|
||||
|> Array.tryFind (fun eIdx ->
|
||||
let vx = x.Grid.getCellVertices eIdx
|
||||
let vx = this.Grid.getCellVertices eIdx
|
||||
Util.isInsideTriangle vx p))
|
||||
)
|
||||
|
||||
member x.tryGetElement p =
|
||||
member this.tryGetElement p =
|
||||
elementTree
|
||||
|> Option.bind (fun tree ->
|
||||
x.tryFindElementTwice grid tree p)
|
||||
this.tryFindElementTwice grid tree p)
|
||||
|> Option.orElseWith (fun () ->
|
||||
x.initElementTree ()
|
||||
x.tryFindElementTwice grid elementTree.Value p)
|
||||
this.initElementTree ()
|
||||
this.tryFindElementTwice grid elementTree.Value p)
|
||||
|
||||
member x.tryGetElementSloppy(p0, p1 as p) =
|
||||
member this.tryGetElementSloppy(p0, p1 as p) =
|
||||
match elementTree with
|
||||
| Some tree -> Util.tryFindElement grid tree p
|
||||
| None ->
|
||||
x.initElementTree ()
|
||||
// x.initNodeTree ()
|
||||
this.initElementTree ()
|
||||
// this.initNodeTree ()
|
||||
Util.tryFindElement grid elementTree.Value p
|
||||
|
||||
member x.getCentroids() =
|
||||
member this.getSha1() =
|
||||
if gridHash.Length = 0 then
|
||||
let bg : BinGrid = {
|
||||
hash = [||]
|
||||
vertices = (this :> IGrid).getVertices ()
|
||||
cells = (this :> IGrid).getCells ()
|
||||
}
|
||||
let bytes = MessagePackSerializer.Serialize(bg)
|
||||
let sha1 = System.Security.Cryptography.SHA1.Create()
|
||||
gridHash <- sha1.ComputeHash bytes
|
||||
gridHash
|
||||
|
||||
member this.getSha1String() =
|
||||
this.getSha1() |> Convert.ToHexStringLower
|
||||
|
||||
member this.getCentroids() =
|
||||
match centroids with
|
||||
| Some cx -> cx
|
||||
| None ->
|
||||
@@ -606,35 +636,35 @@ type ExtendedGrid(grid: IGrid) =
|
||||
centroids <- Some cx
|
||||
cx
|
||||
|
||||
member x.calcCircumCircle e =
|
||||
member this.calcCircumCircle e =
|
||||
let triangle = grid.getCellVertices e
|
||||
Util.Element.calcCircumscribedCircle triangle
|
||||
|
||||
member x.getElemsSurroundingNode n =
|
||||
member this.getElemsSurroundingNode n =
|
||||
getNeighborIdx ()
|
||||
|> fun idx -> idx.ElemsAroundNode[n]
|
||||
|
||||
member x.getNodesSurroundingNode n =
|
||||
member this.getNodesSurroundingNode n =
|
||||
getNeighborIdx ()
|
||||
|> fun idx -> idx.NodesAroundNode[n]
|
||||
|
||||
member x.getNodesSurroundingElem e =
|
||||
member this.getNodesSurroundingElem e =
|
||||
let idx = getNeighborIdx ()
|
||||
let elem = grid.getCell e
|
||||
getSurrounding idx.NodesAroundNode elem
|
||||
|
||||
member x.getElemsSurroundingElem e =
|
||||
member this.getElemsSurroundingElem e =
|
||||
let idx = getNeighborIdx ()
|
||||
let elem = grid.getCell e
|
||||
getSurrounding idx.ElemsAroundNode elem
|
||||
|
||||
member x.saveNeighborIndex(fname: string) =
|
||||
member this.saveNeighborIndex(fname: string) =
|
||||
let binarySerializer = FsPickler.CreateBinarySerializer()
|
||||
let nix = getNeighborIdx ()
|
||||
let pickle = binarySerializer.Pickle nix
|
||||
IO.File.WriteAllBytes(fname, pickle)
|
||||
|
||||
member x.loadNeighborIndex(fname: string) =
|
||||
member this.loadNeighborIndex(fname: string) =
|
||||
let binarySerializer = FsPickler.CreateBinarySerializer()
|
||||
if IO.File.Exists fname then
|
||||
let pickle = IO.File.ReadAllBytes fname
|
||||
@@ -645,18 +675,18 @@ type ExtendedGrid(grid: IGrid) =
|
||||
else
|
||||
false
|
||||
|
||||
member x.saveNodeTree(fname: string) =
|
||||
member this.saveNodeTree(fname: string) =
|
||||
let binarySerializer = FsPickler.CreateBinarySerializer()
|
||||
let tree =
|
||||
nodeTree
|
||||
|> Option.defaultWith (fun () ->
|
||||
x.initNodeTree ()
|
||||
this.initNodeTree ()
|
||||
nodeTree.Value)
|
||||
|
||||
let pickle = binarySerializer.Pickle tree
|
||||
IO.File.WriteAllBytes(fname, pickle)
|
||||
|
||||
member x.loadNodeTree(fname: string) =
|
||||
member this.loadNodeTree(fname: string) =
|
||||
let binarySerializer = FsPickler.CreateBinarySerializer()
|
||||
if IO.File.Exists fname then
|
||||
let pickle = IO.File.ReadAllBytes fname
|
||||
@@ -665,18 +695,18 @@ type ExtendedGrid(grid: IGrid) =
|
||||
else
|
||||
false
|
||||
|
||||
member x.saveElementTree(fname: string) =
|
||||
member this.saveElementTree(fname: string) =
|
||||
let binarySerializer = FsPickler.CreateBinarySerializer()
|
||||
let tree =
|
||||
elementTree
|
||||
|> Option.defaultWith (fun () ->
|
||||
x.initElementTree ()
|
||||
this.initElementTree ()
|
||||
elementTree.Value)
|
||||
|
||||
let pickle = binarySerializer.Pickle tree
|
||||
IO.File.WriteAllBytes(fname, pickle)
|
||||
|
||||
member x.loadElementTree(fname: string) =
|
||||
member this.loadElementTree(fname: string) =
|
||||
let binarySerializer = FsPickler.CreateBinarySerializer()
|
||||
if IO.File.Exists fname then
|
||||
let pickle = IO.File.ReadAllBytes fname
|
||||
|
||||
@@ -5,37 +5,38 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<IsPackable>true</IsPackable>
|
||||
<PackageId>Oceanbox.FvcomKit</PackageId>
|
||||
<Authors/>
|
||||
<Company/>
|
||||
<Authors />
|
||||
<Company />
|
||||
<Version>5.7.0</Version>
|
||||
<LangVersion>preview</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Types.fs"/>
|
||||
<Compile Include="Grid.fs"/>
|
||||
<Compile Include="Arome.fs"/>
|
||||
<Compile Include="Fvcom.fs"/>
|
||||
<Compile Include="Thredds.fs"/>
|
||||
<Compile Include="Polygon.fs"/>
|
||||
<Compile Include="Adjoin.fs"/>
|
||||
<Compile Include="Interpol.fs"/>
|
||||
<Compile Include="ROMS.fs"/>
|
||||
<Compile Include="NorKyst.fs"/>
|
||||
<Compile Include="NorShelf.fs"/>
|
||||
<Compile Include="Smoothing.fs"/>
|
||||
<Compile Include="Types.fs" />
|
||||
<Compile Include="Grid.fs" />
|
||||
<Compile Include="Arome.fs" />
|
||||
<Compile Include="Fvcom.fs" />
|
||||
<Compile Include="Thredds.fs" />
|
||||
<Compile Include="Polygon.fs" />
|
||||
<Compile Include="Adjoin.fs" />
|
||||
<Compile Include="Interpol.fs" />
|
||||
<Compile Include="ROMS.fs" />
|
||||
<Compile Include="NorKyst.fs" />
|
||||
<Compile Include="NorShelf.fs" />
|
||||
<Compile Include="Smoothing.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.100"/>
|
||||
<PackageReference Include="FSharp.Data" Version="6.4.0"/>
|
||||
<PackageReference Include="FSharpPlus" Version="1.6.1"/>
|
||||
<PackageReference Include="FsPickler" Version="5.3.2"/>
|
||||
<PackageReference Include="KDTree" Version="1.4.1"/>
|
||||
<PackageReference Include="MathNet.Numerics.FSharp" Version="5.0.0"/>
|
||||
<PackageReference Include="ProjNet.FSharp" Version="5.2.0"/>
|
||||
<PackageReference Include="SDSlite.Oceanbox" Version="2.7.3"/>
|
||||
<PackageReference Include="Serilog" Version="4.1.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="8.0.0"/>
|
||||
<PackageReference Include="Thoth.Json.Net" Version="12.0.0"/>
|
||||
<PackageReference Include="FSharp.Data" Version="6.4.1" />
|
||||
<PackageReference Include="FSharpPlus" Version="1.7.0" />
|
||||
<PackageReference Include="FsPickler" Version="5.3.2" />
|
||||
<PackageReference Include="KDTree" Version="1.4.1" />
|
||||
<PackageReference Include="MathNet.Numerics.FSharp" Version="5.0.0" />
|
||||
<PackageReference Include="MessagePack" Version="3.1.3" />
|
||||
<PackageReference Include="ProjNet.FSharp" Version="5.2.0" />
|
||||
<PackageReference Include="SDSlite.Oceanbox" Version="2.7.3" />
|
||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />
|
||||
<PackageReference Include="Thoth.Json.Net" Version="12.0.0" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.200" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user