예제 #1
0
 public void OnCoordinateConversionButtonClick()
 {
     if (!string.IsNullOrEmpty(SourceLat.text) && !string.IsNullOrEmpty(SourceLon.text))
     {
         string latstring = SourceLat.text.Trim();
         string lonstring = SourceLon.text.Trim();
         double lat       = 0;
         double lon       = 0;
         if (double.TryParse(latstring, out lat) && double.TryParse(lonstring, out lon))
         {
             var vector3 = CoordinateConvertor.LatLonToVector3(lat, lon);
             TargetDisplay.text = vector3.ToString();
             if (GoToLocation.isOn)
             {
                 // Transform the camera
                 //Camera.main.transform.position
                 Camera.main.transform.position = vector3 + new Vector3(CameraDistanceFromThePoint, 1, CameraDistanceFromThePoint);
                 Camera.main.transform.LookAt(vector3);
                 Camera.main.GetComponent <CameraControl>().targetCameraPosition = new Vector3(vector3.x + CameraDistanceFromThePoint, 2, vector3.z + CameraDistanceFromThePoint);
             }
         }
         else
         {
             TargetDisplay.text = "Invalid input!";
         }
     }
 }
예제 #2
0
    public void CalculateLatLon(MapBoundaries mb)
    {
        var latlon = new Vector3[4];

        for (int i = 0; i < vertices.Length; i++)
        {
            var res = CoordinateConvertor.Vector3ToLatLon(vertices[i], mb);
            latlon[i] = new Vector3(res[0], 0, res[1]);
        }
        var bounds = GetBounds(latlon);

        minLat = bounds[0];
        maxLat = bounds[1];
        minLon = bounds[2];
        maxLon = bounds[3];

        if (verbose)
        {
            for (int i = 0; i < vertices.Length; i++)
            {
                var convVert = CoordinateConvertor.LatLonToVector3(latlon[i].x, latlon[i].z, latlon[i].y, mb);
                Debug.Log("vertice: " + vertices[i] + " converted back: " + convVert);
            }
        }
    }
예제 #3
0
    // Use this for initialization
    void Start()
    {
        ServiceGapslabsClient client = ServicePropertiesClass.GetGapslabsService(ServicePropertiesClass.ServiceUri);
        var go            = GameObject.Find("AramGISBoundaries");
        var mapboundaries = go.GetComponent <MapBoundaries>();

        CoordinateConvertor.Initialize(client, mapboundaries);
    }
예제 #4
0
    /// <summary>
    /// Starts the script.
    /// </summary>
    void Start()
    {
        log.Info("Map boundaries : MaxLat " + maxLat + ", MinLat " + minLat + ", MaxLon " + maxLon + ", MinLon " + minLon);

        //Initialize the coordinate convertor (need it for running the game!)
        ServiceGapslabsClient client = ServicePropertiesClass.GetGapslabsService(ServicePropertiesClass.ServiceUri);

        CoordinateConvertor.Initialize(client, this);
    }
예제 #5
0
    public void CreateBusStops()
    {
        if (busInfo == null)
        {
            Debug.Log("no busInfo loaded.");
            return;
        }
        if (netInfo == null)
        {
            Debug.Log("no netInfo loaded.");
            return;
        }
        var mb = FindObjectOfType <MapBoundaries>();

        if (mb == null)
        {
            Debug.Log("no MapBoundaries found.");
            return;
        }

        //ArrowUtils.CheckTransportationModuleExist();
        StationCreator creator = StationCreator.AttachToGameObject();

        creator.SetStations(FindObjectsOfType <StationController>());

        // SumoLocation used in UTM to WGS-84 conversion.
        var location = netInfo.location;

        // Go through the busStops in busInfo.
        foreach (var busStop in busInfo.busStops)
        {
            // Get the polyline of the lane of the busStop
            var lane = netInfo.GetLane(busStop.lane);
            // Get the midpoint of the first 2 positions of shape in lane.
            var midPoint = lane.GetMidPoint();
            //Debug.Log(midPoint);

            // Get the UTM corrdinates by subtracting the netOffset in location-element.
            var utm = location.GetUTM(midPoint.x, midPoint.y);
            // Convert the UTM corrdinates to Latitude Longitude.
            var latlon = UTMtoLatLon(utm[0], utm[1], location.GetZone());
            //Debug.Log(latlon[0] + ", " + latlon[1]);

            // Convert the Latitude Longitude to coordinates in Unity.
            var convVec = CoordinateConvertor.LatLonToVector3(latlon[0], latlon[1], 0, mb);
            //Debug.Log(convVec);

            // Create a busStop based on the converted coordinate.
            //var go = new GameObject(busStop.id);
            //go.transform.position = convVec;
            //go.transform.SetParent(this.transform);
            creator.AddNewStation(convVec, busStop.id);
        }

        DestroyImmediate(creator);
    }
예제 #6
0
    public void CreateFirstBuilding()
    {
        buildingCreationWindow.transform.position = CoordinateConvertor.SimpleToIso(new Point(15, 15));
        var      go       = Instantiate(mainBuildingPrefab, CoordinateConvertor.SimpleToIso(new Point(15, 15)), Quaternion.identity) as GameObject;
        Building building = go.GetComponent <Building>();

        go.transform.parent = buildingCreationWindow.transform;
        buildingCreationWindow.SetSelectedBuilding(building);
        buildingCreationWindow.SetPosition(buildingCreationWindow.transform.position);
        building.InitializeBuilding(BuildingType.Foot);
    }
예제 #7
0
 public Vector3 GetPoint()
 {
     if (lat != 0 || lon != 0)
     {
         CoordinateConvertor.Initialize();
         return(CoordinateConvertor.LatLonToVector3(lat, lon));
     }
     else
     {
         return(new Vector3(x, y, z));
     }
 }
예제 #8
0
        protected EnhancedMapPoint createPoint(IGeometry point, MapLayerBase layer)
        {
            var location = CoordinateConvertor.ConvertBack(point.Coordinate);
            var mapPoint = new EnhancedMapPoint(location, mapInstance)
            {
                GeometryStyle = StyleSpecification
            };

            layer.AddChild(mapPoint, location);
            mapObjects.Add(mapPoint);
            mapPoint.Visibility = Visibility;
            return(mapPoint);
        }
예제 #9
0
    void InitTiles()
    {
        var dt1 = DateTime.Now;

        for (int i = 0; i < 30; i++)
        {
            for (int j = 0; j < 30; j++)
            {
                var go = Instantiate(tilePrefab, CoordinateConvertor.SimpleToIso(new Point(i, j)), Quaternion.identity) as GameObject;
                go.transform.parent = tilesPlace;
            }
        }
    }
예제 #10
0
        protected EnhancedMapPolygon createPolygon(IGeometry polygon, MapLayerBase layer)
        {
            var poly = new EnhancedMapPolygon
            {
                Locations     = CoordinateConvertor.CoordinatesToLocationCollection(polygon.Coordinates),
                GeometryStyle = StyleSpecification,
                Visibility    = Visibility
            };

            layer.AddChild(poly, CoordinateConvertor.ConvertBack(polygon.Centroid.Coordinate));
            mapObjects.Add(poly);
            return(poly);
        }
예제 #11
0
        protected EnhancedMapPolyline createPolyLine(IGeometry lineString, MapLayerBase layer)
        {
            var line = new EnhancedMapPolyline
            {
                Locations     = CoordinateConvertor.CoordinatesToLocationCollection(lineString.Coordinates),
                GeometryStyle = StyleSpecification,
                Visibility    = Visibility
            };

            layer.AddChild(line, CoordinateConvertor.ConvertBack(lineString.Centroid.Coordinate));
            mapObjects.Add(line);
            return(line);
        }
예제 #12
0
    /// <summary>
    /// Log the position of the dropped object in Lat-Lon coordinates.
    /// </summary>
    public void LogPositionInLatLon()
    {
        if (!deleting)
        {
            float[] latLon = CoordinateConvertor.Vector3ToLatLon(this.transform.position);

            Debug.Log(this.name + " placed at " + latLon[0] + ", " + latLon[1]);

            if (loggerAssembly != null && loggerAssembly.logDragAndDrop)
            {
                log.Info(string.Format("{0} placed at {1}, {2}", this.name, latLon[0].ToString(), latLon[1].ToString()));
            }
        }
    }
예제 #13
0
    /// <summary>
    /// Generates a pedestrian inside the Unity scene. The position will be set
    /// according to the data contained in the sql database of pedestrian information.
    /// </summary>
    void GeneratePedestrianFromDB()
    {
        //Establish connection with the sql database
        NpgsqlConnection dbcon = EstablishConnectionWithSqlDB();

        //Create the command to query (RandomPoint)
        NpgsqlCommand dbcmd = CreateSqlCommand(dbcon, "SELECT ST_AsText(RandomPoint(geom, 100)) FROM zones WHERE (zone_txt = 720134::varchar)");

        //Query the command to the database
        NpgsqlDataReader reader = dbcmd.ExecuteReader();

        if (reader.Read())
        {
            //Read the random point
            string   point = reader.GetString(0);
            string[] parse = point.Split(' ', '(', ')');
            double   lat   = double.Parse(parse[1]);
            double   lon   = double.Parse(parse[2]);

            Vector3 v3;
            if (UseCoordinateConversion)
            {
                v3 = CoordinateConvertor.LatLonToVector3(lon, lat);
            }
            else
            {
                v3 = new Vector3((float)lon, 0.0f, (float)lat);
            }

            //Add an offset to fit the Unity scene
            v3.x += 85.0f;
            v3.z -= 290.0f;

            //Try to find the closest point in the navmesh
            NavMeshHit hit;
            if (NavMesh.SamplePosition(v3, out hit, 100.0f, 1 << NavMesh.GetNavMeshLayerFromName("footway")))
            {
                SpawnPedestrian(hit.position);
            }
        }

        //Free the resources
        reader.Close();
        reader = null;
        dbcmd.Dispose();
        dbcmd = null;
        dbcon.Close();
        dbcon = null;
    }
예제 #14
0
    void OnGUI()
    {
        GUILayout.Label("Coordinate Convertor Tool", EditorStyles.boldLabel);

        vector3 = EditorGUILayout.Vector3Field("3D point to convert", vector3);

        if (GUILayout.Button("Convert point to lat-lon"))
        {
            float[] conversion = CoordinateConvertor.Vector3ToLatLon(vector3, FindObjectOfType <MapBoundaries>());
            latitude  = conversion[0];
            longitude = conversion[1];
        }

        latitude  = EditorGUILayout.FloatField("latitude", latitude);
        longitude = EditorGUILayout.FloatField("longitude", longitude);
    }
예제 #15
0
    void BuildingTapCheck()
    {
        Debug.Log("BuildingTapCheck");
        RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

        if (hit.collider != null && (hit.transform.tag == "Tile" || hit.transform.tag == "Building"))
        {
            Debug.Log(hit.transform.tag);
            //якщо відкрито вікно оновлення - закриваєм його
            if (upgradingWindow.selectedBuilding)
            {
                /*if (hit.collider != null && hit.transform.tag == "Building")
                 * {
                 *  var building = hit.transform.GetComponent<Building>();
                 *  if (upgradingWindow.selectedBuilding == building)
                 *  {
                 *      if (!(building is HumanInputer))
                 *      {
                 *          WindowManager.Instance.GetWindow<WindowProductCreation>().Open(building);
                 *          WindowManager.Instance.GetWindow<GUI>().Close(false);
                 *          upgradingWindow.SetSelectedBuilding(null);
                 *      }
                 *  }
                 * }*/
                upgradingWindow.SetSelectedBuilding(null);
            }
            if (creatingWindow.selectedBuilding)
            {
                Point point = CoordinateConvertor.IsoToSimple(hit.point);
                creatingWindow.SetPosition(CoordinateConvertor.SimpleToIso(point));
            }
        }
        // якщо начого не строїмо
        if (!creatingWindow.selectedBuilding)
        {
            // і натискаєм на побудований будинок
            if (hit.collider != null && hit.transform.tag == "Building")
            {
                var building = hit.transform.GetComponent <Building>();
                upgradingWindow.SetSelectedBuilding(building);
                Point point = CoordinateConvertor.IsoToSimple(building.transform.position);
                upgradingWindow.SetPosition(CoordinateConvertor.SimpleToIso(point));
            }
        }
    }
예제 #16
0
        private void reductionWorkerDoWork(object sender, DoWorkEventArgs args)
        {
            var worker       = sender as BackgroundWorker;
            var lineSimplify = new DouglasPeuckerLineSimplifier(CoordinateConvertor.LocationCollectionToCoordinates(Original));

            for (int i = 21; i > 0; i--)
            {
                if (worker != null && worker.CancellationPending)
                {
                    args.Cancel = true;
                    break;
                }

                var simplificationDistance = (1 / (Math.Pow(2, i - 1)));
                lineSimplify.DistanceTolerance = simplificationDistance;
                Reduced.Add(i, CoordinateConvertor.CoordinatesToLocationCollection(lineSimplify.Simplify()));
            }

            Initalized = true;
        }
예제 #17
0
    /// <summary>
    /// Coroutine for drawing the points in the map.
    /// </summary>
    IEnumerator DrawPoints()
    {
        while (!pointsReadyToBeDrawn)
        {
            yield return(new WaitForSeconds(0.1f));
        }

        ServiceGapslabsClient client = ServicePropertiesClass.GetGapslabsService(ServicePropertiesClass.ServiceUri);

        CoordinateConvertor.Initialize(client, FindObjectOfType <MapBoundaries>());

        for (int i = 0; i < points.Count; i++)
        {
            Vector3 V        = points[i];
            Vector3 position = CoordinateConvertor.LatLonToVector3(V.x, V.y);

            var newPoint = Instantiate(pointObject, position, Quaternion.identity) as GameObject;

            newPoint.name             = "fixPoint" + i;
            newPoint.transform.parent = pointHolder.transform;

            var pointInfo = newPoint.GetComponent <VVisFixPointInfo>();

            if (pointInfo != null)
            {
                List <string> info = new List <string>();
                info.Add("count: " + V.z.ToString());
                pointInfo.StorePointInfo(info);
            }

            newPoint.SetActive(true);
        }

        if (hidePointsAfterLoading)
        {
            HideLoadedPoints();
        }

        pointsReadyToBeDrawn = false;
    }
예제 #18
0
    /// <summary>
    /// Auxiliar private method. Creates and updates the graphic vehicles in the Unity scene
    /// for the current timestep of the simulation.
    /// </summary>
    private void UpdateVehiclesInScene()
    {
        int currentNumberOfVehicles = trafficData.GetNumberOfVehiclesInTimeStep(timeStepIndex);

        // Log the number of vehicles once per second (independently of game time)
        if (Time.time > nextActionTime)
        {
            nextActionTime = Time.time + period;
            log.Info("Current number of vehicles in the simulation: " + currentNumberOfVehicles);
        }

        //Check for each vehicle in the Traffic Integration Data at the current timestep
        for (int i = 0; i < currentNumberOfVehicles; i++)
        {
            VehicleTDB v = trafficData.GetVehicleAt(timeStepIndex, i);

            Vector3 v3;
            if (UseCoordinateConversion)
            {
                v3 = CoordinateConvertor.LatLonToVector3(v.latitude, v.longitude);
            }
            else
            {
                v3 = new Vector3(v.latitude, 0.0f, v.longitude);
            }

            TrafficIntegrationVehicle vController;

            if (vehControllers.TryGetValue(v.id, out vController))
            {
                if (!vController.gameObject.activeSelf)
                {
                    vController.gameObject.SetActive(true);
                }

                vController.isUpdated = true;

                var meshRenderer = vController.gameObject.GetComponent <MeshRenderer>();
                var lod          = vController.gameObject.GetComponent <LODGroup>();

                //Render an existing vehicle if it is inside the frustrum
                if (!UseFrustumForUpdate || UnityEngine.GeometryUtility.TestPlanesAABB(cameraFrustum.Frustum, new Bounds(v3, 2 * Vector3.one)) || v.type.ToUpperInvariant().Contains("BUS"))
                {
                    vController.UpdateVehiclePosition(v3.x, v3.z, v.angle);

                    if (meshRenderer != null)
                    {
                        meshRenderer.enabled = true;
                    }
                    if (lod != null)
                    {
                        lod.enabled = true;
                    }
                }
                else
                {
                    if (meshRenderer != null)
                    {
                        meshRenderer.enabled = false;
                    }
                    if (lod != null)
                    {
                        lod.enabled = false;
                    }
                }
            }
            else
            {
                //Create a new vehicle in the scene
                Vector3 vehPosition = new Vector3(v3.x, 0.0f, v3.z);

                GameObject vehObject;
                if (v.type.ToUpperInvariant().Contains("BUS"))
                {
                    if (v.id.Contains("dz_repl")) // for Driebergen-Zeist case
                    {
                        vehObject = (GameObject)Instantiate(graphicAltBus, vehPosition, Quaternion.identity);
                    }
                    else
                    {
                        vehObject = (GameObject)Instantiate(graphicBus, vehPosition, Quaternion.identity);
                    }

                    if (routingContr != null)
                    {
                        routingContr.HandleBusObjectsFromSumo(vehObject, v.id);
                    }
                }
                else
                {
                    vehObject = (GameObject)Instantiate(graphicCar[Random.Range(0, graphicCar.Length)], vehPosition, Quaternion.identity);
                }

                vehObject.transform.parent = this.transform;
                vehObject.name             = v.id;
                TrafficIntegrationVehicle vc = vehObject.GetComponent <TrafficIntegrationVehicle>();
                vc.smooth                   = smoothPaths;
                vc.brakingActive            = brakingActive && (trafficContr.typeOfIntegration == TrafficIntegrationController.TypeOfIntegration.SumoLiveIntegration);
                vc.timeToBrakeInSeconds     = timeToBrakeInSeconds;
                vc.driversPatienceInSeconds = driversPatienceInSeconds;
                vc.angleOfView              = angleOfView;
                vehControllers.Add(v.id, vc);
            }
        }
    }
예제 #19
0
    static void SaveStationsAndLines()
    {
        var sgos = GameObject.FindGameObjectsWithTag("TransStation");

        if (sgos.Length < 1)
        {
            Debug.Log("no stations to save.");
            return;
        }
        var lgos = GameObject.FindGameObjectsWithTag("TransLine");

        if (lgos.Length < 1)
        {
            Debug.Log("no lines to save.");
            return;
        }

        var path = EditorUtility.SaveFilePanel("Save XML Data", "Assets/Transportations", "", "xml");

        if (path.Length == 0)
        {
            EditorUtility.DisplayDialog("Saving Cancelled", "No file was provided", "OK");
            return;
        }

        List <BaseStation> stations = new List <BaseStation>();

        foreach (var go in sgos)
        {
            CoordinateConvertor.Initialize();
            float[] latLon = CoordinateConvertor.Vector3ToLatLon(go.transform.position);

            var sc = go.GetComponent <StationController>();
            var bs = new BaseStation
            {
                id   = int.Parse(sc.name),
                lat  = latLon[0],
                lon  = latLon[1],
                x    = go.transform.position.x,
                y    = go.transform.position.y,
                z    = go.transform.position.z,
                name = sc.stationName,
            };
            stations.Add(bs);
        }

        List <BaseLine> lines = new List <BaseLine>();

        foreach (var go in lgos)
        {
            var lc = go.GetComponent <LineController>();
            var bl = LineController.CreateBaseLine(lc);
            lines.Add(bl);
        }

        var container = new TrafficContainer();

        container.stations = stations;
        container.lines    = lines;
        container.Save(path);
        string stationStats = string.Format("{0} stations saved.", container.stations.Count);
        string lineStats    = string.Format("{0} lines saved.", container.lines.Count);

        EditorUtility.DisplayDialog("Saving Finished", stationStats + "\n" + lineStats + "\n to: " + path, "OK");
    }
예제 #20
0
        static void MainParallel(string[] args, MapProperties properties , string exportPath)
        {
            int max = 25;
            int current = 0;

            GaPSlabsVersion version = new GaPSlabsVersion("GaPSLabs 3D City Generator 1.0", 1, 0);

            if (!System.IO.Directory.Exists(exportPath))
                System.IO.Directory.CreateDirectory(exportPath);

            Random rand = new Random((int)DateTime.Now.Ticks);
            MapProperties mapboundaries = new MapProperties();
            if (properties != null)
                mapboundaries = properties;
            else
            {
                //mapboundaries.minLat = 59.3457;
                //mapboundaries.maxLat = 59.3527;
                //mapboundaries.minLon = 18.0609;
                //mapboundaries.maxLon = 18.0765;
                //mapboundaries.Name = "KTH Area";
                mapboundaries.minLat = 59.2294;
                mapboundaries.maxLat = 59.4800;
                mapboundaries.minLon = 17.7649;
                mapboundaries.maxLon = 18.2977;
                mapboundaries.Name = "KTH Area";
                mapboundaries.BuildingLineThickness = 0.6f;
                mapboundaries.RoadLineThickness = 0.2f;
                mapboundaries.Scale = new Vector2(16, 16);
                mapboundaries.BuildingColor = new Color(0, 255, 0);
                mapboundaries.LineColorStart = new Color(255, 255, 0);
                mapboundaries.LineColorEnd = new Color(255, 255, 0);
                mapboundaries.BuildingMaterial = null;
                mapboundaries.RoadMaterial = new Material("Route");
                mapboundaries.CycleWayMaterial = new Material("RouteCycleway");
                mapboundaries.FootWayMaterial = new Material("RouteFootway");
                mapboundaries.RailWayMaterial = null;
                mapboundaries.StepsMaterial = new Material("RouteSteps");
                mapboundaries.RoadWidth = 1;// 0.05f;
                mapboundaries.CyclewayWidth = 0.05f;
                mapboundaries.FootwayWidth = 0.05f;
                mapboundaries.BuildingHeight = 7.5f;
                mapboundaries.CombinationOptimizationSize = new Vector2(100, 100);
            }

            bool GenerateBuildingShapes = true;
            bool GenerateRoads = true;
            bool GenerateBuildings = true;
            bool CorrectAspectRatio = false;
            
            OSMPostgresqlSource source = new OSMPostgresqlSource(connPostGreSql);
            var bounds = source.Bounds;

            float[] minmaxX;
            float[] minmaxY;

            minmaxX = new float[] { 0, 5000 };
            minmaxY = new float[] { 0, 5000 };

            Bounds SelectedArea = new Bounds();
            float LineWidth = 0.4f;
            float BuildingWidth = 0.6f;

            float height;
            height = 7.5f;

            SelectedArea.minlat = mapboundaries.minLat;
            SelectedArea.maxlat = mapboundaries.maxLat;
            SelectedArea.minlon = mapboundaries.minLon;
            SelectedArea.maxlon = mapboundaries.maxLon;
            minmaxX = mapboundaries.minMaxX;
            minmaxY = mapboundaries.minMaxY;
            if (CorrectAspectRatio)
            {
                var aspectRatio = System.Math.Abs(SelectedArea.maxlat - SelectedArea.minlat) / System.Math.Abs(SelectedArea.maxlon - SelectedArea.minlon);
                minmaxY[1] = (float)(minmaxX[1] * aspectRatio);
            }

            LineWidth = mapboundaries.RoadLineThickness;
            BuildingWidth = mapboundaries.BuildingLineThickness;
            height = mapboundaries.BuildingHeight;
            if (height < 4)
                height = 4;

            string[] ways = null;
            if (!GenerateRoads)
            {
                string[][] buildingtag = new string[1][];
                buildingtag[0] = new string[] { "building", "" }; // NOTE: building tag in OSM is in lower case.
                ways = source.GetWayIdsWithTags(SelectedArea, buildingtag);
            }
            else
                if (!GenerateBuildings)
                {
                    string[][] roadtag = new string[1][];
                    roadtag[0] = new string[] { "highway", "" }; // NOTE: highway tag in OSM is in lower case.
                    ways = source.GetWayIdsWithTags(SelectedArea, roadtag);
                }
                else
                    ways = source.GetWayIdsInBound(SelectedArea);
            
            float[] MinPointOnArea = CoordinateConvertor.SimpleInterpolation((float)SelectedArea.minlat, (float)SelectedArea.minlon, bounds, minmaxX, minmaxY);

            int direction = -1;
            Vector3 MinPointOnMap = new Vector3(direction * MinPointOnArea[0], 0, MinPointOnArea[1]);
            mapboundaries.MinPointOnMap = MinPointOnMap;

            int totalWays = ways.Length;
            int progress = 0;
            //List<OsmNode> WayNodes;
            //List<Tag> WayTags;
            //Vector3[] tempPoints;
            //PolygonCuttingEar.CPolygonShape shp;
            Console.WriteLine("Started at " + DateTime.Now + " for " + ways.Length + " objects.");
            var duration = Stopwatch.StartNew();
            Parallel.ForEach<string>(ways, (FirstWay, state) =>
            //foreach (var FirstWay in ways)
            {
                var w = new Way(FirstWay);
                List<OsmNode> WayNodes;
                List<Tag> WayTags;
                using (Npgsql.NpgsqlConnection con = new Npgsql.NpgsqlConnection(connPostGreSql))
                {
                    con.Open();
                    WayNodes = w.GetNodesPostgreSQL(FirstWay, con);
                    WayTags = w.GetTagsPostgreSQL(FirstWay, con);
                    con.Close();
                }
                if (WayTags.Where(i => i.KeyValueSQL[0].ToLower() == "landuse" || i.KeyValueSQL[0].ToLower() == "building" || i.KeyValueSQL[0].ToLower() == "highway").Count() != 0)
                {
                    var tempPoints = new Vector3[WayNodes.Count];

                    int counter = 0;
                    foreach (var node in WayNodes)
                    {
                        var result = CoordinateConvertor.SimpleInterpolation((float)node.PositionSQL.Lat, (float)node.PositionSQL.Lon, bounds, minmaxX, minmaxY);
                        // Testing the correct direction
                        tempPoints[counter] = new Vector3(direction * (float)result[0], 0, (float)result[1]) - MinPointOnMap;
                        counter++;
                    }
                    WayNodes = null;
                    var building = WayTags.Where(i => i.KeyValueSQL[0].ToLower() == "building");
                    var highwayType = WayTags.Where(i => i.KeyValueSQL[0].ToLower() == "highway");
                    WayTags = null;
                    if (building.Count() != 0)
                    {
                        if (GenerateBuildings)
                        {
                            //Debug.Log("Current building: "+FirstWay);
                            if (GenerateBuildingShapes)
                            {
                                // Check if it has overlapping start and ending points.
                                // NOTE: Replaced with the code to remove all the duplicates, not only the endpoints.							
                                // Checking for duplicates:
                                tempPoints = tempPoints.ToArray().RemoveDuplicates();
                                var Skip = false;
                                if (tempPoints.Length <= 2)
                                {
                                    // Buildings that are too small to show such as 76844368
                                    // http://www.openstreetmap.org/browse/way/76844368
                                    // "A weird building were found and ignored. FirstWay \nRelated url: http://www.openstreetmap.org/browse/way/{0}"
                                    Skip = true; // continue;
                                }
                                if (!Skip)
                                {
                                    var p2d = tempPoints.ToCPoint2D();
                                    // TODO bug in the cpolygon, probably duplicates
                                    var shp = new PolygonCuttingEar.CPolygonShape(p2d);
                                    shp.CutEar();
                                    p2d = null;
                                    GC.Collect();
                                    // TODO:
                                    var randHeight = CoordinateConvertor.linear((float)rand.NextDouble(), 0, 1, -3f, height);
                                    var randMaterial = (randHeight > height / 2f) ? "BuildingTall" : randHeight < height / 2f ? "Building2" : "Building";
                                    var resultedGameObject = shp.GenerateShapeUVedWithWalls_Balanced(
                                            CoordinateConvertor.OSMType.Polygon, FirstWay,
                                            "Building", "Building", randMaterial,
                                            height + randHeight, height + 7, true);
                                    //Console.WriteLine("Generating building..id=" + FirstWay);

                                    // To file:
                                    // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));
                                    
                                    // To PostGreSql LargeObjects:
                                    var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                    var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                    AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                    // gc.id , gc is now set
                                }
                            }
                            else
                                Console.WriteLine("TODO");
                            // draw.Draw(tempPoints, buildingColor, buildingColor, BuildingWidth, BuildingWidth, LineDraw.OSMType.Line, FirstWay, "Building", "Building");
                        }
                    }
                    else
                    {
                        if (highwayType.Count() != 0)
                        {
                            if (GenerateRoads)
                            {
                                var hwtype = highwayType.First();
                                //Console.WriteLine("Generating roads..id=" + FirstWay);
                                switch (hwtype.KeyValueSQL[1])
                                {
                                    case "cycleway":
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(2f), mapboundaries.CyclewayWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.CycleWayMaterial.Name, -0.01f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                    case "footway":
                                    case "path":
                                    case "pedestrian":
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(4f), mapboundaries.FootwayWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.FootWayMaterial.Name, -0.01f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                    case "steps":
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(4f), mapboundaries.CyclewayWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.StepsMaterial.Name, -0.01f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                    case "motorway":
                                        {
                                            break;
                                        }
                                    default:
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(0.5f), mapboundaries.RoadWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.RoadMaterial.Name, 0f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                }
                                //current++;
                                //if (current > max)
                                //    state.Break();
                            }
                        }
                    }
                }
            });
            duration.Stop();
            Console.WriteLine("Finished in " + duration.Elapsed.Minutes + " minutes, " + duration.Elapsed.Seconds + " seconds, " + duration.Elapsed.Milliseconds + " milliseconds.");
            Console.ReadLine();
        }