/* * Try to split the range to multiple ranges based on the hash key. * * e.g., for the following range: * * min: 123456789 * max: 125678912 * * when the hash key length is 3, we want to split the range to: * * 1 * min: 123456789 * max: 123999999 * * 2 * min: 124000000 * max: 124999999 * * 3 * min: 125000000 * max: 125678912 * * For this range: * * min: -125678912 * max: -123456789 * * we want: * * 1 * min: -125678912 * max: -125000000 * * 2 * min: -124999999 * max: -124000000 * * 3 * min: -123999999 * max: -123456789 */ public IReadOnlyList <GeohashRange> TrySplit(int hashKeyLength) { var result = new List <GeohashRange>(); var minHashKey = S2Manager.GenerateHashKey(RangeMin, hashKeyLength); var maxHashKey = S2Manager.GenerateHashKey(RangeMax, hashKeyLength); var denominator = (ulong)Math.Pow(10, RangeMin.ToString(CultureInfo.InvariantCulture).Length - minHashKey.ToString(CultureInfo.InvariantCulture).Length); if (minHashKey == maxHashKey) { result.Add(this); } else { for (var l = minHashKey; l <= maxHashKey; l++) { if (l > 0) { result.Add(new GeohashRange(l == minHashKey ? RangeMin : l * denominator, l == maxHashKey ? RangeMax : (l + 1) * denominator - 1)); } else { result.Add(new GeohashRange(l == minHashKey ? RangeMin : (l - 1) * denominator + 1, l == maxHashKey ? RangeMax : l * denominator)); } } } return(result); }
private void buttonText_Click(object sender, EventArgs e) { CustomDialog.KeyboardDialog kdlg = new CustomDialog.KeyboardDialog(); kdlg.ValLower = RangeMin; kdlg.ValUpper = RangeMax; kdlg.DispMode = KeyboardDialog.KB_MODE.NUMBER; //数値 string strrange = RangeMax.ToString(StringForm); int digits = strrange.IndexOf('.'); kdlg.LengthInt = (digits < 0) ? strrange.Length : digits; kdlg.LengthDec = (digits < 0) ? 0 : (strrange.Length - digits - 1); kdlg.AllLength = Math.Max(strrange.Length, RangeMin.ToString(StringForm).Length); string msgfmt = CommonProc.MessageText("G001"); msgfmt = msgfmt.Replace("%param", paramName); msgfmt = msgfmt.Replace("%min", RangeMin.ToString(StringForm)); msgfmt = msgfmt.Replace("%max", RangeMax.ToString(StringForm)); kdlg.Message_Text = msgfmt; kdlg.InputArea = _buttonText.Text; kdlg.AllowNone = allowNone; if (kdlg.ShowDialog() == DialogResult.OK) { if (allowNone && kdlg.InputArea == "") { Value = double.NaN; } else { Value = double.Parse(kdlg.InputArea); } if (ValueChanged != null) { ValueChanged(sender, e); } } kdlg.Dispose(); Invalidate(); }
void Canvas_PaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; var halfWidth = info.Width / 2; var halfHeight = info.Height / 2; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; CanvasScale = info.Height / this.Height; StepDollarValue = 100; var maxLength = (info.Height - 50) - 50; StepSize = (StepDollarValue * maxLength) / 5000; if (!TouchY.HasValue) { // set the knob locations on first draw pass // get y for top of line if (SelectedRange is null) { SelectedRange = new Tuple <int?, int?>(0, 5000); } var maxValue = SelectedRange.Item2 ?? 5000; var minValue = SelectedRange.Item1 ?? 0; var topSteps = (5000 - maxValue) / StepDollarValue; var bottomSteps = minValue / StepDollarValue; TopKnobCenter = new Tuple <float, float>(halfWidth, 50 + (topSteps * StepSize)); BottomKnobCenter = new Tuple <float, float>(halfWidth, (info.Height - 50) - (bottomSteps * StepSize)); RangeMax = maxValue; RangeMin = minValue; } else { // set the knob locations on movement if (isDrawing) { return; } isDrawing = true; var newY = (float)(TouchY.Value * CanvasScale); if ((float)Math.Round(newY) <= 50.0f && MovingTopKnob) { newY = 50.0f; } else if ((float)Math.Round(newY) >= info.Height - 50.0f && MovingBottomKnob) { newY = info.Height - 50.0f; } if (MovingTopKnob || (Math.Abs(newY - TopKnobCenter.Item2) <= 50 && !MovingBottomKnob)) { MovingTopKnob = true; MovingBottomKnob = false; var numOfSteps = (float)Math.Round(Math.Abs(newY - 50) / StepSize); var topDollarValue = 5000 - (numOfSteps * StepDollarValue); if (topDollarValue - RangeMin >= StepDollarValue * 3) { TopKnobCenter = new Tuple <float, float>(halfWidth, 50 + (numOfSteps * StepSize)); RangeMax = (int)Math.Max(RangeMin.Value, topDollarValue); Console.WriteLine($"Max value: {RangeMax}"); } //get distance from topknobCenter to top of the view } else if (MovingBottomKnob || (Math.Abs(newY - BottomKnobCenter.Item2) <= 50 && !MovingTopKnob)) { MovingTopKnob = false; MovingBottomKnob = true; var numOfSteps = (float)Math.Round(Math.Abs(newY - (info.Height - 50)) / StepSize); var bottomDollarValue = (numOfSteps * StepDollarValue); if (RangeMax - bottomDollarValue >= StepDollarValue * 3) { BottomKnobCenter = new Tuple <float, float>(halfWidth, info.Height - (numOfSteps * StepSize) - 50); //get distance from topknobCenter to top of the view RangeMin = (int)Math.Min(RangeMax.Value, bottomDollarValue); Console.WriteLine($"Min value: {RangeMin}"); } } SelectedRange = new Tuple <int?, int?>(RangeMin, RangeMax); } RangeMinString = RangeMin?.ToString("C0"); RangeMaxString = RangeMax?.ToString("C0") + (Math.Abs(RangeMax.Value - 5000) < float.Epsilon ? "+" : ""); canvas.Clear(); // draw line in between --order of drawing is important canvas.DrawLine(halfWidth, 50, halfWidth, info.Height - 50, linePaint); // draw top circle canvas.DrawCircle(TopKnobCenter.Item1, TopKnobCenter.Item2, knobRadius, endKnobPaint); // draw bottom circle canvas.DrawCircle(BottomKnobCenter.Item1, BottomKnobCenter.Item2, knobRadius, endKnobPaint); InternalValueChange = true; InternalValueChange = false; isDrawing = false; }