gpt4 book ai didi

.net - Google Maps Static API - 通过中心坐标获取西南和东北

转载 作者:行者123 更新时间:2023-12-02 02:50:36 25 4
gpt4 key购买 nike

我正在使用 .NET 使用静态 map 从 Google map 加载 map 图 block 。

我遇到的问题是我不知道返回图像的西南坐标和东北坐标。

我发现了许多不同的代码示例、公式,但它们似乎都有缺陷。这是最接近正确答案的一个。当我在 Google map 中输入坐标时,它显示位置有点偏差。

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();
}
}

来源:
How to get bounds of a google static map?
http://www.easywms.com/easywms/?q=zh-hans/node/3612

按中心坐标加载图像:
http://maps.googleapis.com/maps/api/staticmap?center=51.15479,4.79635&zoom=20&size=512x512&sensor=false

软件故障:
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:
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

最佳答案

编辑:哇,我刚刚意识到这个问题已经快两年了。对此感到抱歉。

好的,我认为这里发生了一些事情。最重要的是,您没有进行您提供的链接中提到的墨卡托投影。您可以使用code sample来查看它的运行情况。在谷歌地图 API 文档中。我认为你有点接近的原因是缩放级别 20 时比例因子太大,以至于掩盖了问题的细节。

要获取边界,您需要获取中心纬度/经度,将其转换为像素坐标,添加/减去以获得所需角点的像素坐标,然后转换回纬度/经度。第一个链接中的代码可以进行投影和逆投影。下面我将其翻译成c#。

在上面的解决方案中,您采用纬度/经度坐标并添加/减去世界坐标(像素坐标/比例),因此您组合了两个不同的坐标系。

我在尝试解决这个问题时遇到的一个问题是您的坐标类有点令人困惑。希望我没有倒退,但看起来你正在倒退纬度和经度。这很重要,因为除其他原因外,墨卡托投影在每个方向上都不同。您的 X/Y 映射似乎也是向后的,因为纬度是您的北/南位置,这应该是投影时的 Y 坐标,而经度是您的东/西位置,这应该是投影时的 X 坐标。

要找到边界,three coordinate systems需要:经度/纬度、世界坐标和像素坐标。过程是中心纬度/经度 -(墨卡托投影)-> 中心世界坐标 -> 中心像素坐标 -> NE/SW 像素坐标 -> NE/SW 世界坐标 -(逆墨卡托投影)-> NE/SW 纬度/经度。

您可以通过添加/减去图像/2的尺寸来找到像素坐标。不过,像素坐标系从左上角开始,因此要获得东北角,您需要从 x 中添加宽度/2,并从 y 中减去高度/2。对于西南角,您需要从 x 中减去宽度/2,并将高度/2 添加到 y。

这里是 C# 中的投影代码(作为 GoogleMapsAPI 类的一部分),来自上面第一个 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代码以获取更详细的注释。

我通过手动近似边界然后与代码给出的答案进行比较来测试它。我对 NE 角的手动近似值是 (51.15501, 4.796695),代码吐出 (51.155005..., 4.797038...)这看起来很接近。 SW角近似为(51.154572, 4.796007),代码吐出(51.154574..., 4.796006...) .

这是一件有趣的事情,我希望这会有所帮助!

编辑:意识到我没有包含新的 GetBounds 函数:

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 };
}

请记住确保您的纬度和经度正确无误:

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

我知道代码不是最好的,但我希望它是清晰的。

关于.net - Google Maps Static API - 通过中心坐标获取西南和东北,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12688092/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com