用silverlight制作自己的GIS

用silverlight制作自己的GIS

看了笨鸟的一篇文章:

基于DeepZoom技术的Bing Maps客户端实现研究

地址:http://www.cnblogs.com/beniao/archive/2010/05/21/1740480.html

 

感觉大家都可以实现自己的GIS

这一篇文章会基本的讲一下如何通过silverlight实现封装自己的GIS,原理就是笨鸟那一篇文章的介绍

主要是用了silverlight的MultiScaleImage组件

<Grid x:Name="LayoutRoot" Background="White">  
 <MultiScaleImage x:Name="msi"/>
</Grid>

 

下一步就要给msi加载地图源

这就要实现自己的Tile,把我自己的Tile贴出来

 

 

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;
using System.Collections.Generic;
namespace MyMap
{
public abstract class MySelfTileSource : MultiScaleTileSource
{
/*
imageWidth
类型:System.Int32
Deep Zoom 图像的宽度。
imageHeight
类型:System.Int32
Deep Zoom 图像的高度。
tileWidth
类型:System.Int32
Deep Zoom 图像中图块的宽度。
tileHeight
类型:System.Int32
Deep Zoom 图像中图块的高度。
tileOverlap
类型:System.Int32
Deep Zoom 图像中图块的重叠程度。
*/
protected MySelfTileSource()
:
base(int.MaxValue, int.MaxValue, 256, 256, 0)
{ }
/// <summary>
/// 地图的Tile映射地址
/// </summary>
public abstract string UriFormat { get; }

/// <summary>
/// 转换X,Y坐标值为地图的QuadKey参数值
/// </summary>
/// <param name="tileX"></param>
/// <param name="tileY"></param>
/// <param name="levelOfDetail"></param>
/// <returns></returns>
private static string TileXYToQuadKey(int tileX, int tileY, int levelOfDetail)
{
var quadKey
= new StringBuilder();
for (int i = levelOfDetail; i > 0; i--)
{
char digit = '0';
int mask = 1 << (i - 1);
if ((tileX & mask) != 0)
{
digit
++;
}
if ((tileY & mask) != 0)
{
digit
++;
digit
++;
}
quadKey.Append(digit);
}
return quadKey.ToString();
}

/// <summary>
/// 图层Tile算法
/// </summary>
/// <param name="tileLevel">缩放级别</param>
/// <param name="tilePositionX">X坐标</param>
/// <param name="tilePositionY">Y坐标</param>
/// <param name="tileImageLayerSources">图层源集合</param>
protected override void GetTileLayers(int tileLevel, int tilePositionX, int tilePositionY, IList<object> tileImageLayerSources)
{
int zoom = tileLevel - 8;
if (zoom > 0)
{
string QuadKey = TileXYToQuadKey(tilePositionX, tilePositionY, zoom);
string veLink = string.Format(UriFormat, new object[] { QuadKey[QuadKey.Length - 1], QuadKey });
var veUri
= new Uri(veLink);
tileImageLayerSources.Add(veUri);
}
}
}
}

 

 

 

 

 

图块默认大小是256*256,当然你也可以改变其大小,比如自己的切图是320*320,只需要把两个256改为320就可以

以下是自己的Tile

 

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace MyMap
{
public class BingMapsRoadTileSource : MySelfTileSource
{
string url = "";
public BingMapsRoadTileSource(string str)
{
url
= str;
}
public override string UriFormat
{
get { return "http://mt{0}.google.com/vt/lyrs=m@116&hl=zh-CN&x={1}&y={2}&z={3}&s="; }// "http://khm{0}.google.com/kh/v=47&x={1}&y={2}&z={3}"; } // "http://r{0}.ortho.tiles.virtualearth.net/tiles/r{1}.png?g=203"; }
}
/// <summary>
/// 图层Tile算法
/// </summary>
/// <param name="tileLevel">缩放级别</param>
/// <param name="tilePositionX">X坐标</param>
/// <param name="tilePositionY">Y坐标</param>
/// <param name="tileImageLayerSources">图层源集合</param>
/*google 地图
protected override void GetTileLayers(int tileLevel, int tilePositionX, int tilePositionY, IList<object> tileImageLayerSources)
{
int zoom = tileLevel - 8;
if (zoom > 0)
{
string veLink = string.Format(UriFormat, tilePositionX % 4, tilePositionX, tilePositionY, zoom);
var veUri = new Uri(veLink);
tileImageLayerSources.Add(veUri);
}
}
*/
//本地地图
protected override void GetTileLayers(int tileLevel, int tilePositionX, int tilePositionY, IList<object> tileImageLayerSources)
{
string weburl = url;
int zoom = tileLevel -8;

weburl
+= "ClientBin/map/" + zoom + "/" + tilePositionX.ToString("D2") + tilePositionY.ToString("D2") + ".png";
var veUri
= new Uri(weburl);
tileImageLayerSources.Add(veUri);

}
}
}

 

 

 

 

 这个Tile包含了加载google地图,加载自己本地地图的方法

接下来要实现自己的GIS就很容易了.

只要3行代码:

 

var xapUri = Application.Current.Host.Source;
var webUri = new Uri(xapUri, "../");
msi.Source
= new BingMapsRoadTileSource(webUri.ToString());

 

这样就能加载自己的地图了.这需要把本地地图放在ClientBin/map/0,ClientBin/map/1.........之下.

为什么放在这个目录下 这与我自己的Tile有关.

以下加载上事件

 

this.MouseLeftButtonDown += new MouseButtonEventHandler(MainPage_MouseLeftButtonDown);
this.MouseLeftButtonUp += new MouseButtonEventHandler(MainPage_MouseLeftButtonUp);
this.MouseWheel += new MouseWheelEventHandler(MainPage_MouseWheel);
this.MouseEnter += new MouseEventHandler(MainPage_MouseEnter);
this.MouseMove += delegate(object sender, MouseEventArgs e)
{
this.tbcrood.Text = msi.ElementToLogicalPoint(e.GetPosition(msi)).X + " " +
msi.ElementToLogicalPoint(e.GetPosition(msi)).Y
+ " " + msi.ViewportWidth;
//按住左键拖动
if (mouseIsDragging)
{
if (mouseFlag == "")
{
mouseFlag
= "fisrtdown";
currentPosition
= msi.ViewportOrigin;
dragOffset
= new Point(e.GetPosition(msi).X, e.GetPosition(msi).Y);
}
var newOrigin
= new Point();
newOrigin.X
= currentPosition.X -
(((e.GetPosition(msi).X
- dragOffset.X) / msi.ActualWidth) * msi.ViewportWidth);
newOrigin.Y
= currentPosition.Y -
(((e.GetPosition(msi).Y
- dragOffset.Y) / msi.ActualHeight) * msi.ViewportWidth);
msi.ViewportOrigin
= newOrigin;
}
};

 

 

 

 

需要几个全局变量:

 

private Point currentPosition;
        private Point dragOffset;
        private bool mouseIsDragging;
        private string mouseFlag = "";

private Point currentPosition;        private Point dragOffset;        private bool mouseIsDragging;        private string mouseFlag = "";

 

void MainPage_MouseEnter(object sender, MouseEventArgs e)
{
mouseIsDragging
= false;
}


void MainPage_MouseWheel(object sender, MouseWheelEventArgs e)
{
Point mouseP
= msi.ElementToLogicalPoint(e.GetPosition(msi));
if (e.Delta > 0)
{
msi.ZoomAboutLogicalPoint(
1.1, mouseP.X, mouseP.Y);

}
if (e.Delta < 0)
{

msi.ZoomAboutLogicalPoint(
0.5, mouseP.X, mouseP.Y);

}
}

void MainPage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
mouseIsDragging
= false;
mouseFlag
= "";
}

void MainPage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
mouseIsDragging
= true;
}

 

 

 

如果调用google地图,只需要把BingMapsRoadTileSource 类中的google加载方式打开即可.

上面就是如何搭建自己的GIS.

下一章会介绍如何实现添加层 点.线.面等.用坐标系的处理.

 

附上源码:http://www.louningbo.com/download/MyMap.rar

我自己的网站下载可能比较慢.

另 怎么才能在博客源上传附件?

posted on 2010-07-17 11:29  丐帮大侠  阅读(1675)  评论(3编辑  收藏  举报

导航