C# 在没有外部API的地图图像上放置GPS坐标

C# 在没有外部API的地图图像上放置GPS坐标,c#,gis,openstreetmap,map-projections,mercator,C#,Gis,Openstreetmap,Map Projections,Mercator,我现在正在做一个旅行跟踪器。目标是将GPS设备记录的一些GPS坐标放置在从MapQuest或OpenStreetMap下载的静态图像地图上。 为了实现这一目标,我遵循以下程序: 查找我的GPS坐标集的中心maxLat minLat/2,maxLon minLon/2 从MapQuest下载3840x3840地图固定缩放15,现在以我的坐标集的中心为中心 使用墨卡托投影,我尝试使用EPSG:4326或EPSG:3857的球面和椭圆投影,得到中心的X,Y,单位为米 对于我集合中的每个点 使用墨卡托投

我现在正在做一个旅行跟踪器。目标是将GPS设备记录的一些GPS坐标放置在从MapQuest或OpenStreetMap下载的静态图像地图上。 为了实现这一目标,我遵循以下程序:

查找我的GPS坐标集的中心maxLat minLat/2,maxLon minLon/2 从MapQuest下载3840x3840地图固定缩放15,现在以我的坐标集的中心为中心 使用墨卡托投影,我尝试使用EPSG:4326或EPSG:3857的球面和椭圆投影,得到中心的X,Y,单位为米 对于我集合中的每个点 使用墨卡托投影获得点的X,Y 将点X,Y减去中心X,Y 根据缩放级别和贴图平铺将米转换为像素?宽度我尝试了瓦片宽度256和贴图宽度3840 不幸的是,在一周的研究和尝试中,我没有成功地提出这些观点

有人能完全解决这类问题吗

多谢各位

编辑1 删除:不一致

编辑2 这是一个干净的项目示例

路径在MainWindow.xaml.cs:L130处旋转90° 这条路是平坦的 Img:

编辑3 添加了多个公式

地理坐标>计算器修改

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 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;
}
地理坐标>计算器修改

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 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
我尝试过多次公式和Proj.Net库,我总是以相同的形状结束-90°&平坦

地图坐标也需要转换为墨卡托。您需要地图的delta x和delta y以及图像属性:。

我过去曾在Windows窗体客户端上使用它在地图上生成信息:

这是答案

地理坐标>自动计算器

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;
}
及 地理坐标>ToMercator 应交换地理坐标类型。纬度/经度大小写

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


&这项工作已经完成。

如果您正在寻找一个完整的解决方案,那么您所处的位置是错误的。你需要展示你已经尝试过的东西,最好是一些代码。你在OSM维基上读过吗?我读过滑动贴图块名称doc&与缩放级别相关的一个。我将提供一些代码,以便向您展示我尝试过的一些方法。