zoukankan      html  css  js  c++  java
  • SharpMap学习10比例尺

    看了SharpMap的比例尺相关代码,看的是一知半解,主要原因在于代码中的Zoom和以往对比例尺的概念联系不上,但是代码的意思,我想应该是一个坐标系(也就是地理坐标,或者叫WordView)到窗口坐标的转换吧。这个似乎在图形编程的时候经常用到,自己理解不是很深刻,那就将就着写点感悟吧。

    地理坐标系下是笛卡尔坐标系

    image 而屏幕坐标系:image

    假设地理坐标系下,也就是现实中一个点如下左图示,要转为屏幕点(右侧图)显示,就需要通过比例转换得到:

    image

    具体转换公式很简单,分别处理X,Y即可。简单实践代码如下,首先定义一个显示的点集合:

    public class Geometry
    {
    private List<PointF> points;
    public List<PointF> Points
    {
    get
    {
    return points;
    }
    }

    public Geometry()
    {
    this.points = new List<PointF>();
    }

    public void ReadData()
    {
    PointF pt;

    pt = new PointF(13183368.7f, 3836485.263f);
    points.Add(pt);

    pt = new PointF(13183709.796f, 3785207.202f);
    points.Add(pt);

    pt = new PointF(13206335.814f, 3784297.613f);
    points.Add(pt);

    pt = new PointF(13210770.059f, 3802716.783f);
    points.Add(pt);

    pt = new PointF(13230667.311f, 3803398.975f);
    points.Add(pt);

    pt = new PointF(13231804.297f, 3820453.762f);
    points.Add(pt);

    pt = new PointF(13206790.608f, 3839327.727f);
    points.Add(pt);
    }

    public Geometry Colon()
    {
    Geometry geometry = new Geometry();
    foreach (PointF ptItem in this.points)
    {
    geometry.points.Add(ptItem);
    }
    return geometry;
    }
    }

    然后类似定义一个Map对象

    class Map
    {
    private int imgWidth;
    private int imgHeight;

    public int ImgWidth
    {
    get
    {
    return imgWidth;
    }
    set
    {
    imgWidth = value;
    }
    }

    public int ImgHeight
    {
    get
    {
    return imgHeight;
    }
    set
    {
    imgHeight = value;
    }
    }

    private float zoomScale;
    public float ZoomScale
    {
    get
    {
    return zoomScale;
    }
    set
    {
    if (value < 1)
    return;
    zoomScale = value;
    }
    }

    public Map(int imgWidth,int imgHeight)
    {
    this.imgWidth = imgWidth;
    this.imgHeight = imgHeight;

    this.zoomScale = 100.0f;

    this.data = new Geometry();
    data.ReadData();
    }

    private Geometry data = null;

    public PointF GetCenter()
    {
    PointF resultPt = new PointF();
    if (this.data != null)
    {
    BoundingBox box = Utility.GetEnvolope(this.data.Points);
    resultPt.X = (box.MinX + box.MaxX) / 2.0f;
    resultPt.Y = (box.MinY + box.MaxY) / 2.0f;
    }
    return resultPt;
    }

    public void GetLineMap(Graphics g)
    {
    Geometry lineGeo = data.Colon();
    for (int i = 0; i < lineGeo.Points.Count; i++)
    {
    lineGeo.Points[i] = Utility.WordToImage(lineGeo.Points[i], this);
    }

    GraphicsPath gpPath = new GraphicsPath();
    gpPath.AddLines(lineGeo.Points.ToArray());

    g.DrawPath(linePen, gpPath);
    }

    public void GetRegionMap(Graphics g)
    {
    Geometry regionGeo = data.Colon();
    for (int i = 0; i < regionGeo.Points.Count; i++)
    {
    regionGeo.Points[i] = Utility.WordToImage(regionGeo.Points[i], this);
    }

    GraphicsPath gpPath = new GraphicsPath();
    gpPath.AddPolygon(regionGeo.Points.ToArray());

    g.FillPath(regionBrush, gpPath);
    }

    private Pen linePen = new Pen(Color.Red, 3);
    private Brush regionBrush = new SolidBrush(Color.FromArgb(120, Color.Blue));

    public float GetExtentZoomScale()
    {
    if (this.data != null)
    {
    return Utility.GetEnvolope(this.data.Points).BoundingWidth;
    }
    else
    {
    return 0;
    }
    }
    }

    在绘制前,首先要遍历每一个点,将其从地理坐标转为窗口坐标,以下是具体的转换函数:

    public static PointF WordToImage(PointF wordPt, Map map)
    {
    PointF imgPt = new PointF();
    float wordHeight = map.ZoomScale * (float)map.ImgHeight / (float)map.ImgWidth;

    float wordLeft = map.GetCenter().X - map.ZoomScale * 0.5f;
    float wordTop = map.GetCenter().Y + wordHeight * 0.5f;

    imgPt.X = (wordPt.X - wordLeft) / map.ZoomScale * map.ImgWidth;
    imgPt.Y = (wordTop - wordPt.Y) / wordHeight * map.ImgHeight;

    return imgPt;
    }

    解释下,Map对象的ZoomScale是作为“比例尺”的“比例”概念存在的,按照一些博文中的解释,是作为地理坐标显示范围的宽度处理的,也就是说地理显示范围(真实范围)的宽度=ZoomScale,通过它和窗口中高、宽比再求得地理显示范围的高,从而进行转换操作的。SharpMap中还涉及到其他的参数处理,不过我觉得大概意思应该是这样的吧。

    最终效果:

    image改变比例尺:image        image

  • 相关阅读:
    jQuery Event.delegateTarget 属性详解
    velocity 判断 变量 是否不是空或empty
    触碰jQuery:AJAX异步详解
    jQuery Select操作大集合
    常用元素默认margin和padding值问题探讨
    九大排序算法再总结
    八大排序算法
    JavaScript中toStirng()与Object.prototype.toString.call()方法浅谈
    使用CSS3的appearance属性改变元素的外观
    CSS清浮动处理(Clear与BFC)
  • 原文地址:https://www.cnblogs.com/sharpfeng/p/2075553.html
Copyright © 2011-2022 走看看