1+ // Copyright 2014 - Robert Smart (www.cnl-software), Felix Obermaier (www.ivv-aachen.de)
2+ //
3+ // This file is part of SharpMap.
4+ // SharpMap is free software; you can redistribute it and/or modify
5+ // it under the terms of the GNU Lesser General Public License as published by
6+ // the Free Software Foundation; either version 2 of the License, or
7+ // (at your option) any later version.
8+ //
9+ // SharpMap is distributed in the hope that it will be useful,
10+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ // GNU Lesser General Public License for more details.
13+ //
14+ // You should have received a copy of the GNU Lesser General Public License
15+ // along with SharpMap; if not, write to the Free Software
16+ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17+
18+ using System ;
19+ using System . Drawing ;
20+ using System . Drawing . Imaging ;
21+ using Common . Logging ;
22+ using GeoAPI . Geometries ;
23+
24+ namespace SharpMap . Layers
25+ {
26+ /// <summary>
27+ /// Image manipulation proxy layer
28+ /// </summary>
29+ /// <typeparam name="T">The type of the proxy layer. <see cref="ITileAsyncLayer"/> are not excluded, but are not handled in any way.</typeparam>
30+ [ Serializable ]
31+ public class GdiImageLayerProxy < T > : ILayer , IDisposable
32+ where T : class , ILayer
33+ {
34+ private static readonly ILog Logger = Common . Logging . LogManager . GetCurrentClassLogger ( ) ;
35+
36+ private readonly ColorMatrix _colorMatrix ;
37+ private readonly ColorMap [ ] _colorMap ;
38+ private readonly T _baseLayer ;
39+
40+ /// <summary>
41+ /// Creates an instance of this class using the provided <paramref name="opacity"/>
42+ /// </summary>
43+ /// <param name="layer">The layer to be proxied</param>
44+ /// <param name="opacity">An opacity value in the range of [0f, 1f]. Values outside of that range will be clipped.</param>
45+ public GdiImageLayerProxy ( T layer , float opacity )
46+ : this ( layer , new ColorMatrix { Matrix33 = Math . Max ( Math . Min ( 1f , opacity ) , 0f ) } )
47+ {
48+ }
49+
50+ /// <summary>
51+ /// Creates an instance of this class using the provided <paramref name="colorMatrix"/>
52+ /// </summary>
53+ /// <param name="layer">The layer to be proxied</param>
54+ /// <param name="colorMatrix">A color matrix that is to be applied upon drawing</param>
55+ public GdiImageLayerProxy ( T layer , ColorMatrix colorMatrix )
56+ {
57+ if ( layer is ITileAsyncLayer )
58+ {
59+ Logger . Warn ( "ITileAsyncLayer is not a valid layer for GdiImageLayerProxy<T>" ) ;
60+ }
61+ _baseLayer = layer ;
62+ _colorMatrix = colorMatrix ;
63+ }
64+
65+ /// <summary>
66+ /// Creates an instance of this class using the provided <paramref name="colorMap"/>
67+ /// </summary>
68+ /// <param name="layer">The layer to be proxied</param>
69+ /// <param name="colorMap">The color map</param>
70+ public GdiImageLayerProxy ( T layer , params ColorMap [ ] colorMap )
71+ {
72+ if ( layer is ITileAsyncLayer )
73+ {
74+ Logger . Warn ( "ITileAsyncLayer is not a valid layer for GdiImageLayerProxy<T>" ) ;
75+ }
76+ _baseLayer = layer ;
77+ _colorMap = colorMap ;
78+ }
79+
80+ /// <summary>
81+ /// Gets a value indicating the proxied base layer
82+ /// </summary>
83+ public T BaseLayer { get { return _baseLayer ; } }
84+
85+ double ILayer . MinVisible
86+ {
87+ get { return _baseLayer . MinVisible ; }
88+ set { _baseLayer . MinVisible = value ; }
89+ }
90+
91+ double ILayer . MaxVisible
92+ {
93+ get { return _baseLayer . MaxVisible ; }
94+ set { _baseLayer . MaxVisible = value ; }
95+ }
96+
97+ bool ILayer . Enabled
98+ {
99+ get { return _baseLayer . Enabled ; }
100+ set { _baseLayer . Enabled = value ; }
101+ }
102+
103+ string ILayer . LayerName
104+ {
105+ get { return _baseLayer . LayerName ; }
106+ set { _baseLayer . LayerName = value ; }
107+ }
108+
109+ Envelope ILayer . Envelope
110+ {
111+ get { return _baseLayer . Envelope ; }
112+ }
113+
114+ int ILayer . SRID
115+ {
116+ get { return _baseLayer . SRID ; }
117+ set { _baseLayer . SRID = value ; }
118+ }
119+
120+ int ILayer . TargetSRID
121+ {
122+ get { return _baseLayer . TargetSRID ; }
123+ }
124+
125+ string ILayer . Proj4Projection
126+ {
127+ get { return _baseLayer . Proj4Projection ; }
128+ set { _baseLayer . Proj4Projection = value ; }
129+ }
130+
131+ void ILayer . Render ( Graphics g , Map map )
132+ {
133+ if ( _baseLayer is ITileAsyncLayer )
134+ {
135+ Logger . Warn ( "ITileAsyncLayer is not a valid layer for GdiImageLayerProxy<T>. -> Skipping" ) ;
136+ _baseLayer . Render ( g , map ) ;
137+ return ;
138+ }
139+
140+ var s = map . Size ;
141+ using ( var img = new Bitmap ( s . Width , s . Height , PixelFormat . Format32bppArgb ) )
142+ {
143+ using ( var gg = Graphics . FromImage ( img ) )
144+ {
145+ _baseLayer . Render ( gg , map ) ;
146+ }
147+
148+ using ( var ia = CreateImageAttributes ( ) )
149+ {
150+ g . DrawImage ( img , new Rectangle ( 0 , 0 , s . Width , s . Height ) ,
151+ 0 , 0 , s . Width , s . Height , GraphicsUnit . Pixel , ia ) ;
152+ }
153+ }
154+ }
155+
156+ private ImageAttributes CreateImageAttributes ( )
157+ {
158+ var ia = new ImageAttributes ( ) ;
159+ if ( _colorMatrix != null )
160+ {
161+ ia . SetColorMatrix ( _colorMatrix ) ;
162+ }
163+ else if ( _colorMap != null )
164+ {
165+ ia . SetRemapTable ( _colorMap ) ;
166+ }
167+ return ia ;
168+ }
169+
170+ public void Dispose ( )
171+ {
172+ if ( _baseLayer is IDisposable )
173+ {
174+ ( ( IDisposable ) _baseLayer ) . Dispose ( ) ;
175+ }
176+ }
177+ }
178+ }
0 commit comments