谷歌地图API静态 - 获取SW和NE由中心坐标 [英] Google Maps Static API - Get SW and NE by center coordinate

查看:695
本文介绍了谷歌地图API静态 - 获取SW和NE由中心坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是从谷歌地图使用静态地图加载地图图块,使用.NET。

I'm loading map tiles from Google Maps using Static Maps, using .NET.

我遇到的问题是,我不知道是什么SW和NE坐标返回的形象。

The problem I'm having is that I don't know what the SW and NE coordinates are of the returned image.

我发现很多不同的code样品,公式,但他们似乎都存在缺陷。
这是得到了最靠近正确答案的那个。当我在谷歌地图中输入坐标这表明,这是一点点了。

I've found many different code samples, formulas, but they all seem to be flawed. This is the one that got closest to the correct answer. When I entered the coordinates in Google Maps it showed that it was a little bit off.

var result = GoogleMapsAPI.GetBounds(new Coordinate(4.79635, 51.15479), 20, 512, 512);

public static class GoogleMapsAPI
{
    public static MapCoordinates GetBounds(Coordinate center, int zoom, int mapWidth, int mapHeight)
    {
        var scale = Math.Pow(2, zoom);

        var SWPoint = new Coordinate(center.X - (mapWidth / 2) / scale, center.Y - (mapHeight / 2) / scale);
        var NEPoint = new Coordinate(center.X + (mapWidth / 2) / scale, center.Y + (mapHeight / 2) / scale);

        return new MapCoordinates() { SouthWest = SWPoint, NorthEast = NEPoint };
    }
}

public class MapCoordinates
{
    public Coordinate SouthWest { get; set; }
    public Coordinate NorthEast { get; set; }
}

public class Coordinate
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }

    public double X { get { return Latitude; } set { Latitude = value; } }
    public double Y { get { return Longitude; } set { Longitude = value; } }

    public Coordinate(double lat, double lng)
    {
        Latitude = lat;
        Longitude = lng;
    }

    public override string ToString()
    {
        return X.ToString() + ", " + Y.ToString();
    }
}

来源:

如何获得谷歌静态地图的界限?

<一href=\"http://www.easywms.com/easywms/?q=zh-hans/node/3612\">http://www.easywms.com/easywms/?q=zh-hans/node/3612

由中心加载图像坐标:

<一href=\"http://maps.googleapis.com/maps/api/staticmap?center=51.15479,4.79635&zoom=20&size=512x512&sensor=false\">http://maps.googleapis.com/maps/api/staticmap?center=51.15479,4.79635&zoom=20&size=512x512&sensor=false

故障南方周末:

<一href=\"https://maps.google.be/maps?q=51.154545859375,+4.796105859375&hl=en&ll=51.154763,4.796695&spn=0.000568,0.001635&sll=51.154687,4.796838&sspn=0.001136,0.00327&t=m&z=20\">https://maps.google.be/maps?q=51.154545859375,+4.796105859375&hl=en&ll=51.154763,4.796695&spn=0.000568,0.001635&sll=51.154687,4.796838&sspn=0.001136,0.00327&t=m&z=20

NE故障:

<一href=\"https://maps.google.be/maps?q=+51.155034140625,+4.796594140625&hl=en&ll=51.154764,4.796684&spn=0.000568,0.001635&sll=51.154599,4.796723&sspn=0.001136,0.00327&t=m&z=20\">https://maps.google.be/maps?q=+51.155034140625,+4.796594140625&hl=en&ll=51.154764,4.796684&spn=0.000568,0.001635&sll=51.154599,4.796723&sspn=0.001136,0.00327&t=m&z=20

推荐答案

编辑:哇,我才意识到这个问题几乎是两岁。我们对此深感抱歉。

Wow, I just realized this question is almost two years old. Sorry about that.

行,所以我认为有几件事情怎么回事。最重要的是你是不是在做你提供的链接中提到的墨卡托投影。您可以使用 code样品看到它在行动在谷歌地图API文档。我觉得你越来越有点接近的原因是,比例因子是缩放级别为20,它淹没了该问题的细节如此之大。

OK so I think there are a few things going on here. The most important is that you aren't doing the Mercator projection mentioned in the links you provided. You can see it in action with a code sample in the google maps API docs. I think the reason you are getting somewhat close is that the scale factor is so large at zoom level 20 that it drowns out the details of the problem.

要得到的界限,你需要采取纬度中心/经度,将其转换为像素坐标,加/减,以获得您想要的角的像素坐标,然后再转换回经/纬度。在第一个链接的code可以做投影和投影反。下面,我把它翻译成C#。

To get the bounds, you need to take the center lat/lon, convert it to pixel coordinates, add/subtract to get the pixel coordinates of the corners that you want, and then convert back to lat/lon. The code in the first link can do the projection and inverse projection. Below I've translated it into c#.

在你上面的解决方案,你正在服用的纬度/经度坐标和加法/减法世界坐标(像素COORDS /缩放),所以你结合两个不同的坐标系。

In your solution above, you are taking lat/lon coordinates and adding/subtracting world coordinates (pixel coords / scale), so you are combining two different coordinate systems.

我跑进试图弄清楚这一点的一个问题是,你的坐标类是有点混乱。希望我没有这个倒退,但它看起来像你的经度和纬度将倒退。这是重要的,因为墨卡托投影是在每个方向上,除其他原因不同。你的X / Y映射似乎倒退,也因为纬度是你的南/北的位置,这应该是投影时的Y坐标,以及经度就是你东/西的位置,这应该是投影时的X坐标。

An issue I ran into while trying to figure this out is that your Coordinate class is a little confusing. Hopefully I don't have this backwards, but it looks like you are putting in the latitude and longitude backwards. This is important because the Mercator projection is different in each direction, among other reasons. Your X/Y mapping seems backwards, too, because Latitude is your North/South position, which should be the Y coordinate when projected, and Longitude is you East/West position, which should be the X coordinate when projected.

要查找的范围,三个坐标需要系统:经度/纬度,世界坐标和像素坐标。这个过程是中心纬度/经度 - (墨卡托投影) - >中心世界坐标 - >中心像素坐标 - > NE / SW像素坐标 - > NE / SW世界坐标 - (逆墨卡托投影) - > NE / SW纬度/经度。

To find the bounds, three coordinate systems are needed: Longitude/Latitude, World Coordinates and Pixel Coordinates. The process is Center Lat/Lon -(Mercator Projection)-> Center World Coordinates -> Center Pixel Coordinates -> NE/SW Pixel Coordinates -> NE/SW World Coordinates -(Inverse Mercator Projection)-> NE/SW Lat/Lon.

您找到像素由加/减影像/ 2的尺寸坐标。像素坐标系统从左上角开始,虽然,所以要得到你需要添加宽度/ 2 x和选自Y减去高度/ 2东北角。对于SW角落,你需要减去宽/ 2 x和添加高度/ 2为y。

You find the pixel coordinates by adding/subtracting the dimensions of the image/2. The pixel coordinate system starts from the upper left corner though, so to get the NE corner you need to add width/2 from x and subtract height/2 from y. For the SW corner you need to subtract width/2 from x and add height/2 to y.

下面是投影code(如您的GoogleMapsAPI类的一部分)在C#中,从上面的javascript第一链接转换:

Here's the projection code (as part of your GoogleMapsAPI class) in c#, translation from the first link above javascript:

static GoogleMapsAPI()
{
    OriginX =  TileSize / 2;
    OriginY =  TileSize / 2;
    PixelsPerLonDegree = TileSize / 360.0;
    PixelsPerLonRadian = TileSize / (2 * Math.PI);
}

public static int TileSize = 256;
public static double OriginX, OriginY;
public static double PixelsPerLonDegree;
public static double PixelsPerLonRadian;

public static double DegreesToRadians(double deg)
{
    return deg * Math.PI / 180.0;
}

public static double RadiansToDegrees(double rads)
{
    return rads * 180.0 / Math.PI;
}

public static double Bound(double value, double min, double max)
{
    value = Math.Min(value, max);
    return Math.Max(value, min);       
}

//From Lat, Lon to World Coordinate X, Y. I'm being explicit in assigning to
//X and Y properties.
public static Coordinate Mercator(double latitude, double longitude)
{
    double siny = Bound(Math.Sin(DegreesToRadians(latitude)), -.9999, .9999);

    Coordinate c = new Coordinate(0,0);
    c.X = OriginX + longitude*PixelsPerLonDegree;
    c.Y = OriginY + .5 * Math.Log((1 + siny) / (1 - siny)) * -PixelsPerLonRadian;

    return c;
}

//From World Coordinate X, Y to Lat, Lon. I'm being explicit in assigning to
//Latitude and Longitude properties.
public static Coordinate InverseMercator(double x, double y)
{      
    Coordinate c = new Coordinate(0, 0);

    c.Longitude = (x - OriginX) / PixelsPerLonDegree;
    double latRadians = (y - OriginY) / -PixelsPerLonRadian;
    c.Latitude = RadiansToDegrees(Math.Atan(Math.Sinh(latRadians)));

    return c;
}

您可以检查原始的javascript code更详细的评论。

You can check the original javascript code for more detailed comments.

我测试了它通过手动逼近边界,然后比较到code给出了答案。我对东北角手动近似为(51.15501,4.796695)和code吐出<一个href=\"https://www.google.be/maps/place/51%C2%B009%2718.0%22N+4%C2%B047%2748.1%22E/@51.1548343,4.7965149,20z/data=!4m2!3m1!1s0x0:0x0?hl=en\"相对=nofollow>(51.155005 ...,4.797038 ......)这似乎是pretty接近。西南角近似是(51.154572,4.796007),code吐出<一个href=\"https://www.google.be/maps/place/51%C2%B009%2716.5%22N+4%C2%B047%2745.6%22E/@51.1547262,4.7964934,20z/data=!4m2!3m1!1s0x0:0x0?hl=en\"相对=nofollow>(51.154574 ...,4.796006 ......)。

I tested it out by manually approximating the boundaries and then comparing to the answer the code gave. My manual approximations for the NE corner was (51.15501, 4.796695) and the code spit out (51.155005..., 4.797038...) which seems pretty close. SW corner approximate was (51.154572, 4.796007), code spit out (51.154574..., 4.796006...).

这是一个有趣的一个,我希望这可以帮助!

This was a fun one, I hope this helps!

编辑:意识到我并没有包含新的的getBounds 功能:

Realized I didn't include the new GetBounds function:

public static MapCoordinates GetBounds(Coordinate center, int zoom, int mapWidth, int mapHeight)
{
    var scale = Math.Pow(2, zoom);

    var centerWorld = Mercator(center.Latitude, center.Longitude);
    var centerPixel = new Coordinate(0, 0);
    centerPixel.X = centerWorld.X * scale;
    centerPixel.Y = centerWorld.Y * scale;

    var NEPixel = new Coordinate(0, 0);
    NEPixel.X = centerPixel.X + mapWidth / 2.0;
    NEPixel.Y = centerPixel.Y - mapHeight / 2.0;

    var SWPixel = new Coordinate(0, 0);
    SWPixel.X = centerPixel.X - mapWidth / 2.0;
    SWPixel.Y = centerPixel.Y + mapHeight / 2.0;

    var NEWorld = new Coordinate(0, 0);
    NEWorld.X = NEPixel.X / scale;
    NEWorld.Y = NEPixel.Y / scale;

    var SWWorld = new Coordinate(0, 0);
    SWWorld.X = SWPixel.X / scale;
    SWWorld.Y = SWPixel.Y / scale;

    var NELatLon = InverseMercator(NEWorld.X, NEWorld.Y);
    var SWLatLon = InverseMercator(SWWorld.X, SWWorld.Y);

    return new MapCoordinates() { NorthEast = NELatLon, SouthWest = SWLatLon };
}

请记住,以确保你有经度和纬度有正确的:

Just remember to make sure you've got the Latitude and Longitude in there right:

var result = GoogleMapsAPI.GetBounds(new Coordinate(51.15479, 4.79635), 20, 512, 512);

我知道code是不是最大的,但我希望这是显而易见的。

I know the code is not the greatest, but I hope it is clear.

这篇关于谷歌地图API静态 - 获取SW和NE由中心坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆