The first open, vendor-neutral gRPC protocol specification for geospatial services.
🗺️ High-performance binary protocol optimized for spatial data 🔧 Strongly-typed interface definitions preventing runtime errors 📡 Streaming capabilities for large dataset handling 🤝 Real-time collaboration features for modern workflows 🌐 Vendor-neutral specification preventing lock-in
This project establishes the gRPC for the masses in geospatial software - a modern alternative to fragmented, vendor-specific protocols that create lock-in and limit interoperability.
Strategic Goals:
- Pioneer the first open gRPC geospatial standard
- Submit to OGC as next-generation protocol specification
- Present at FOSS4G 2026 with industry adoption examples
- Enable vendor-neutral ecosystem development
- Democratize high-performance geospatial development
- FeatureService: CRUD operations on spatial features
- FormService: Mobile data collection and form management
- MapService (planned): Tile generation and map rendering
- GeometryService (planned): Spatial operations and projections
- CollaborationService (planned): Real-time multi-user editing
- Binary Protocol Efficiency: 60-80% payload reduction vs JSON/XML
- Mobile Data Collection: Complete form-based field data collection (alternative to OpenRosa)
- 12 Spatial Relationships: Complete OGC Simple Features support
- Streaming Support: Memory-efficient processing of large datasets
- Strong Typing: Compile-time validation prevents runtime errors
- Real-time Collaboration: Multi-user form editing with conflict resolution
- Multi-language Support: Auto-generated clients for Go, Python, .NET, TypeScript
# buf.yaml
name: buf.build/your-org/your-project
deps:
- buf.build/geospatial/standard:v0.1.0buf generate# Clone repository
git clone https://github.com/mikemcdougall/geospatial-grpc-standard.git
cd geospatial-grpc-standard
# Install buf
brew install bufbuild/buf/buf
# Validate and generate
buf lint
buf generate
# Generated code available in reference-implementations/Once you have buf.build access:
# Setup the registry (requires buf.build account)
./scripts/setup-registry.sh v0.1.0import { FeatureServiceClient } from '@geospatial/grpc-standard';
const client = new FeatureServiceClient('your-server.com:443');
const response = await client.queryFeatures({
serviceId: 'my-service',
layerId: 1,
where: 'population > 100000'
});
console.log(`Found ${response.features.length} features`);import grpc
from geospatial.v1 import feature_service_pb2_grpc as fs_grpc
from geospatial.v1 import feature_service_pb2 as fs_pb2
channel = grpc.secure_channel('your-server.com:443', grpc.ssl_channel_credentials())
client = fs_grpc.FeatureServiceStub(channel)
request = fs_pb2.QueryFeaturesRequest(
service_id='my-service',
layer_id=1,
where='population > 100000'
)
response = client.QueryFeatures(request)
print(f"Found {len(response.features)} features")package main
import (
"context"
"crypto/tls"
"fmt"
pb "github.com/geospatial-grpc/standard/gen/go/geospatial/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
func main() {
creds := credentials.NewTLS(&tls.Config{})
conn, _ := grpc.Dial("your-server.com:443", grpc.WithTransportCredentials(creds))
defer conn.Close()
client := pb.NewFeatureServiceClient(conn)
response, _ := client.QueryFeatures(context.Background(), &pb.QueryFeaturesRequest{
ServiceId: "my-service",
LayerId: 1,
Where: "population > 100000",
})
fmt.Printf("Found %d features\n", len(response.Features))
}using Grpc.Net.Client;
using Geospatial.V1;
using var channel = GrpcChannel.ForAddress("https://your-server.com:443");
var client = new FeatureService.FeatureServiceClient(channel);
var request = new QueryFeaturesRequest
{
ServiceId = "my-service",
LayerId = 1,
Where = "population > 100000"
};
var response = await client.QueryFeaturesAsync(request);
Console.WriteLine($"Found {response.Features.Count} features");The FormService provides a modern, gRPC-native alternative to OpenRosa XML forms, optimized for mobile field data collection:
import { FormServiceClient } from '@geospatial/grpc-standard';
const formClient = new FormServiceClient('your-server.com:443');
// Get form definition for mobile rendering
const formResponse = await formClient.getFormDefinition({
formId: 'asset-inspection',
serviceId: 'utility-assets',
layerId: 1,
mobileCapabilities: {
hasCamera: true,
hasGps: true,
platform: 'ios',
networkType: 'CELLULAR'
}
});
// Submit completed form as feature
const submission = await formClient.submitFormData({
formId: 'asset-inspection',
instance: {
fieldValues: {
'asset_id': { stringValue: 'POLE-12345' },
'condition': { stringValue: 'Good' },
'photo': { stringValue: 'captured-photo.jpg' },
'location': { stringValue: 'POINT(-122.4194 37.7749)' }
}
},
attachments: [photoAttachment],
metadata: {
deviceId: 'mobile-device-123',
platform: 'ios',
latitude: 37.7749,
longitude: -122.4194
}
});
console.log(`Created feature ${submission.createdFeatureId}`);from geospatial.v1 import form_service_pb2_grpc as form_grpc
from geospatial.v1 import form_service_pb2 as form_pb2
# Get form definition
form_client = form_grpc.FormServiceStub(channel)
form_request = form_pb2.GetFormDefinitionRequest(
form_id='field-survey',
service_id='environmental-data',
layer_id=2,
mobile_capabilities=form_pb2.MobileCapabilities(
has_camera=True,
has_gps=True,
platform='android',
network_type=form_pb2.NETWORK_TYPE_WIFI
)
)
form_response = form_client.GetFormDefinition(form_request)
# Submit form data
submission = form_pb2.SubmitFormDataRequest(
form_id='field-survey',
instance=form_pb2.FormInstance(
field_values={
'species': form_pb2.AttributeValue(string_value='Douglas Fir'),
'height_meters': form_pb2.AttributeValue(double_value=25.5),
'health_rating': form_pb2.AttributeValue(int32_value=4)
}
)
)
result = form_client.SubmitFormData(submission)using Geospatial.V1;
var formClient = new FormService.FormServiceClient(channel);
// Get form optimized for mobile device
var formRequest = new GetFormDefinitionRequest
{
FormId = "infrastructure-inspection",
ServiceId = "city-assets",
LayerId = 3,
MobileCapabilities = new MobileCapabilities
{
HasCamera = true,
HasGps = true,
Platform = "windows",
DeviceType = "tablet",
NetworkType = NetworkType.Wifi
}
};
var formResponse = await formClient.GetFormDefinitionAsync(formRequest);
// Submit with photo attachment
var submission = new SubmitFormDataRequest
{
FormId = "infrastructure-inspection",
Instance = new FormInstance
{
FieldValues = {
{ "asset_type", new AttributeValue { StringValue = "Bridge" } },
{ "condition_score", new AttributeValue { Int32Value = 8 } },
{ "inspection_date", new AttributeValue { DatetimeValue = DateTimeOffset.Now.ToUnixTimeMilliseconds() } }
}
},
Attachments = { photoAttachment }
};
var result = await formClient.SubmitFormDataAsync(submission);Geometry Types (OGC Simple Features):
- Point, MultiPoint
- LineString (Polyline), MultiLineString
- Polygon, MultiPolygon
Spatial Operations:
- 12 spatial relationships (Intersects, Contains, Within, etc.)
- On-the-fly coordinate transformations
- Spatial filtering with buffer support
- Statistical aggregations
Streaming Patterns:
// Server streaming for large datasets
rpc QueryFeaturesStream(QueryFeaturesRequest) returns (stream FeaturePage);
// Bidirectional streaming for real-time collaboration (planned)
rpc CollaborateStream(stream Operation) returns (stream OperationResult);- Binary Encoding: 60-80% smaller payloads vs JSON
- HTTP/2 Multiplexing: Multiple concurrent operations per connection
- Streaming Support: Handle datasets larger than memory
- Connection Reuse: Eliminate connection overhead
- Compression: Built-in gzip/brotli support
vs. Esri ArcGIS REST Services:
- 10x better performance on mobile networks
- Strong typing eliminates runtime errors
- Streaming prevents memory exhaustion
- Vendor-neutral protocol
vs. OGC WFS/WCS:
- Modern HTTP/2 transport
- Efficient binary encoding
- Real-time capabilities
- Developer-friendly tooling
OGC Submission Path:
- RFC development with community input
- Industry implementation validation
- Standards working group participation
- Next-generation protocol adoption
✅ Feature Service: Complete CRUD operations with ApplyEdits ✅ Form Service: Mobile data collection (alternative to OpenRosa) ✅ Spatial Filtering: 12 relationship types ✅ Streaming Support: Large dataset handling ✅ Real-time Collaboration: Multi-user form editing ✅ Multi-language: Go, Python, .NET generation ✅ Mobile Optimization: Device-aware form rendering ✅ Protocol Documentation: Comprehensive specification ⏳ Map Service: Tile generation (planned) ⏳ Geometry Service: Spatial operations (planned) ⏳ buf.build Registry: Public package distribution (in setup)
Q2 2026:
- Map Service specification and implementation
- JavaScript/TypeScript client libraries
- Performance benchmarking framework
- Migration tools from proprietary formats
Q3 2026:
- Real-time collaboration services
- Geometry service spatial operations
- OGC standards submission preparation
- FOSS4G 2026 presentation preparation
We welcome contributions from the geospatial community! See our Contributing Guide for:
- Protocol design feedback
- Reference implementations
- Performance optimizations
- Documentation improvements
- Migration tools
- Map Service specification and implementation
- JavaScript/TypeScript client generation
- Java/Kotlin Android compatibility
- Performance benchmarks vs existing protocols
- Migration guides from Esri/OGC services
- GitHub Issues: Feature requests and bug reports
- GitHub Discussions: Community Q&A and design discussions
- Documentation: Complete specification
- Discord: Real-time development chat (planned)
Licensed under the Apache License 2.0 - see the full license text for details.
Copyright © 2026 Geospatial gRPC Standard Contributors
This project emerged from the Honua Server open-source geospatial platform, demonstrating production-ready gRPC geospatial services at scale.
Ready to revolutionize geospatial protocols? Get started with the specification or contribute to the project! 🚀