udbx4go

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 10 Imported by: 0

README

udbx4go

Go Reference Go Report Card Tests Coverage

A Go implementation of the UDBX (Universal Spatial Database Extension) reader/writer library. UDBX is a spatial data format based on SQLite, supporting tabular datasets and vector datasets such as Point, Line, Region, PointZ, LineZ, RegionZ, Text, and CAD.

中文

Features

  • ✅ Core UDBX read/write support, including Text / GeoText and CAD minimal GeoHeader baselines.
  • ✅ Dataset types: Point, Line, Region, PointZ, LineZ, RegionZ, Tabular, Text, CAD
  • ✅ TextDataset supports minimal GeoText read/write CRUD and CadDataset supports minimal GeoHeader GeoPoint / GeoLine / GeoRegion.
  • ✅ 14 field types with proper type mapping
  • ✅ GeoJSON-like geometry model
  • ✅ Streaming and batch operations
  • ✅ Cross-language compatibility (udbx4j, udbx4ts)
  • ✅ Comprehensive error handling
  • ✅ TDD development with 76%+ test coverage
  • ✅ GUI viewer for visualizing UDBX files (Wails-based, React + TypeScript frontend)

Installation

go get github.com/udbx4x/udbx4go

Note: This package requires CGO because it uses github.com/mattn/go-sqlite3. Make sure you have a C compiler installed.

Quick Start

Opening an Existing UDBX File
package main

import (
    "log"
    "github.com/udbx4x/udbx4go"
)

func main() {
    // Open an existing UDBX file
    ds, err := udbx4go.Open("data.udbx")
    if err != nil {
        log.Fatal(err)
    }
    defer ds.Close()

    // List all datasets
    datasets, err := ds.ListDatasets()
    if err != nil {
        log.Fatal(err)
    }
    for _, info := range datasets {
        log.Printf("Dataset: %s (kind: %s)", info.Name, info.Kind)
    }

    // Get a point dataset
    pointDataset, err := ds.GetPointDataset("cities")
    if err != nil {
        log.Fatal(err)
    }

    // Query features
    features, err := pointDataset.List(&udbx4go.QueryOptions{Limit: 10})
    if err != nil {
        log.Fatal(err)
    }
    for _, f := range features {
        log.Printf("Feature %d: %v", f.ID, f.Attributes["name"])
    }
}

GUI Viewer

udbx4go includes a graphical viewer application for visualizing UDBX files. Built with Wails v2 (Go backend + React/TypeScript frontend).

Features
  • Open and browse UDBX files
  • Display dataset list with type icons
  • View data records in paginated table with MUI X-DataGrid
  • Column sorting, resizing, and reordering
  • Support implemented dataset types: Point, Line, Region, PointZ, LineZ, RegionZ, Tabular
  • Geometry preview in GeoJSON format
  • Cross-platform: macOS, Windows, Linux
Prerequisites
  • Go 1.21 or later
  • Node.js 18 or later
  • Wails CLI: go install github.com/wailsapp/wails/v2/cmd/wails@latest
Installation
cd cmd/udbx4go-viewer

# Install frontend dependencies
cd frontend && npm install && cd ..

# Build for current platform
wails build

# Or build for specific platform
wails build -platform darwin/universal
wails build -platform windows/amd64
wails build -platform linux/amd64
Development
cd cmd/udbx4go-viewer

# Run in development mode (with hot reload)
wails dev

# Build with debug info
wails build -debug
Usage
# Run the built app
./build/bin/udbx4go-viewer.app/Contents/MacOS/udbx4go-viewer

# Or open the .app bundle directly
open ./build/bin/udbx4go-viewer.app

Click "选择文件" to open a .udbx file. The dataset list appears on the left, click any dataset to view its records in the table on the right.

Creating a New UDBX File

package main

import (
    "log"
    "github.com/udbx4x/udbx4go"
)

func main() {
    // Create a new UDBX file
    ds, err := udbx4go.Create("newdata.udbx")
    if err != nil {
        log.Fatal(err)
    }
    defer ds.Close()

    // Create a point dataset with custom fields
    fields := []*udbx4go.FieldInfo{
        {Name: "name", FieldType: udbx4go.FieldTypeText, Nullable: true},
        {Name: "population", FieldType: udbx4go.FieldTypeInt32, Nullable: true},
    }

    pointDS, err := ds.CreatePointDataset("cities", 4326, fields)
    if err != nil {
        log.Fatal(err)
    }

    // Insert a feature
    feature := &udbx4go.Feature{
        ID: 1,
        Geometry: &udbx4go.PointGeometry{
            Type:        "Point",
            Coordinates: []float64{116.4, 39.9},
        },
        Attributes: map[string]interface{}{
            "name":       "Beijing",
            "population": 21540000,
        },
    }

    if err := pointDS.Insert(feature); err != nil {
        log.Fatal(err)
    }
}

Dataset Types

Dataset Type Description Geometry
Tabular Attribute-only table None
Point 2D Point dataset Point
Line 2D Line dataset MultiLineString
Region 2D Region dataset MultiPolygon
PointZ 3D Point dataset Point (with Z)
LineZ 3D Line dataset MultiLineString (with Z)
RegionZ 3D Region dataset MultiPolygon (with Z)
Text Text annotation dataset GeoText
CAD CAD dataset Custom GeoHeader (GeoPoint / GeoLine / GeoRegion)

Field Types

Field Type Go Type SQLite Type
Boolean bool INTEGER
Byte int8 INTEGER
Int16 int16 INTEGER
Int32 int32 INTEGER
Int64 int64 INTEGER
Single float32 REAL
Double float64 REAL
Date string TEXT
Time string TEXT
Char string TEXT
Text string TEXT
NText string TEXT
Binary []byte BLOB
Geometry []byte BLOB

CRUD Operations

Point Dataset
// Get by ID
feature, err := pointDS.GetByID(1)
if err != nil {
    if udbx4go.IsNotFound(err) {
        log.Println("Feature not found")
    } else {
        log.Fatal(err)
    }
}

// Insert
newFeature := &udbx4go.Feature{
    ID: 2,
    Geometry: &udbx4go.PointGeometry{
        Type:        "Point",
        Coordinates: []float64{121.5, 31.2},
    },
    Attributes: map[string]interface{}{
        "name":       "Shanghai",
        "population": 26320000,
    },
}
err = pointDS.Insert(newFeature)

// Update
err = pointDS.Update(2, &udbx4go.FeatureChanges{
    Geometry: &udbx4go.PointGeometry{
        Type:        "Point",
        Coordinates: []float64{121.6, 31.3},
    },
    Attributes: map[string]interface{}{
        "population": 26400000,
    },
})

// Delete
err = pointDS.Delete(2)
Line Dataset
lineDS, err := ds.GetLineDataset("roads")

// Insert a line feature
lineFeature := &udbx4go.Feature{
    ID: 1,
    Geometry: &udbx4go.MultiLineStringGeometry{
        Type: "MultiLineString",
        Coordinates: [][][]float64{
            {{116.4, 39.9}, {116.5, 39.8}, {116.6, 39.85}},
        },
    },
    Attributes: map[string]interface{}{
        "name":   "Highway 1",
        "length": 15.5,
    },
}
err = lineDS.Insert(lineFeature)
Region Dataset
regionDS, err := ds.GetRegionDataset("districts")

// Insert a polygon feature
regionFeature := &udbx4go.Feature{
    ID: 1,
    Geometry: &udbx4go.MultiPolygonGeometry{
        Type: "MultiPolygon",
        Coordinates: [][][][]float64{
            {
                {{0, 0}, {10, 0}, {10, 10}, {0, 10}, {0, 0}},
            },
        },
    },
    Attributes: map[string]interface{}{
        "name": "District A",
        "area": 100.0,
    },
}
err = regionDS.Insert(regionFeature)
Tabular Dataset
tabularDS, err := ds.GetTabularDataset("attributes")

// Insert a record
record := &udbx4go.TabularRecord{
    ID: 1,
    Attributes: map[string]interface{}{
        "code":  "ATTR001",
        "value": 99.9,
    },
}
err = tabularDS.Insert(record)

// Update
err = tabularDS.Update(1, map[string]interface{}{
    "value": 100.0,
})

Stable Public API Semantics

udbx4go follows udbx4spec/docs/08-api-stable-surface.md. Go APIs use synchronous calls and (value, error) returns, while preserving the same cross-language behavior as udbx4j and udbx4ts.

Meaning Go API Stable behavior
Open data source Open(path) Open an existing UDBX file
Create data source Create(path) Create UDBX and initialize system tables
List datasets ListDatasets() Return a DatasetInfo list
Get dataset by name GetDataset(name) / typed getters Return not found error when missing
Get object by ID GetByID(id) Return nil, err; udbx4go.IsNotFound(err) must be true when missing
List objects List(options) Return objects ordered by SmID ascending by default
Count Count() Read the physical table row count, not cached SmRegister.SmObjectCount
Write Insert(...) / InsertMany(...) Write objects and synchronize object count
Update Update(id, ...) Return not found when the target is missing; unknown fields return not found or constraint errors
Delete Delete(id) Return not found when the target is missing; synchronize object count after success

Error handling example:

feature, err := pointDS.GetByID(42)
if err != nil {
    if udbx4go.IsNotFound(err) {
        // Dataset, field, record, or feature not found.
        return
    }
    log.Fatal(err)
}
log.Println(feature.ID)

Error Handling

udbx4go provides specific error types for different failure scenarios:

dataset, err := ds.GetDataset("nonexistent")
if err != nil {
    if errors.Is(err, udbx4go.ErrNotFound) {
        // Handle not found
    } else if udbxErr, ok := err.(udbx4go.UdbxError); ok {
        log.Printf("UDBX error [%s]: %v", udbxErr.Code(), err)
    }
}

Specification

This library follows the udbx4spec cross-language specification for compatibility with:

  • udbx4j - Java implementation
  • udbx4ts - TypeScript implementation

Development

Prerequisites
  • Go 1.21 or later
  • C compiler (for SQLite CGO bindings)
Setup
# Clone the repository
git clone https://github.com/udbx4x/udbx4go.git
cd udbx4go

# Install dependencies
go mod download
Testing
# Run all tests
go test ./...

# Run with coverage
go test -cover ./...

# Generate coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
Code Quality
# Format code
go fmt ./...

# Run linter
go vet ./...

# Run with race detection
go test -race ./...

Project Structure

udbx4go/
├── pkg/                    # Public API
│   ├── types/              # Core types (DatasetKind, FieldType, Geometry, etc.)
│   └── errors/             # Error types and handling
├── internal/               # Internal implementation
│   ├── codec/              # Binary codecs (GAIA, CAD)
│   ├── dataset/            # Dataset implementations (Point, Line, Region, Tabular)
│   ├── schema/             # Schema initialization
│   └── system/             # System table DAOs (SmRegister, SmFieldInfo, etc.)
├── cmd/                    # Applications
│   ├── udbx4go-example/    # Example usage
│   └── udbx4go-viewer/     # GUI viewer (Wails-based)
│       ├── main.go         # Entry point (Wails)
│       ├── app.go          # Go backend bindings
│       ├── models.go       # DTO types
│       └── frontend/       # React + TypeScript frontend
│           ├── src/
│           │   ├── App.tsx         # Main app component
│           │   ├── DatasetTree.tsx # Dataset list sidebar
│           │   ├── DataTable.tsx   # MUI X-DataGrid table
│           │   └── main.tsx        # Entry point
│           └── package.json
├── udbx.go                 # Main package with re-exports
└── datasource.go           # DataSource implementation

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please ensure:

  1. All tests pass (go test ./...)
  2. Code coverage is maintained (currently 76%+)
  3. Follow Go best practices (go fmt, go vet)
  4. Run tests with race detector (go test -race ./...)
  5. Add tests for new features
  6. Update documentation as needed
  7. Before a public release, follow the release gates in the workspace root RELEASE.md

Architecture

Core Design Principles
  • Immutable data: Prefer creating new objects over modifying existing ones
  • Interface-based design: Small, focused interfaces for extensibility
  • Error wrapping: All errors include context for debugging
  • TDD approach: Tests are written before implementation
Binary Format

UDBX uses SQLite as the underlying storage with GAIA geometry encoding:

GAIA Point Header (43 bytes):
0x00 | byteOrder(0x01) | srid(int32) | MBR(4×double) | 0x7c | geoType(int32)
System Tables
Table Purpose
SmRegister Dataset metadata (name, kind, bounds, count)
SmFieldInfo Field metadata (name, type, alias, nullable)
geometry_columns Geometry column registration
SmDataSourceInfo File-level metadata

Documentation

Overview

Package udbx4go provides a Go implementation of the UDBX (Universal Spatial Database Extension) reader/writer library. UDBX is a spatial data format based on SQLite.

Basic Usage

Opening an existing UDBX file:

ds, err := udbx4go.Open("data.udbx")
if err != nil {
    log.Fatal(err)
}
defer ds.Close()

Creating a new UDBX file:

ds, err := udbx4go.Create("newdata.udbx")
if err != nil {
    log.Fatal(err)
}
defer ds.Close()

Dataset Types

UDBX supports multiple dataset types:

  • Point: 2D point features
  • Line: 2D line features
  • Region: 2D polygon features
  • PointZ: 3D point features
  • LineZ: 3D line features
  • RegionZ: 3D polygon features
  • Tabular: Non-spatial tables
  • Text: Text annotation features
  • CAD: CAD geometry features

Geometry Model

The library uses a GeoJSON-like geometry model:

  • PointGeometry: {"type": "Point", "coordinates": [x, y]}
  • MultiLineStringGeometry: {"type": "MultiLineString", "coordinates": [...]}
  • MultiPolygonGeometry: {"type": "MultiPolygon", "coordinates": [...]}

Error Handling

All errors implement the UdbxError interface with a Code() method:

  • FormatError: Invalid UDBX format
  • NotFoundError: Dataset or feature not found
  • UnsupportedError: Unsupported operation
  • ConstraintError: Data constraint violation
  • IOError: File I/O error

Example:

dataset, err := ds.GetDataset("cities")
if err != nil {
    if errors.Is(err, udbx4go.ErrNotFound) {
        // Handle not found
    }
}

Specification Compliance

This library follows the udbx4spec cross-language specification for compatibility with Java (udbx4j) and TypeScript (udbx4ts) implementations.

Index

Constants

View Source
const (
	DatasetKindTabular = types.DatasetKindTabular
	DatasetKindPoint   = types.DatasetKindPoint
	DatasetKindLine    = types.DatasetKindLine
	DatasetKindRegion  = types.DatasetKindRegion
	DatasetKindText    = types.DatasetKindText
	DatasetKindPointZ  = types.DatasetKindPointZ
	DatasetKindLineZ   = types.DatasetKindLineZ
	DatasetKindRegionZ = types.DatasetKindRegionZ
	DatasetKindCAD     = types.DatasetKindCAD
)

DatasetKind constants.

View Source
const (
	FieldTypeBoolean  = types.FieldTypeBoolean
	FieldTypeByte     = types.FieldTypeByte
	FieldTypeInt16    = types.FieldTypeInt16
	FieldTypeInt32    = types.FieldTypeInt32
	FieldTypeInt64    = types.FieldTypeInt64
	FieldTypeSingle   = types.FieldTypeSingle
	FieldTypeDouble   = types.FieldTypeDouble
	FieldTypeDate     = types.FieldTypeDate
	FieldTypeBinary   = types.FieldTypeBinary
	FieldTypeGeometry = types.FieldTypeGeometry
	FieldTypeChar     = types.FieldTypeChar
	FieldTypeNText    = types.FieldTypeNText
	FieldTypeText     = types.FieldTypeText
	FieldTypeTime     = types.FieldTypeTime
)

FieldType constants.

Variables

View Source
var (
	IsFormatError         = errors.IsFormatError
	IsNotFound            = errors.IsNotFound
	IsUnsupported         = errors.IsUnsupported
	IsConstraintViolation = errors.IsConstraintViolation
	IsIOError             = errors.IsIOError
	IsUdbxError           = errors.IsUdbxError
)

Error checking functions.

View Source
var (
	ErrNotFound    = errors.ErrNotFound
	ErrFormat      = errors.ErrFormat
	ErrUnsupported = errors.ErrUnsupported
	ErrConstraint  = errors.ErrConstraint
	ErrIO          = errors.ErrIO
)

Sentinel errors.

Functions

This section is empty.

Types

type CadFillStyle

type CadFillStyle = types.CadFillStyle

CadFillStyle represents a CAD fill style.

type CadGeometry

type CadGeometry = types.CadGeometry

CadGeometry represents a minimal CAD GeoHeader geometry.

type CadLineGeometry

type CadLineGeometry = types.CadLineGeometry

CadLineGeometry represents a CAD line geometry.

type CadLineStyle

type CadLineStyle = types.CadLineStyle

CadLineStyle represents a CAD line style.

type CadMarkerStyle

type CadMarkerStyle = types.CadMarkerStyle

CadMarkerStyle represents a CAD marker style.

type CadPointGeometry

type CadPointGeometry = types.CadPointGeometry

CadPointGeometry represents a CAD point geometry.

type CadRegionGeometry

type CadRegionGeometry = types.CadRegionGeometry

CadRegionGeometry represents a CAD region geometry.

type CadStyle

type CadStyle = types.CadStyle

CadStyle represents a CAD GeoHeader style payload.

type Color

type Color = types.Color

Color represents a UDBX Color value in ABGR byte order.

type DataSource

type DataSource struct {
	// contains filtered or unexported fields
}

DataSource represents a UDBX data source.

func Create

func Create(path string) (*DataSource, error)

Create creates a new UDBX file.

func Open

func Open(path string) (*DataSource, error)

Open opens an existing UDBX file.

func (*DataSource) Close

func (ds *DataSource) Close() error

Close closes the data source.

func (*DataSource) CreateCadDataset

func (ds *DataSource) CreateCadDataset(name string, fields []*types.FieldInfo) (*dataset.CadDataset, error)

CreateCadDataset creates a new CAD GeoHeader dataset.

func (*DataSource) CreateLineDataset

func (ds *DataSource) CreateLineDataset(name string, srid int, fields []*types.FieldInfo) (*dataset.LineDataset, error)

CreateLineDataset creates a new 2D line dataset.

func (*DataSource) CreateLineZDataset

func (ds *DataSource) CreateLineZDataset(name string, srid int, fields []*types.FieldInfo) (*dataset.LineZDataset, error)

CreateLineZDataset creates a new 3D line dataset.

func (*DataSource) CreatePointDataset

func (ds *DataSource) CreatePointDataset(name string, srid int, fields []*types.FieldInfo) (*dataset.PointDataset, error)

CreatePointDataset creates a new 2D point dataset.

func (*DataSource) CreatePointZDataset

func (ds *DataSource) CreatePointZDataset(name string, srid int, fields []*types.FieldInfo) (*dataset.PointZDataset, error)

CreatePointZDataset creates a new 3D point dataset.

func (*DataSource) CreateRegionDataset

func (ds *DataSource) CreateRegionDataset(name string, srid int, fields []*types.FieldInfo) (*dataset.RegionDataset, error)

CreateRegionDataset creates a new 2D region dataset.

func (*DataSource) CreateRegionZDataset

func (ds *DataSource) CreateRegionZDataset(name string, srid int, fields []*types.FieldInfo) (*dataset.RegionZDataset, error)

CreateRegionZDataset creates a new 3D region dataset.

func (*DataSource) CreateTabularDataset

func (ds *DataSource) CreateTabularDataset(name string, fields []*types.FieldInfo) (*dataset.TabularDataset, error)

CreateTabularDataset creates a new tabular dataset.

func (*DataSource) CreateTextDataset

func (ds *DataSource) CreateTextDataset(name string, srid int, fields []*types.FieldInfo) (*dataset.TextDataset, error)

CreateTextDataset creates a new Text / GeoText dataset.

func (*DataSource) GetCadDataset

func (ds *DataSource) GetCadDataset(name string) (*dataset.CadDataset, error)

GetCadDataset returns a CAD dataset by name.

func (*DataSource) GetDataset

func (ds *DataSource) GetDataset(name string) (dataset.Dataset, error)

GetDataset returns a dataset by name (generic interface).

func (*DataSource) GetLineDataset

func (ds *DataSource) GetLineDataset(name string) (*dataset.LineDataset, error)

GetLineDataset returns a line dataset by name.

func (*DataSource) GetPointDataset

func (ds *DataSource) GetPointDataset(name string) (*dataset.PointDataset, error)

GetPointDataset returns a point dataset by name.

func (*DataSource) GetRegionDataset

func (ds *DataSource) GetRegionDataset(name string) (*dataset.RegionDataset, error)

GetRegionDataset returns a region dataset by name.

func (*DataSource) GetTabularDataset

func (ds *DataSource) GetTabularDataset(name string) (*dataset.TabularDataset, error)

GetTabularDataset returns a tabular dataset by name.

func (*DataSource) GetTextDataset

func (ds *DataSource) GetTextDataset(name string) (*dataset.TextDataset, error)

GetTextDataset returns a Text dataset by name.

func (*DataSource) ListDatasets

func (ds *DataSource) ListDatasets() ([]*types.DatasetInfo, error)

ListDatasets returns a list of all datasets in the data source.

type DatasetInfo

type DatasetInfo = types.DatasetInfo

DatasetInfo holds metadata about a dataset.

type DatasetKind

type DatasetKind = types.DatasetKind

DatasetKind represents the type of dataset.

type Feature

type Feature = types.Feature

Feature represents a spatial feature.

type FeatureChanges

type FeatureChanges = dataset.FeatureChanges

FeatureChanges holds geometry and attribute changes for vector dataset updates.

type FieldInfo

type FieldInfo = types.FieldInfo

FieldInfo holds metadata about a field.

type FieldType

type FieldType = types.FieldType

FieldType represents the type of a field.

type Geometry

type Geometry = types.Geometry

Geometry is the interface for all geometry types.

type MultiLineStringGeometry

type MultiLineStringGeometry = types.MultiLineStringGeometry

MultiLineStringGeometry represents a MultiLineString geometry.

type MultiPolygonGeometry

type MultiPolygonGeometry = types.MultiPolygonGeometry

MultiPolygonGeometry represents a MultiPolygon geometry.

type PointGeometry

type PointGeometry = types.PointGeometry

PointGeometry represents a Point geometry.

type QueryOptions

type QueryOptions = types.QueryOptions

QueryOptions provides options for querying features.

type TabularRecord

type TabularRecord = types.TabularRecord

TabularRecord represents a non-spatial record.

type TextGeometry

type TextGeometry = types.TextGeometry

TextGeometry represents a UDBX GeoText geometry.

type TextStyle

type TextStyle = types.TextStyle

TextStyle represents GeoText style.

type TextSubText

type TextSubText = types.TextSubText

TextSubText represents a GeoText sub-text object.

type UdbxError

type UdbxError = errors.UdbxError

UdbxError is the interface for all UDBX errors.

Directories

Path Synopsis
cmd
udbx4go-example command
internal
codec
Package codec provides binary codecs for UDBX geometry formats.
Package codec provides binary codecs for UDBX geometry formats.
dataset
Package dataset provides UDBX dataset implementations.
Package dataset provides UDBX dataset implementations.
schema
Package schema provides UDBX database schema initialization.
Package schema provides UDBX database schema initialization.
system
Package system provides DAOs for UDBX system tables.
Package system provides DAOs for UDBX system tables.
pkg
errors
Package errors provides UDBX-specific error types.
Package errors provides UDBX-specific error types.
types
Package types provides core type definitions for udbx4go.
Package types provides core type definitions for udbx4go.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL