private GeoJsonRoot ParseData(string geoJsonData)
    {
        fsSerializer serializer = new fsSerializer();

        serializer.Config.GetJsonNameFromMemberName = GetJsonNameFromMemberName;
        serializer.AddConverter(new Converter());
        fsData data = null;

        data = fsJsonParser.Parse(geoJsonData);

        // step 2: deserialize the data
        GeoJsonRoot deserialized = null;

        serializer.TryDeserialize(data, ref deserialized).AssertSuccessWithoutWarnings();
        return(deserialized);
    }
    // Use this for initialization
    void Start()
    {
        // MIN 51.579687, -0.341837
        // MAX 51.580780, -0.333930
        //const float minLat = 51.579687f;
        //const float maxLat = 51.580780f;
        //const float minLon = -0.341837f;
        //const float maxLon = -0.333930f;

        float maxLat = 51.5140574994f;
        float maxLon = -0.1145303249f;
        float minLat = 51.5073134351f;
        float minLon = -0.1295164166f;

        float[][][] TileBounds = new float[][][]
        {
            new float[][]
            {
                new float[] { maxLon, maxLat, 0.0f },
                new float[] { minLon, minLat, 0.0f },
            }
        };

        // Can get the OSM data using something like the following..
        var httpStr = @"http://overpass-api.de/api/interpreter?data=[out:json];(node[""building""](51.579687,-0.341837,51.580780,-0.333930);way[""building""](51.579687,-0.341837,51.580780,-0.333930);relation[""building""](51.579687,-0.341837,51.580780,-0.333930););out body;>;out skel qt;";

        //var geoJson = Resources.Load("santander") as TextAsset;
        var geoJson = Resources.Load("london2") as TextAsset;

        fsSerializer serializer = new fsSerializer();

        serializer.Config.GetJsonNameFromMemberName = GetJsonNameFromMemberName;
        serializer.AddConverter(new Converter());
        fsData data = null;

        data = fsJsonParser.Parse(geoJson.text);

        // step 2: deserialize the data
        GeoJsonRoot deserialized = null;

        try
        {
            serializer.TryDeserialize(data, ref deserialized).AssertSuccessWithoutWarnings();
        }
        catch (Exception ex)
        {
            int x = 3;
        }

        Debug.Log("Number of features = " + deserialized.features.Count());

        var buildings = deserialized.features.Where(f => f.properties != null && f.properties.tags.building != null);

        // Need to know the centre of the 'tile' so we can create the buildings at
        // the origin and then translate to the correct positions.
        // When we are calling an API we will know the lat lon of the requested tile
        // until then we can use a bounding box around all of the buildings..
        //var tb = GetBoundingBoxForBuilding(buildings.First());
        //foreach (var building in buildings)
        //{
        //    if (building == buildings.First())
        //        continue;
        //    var bounds = GetBoundingBoxForBuilding(building);
        //    if (bounds == null)
        //        continue;
        //    tb.Value.Encapsulate(bounds.Value);
        //}

        // Use the centre of the tile bounding box
        var tb = GetBoundingBox(TileBounds);

        int buildingCount = 0;

        foreach (var building in buildings)
        {
            try
            {
                if (++buildingCount != 1)
                {
                    continue;
                }

                if (building.geometry.coordinates == null)
                {
                    continue;
                }

                foreach (var coords in building.geometry.coordinates)
                {
                    // Create Vector2 vertices
                    List <Vector2> verts = new List <Vector2>();

                    foreach (var crd in coords)
                    {
                        // remember lat/lon are reversed in geoJSON
                        verts.Add(GM.LatLonToMeters(crd[1], crd[0]));
                    }

                    // Create the Vector3 vertices -
                    // So, x corresponds to latitude
                    // z corresponds to longitude
                    List <Vector3> verts3 = verts.Select(v => v.ToVector3xz()).ToList();

                    // Calculate axis aligned bounding box for polygon
                    var bound = new Bounds(verts3[0], Vector3.zero);
                    foreach (var vtx in verts3)
                    {
                        bound.Encapsulate(vtx);
                    }

                    // Move the polygon to the origin by subtracting the centre of the bounding box from
                    // each vertex.
                    verts = verts3.Select(vtx => (vtx - bound.center).ToVector2xz()).ToList();

                    Debug.Log(string.Format("NUM VERTS (before triangulation) = {0}", verts.Count));

                    // Work out the height of the building either from height or estimate from
                    // number of levels or failing that, just one level..
                    const float oneLevel  = 16.0f;
                    int         numLevels = 1;
                    if (!string.IsNullOrEmpty(building.properties.tags.building_levels))
                    {
                        numLevels = int.Parse(building.properties.tags.building_levels);
                    }
                    var mesh = Triangulator.CreateMesh(verts.ToArray(), numLevels * oneLevel);
                    var g    = new GameObject();
                    g.AddComponent(typeof(MeshFilter));
                    g.AddComponent(typeof(MeshRenderer));

                    // If you want to get flat shading then you need a unique vertex for each
                    // face. I haven't processed the data like that so have run this code as a post
                    // process to generate the required vertices
                    // (see http://answers.unity3d.com/questions/798510/flat-shading.html)
                    Vector3[] oldVerts  = mesh.vertices;
                    int[]     triangles = mesh.triangles;
                    Vector3[] vertices  = new Vector3[triangles.Length];
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        vertices[i]  = oldVerts[triangles[i]];
                        triangles[i] = i;
                    }
                    mesh.vertices  = vertices;
                    mesh.triangles = triangles;

                    mesh.RecalculateBounds();
                    mesh.RecalculateNormals();

                    g.GetComponent <MeshFilter>().mesh = mesh;

                    var dist = bound.center - tb.Value.center;

                    // also, translate the building in y by half of its height..
                    //dist.y +=
                    g.transform.Translate(dist);

                    Material m = new Material(Shader.Find("Standard"));
                    m.color = Color.grey;
                    if (building.properties.tags != null)
                    {
                        if (!string.IsNullOrEmpty(building.properties.tags.name))
                        {
                            g.name = building.properties.tags.name;
                        }
                        else if (!string.IsNullOrEmpty(building.properties.tags.addrhousename))
                        {
                            g.name = building.properties.tags.addrhousename;
                        }
                        else if (!string.IsNullOrEmpty(building.properties.tags.addrstreet))
                        {
                            g.name = building.properties.tags.addrstreet;
                        }
                    }
                    g.GetComponent <MeshRenderer>().material = m;
                    g.transform.parent = gameObject.transform;
                }
            }
            catch (Exception ex)
            {
                Debug.Log(string.Format("Building load failed"));
            }
        }

        // Now generate a plane and texture it with a map image..
        //var tb = GetBoundingBox(TileBounds);
        var poly = tb.Value.ToPolygonFromBounds();

        // Centre on the origin..
        var polyArray = poly.ToList().Select(p => (p.ToVector3xz() - tb.Value.center).ToVector2xz());
        var planeMesh = Triangulator.CreateMesh(polyArray.ToArray());

        // Set the UVs:
        //Vector2[] uvs = new Vector2[4];

        //uvs[0] = new Vector2(0.0f, 0.0f);
        //uvs[1] = new Vector2(0.0f, 1.0f);
        //uvs[2] = new Vector2(1.0f, 1.0f);
        //uvs[3] = new Vector2(1.0f, 0.0f);

        {
            Vector3[] old       = planeMesh.vertices;
            int[]     triangles = planeMesh.triangles;
            Vector3[] vertices  = new Vector3[triangles.Length];
            for (int i = 0; i < triangles.Length; i++)
            {
                vertices[i]  = old[triangles[i]];
                triangles[i] = i;
            }
        }

        //planeMesh.uv = uvs;
        planeMesh.RecalculateNormals();
        planeMesh.RecalculateBounds();

        var gobj = new GameObject();

        gobj.name = "Tile Plane";
        gobj.AddComponent(typeof(MeshFilter));
        gobj.AddComponent(typeof(MeshRenderer));
        gobj.GetComponent <MeshFilter>().mesh = planeMesh;
        Material mt = new Material(Shader.Find("Standard"));

        mt.color = Color.white;
        gobj.GetComponent <MeshRenderer>().material = mt;
        //Texture my_img = (Texture)Resources.Load("harrowtestimg");
        //gobj.GetComponent<MeshRenderer>().material.mainTexture = my_img;
    }