How to get map scale?

Apr 4, 2012 at 2:04 PM

Hi,everybody.I got started with DotSpatial library just a few days ago,and do not know much about the library.

Now,I want to show the map scale when I add a layer to the map control.Is there any existing functions?or I must figure it out myself.

Thanks.

Developer
Apr 4, 2012 at 3:00 PM

Here's a code snippet we use in our own DotSpatial app.  We have our own MapFrame, so we added a GCMapScale property and the ComputeMapScale method to the MapFrame.  This might be something that could be added to the DotSpatial MapFrame.  Please excuse the empty catches.... Not my idea.

Kyle

        private void ComputeMapScale()
        {
            try
            {
                const double dInchesPerMeter = 39.3700787401575;
                const double dDegreesPerRadian = 57.2957;
                double dMapWidthInMeters;

                if(null == Projection)
                    return;

                if (Projection.IsLatLon)
                {
                    var dMapWidthInRadians = ViewExtents.Width * Projection.GeographicInfo.Unit.Radians;
                    var dMapWidthInDegrees = dMapWidthInRadians * dDegreesPerRadian;
                    var dMapLatInRadians = ViewExtents.Center.Y * Projection.GeographicInfo.Unit.Radians;
                    var dMapLatInDegrees = dMapLatInRadians * dDegreesPerRadian;
                    dMapWidthInMeters = GeoCueDotSpatial.GCDSGraphicUtils.MetersFromDecimalDegreesPoints(0.0, dMapLatInDegrees, dMapWidthInDegrees, dMapLatInDegrees);
                }
                else
                    dMapWidthInMeters = ViewExtents.Width * Projection.Unit.Meters;


                // Get the number of pixels in one screen inch.
                // get resolution, most screens are 96 dpi, but
                // you never know...
                double dScreenWidthInMeters = (Convert.ToDouble(BufferImage.Width) / BufferImage.HorizontalResolution) / dInchesPerMeter;
                double dMetersPerScreenMeter = dMapWidthInMeters / dScreenWidthInMeters;
                GCMapScale = dMetersPerScreenMeter;
            }
            catch { }	// Should not happen...
        }

        /// <summary>
        /// Uses spherical approximation method to return distance in meters between two decimal degree points.
        /// </summary>
        /// <param name="dDegX1"></param>
        /// <param name="dDegY1"></param>
        /// <param name="dDegX2"></param>
        /// <param name="dDegY2"></param>
        /// <returns></returns>
        public static double MetersFromDecimalDegreesPoints(double dDegX1, double dDegY1, double dDegX2, double dDegY2)
        {
            try
            {
                double dRadius = 6378007;  // radius of Earth in meters
                double dCircumference = dRadius * 2 * Math.PI;
                double dMetersPerLatDD = 111113.519;
                double dDeltaXdd = 0.0;
                double dDeltaYdd = 0.0;
                double dDeltaXmeters = 0.0;
                double dDeltaYmeters = 0.0;
                double dMetersPerLongDD = 0.0;
                double dCenterY = 0.0;

                dDeltaXdd = Math.Abs(dDegX1 - dDegX2);
                dDeltaYdd = Math.Abs(dDegY1 - dDegY2);
                dCenterY = (dDegY1 + dDegY2) / 2.0;
                dMetersPerLongDD = (Math.Cos(dCenterY * (Math.PI / 180.0)) * dCircumference) / 360.0;
                dDeltaXmeters = dMetersPerLongDD * dDeltaXdd;
                dDeltaYmeters = dMetersPerLatDD * dDeltaYdd;

                return Math.Sqrt(Math.Pow(dDeltaXmeters, 2.0) + Math.Pow(dDeltaYmeters, 2.0));
            }
            catch { return 0.0; }
        }