【问题标题】:Place GPS coordinates on a map image without external API无需外部 API 在地图图像上放置 GPS 坐标
【发布时间】:2014-10-13 18:23:54
【问题描述】:

我目前正在开发“旅行跟踪器”。目标是将一些 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)

不幸的是,在一周的研究和尝试中,我没有成功地提出这些观点。

有人对这类问题有完整的解决方案吗?

谢谢

编辑#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 > 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 > 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

我尝试过多个公式和 Proj.Net 库,我总是得到相同的形状(-90° &&“扁平化”)

【问题讨论】:

  • 如果您正在寻找一个完整的解决方案,那么您来错地方了。您需要展示您尝试过的内容,最好使用一些代码。
  • 你读过 OSM wiki 中的slippy map tilenames 吗?
  • 我确实阅读了滑动地图图块名称文档和与缩放级别相关的文档。我将提供一些代码,以便向您展示我尝试过的一些方法。

标签: c# gis openstreetmap map-projections mercator


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    http://greatmaps.codeplex.com/

    【讨论】:

      【解决方案3】:

      这就是答案

      地理坐标> 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;
      }
      

      并且 地理坐标 > ToMercator() 应该交换 GeographicCoordinateType.Latitude/Longitude 大小写。

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

      &工作已经完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-11
        • 1970-01-01
        • 2013-04-06
        • 1970-01-01
        • 2013-01-14
        • 1970-01-01
        • 2020-11-10
        相关资源
        最近更新 更多