/** * Parse trees from XML file */ private List <TreeObject> ParseTrees(XmlNodeList treeTags) { var treeObjects = new List <TreeObject>(); //<T> tags foreach (XmlNode treeTag in treeTags) { var treeObject = new TreeObject(); var latLngCoordinate = new LatLngObject(); //tags in <T> tag for (var i = 0; i < treeTag.ChildNodes.Count; i++) { //lat or lng tag var coordinateTag = treeTag.ChildNodes[i]; //coordinate var coordinate = float.Parse(coordinateTag.InnerText); if (i == 0) { latLngCoordinate.Latitude = coordinate; } else { latLngCoordinate.Longitude = coordinate; } } treeObject.LatLngCoordinate = latLngCoordinate; treeObjects.Add(treeObject); } return(treeObjects); }
/** * Visualize terrain borders */ public static void CheckTerrainBorders(LatLngObject mapMiddlePoint) { var left = new LatLngObject(mapMiddlePoint.Latitude, mapMiddlePoint.Longitude); left.Latitude += 0.0116f; left.Longitude += 0.004f; var sphereL = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphereL.transform.position = Converter.ConvertLatLngToXyz(left); var right = new LatLngObject(mapMiddlePoint.Latitude, mapMiddlePoint.Longitude); right.Latitude -= 0.0122f; right.Longitude -= 0.004f; var sphereR = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphereR.transform.position = Converter.ConvertLatLngToXyz(right); var top = new LatLngObject(mapMiddlePoint.Latitude, mapMiddlePoint.Longitude); top.Latitude -= 0.0035f; top.Longitude += 0.0134f; var sphereT = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphereT.transform.position = Converter.ConvertLatLngToXyz(top); var bottom = new LatLngObject(mapMiddlePoint.Latitude, mapMiddlePoint.Longitude); bottom.Latitude += 0.0033f; bottom.Longitude -= 0.0145f; var sphereB = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphereB.transform.position = Converter.ConvertLatLngToXyz(bottom); }
/** * */ private BuildingObject GetCoordinatesById(XmlNodeList nodeTags, List <long> nodeTagIds, XmlNode wayTag, float buildingHeight) { if (buildingHeight == DefaultBuildingHeight) { buildingHeight = 1; } //ids for coordinate pairing from way tag var locationIDs = LoaderUtils.GetWayTagIDs(wayTag); var latLngObjects = new LatLngObject[locationIDs.Count]; var numOfFoundedIDs = 0; for (var k = 0; k < nodeTags.Count; k++) { //cached id from node tag var id = nodeTagIds[k]; int locationIndex; if ((locationIndex = locationIDs.IndexOf(id)) != -1) { var nodeTag = nodeTags[k]; var lat = float.Parse(nodeTag.Attributes["lat"].Value); var lon = float.Parse(nodeTag.Attributes["lon"].Value); latLngObjects[locationIndex] = new LatLngObject(lat, lon); ++numOfFoundedIDs; } //pokud všechny souřadnice byly spárovány s IDčkama od budovy if (locationIDs.Count == numOfFoundedIDs) { break; } } return(new BuildingObject(latLngObjects.ToList(), buildingHeight)); }
/** * Create LatLng terrain grid for Elevation API */ public static List <LatLngObject> GetLatLngGrid(LatLngObject middlePoint) { var latLngGrid = new List <LatLngObject>(); var leftBorder = new LatLngObject(middlePoint.Latitude, middlePoint.Longitude); leftBorder.Latitude += 0.0116f; leftBorder.Longitude += 0.004f; var rightBorder = new LatLngObject(middlePoint.Latitude, middlePoint.Longitude); rightBorder.Latitude -= 0.0122f; rightBorder.Longitude -= 0.004f; var topBorder = new LatLngObject(middlePoint.Latitude, middlePoint.Longitude); topBorder.Latitude -= 0.0035f; topBorder.Longitude += 0.0134f; var bottomBorder = new LatLngObject(middlePoint.Latitude, middlePoint.Longitude); bottomBorder.Latitude += 0.0033f; bottomBorder.Longitude -= 0.0145f; //lat var mapLengthLat = Math.Abs(leftBorder.Latitude - rightBorder.Latitude); var mapPartLat = mapLengthLat / MapWidth; var mapStartLat = leftBorder.Latitude < rightBorder.Latitude ? leftBorder.Latitude : rightBorder.Latitude; mapStartLat -= mapPartLat; //lon var mapLengthLon = Math.Abs(topBorder.Longitude - bottomBorder.Longitude); var mapPartLon = mapLengthLon / MapHeight; var mapStartLon = topBorder.Longitude < bottomBorder.Longitude ? topBorder.Longitude : bottomBorder.Longitude; var defaultLon = mapPartLon * 33 + mapStartLon; var lats = new float[MapHeight]; for (var i = 0; i < MapHeight; i++) { lats[i] = mapStartLat += mapPartLat; } for (var i = 0; i < MapWidth; i++) { mapStartLon = defaultLon; for (var j = 0; j < MapHeight; j++) { mapStartLon -= mapPartLon; latLngGrid.Add(new LatLngObject(lats[32 - i], mapStartLon)); } } return(latLngGrid); }
/** * Converts LatLng coordinates into XYZ format * @see https://answers.unity.com/questions/923182/lat-long-to-unity-world-coordinates.html */ public static Vector3 ConvertLatLngToXyz(LatLngObject latLng) { if (latLng == null) { return(Vector3.zero); } const int scaleUp = 100000; Vector3 xyzPosition = Quaternion.AngleAxis(latLng.Longitude, -Vector3.up) * Quaternion.AngleAxis(latLng.Latitude, -Vector3.right) * new Vector3(0, 0, 1); var scaledXyzPosition = new Vector3(xyzPosition.x * scaleUp, 0f, xyzPosition.z * scaleUp); return(scaledXyzPosition); }
/** * Generate map terrain */ public void GenerateTerrain(LatLngObject mapMiddleMapPoint, Transform cameraTransform) { Vector3 mapMiddlePoint; //todo refactorovat tuhle podminku obecne u vsech middle pointu if (mapMiddleMapPoint.Equals(new LatLngObject())) { mapMiddlePoint = Vector3.zero; UiUtils.SetDefaultCameraPos(mapMiddlePoint, cameraTransform); } else { mapMiddlePoint = Converter.ConvertLatLngToXyz(mapMiddleMapPoint); } //create underground CreateUnderground(mapMiddlePoint); //create terrain var terrainGameObject = new GameObject("TerrainObj"); terrainGameObject.AddComponent <Terrain>(); terrainGameObject.AddComponent <TerrainCollider>(); Terrain = terrainGameObject.GetComponent <Terrain>(); var terrainData = new TerrainData { heightmapResolution = TerrainUtils.MapWidth, size = new Vector3(TerrainUtils.MapWidth, TerrainUtils.MapTopValue, TerrainUtils.MapHeight) }; //load default or elevationAPI terrain float[,] heightsData = Main.Settings.TerrainToggle ? ConvertHeights() : GenerateHeightDemo(); terrainData.SetHeights(0, 0, heightsData); Terrain.terrainData = terrainData; //odkomentovat jen, pokud je vyska terenu vetsi nez 0 // terrainGameObject.GetComponent<TerrainCollider>().terrainData = terrainData; Terrain.materialType = Terrain.MaterialType.BuiltInLegacyDiffuse; AddTexture(Terrain.terrainData, Resources.Load <Texture2D>("Textures/grass_texture")); mapMiddlePoint.x -= TerrainUtils.MapWidth / 2; mapMiddlePoint.y = -0.01f; mapMiddlePoint.z -= TerrainUtils.MapHeight / 2; terrainGameObject.transform.position = mapMiddlePoint; }
/** * Render 3D objects into the scene */ IEnumerator RenderObjects(LatLngObject mapMiddlePoint, List <BuildingObject> buildings, List <RoadObject> roads, List <TreeObject> trees) { while (!CanRenderObjects) { yield return(new WaitForSeconds(0.1f)); } //render terrain TerrainRender.Get().GenerateTerrain(mapMiddlePoint, transform); //render buildings BuildingRender.Get().Render(transform, buildings); //render roads RoadRender.Get().Render(mapMiddlePoint, transform, roads); //render trees TreeRender.Get().GenerateTrees(mapMiddlePoint, trees); //init address info game objects MenuController.Get().AddAddressGameObjects(AddressBackground, AddressText); CanRenderObjects = false; }
/** * Get map middle point and set default camera position */ private LatLngObject GetMiddlePoint(List <BuildingObject> buildings, List <RoadObject> roads) { LatLngObject middleMapPointLatLng = null; if (buildings.Count != 0) { middleMapPointLatLng = TerrainRender.GetMiddlePoint(buildings); } else if (roads.Count != 0) { middleMapPointLatLng = TerrainRender.GetMiddlePoint(roads); } //set default camera position var middlePoint = Converter.ConvertLatLngToXyz(middleMapPointLatLng); UiUtils.SetDefaultCameraPos(middlePoint, transform); return(middleMapPointLatLng); }
/** * */ private RoadObject GetCoordinatesById(XmlNodeList nodeTags, List <long> nodeTagIds, XmlNode wayTag, int vehicleType, int roadType) { //ids for coordinate pairing from way tag var locationIDs = LoaderUtils.GetWayTagIDs(wayTag); var latLngObjects = new LatLngObject[locationIDs.Count]; var numOfFoundedIDs = 0; for (var k = 0; k < nodeTags.Count; k++) { //cached id from node tag var id = nodeTagIds[k]; int locationIndex; if ((locationIndex = locationIDs.IndexOf(id)) != -1) { var nodeTag = nodeTags[k]; var lat = float.Parse(nodeTag.Attributes["lat"].Value); var lon = float.Parse(nodeTag.Attributes["lon"].Value); latLngObjects[locationIndex] = new LatLngObject(lat, lon); ++numOfFoundedIDs; } //pokud všechny souřadnice byly spárovány s IDčkama od budovy if (locationIDs.Count == numOfFoundedIDs) { break; } } var roadObject = new RoadObject { LatLngCoordinates = latLngObjects.ToList(), RoadType = roadType, VehicleType = vehicleType }; return(roadObject); }
protected bool Equals(LatLngObject other) { return(Latitude.Equals(other.Latitude) && Longitude.Equals(other.Longitude)); }
/** * Create trees on the terrain */ public void GenerateTrees(LatLngObject middleMapPoint, List <TreeObject> trees) { Vector3 middleMapXyz; ConiferousTree = Resources.Load("3DObjects/Trees/Prefabs/Fir_Tree", typeof(GameObject)) as GameObject; LeafyTree = Resources.Load("3DObjects/Trees/Prefabs/Poplar_Tree", typeof(GameObject)) as GameObject; //default position, if map does not contain any building or road if (middleMapPoint.Equals(new LatLngObject())) { middleMapXyz = Vector3.zero; } else { middleMapXyz = Converter.ConvertLatLngToXyz(middleMapPoint); } var treeCount = Main.Settings.NumberOfTrees; const float treeScale = 0.06f; var terrain = TerrainRender.Get().Terrain; var random = new Random(); //GENERATE RANDOM TREE POSITIONS if (trees.Count == 0) { for (var i = 0; i < treeCount; i++) { var decimalRandomPartX = random.NextDouble(); var decimalRandomPartZ = random.NextDouble(); const int limitX = (TerrainUtils.MapWidth / 2) - 2; const int limitZ = (TerrainUtils.MapHeight / 2) - 2; var randomX = random.Next((int)(middleMapXyz.x - limitX), (int)(middleMapXyz.x + limitX)); // + 2 a + 1 kvuli korekcim umisteni na hranice terenu var randomZ = random.Next((int)(middleMapXyz.z - limitZ + 2), (int)(middleMapXyz.z + limitZ + 1)); var randomDecX = (float)(randomX + decimalRandomPartX); var randomDecZ = (float)(randomZ + decimalRandomPartZ); var randomPos = new Vector3(randomDecX, 0, randomDecZ); var terrainY = terrain.SampleHeight(randomPos); randomPos.y = terrainY; var randNumberTree = random.Next(0, 2); if (!IsPointInCollision(randomPos)) { GameObject tree; switch (randNumberTree) { case 0: tree = Instantiate(LeafyTree); break; default: tree = Instantiate(ConiferousTree); break; } var treeTransform = tree.transform; treeTransform.position = randomPos; treeTransform.localScale = new Vector3(treeScale, treeScale, treeScale); } else { --i; } } } //CUSTOM TREE POSITIONS else { foreach (var currentTree in trees) { var treePos = Converter.ConvertLatLngToXyz(currentTree.LatLngCoordinate); //if tree is outside the map if (TerrainUtils.IsObjectOutsideMap(treePos, middleMapXyz)) { continue; } //set y position from terrain var terrainY = terrain.SampleHeight(treePos); treePos.y = terrainY; var randNumberTree = random.Next(0, 2); GameObject tree; switch (randNumberTree) { case 0: tree = Instantiate(LeafyTree); break; default: tree = Instantiate(ConiferousTree); break; } var treeTransform = tree.transform; treeTransform.position = treePos; treeTransform.localScale = new Vector3(treeScale, treeScale, treeScale); } } }
/** * Render roads */ public void Render(LatLngObject mapMiddleMapPoint, Transform cameraTransform, List <RoadObject> roads) { if (roads.Count == 0) { return; } var middleMapPoint = Converter.ConvertLatLngToXyz(mapMiddleMapPoint); //save into global variable Roads = roads; var terrain = TerrainRender.Get().Terrain; //render roads for (var i = 0; i < roads.Count; i++) { var ySize = 1; var roadPointInXyz = new Vector3[roads[i].LatLngCoordinates.Count]; if (roadPointInXyz.Length == 0) { continue; } //convert road point from LatLng to Xyz coordination's; Y coordinate values set as terrain height for (var j = 0; j < roadPointInXyz.Length; j++) { roadPointInXyz[j] = Converter.ConvertLatLngToXyz(roads[i].LatLngCoordinates[j]); //pricteni hodnoty navic proti prolinani s terenem roadPointInXyz[j].y = terrain.SampleHeight(roadPointInXyz[j]) + 0.03f; } //road starts outside terrain => reverse points if (TerrainUtils.IsObjectOutsideMap(roadPointInXyz[0], middleMapPoint)) { Array.Reverse(roadPointInXyz); } //points of road for (var j = 0; j < roadPointInXyz.Length; j++) { var roadPoint = roadPointInXyz[j]; //pokud je mezi dvěma body cesty rozdíl větší než 1 if (j == 0 || Math.Abs(roadPoint.x - roadPointInXyz[j - 1].x) >= 1 || Math.Abs(roadPoint.z - roadPointInXyz[j - 1].z) >= 1) { continue; } //snižovat souřadnici Y cesty, pokud je za hranou terénu (efekt padání cesty) if (TerrainUtils.IsObjectOutsideMap(roadPoint, middleMapPoint)) { roadPointInXyz[j].y -= ySize; ySize++; } } //vytvoreni cesty(nastaveni barvy, pozic, poctu pozic...) CreateRoadObject(roads, roadPointInXyz, i); //set cars for road type var carRoads = new[] { RoadUtils.Secondary }; var vehicleTypes = new[] { RoadUtils.VehicleTram }; if (Main.Settings.RoadObjectsToggle && carRoads.Contains(roads[i].RoadType) || vehicleTypes.Contains(roads[i].VehicleType)) { roads[i].XyzCoordinates = roadPointInXyz; RoadObjectRender.Get().RenderObjectsOnRoad(roads[i], middleMapPoint); } UiUtils.SetDefaultCameraPos(middleMapPoint, cameraTransform); } }