无需外部API即可将GPS坐标放置在地图图像上

时间:2014-10-13 18:23:54

标签: c# gis openstreetmap map-projections mercator

我目前正在制作一个“旅行追踪器”。目标是将一些GPS坐标(由GPS设备记录)放置在从MapQuest(或OpenStreetMap)下载的静态图像映射上。 为了实现这一目标,我遵循以下程序:

  1. 查找我的GPS坐标设置中心((maxLat-minLat)/ 2,(maxLon-minLon)/ 2)
  2. 从MapQuest <我的“坐标集中心”中心下载一张3840x3840地图(现在固定缩放15)
  3. 使用墨卡托投影(我尝试使用EPSG的球形和椭圆形:4326或EPSG:3857),以米为单位得到中心的(X,Y)
  4. 我的集合中的每一点
  5. 使用墨卡托投影获取点(X,Y)
  6. 将点(X,Y)减去中心(X,y)
  7. 根据缩放级别和地图(平铺?)宽度将米转换为像素(我尝试了平铺宽度(256)和地图宽度(3840)
  8. 不幸的是,在为期一周的研究中尝试,我没有成功地提出这一点。

    有没有人有这种问题的完整解决方案?

    谢谢

    编辑#1

    (删除:不一致)

    编辑#2

    这是一个干净的项目样本

    https://dl.dropboxusercontent.com/u/429726/MapSample.zip

    • 路径旋转90°(欺骗@ MainWindow.xaml.cs:L130)
    • 路径扁平化

    图: https://dl.dropboxusercontent.com/u/429726/MapSample.jpg

    编辑#3

    添加了多个公式

    GeographicCoordinates&gt; ToMercator()修改

    public System.Windows.Point ToMercator(int test = 0)
    {
        System.Windows.Point mercator;
        double x = this.Longitude.ToMercator(test);
        double y = this.Latitude.ToMercator(test);
        mercator = new System.Windows.Point(x, y);
        return mercator;
    }
    

    GeographicCoordinate&gt; ToMercator()修改

    public double ToMercator(int test = 0)
    {
        double result = 0;
        switch (this.Type)
        {
            case(GeographicCoordinateType.Longitude):
                switch (test) { 
                    case 0:
                        return this.DecimalDegrees.ToRadians() * Maps.EarthGreatRadius;
                    case 1:
                        //http://jackofalltradesdeveloper.blogspot.be/2012/03/how-to-project-point-from-geography-to.html
                        return this.DecimalDegrees * 0.017453292519943 * 6378137;
                    case 2:
                        //http://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/
                        return this.DecimalDegrees * 20037508.34 / 180;
                }
                break;
            case(GeographicCoordinateType.Latitude):
                switch (test)
                {
                    case 0:
                        double latitude = this.DecimalDegrees;
                        if (latitude > 89.5)
                        {
                            latitude = 89.5;
                        }
                        if (latitude < -89.5)
                        {
                            latitude = -89.5;
                        }
                        double temp = Maps.EarthGreatRadius / Maps.EarthGreatRadius;
                        double es = 1.0 - (temp * temp);
                        double eccent = Math.Sqrt(es);
                        double phi = latitude.ToRadians();
                        double sinphi = Math.Sin(phi);
                        double con = eccent * sinphi;
                        double com = 0.5 * eccent;
                        con = Math.Pow((1.0 - con) / (1.0 + con), com);
                        double ts = Math.Tan(0.5 * ((Math.PI * 0.5) - phi)) / con;
                        double y = 0 - Maps.EarthGreatRadius * Math.Log(ts);
                        return y;
                    case 1:
                        double FSin = Math.Sin(this.DecimalDegrees.ToRadians());
                        return 6378137 / 2.0 * Math.Log((1.0 + FSin) / (1.0 - FSin));
                    case 2:
                        y  = Math.Log(Math.Tan((90 + this.DecimalDegrees) * Math.PI / 360)) / (Math.PI / 180);
                        return y * 20037508.34 / 180;
                }
                break;
            default:
                throw new Exception();
        }
        return result;
    }
    

    编辑#4

    我尝试了倍数公式和&amp; Proj.Net库,我总是以相同的形状(-90°&amp;&amp;“flatened”)

3 个答案:

答案 0 :(得分:0)

地图坐标也需要转换为墨卡托。您需要地图的delta x和delta y以及图像属性:Convert lat/lon to pixel coordinate?

答案 1 :(得分:0)

我过去曾使用它来在Windows窗体客户端上的地图上构建信息:

http://greatmaps.codeplex.com/

答案 2 :(得分:0)

以下是答案

GeographicCoordinates&gt; ToMercator()

public System.Windows.Point ToMercator(int test = 0)
{
    System.Windows.Point mercator;
    double x = this.Longitude.ToMercator(test);
    double y = this.Latitude.ToMercator(test);
    mercator = new System.Windows.Point(x, y);
    return mercator;
}

应该是

public System.Windows.Point ToMercator(int test = 0)
{
    System.Windows.Point mercator;
    double x = this.Latitude.ToMercator(test);
    double y = this.Longitude.ToMercator(test);
    mercator = new System.Windows.Point(x, y);
    return mercator;
}

和 GeographicCoordinate&gt; ToMercator() 应该交换GeographicCoordinateType.Latitude / Longitude案例。

我还必须根据半球来修复Y

&安培;工作已经完成。