⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapprinter.cs

📁 arcgis engine地图打印任务的应用
💻 CS
字号:
// Copyright 2006 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See use restrictions at /arcgis/developerkit/userestrictions.
// 

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Web;
using System.Web.SessionState;
using System.Web.UI.WebControls;
using ESRI.ArcGIS.ADF.Web;
using ESRI.ArcGIS.ADF.Web.DataSources;
using ESRI.ArcGIS.ADF.Web.Geometry;
using ESRI.ArcGIS.ADF.Web.UI.WebControls;
using System.Drawing.Imaging;

namespace PrintTask_CSharp
{
    /// <summary>
    /// Outputs a single bitmap image for an ADF Map control.
    /// </summary>
    class MapPrinter
    {
        private int _height;
        private int _width;
        private Map _map;
        private ScaleBar _scaleBar;
        private Bitmap _mapBitmap;
        private int _dpi;
        private double _scale;

        /// <summary>
        /// Creates a printer object.
        /// </summary>
        /// <param name="mapControl">Map control to use for creating image.</param>
        public MapPrinter(Map mapControl)
        {
            _map = mapControl;
            _height = 0; _width = 0;
            _dpi = 96;
            _scale = 0;
        }

        #region Properties

        /// <summary>
        /// Height to print map at. Default is to use current Map control height.
        /// </summary>
        public int MapHeight
        {
            get { return (_height == 0) ? _map.TilingScheme.ViewHeight : _height; }
            set { _height = value; }
        }

        /// <summary>
        /// Width to print map at. Default is to use current Map control width.
        /// </summary>
        public int MapWidth
        {
            get { return (_width == 0) ? _map.TilingScheme.ViewWidth : _width; }
            set { _width = value; }
        }

        /// <summary>
        /// DPI setting for map. Affects label sizes when printing at higher resolutions.
        /// </summary>
        public int Dpi
        {
            get { return _dpi; }
            set { _dpi = value; }
        }

        /// <summary>
        /// Scale for the map.
        /// </summary>
        public double MapScale
        {
            get { return _scale; }
            set { _scale = value; }
        }

        /// <summary>
        /// Map control for which to print image.
        /// </summary>
        public Map MapControl
        {
            get { return _map; }
            set { _map = value; }
        }

        /// <summary>
        /// If set, scalebar is drawn on top of the map.
        /// </summary>
        public ScaleBar ScaleBarControl
        {
            get { return _scaleBar; }
            set { _scaleBar = value; }
        }

        /// <summary>
        /// Image output from GeneratePrintImage() method. Null if method not yet called.
        /// </summary>
        public Bitmap PrintImage
        {
            get { return _mapBitmap; }
        }

        #endregion

        /// <summary>
        /// Generates a merged bitmap image all resources in Map.
        /// </summary>
        /// <returns>Bitmap of merged images of all resources in Map control.</returns>
        public Bitmap GeneratePrintImage()
        {
            if (MapControl != null)
            {
                _mapBitmap = GetMergedMapImage(MapControl, MapHeight, MapWidth);
            }
            return _mapBitmap;
        }

        #region Private methods

        private Bitmap GetMergedMapImage(Map map, int height, int width)
        {
            Bitmap mapImageMerged = null;

            // scalebar bitmap created when processing primary map resource
            Bitmap scaleBarImage = null;
            
            if (map == null)
                return null;

            List<Bitmap> imageBitmaps = new List<Bitmap>();
            List<float> imageTransparencies = new List<float>();

            Envelope tempEnv = null;
            if (MapScale > 0)
            {
                tempEnv = map.Extent;
                map.Extent = this.GetEnvelopeAtScale(MapScale, map.Scale, map.Extent);
            }

            // create image descriptor to use for each resource print
            ImageDescriptor imgDescriptor = (ImageDescriptor)
                map.GetFunctionality(0).DisplaySettings.ImageDescriptor.Clone();
            imgDescriptor.Height = height;
            imgDescriptor.Width = width;
            if (this.Dpi > 0)
                imgDescriptor.Dpi = this.Dpi;
            imgDescriptor.TransparentBackground = true;
            imgDescriptor.ReturnMimeData = true;
            // (could examine each functionality and use 8 bit if no func. is png24/jpg)
            imgDescriptor.ImageFormat = ESRI.ArcGIS.ADF.Web.ImageFormat.PNG24;

            ImageDescriptor tempImgDesc;

            MapResourceManager mapResMgr = map.MapResourceManagerInstance;
            // Make sure resources initialized (needed after 9.2 SP1)
            if (!mapResMgr.Initialized)
                mapResMgr.Initialize();
           
            foreach (IMapFunctionality mf in map.GetFunctionalities())
            {
                // just in case one of the map services isn't working, but others are...
                // ...or if the map resource is invisible, skip to next resource
                if (mf == null || !mf.DisplaySettings.Visible)
                    continue;

                // swap out the image settings temporarily
                tempImgDesc = mf.DisplaySettings.ImageDescriptor;
                mf.DisplaySettings.ImageDescriptor = imgDescriptor;
                imgDescriptor.TransparentColor = tempImgDesc.TransparentColor;

                // handle label/symbol scaling issue with IMS services
                if (mf is ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality)
                    SetImsSymbolScaling((ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality)mf, true);

                ESRI.ArcGIS.ADF.Web.MapImage mi = mf.DrawExtent(map.Extent);
                
                // get the bitmap for each image, if anything is drawn
                //  (blank graphics layers will be null)
                if (mi != null)
                {
                    Bitmap bm = mi.GetImage();
                    if (this.Dpi > 0)
                        bm.SetResolution(this.Dpi, this.Dpi);
                    else
                        bm.SetResolution(96f, 96f);
                    imageBitmaps.Add(bm);

                    // remember transparency of image for merging later
                    imageTransparencies.Add(mf.DisplaySettings.Transparency / 100);
                }

                // handle label/symbol scaling issue with IMS services - turn off scaling
                if (mf is ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality)
                    SetImsSymbolScaling(
                        (ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality)mf, false);

                // if this is the primary map resource, handle scalebar if it exists
                if (MapControl.PrimaryMapResource == mf.Resource.Name &&
                    this.ScaleBarControl != null)
                {
                    scaleBarImage = ScaleBarPrinter.GetRefreshedScalebar(
                        ScaleBarControl);
                }

                // restore preexisting image settings
                mf.DisplaySettings.ImageDescriptor = tempImgDesc;
            }

            // create a merged bitmap from all Map resource layers
            if (imageBitmaps.Count > 0)
                mapImageMerged = MergeImages(imageBitmaps, imageTransparencies);

            // add scalebar image on top, if one has been created
            if (scaleBarImage != null)
                AddScalebarImage(ref mapImageMerged, scaleBarImage);

            // restore pre-existing map envelope when scale is set
            if (MapScale > 0)
                map.Extent = tempEnv;

            return mapImageMerged;
        }

        private Envelope GetEnvelopeAtScale(double scale,
            double currentScale, Envelope currentExtent)
        {
            // scale the envelope
            double xCtr = (currentExtent.XMax + currentExtent.XMin) / 2;
            double yCtr = (currentExtent.YMin + currentExtent.YMax) / 2;
            double xWidth = currentExtent.XMax - currentExtent.XMin;
            double yHeight = currentExtent.YMax - currentExtent.YMin;
            double newXRadius = xWidth / currentScale * scale;
            double newYRadius = yHeight / currentScale * scale;

            double newXMin = xCtr - newXRadius;
            double newXMax = xCtr + newXRadius;
            double newYMin = yCtr - newYRadius;
            double newYMax = yCtr + newYRadius;

            Envelope newEnv = new Envelope(newXMin, newYMin, newXMax, newYMax);
            return newEnv;
        }

        /// <summary>
        /// Merges a set of Bitmap images into a single Bitmap. Draws from bottom of list upwards.
        /// </summary>
        /// <param name="images">List of Bitmap images. Must all be same size.</param>
        /// <param name="transparencies">Transparency values for each image, for partial
        /// transparency to image underneath. Values must be between 0 and 1 (opaque).</param>
        /// <returns>Merge of bitmaps.</returns>
        public Bitmap MergeImages(List<Bitmap> images, List<float> transparencies)
        {
            Bitmap mergedImage = new Bitmap(images[0].Width, images[0].Height);
            mergedImage.SetResolution(images[0].HorizontalResolution, images[0].VerticalResolution);
            Graphics graphics = Graphics.FromImage(mergedImage);

            for (int i = images.Count - 1; i >= 0; i--)
            {
                if (transparencies[i] == 0)
                    graphics.DrawImageUnscaled(images[i], 0, 0);
                else
                {
                    // draw with transparency via alpha blending
                    float[][] ptsArray ={
                        new float[] {1, 0, 0, 0, 0},
                        new float[] {0, 1, 0, 0, 0},
                        new float[] {0, 0, 1, 0, 0},
                        new float[] {0, 0, 0, 1-transparencies[i], 0},
                        new float[] {0, 0, 0, 0, 1}};
                    ColorMatrix clrMatrix = new ColorMatrix(ptsArray);
                    ImageAttributes imgAttributes = new ImageAttributes();
                    imgAttributes.SetColorMatrix(clrMatrix,
                        ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                    graphics.DrawImage(images[i],
                        new Rectangle(0, 0, images[i].Width, images[i].Height),
                        0, 0, images[i].Width, images[i].Height,
                        GraphicsUnit.Pixel, imgAttributes);
                }
            }

            graphics.Dispose();

            return mergedImage;
        }

        // Adds a scalebar image to the merged map image, in the lower right corner
        private void AddScalebarImage(ref Bitmap mergedImage, Bitmap scalebarImage)
        {
            int top = mergedImage.Height - scalebarImage.Height;
            int left = mergedImage.Width - scalebarImage.Width;
            Graphics graphics = Graphics.FromImage(mergedImage);
            graphics.DrawImageUnscaled(scalebarImage, left, top);
            graphics.Dispose();
        }

        // Handles problem with ArcIMS image services when DPI increases
        //  -- labels/symbols aren't scaled by default, so appear too small with
        //     higher resolutions. Setting ScaleSymbols enlarges symbols appropriately.
        private void SetImsSymbolScaling(ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality mapFunc,
            bool enableScaling)
        {
            ESRI.ArcGIS.ADF.IMS.Carto.MapView mapView = mapFunc.MapView;
            if (mapFunc.DisplaySettings.ImageDescriptor.Dpi > 96)
            {
                mapView.ImageDescriptor.ScaleSymbols = enableScaling;
                mapView.ImageDescriptor.Dpi = mapFunc.DisplaySettings.ImageDescriptor.Dpi;
            }
        }

        #endregion

        /// <summary>
        /// Cleans up bitmap resource in the class.
        /// </summary>
        public void Dispose()
        {
            if (_mapBitmap != null)
                _mapBitmap.Dispose();
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -