目的:
1.arcgis server9.2 ADF中把Virtual Earth地图图片数据作为数据源,这样可以直接使用MicroSoft的卫星图片。
准备工作:
1.参考DeveloperKit\SamplesNET\Server\Web_Applications目录下的Common_CustomDataSourceCSharp.zip。
完成后的效果图:

开始:
1.把Virtual Earth地图图片数据作为地图数据源,和(九、一)例子一样也是需要通过自定义数据源实现了,具体的关于地图数据、地图控件、Data Source、Resource、Functionatily之间的关系地图以及地图从数据到显示的整个过程说明可以参考(九、一)例子,这里不做详细的说明。
2.新建名为CustomDataSource的ASP.NET Web应用程序,然后添加一个Default_TileMapData.aspx页面用来具体功能的展示。
3.在CustomDataSource的解决方案中在添加一个名为TiledMapDataSource的类库工程,用来实现自定义DataSource类型和MapResource的功能。同时在CustomDataSource的ASP.NET Web应用程序中添加对这个TiledMapDataSource的类库工程的引用。
4.同(九、一)例子一样自定义数据源的要在ADF中使用需要在ArcGisServer安装目录的DotNet文件内添加配置文件,关于配置文件的说明可以看(九、一)例子,添加名为ESRI.ArcGIS.ADF.Web.DataSources.TiledMap.config的配置文件,内容如下:

Code
1
<?xml version="1.0" encoding="utf-8" ?>
2
<DataSources>
3
<DataSource name="TiledMap CSharp">
4
<Implementation assembly ="TiledMapDataSource" class="TiledMapDataSource.GISDataSource"></Implementation>
5
<IdentityEditorForm assembly ="ESRI.ArcGIS.ADF.Web.UI.WebControls" class="ESRI.ArcGIS.ADF.Web.UI.WebControls.Design.UnusedPropertyEditor"></IdentityEditorForm>
6
<DefinitionEditorForm assembly ="" class=""></DefinitionEditorForm>
7
<Resource type="Map">
8
<DefinitionEditorForm assembly ="" class=""></DefinitionEditorForm>
9
<Implementation assembly ="TiledMapDataSource" class="TiledMapDataSource.MapResource"></Implementation>
10
</Resource>
11
</DataSource>
12
</DataSources>
5.从上面配置文件看,我们需要实现TiledMapDataSource.GISDataSource、TiledMapDataSource.MapResource这2个类,新建GISDataSource.cs和MapResource.cs两个文件。
6.TiledMapDataSource.GISDataSource类和(九、一)例子一样了这里不详细说明了,同时也可以参考Common_CustomDataSourceCSharp.zip的源代码,这样需要对在TiledMapDataSource.GISDataSource类中使用到的MapInformation.cs类需要进行说明,与上例不同这次是采用Virtual Earth瓦块图片数据,所以MapInformation.cs类的实现较上例有些不同,主要区别是当MapInformation类实例化时,读取配置了Virtual Earth地图数据的一些配置参数对TileCacheInfo属性进行数据设置,主要是在方法parseConfig()中。
Virtual Earth地图数据配置参数文件VirtualEarth_original.xml,具体节点说明可以对照parseConfig()方法,内容具体如下:

Code
1
<TileCacheInfos>
2
<TileCacheInfo Name='Virtual Earth Map'
3
SpatialReference='PROJCS["Sphere_VE_WGS84",GEOGCS["GCS_Sphere_VE_WGS84",
4
DATUM["D_Sphere_VE_WGS84",
5
SPHEROID["Sphere_VE_WGS84",6378137.0,0.0]],
6
PRIMEM["Greenwich",0.0],
7
UNIT["Degree",0.0174532925199433]],
8
PROJECTION["Mercator"],
9
PARAMETER["False_Easting",0.0],
10
PARAMETER["False_Northing",0.0],
11
PARAMETER["Central_Meridian",0.0],
12
PARAMETER["Standard_Parallel_1",0.0],
13
UNIT["Meter",1.0]]'
14
DPI='96'
15
Width='256' Height='256' TileOrigin='-20037508.3427892,20037508.3427892'>
16
<FullExtent XMin='-20037508.3427892' YMin='-20037508.3427892' XMax='20037508.3427892' YMax='20037508.3427892'/>
17
<DefaultExtent XMin='-20037508.3427892' YMin='-20037508.3427892' XMax='20037508.3427892' YMax='20037508.3427892'/>
18
<Layers>
19
<Layer LayerID='r' Name='Road' />
20
<Layer LayerID='a' Name='Aerial' />
21
</Layers>
22
<TileUrlGenerator type='class' Assembly='TiledMapDataSource' Class='TiledMapDataSource.VirtualEarthTileUrlGenerator' />
23
<LodInfos>
24
<LodInfo LevelID='1' Resolution='78271.5170' Scale='295829355.45' Rows='2' Columns='2' TileExtentWidth='20037508.3427892' TileExtentHeight='20037508.3427893' TileUrl='' />
25
<LodInfo LevelID='2' Resolution='39135.7585' Scale='147914677.73' Rows='4' Columns='4' TileExtentWidth='10018754.1713946' TileExtentHeight='10018754.1713947' TileUrl='' />
26
<LodInfo LevelID='3' Resolution='19567.8792' Scale='73957338.86' Rows='8' Columns='8' TileExtentWidth='5009377.08569731' TileExtentHeight='5009377.08569736' TileUrl='' />
27
<LodInfo LevelID='4' Resolution='9783.9396' Scale='36978669.43' Rows='16' Columns='16' TileExtentWidth='2504688.54284865' TileExtentHeight='2504688.54284866' TileUrl='' />
28
<LodInfo LevelID='5' Resolution='4891.9698' Scale='18489334.72' Rows='32' Columns='32' TileExtentWidth='1252344.27142432' TileExtentHeight='1252344.27142439' TileUrl='' />
29
<LodInfo LevelID='6' Resolution='2445.9849' Scale='9244667.36' Rows='64' Columns='64' TileExtentWidth='626172.135712165' TileExtentHeight='626172.135712203' TileUrl='' />
30
<LodInfo LevelID='7' Resolution='1222.9925' Scale='4622333.68' Rows='128' Columns='128' TileExtentWidth='313086.067856081' TileExtentHeight='313086.067856163' TileUrl='' />
31
<LodInfo LevelID='8' Resolution='611.4962' Scale='2311166.84' Rows='256' Columns='256' TileExtentWidth='156543.03392804' TileExtentHeight='156543.033928085' TileUrl='' />
32
<LodInfo LevelID='9' Resolution='305.7481' Scale='1155583.42' Rows='512' Columns='512' TileExtentWidth='78271.5169640221' TileExtentHeight='78271.5169640593' TileUrl='' />
33
<LodInfo LevelID='10' Resolution='152.8741' Scale='577791.71' Rows='1024' Columns='1024' TileExtentWidth='39135.7584820092' TileExtentHeight='39135.7584820762' TileUrl='' />
34
<LodInfo LevelID='11' Resolution='76.4370' Scale='288895.85' Rows='2048' Columns='2048' TileExtentWidth='19567.8792410046' TileExtentHeight='19567.8792410083' TileUrl='' />
35
<LodInfo LevelID='12' Resolution='38.2185' Scale='144447.93' Rows='4096' Columns='4096' TileExtentWidth='9783.93962049857' TileExtentHeight='9783.93962051347' TileUrl='' />
36
<LodInfo LevelID='13' Resolution='19.1093' Scale='72223.96' Rows='8192' Columns='8192' TileExtentWidth='4891.96981025115' TileExtentHeight='4891.96981034055' TileUrl='' />
37
<LodInfo LevelID='14' Resolution='9.5546' Scale='36111.98' Rows='16384' Columns='16384' TileExtentWidth='2445.98490512371' TileExtentHeight='2445.98490521312' TileUrl='' />
38
<LodInfo LevelID='15' Resolution='4.7773' Scale='18055.99' Rows='32768' Columns='32768' TileExtentWidth='1222.99245255813' TileExtentHeight='1222.99245259538' TileUrl='' />
39
<LodInfo LevelID='16' Resolution='2.3887' Scale='9027.0' Rows='65536' Columns='65536' TileExtentWidth='611.496226280928' TileExtentHeight='611.496226321906' TileUrl='' />
40
<LodInfo LevelID='17' Resolution='1.1943' Scale='4513.0' Rows='131072' Columns='131072' TileExtentWidth='305.748113140464' TileExtentHeight='305.748113185167' TileUrl='' />
41
<LodInfo LevelID='18' Resolution='0.5971' Scale='2254.4' Rows='262144' Columns='262144' TileExtentWidth='152.702993744053' TileExtentHeight='152.702993744053' TileUrl= '' />
42
<LodInfo LevelID='19' Resolution='0.29858' Scale='1127.2' Rows='524288' Columns='524288' TileExtentWidth='76.3514968720267' TileExtentHeight='76.3514968720267' TileUrl= '' />
43
<LodInfo LevelID='20' Resolution='0.14929' Scale='563.6' Rows='1048576' Columns='1048576' TileExtentWidth='38.1757484360134' TileExtentHeight='38.1757484360134' TileUrl= '' />
44
<LodInfo LevelID='21' Resolution='0.07464' Scale='281.8' Rows='2097152' Columns='2097152' TileExtentWidth='19.0878742180067' TileExtentHeight='19.0878742180067' TileUrl= '' />
45
<LodInfo LevelID='22' Resolution='0.03732' Scale='140.9' Rows='4194304' Columns='4194304' TileExtentWidth='9.54393710900334' TileExtentHeight='9.54393710900334' TileUrl= '' />
46
<LodInfo LevelID='23' Resolution='0.01866' Scale='70.45' Rows='8388608' Columns='8388608' TileExtentWidth='4.77196855450167' TileExtentHeight='4.77196855450167' TileUrl= '' />
47
</LodInfos>
48
</TileCacheInfo>
49
</TileCacheInfos>
50
MapInformation类具体的代码和说明如下:
1
namespace TiledMapDataSource
2

{
3
public class MapInformation : IMapInformation
4
{
5
public MapInformation(string dataSourceDefinition, string resourceDefinition)
6
{
7
this.dataSourceConfig = dataSourceDefinition;
8
resourceConfig = resourceDefinition;
9
//读取对Virtual Earth地图数据的配置定义信心,包括名称、坐标系、图层、各个比例尺等信息
10
parseConfig();
11
}
12
13
private string dataSourceConfig = string.Empty;
14
private string resourceConfig = string.Empty;
15
private SpatialReference defaultSpatialReference = null;
16
private TileCacheInfo tileCacheInfo = null;
17
private Envelope defaultExtent, fullExtent;
18
19
//IMapInformation成员
20
public string DataFrame
21
{
22
get
{ return "(default)"; }
23
}
24
//IMapInformation成员
25
public SpatialReference DefaultSpatialReference
26
{
27
get
{ return defaultSpatialReference; }
28
}
29
//IMapInformation成员
30
public Envelope DefaultExtent
31
{
32
get
33
{
34
return defaultExtent;
35
}
36
}
37
//IMapInformation成员
38
public Envelope FullExtent
39
{
40
get
41
{
42
return fullExtent;
43
}
44
}
45
//IMapInformation成员
46
public ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo TileCacheInfo
47
{
48
get
{ return tileCacheInfo; }
49
set
{ tileCacheInfo = new TileCacheInfo(value); }
50
}
51
52
private void parseConfig()
53
{
54
//读取xml文档
55
XmlDocument doc = new XmlDocument();
56
doc.Load(dataSourceConfig);
57
XmlNode root = doc.DocumentElement;
58
//读取TileCacheInfo节点
59
XmlNodeList tileCacheInfoNodes = root.SelectNodes("TileCacheInfo");
60
if (tileCacheInfoNodes == null || tileCacheInfoNodes.Count < 1)
61
{
62
throw new Exception("Could not find configuration for resource " + resourceConfig);
63
}
64
65
XmlNode tileCacheNode = null;
66
System.Collections.Generic.Dictionary<int, string> tileUrls = new Dictionary<int, string>();
67
System.Collections.Generic.Dictionary<string, string> layers = new Dictionary<string, string>();
68
69
//如果Name节点为resourceConfig
70
for (int t = 0; t < tileCacheInfoNodes.Count; ++t)
71
{
72
if (tileCacheInfoNodes[t].Attributes["Name"].InnerText == resourceConfig)
73
{
74
tileCacheNode = tileCacheInfoNodes[t];
75
break;
76
}
77
}
78
//获取第一个节点
79
if (tileCacheNode == null)
80
{
81
tileCacheNode = tileCacheInfoNodes[0];
82
}
83
//获取SpatialReference节点内容,坐标系统定义字符串
84
string srtext = tileCacheNode.Attributes["SpatialReference"].InnerText;
85
int srid;
86
//设置defaultSpatialReference
87
if (Int32.TryParse(srtext, out srid))
88
{
89
defaultSpatialReference = new SpatialReference(srid);
90
}
91
else
92
{
93
defaultSpatialReference = new SpatialReference(srtext);
94
}
95
96
//获取图片解像度
97
int dpi = Convert.ToInt32(tileCacheNode.Attributes["DPI"].InnerText);
98
//瓦块图的高
99
int height = Convert.ToInt32(tileCacheNode.Attributes["Height"].InnerText);
100
//瓦块图的宽
101
int width = Convert.ToInt32(tileCacheNode.Attributes["Width"].InnerText);
102
//原点坐标
103
string[] originCoords = tileCacheNode.Attributes["TileOrigin"].InnerText.Split(new char[]
{ ',' });
104
//最小x坐标
105
double xmin = Convert.ToDouble(originCoords[0]);
106
//最小y坐标
107
double ymin = Convert.ToDouble(originCoords[1]);
108
//原点
109
Point origin = new Point(xmin, ymin);
110
111
//全图范围
112
XmlNode extentNode = tileCacheNode.SelectSingleNode("FullExtent");
113
xmin = Convert.ToDouble(extentNode.Attributes["XMin"].InnerText);
114
ymin = Convert.ToDouble(extentNode.Attributes["YMin"].InnerText);
115
double xmax = Convert.ToDouble(extentNode.Attributes["XMax"].InnerText);
116
double ymax = Convert.ToDouble(extentNode.Attributes["YMax"].InnerText);
117
fullExtent = new Envelope(xmin, ymin, xmax, ymax);
118
fullExtent.SpatialReference = defaultSpatialReference;
119
120
//默认显示范围
121
extentNode = tileCacheNode.SelectSingleNode("DefaultExtent");
122
xmin = Convert.ToDouble(extentNode.Attributes["XMin"].InnerText);
123
ymin = Convert.ToDouble(extentNode.Attributes["YMin"].InnerText);
124
xmax = Convert.ToDouble(extentNode.Attributes["XMax"].InnerText);
125
ymax = Convert.ToDouble(extentNode.Attributes["YMax"].InnerText);
126
defaultExtent = new Envelope(xmin, ymin, xmax, ymax);
127
defaultExtent.SpatialReference = defaultSpatialReference;
128
129
//获取图层id和名称
130
XmlNode layersNode = tileCacheNode.SelectSingleNode("Layers");
131
if (layersNode != null)
132
{
133
XmlNodeList layerNodes = layersNode.SelectNodes("Layer");
134
if (layerNodes != null)
135
{
136
for (int l = 0; l < layerNodes.Count; ++l)
137
{
138
string layerId = layerNodes[l].Attributes["LayerID"].InnerText;
139
string layerName = layerNodes[l].Attributes["Name"].InnerText;
140
layers.Add(layerId, layerName);
141
}
142
}
143
}
144
145
//获取各个比例尺的信息
146
System.Collections.Generic.List<LodInfo> lodInfos = new List<LodInfo>();
147
System.Collections.Generic.Dictionary<int, int> levels = new Dictionary<int, int>();
148
XmlNode lodInfoNode = tileCacheNode.SelectSingleNode("LodInfos");
149
XmlNodeList lodInfoNodes = lodInfoNode.SelectNodes("LodInfo");
150
for (int l = 0; l < lodInfoNodes.Count; ++l)
151
{
152
int levelid = Convert.ToInt32(lodInfoNodes[l].Attributes["LevelID"].InnerText);
153
levels.Add(l, levelid);
154
//瓦片图行数量
155
int rows = Convert.ToInt32(lodInfoNodes[l].Attributes["Rows"].InnerText);
156
//瓦片图列数量
157
int columns = Convert.ToInt32(lodInfoNodes[l].Attributes["Columns"].InnerText);
158
//瓦片图路径
159
string tileUrl = lodInfoNodes[l].Attributes["TileUrl"].InnerText;
160
//瓦片图地理宽度
161
double tilewidth = Convert.ToDouble(lodInfoNodes[l].Attributes["TileExtentWidth"].InnerText);
162
//瓦片图地理高度
163
double tileheight = Convert.ToDouble(lodInfoNodes[l].Attributes["TileExtentHeight"].InnerText);
164
//比例尺
165
double scale = Convert.ToDouble(lodInfoNodes[l].Attributes["Scale"].InnerText);
166
//分辨率
167
double resolution = Convert.ToDouble(lodInfoNodes[l].Attributes["Resolution"].InnerText);
168
LodInfo lodInfo = new LodInfo(levelid, resolution, scale, columns, rows, tilewidth, tileheight);
169
lodInfos.Add(lodInfo);
170
tileUrls.Add(levelid, tileUrl);
171
}
172
173
//设置TileCacheInfo
174
tileCacheInfo = new TileCacheInfo(width, height,dpi, origin, lodInfos.ToArray());
175
tileCacheInfo.TileUrls = tileUrls;
176
tileCacheInfo.Layers = layers;
177
tileCacheInfo.Levels = levels;
178
179
//获取Virtual Earth瓦块图片路径处理类的Assembly和名称
180
XmlNode urlGenNode = tileCacheNode.SelectSingleNode("TileUrlGenerator");
181
if (urlGenNode != null)
182
{
183
tileCacheInfo.TileUrlGeneratorAssembly =urlGenNode.Attributes["Assembly"].InnerText;
184
tileCacheInfo.TileUrlGeneratorClass =urlGenNode.Attributes["Class"].InnerText;
185
}
186
187
}
188
}
189
}
190
TileCacheInfo.cs类代码:
1
namespace TiledMapDataSource
2

{
3
public class TileCacheInfo : ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo
4
{
5
public TileCacheInfo(int width, int height, int dpi, Point origin, LodInfo[] lodInfos): base(width, height, dpi, origin, lodInfos)
6
{ }
7
public TileCacheInfo(ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo tci): base(tci.Width, tci.Height, tci.Dpi, tci.Origin, tci.LodInfos)
8
{ }
9
internal System.Collections.Generic.Dictionary<int, int> Levels = new Dictionary<int, int>();
10
internal System.Collections.Generic.Dictionary<int, string> TileUrls = new Dictionary<int, string>();
11
internal System.Collections.Generic.Dictionary<string, string> Layers = new Dictionary<string, string>();
12
internal string TileUrlGeneratorAssembly;
13
internal string TileUrlGeneratorClass;
14
}
15
}
16
7.MapResource类和(九、一)例子差不多了这里不详细说明了,具体的可以看Common_CustomDataSourceCSharp.zip的源代码,与上例不同的地方是这个Resource实现了TileFunctionality,因为本来的Virtual Earth地图数据源是切成小块的瓦块图,所以需要实现TileFunctionality,关于TileFunctionality的具体代码和说明如下:
1
namespace TiledMapDataSource
2

{
3
class TileFunctionality : ITileFunctionality
4
{
5
ITileFunctionality 成员#region ITileFunctionality 成员
6
private string serviceUrl;
7
TileCacheInfo _tileCacheInfo = null;
8
9
public TileFunctionality(string name, MapResource resource, TileCacheInfo tileCacheInfo)
10
{
11
this.name = name;
12
this.resource = resource;
13
_tileCacheInfo = tileCacheInfo;
14
}
15
16
17
//ITileFunctionality 成员
18
public ESRI.ArcGIS.ADF.Web.MapImage Draw(string mapFunctionalityName, long column, long row, int level)
19
{
20
int realLevel = _tileCacheInfo.Levels[level];
21
string baseUrl = _tileCacheInfo.TileUrls[realLevel];
22
if (string.IsNullOrEmpty(_tileCacheInfo.TileUrlGeneratorAssembly) || string.IsNullOrEmpty(_tileCacheInfo.TileUrlGeneratorClass))
23
{
24
return null;
25
}
26
//通过getInstanceOfType方法实例化VirtualEarthTileUrlGenerator类,根据VirtualEarthTileUrlGenerator类的Assembly和Class名进行实例化
27
//VirtualEarthTileUrlGenerator类的Assembly和Class配置在VirtualEarth_original.xml中
28
//VirtualEarthTileUrlGenerator类实现了ITileUrlGenerator接口
29
//VirtualEarthTileUrlGenerator类是VirtualEarth的瓦块图片路径处理类
30
ITileUrlGenerator urlGen = getInstanceOfType(_tileCacheInfo.TileUrlGeneratorAssembly,_tileCacheInfo.TileUrlGeneratorClass) as ITileUrlGenerator;
31
if (urlGen == null)
32
{
33
return null;
34
}
35
36
MapFunctionality mapFunc = GetMapFunctionality(mapFunctionalityName);
37
if (mapFunc == null)
38
{
39
throw new ArgumentException("mapFunctionalityName");
40
}
41
//获取瓦块图的路径
42
serviceUrl = urlGen.GetTileUrl(column, row, realLevel, baseUrl, mapFunc.LayerVisibility);
43
return new ESRI.ArcGIS.ADF.Web.MapImage(serviceUrl, null);
44
}
45
46
//ITileFunctionality 成员,地图图片格式
47
public ESRI.ArcGIS.ADF.Web.WebImageFormat ImageFormat
48
{
49
get
{ return WebImageFormat.JPG; }
50
}
51
52
//ITileFunctionality 成员
53
public string ServiceUrl
54
{
55
get
{ return serviceUrl; }
56
}
57
58
//ITileFunctionality 成员
59
public string UrlGeneratorJSFunction
60
{
61
get
{ return null; }
62
}
63
64
#endregion
65
66
IGISFunctionality 成员#region IGISFunctionality 成员
67
private string name = string.Empty;
68
IGISResource resource = null;
69
System.Web.UI.WebControls.WebControl _webControl;
70
bool _initialized = false;
71
72
public void Dispose()
73
{
74
_initialized = false;
75
}
76
77
public void Initialize()
78
{
79
_initialized = true;
80
}
81
82
public bool Initialized
83
{
84
get
{ return _initialized; }
85
}
86
87
public void LoadState()
88
{
89
90
}
91
92
public string Name
93
{
94
get
95
{
96
return this.name;
97
}
98
set
99
{
100
this.name = value;
101
}
102
}
103
104
public IGISResource Resource
105
{
106
get
107
{
108
return this.resource;
109
}
110
set
111
{
112
this.resource = value;
113
}
114
}
115
116
public void SaveState()
117
{
118
119
}
120
121
public bool Supports(string operation)
122
{
123
return true;
124
}
125
126
public System.Web.UI.WebControls.WebControl WebControl
127
{
128
get
{ return _webControl; }
129
set
{ _webControl = value; }
130
}
131
132
#endregion
133
134
private MapFunctionality GetMapFunctionality(string name)
135
{
136
MapFunctionality mapFunctionality = resource.Functionalities.Find(name) as MapFunctionality;
137
return mapFunctionality;
138
}
139
140
private object getInstanceOfType(string assemblyName, string type)
141
{
142
object o = null;
143
try
144
{
145
System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(assemblyName);
146
o = assembly.CreateInstance(type);
147
}
148
catch (Exception e)
149
{
150
string mess = e.Message;
151
}
152
return o;
153
}
154
}
155
}
156
8.在TileFunctionality类中有用到ITileUrlGenerator接口,新建ITileUrlGenerator.cs文件,代码如下:
1
namespace TiledMapDataSource
2

{
3
public interface ITileUrlGenerator
4
{
5
//获取瓦块图路径的的方法
6
string GetTileUrl(long column, long row, int level, string defaultUrl, Dictionary<string, bool> layerVisibility);
7
}
8
}
9.在TileFunctionality类中有用到VirtualEarthTileUrlGenerator类,它实现了ITileUrlGenerator接口。VirtualEarthTileUrlGenerator方法是获取Virtual Earth的图片,所以有必要对VirtualEarth的图片算法进行了解,看如下的参考资料:
卫星图和微软普通地图瓦片算法是一样的,区别在于卫星图要是a或者h开头,而微普通地图则是r开头,服务器地址不同下面举例:
http://a1.ortho.tiles.virtualearth.net/tiles/a1322111.jpeg?g=1 这是不带label的微软卫星图
http://h1.ortho.tiles.virtualearth.net/tiles/h1322111.jpeg?g=1 这是带label(如显示省份、地市)的微软卫星图
http://r1.tiles.ditu.live.com/tiles/r1322111.png?g=1 这微软普通地图
看到http://后面,红色的a、h、r分别代表不带label卫星图、带label卫星图、微软普通地图。
10.有了上面的资料后就能知道如何取地图图片了,新建VirtualEarthTileUrlGenerator.cs文件,代码如下:
1
namespace TiledMapDataSource
2

{
3
public class VirtualEarthTileUrlGenerator : ITileUrlGenerator
4
{
5
ITileUrlGenerator Members#region ITileUrlGenerator Members
6
//获取瓦块图路径
7
public string GetTileUrl(long column, long row, int level, string defaultUrl, Dictionary<string, bool> layerVisibility)
8
{
9
return GetUrl(Convert.ToInt32(column), Convert.ToInt32(row), level, layerVisibility);
10
}
11
12
#endregion
13
14
//获取瓦块图路径,参数:瓦块列值,瓦块的行值,比例等级,可视图层
15
private string GetUrl(int column, int row, int level, Dictionary<string, bool> layerVisibility)
16
{
17
string mapType = null;
18
string mapExtension = null;
19
//如果同时包括Road图层和Aerial图层
20
if (layerVisibility["r"] && layerVisibility["a"])
21
{
22
mapType = "h";
23
mapExtension = ".jpeg";
24
}
25
//只包括Road图层
26
else if (layerVisibility["r"])
27
{
28
mapType = "r";
29
mapExtension = ".png";
30
}
31
//只包括Aerial图层
32
else if (layerVisibility["a"])
33
{
34
mapType = "a";
35
mapExtension = ".jpeg";
36
}
37
else
38
{
39
return null;
40
}
41
42
string quadKey = TileToQuadKey(column, row, level);
43
44
string url = String.Concat(new object[]
{ "http://", mapType, quadKey[quadKey.Length - 1], ".ortho.tiles.virtualearth.net/tiles/", mapType, quadKey, mapExtension, "?g=", 1 });
45
return url;
46
}
47
48
//Virtual Earth图片名称的算法
49
private static string TileToQuadKey(int tx, int ty, int zl)
50
{
51
string quad = "";
52
for (int i = zl; i > 0; i--)
53
{
54
int mask = 1 << (i - 1);
55
int cell = 0;
56
if ((tx & mask) != 0)
57
{
58
cell++;
59
}
60
if ((ty & mask) != 0)
61
{
62
cell += 2;
63
}
64
quad += cell;
65
}
66
return quad;
67
}
68
}
69
}
11.剩下的MapFunctionality.cs和MapTocFunctionality.cs和上例类似比较简单了不做详细解释,具体参考Common_CustomDataSourceCSharp.zip的源代码。
12.这样自定义数据源完成了,接下在就是测试这个数据源,在CustomDataSource的ASP.NET Web应用程序的Default_TileMapData.aspx页面中添加Map1、MapResourceManager1、Toc13个控件,然后做相应的设置,具体设置可以参考前面的文章。
13.接下来在MapResourceManager1中在Server Resource上面在新增加名为Virtual Earth,在弹出的Map Resource Definition Editor中Type:选择TiledMap就是上面添加到DotNet文件内的ESRI.ArcGIS.ADF.Web.DataSources.TiledMap.config中定义的名字,在Data Source:输入上面的那个xml的地址,如:D:\VirtualEarth_original.xml,然后确定就完成了设置。这里的Data Source为了方便是输入的方式了,最好的做法可以参考Common_CustomDataSourceCSharp.zip样例为它做一个xml文件选择界面,具体的参考CustomDataSource_CSharp\REXMLDataSource_CSharp\Design\DataSourceDefinitionEditorFormREXML.cs,是一个Winform的选择节目,只有在config文件配置一下,就可以在 Map Resource Definition Editor中调用自己定制的编辑器。
14.运行查看效果,这样成功的把Virtual Earth的卫星图片显示在我们的页面中了。