获取SW和放大器;谷歌静态地图API的NE角落 [英] Get SW & NE corners of Google Static Maps API

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

问题描述

我遇到了让我的谷歌静态地图的界限在我的Unity应用的一个问题。我试图在这里找到计算器上多个答案。

I'm having a problem with getting the bounds of my Google Static Map in my Unity application. I've tried multiple answers found here on stackoverflow.

扣除相关问题

我试图计算角落是的这个中有一个

The map I'm trying to calculate the corners for is this one.

首先,我试着翻译马塞洛他从JavaScript代码为C#。 。这是翻译成下面的类

First I tried translating marcelo his code from javascript to C#. Which is translated into the following class.

using System;
using UnityEngine;
public class MercatorProjection
{
    static double MERCATOR_RANGE = 256;
    Point pixelsOrigin;
    double pixelsPerLonDegree;
    double pixelsPerLonRadian;

    public MercatorProjection()
    {
        pixelsOrigin = new Point(MERCATOR_RANGE / 2, MERCATOR_RANGE / 2);
        pixelsPerLonDegree = MERCATOR_RANGE / 360;
        pixelsPerLonRadian = MERCATOR_RANGE / (2 * Math.PI);
    }

    double bound(double value, double opt_min, double opt_max)
    {
        if (opt_min != 0)
            value = Math.Max(value, opt_min);
        if (opt_max != 0)
            value = Math.Min(value, opt_max);
        return value;
    }

    double degreesToRadians(double deg)
    {
        return deg * (Math.PI / 180);
    }

    double radiansToDegrees(double rad)
    {
        return rad / (Math.PI / 180);
    }

    Point fromLatLonToPoint(Coordinates latLon)
    {
        Point point = new Point();
        Point origin = pixelsOrigin;

        point.X = origin.X + latLon.Longitude * pixelsPerLonDegree;

        double sinY = bound(Math.Sin(degreesToRadians(latLon.Latitude)), -0.9999, 0.9999);

        point.Y = origin.Y + 0.5 * Math.Log((1 + sinY) / (1 - sinY)) * -pixelsPerLonRadian;

        return point;
    }

    Coordinates fromPointToLatlon(Point point)
    {
        Point origin = pixelsOrigin;
        Coordinates latLon = new Coordinates();

        latLon.Latitude = (point.X - origin.X) / pixelsPerLonDegree;
        double latRadians = (point.Y - origin.Y) / -pixelsPerLonRadian;
        latLon.Longitude = radiansToDegrees(2 * Math.Atan(Math.Exp(latRadians)) - Math.PI / 2);

        return latLon;
    }

    public void GetCorners(Coordinates center, float zoom, float mapWidth, float mapHeight)
    {
        double scale = Math.Pow(2, zoom);
        Point centerPx = fromLatLonToPoint(center);
        Point SWPoint = new Point(centerPx.X - (mapWidth / 2) / scale, centerPx.Y + (mapHeight / 2) / scale);
        Coordinates SWLatLon = fromPointToLatlon(SWPoint);
        Debug.Log(SWLatLon.Latitude + " " + SWLatLon.Longitude + " " + SWPoint.X + " " + SWPoint.Y);
    }
}



所以刚开始我试过只获得西南角地图和它的相当接近,但它是一个有点过。

So at first I tried only getting the South West corner of the map and it's pretty close, but it's a bit off.

MercatorProjection.GetCorners(new Coordinates(Coordinates.Longitude, Coordinates.Latitude), 16, 640, 640);



给我带来的结果。

既然这么多人投票开始我尝试翻译马塞洛的他的回答了,我想我做了一些代码到C#的翻译过程中错

Since so many people voted First I tried translating marcelo his answer up I figured I did something wrong during the translation of the code to C#.

比我遇到的peterjb's回答谁已经做的JavaScript答案C#的翻译,甚至给了例子,他的代码得到了谷歌静态地图的右侧边界。因此,在下面的类试图 peterjb 的代码后;

Than I stumbled across peterjb's answer who already did the translation of the javascript answer to C# and even gave examples where his code got the right bounds of a Google static map. So after trying peterjb's code in the following class;

using System;

public static class GoogleMapsAPI{

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

    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 };
    }
}
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 Y { get { return Latitude; } set { Latitude = value; } }
    public double X { get { return Longitude; } set { Longitude = value; } }

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

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



我通过调用试图计算SW和NE角落再次以下

I tried calculating the SW and NE corners again by calling the following

Coordinates = new Coordinate(51.445691, 5.460318);
var result = GoogleMapsAPI.GetBounds(Coordinates, 16, 640, 640);
Debug.Log("SouthWest: "+result.SouthWest.ToString() + " NorthEast: "+result.NorthEast.ToString());



输出:

Output:

西南:51.438825,5.453483东北地区:51.452557,5.467153

SouthWest: 51.438825, 5.453483 NorthEast: 51.452557, 5.467153

西南坐标是完全一样的我自己的JavaScript翻译。如此以来,在peterjb他的回答声称,他的解决方案为在比利时一定区域内,我试图在同一区域的代码。然而,结果又被相当多的关

The SouthWest coordinates are the exact same as my own translation of the javascript. So since peterjb claimed in his answer that his solution worked for a certain area in Belgium, I tried the code on the same area. However, the result again was quite a bit off.

所以很随意我使用计算名为在尼日利亚的一个小镇的卡诺 /的静态地图让我吃惊,西南角是非常精确的

So quite randomly I tried using the calculation for a town in Nigeria named Kano / Static map and to my surprise, the SouthWest corner was extremely accurate!

输出:

西南:12.015251,8.527824东北地区:12.028983 ,8.541404

SouthWest: 12.015251, 8.527824 NorthEast: 12.028983, 8.541404

西南位置

我试过其他多个地区的世界之后,但它往往是遥远,有时甚至数百英里。所以,也许这个镇在尼日利亚只是一个巧合,但我希望有人给我一个解释和/或解决方案。

I've tried multiple other area's in the world afterwards, but it often was way off and sometimes even hundreds of miles. So maybe this town in Nigeria was just an coincidence, but I'm hoping someone has an explanation and/or solution for me.

特别感谢 peterjb 并的马塞洛

推荐答案

为坐标的构造类接受(LNG,纬度),而不是(纬度,经度)如你所料,这样的参数在不同的顺序比你传递

The constructor for Coordinate class accepts (lng, lat) instead of (lat, lng) as you might expect, so the parameters are in a different order than you are passing in.

我也注意到,协调的ToString覆盖打印件(LNG,LAT)为好,因此它可能会造成混乱,如果你希望看到(纬度,经度)。

I also noticed that Coordinate's ToString override prints as (lng, lat) as well, so it could be confusing if you expect to see (lat, lng).

只需在交换这两个静态API。

Simply swap both of these in the static API.

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

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