Beispiel #1
0
        /// <summary>
        /// Try to initialize the map units
        /// </summary>
        private void InitializeMapUnit()
        {
            if (Map == null || Map.SpatialReference == null)
            {
                return;
            }

            // First test the well know spatial references
            if (Map.SpatialReference.WKID == 4326)
            {
                MapUnit = ScaleLineUnit.DecimalDegrees;
            }
            else if (_webMercSref.Equals(Map.SpatialReference))
            {
                MapUnit = ScaleLineUnit.Meters;
            }
            else
            {
                Layer layer = Map.Layers == null ? null :
                              Map.Layers.FirstOrDefault(l => l.SpatialReference != null && l.SpatialReference.Equals(Map.SpatialReference));

                string layerUnits;
                if (layer is ArcGISDynamicMapServiceLayer)
                {
                    layerUnits = ((ArcGISDynamicMapServiceLayer)layer).Units;
                }
                else if (layer is ArcGISTiledMapServiceLayer)
                {
                    layerUnits = ((ArcGISTiledMapServiceLayer)layer).Units;
                }
                else
                {
                    layerUnits = null;
                }

                if (!string.IsNullOrEmpty(layerUnits))
                {
                    // Remove leading 'esri' to layerUnits
                    if (layerUnits.StartsWith("esri"))
                    {
                        layerUnits = layerUnits.Substring(4);
                    }

                    try
                    {
                        ScaleLineUnit unit = (ScaleLineUnit)Enum.Parse(typeof(ScaleLineUnit), layerUnits, true);
                        MapUnit = unit;
                    }
                    catch (ArgumentException)                     // layersUnits is not one of the named constants defined for the enumeration
                    {
                    }
                }
            }
        }
Beispiel #2
0
        private double GetBestEstimateOfValue(double resolution, ScaleLineUnit displayUnit, out ScaleLineUnit unit, out double outResolution)
        {
            unit = displayUnit;
            double rounded     = 0;
            double originalRes = resolution;

            while (rounded < 0.5)
            {
                resolution = originalRes;
                if (MapUnit == ScaleLineUnit.DecimalDegrees)
                {
                    resolution = GetResolutionForGeographic(Map.Extent.GetCenter(), resolution);
                    resolution = resolution * (int)ScaleLineUnit.Meters / (int)unit;
                }
                else if (_webMercSref.Equals(Map.SpatialReference))
                {
                    //WebMercator
                    double mercatorStretch = 1 / Math.Cosh(Map.Extent.GetCenter().Y / earthRadius);                     // = Cos(lat)
                    resolution = mercatorStretch * originalRes * (int)ScaleLineUnit.Meters / (int)unit;
                }
                else if (MapUnit != ScaleLineUnit.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)
                {
                    ScaleLineUnit newUnit = ScaleLineUnit.Undefined;
                    // Automatically switch unit to a lower one
                    if (unit == ScaleLineUnit.Kilometers)
                    {
                        newUnit = ScaleLineUnit.Meters;
                    }
                    else if (unit == ScaleLineUnit.Miles)
                    {
                        newUnit = ScaleLineUnit.Feet;
                    }
                    if (newUnit == ScaleLineUnit.Undefined)
                    {
                        break;
                    }                                                                      //no lower unit
                    unit = newUnit;
                }
                else if (noFrac > 1)
                {
                    rounded = noFrac;
                    var len = noFrac.ToString("F0").Length;                     // Format F0 prevents from using exponential notation for big numbers
                    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;
                            ScaleLineUnit newUnit = ScaleLineUnit.Undefined;
                            // Automatically switch unit to a lower one
                            if (unit == ScaleLineUnit.Kilometers)
                            {
                                newUnit = ScaleLineUnit.Meters;
                            }
                            else if (unit == ScaleLineUnit.Miles)
                            {
                                newUnit = ScaleLineUnit.Feet;
                            }
                            if (newUnit == ScaleLineUnit.Undefined)
                            {
                                break;
                            }                                                                              //no lower unit
                            unit = newUnit;
                        }
                    }
                }
            }
            outResolution = resolution;
            return(rounded);
        }
		private double GetBestEstimateOfValue(double resolution, ScaleLineUnit displayUnit, out ScaleLineUnit unit, out double outResolution)
		{
			unit = displayUnit;
			double rounded = 0;
			double originalRes = resolution;
			while (rounded < 0.5)
			{
				resolution = originalRes;
				if (MapUnit == ScaleLineUnit.DecimalDegrees)
				{
					resolution = GetResolutionForGeographic(Map.Extent.GetCenter(), resolution);
					resolution = resolution * (int)ScaleLineUnit.Meters / (int)unit;
				}
				else if (_webMercSref.Equals(Map.SpatialReference))
				{
					//WebMercator
					double mercatorStretch = 1 / Math.Cosh(Map.Extent.GetCenter().Y / earthRadius); // = Cos(lat)
					resolution = mercatorStretch * originalRes * (int)ScaleLineUnit.Meters / (int)unit;
				}
				else if (MapUnit != ScaleLineUnit.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)
				{
					ScaleLineUnit newUnit = ScaleLineUnit.Undefined;
					// Automatically switch unit to a lower one
					if (unit == ScaleLineUnit.Kilometers)
						newUnit = ScaleLineUnit.Meters;
					else if (unit == ScaleLineUnit.Miles)
						newUnit = ScaleLineUnit.Feet;
					if (newUnit == 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;
							ScaleLineUnit newUnit = ScaleLineUnit.Undefined;
							// Automatically switch unit to a lower one
							if (unit == ScaleLineUnit.Kilometers)
								newUnit = ScaleLineUnit.Meters;
							else if (unit == ScaleLineUnit.Miles)
								newUnit = ScaleLineUnit.Feet;
							if (newUnit == ScaleLineUnit.Undefined) { break; } //no lower unit
							unit = newUnit;
						}
					}
				}
			}
			outResolution = resolution;
			return rounded;
		}