1package vnext23import "fmt"45// Outline restores the complete semantic catalog except feature rows,6// relationships, provenance payloads, and asset bytes. It is the page-zero7// entry point for clients that subsequently demand-page visible features and8// tiles from the compiled Atlas.9func (reader *Reader) Outline() (Volume, error) {10 tables := make(map[string]Table, len(tableNames())-3)11 for _, name := range tableNames() {12 if name == featureTableName || name == relationshipTableName || name == provenanceTableName {13 continue14 }15 table, err := reader.Table(name)16 if err != nil {17 return Volume{}, err18 }19 tables[name] = table20 }21 root := tables[volumeTableName]22 if root.Rows != 1 {23 return Volume{}, fmt.Errorf("volume table has %d rows", root.Rows)24 }25 volume := Volume{ID: requiredString(root, 0, "volume.id"), Title: requiredString(root, 0, "volume.title")}26 worlds, worldIndex, err := decodeWorlds(tables)27 if err != nil {28 return Volume{}, err29 }30 volume.Worlds = worlds31 if _, err := decodeFeatureSets(&volume, tables, worldIndex); err != nil {32 return Volume{}, err33 }34 if err := decodeWorldDetails(&volume, tables, worldIndex); err != nil {35 return Volume{}, err36 }37 volume.Assets = decodeAssetOutline(tables[assetTableName])38 return volume, nil39}4041func decodeAssetOutline(table Table) []Asset {42 assets := make([]Asset, table.Rows)43 for row := 0; row < table.Rows; row++ {44 assets[row] = Asset{45 ID: requiredString(table, row, "asset.id"), MediaType: requiredString(table, row, "asset.mediaType"),46 Path: requiredString(table, row, "asset.path"), Provenance: optionalStringAt(table, row, "asset.provenance"),47 }48 }49 return assets50}