| 和传统GIS客户端架构有所不同,BMSL同MapMode的方式来控制Map的一些特征,比如更换地图瓦片数据,限定缩放级别,固定平移范围;甚至是控制鼠标键盘事件导航地图的方式,以及地理坐标与像素坐标的映射等。
Map有属性曰Mode,类型为MapMode。MapMode有子类FlatMapMode,FlatMapMode有子类MercatorMode,MercatorMode有两个子类RoadMode和AerialMode。(关系简单,不再图示)
MercatorMode设置了Web Mercator投影的相关投影,RoadMode和AerialMode分别定了Bing Maps的数据类型,以及导航控件等。比如把Map的Mode设置为空的MercatorMode,即可清除Bing Maps数据,替换其中的TileSource,即可更换底图数据。
若要限制显示范围,则要定制自己的MapMode,比如从RoadMode继承,覆盖GetZoomRange限制缩放级别,覆盖ConstrainView限制平移范围。
下文的示例,大致限定在中国经纬度范围内,缩放级别限定在3和10之间,并把底图数据改变为Google卫星地图以及它的地图注记数据(即那些汉字标绘),如何自定义TileSource请参考《在BMSL中使用Google 地图》。
public class ChinaMode : RoadMode { private Range<double> validLatitudeRange = new Range<double>(3.92, 53.51); private Range<double> validLongitudeRange = new Range<double>(73.60, 135.01);
public ChinaMode() : base() { var tileLayer = (MapTileLayer)this.Content; tileLayer.TileSources.Clear(); tileLayer.TileSources.Add(new GoogleSatelliteTileSource()); tileLayer.TileSources.Add(new GoogleLabelTileSource()); }
protected override Range<double> GetZoomRange(Location center) { return new Range<double>(3, 10); }
public override bool ConstrainView(Location center, ref double zoomLevel, ref double heading, ref double pitch) { bool isChanged = base.ConstrainView(center, ref zoomLevel, ref heading, ref pitch); double newLatitude = center.Latitude; double newLongitude = center.Longitude; if (center.Longitude > validLongitudeRange.To) { newLongitude = validLongitudeRange.To; } else if (center.Longitude < validLongitudeRange.From) { newLongitude = validLongitudeRange.From; }
if (center.Latitude > validLatitudeRange.To) { newLatitude = validLatitudeRange.To; } else if (center.Latitude < validLatitudeRange.From) { newLatitude = validLatitudeRange.From; }
if (newLatitude != center.Latitude || newLongitude != center.Longitude) { center.Latitude = newLatitude; center.Longitude = newLongitude; isChanged = true; }
Range<double> range = GetZoomRange(center); if (zoomLevel > range.To) { zoomLevel = range.To; isChanged = true; } else if (zoomLevel < range.From) { zoomLevel = range.From; isChanged = true; }
return isChanged; }
}
|