Hi all!I'm using OpenStreetMap in my app based on Minimal Template the problem is it's not viewing the scale line (and the zoom stack, but that's less important): http://samantha.mazury.pl/Map2/ as you can see a scale line added into MainPage.xaml work perfect, but the one in the right globe-wing just doesn't (as you probably know it should look like this: http://help.arcgis.com/en/webapi/silverlight/samples/TemplateGalleryWeb/Samples/Customized_Templates...)I think code used by scale line is inside Navigator.cs and in my opinion it's that part:#region ScaleBar Helper Functions
private void refreshScalebar()
{
Visibility viz = Visibility.Collapsed;
bool canDisplay = true;
if (ScaleBar != null)
{
viz = ScaleBar.Visibility;
if (Map == null || double.IsNaN(Map.Resolution) ||
MapUnit == ScaleBarUnit.DecimalDegrees && Math.Abs(Map.Extent.GetCenter().Y) >= 90)
{
viz = Visibility.Collapsed;
canDisplay = false;
}
if (ScaleBar != null) ScaleBar.Visibility = viz;
}
if (!canDisplay) return;
ScaleBarUnit outUnit = ScaleBarUnit.Undefined;
double outResolution;
#region KiloMeters/Meters
double roundedKiloMeters = getBestEstimateOfValue(Map.Resolution, ScaleBarUnit.Kilometers, out outUnit, out outResolution);
double widthMeters = roundedKiloMeters / outResolution;
bool inMeters = outUnit == ScaleBarUnit.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, ScaleBarUnit.Miles, out outUnit, out outResolution);
double widthMiles = roundedMiles / outResolution;
bool inFeet = outUnit == ScaleBarUnit.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;
}
private double getBestEstimateOfValue(double resolution, ScaleBarUnit displayUnit, out ScaleBarUnit unit, out double outResolution)
{
unit = displayUnit;
double rounded = 0;
double originalRes = resolution;
while (rounded < 0.5)
{
resolution = originalRes;
if (MapUnit == ScaleBarUnit.DecimalDegrees)
{
resolution = getResolutionForGeographic(Map.Extent, resolution);
resolution = resolution * (int)ScaleBarUnit.Meters / (int)unit;
}
else if (MapUnit != ScaleBarUnit.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)
{
ScaleBarUnit newUnit = ScaleBarUnit.Undefined;
// Automatically switch unit to a lower one
if (unit == ScaleBarUnit.Kilometers)
newUnit = ScaleBarUnit.Meters;
else if (unit == ScaleBarUnit.Miles)
newUnit = ScaleBarUnit.Feet;
if (newUnit == ScaleBarUnit.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;
ScaleBarUnit newUnit = ScaleBarUnit.Undefined;
// Automatically switch unit to a lower one
if (unit == ScaleBarUnit.Kilometers)
newUnit = ScaleBarUnit.Meters;
else if (unit == ScaleBarUnit.Miles)
newUnit = ScaleBarUnit.Feet;
if (newUnit == ScaleBarUnit.Undefined) { break; } //no lower unit
unit = newUnit;
}
}
}
}
outResolution = resolution;
return rounded;
}
double roundToSignificant(double value, double resolution)
{
var round = Math.Floor(-Math.Log(resolution));
if (round > 0)
{
round = Math.Pow(10, round);
return Math.Round(value * round) / round;
}
else { return Math.Round(value); }
}
/// <summary>
/// Calculates horizontal scale at center of extent
/// for geographic / Plate Carrée projection.
/// Horizontal scale is 0 at the poles.
/// </summary>
double toRadians = 0.017453292519943295769236907684886;
double earthRadius = 6378137; //Earth radius in meters (defaults to WGS84 / GRS80)
double degreeDist;
private double getResolutionForGeographic(ESRI.ArcGIS.Client.Geometry.Envelope extent, double resolution)
{
degreeDist = earthRadius * toRadians;
MapPoint center = extent.GetCenter();
double y = center.Y;
if (Math.Abs(y) > 90) { return 0; }
return Math.Cos(y * toRadians) * resolution * degreeDist;
}
#endregion
I think there is a problem with a map units (OSM is in meters), but I'm really new to .NET and C#, I tried to figure it out by myself but no success.Please help me... 🙂