private static RouteFeature[] ReadFeatures(string path) { var sf = Shapefile.OpenFile(path); sf.Reproject(KnownCoordinateSystems.Geographic.World.WGS1984); var features = new List <RouteFeature>(); var columns = GetColumns(sf); foreach (var feature in sf.Features) { var f = new RouteFeature(); f.Data.Coordinates = feature.Coordinates.Select(t => new PointPosition { Latitude = t.Y, Longitude = t.X }).ToArray(); f.Data.Properties = GetAttributes(feature, columns); features.Add(f); } return(features.ToArray()); }
private bool AreNeighbours(RouteFeature routeFeature, RouteFeature testRouteFeature) { if (routeFeature == testRouteFeature) { return(false); } var startPoint1 = routeFeature.Feature.Coordinates.First(); var endPoint1 = routeFeature.Feature.Coordinates.Last(); var startPoint2 = testRouteFeature.Feature.Coordinates.First(); var endPoint2 = testRouteFeature.Feature.Coordinates.Last(); if (Helpers.AreClose(startPoint1, startPoint2)) { return(true); } if (Helpers.AreClose(startPoint1, endPoint2)) { return(true); } if (Helpers.AreClose(endPoint1, startPoint2)) { return(true); } if (Helpers.AreClose(endPoint1, endPoint2)) { return(true); } return(false); }
private double ApplySearchOptionsToGetLength(RouteFeature feature, List <RouteFeature> featuresToOverlap) { var featureLength = feature.Feature.Properties["length"]; if (_searchOptions == null) { return(featureLength); } var option = _searchOptions.PropertyImportance.FirstOrDefault(x => feature.Feature.Properties.Any(y => y.Key == x.Property && y.Value == x.Value)); if (option != null) { featureLength *= option.Importance; } if (featuresToOverlap != null && featuresToOverlap.Contains(feature)) { featureLength *= _searchOptions.TrackOverlapImportance; } foreach (var propertyValueImportance in _searchOptions.PropertyValueImportance) { if (feature.Feature.Properties[propertyValueImportance.Property] <= propertyValueImportance.Threshold) { featureLength *= propertyValueImportance.Importance; } } return(featureLength); }
public static double CalcualteDistanceToFeature(RouteFeature feature, Coordinate coordinate) { var lineSegments = SplitFeatureIntoLineSegments(feature); var distance = GetDistance(lineSegments.First(), coordinate); foreach (var c in lineSegments.Skip(1)) { var newDistance = GetDistance(c, coordinate); if (newDistance < distance) { distance = newDistance; } } return(distance); }
public static Tuple <CustomPosition, CustomPosition>[] SplitFeatureIntoLineSegments(RouteFeature feature) { var coords = feature.Feature.Coordinates; var lineSegments = new List <Tuple <CustomPosition, CustomPosition> >(); var lastPosition = coords.First(); foreach (var c in coords.Skip(1)) { lineSegments.Add(new Tuple <CustomPosition, CustomPosition>(lastPosition, c)); lastPosition = c; } return(lineSegments.ToArray()); }
public List <RouteFeature> FindShortestPath(RouteFeature startFeature, RouteFeature endFeature, List <RouteFeature> featuresToOverlap) { var previous = new Dictionary <RouteFeature, RouteFeature>(); var distances = new Dictionary <RouteFeature, double>(); var nodes = new List <RouteFeature>(); List <RouteFeature> path = null; foreach (var vertex in _routeFeatures) { if (vertex == startFeature) { distances[vertex] = ApplySearchOptionsToGetLength(startFeature, featuresToOverlap); } else { distances[vertex] = double.MaxValue; } nodes.Add(vertex); } while (nodes.Count != 0) { //Debug.WriteLine(nodes.Count()); nodes.Sort((x, y) => Math.Sign(distances[x] - distances[y])); var smallest = nodes.First(); nodes.Remove(smallest); if (smallest == endFeature) { path = new List <RouteFeature>(); while (previous.ContainsKey(smallest)) { path.Add(smallest); smallest = previous[smallest]; } break; } if (distances[smallest] == double.MaxValue) { break; } foreach (var neighbor in smallest.Neighbours) { var alt = distances[smallest] + ApplySearchOptionsToGetLength(neighbor, featuresToOverlap); if (alt < distances[neighbor]) { distances[neighbor] = alt; previous[neighbor] = smallest; } } } if (path == null) //no path { return(null); } path.Add(startFeature); return(path); }