public PointLatLng[] GetRandomPoints(RandomPointLayer config, Area area, DateTime dateAndTime) { //Determine fields of the 4 corners int north = (int)(area.TopLeftCorner.Latitude / config.FieldSizeWsg84); int east = (int)(area.BottomRightCorner.Longitude / config.FieldSizeWsg84); int south = (int)(area.BottomRightCorner.Latitude / config.FieldSizeWsg84); int west = (int)(area.TopLeftCorner.Longitude / config.FieldSizeWsg84); DateTime dateTimeOfPlacing = RoundUp(dateAndTime, new TimeSpan(0, config.TimeIncrementsInMinutes, 0)); //Get Points of all determined fields List <PointLatLng> pointsOfFields = new List <PointLatLng>(); for (int x = west; x <= east; x++) { for (int y = south; y < north; y++) { Random rand = GetRandomGenerator($"{config.Seed} {dateTimeOfPlacing.ToLongDateString()} {dateTimeOfPlacing.ToLongTimeString()} {x} {y}"); double someDouble = rand.NextDouble(); if (someDouble <= config.ChanceOfSpawn) { double latitude = y * config.FieldSizeWsg84 + rand.NextDouble() * config.FieldSizeWsg84; double longitude = x * config.FieldSizeWsg84 + rand.NextDouble() * config.FieldSizeWsg84; pointsOfFields.Add(new PointLatLng(latitude, longitude)); } } } //only return those points, that are within the area return(pointsOfFields.Where(x => WSG84Math.IsPointWithinArea(area, x)).ToArray()); }
private string BuildNodeQuery(Tuple <string, string, int>[] nodesToLoad, double latitude, double longitude) { string result = ""; Dictionary <int, string> calculatedFences = new Dictionary <int, string>(); PointLatLng centerPoint = new PointLatLng(latitude, longitude); foreach (Tuple <string, string, int> tagToLoad in nodesToLoad.Where(x => !string.IsNullOrWhiteSpace(x.Item1))) { string fence; if (!calculatedFences.TryGetValue(tagToLoad.Item3, out fence)) { PointLatLng botLeft = WSG84Math.GetDestinationPoint(centerPoint, 225, tagToLoad.Item3); PointLatLng topRight = WSG84Math.GetDestinationPoint(centerPoint, 45, tagToLoad.Item3); fence = $"{ParsingHelper.DoubleToString(botLeft.Latitude)},{ParsingHelper.DoubleToString(botLeft.Longitude)},{ParsingHelper.DoubleToString(topRight.Latitude)},{ParsingHelper.DoubleToString(topRight.Longitude)}"; calculatedFences.Add(tagToLoad.Item3, fence); } if (string.IsNullOrEmpty(tagToLoad.Item2) || tagToLoad.Item2 == "*") { result += $"node[{tagToLoad.Item1}]({fence});"; } else { result += $"node[{tagToLoad.Item1}={tagToLoad.Item2}]({fence});"; } } return(result); }
public void GetDestinationPointTests() { PointLatLng point = new PointLatLng(0, 0); PointLatLng movedPoint = WSG84Math.GetDestinationPoint(point, 45, 157000); var latitudeError = Math.Abs(movedPoint.Latitude - 1); var longitudeError = Math.Abs(movedPoint.Longitude - 1); Assert.IsTrue(latitudeError < 0.002); Assert.IsTrue(longitudeError < 0.002); }
public void DistanceInKmTests() { Tuple <double, double, double, double, int>[] testEntries = new Tuple <double, double, double, double, int>[] { new Tuple <double, double, double, double, int>(0, 0, 1, 1, 157) }; foreach (var entry in testEntries) { double distanceInKilometers = WSG84Math.GetDistanceInKilometers(entry.Item1, entry.Item2, entry.Item3, entry.Item4); Assert.AreEqual((int)distanceInKilometers, entry.Item5); } }
/// <inheritdoc cref="IOverpassApi"/> public OsmNode[] GetOsmNodes(OSMPointsLayer osmLayer, PointLatLng point, int maxDistance) { PointLatLng start = WSG84Math.GetDestinationPoint(point, 315, maxDistance); PointLatLng end = WSG84Math.GetDestinationPoint(point, 135, maxDistance); Area area = new Area(); area.XStart = start.Longitude; area.YStart = start.Latitude; area.XEnd = end.Longitude; area.YEnd = end.Latitude; return(GetOsmNodes(osmLayer, area)); }
public string BuildQueryForNodes(OSMPointsLayer osmLayer, double latitudeStart, double latitudeEnd, double longitudeStart, double longitudeEnd) { if (osmLayer == null) { return(""); } double latitude = latitudeStart + (latitudeEnd - latitudeStart) / 2; double longitude = longitudeStart + (longitudeEnd - longitudeStart) / 2; double maxDistanceInMeters = WSG84Math.GetDistanceInMeters(latitudeStart, longitudeStart, latitudeEnd, longitudeEnd); var nodesToLoad = GetNodesToLoad(osmLayer, maxDistanceInMeters); return(BuildQueryForNodes(nodesToLoad.ToArray(), latitude, longitude)); }
private IEnumerable <OsmNode> CleanFromToFarAwayEntries(OsmNode[] nodes, PointLatLng centerPoint, double maxDistanceCities, double maxDistanceTags) { if (nodes == null || nodes.Length == 0) { yield break; } foreach (var node in nodes) { double distance = WSG84Math.GetDistanceInMeters(centerPoint, node.Latitude, node.Longitude); if (distance <= maxDistanceTags || distance <= maxDistanceCities && IsTown(node)) { yield return(node); } } }
public float[][] GetNoiseValues(NoiseConfiguration config, double zoom, Area area, double maxDistanceInMeters, int imageWidth, int imageHeight) { if (imageWidth == 0 || imageHeight == 0) { return(null); } //float factor = Math.Max(imageWidth / 256f, imageHeight / 256f); float factor = 1; int calcWidth = (int)(imageWidth / factor); int calcHeight = (int)(imageHeight / factor); float[][] result = new float[calcWidth][]; for (int i = 0; i < result.Length; i++) { result[i] = new float[calcHeight]; } FastNoise noiseGenerator = new FastNoise(GetSeed(config)); double xMovementPerPixel = (area.XEnd - area.XStart) / calcWidth; double yMovementPerPixel = (area.YEnd - area.YStart) / calcHeight; //Optimisation possibility: we don't have to calculate haversine for each pixel. //Calculate the rectangle that needs to be calculated and set all the other cells to //Color.FromArgb(0, 0, 0, 0) //i.e. start in the middle and move to the right and left. Stop calculating when the calculationborder is reached bool allPointsIncluded = maxDistanceInMeters == 0 || WSG84Math.GetDistanceInMeters(area.Center, area.TopLeftCorner) < maxDistanceInMeters; for (int x = 0; x < calcWidth; x++) { for (int y = 0; y < calcHeight; y++) { double pixelX = area.XStart + xMovementPerPixel * x; double pixelY = area.YStart + yMovementPerPixel * y; result[x][y] = 0; if (allPointsIncluded || WSG84Math.GetDistanceInMeters(pixelY, pixelX, area.YCenter, area.XCenter) < maxDistanceInMeters) { result[x][y] = GetValue(noiseGenerator, (NoiseType)config.Type, pixelX * zoom, pixelY * zoom); } } } return(result); }
public void TestGetAreaFor() { var distance = 10000.0; Area result = WSG84Math.GetAreaFor(51, 7, distance); var distanceTopLeftToCenter = WSG84Math.GetDistanceInMeters(result.Center, result.TopLeftCorner); var distanceBottomRightToCenter = WSG84Math.GetDistanceInMeters(result.Center, result.BottomRightCorner); var distanceTopLeftToBorromRight = WSG84Math.GetDistanceInMeters(result.TopLeftCorner, result.BottomRightCorner); //if you don't know why, draw the smallest possible rectangle which contains a circle with the radius r=1 //and try to figure out the distance between the center without a ruler. Math only! //hint: a² + b² = c² var expectedDistance = distance * Math.Sqrt(2); //calculating with WSG84 is messy since we aren't living on an euclidean-2D-plane var epsilon = 10; Assert.IsTrue(distanceBottomRightToCenter - expectedDistance < epsilon); Assert.IsTrue(distanceTopLeftToCenter - expectedDistance < epsilon); Assert.IsTrue(distanceTopLeftToBorromRight - 2 * expectedDistance < epsilon); }
public void PointIncludedInAreaTest() { Area area = WSG84Math.GetAreaFor(0, 0, 100000); PointLatLng center = new PointLatLng(0, 0); Assert.IsTrue(WSG84Math.IsPointWithinArea(area, center)); PointLatLng toLeft = new PointLatLng(0, -1); Assert.IsFalse(WSG84Math.IsPointWithinArea(area, toLeft)); PointLatLng toRight = new PointLatLng(0, 1); Assert.IsFalse(WSG84Math.IsPointWithinArea(area, toRight)); PointLatLng above = new PointLatLng(1, 0); Assert.IsFalse(WSG84Math.IsPointWithinArea(area, above)); PointLatLng below = new PointLatLng(-1, -1); Assert.IsFalse(WSG84Math.IsPointWithinArea(area, below)); }