Skip to content

Instantly share code, notes, and snippets.

@misterspeedy
Created September 24, 2017 16:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save misterspeedy/51cd38f4ff423be4718fb3f5be834bc0 to your computer and use it in GitHub Desktop.
Save misterspeedy/51cd38f4ff423be4718fb3f5be834bc0 to your computer and use it in GitHub Desktop.
namespace OSBuildings
module Perimeter =
// Need to include this Nuget package: https://www.nuget.org/packages/Huitian.EGIS.ShapeFileLib/
// Need to add a reference to System.Drawing
let shpPath = @"C:\Data\OSBuildings\wales_buildings_clipped.shp"
let demo1() =
let sf = new EGIS.ShapeFileLib.ShapeFile(shpPath)
Seq.init sf.RecordCount (sf.GetShapeData)
|> Seq.take 10
|> Seq.iter(fun c ->
printfn "---"
c
|> Seq.iter (fun p ->
printfn "%A" p))
open System.Drawing
let distance (p1: PointF, p2: PointF) =
let dx = pown (p1.X - p2.X) 2
let dy = pown (p1.Y - p2.Y) 2
dx + dy |> sqrt
let polyLength (ps : PointF seq) =
ps
|> Seq.pairwise
|> Seq.sumBy distance
// This will slightly overestimate the perimeter because it will
// effectively join any 'voids' in the building with the main
// perimeter. How would you fix it?
let maxPerimeter filePath =
use sf = new EGIS.ShapeFileLib.ShapeFile(filePath)
Seq.init sf.RecordCount (sf.GetShapeData)
|> Seq.maxBy (fun pointGroups ->
pointGroups
|> Seq.concat
|> polyLength)
maxPerimeter shpPath |> printfn "%A"
open System.IO
let maxPerimeterDir dirPath filePattern =
Directory.EnumerateFiles(dirPath, filePattern)
|> Seq.collect (fun fileName ->
let sf = new EGIS.ShapeFileLib.ShapeFile(fileName)
Seq.init sf.RecordCount (sf.GetShapeData))
|> Seq.maxBy (fun pointGroups ->
pointGroups
|> Seq.concat
|> polyLength)
maxPerimeterDir @"C:\Data\OSBuildings" "*.shp" |> printfn "%A"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment