private void refreshScalebar() { if (Map == null || double.IsNaN(getMapResolution())) { return; } ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit outUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Undefined; double outResolution; #region KiloMeters/Meters double roundedKiloMeters = getBestEstimateOfValue(getMapResolution(), ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Kilometers, out outUnit, out outResolution); double widthMeters = roundedKiloMeters / outResolution; bool inMeters = outUnit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Meters; if (PaddingLeftForScaleBarTextMeters != null && PaddingLeftForScaleBarTextMeters != null && ScaleBarTextForMeters != null) { PaddingLeftForScaleBarTextMeters.Width = widthMeters; PaddingLeftTopNotch.Width = widthMeters; ScaleBarTextForMeters.Text = string.Format("{0}{1}", roundedKiloMeters, (inMeters ? LocalizableStrings.ScaleBarUnit_meters : LocalizableStrings.ScaleBarUnit_kilometers)); ScaleBarTextForMeters.Width = widthMeters; } #endregion #region Miles double roundedMiles = getBestEstimateOfValue(getMapResolution(), ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Miles, out outUnit, out outResolution); double widthMiles = roundedMiles / outResolution; bool inFeet = outUnit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Feet; if (PaddingLeftForScaleBarTextMiles != null && PaddingLeftBottomNotch != null && ScaleBarTextForMiles != null) { PaddingLeftForScaleBarTextMiles.Width = widthMiles; PaddingLeftBottomNotch.Width = widthMiles; ScaleBarTextForMiles.Text = string.Format("{0}{1}", roundedMiles, inFeet ? LocalizableStrings.ScaleBarUnit_feet : LocalizableStrings.ScaleBarUnit_miles); ScaleBarTextForMiles.Width = widthMiles; } #endregion if (roundedMiles == double.NaN || roundedKiloMeters == double.NaN && this.Visibility == Visibility.Visible) { this.Visibility = Visibility.Collapsed; } if (ScaleBarBlock != null) { double widthOfNotches = 4; // 2 for left notch, 2 for right notch double scaleBarBlockWidth = (widthMiles > widthMeters) ? widthMiles : widthMeters; scaleBarBlockWidth += widthOfNotches; if (!double.IsNaN(scaleBarBlockWidth)) { ScaleBarBlock.Width = scaleBarBlockWidth; } } }
private double getBestEstimateOfValue(double resolution, ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit displayUnit, out ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit unit, out double outResolution) { unit = displayUnit; double rounded = 0; double originalRes = resolution; while (rounded < 0.5) { resolution = originalRes; if (MapUnit == MapUnit.DecimalDegrees) { resolution = getResolutionForGeographic(Map.Extent.GetCenter(), resolution); resolution = resolution * (int)ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Meters / (int)unit; } else if (webMercSref.Equals(Map.SpatialReference)) { //WebMercator MapPoint center = Map.Extent.GetCenter(); center.X = Math.Min(Math.Max(center.Y, -20037508.3427892), 20037508.3427892); MapPoint center2 = merc.ToGeographic(new MapPoint(Math.Min(center.X + getMapResolution(), 20037508.3427892), center.Y)) as MapPoint; center = merc.ToGeographic(center) as MapPoint; resolution = getResolutionForGeographic(center, center2.X - center.X); resolution = resolution * (int)ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Meters / (int)unit; } else if (MapUnit != MapUnit.Undefined) { resolution = resolution * (int)MapUnit / (int)unit; } double val = TargetWidth * resolution; val = roundToSignificant(val, resolution); double noFrac = Math.Round(val); // to get rid of the fraction if (val < 0.5) { ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit newUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Undefined; // Automatically switch unit to a lower one if (unit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Kilometers) { newUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Meters; } else if (unit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Miles) { newUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Feet; } if (newUnit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Undefined) { break; } //no lower unit unit = newUnit; } else if (noFrac > 1) { rounded = noFrac; var len = noFrac.ToString().Length; if (len <= 2) { // single/double digits ... make it a multiple of 5 ..or 1,2,3,4 if (noFrac > 5) { rounded -= noFrac % 5; } while (rounded > 1 && (rounded / resolution) > TargetWidth) { // exceeded maxWidth .. decrement by 1 or by 5 double decr = noFrac > 5 ? 5 : 1; rounded = rounded - decr; } } else if (len > 2) { rounded = Math.Round(noFrac / Math.Pow(10, len - 1)) * Math.Pow(10, len - 1); if ((rounded / resolution) > TargetWidth) { // exceeded maxWidth .. use the lower bound instead rounded = Math.Floor(noFrac / Math.Pow(10, len - 1)) * Math.Pow(10, len - 1); } } } else { // anything between 0.5 and 1 rounded = Math.Floor(val); if (rounded == 0) { //val >= 0.5 but < 1 so round up rounded = (val == 0.5) ? 0.5 : 1; if ((rounded / resolution) > TargetWidth) { // exceeded maxWidth .. re-try by switching to lower unit rounded = 0; ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit newUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Undefined; // Automatically switch unit to a lower one if (unit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Kilometers) { newUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Meters; } else if (unit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Miles) { newUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Feet; } if (newUnit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Undefined) { break; } //no lower unit unit = newUnit; } } } } outResolution = resolution; return(rounded); }
private void refreshScalebar() { Visibility viz = Visibility.Visible; if (Map == null || double.IsNaN(Map.Resolution) || MapUnit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.DecimalDegrees && Math.Abs(Map.Extent.GetCenter().Y) >= 90) { viz = Visibility.Collapsed; } if (LayoutRoot != null) { LayoutRoot.Visibility = viz; } if (viz == Visibility.Collapsed) { return; } ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit outUnit = ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Undefined; double outResolution; #region KiloMeters/Meters double roundedKiloMeters = getBestEstimateOfValue(Map.Resolution, ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Kilometers, out outUnit, out outResolution); double widthMeters = roundedKiloMeters / outResolution; bool inMeters = outUnit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Meters; if (PaddingLeftForScaleBarTextMeters != null) { PaddingLeftForScaleBarTextMeters.Width = widthMeters; } if (PaddingLeftTopNotch != null) { PaddingLeftTopNotch.Width = widthMeters; } if (ScaleBarTextForMeters != null) { ScaleBarTextForMeters.Text = string.Format("{0}{1}", roundedKiloMeters, (inMeters ? "m" : "km")); ScaleBarTextForMeters.Width = widthMeters; } #endregion #region Miles double roundedMiles = getBestEstimateOfValue(Map.Resolution, ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Miles, out outUnit, out outResolution); double widthMiles = roundedMiles / outResolution; bool inFeet = outUnit == ESRI.ArcGIS.Client.Toolkit.ScaleLine.ScaleLineUnit.Feet; if (PaddingLeftForScaleBarTextMiles != null) { PaddingLeftForScaleBarTextMiles.Width = widthMiles; } if (PaddingLeftBottomNotch != null) { PaddingLeftBottomNotch.Width = widthMiles; } if (ScaleBarTextForMiles != null) { ScaleBarTextForMiles.Text = string.Format("{0}{1}", roundedMiles, inFeet ? "ft" : "mi"); ScaleBarTextForMiles.Width = widthMiles; } #endregion double widthOfNotches = 4; // 2 for left notch, 2 for right notch double scaleBarBlockWidth = (widthMiles > widthMeters) ? widthMiles : widthMeters; scaleBarBlockWidth += widthOfNotches; if (!double.IsNaN(scaleBarBlockWidth) && ScaleBarBlock != null) { ScaleBarBlock.Width = scaleBarBlockWidth; } }