private static double[] GenerateTickPositions(CoordinateRange range, PixelLength size, float predictedTickSize) { double unitsPerPx = range.Span / size.Length; float tickDensity = 1.0f; int targetTickCount = (int)(size.Length / predictedTickSize * tickDensity); double tickSpacing = GetIdealTickSpacing(range, targetTickCount); double firstTickOffset = range.Min % tickSpacing; int tickCount = (int)(range.Span / tickSpacing) + 2; tickCount = Math.Min(1000, tickCount); tickCount = Math.Max(1, tickCount); double[] majorTickPositions = Enumerable.Range(0, tickCount) .Select(x => range.Min - firstTickOffset + tickSpacing * x) .Where(x => range.Contains(x)) .ToArray(); if (majorTickPositions.Length < 2) { double tickBelow = range.Min - firstTickOffset; double firstTick = majorTickPositions.Length > 0 ? majorTickPositions[0] : tickBelow; double nextTick = tickBelow + tickSpacing; majorTickPositions = new double[] { firstTick, nextTick }; } return(majorTickPositions); }
public AxisLimits GetLimits() { CoordinateRange xRange = new(0, Ys.Count *Period); CoordinateRange yRange = GetYRange(xRange); return(new AxisLimits(xRange, yRange)); }
private static double GetIdealTickSpacing(CoordinateRange range, int maxTickCount) { int radix = 10; int exponent = (int)Math.Log(range.Span, radix); double initialSpace = Math.Pow(radix, exponent); List <double> tickSpacings = new() { initialSpace, initialSpace, initialSpace }; double[] divBy; if (radix == 10) { divBy = new double[] { 2, 2, 2.5 } } ; // 10, 5, 2.5, 1 else if (radix == 16) { divBy = new double[] { 2, 2, 2, 2 } } ; // 16, 8, 4, 2, 1 else { throw new ArgumentException($"radix {radix} is not supported"); } int divisions = 0; int tickCount = 0; while (tickCount < maxTickCount && tickSpacings.Count < 1000) { tickSpacings.Add(tickSpacings.Last() / divBy[divisions++ % divBy.Length]); tickCount = (int)(range.Span / tickSpacings.Last()); } return(tickSpacings[tickSpacings.Count - 3]); }
private Tick[] GenerateTicks(CoordinateRange range, PixelLength size, PixelSize predictedTickSize, int depth = 0) { if (depth > 3) { System.Diagnostics.Debug.WriteLine($"Warning: Tick recusion depth = {depth}"); } // generate ticks and labels based on predicted maximum label size float maxPredictedSize = IsVertical ? predictedTickSize.Height : predictedTickSize.Width; double[] majorTickPositions = GenerateTickPositions(range, size, maxPredictedSize); string[] majorTickLabels = majorTickPositions.Select(position => GetPrettyTickLabel(position)).ToArray(); // determine if the actual tick labels are larger than predicted (suggesting density is too high and overlapping may occur) using SkiaSharp.SKPaint paint = new(); PixelSize measuredLabel = Drawing.MeasureLargestString(majorTickLabels, paint); PixelSize largestLabel = new( width : Math.Max(predictedTickSize.Width, measuredLabel.Width), height : Math.Max(predictedTickSize.Height, measuredLabel.Height)); bool tickExceedsPredictedSize = largestLabel.Area > predictedTickSize.Area; // recursively recalculate tick density if necessary return(tickExceedsPredictedSize ? GenerateTicks(range, size, largestLabel, depth + 1) : GenerateFinalTicks(majorTickPositions, majorTickLabels, range)); }
public void GetAllCoordinatesTest() { // Arrange CoordinateRange coordinateRange = new CoordinateRange( new Coordinate(0, 0), new Coordinate(0, 3)); List <Coordinate> expected = new List <Coordinate>() { new Coordinate(0, 0), new Coordinate(0, 1), new Coordinate(0, 2), new Coordinate(0, 3), }; // Act List <Coordinate> actual = coordinateRange.GetAllCoordinates(); // Assert // Check Lists are same length Assert.AreEqual(expected.Count, actual.Count); // Check each item in lists for (var i = 0; i < expected.Count; i++) { // Get properties of each item PropertyInfo[] expectedProps = expected.GetType().GetProperties(); PropertyInfo[] actualProps = actual.GetType().GetProperties(); Assert.AreEqual(expectedProps.Length, actualProps.Length); // Compare properties of each item for (int j = 0; j < expectedProps.Length; j++) { Assert.AreEqual(expectedProps[j], actualProps[j]); } } }
/// <summary> /// Returns all image data for a given street address /// Accepts a range of miles to search, with the street address as the center point. /// </summary> /// <param name="address">street address</param> /// <param name="range">range in miles</param> /// <returns>IEnumerable list of ImageData.</returns> public IEnumerable <ImageData> GetImagesByAddress(string address, double range) { CoordinateRange coords = GeocodingUtils.BingGeocodeAddress(address, range); IEnumerable <ImageData> data = from image in Database.Imagedata where (image.Latitude > coords.LatitudeMin && image.Longitude > coords.LongitudeMin) && (image.Latitude < coords.LatitudeMax && image.Longitude < coords.LongitudeMax) select image; return(data); }
private static Tick[] GenerateFinalTicks(double[] positions, string[] labels, CoordinateRange range, int minorTicksPerMajorTick = 5) { Tick[] majorTicks = positions .Select((position, i) => Tick.Major(position, labels[i])) .ToArray(); Tick[] minorTicks = MinorFromMajor(positions, minorTicksPerMajorTick, range) .Select(position => Tick.Minor(position)) .ToArray(); return(majorTicks.Concat(minorTicks).ToArray()); }
/// <summary> /// Return a range of long/lat points based on a given distance. /// </summary> /// <param name="CenterLocation">The center location.</param> /// <param name="Range">The range of miles from center location.</param> /// <returns>Returns a set of coordinates that create a bounding box around the center location based on Range</returns> private static CoordinateRange GetLongLatRangeFromCenter(Point centerPoint, double range) { double pointRange = range / 68; //68 miles is the equivalent of one latitude and longitude point CoordinateRange coordRange = new CoordinateRange(); coordRange.LatitudeMin = centerPoint.Coordinates[0] - pointRange; coordRange.LatitudeMax = centerPoint.Coordinates[0] + pointRange; coordRange.LongitudeMin = centerPoint.Coordinates[1] - pointRange; coordRange.LongitudeMax = centerPoint.Coordinates[1] + pointRange; return(coordRange); }
public CoordinateRange GetYRange(CoordinateRange xRange) { int i1 = GetIndex(xRange.Min, true); int i2 = GetIndex(xRange.Max, true); CoordinateRange yRange = new(Ys[i1], Ys[i1]); for (int i = i1; i <= i2; i++) { yRange.Expand(Ys[i]); } return(yRange); }
/// <summary> /// Calculates the minimum and maximum latitude and longitude points surrounding the given address. /// </summary> /// <param name="Address">The address to resolve into latitude/longitude</param> /// <param name="range">The range, in miles, that reflects the </param> /// <returns>CoordinateRange with address residing in the center of the points.</returns> public static CoordinateRange BingGeocodeAddress(string Address, double range) { CoordinateRange coordRange = null; BingGeocoding geoCoder = new BingGeocoding("AphMNwBsMsPWN6Ss2xvurl_19C7iztqYWFZGkKUET0gc2kO6c81bXCSQoY9pPDv9"); Location thisLocation = geoCoder.GeocodeFromString(Address); if (thisLocation != null) { coordRange = GeocodingUtils.GetLongLatRangeFromCenter(thisLocation.Point, range); } return(coordRange); }
public void Regenerate(CoordinateRange range, PixelLength size) { List <Tick> ticks = new(); double lowest = range.Min - range.Min % InterTickSpacing; double highest = range.Max - range.Max % InterTickSpacing + InterTickSpacing; int tickCount = (int)((highest - lowest) / InterTickSpacing); tickCount = Math.Min(tickCount, MaxTickCount); for (int i = 0; i < tickCount; i++) { double position = lowest + i * InterTickSpacing; string label = position.ToString(); ticks.Add(new Tick(position, label, true)); } Ticks = ticks.ToArray(); }
public AxisLimits(CoordinateRange xRange, CoordinateRange yRange) { Rect = new(xRange.Min, xRange.Max, yRange.Min, yRange.Max); }
public IEnumerable <Tick> GetVisibleTicks(CoordinateRange range) { return(Ticks.Where(x => range.Contains(x.Position))); }
private void GenerateValidTiles(int size) { CoordinateRange coordinateRange = new CoordinateRange(new Coordinate(0, 0), new Coordinate(size - 1, size - 1)); ValidTiles = coordinateRange.GetAllCoordinates(); }
public void Regenerate(CoordinateRange range, PixelLength size) { PixelSize largestLabel = new(12, 12); Ticks = GenerateTicks(range, size, largestLabel); }
private static double[] MinorFromMajor(double[] majorTicks, double minorTicksPerMajorTick, CoordinateRange range) { if (majorTicks == null || majorTicks.Length < 2) { return new double[] { } } ; double majorTickSpacing = majorTicks[1] - majorTicks[0]; double minorTickSpacing = majorTickSpacing / minorTicksPerMajorTick; List <double> majorTicksWithPadding = new() { majorTicks[0] - majorTickSpacing }; majorTicksWithPadding.AddRange(majorTicks); List <double> minorTicks = new(); foreach (var majorTickPosition in majorTicksWithPadding) { for (int i = 1; i < minorTicksPerMajorTick; i++) { double minorTickPosition = majorTickPosition + minorTickSpacing * i; if (range.Contains(minorTickPosition)) { minorTicks.Add(minorTickPosition); } } } return(minorTicks.ToArray()); }