2016-05-03 1 views
2

Je vais avoir un problème à obtenir les limites de mon Google Static Map dans mon application Unity. J'ai essayé plusieurs réponses trouvées ici sur stackoverflow.Obtenez coins SW & NE de l'API Google Static Maps

.NET related question

Javascript related question

La carte que je suis en train de calculer les angles pour est this un.

D'abord j'ai essayé de traduire marcelo son code de javascript en C#. Ce qui est traduit dans la classe suivante. Donc, au début, j'ai essayé seulement d'obtenir le coin sud-ouest de la carte et c'est assez proche, mais c'est un peu loin.

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

a moi envoyé this résultat. Depuis tant de gens ont voté d'abord J'ai essayé de traduire marcelo sa réponse jusqu'à je me suis dit que j'ai fait quelque chose de mal lors de la traduction du code en C# marcelo Je suis tombé sur peterjb's answer qui a déjà fait la traduction de la réponse javascript à C# et a même donné des exemples où son code a obtenu les bonnes limites d'une carte statique Google. Donc, après avoir essayé le code de peterjb dans la classe suivante;

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

J'ai essayé de calculer les angles SW et NE nouveau en appelant les éléments suivants

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

Sortie:

SouthWest: 51,438825, 5,453483 NorthEast: 51,452557, 5,467153

Les coordonnées SouthWest sont les mêmes que ma propre traduction du javascript. Donc, puisque peterjb a prétendu dans sa réponse que sa solution fonctionnait pour une certaine zone en Belgique, j'ai essayé le code sur la même zone. Cependant, le résultat était encore un peu loin. Donc, tout à fait au hasard, j'ai essayé d'utiliser le calcul pour une ville au Nigeria nommé Kano/Static map et à ma grande surprise, le coin SouthWest était extrêmement précis!

Sortie:

SouthWest: 12,015251, 8,527824 NorthEast: 12,028983, 8,541404

SouthWest position.

J'ai essayé plusieurs autres domaines dans le monde par la suite, mais il était souvent loin et parfois même des centaines de miles. Alors peut-être que cette ville au Nigeria était juste une coïncidence, mais j'espère que quelqu'un a une explication et/ou une solution pour moi.

Un grand merci à peterjb et marcelo

+0

Information associée: https://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/ –

+0

Salut Leniaal, je pense que le problème est que vos coordonnées le constructeur prend les paramètres comme lng, lat mais vous passez dans lat, lng. L'exemple de Kano s'est probablement rapproché parce que le lat et le lng sont presque les mêmes. J'espère que cela aide, laissez-moi savoir si ce n'est pas encore tout à fait là. – peterjb

+0

Hey @peterjb merci pour votre temps et votre intérêt. Tu as raison, je ne peux pas croire que j'ai oublié ça. Je suis très content que tu l'aies remarqué parce que je regardais fixement le problème, merci beaucoup! Vous pouvez l'ajouter comme réponse si vous le souhaitez afin que je puisse répondre à cette question. – Leniaal

Répondre

0

Le constructeur de Coordinate classe accepte (lng, lat) au lieu de (lat, lng) comme on pouvait s'y attendre, de sorte que les paramètres sont dans un autre ordre que vous passez dans

J'ai également remarqué que l'override de ToString de Coordinate s'imprime également en tant que (lng, lat), donc cela peut prêter à confusion si vous vous attendez à voir (lat, lng).

Échangez simplement les deux dans l'API statique.