Awesome Go

geo-engine-go

CategoryGeographic
SubcategoryGeographic
Stars0

Official Go SDK for GeoEngine, offering high-performance geospatial data ingestion with single-digit millisecond latency

About geo-engine-go

πŸ“¦ Geo-Engine Go SDK

Go Reference Go Report Card License: MIT Go Tests

Read this in Spanish: README.es.md

Official idiomatic Go client for the Geo-Engine platform.
Designed for high performance, thread safety, and seamless integration into backend microservices over HTTP REST and gRPC.

✨ Features

  • πŸ“ Real-time sub-10ms location ingestion (HTTP REST & gRPC).
  • πŸ—ΊοΈ High-performance Spatial Validation module for point-in-polygon queries (single & general).
  • 🚧 Dynamic geofence creation and management backed by PostGIS spatial queries.
  • ⚑ Native context.Context support for timeouts, deadlines, and cancellation.
  • πŸ”„ Thread-safe asynchronous worker pool for high-throughput batching.
  • πŸ›‘οΈ Built-in HMAC-SHA256 signature generation for anti-replay protection.
  • 🧩 Minimal dependencies: only standard library and official gRPC/Protobuf packages.

πŸš€ Installation

Use go get to install the SDK:

go get github.com/AlexG695/geo-engine-go/v2

⚑ Quick Start

Send a device location in just a few lines:

package main

import (
    "context"
    "log"
    "time"

    geoengine "github.com/AlexG695/geo-engine-go/v2"
)

func main() {
    client := geoengine.New("sk_live_123456")
    defer client.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    err := client.SendLocation(ctx, "truck-01", 19.4326, -99.1332)
    if err != nil {
        log.Fatalf("Error sending location: %v", err)
    }

    log.Println("Location sent successfully")
}

πŸ—ΊοΈ Spatial Module & Point Validation

The client.Spatial module connects directly to the GeoEngine API service to perform point-in-polygon evaluations with the best DX:

Single Geofence Validation

res, err := client.Spatial.ValidatePoint(ctx, "geofence_123", 19.4326, -99.1332)
if err != nil {
    if errors.Is(err, geoengine.ErrGeofenceNotFound) {
        log.Println("Geofence not found")
        return
    }
    log.Fatalf("Spatial error: %v", err)
}

if res.IsInside() {
    log.Printf("Device is inside %s (%s)!", res.GeofenceName, res.GeofenceID)
} else {
    log.Println("Device is outside the geofence")
}

General Geofence Validation (All Geofences)

res, err := client.Spatial.ValidateGeneral(ctx, 19.4326, -99.1332)
if err != nil {
    log.Fatalf("General validation failed: %v", err)
}

if res.HasMatches() {
    log.Printf("Matched %d geofences: %v", res.TotalMatches, res.GeofenceNames())
    if res.ContainsGeofence("CDMX Downtown") {
        log.Println("Device is in CDMX Downtown")
    }
}

Fluent Query Builder

// Fluent syntax for maximum readability
res, err := client.Spatial.Check(19.4326, -99.1332).
    InGeofence("geofence_123").
    ExecuteSingle(ctx)

generalRes, err := client.Spatial.Check(19.4326, -99.1332).
    InAllGeofences().
    ExecuteGeneral(ctx)

πŸ”§ Advanced Configuration

The client uses the Functional Options pattern for clean configuration:

client := geoengine.New(
    "sk_test_123456",
    geoengine.WithEnvironment("test"),
    geoengine.WithAPIServiceURL("https://api.geoengine.dev"),
    geoengine.WithTimeout(2 * time.Second),
)

Available Options

OptionDescription
WithAPIKey(key string)Sets the API key for execution
WithJWTToken(token string)Sets the Bearer JWT token for authenticated batch sessions
WithEnvironment(env string)Configures the execution target ("live" or "test")
WithAPIServiceURL(url string)Overrides the API service URL for spatial operations
WithIngestURL(url string)Overrides the ingestion REST endpoint
WithGRPCAddress(addr string)Overrides the default gRPC server target address
WithManagementURL(url string)Overrides the control plane management endpoint
WithBaseURL(url string)Overrides ingest, management, and API service endpoints (for testing)
WithTimeout(d time.Duration)Sets the HTTP client timeout
WithHTTPClient(client *http.Client)Configures a custom *http.Client (tracing, proxies)
WithBatchConfig(size, interval)Configures buffer limits for the background async worker

πŸ”„ High-Throughput Async Batch Ingestion

For high-volume fleet tracking or IoT telemetry, use the background worker:

package main

import (
    "time"

    geoengine "github.com/AlexG695/geo-engine-go/v2"
    geopb "github.com/AlexG695/geo-engine-go/v2/proto/geopb"
)


func main() {
    client := geoengine.New("sk_live_123456")
    defer client.Close()

    // Buffer: 5000 pings, Batch size: 100, Flush interval: 500ms
    ingester := geoengine.NewAsyncIngester(client, 5000, 100, 500*time.Millisecond)
    defer ingester.Stop()

    ok := ingester.Enqueue(&geopb.LocationPing{
        DeviceId:  "vehicle-scooter-09",
        Latitude:  19.4326,
        Longitude: -99.1332,
        Timestamp: time.Now().UnixMilli(),
    })
    if !ok {
        // Handle buffer queue full or ingester stopped
    }
}

πŸ§ͺ Testing

Run the unit tests with race detection using standard Go tooling:

go test -v -race -cover ./...

πŸ“„ License

MIT Β© Geo-Engine Team

Frequently Asked Questions

What is geo-engine-go?

geo-engine-go is a Geographic library for the Go programming language. Official Go SDK for GeoEngine, offering high-performance geospatial data ingestion with single-digit millisecond latency

How do I install geo-engine-go?

Install geo-engine-go with the Go module system using `go get AlexG695/geo-engine-go`. Check the repository for the current installation instructions.

What category does geo-engine-go belong to?

geo-engine-go is listed under Geographic, specifically Geographic.

← Back to Geographic