如何将地理坐标转换为像素?

Posted

技术标签:

【中文标题】如何将地理坐标转换为像素?【英文标题】:How to convert geographical coordinates to pixels? 【发布时间】:2012-10-05 06:58:38 【问题描述】:

我正在开发 wpf 应用程序。我有一张 500 宽和 500 高的静态世界地图。我的申请中有一张表格。在此来自用户输入纬度和经度并提交详细信息。我想在我的静态地图上显示这些纬度和经度的确切位置。所以我试图将这些纬度和经度转换为像素。我正在使用椭圆在我的静态地图上显示圆圈。我应该如何将地理坐标转换为 C# 中的像素?您能否提供我可以解决上述问题的任何代码或链接?我的问题类似于链接

Convert long/lat to pixel x/y on a given picture

我发现这个链接很有用。

编辑: 我已经使用了链接

http://code.google.com/p/geographical-dot-net/source/browse/trunk/GeographicalDotNet/GeographicalDotNet/Projection/GoogleMapsAPIProjection.cs

并编写了以下代码

GoogleMapsAPIProjection googleApiProjObj = new GoogleMapsAPIProjection(0);
            float x = 18.29F;
            float y = 73.57F;
            System.Drawing.PointF p1 = new System.Drawing.PointF(x,y);
            System.Drawing.PointF p2 =googleApiProjObj.FromCoordinatesToPixel(p1);

            //CircleEllipse.Margin = new Thickness(longitudePixels,latitudePixels, 0, 0);
            CircleEllipse.Margin = new Thickness(p2.X, p2.Y, 0, 0);
            CircleEllipse.Visibility = Visibility.Visible;

18.29 和 73.57 是印度浦那市的纬度和日志。在上面的代码中 p2.x 给我 141 和 p2.y 给我 49。所以上面的代码没有显示我在地图上的浦那位置。我的xaml代码如下

<ScrollViewer HorizontalScrollBarVisibility="Auto" Grid.Row="4" Width="500" Height="500" Background="Gray">
            <Grid>
                <Image Margin="0,0,0,0" x:Name="MapImage" Source="Images\World-Blank-Map.png" Stretch="Fill" Width="500" Height="500" ></Image>
                <Ellipse Canvas.Top="50" 
      Canvas.Left="50" 
      Fill="Red" 
      Height="5"
      Width="5"
      Visibility="Collapsed"
      StrokeThickness="4"                     

      x:Name="CircleEllipse"
      HorizontalAlignment="Left"
      VerticalAlignment="Top"
      Margin="0,0,0,0" />
            </Grid>
        </ScrollViewer>

【问题讨论】:

我正在尝试使用链接中@Jader Dias 建议的 C# 代码 您的“静态世界地图”使用什么投影?是谷歌静态地图吗? 你好@Mercelo。我的地图使用墨卡托投影 一些信息仍然缺失。使用墨卡托投影的标准 Google 地图将整个世界包含在一个 256 x 256 像素而不是 500 x 500 像素的地图图块中。您的“静态世界地图”是如何达到这个尺寸的? @Marcelo 你是对的。我拍摄了 256*256 的谷歌地图图像。现在一切正常。它显示给定纬度和经度的正确位置。 【参考方案1】:

你提供了自己的答案,看看下面的代码

http://code.google.com/p/geographical-dot-net/source/browse/trunk/GeographicalDotNet/GeographicalDotNet/Projection/GoogleMapsAPIProjection.cs

public class GoogleMapsAPIProjection

    private readonly double PixelTileSize = 256d;
    private readonly double DegreesToRadiansRatio = 180d / Math.PI;
    private readonly double RadiansToDegreesRatio = Math.PI / 180d;
    private readonly PointF PixelGlobeCenter;
    private readonly double XPixelsToDegreesRatio;
    private readonly double YPixelsToRadiansRatio;

    public GoogleMapsAPIProjection(double zoomLevel)
    
        var pixelGlobeSize = this.PixelTileSize * Math.Pow(2d, zoomLevel);
        this.XPixelsToDegreesRatio = pixelGlobeSize / 360d;
        this.YPixelsToRadiansRatio = pixelGlobeSize / (2d * Math.PI);
        var halfPixelGlobeSize = Convert.ToSingle(pixelGlobeSize / 2d);
        this.PixelGlobeCenter = new PointF(
            halfPixelGlobeSize, halfPixelGlobeSize);
    

    public PointF FromCoordinatesToPixel(PointF coordinates)
    
        var x = Math.Round(this.PixelGlobeCenter.X
            + (coordinates.X * this.XPixelsToDegreesRatio));
        var f = Math.Min(
            Math.Max(
                 Math.Sin(coordinates.Y * RadiansToDegreesRatio),
                -0.9999d),
            0.9999d);
        var y = Math.Round(this.PixelGlobeCenter.Y + .5d * 
            Math.Log((1d + f) / (1d - f)) * -this.YPixelsToRadiansRatio);
        return new PointF(Convert.ToSingle(x), Convert.ToSingle(y));
    

    public PointF FromPixelToCoordinates(PointF pixel)
    
        var longitude = (pixel.X - this.PixelGlobeCenter.X) /
            this.XPixelsToDegreesRatio;
        var latitude = (2 * Math.Atan(Math.Exp(
            (pixel.Y - this.PixelGlobeCenter.Y) / -this.YPixelsToRadiansRatio))
            - Math.PI / 2) * DegreesToRadiansRatio;
        return new PointF(
            Convert.ToSingle(latitude),
            Convert.ToSingle(longitude));
    

【讨论】:

嗨@Marcelo。我更新了我的问题?你能告诉我哪里出错了 我已经完成了 GoogleMapsAPIProjection 类的复制和粘贴。我们是否需要在 GoogleMapsAPIProjection 类的任何地方指定地图的宽度和高度?我是否需要对 GoogleMapsAPIProjection 类进行任何更改?【参考方案2】:

我为 Google 地图发布了我的 api Mercator Projection。 ;-) 你有三个类:

常量 PointCoordinates:纬度和经度。

PointPixel:谷歌地图第 0 级的 x,y。

您可以将 PointPixel 从/转换为 PointCoordinates

public static class PointUtils

    public const double MercatorGoogleHeight = 256;
    public const double MercatorGoogleWidth = 256;
    public const double PixelLongintudeOrigin = MercatorGoogleWidth / 2;
    public const double PixelLatitudeOrigin = MercatorGoogleHeight / 2;
    public const double PixelsPerLongintudeDegre = MercatorGoogleWidth / 360;
    public const double RadsPerLatitudeDegre = MercatorGoogleHeight / (2 * Math.PI);


/// <summary>
/// Point Pixel on Mercator Google Zoom 0
/// </summary>
public class PointPixel

    public double X  get; set; 
    public double Y  get; set; 

    public PointCoordinates ToPointCoordinates()
    
        var lng = (X - PointUtils.PixelLongintudeOrigin) / PointUtils.PixelsPerLongintudeDegre;
        var latRad = (Y - PointUtils.PixelLatitudeOrigin)/-PointUtils.RadsPerLatitudeDegre;
        var lat = (2*Math.Atan(Math.Exp(latRad)) - Math.PI/2).RadToDeg();
        return new PointCoordinates()
            
                Latitude = lat,
                Longitude = lng
            ;
    



/// <summary>
/// Point on Map World
/// </summary>
public class PointCoordinates


    public double Latitude  get; set; 
    public double Longitude  get; set; 

    public PointPixel ToPointPixel()
    
        var x = PointUtils.PixelLongintudeOrigin + PointUtils.PixelsPerLongintudeDegre * Longitude;
        var siny = Math.Sin(Latitude.DegToRad());
        var y = PointUtils.PixelLatitudeOrigin - (Math.Log((1 + siny) / (1 - siny)) / 2) * PointUtils.RadsPerLatitudeDegre;
        return new PointPixel()  X = x, Y = y ;

    



【讨论】:

以上是关于如何将地理坐标转换为像素?的主要内容,如果未能解决你的问题,请参考以下文章

将平铺坐标转换为像素到地理坐标

如何使用 cartopy 将显示坐标转换为地理坐标(纬度、经度)?

如何将像素位置转换为 GPS 点?

iOS 如何在 2015 年将地址转换为 GPS 坐标(地理编码)?

将地理坐标转换为地址 C# 或 jQuery

如何把地理位置的经纬度坐标转换为unity3d的系统坐标