1

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

在给定图片上将 long/lat 转换为像素 x/y

我发现这个链接很有用。

编辑:我已经使用了链接

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。所以上面的代码没有显示我在地图上的浦那位置。我的xml代码如下

<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>
4

2 回答 2

2

您提供了自己的答案,请查看以下代码

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));
    }
}
于 2012-10-05T07:40:03.423 回答
0

我为谷歌地图发布了我的 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 };

    }


}
于 2014-04-01T11:14:35.687 回答