//calculates the angles of the pre and post turn line segments public static double calculateTheta(double xDelta, double yDelta) { double theta = 0.0; if (xDelta == 0.0 && yDelta > 0.0) { theta = 90.0; } else if (xDelta == 0.0 && yDelta < 0.0) { theta = 270.0; } else { theta = ConvertDegRad.getDegrees(Math.Atan(yDelta / xDelta)); if (xDelta < 0.0 && yDelta > 0.0) { theta = 180.0 + theta; } else if (xDelta < 0.0 && yDelta < 0.0) { theta = 180.0 + theta; } else if (xDelta > 0.0 && yDelta < 0.0) { theta = 360.0 + theta; } } return(theta); }
/// <summary> /// iterate through the stored locations and convert the lat lon position /// utm coordinates, mark their distances, and thin them out by distance /// </summary> public void processLocations(double distance) { _totalDistance = 0.0; if (_locations != null && _locations.Count > 0) { _utmConvert = new ConvertLatLonUtm(); double radLat = ConvertDegRad.getRadians(_locations[0].Lat); double radLon = ConvertDegRad.getRadians(_locations[0].Lon); _utmConvert.convertLatLonToUtm(radLat, radLon); _locations[0].Easting = _utmConvert.Easting; _locations[0].Northing = _utmConvert.Northing; _locations[0].Zone = _utmConvert.Zone; _locations[0].Distance = 0.0; _locations[0].setKey(); for (int i = 1; i < _locations.Count; i++) { radLat = ConvertDegRad.getRadians(_locations[i].Lat); radLon = ConvertDegRad.getRadians(_locations[i].Lon); _utmConvert.convertLatLonToUtm(radLat, radLon); _locations[i].Easting = _utmConvert.Easting; _locations[i].Northing = _utmConvert.Northing; x1 = _locations[i - 1].Easting; y1 = _locations[i - 1].Northing; x2 = _locations[i].Easting; y2 = _locations[i].Northing; _locations[i].setKey(); _totalDistance += Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2)); _locations[i].Zone = _utmConvert.Zone; _locations[i].Distance = _totalDistance; } //set the index of each location for (int i = 0; i < _locations.Count; i++) { _locations[i].Index = i; } //if locations are within _locationSeperation meters of eachother, remove one of them int current = 0; _spacedOutPoints.Clear(); _spacedOutPoints.Add(_locations[current]); for (int i = 1; i < _locations.Count; i++) { if (Math.Abs(_locations[current].Distance - _locations[i].Distance) > distance) { _spacedOutPoints.Add(_locations[i]); current = i; } } //clear out the list of locations to geocode _geocodeLocations.Clear(); //call douglass reduction List <Location> temp = DouglasReduction(_locations, 4.0); List <int> locationsToKeep = new List <int>(); locationsToKeep.Add(0); int j = 0; for (int i = 1; i < temp.Count - 1; i++) { j = findSecondPrevious(temp[i]); if (j >= temp[i - 1].Index) { locationsToKeep.Add(j); } locationsToKeep.Add(findFirstPrevious(temp[i])); if (j < temp[i - 1].Index) { locationsToKeep.Add(temp[i].Index); } locationsToKeep.Add(findFirstNext(temp[i])); j = findSecondNext(temp[i]); if (j < temp[i + 1].Index) { locationsToKeep.Add(j); } j = findFirstNext(temp[i]); while (i < temp.Count && temp[i].Index < j) { i++; } } locationsToKeep.Add(temp[temp.Count - 1].Index); int k = 0; while (k < locationsToKeep.Count - 1) { if (locationsToKeep[k] >= locationsToKeep[k + 1]) { locationsToKeep.RemoveAt(k + 1); } else { k++; } } for (int i = 0; i < locationsToKeep.Count; i++) { _geocodeLocations.Add(_locations[locationsToKeep[i]]); } } }