Skip to content

Instantly share code, notes, and snippets.

@jinweijie
Last active December 27, 2021 06:35
Show Gist options
  • Save jinweijie/b3dc4cd9695a475bdfd1a0a9a6d050d6 to your computer and use it in GitHub Desktop.
Save jinweijie/b3dc4cd9695a475bdfd1a0a9a6d050d6 to your computer and use it in GitHub Desktop.
Shrink Geo Coordinates Evenly
public class GeoHelper
{
public static List<GeoLocation> ShrinkCoordinates(
List<GeoLocation> coordinates,
int count,
bool removeDuplication = true,
bool isClosedLoop = false)
{
if (coordinates == null || coordinates.Count <= 1)
return coordinates;
const double tolerance = 0.000001;
var points = new List<GeoLocation>();
if (removeDuplication)
{
// if removeDuplication is true and if last point is same as first point, it will be removed,
// if we want to keep the loop, need append the first later
foreach (var coordinate in coordinates.Where(
coordinate =>
!points.Any(_ => Math.Abs(_.Longitude - coordinate.Longitude) < tolerance
&& Math.Abs(_.Latitude - coordinate.Latitude) < tolerance)))
points.Add(coordinate);
}
else
{
points = coordinates;
}
var first = points.First();
if (points.Count <= 2 || points.Count <= count)
{
// if the result is less than count, return the result
if (isClosedLoop) points.Add(first);
return points;
}
// remove the first point in order to keep the first and last
points.RemoveAt(0);
var result = new List<GeoLocation>();
var remainingCount = isClosedLoop ? count - 2 : count - 1;
for (var i = 1; i <= remainingCount; i++)
result.Add(points[(int)Math.Round(i * ((double)points.Count / remainingCount) - 1)]);
// append back the first
result.Insert(0, first);
// if it is a closed loop, append the last
if (isClosedLoop)
result.Add(first);
return result;
}
}
public class GeoLocation
{
public GeoLocation(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
public double Latitude { get; }
public double Longitude { get; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment