private static Box3d ReadBox3d(XElement e, string tagName) { return(Box3d.Parse(e.Element(tagName).Value.Trim())); }
private static void Test(string dirname) { var metaFileName = Path.GetFullPath(@"meta.json"); var meta = JArray .Parse(File.ReadAllText(metaFileName)) .Select(x => ( filename: (string)x["FileName"], count: (long)x["Count"], bounds: Box3d.Parse((string)x["Bounds"]) )) .ToArray() ; var area = meta.Sum(x => x.bounds.Size.X * x.bounds.Size.Y) / 1000000.0; WriteLine($"area: {area:N3} km²"); var bounds = new Box3d(meta.Select(x => x.bounds)); WriteLine($"bounds: {bounds}"); const double TILE_SIZE = 256.0; var OFFSET = new V3d(0, 0, 50); bounds = bounds + OFFSET; if (bounds.Size.Z > TILE_SIZE) { throw new InvalidOperationException(); } var bb = new Box3d((bounds.Min / 256).Floor * 256, (bounds.Max / 256).Ceiling * 256); WriteLine($"bounds: {bb}"); var minIncl = new V2l(bb.Min.X / TILE_SIZE, bb.Min.Y / TILE_SIZE); var maxExcl = new V2l(bb.Max.X / TILE_SIZE + 1, bb.Max.Y / TILE_SIZE + 1); WriteLine($"a: {new Cell(minIncl.X, minIncl.Y, 0, 8).BoundingBox}"); WriteLine($"b: {new Cell(maxExcl.X, maxExcl.Y, 0, 8).BoundingBox}"); var maxCount = 0L; var i = 0; var importConfig = ParseConfig.Default.WithMaxChunkPointCount(16 * 1024 * 1024); for (var cx = minIncl.X; cx < maxExcl.X; cx++) { for (var cy = minIncl.Y; cy < maxExcl.Y; cy++) { i++; var localCell = new Cell(cx, cy, 0, 8); var localBounds = localCell.BoundingBox - OFFSET; var candidates = meta.Where(x => x.bounds.Intersects(localBounds)).ToArray(); if (candidates.Length > 0) { var key = $"cell_{localCell.X}_{localCell.Y}_{localCell.Z}_{localCell.Exponent}"; var targetFilename = $"G://{key}.bin"; var targetFilenameTmp = $"{targetFilename}.tmp"; if (File.Exists(targetFilename)) { WriteLine($"[{i,6:N0}] {targetFilename} already exists"); continue; } var sw = new Stopwatch(); sw.Start(); var localCount = candidates.Sum(x => x.count); if (localCount > maxCount) { maxCount = localCount; } var chunks = candidates .SelectMany(x => Aardvark.Data.Points .Import.Laszip.Chunks(Path.Combine(dirname, x.filename), importConfig) .Select(y => y.ImmutableFilterByPosition(localBounds.Contains)) ) .Where(x => x.Count > 0) .Select(x => new Chunk(x.Positions, x.Colors)) .ToArray() ; if (chunks.Sum(x => x.Count) == 0) { continue; } //var store = PointCloud.OpenStore($"T:/Koeln/{key}.bin"); //PointCloud.Chunks(chunks, ImportConfig.Default.WithStorage(store).WithKey(key)); var countWritten = 0L; using (var f = File.OpenWrite(targetFilenameTmp)) using (var z = new GZipStream(f, CompressionMode.Compress)) using (var bw = new BinaryWriter(z)) { var o = chunks.First().Positions[0]; bw.Write(o.X); bw.Write(o.Y); bw.Write(o.Z); bw.Write(chunks.Sum(x => (long)x.Count)); foreach (var chunk in chunks) { var chunk2 = chunk.ImmutableFilterSequentialMinDistL1(0.01); if (chunk2.Count == 0) { continue; } var ps = chunk2.Positions.Map(p => (V3f)(p - o).Round(2)); for (var j = 0; j < ps.Length; j++) { var p = ps[j]; bw.Write(p.X); bw.Write(p.Y); bw.Write(p.Z); countWritten++; } for (var j = 0; j < chunk2.Count; j++) { var c = chunk2.Colors[j]; bw.Write(c.R); bw.Write(c.G); bw.Write(c.B); } } } File.Move(targetFilenameTmp, targetFilename); WriteLine($"[{i,6:N0}] {localCell,6} -> {candidates.Length,6:N0} -> {localCount,15:N0} {chunks.Sum(x => x.Count),15:N0} {countWritten,15:N0} ({sw.Elapsed})"); } } } WriteLine(i); }
/// <summary></summary> public static FilterInsideBox3d Deserialize(JObject json) => new FilterInsideBox3d(Box3d.Parse((string)json["Box"]));