1 / 21

F# and Path Reduction

F# and Path Reduction. Kit Eason - @ kitlovesfsharp – www.kiteason.com – kit.eason@gmail.com. Norway – way too complicated!. Way, way too complicated!. Ramer–Douglas– Peucker. A record type. type Point = {Long : double; Lat : double}. Distance from line.

lilli
Télécharger la présentation

F# and Path Reduction

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. F# and Path Reduction Kit Eason - @kitlovesfsharp – www.kiteason.com – kit.eason@gmail.com

  2. Norway – way too complicated!

  3. Way, way too complicated!

  4. Ramer–Douglas–Peucker

  5. A record type type Point = {Long: double; Lat: double}

  6. Distance from line letprivatefindPerpendicularDistance p p1 p2 = if (p1.Long = p2.Long) then abs(p.Long- p1.Long) else let slope = (p2.Lat - p1.Lat) / (p2.Long - p1.Long) let intercept = p1.Lat - (slope * p1.Long) abs(slope *p.Long-p.Lat+ intercept) /sqrt((pown slope 2) +1.)

  7. Recursive algorithm letrec Reduce epsilon (points : Point[]) = ifpoints.Length<3|| epsilon =0.then points else letfirstPoint= points.[0] letlastPoint= points.[points.Length-1] letmutable index =-1 letmutabledist=0.0 foriin1..points.Length-1do letcDist=findPerpendicularDistance points.[i] firstPointlastPoint if (cDist>dist) then dist<-cDist index <-i if (dist> epsilon) then let l1 = points.[0..index] let l2 = points.[index..] let r1 = Reduce epsilon l1 let r2 = Reduce epsilon l2 Array.append (r1.[0..r1.Length-2]) r2 else [|firstPoint; lastPoint|]

  8. letrec Reduce epsilon (points : Point[]) = ifpoints.Length<3|| epsilon =0.then points else letfirstPoint= points.[0] letlastPoint= points.[points.Length-1] letmutable index =-1 letmutabledist=0.0 foriin1..points.Length-1do letcDist=findPerpendicularDistance points.[i] firstPointlastPoint if (cDist>dist) then dist<-cDist index <-i if (dist> epsilon) then let l1 = points.[0..index] let l2 = points.[index..] let r1 = Reduce epsilon l1 let r2 = Reduce epsilon l2 Array.append (r1.[0..r1.Length-2]) r2 else [|firstPoint; lastPoint|]

  9. The data nan nan 8.299972 54.778750 8.300778 54.778278 8.300806 54.775778 8.302417 54.775000 8.302444 54.772472 8.300778 54.771611 8.300750 54.767444 nan nan 8.277417 54.764111 8.277417 54.775750 8.279083 54.776611 8.279111 54.797444

  10. Reading the data letprivateReadDatafileName= fileName |>File.ReadAllLines |>Array.breakOn (fun line -> line ="nan nan") |>Array.Parallel.mapToPoints |>FilterCount100

  11. Breaking into arrays letbreakOn (f :'a -> bool) (a : array<'a>) = [| let result =ResizeArray() for x in a do if f x then yield result |>Array.ofSeq result.Clear() else result.Add(x) yield result |>Array.ofSeq |]

  12. Converting to points letprivateToPoints (lines : array<string>) = lines |>Array.Parallel.map (fun line ->line.Split [|'\t'|]) |>Array.Parallel.map (fun items -> items |>Array.mapDouble.Parse) |>Array.choose (fun doubles ->match doubles with | [|long; lat|] -> Some {Long=long; Lat=lat} | _ -> None)

  13. Eliminating tiny islands (and lakes!) letprivateFilterCountminCount groups = groups |>Array.filter (fun g ->Array.length g >minCount)

  14. Calling the RDP algorithm let Simplify e polyLines= polyLines |>Array.Parallel.map (fun p -> p |>Reduce.Reduce e)

  15. ε = 0

  16. ε = 0.001

  17. ε = 0.01

  18. ε = 0.1

  19. ε = 1

  20. Out-takes

  21. Resources • www.github.com/misterspeedy/coastline • www.fsharp.org • www.fsharpforfunandprofit.com • Chris Smith’s “Animal Guide”

More Related