Esempio n. 1
0
        public static bool GetGeodesicSizePrecise(this IPrintableMap map, IEnvelope extents, out GeoSize size)
        {
            size = null;
            double width, height;

            if (map.Projection.HasTransformation)
            {
                // the projection supports coordinate tranformation to WGS84
                if (CalculateExtentsWidth(map, extents, out width) &&
                    CalculateExtentsHeight(map, extents, out height))
                {
                    size = new GeoSize(width, height);
                    return(true);
                }
            }

            if (map.Projection.IsGeographic)
            {
                // it's WGS84
                var center = extents.Center;

                width  = GeodesicDistance(center.Y, extents.MinX, center.Y, extents.MaxX);
                height = GeodesicDistance(extents.MinY, center.X, extents.MaxY, center.X);

                size = new GeoSize(width, height);

                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        /// <summary>
        /// Recursively calculates new extents of the map ot cover a certain geo size in meters.
        /// </summary>
        private static IEnvelope CalcNewExtentsCore(
            IPrintableMap map,
            IEnvelope oldExtents,
            GeoSize newSize,
            SizeF paperSize,
            ref int depth)
        {
            depth++;

            GeoSize oldSize;

            if (map.GetGeodesicSize(oldExtents, out oldSize))
            {
                const int maxDepth = 5;

                double newScale = CalcMapScale(newSize, paperSize);
                double oldScale = CalcMapScale(oldSize, paperSize);

                if (NumericHelper.Equal(newScale, oldScale, 1e-6) || depth > maxDepth)
                {
                    return(oldExtents);
                }

                double ratio   = newScale / oldScale - 1;
                double dx      = oldExtents.Width * ratio;
                double dy      = oldExtents.Height * ratio;
                var    extents = oldExtents.Inflate(dx, dy);

                return(CalcNewExtentsCore(map, extents, newSize, paperSize, ref depth));
            }

            return(null);
        }
        private void Map1_Loaded(object sender, RoutedEventArgs e)
        {
            Map1.MapUnit = GeoUnit.Meter;

            GeoImage      image         = new GeoImage(@"SampleData/bing-aerial-900913.png");
            GeoSize       size          = image.GetSize();
            GeoImageLayer geoImageLayer = new GeoImageLayer(image, new WorldFile(GeoCommonHelper.GetMaxBound(GeoUnit.Meter), (float)size.Width, (float)size.Height));

            LayerOverlay layerOverlay = new LayerOverlay();

            layerOverlay.Layers.Add(geoImageLayer);
            Map1.Overlays.Add(layerOverlay);
            Map1.ZoomToFullBound();
        }
Esempio n. 4
0
        /// <summary>
        /// Calculates the size of specified map extents in meters.
        /// </summary>
        public static bool GetGeodesicSize(this IPrintableMap map, IEnvelope extents, out GeoSize size)
        {
            bool result = GetGeodesicSizePrecise(map, extents, out size);

            if (result)
            {
                return(true);
            }

            // we have nothing better but return width and height of the extents in original
            // coordinate system; only let's convert them to meters (geodesic size is always in meters)
            double width  = UnitConversionHelper.Convert(map.MapUnits, LengthUnits.Meters, extents.Width);
            double height = UnitConversionHelper.Convert(map.MapUnits, LengthUnits.Meters, extents.Height);

            size = new GeoSize(width, height);
            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Calculates the size of the map on screen for a given size of map area and scale.
        /// </summary>
        /// <param name="mapScale">Map scale.</param>
        /// <param name="geoSize">Geodesic size of the map area in meters.</param>
        /// <param name="xyRatio">The X / Y ratio for the extents in original coordinate system.</param>
        /// <returns>Size of the map on the screen in 1/100 of an inch.</returns>
        public static SizeF CalcMapSize(int mapScale, GeoSize geoSize, double xyRatio)
        {
            double cf           = LengthUnits.Meters.GetConversionFactor();
            var    widthInches  = geoSize.Width * cf / mapScale;
            var    heightInches = geoSize.Height * cf / mapScale;

            // The distortion introduced be orginal map coordinate system may be different along X and Y axes,
            // so paper size rectangle may no longer have the same X / Y side ratio as original extents.
            // This will result in adjustment of extents in map projection according to this ratio, which is undesirable.
            // Let's instead adjust resulting paper size to orignal X / Y ratio.
            double newRatio = widthInches / heightInches;

            if (!NumericHelper.Equal(newRatio, xyRatio, 1e-6))
            {
                double correction = Math.Sqrt(newRatio / xyRatio);
                heightInches *= correction;
                widthInches  /= correction;
            }

            return(new SizeF((float)(widthInches * 100.0), (float)(heightInches * 100.0)));
        }
Esempio n. 6
0
        /// <summary>
        /// Calculates map scale to fit given extents.
        /// </summary>
        /// <param name="geoSize">Geodesic size of mapped area in meters.</param>
        /// <param name="mapSize">Size of the map on the screen (1/100 of inch).</param>
        /// <param name="scaleType">The X and Y scale are often different, this parameter tells how to choose the return value from 2 values available.</param>
        /// <returns>Scale of the map.</returns>
        public static double CalcMapScale(GeoSize geoSize, SizeF mapSize, ScaleType scaleType = ScaleType.Average)
        {
            double cf     = LengthUnits.Meters.GetConversionFactor();
            double scaleX = geoSize.Width / (mapSize.Width / 100.0 / cf);
            double scaleY = geoSize.Height / (mapSize.Height / 100.0 / cf);

            switch (scaleType)
            {
            case ScaleType.Average:
                return((scaleX + scaleY) / 2.0);

            case ScaleType.Smallest:
                return(Math.Max(scaleX, scaleY));

            case ScaleType.Largest:
                return(Math.Min(scaleX, scaleY));

            default:
                throw new ArgumentOutOfRangeException("scaleType");
            }
        }
Esempio n. 7
0
 /// <summary>
 /// Calculates the size of currently selected map extents in meters
 /// </summary>
 public static bool GetGeodesicSize(this IPrintableMap map, out GeoSize size)
 {
     return(GetGeodesicSize(map, map.Extents, out size));
 }
 ////////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 18JUN2009  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * Constructs a new <code>GeoBounds</code> whose top left corner is
  * (0,&nbsp;0) and whose Width and Height are specified
  * by the <code>GeoSize</code> argument.
  * @param size a <code>GeoSize</code>, specifying Width and Height
  */
 public GeoLatLngBounds(GeoSize size)
     : this(0, 0, size.Width, size.Height)
 {
 }
 ////////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 18JUN2009  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * Constructs a new <code>GeoBounds</code> whose upper-left corner is
  * specified by the GeoPoint argument, and
  * whose Width and Height are specified by the
  * {@link GeoSize} argument.
  * @param p a <code>GeoPoint</code> that is the upper-left corner of
  * the <code>GeoBounds</code>
  * @param size a <code>GeoSize</code>, representing the
  * Width and Height of the <code>GeoBounds</code>
  */
 public GeoLatLngBounds(GeoPoint p, GeoSize size)
     : this(p.X, p.Y, size.Width, size.Height)
 {
 }
Esempio n. 10
0
        /// <summary>
        /// Calculates new extents of the map given that they must cover certain geo size in meters.
        /// </summary>
        /// <param name="map">The map.</param>
        /// <param name="oldExtents">The extents.</param>
        /// <param name="newSize">The new size.</param>
        /// <param name="paperSize"></param>
        /// <returns>New extents</returns>
        public static IEnvelope CalcNewExtents(IPrintableMap map, IEnvelope oldExtents, GeoSize newSize, SizeF paperSize)
        {
            int depth = 0;

            return(CalcNewExtentsCore(map, oldExtents, newSize, paperSize, ref depth));
        }
Esempio n. 11
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 18JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Constructs a new <code>GeoBounds</code> whose top left corner is
         * (0,&nbsp;0) and whose Width and Height are specified
         * by the <code>GeoSize</code> argument.
         * @param size a <code>GeoSize</code>, specifying Width and Height
         */
        public GeoLatLngBounds(GeoSize size)
            : this(0, 0, size.Width, size.Height)
        {
        }
Esempio n. 12
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 18JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Constructs a new <code>GeoBounds</code> whose upper-left corner is
         * specified by the GeoPoint argument, and
         * whose Width and Height are specified by the
         * {@link GeoSize} argument.
         * @param p a <code>GeoPoint</code> that is the upper-left corner of
         * the <code>GeoBounds</code>
         * @param size a <code>GeoSize</code>, representing the
         * Width and Height of the <code>GeoBounds</code>
         */
        public GeoLatLngBounds(GeoPoint p, GeoSize size)
            : this(p.X, p.Y, size.Width, size.Height)
        {
        }