public static (int tileId, List <Tile> tiles) GetTiles(int tileId, NpgsqlConnection conn, double extentTile, string geometryTable, string geometryColumn, BoundingBox3D box3d, int epsg, int currentLod, List <int> lods, double[] geometricErrors, string lodcolumn = "", string query = "") { var tiles = new List <Tile>(); var xrange = (int)Math.Ceiling(box3d.ExtentX() / extentTile); var yrange = (int)Math.Ceiling(box3d.ExtentY() / extentTile); for (var x = 0; x < xrange; x++) { for (var y = 0; y < yrange; y++) { if (currentLod == 0) { counter++; var perc = Math.Round((double)counter / (xrange * yrange) * 100, 2); Console.Write($"\rcreating quadtree: {counter}/{xrange * yrange} - {perc:F}%"); } var lodQuery = LodQuery.GetLodQuery(lodcolumn, lods[currentLod]); var from = new Point(box3d.XMin + extentTile * x, box3d.YMin + extentTile * y); var to = new Point(box3d.XMin + extentTile * (x + 1), box3d.YMin + extentTile * (y + 1)); var hasFeatures = BoundingBoxRepository.HasFeaturesInBox(conn, geometryTable, geometryColumn, from, to, epsg, lodQuery, query); if (hasFeatures) { tileId++; var tile = new Tile(tileId, new BoundingBox((double)from.X, (double)from.Y, (double)to.X, (double)to.Y)) { Lod = lods[currentLod], GeometricError = geometricErrors[currentLod] }; if (currentLod < lods.Count - 1) { var newBox3d = new BoundingBox3D((double)from.X, (double)from.Y, (double)box3d.FromPoint().Z, (double)to.X, (double)to.Y, (double)box3d.ToPoint().Z); var new_tiles = GetTiles(tileId, conn, extentTile / 2, geometryTable, geometryColumn, newBox3d, epsg, currentLod + 1, lods, geometricErrors, lodcolumn, query); tile.Children = new_tiles.tiles; tileId = new_tiles.tileId; } tiles.Add(tile); } } } return(tileId, tiles); }
public static List <GeometryRecord> GetGeometrySubset(NpgsqlConnection conn, string geometry_table, string geometry_column, string idcolumn, double[] translation, Tile t, int epsg, string shaderColumn = "", string attributesColumn = "", string lodColumn = "") { var geometries = new List <GeometryRecord>(); var g = GetGeometryColumn(geometry_column, translation); var sqlselect = $"SELECT {idcolumn}, ST_AsBinary({g})"; if (shaderColumn != String.Empty) { sqlselect = $"{sqlselect}, {shaderColumn} "; } if (attributesColumn != String.Empty) { sqlselect = $"{sqlselect}, {attributesColumn} "; } var sqlFrom = "FROM " + geometry_table; var lodQuery = LodQuery.GetLodQuery(lodColumn, t.Lod); var sqlWhere = $" WHERE ST_Intersects(ST_Centroid(ST_Envelope({ geometry_column})), ST_MakeEnvelope({ t.BoundingBox.XMin}, { t.BoundingBox.YMin}, { t.BoundingBox.XMax}, { t.BoundingBox.YMax}, { epsg})) and ST_GeometryType({ geometry_column}) = 'ST_PolyhedralSurface' { lodQuery}"; var sql = sqlselect + sqlFrom + sqlWhere; conn.Open(); var cmd = new NpgsqlCommand(sql, conn); var reader = cmd.ExecuteReader(); var attributesColumnId = int.MinValue; var shadersColumnId = int.MinValue; if (attributesColumn != String.Empty) { attributesColumnId = FindField(reader, attributesColumn); } if (shaderColumn != String.Empty) { shadersColumnId = FindField(reader, shaderColumn); } var batchId = 0; while (reader.Read()) { var id = reader.GetString(0); var stream = reader.GetStream(1); var geom = Geometry.Deserialize <WkbSerializer>(stream); var geometryRecord = new GeometryRecord(batchId) { Id = id, Geometry = geom }; if (shaderColumn != String.Empty) { var json = GetJson(reader, shadersColumnId); geometryRecord.Shader = JsonConvert.DeserializeObject <ShaderColors>(json); } if (attributesColumn != String.Empty) { geometryRecord.Attributes = GetColumnValuesAsList(reader, attributesColumnId); } geometries.Add(geometryRecord); batchId++; } reader.Close(); conn.Close(); return(geometries); }