geo-engine-go
Official Go SDK for GeoEngine, offering high-performance geospatial data ingestion with single-digit millisecond latency
About geo-engine-go
π¦ Geo-Engine Go SDK
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.Contextsupport 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
| Option | Description |
|---|---|
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.