📄 mapprinter.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 + -