如何将地理坐标转换为像素?
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 将显示坐标转换为地理坐标(纬度、经度)?