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