clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

feat/atlas-next-horizon
atlas / internal / authoring / semantic_budget.go
semantic_budget.go 1.7K
1package authoring23import (4 "fmt"5 "math"67 "github.com/FelineStateMachine/atlas/format/vnext"8)910type semanticCounts struct {11 features int6412 positions int6413}1415func enforceSemanticBudgets(volume vnext.Volume, budgets BuildBudgets) error {16 counts, err := countSemantics(volume)17 if err != nil {18 return err19 }20 if counts.features > budgets.Features {21 return fmt.Errorf("semantic output emits %d features, budget is %d", counts.features, budgets.Features)22 }23 if counts.positions > budgets.GeometryPositions {24 return fmt.Errorf("semantic output emits %d geometry positions, budget is %d", counts.positions, budgets.GeometryPositions)25 }26 return nil27}2829func countSemantics(volume vnext.Volume) (semanticCounts, error) {30 var counts semanticCounts31 for _, world := range volume.Worlds {32 for _, set := range world.FeatureSets {33 var err error34 counts.features, err = checkedSemanticAdd(counts.features, len(set.Features))35 if err != nil {36 return semanticCounts{}, fmt.Errorf("count emitted features: %w", err)37 }38 for _, feature := range set.Features {39 for _, part := range feature.Geometry.Parts {40 for _, ring := range part.Rings {41 counts.positions, err = checkedSemanticAdd(counts.positions, len(ring))42 if err != nil {43 return semanticCounts{}, fmt.Errorf("count emitted geometry positions: %w", err)44 }45 }46 }47 }48 }49 }50 return counts, nil51}5253func checkedSemanticAdd(total int64, count int) (int64, error) {54 if count < 0 || uint64(count) > math.MaxInt64 {55 return 0, fmt.Errorf("count overflows int64")56 }57 increment := int64(count)58 if total > math.MaxInt64-increment {59 return 0, fmt.Errorf("total overflows int64")60 }61 return total + increment, nil62}