【问题标题】:Get lat and lng from google using Unity WWW class使用 Unity WWW 类从谷歌获取 lat 和 lng
【发布时间】:2016-06-21 20:59:31
【问题描述】:

我正在尝试在 Unity 中使用来自 google 的地理服务。我是这样做的:

WWW www = new WWW("https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&oe=utf-8&key="+googleKey);
yield return www;

if (!string.IsNullOrEmpty(www.error)){
    print(www.error);
} else {
    var newobject = JsonConvert.DeserializeObject(www.text);
    print ("Object: " + newobject);
}

这部分工作正常,我得到了我想要的结果......但知道我只需要从结果中得到纬度和经度,但不知道该怎么做?

这是我从谷歌得到的结果:

{
  "results": [
    {
      "address_components": [
        {
          "long_name": "1600",
          "short_name": "1600",
          "types": [
            "street_number"
          ]
        },
        {
          "long_name": "Amphitheatre Parkway",
          "short_name": "Amphitheatre Pkwy",
          "types": [
            "route"
          ]
        },
        {
          "long_name": "Mountain View",
          "short_name": "Mountain View",
          "types": [
            "locality",
            "political"
          ]
        },
        {
          "long_name": "Santa Clara County",
          "short_name": "Santa Clara County",
          "types": [
            "administrative_area_level_2",
            "political"
          ]
        },
        {
          "long_name": "California",
          "short_name": "CA",
          "types": [
            "administrative_area_level_1",
            "political"
          ]
        },
        {
          "long_name": "United States",
          "short_name": "US",
          "types": [
            "country",
            "political"
          ]
        },
        {
          "long_name": "94043",
          "short_name": "94043",
          "types": [
            "postal_code"
          ]
        }
      ],
      "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
      "geometry": {
        "location": {
          "lat": 37.422364,
          "lng": -122.084364
        },
        "location_type": "ROOFTOP",
        "viewport": {
          "northeast": {
            "lat": 37.4237129802915,
            "lng": -122.0830150197085
          },
          "southwest": {
            "lat": 37.421015019708513,
            "lng": -122.0857129802915
          }
        }
      },
      "place_id": "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
      "types": [
        "street_address"
      ]
    }
  ],
  "status": "OK"
}

我想我需要去这个:

"geometry": {
        "location": {
          "lat": 37.422364,
          "lng": -122.084364
        },

但是我该怎么做呢?

任何帮助表示赞赏并提前感谢:-)

【问题讨论】:

    标签: c# json google-maps unity3d


    【解决方案1】:

    我想我需要去这个:

    "geometry": {
        "location": {
          "lat": 37.422364,
          "lng": -122.084364
        },
    

    你是对的。您需要 Json 中的 geometry 对象。我以前使用过 Google 的 API 来取回对象。

    您需要在 C# 中创建一些类,这些类映射到 Json 对象的相同/相关属性。然后您可以使用 JsonConvert 将您的 Json 字符串转换回一些 C# 对象 -http://www.newtonsoft.com/json/help/html/t_newtonsoft_json_jsonconvert.htm

    http://json2csharp.com/ 是一个很好用的工具,它允许您粘贴 Json 代码,并在另一端获取一些可识别的 C# 类。

    显然,您可以删除任何您绝对不需要的属性。

    您的最终结果应如下所示(复制/粘贴到/来自 json2csharp.com):

    public class AddressComponent
    {
        public string long_name { get; set; }
        public string short_name { get; set; }
        public List<string> types { get; set; }
    }
    
    public class Location
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }
    
    public class Northeast
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }
    
    public class Southwest
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }
    
    public class Viewport
    {
        public Northeast northeast { get; set; }
        public Southwest southwest { get; set; }
    }
    
    public class Geometry
    {
        public Location location { get; set; }
        public string location_type { get; set; }
        public Viewport viewport { get; set; }
    }
    
    public class Result
    {
        public List<AddressComponent> address_components { get; set; }
        public string formatted_address { get; set; }
        public Geometry geometry { get; set; }
        public string place_id { get; set; }
        public List<string> types { get; set; }
    }
    
    public class RootObject
    {
        public List<Result> results { get; set; }
        public string status { get; set; }
    }
    

    然后使用 JsonConvert 创建一些对象,你可以这样做:

    RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(www.text);
    

    然后,您可以通过遍历 Results 中的 Geometry 对象(或访问 .First())等来访问它们。

    像这样:

    foreach (var resultObject in rootObject.results)
    {
        var geometry = resultObject.geometry;
        var location = geometry.location;
        var lat = location.lat;
        var lng = location.lng
    }
    

    为了收拾东西,你还可以重命名一些属性,让它们更“友好”,然后用一个属性装饰它们,这样 JsonConvert 仍然知道要映射哪个 Json 属性。

    像这样:

    [JsonProperty(PropertyName = "a_json_property")]
    public string ACSharpProperty { get; set; }
    

    有任何问题,请告诉我。

    希望这会有所帮助! :)

    【讨论】:

    • 嗨 Geoff,由于某种原因,我无法完成这项工作:-/ 我不确定如何处理 geometryObject 以及如何从中获取 lat 和 lng。不过,我已经完成了另一个示例。
    • 哎呀!完全是我的错 - 我将Geometry 卡在我的脑海中作为最后的游戏。您需要先反序列化为 Result 对象,然后从 resultObject.Geometry 访问属性,依此类推。我已经为你更新了我的答案:)
    • 哦,是的,但现在我在这一行出现错误:var location = geometry.location;
    • 我明白了。只需输入代码(我之前是盲目的)来检查 - 我意识到您需要先从您的 Json 创建一个 RootObject,然后遍历 rootObject.results 中的项目以获得结果。更新了我的答案以反映这一点 - 它现在是经过尝试和测试的工作代码:)
    • 完美...谢谢 :-) 你拯救了我的一天(y)
    【解决方案2】:

    您需要创建一个数据结构来存储 Json 数据。使用 Unity 的 JsonUtility.FromJson,您可以提取 json 数据并将其存储到该数据结构中。

    请记住,由于 results 是 array/list,因此您必须遍历它才能获取所有值。您必须从每个类中删除{ get; set; },并且还必须在每个类的顶部包含[System.Serializable]。只要您拥有 Unity 5.3 及更高版本,就不需要外部 API 来执行此操作。这是一个经过测试的完整解决方案。

    [System.Serializable]
    public class AddressComponent
    {
        public string long_name;
        public string short_name;
        public List<string> types;
    }
    [System.Serializable]
    public class Location
    {
        public double lat;
        public double lng;
    }
    [System.Serializable]
    public class Northeast
    {
        public double lat;
        public double lng;
    }
    [System.Serializable]
    public class Southwest
    {
        public double lat;
        public double lng;
    }
    [System.Serializable]
    public class Viewport
    {
        public Northeast northeast;
        public Southwest southwest;
    }
    [System.Serializable]
    public class Geometry
    {
        public Location location;
        public string location_type;
        public Viewport viewport;
    }
    [System.Serializable]
    public class Result
    {
        public List<AddressComponent> address_components;
        public string formatted_address;
        public Geometry geometry;
        public string place_id;
        public List<string> types;
    }
    [System.Serializable]
    public class GoogleJson
    {
        public List<Result> results;
        public string status;
    }
    

    并使用它:

    void Start()
    {
        //Replace value with what you got from WWW
        string value = "{\r\n  \"results\": [\r\n    {\r\n      \"address_components\": [\r\n        {\r\n          \"long_name\": \"1600\",\r\n          \"short_name\": \"1600\",\r\n          \"types\": [\r\n            \"street_number\"\r\n          ]\r\n        },\r\n        {\r\n          \"long_name\": \"Amphitheatre Parkway\",\r\n          \"short_name\": \"Amphitheatre Pkwy\",\r\n          \"types\": [\r\n            \"route\"\r\n          ]\r\n        },\r\n        {\r\n          \"long_name\": \"Mountain View\",\r\n          \"short_name\": \"Mountain View\",\r\n          \"types\": [\r\n            \"locality\",\r\n            \"political\"\r\n          ]\r\n        },\r\n        {\r\n          \"long_name\": \"Santa Clara County\",\r\n          \"short_name\": \"Santa Clara County\",\r\n          \"types\": [\r\n            \"administrative_area_level_2\",\r\n            \"political\"\r\n          ]\r\n        },\r\n        {\r\n          \"long_name\": \"California\",\r\n          \"short_name\": \"CA\",\r\n          \"types\": [\r\n            \"administrative_area_level_1\",\r\n            \"political\"\r\n          ]\r\n        },\r\n        {\r\n          \"long_name\": \"United States\",\r\n          \"short_name\": \"US\",\r\n          \"types\": [\r\n            \"country\",\r\n            \"political\"\r\n          ]\r\n        },\r\n        {\r\n          \"long_name\": \"94043\",\r\n          \"short_name\": \"94043\",\r\n          \"types\": [\r\n            \"postal_code\"\r\n          ]\r\n        }\r\n      ],\r\n      \"formatted_address\": \"1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA\",\r\n      \"geometry\": {\r\n        \"location\": {\r\n          \"lat\": 37.422364,\r\n          \"lng\": -122.084364\r\n        },\r\n        \"location_type\": \"ROOFTOP\",\r\n        \"viewport\": {\r\n          \"northeast\": {\r\n            \"lat\": 37.4237129802915,\r\n            \"lng\": -122.0830150197085\r\n          },\r\n          \"southwest\": {\r\n            \"lat\": 37.421015019708513,\r\n            \"lng\": -122.0857129802915\r\n          }\r\n        }\r\n      },\r\n      \"place_id\": \"ChIJ2eUgeAK6j4ARbn5u_wAGqWA\",\r\n      \"types\": [\r\n        \"street_address\"\r\n      ]\r\n    }\r\n  ],\r\n  \"status\": \"OK\"\r\n}";
        GoogleJson gJson = null;
        gJson = JsonUtility.FromJson<GoogleJson>(value);
    
        for (int i = 0; i < gJson.results.Count; i++)
        {
            Debug.Log("RESULT: " + i);
            Debug.Log("Geometry lat: " + gJson.results[i].geometry.location.lat);
            Debug.Log("Geometry lng: " + gJson.results[i].geometry.location.lng);
        }
    }
    

    【讨论】:

    • 不错!这是创建一个dynamic 对象吗?
    • @GeoffJames 是的。它创建它,然后将结果分配给它。如果您不希望它创建该对象的新实例,您可以使用JsonUtility.FromJsonOverwrite,但这意味着您必须在调用该函数之前执行GoogleJson gJson = new GoogleJson ();。看起来我们都在您的答案中使用相同的链接来完成我们的 json 工作。
    • 我以为我认出了它。当我开始为一个项目做一些谷歌地理编码的东西时,我使用dynamic 对象来解析一些 Json。最后它变得非常繁琐和丑陋,所以我选择了一个好的旧 C# 类。 json2csharp.com是救命工具!
    • 我同意。 json2csharp.com 是一个救生工具。 JsonUtility.FromJson 对 Unity 来说仍然是新的,并且正在改进中。编码愉快!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    相关资源
    最近更新 更多