internal static VertexIndiceBuffer MakeSphereSegExplicit(GraphicsDevice graphicsDevice, ISector root, double diameter, double minX, double minY, double maxX, double maxY, EditorCamera camera) { Vector3d cameraVector = new LongLat(camera.cameraRotX, camera.cameraRotY).ToSphereVector(); // TODO: this is hacky VertexIndiceBuffer buffer = new VertexIndiceBuffer(); List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>(); double radius = diameter / 2; int verticalSegments = Math.Max((int)((maxY - minY) * 50), 1); int horizontalSegments = Math.Max((int)((maxX - minX) * 50), 1); for (int i = 0; i <= verticalSegments; i++) { double y = (minY + (maxY - minY) * i / (double)verticalSegments); for (int j = 0; j <= horizontalSegments; j++) { double x = (minX + (maxX - minX) * j / (double)horizontalSegments); double tx = j / (double)horizontalSegments; double ty = i / (double)verticalSegments; // stole this equation Vector3d normal = root.ProjectToSphereCoordinates(new Vector2d(x, y)); Vector3d position = normal * (float)radius; // switched dy and dz here to align the poles from how we had them Vector2d texturepos = new Vector2d((float)tx, (float)ty); vertices.Add(new VertexPositionNormalTexture((position - cameraVector).ToVector3(), normal.ToVector3(), texturepos)); } } List <int> indices = MakeIndices(horizontalSegments, verticalSegments); buffer.vertices = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Count, BufferUsage.WriteOnly); buffer.vertices.SetData(vertices.ToArray()); buffer.indices = new IndexBuffer(graphicsDevice, IndexElementSize.ThirtyTwoBits, indices.Count, BufferUsage.WriteOnly); buffer.indices.SetData(indices.ToArray()); return(buffer); }
private void LoadDetailsFromSource(ISector sector) { BlobCollection blobs = OSMReader.GetAllBlobs(sector); foreach (var way in blobs.EnumerateWays(false)) { for (int i = 0; i < way.refs.Count; i++) { long ref1 = way.refs[i]; long ref2 = way.refs[(i + 1) % way.refs.Count]; if (ref1 == ref2) { continue; } Vector2d v1 = blobs.nodes[ref1]; Vector2d v2 = blobs.nodes[ref2]; LongLat longLat1 = new SphereVector(sector.ProjectToSphereCoordinates(v1)).ToLongLat(); LongLat longLat2 = new SphereVector(sector.ProjectToSphereCoordinates(v2)).ToLongLat(); // hmm, this logic will ignore edges that brush up exactly against the top or left of their sector (ex: nodes 6151473219, 6151473220 in way 146849673) // I have to compensate for this elswhere ISector sector1 = GetContainingSector(longLat1, 8); ISector sector2 = GetContainingSector(longLat2, 8); if (!sector1.Equals(sector2)) { var e = new EdgeInfo() { wayID = way.id, node1 = ref1, node2 = ref2, longLat1 = longLat1, longLat2 = longLat2 }; if (!edgeInfo.Contains(e)) { edgeInfo.Add(e); } List <int> wKeys = new List <int>(); List <int> wVals = new List <int>(); foreach (var pair in way.keyValues) { wKeys.Add(LoadIntoStringTable(pair.Key)); wVals.Add(LoadIntoStringTable(pair.Value)); } var w = new WayInfo() { id = way.id, keys = wKeys, values = wVals, startNode = way.refs.First(), endNode = way.refs.Last(), relations = new List <long>() }; if (!wayInfo.ContainsKey(w.id)) { wayInfo[w.id] = w; } } } } HashSet <long> extraWays = new HashSet <long>(); foreach (var relation in blobs.EnumerateRelations()) { foreach (var way in relation.memids) { extraWays.Add(way); if (wayInfo.ContainsKey(way) && !relationInfo.ContainsKey(relation.id)) { List <int> rKeys = new List <int>(); List <int> rVals = new List <int>(); List <int> rRoles = new List <int>(); foreach (var pair in relation.keyValues) { rKeys.Add(LoadIntoStringTable(pair.Key)); rVals.Add(LoadIntoStringTable(pair.Value)); } foreach (var role in relation.roleValues) { rRoles.Add(LoadIntoStringTable(role)); } var r = new RelationInfo() { id = relation.id, keys = rKeys, values = rVals, roleValues = rRoles, memids = relation.memids, types = relation.types }; relationInfo[r.id] = r; } } } foreach (var way in blobs.EnumerateWays(false)) { if (!extraWays.Contains(way.id)) { continue; } List <int> wKeys = new List <int>(); List <int> wVals = new List <int>(); foreach (var pair in way.keyValues) { wKeys.Add(LoadIntoStringTable(pair.Key)); wVals.Add(LoadIntoStringTable(pair.Value)); } var w = new WayInfo() { id = way.id, keys = wKeys, values = wVals, startNode = way.refs.First(), endNode = way.refs.Last() }; if (!wayInfo.ContainsKey(w.id)) { wayInfo[w.id] = w; } } }
private static int[,] ConvertHGTZIPsToShorts(ISector sector) { int BUFFER_SIZE = 10; var fileBytes = new List <KeyValuePair <string, byte[]> >(); int[,] shorts = new int[REZ, REZ]; var exists = new HashSet <string>(); var doesntexist = new HashSet <string>(); for (int x = 0; x < REZ; x++) { for (int y = 0; y < REZ; y++) { // for now, nearest-neighbor var longLat = new SphereVector(sector.ProjectToSphereCoordinates(new Vector2d((0.5 + x) / REZ, (0.5 + y) / REZ))).ToLongLat() * 180 / Math.PI; string filePath; double px, py; // ex: N00E017.SRTMGL1.hgt.zip (note, file name is the coordinate of bottom-left most point) // for some reason for dem, the file name is the coordinate of the top-left most point? if (longLat.Y < -60 || longLat.Y > 60) { int roundX = ((int)((longLat.X + 420) / 40)) * 40 - 420; int roundY = ((int)Math.Ceiling((longLat.Y + 510) / 50)) * 50 - 510; filePath = Path.Combine(@"C:\Users\Geoffrey Hart\Downloads\Source\STRMGL30", $"{(roundX > 0 ? "E" : "W")}{Math.Abs(roundX):D3}{(roundY > 0 ? "N" : "S")}{Math.Abs(roundY):D2}.SRTMGL30.dem.zip"); if (!exists.Contains(filePath) && !doesntexist.Contains(filePath)) { if (File.Exists(filePath)) { exists.Add(filePath); } else { doesntexist.Add(filePath); } } if (exists.Contains(filePath)) { px = (longLat.X - roundX) / 40; py = (1 - (roundY - longLat.Y) / 50); } else { continue; } } else { filePath = Path.Combine(@"C:\Users\Geoffrey Hart\Downloads\Source\STRMGL1", $"{(longLat.Y > 0 ? "N" : "S")}{(int)Math.Abs(Math.Floor(longLat.Y)):D2}{(longLat.X > 0 ? "E" : "W")}{(int)Math.Abs(Math.Floor(longLat.X)):D3}.SRTMGL1.hgt.zip"); if (!exists.Contains(filePath) && !doesntexist.Contains(filePath)) { if (File.Exists(filePath)) { exists.Add(filePath); } else { doesntexist.Add(filePath); } } if (exists.Contains(filePath)) { px = (longLat.X + 360) % 1; py = (longLat.Y + 360) % 1; } else { int roundX = ((int)((longLat.X + 420) / 40)) * 40 - 420; int roundY = ((int)Math.Ceiling((longLat.Y + 510) / 50)) * 50 - 510; filePath = Path.Combine(@"C:\Users\Geoffrey Hart\Downloads\Source\STRMGL30", $"{(roundX > 0 ? "E" : "W")}{Math.Abs(roundX):D3}{(roundY > 0 ? "N" : "S")}{Math.Abs(roundY):D2}.SRTMGL30.dem.zip"); px = (longLat.X - roundX) / 40; py = (1 - (roundY - longLat.Y) / 50); } } if (!fileBytes.Any(z => z.Key == filePath)) { if (fileBytes.Count == BUFFER_SIZE) { fileBytes.RemoveAt(0); } fileBytes.Add(new KeyValuePair <string, byte[]>(filePath, Compression.UnZipToBytes(filePath))); } var bytes = fileBytes.Where(z => z.Key == filePath).Single().Value; int W, H; if (filePath.Contains("hgt")) { int size = (int)Math.Sqrt(bytes.Length / 2); W = size; H = size; } else { W = 600 * 8; H = 750 * 8; } if (W * H * 2 != bytes.Length) { throw new NotImplementedException(); } shorts[x, y] = (int)Sample(bytes, px * (W - 1), (1 - py) * (H - 1), W, H); } } return(shorts); }