diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..269bc19
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,45 @@
+# Catch all for anything we forgot. Add rules if you get CRLF to LF warnings.
+* text=auto
+
+# Text files that should be normalized to LF in odb.
+*.cs text eol=lf diff=csharp
+*.xaml text
+*.config text
+*.c text
+*.h text
+*.cpp text
+*.hpp text
+
+*.sln text
+*.csproj text
+*.vcxproj text
+
+*.md text
+*.tt text
+*.sh text
+*.ps1 text
+*.cmd text
+*.bat text
+*.markdown text
+*.msbuild text
+
+
+# Binary files that should not be normalized or diffed
+*.png binary
+*.jpg binary
+*.gif binary
+*.ico binary
+*.rc binary
+
+*.pfx binary
+*.snk binary
+*.dll binary
+*.exe binary
+*.lib binary
+*.exp binary
+*.pdb binary
+*.sdf binary
+*.7z binary
+
+# Generated file should just use CRLF, it's fiiine
+SolutionInfo.cs text eol=crlf diff=csharp
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..902fec9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,237 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directory
+AppPackages/
+BundleArtifacts/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+
+# FAKE - F# Make
+.fake/
+
+# Tools
+tools/
+
+# Packaging
+packaging/
\ No newline at end of file
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
new file mode 100644
index 0000000..a83b1ef
--- /dev/null
+++ b/DEPLOYMENT.md
@@ -0,0 +1,18 @@
+# Deploying a new release
+
+
+When we're ready to deploy a new release, we need to do the following steps:
+
+* Create a branch named `release`.
+* Update [`ReleaseNotes.md`](ReleaseNotes.md). Note that the format is
+important as we parse the version out and use that for the NuGet packages.
+* Push the branch to GitHub and create a pull request. This will kick off the
+AppVeyor build of the NuGet package with this new version. If you're impatient, you can run `.\build CreatePackages` and get the packages locally. If your having issues creating a package read: https://github.com/octokit/octokit.net/issues/899
+* Test!
+* When you're satisfied with this release, push the package to NuGet.
+* Create a tag `git tag v#.#.#`. For example, to create a tag for 1.0.0
+`git tag v1.0.0`
+* Push the tag to the server. `git push --tags`
+* Accept the pull request.
+* Create a [new release](https://github.com/ghuntley/geocoordinate/releases/new)
+using the tag you just created and pasting in the release notes you just wrote up
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..c4e4284
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,50 @@
+# Microsoft Public License (Ms-PL)
+
+This license governs use of the accompanying software. If you use the software,
+you accept this license. If you do not accept the license, do not use the
+software.
+
+1. Definitions
+The terms "reproduce," "reproduction," "derivative works," and "distribution"
+have the same meaning here as under U.S. copyright law. A "contribution" is the
+original software, or any additions or changes to the software. A "contributor"
+is any person that distributes its contribution under this license. "Licensed
+patents" are a contributor's patent claims that read directly on its
+contribution.
+
+2. Grant of Rights
+
+(A) Copyright Grant- Subject to the terms of this license, including the license
+conditions and limitations in section 3, each contributor grants you a
+non-exclusive, worldwide, royalty-free copyright license to reproduce its
+contribution, prepare derivative works of its contribution, and distribute its
+contribution or any derivative works that you create.
+
+(B) Patent Grant- Subject
+to the terms of this license, including the license conditions and limitations
+in section 3, each contributor grants you a non-exclusive, worldwide,
+royalty-free license under its licensed patents to make, have made, use, sell,
+offer for sale, import, and/or otherwise dispose of its contribution in the
+software or derivative works of the contribution in the software.
+
+3. Conditions and Limitations
+
+(A) No Trademark License- This license does not grant you rights to use any
+contributors' name, logo, or trademarks.
+(B) If you bring a patent claim against any contributor over patents that you
+claim are infringed by the software, your patent license from such contributor
+to the software ends automatically.
+(C) If you distribute any portion of the software, you must retain all
+copyright, patent, trademark, and attribution notices that are present in the
+software.
+(D) If you distribute any portion of the software in source code form, you may
+do so only under this license by including a complete copy of this license with
+your distribution. If you distribute any portion of the software in compiled or
+object code form, you may only do so under a license that complies with this
+license.
+(E) The software is licensed "as-is." You bear the risk of using it. The
+contributors give no express warranties, guarantees or conditions. You may have
+additional consumer rights under your local laws which this license cannot
+change. To the extent permitted under your local laws, the contributors exclude
+the implied warranties of merchantability, fitness for a particular purpose and
+non-infringement.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8a0c963
--- /dev/null
+++ b/README.md
@@ -0,0 +1,31 @@
+![Icon](https://i.imgur.com/OfoiwTs.png)
+# GeoCoordinate
+
+GeoCoordinate is a Portable Class Library compatible implementation of System.Device.Location.GeoCoordinate. It is an exact 1:1 API compliant implementation and will be supported until MSFT [sees it fit to embed the type](https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/5221530-geocoordinate-class-included-in-portable-class-lib). Which at that point this implementation will cease development/support and you will be able to simply remove this package and everything will still work.
+
+# Supported Platforms
+
+* Mono
+* .NET 4.5
+* .NET Core
+* Windows Phone 8.x
+* Universal Windows Platform
+* Xamarin iOS
+* Xamarin Android
+
+# Installation
+Installation is done via NuGet:
+
+ PM> Install-Package GeoCoordinate
+
+# Usage
+
+ GeoCoordinate pin1 = new GeoCoordinate(lat, lng);
+ GeoCoordinate pin2 = new GeoCoordinate(lat, lng);
+
+ double distanceBetween = pin1.GetDistanceTo(pin2);
+
+For more examples, refer to the MSDN reference documentation over at: https://msdn.microsoft.com/en-us/library/system.device.location.geocoordinate(v=vs.110).aspx
+
+# With thanks to
+* The icon "[Map Marker](https://thenounproject.com/term/map-marker/60112)" designed by [julianne](https://thenounproject.com/janne232) from The Noun Project.
\ No newline at end of file
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
new file mode 100644
index 0000000..3584ba8
--- /dev/null
+++ b/RELEASENOTES.md
@@ -0,0 +1,2 @@
+### New in 0.1.0 (released 2016/01/05)
+* Initial release
\ No newline at end of file
diff --git a/SolutionInfo.cs b/SolutionInfo.cs
new file mode 100644
index 0000000..df440e6
--- /dev/null
+++ b/SolutionInfo.cs
@@ -0,0 +1,13 @@
+//
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyProductAttribute("GeoCoordinate")]
+[assembly: AssemblyVersionAttribute("0.1.0")]
+[assembly: AssemblyFileVersionAttribute("0.1.0")]
+[assembly: ComVisibleAttribute(false)]
+namespace System {
+ internal static class AssemblyVersionInformation {
+ internal const string Version = "0.1.0";
+ }
+}
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..9a67022
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,14 @@
+
+init:
+ - git config --global core.autocrlf input
+build_script:
+ - cmd: build.cmd BuildApp
+# - cmd: build.cmd UnitTests
+ - cmd: build.cmd CreatePackages
+test: off
+nuget:
+ account_feed: true
+ project_feed: true
+artifacts:
+- path: 'packaging\*.nupkg'
+ name: GeoCoordinatePackages
\ No newline at end of file
diff --git a/assets/.gitkeep b/assets/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/assets/noun_60112_cc.png b/assets/noun_60112_cc.png
new file mode 100644
index 0000000..7ce74ff
Binary files /dev/null and b/assets/noun_60112_cc.png differ
diff --git a/assets/noun_60112_cc_cropped.png b/assets/noun_60112_cc_cropped.png
new file mode 100644
index 0000000..2eace02
Binary files /dev/null and b/assets/noun_60112_cc_cropped.png differ
diff --git a/build.cmd b/build.cmd
new file mode 100644
index 0000000..4bf7b28
--- /dev/null
+++ b/build.cmd
@@ -0,0 +1,38 @@
+@echo off
+
+"tools\nuget\nuget.exe" "install" "xunit.runner.console" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "2.1.0"
+"tools\nuget\nuget.exe" "install" "FAKE.Core" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "4.4.2"
+"tools\nuget\nuget.exe" "install" "SourceLink.Fake" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "1.1.0"
+:Build
+cls
+
+SET TARGET="Default"
+
+IF NOT [%1]==[] (set TARGET="%1")
+
+SET BUILDMODE="Release"
+IF NOT [%2]==[] (set BUILDMODE="%2")
+
+:: because we want to run specific steps inline on qed
+:: we need to break the dependency chain
+:: this ensures we do a build before running any tests
+
+if %TARGET%=="Default" (SET RunBuild=1)
+if %TARGET%=="RunUnitTests" (SET RunBuild=1)
+if %TARGET%=="RunIntegrationTests" (SET RunBuild=1)
+if %TARGET%=="CreatePackages" (SET RunBuild=1)
+
+if NOT "%RunBuild%"=="" (
+"tools\FAKE.Core\tools\Fake.exe" "build.fsx" "target=BuildApp" "buildMode=%BUILDMODE%"
+)
+
+"tools\FAKE.Core\tools\Fake.exe" "build.fsx" "target=%TARGET%" "buildMode=%BUILDMODE%"
+
+rem Bail if we're running a TeamCity build.
+if defined TEAMCITY_PROJECT_NAME goto Quit
+
+rem Bail if we're running a MyGet build.
+if /i "%BuildRunner%"=="MyGet" goto Quit
+
+:Quit
+exit /b %errorlevel%
\ No newline at end of file
diff --git a/build.fsx b/build.fsx
new file mode 100644
index 0000000..5bdd163
--- /dev/null
+++ b/build.fsx
@@ -0,0 +1,145 @@
+#r @"tools/FAKE.Core/tools/FakeLib.dll"
+#load "tools/SourceLink.Fake/tools/SourceLink.fsx"
+open Fake
+open System
+open SourceLink
+
+let authors = ["Geoffrey Huntley"]
+
+// project name and description
+let projectName = "GeoCoordinate"
+let projectDescription = "GeoCoordinate is a Portable Class Library compatible implementation of System.Device.Location.GeoCoordinate. It is an exact 1:1 API compliant implementation and will be supported until MSFT sees it fit to embed the type. Which at that point this implementation will cease development/support and you will be able to simply remove this package and everything will still work."
+let projectSummary = projectDescription
+
+// directories
+let buildDir = "./src/GeoCoordinatePortable/bin"
+let testResultsDir = "./testresults"
+let packagingRoot = "./packaging/"
+let packagingDir = packagingRoot @@ "GeoCoordinatePortable"
+
+let releaseNotes =
+ ReadFile "RELEASENOTES.md"
+ |> ReleaseNotesHelper.parseReleaseNotes
+
+let buildMode = getBuildParamOrDefault "buildMode" "Release"
+
+MSBuildDefaults <- {
+ MSBuildDefaults with
+ ToolsVersion = Some "14.0"
+ Verbosity = Some MSBuildVerbosity.Minimal }
+
+Target "Clean" (fun _ ->
+ CleanDirs [buildDir; testResultsDir; packagingRoot; packagingDir]
+)
+
+open Fake.AssemblyInfoFile
+open Fake.Testing
+
+Target "AssemblyInfo" (fun _ ->
+ CreateCSharpAssemblyInfo "./SolutionInfo.cs"
+ [ Attribute.Product projectName
+ Attribute.Version releaseNotes.AssemblyVersion
+ Attribute.FileVersion releaseNotes.AssemblyVersion
+ Attribute.ComVisible false ]
+)
+
+Target "CheckProjects" (fun _ ->
+ !! "./src/GeoCoordinatePortable/GeoCoordinatePortable*.csproj"
+ |> Fake.MSBuild.ProjectSystem.CompareProjectsTo "./src/GeoCoordinatePortable/GeoCoordinatePortable.csproj"
+)
+
+
+Target "FixProjects" (fun _ ->
+ !! "./src/GeoCoordinatePortable/GeoCoordinatePortable*.csproj"
+ |> Fake.MSBuild.ProjectSystem.FixProjectFiles "./src/GeoCoordinatePortable/GeoCoordinatePortable.csproj"
+)
+
+let setParams defaults = {
+ defaults with
+ ToolsVersion = Some("14.0")
+ Targets = ["Build"]
+ Properties =
+ [
+ "Configuration", buildMode
+ ]
+ }
+
+let Exec command args =
+ let result = Shell.Exec(command, args)
+ if result <> 0 then failwithf "%s exited with error %d" command result
+
+Target "BuildApp" (fun _ ->
+ build setParams "./src/GeoCoordinatePortable.sln"
+ |> DoNothing
+)
+
+Target "BuildMono" (fun _ ->
+ // xbuild does not support msbuild tools version 14.0 and that is the reason
+ // for using the xbuild command directly instead of using msbuild
+ Exec "xbuild" "./src/GeoCoordinatePortable.sln /t:Build /tv:12.0 /v:m /p:RestorePackages='False' /p:Configuration='Release' /logger:Fake.MsBuildLogger+ErrorLogger,'../src/GeoCoordinatePortable.net/tools/FAKE.Core/tools/FakeLib.dll'"
+
+)
+
+// Target "UnitTests" (fun _ ->
+// !! (sprintf "./src/GeoCoordinatePortable.Tests/bin/%s/**/GeoCoordinatePortable.Tests*.dll" buildMode)
+// |> xUnit2 (fun p ->
+// {p with
+// HtmlOutputPath = Some (testResultsDir @@ "xunit.html") })
+// )
+
+Target "SourceLink" (fun _ ->
+ [ "./src/GeoCoordinatePortable/GeoCoordinatePortable.csproj" ]
+ |> Seq.iter (fun pf ->
+ let proj = VsProj.LoadRelease pf
+ let url = "https://raw.githubusercontent.com/ghuntley/GeoCoordinatePortable/{0}/%var2%"
+ SourceLink.Index proj.Compiles proj.OutputFilePdb __SOURCE_DIRECTORY__ url
+ )
+)
+
+Target "CreateGeoCoordinatePortablePackage" (fun _ ->
+ let portableDir = packagingDir @@ "lib/portable-net45+wp80+win+wpa81/"
+ CleanDirs [portableDir]
+
+ CopyFile portableDir (buildDir @@ "Release/GeoCoordinatePortable.dll")
+ CopyFile portableDir (buildDir @@ "Release/GeoCoordinatePortable.XML")
+ CopyFile portableDir (buildDir @@ "Release/GeoCoordinatePortable.pdb")
+ CopyFiles packagingDir ["LICENSE.md"; "README.md"; "RELEASENOTES.md"]
+
+ NuGet (fun p ->
+ {p with
+ Authors = authors
+ Project = projectName
+ Description = projectDescription
+ OutputPath = packagingRoot
+ Summary = projectSummary
+ WorkingDir = packagingDir
+ Version = releaseNotes.AssemblyVersion
+ ReleaseNotes = toLines releaseNotes.Notes
+ AccessKey = getBuildParamOrDefault "nugetkey" ""
+ Publish = hasBuildParam "nugetkey" }) "src/GeoCoordinate.nuspec"
+)
+
+Target "Default" DoNothing
+
+Target "CreatePackages" DoNothing
+
+"Clean"
+ ==> "AssemblyInfo"
+ ==> "CheckProjects"
+ ==> "BuildApp"
+
+"Clean"
+ ==> "AssemblyInfo"
+ ==> "CheckProjects"
+ ==> "BuildMono"
+
+//"UnitTests"
+// ==> "Default"
+
+"SourceLink"
+ ==> "CreatePackages"
+
+"CreateGeoCoordinatePortablePackage"
+ ==> "CreatePackages"
+
+RunTargetOrDefault "Default"
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..e05e63a
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+if test "$OS" = "Windows_NT"
+then
+ # use .Net
+
+"./tools/nuget/nuget.exe" "install" "xunit.runner.console" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "2.0.0"
+"./tools/nuget/nuget.exe" "install" "FAKE.Core" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "4.4.2"
+"./tools/nuget/nuget.exe" "install" "SourceLink.Fake" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "1.1.0"
+packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
+else
+ # use mono
+mono "./tools/nuget/NuGet.exe" "install" "xunit.runner.console" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "2.0.0"
+mono "./tools/nuget/NuGet.exe" "install" "FAKE.Core" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "4.4.2"
+mono "./tools/nuget/NuGet.exe" "install" "SourceLink.Fake" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "1.1.0"
+mono "./tools/nuget/NuGet.exe" "install" "System.Net.Http" "-OutputDirectory" "tools"
+mono "./tools/nuget/NuGet.exe" "install" "Microsoft.Net.Http" "-OutputDirectory" "tools"
+mono ./tools/FAKE.Core/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
+fi
\ No newline at end of file
diff --git a/contrib/.gitkeep b/contrib/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/licenses/.gitkeep b/licenses/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/.gitkeep b/src/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/GeoCoordinate.nuspec b/src/GeoCoordinate.nuspec
new file mode 100644
index 0000000..58d4482
--- /dev/null
+++ b/src/GeoCoordinate.nuspec
@@ -0,0 +1,25 @@
+
+
+
+ @project@
+ @build.number@
+ @authors@
+ @authors@
+ @summary@
+ https://github.com/ghuntley/geocoordinate/blob/master/LICENSE.md
+ https://github.com/ghuntley/geocoordinate
+ https://i.imgur.com/OfoiwTs.png
+ false
+ @description@
+ @releaseNotes@
+ Copyright Geoffrey Huntley 2016
+ GeoCoordinate GeoCoordinatePortable system.device.location.geocoordinate
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/GeoCoordinatePortable.sln b/src/GeoCoordinatePortable.sln
new file mode 100644
index 0000000..0016934
--- /dev/null
+++ b/src/GeoCoordinatePortable.sln
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeoCoordinatePortable", "GeoCoordinatePortable\GeoCoordinatePortable.csproj", "{3F8D76E7-1AF6-40F5-960F-13C4DFA80935}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4DB8F23A-14DF-429C-88F4-7FD3B21FFDD8}"
+ ProjectSection(SolutionItems) = preProject
+ ..\.gitattributes = ..\.gitattributes
+ ..\.gitignore = ..\.gitignore
+ ..\appveyor.yaml = ..\appveyor.yaml
+ ..\build.cmd = ..\build.cmd
+ ..\build.fsx = ..\build.fsx
+ ..\build.sh = ..\build.sh
+ ..\DEPLOYMENT.md = ..\DEPLOYMENT.md
+ GeoCoordinate.nuspec = GeoCoordinate.nuspec
+ ..\LICENSE.md = ..\LICENSE.md
+ ..\README.md = ..\README.md
+ ..\RELEASENOTES.md = ..\RELEASENOTES.md
+ SolutionInfo.cs = SolutionInfo.cs
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3F8D76E7-1AF6-40F5-960F-13C4DFA80935}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F8D76E7-1AF6-40F5-960F-13C4DFA80935}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F8D76E7-1AF6-40F5-960F-13C4DFA80935}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F8D76E7-1AF6-40F5-960F-13C4DFA80935}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/GeoCoordinatePortable/GeoCoordinate.cs b/src/GeoCoordinatePortable/GeoCoordinate.cs
new file mode 100644
index 0000000..3f4cb86
--- /dev/null
+++ b/src/GeoCoordinatePortable/GeoCoordinate.cs
@@ -0,0 +1,332 @@
+using System;
+using System.Globalization;
+
+namespace GeoCoordinatePortable
+{
+ public class GeoCoordinate : IEquatable
+ {
+ public static readonly GeoCoordinate Unknown = new GeoCoordinate();
+ private double _course = double.NaN;
+ private double _horizontalAccuracy = double.NaN;
+ private double _latitude = double.NaN;
+ private double _longitude = double.NaN;
+ private double _speed = double.NaN;
+ private double _verticalAccuracy = double.NaN;
+
+
+ //
+ /// Initializes a new instance of GeoCoordinate that has no data fields set.
+ ///
+ public GeoCoordinate()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the GeoCoordinate class from latitude and longitude data.
+ ///
+ /// The latitude of the location. May range from -90.0 to 90.0.
+ /// The longitude of the location. May range from -180.0 to 180.0.
+ /// Latitude or longitude is out of range.
+ public GeoCoordinate(double latitude, double longitude)
+ : this(latitude, longitude, double.NaN)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the GeoCoordinate class from latitude, longitude, and altitude data.
+ ///
+ /// Latitude. May range from -90.0 to 90.0.
+ /// Longitude. May range from -180.0 to 180.0
+ /// The altitude in meters. May be negative, 0, positive, or Double.NaN, if unknown.
+ ///
+ /// latitude, longitude or altitude is out of range.
+ ///
+ public GeoCoordinate(double latitude, double longitude, double altitude)
+ : this(latitude, longitude, altitude, double.NaN, double.NaN, double.NaN, double.NaN)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the GeoCoordinate class from latitude, longitude, altitude, horizontal accuracy,
+ /// vertical accuracy, speed, and course.
+ ///
+ /// The latitude of the location. May range from -90.0 to 90.0.
+ /// The longitude of the location. May range from -180.0 to 180.0.
+ /// The altitude in meters. May be negative, 0, positive, or Double.NaN, if unknown.
+ ///
+ /// The accuracy of the latitude and longitude coordinates, in meters. Must be greater
+ /// than or equal to 0. If a value of 0 is supplied to this constructor, the HorizontalAccuracy property will be set to
+ /// Double.NaN.
+ ///
+ ///
+ /// The accuracy of the altitude, in meters. Must be greater than or equal to 0. If a value
+ /// of 0 is supplied to this constructor, the VerticalAccuracy property will be set to Double.NaN.
+ ///
+ ///
+ /// The speed measured in meters per second. May be negative, 0, positive, or Double.NaN, if unknown.
+ /// A negative speed can indicate moving in reverse.
+ ///
+ ///
+ /// The direction of travel, rather than orientation. This parameter is measured in degrees relative
+ /// to true north. Must range from 0 to 360.0, or be Double.NaN.
+ ///
+ ///
+ /// If latitude, longitude, horizontalAccuracy, verticalAccuracy, course is out of range.
+ ///
+ public GeoCoordinate(double latitude, double longitude, double altitude, double horizontalAccuracy,
+ double verticalAccuracy, double speed, double course)
+ {
+ Latitude = latitude;
+ Longitude = longitude;
+ Altitude = altitude;
+ HorizontalAccuracy = horizontalAccuracy;
+ VerticalAccuracy = verticalAccuracy;
+ Speed = speed;
+ Course = course;
+ }
+
+ ///
+ /// Gets or sets the latitude of the GeoCoordinate.
+ ///
+ ///
+ /// Latitude of the location.
+ ///
+ /// Latitude is set outside the valid range.
+ public double Latitude
+ {
+ get { return _latitude; }
+ set
+ {
+ if (value > 90.0 || value < -90.0)
+ {
+ throw new ArgumentOutOfRangeException("Latitude", "Argument must be in range of -90 to 90");
+ }
+ _latitude = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the longitude of the GeoCoordinate.
+ ///
+ ///
+ /// The longitude.
+ ///
+ /// Longitude is set outside the valid range.
+ public double Longitude
+ {
+ get { return _longitude; }
+ set
+ {
+ if (value > 180.0 || value < -180.0)
+ {
+ throw new ArgumentOutOfRangeException("Longitude", "Argument must be in range of -180 to 180");
+ }
+ _longitude = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the accuracy of the latitude and longitude that is given by the GeoCoordinate, in meters.
+ ///
+ ///
+ /// The accuracy of the latitude and longitude, in meters.
+ ///
+ /// HorizontalAccuracy is set outside the valid range.
+ public double HorizontalAccuracy
+ {
+ get { return _horizontalAccuracy; }
+ set
+ {
+ if (value < 0.0)
+ throw new ArgumentOutOfRangeException("HorizontalAccuracy", "Argument must be non negative");
+ _horizontalAccuracy = value == 0.0 ? double.NaN : value;
+ }
+ }
+
+ ///
+ /// Gets or sets the accuracy of the altitude given by the GeoCoordinate, in meters.
+ ///
+ ///
+ /// The accuracy of the altitude, in meters.
+ ///
+ /// VerticalAccuracy is set outside the valid range.
+ public double VerticalAccuracy
+ {
+ get { return _verticalAccuracy; }
+ set
+ {
+ if (value < 0.0)
+ throw new ArgumentOutOfRangeException("VerticalAccuracy", "Argument must be non negative");
+ _verticalAccuracy = value == 0.0 ? double.NaN : value;
+ }
+ }
+
+ ///
+ /// Gets or sets the speed in meters per second.
+ ///
+ ///
+ /// The speed in meters per second. The speed must be greater than or equal to zero, or Double.NaN.
+ ///
+ /// Speed is set outside the valid range.
+ public double Speed
+ {
+ get { return _speed; }
+ set
+ {
+ if (value < 0.0)
+ throw new ArgumentOutOfRangeException("speed", "Argument must be non negative");
+ _speed = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the heading in degrees, relative to true north.
+ ///
+ ///
+ /// The heading in degrees, relative to true north.
+ ///
+ /// Course is set outside the valid range.
+ public double Course
+ {
+ get { return _course; }
+ set
+ {
+ if (value < 0.0 || value > 360.0)
+ throw new ArgumentOutOfRangeException("course", "Argument must be in range 0 to 360");
+ _course = value;
+ }
+ }
+
+ ///
+ /// Gets a value that indicates whether the GeoCoordinate does not contain latitude or longitude data.
+ ///
+ ///
+ /// true if the GeoCoordinate does not contain latitude or longitude data; otherwise, false.
+ ///
+ public bool IsUnknown => Equals(Unknown);
+
+
+ ///
+ /// Gets the altitude of the GeoCoordinate, in meters.
+ ///
+ ///
+ /// The altitude, in meters.
+ ///
+ public double Altitude { get; set; } = double.NaN;
+
+ ///
+ /// Determines if the GeoCoordinate object is equivalent to the parameter, based solely on latitude and longitude.
+ ///
+ ///
+ /// true if the GeoCoordinate objects are equal; otherwise, false.
+ ///
+ /// The GeoCoordinate object to compare to the calling object.
+ public bool Equals(GeoCoordinate other)
+ {
+ if (other == null)
+ return false;
+ var num = Latitude;
+ if (!num.Equals(other.Latitude))
+ return false;
+ num = Longitude;
+ return num.Equals(other.Longitude);
+ }
+
+ ///
+ /// Determines whether two GeoCoordinate objects refer to the same location.
+ ///
+ ///
+ /// true, if the GeoCoordinate objects are determined to be equivalent; otherwise, false.
+ ///
+ /// The first GeoCoordinate to compare.
+ /// The second GeoCoordinate to compare.
+ public static bool operator ==(GeoCoordinate left, GeoCoordinate right)
+ {
+ if (left == null)
+ return right == null;
+ return left.Equals(right);
+ }
+
+ ///
+ /// Determines whether two GeoCoordinate objects correspond to different locations.
+ ///
+ ///
+ /// true, if the GeoCoordinate objects are determined to be different; otherwise, false.
+ ///
+ /// The first GeoCoordinate to compare.
+ /// The second GeoCoordinate to compare.
+ public static bool operator !=(GeoCoordinate left, GeoCoordinate right)
+ {
+ return !(left == right);
+ }
+
+ ///
+ /// Returns the distance between the latitude and longitude coordinates that are specified by this GeoCoordinate and
+ /// another specified GeoCoordinate.
+ ///
+ ///
+ /// The distance between the two coordinates, in meters.
+ ///
+ /// The GeoCoordinate for the location to calculate the distance to.
+ public double GetDistanceTo(GeoCoordinate other)
+ {
+ if (double.IsNaN(Latitude) || double.IsNaN(Longitude) || double.IsNaN(other.Latitude) ||
+ double.IsNaN(other.Longitude))
+ {
+ throw new ArgumentException("Argument latitude or longitude is not a number");
+ }
+ var d1 = Latitude*(Math.PI/180.0);
+ var num1 = Longitude*(Math.PI/180.0);
+ var d2 = other.Latitude*(Math.PI/180.0);
+ var num2 = other.Longitude*(Math.PI/180.0) - num1;
+ var d3 = Math.Pow(Math.Sin((d2 - d1)/2.0), 2.0) +
+ Math.Cos(d1)*Math.Cos(d2)*Math.Pow(Math.Sin(num2/2.0), 2.0);
+ return 6376500.0*(2.0*Math.Atan2(Math.Sqrt(d3), Math.Sqrt(1.0 - d3)));
+ }
+
+ ///
+ /// Serves as a hash function for the GeoCoordinate.
+ ///
+ ///
+ /// A hash code for the current GeoCoordinate.
+ ///
+ public override int GetHashCode()
+ {
+ return Latitude.GetHashCode() ^ Longitude.GetHashCode();
+ }
+
+ ///
+ /// Determines if a specified GeoCoordinate is equal to the current GeoCoordinate, based solely on latitude and
+ /// longitude.
+ ///
+ ///
+ /// true, if the GeoCoordinate objects are equal; otherwise, false.
+ ///
+ /// The object to compare the GeoCoordinate to.
+ public override bool Equals(object obj)
+ {
+ if (!(obj is GeoCoordinate))
+ {
+ return base.Equals(obj);
+ }
+ return Equals(obj as GeoCoordinate);
+ }
+
+ ///
+ /// Returns a string that contains the latitude and longitude.
+ ///
+ ///
+ /// A string that contains the latitude and longitude, separated by a comma.
+ ///
+ public override string ToString()
+ {
+ if (this == Unknown)
+ {
+ return "Unknown";
+ }
+
+ return
+ $"{Latitude.ToString("G", CultureInfo.InvariantCulture)}, {Longitude.ToString("G", CultureInfo.InvariantCulture)}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/GeoCoordinatePortable/GeoCoordinatePortable.csproj b/src/GeoCoordinatePortable/GeoCoordinatePortable.csproj
new file mode 100644
index 0000000..28513ed
--- /dev/null
+++ b/src/GeoCoordinatePortable/GeoCoordinatePortable.csproj
@@ -0,0 +1,52 @@
+
+
+
+
+ 10.0
+ Debug
+ AnyCPU
+ {3F8D76E7-1AF6-40F5-960F-13C4DFA80935}
+ Library
+ Properties
+ GeoCoordinatePortable
+ GeoCoordinatePortable
+ en-US
+ 512
+ {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Profile111
+ v4.5
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ bin\Release\GeoCoordinatePortable.xml
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/GeoCoordinatePortable/Properties/AssemblyInfo.cs b/src/GeoCoordinatePortable/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..10ac09a
--- /dev/null
+++ b/src/GeoCoordinatePortable/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Resources;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("GeoCoordinate")]
+[assembly:
+ AssemblyDescription(
+ "GeoCoordinate is a Portable Class Library compatible implementation of System.Device.Location.GeoCoordinate. It is an exact 1:1 API compliant implementation and will be supported until MSFT sees it fit to embed the type. Which at that point this implementation will cease development/support and you will be able to simply remove this package and everything will still work."
+ )]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("https://ghuntley.com/; ghuntley@ghuntley.com")]
+[assembly: AssemblyProduct("GeoCoordinate")]
+[assembly: AssemblyCopyright("Copyright © Geoffrey Huntley 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: NeutralResourcesLanguage("en")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs
new file mode 100644
index 0000000..f5df90c
--- /dev/null
+++ b/src/SolutionInfo.cs
@@ -0,0 +1,26 @@
+//
+using System.Reflection;
+using System.Resources;
+using System.Runtime.InteropServices;
+
+
+[assembly: AssemblyTitle("GeoCoordinatePortable")]
+[assembly:
+ AssemblyDescription(
+ "GeoCoordinate is a Portable Class Library compatible implementation of System.Device.Location.GeoCoordinate. It is an exact 1:1 API compliant implementation and will be supported until MSFT sees it fit to embed the type. Which at that point this implementation will cease development/support and you will be able to simply remove this package and everything will still work."
+ )]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("https://ghuntley.com/")]
+[assembly: AssemblyProduct("GeoCoordinate")]
+[assembly: AssemblyCopyright("Copyright © Geoffrey Huntley 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: NeutralResourcesLanguage("en")]
+[assembly: AssemblyVersionAttribute("0.1.0")]
+[assembly: AssemblyFileVersionAttribute("0.11.0")]
+[assembly: ComVisibleAttribute(false)]
+namespace System {
+ internal static class AssemblyVersionInformation {
+ internal const string Version = "0.1.0";
+ }
+}
diff --git a/tools/nuget/NuGet.exe b/tools/nuget/NuGet.exe
new file mode 100644
index 0000000..9f8781d
Binary files /dev/null and b/tools/nuget/NuGet.exe differ