Grid9 Java Implementation

The Java implementation of Grid9 provides enterprise-grade coordinate compression for JVM-based applications. With comprehensive JUnit test coverage and Java 8+ compatibility, it's perfect for Spring Boot applications, microservices, and large-scale distributed systems.

Key Features: Java 8+ compatible • Maven Central ready • Spring Boot integration • Thread-safe operations • Comprehensive JUnit tests • Zero external dependencies

Installation

Maven

<dependency>
    <groupId>com.grid9</groupId>
    <artifactId>grid9-java</artifactId>
    <version>1.0.0</version>
</dependency>

Gradle

// Gradle (Groovy)
implementation 'com.grid9:grid9-java:1.0.0'

// Gradle (Kotlin DSL)
implementation("com.grid9:grid9-java:1.0.0")

From Source

git clone https://github.com/pedrof69/Grid9.git
cd Grid9/java
mvn clean install

Quick Start

Basic Usage

import com.grid9.UniformPrecisionCoordinateCompressor;

public class LocationExample {
    public static void main(String[] args) {
        // Encode coordinates to Grid9 code
        String code = UniformPrecisionCoordinateCompressor.encode(40.7128, -74.0060);
        System.out.println(code); // "Q7KH2BBYF"
        
        // Decode Grid9 code to coordinates
        double[] coords = UniformPrecisionCoordinateCompressor.decode("Q7KH2BBYF");
        System.out.println("Lat: " + coords[0] + ", Lon: " + coords[1]);
        // Result: Lat: 40.712779, Lon: -74.005988
        
        // Human-readable format
        String readable = UniformPrecisionCoordinateCompressor.encode(40.7128, -74.0060, true);
        System.out.println(readable); // "Q7K-H2B-BYF"
    }
}

Spring Boot Integration

@RestController
@RequestMapping("/api/location")
public class LocationController {
    
    @PostMapping("/encode")
    public ResponseEntity<Map<String, String>> encodeCoordinates(
            @RequestBody CoordinateRequest request) {
        try {
            String code = UniformPrecisionCoordinateCompressor.encode(
                request.getLatitude(), 
                request.getLongitude()
            );
            return ResponseEntity.ok(Map.of("grid9Code", code));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest()
                .body(Map.of("error", e.getMessage()));
        }
    }
    
    @GetMapping("/decode/{code}")
    public ResponseEntity<CoordinateResponse> decodeGrid9(
            @PathVariable String code) {
        try {
            double[] coords = UniformPrecisionCoordinateCompressor.decode(code);
            return ResponseEntity.ok(new CoordinateResponse(coords[0], coords[1]));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }
}

Stream Processing

import java.util.stream.Collectors;
import com.grid9.CoordinateOperations;

public class LocationProcessor {
    public List<String> processLocationStream(List<Location> locations) {
        return locations.stream()
            .filter(loc -> loc.getLatitude() != 0 && loc.getLongitude() != 0)
            .map(loc -> UniformPrecisionCoordinateCompressor.encode(
                loc.getLatitude(), loc.getLongitude()))
            .distinct()
            .collect(Collectors.toList());
    }
    
    // Parallel processing for large datasets
    public List<String> processLargeDataset(List<Location> locations) {
        return locations.parallelStream()
            .map(this::encodeLocation)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
    }
    
    private String encodeLocation(Location loc) {
        try {
            return UniformPrecisionCoordinateCompressor.encode(
                loc.getLatitude(), loc.getLongitude());
        } catch (IllegalArgumentException e) {
            return null; // Skip invalid coordinates
        }
    }
}

API Reference

UniformPrecisionCoordinateCompressor

Method Description Returns
encode(double lat, double lon) Encode coordinates to Grid9 code String
encode(double lat, double lon, boolean humanReadable) Encode with optional formatting String
decode(String code) Decode Grid9 code to coordinates double[] {lat, lon}
calculateDistance(String code1, String code2) Calculate distance in meters double
getNeighbors(String code) Get adjacent Grid9 codes List<String>
isValidEncoding(String code) Validate Grid9 code format boolean
getActualPrecision(double lat, double lon) Get precision information double[] {x, y, total}

CoordinateOperations

Method Description Returns
batchEncode(List<double[]> coordinates) Encode multiple coordinates List<String>
batchDecode(List<String> codes) Decode multiple codes List<double[]>
findNearby(double lat, double lon, double radius) Find codes within radius List<String>

Enterprise Integration

JPA Entity Integration

@Entity
@Table(name = "locations")
public class LocationEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "latitude")
    private Double latitude;
    
    @Column(name = "longitude")
    private Double longitude;
    
    // Computed property for Grid9 code
    @Transient
    public String getGrid9Code() {
        if (latitude != null && longitude != null) {
            return UniformPrecisionCoordinateCompressor.encode(latitude, longitude);
        }
        return null;
    }
    
    // Static method to create from Grid9 code
    public static LocationEntity fromGrid9(String code, String name) {
        double[] coords = UniformPrecisionCoordinateCompressor.decode(code);
        LocationEntity entity = new LocationEntity();
        entity.setName(name);
        entity.setLatitude(coords[0]);
        entity.setLongitude(coords[1]);
        return entity;
    }
}

Spring Data Repository

@Repository
public interface LocationRepository extends JpaRepository<LocationEntity, Long> {
    
    @Query("SELECT l FROM LocationEntity l WHERE " +
           "ABS(l.latitude - :lat) < :delta AND ABS(l.longitude - :lon) < :delta")
    List<LocationEntity> findNearby(@Param("lat") double latitude, 
                                   @Param("lon") double longitude,
                                   @Param("delta") double delta);
}

@Service
public class LocationService {
    
    @Autowired
    private LocationRepository repository;
    
    public List<String> findNearbyGrid9Codes(double lat, double lon, double radiusMeters) {
        // Convert radius to approximate degree delta (rough approximation)
        double delta = radiusMeters / 111000.0; // 1 degree ≈ 111km
        
        return repository.findNearby(lat, lon, delta)
            .stream()
            .map(LocationEntity::getGrid9Code)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
    }
}

Apache Kafka Integration

@Component
public class LocationEventProcessor {
    
    @EventListener
    public void handleLocationUpdate(LocationUpdateEvent event) {
        String grid9Code = UniformPrecisionCoordinateCompressor.encode(
            event.getLatitude(), event.getLongitude());
        
        // Send to Kafka topic with Grid9 code as key for partitioning
        kafkaTemplate.send("location-updates", grid9Code, event);
    }
    
    @KafkaListener(topics = "location-updates")
    public void processLocationEvent(
            @Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) String grid9Code,
            LocationUpdateEvent event) {
        
        // Process events grouped by Grid9 location
        double[] coords = UniformPrecisionCoordinateCompressor.decode(grid9Code);
        processLocationCluster(coords[0], coords[1], event);
    }
}

Performance

Encoding Speed

4.8M+ operations/second

Decoding Speed

5.2M+ operations/second

Memory Usage

Minimal heap allocation

Performance Tuning

// For high-throughput applications, consider caching
public class CachedGrid9Encoder {
    private final LRUCache<String, String> encodeCache = new LRUCache<>(10000);
    private final LRUCache<String, double[]> decodeCache = new LRUCache<>(10000);
    
    public String encode(double lat, double lon) {
        String key = lat + "," + lon;
        return encodeCache.computeIfAbsent(key, k -> 
            UniformPrecisionCoordinateCompressor.encode(lat, lon));
    }
    
    public double[] decode(String code) {
        return decodeCache.computeIfAbsent(code,
            UniformPrecisionCoordinateCompressor::decode);
    }
}

Advanced Features

Geospatial Analysis

public class GeospatialAnalyzer {
    
    public Map<String, Integer> analyzeLocationDensity(List<Location> locations) {
        return locations.stream()
            .collect(Collectors.groupingBy(
                loc -> UniformPrecisionCoordinateCompressor.encode(
                    loc.getLatitude(), loc.getLongitude()),
                Collectors.collectingAndThen(
                    Collectors.counting(),
                    Math::toIntExact
                )
            ));
    }
    
    public List<String> findLocationClusters(List<Location> locations, 
                                           int minClusterSize) {
        Map<String, Integer> density = analyzeLocationDensity(locations);
        
        return density.entrySet().stream()
            .filter(entry -> entry.getValue() >= minClusterSize)
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
    }
}

Microservice Communication

@RestTemplate
public class LocationServiceClient {
    
    @Autowired
    private RestTemplate restTemplate;
    
    public List<String> getNearbyServices(double lat, double lon, double radius) {
        String grid9Code = UniformPrecisionCoordinateCompressor.encode(lat, lon);
        
        // Use Grid9 code in service discovery
        String url = "http://service-registry/api/services/nearby/" + grid9Code + 
                    "?radius=" + radius;
        
        ServiceResponse response = restTemplate.getForObject(url, ServiceResponse.class);
        return response.getServiceEndpoints();
    }
}

Validation and Error Handling

public class LocationValidator {
    
    public static class ValidationResult {
        private final boolean valid;
        private final String errorMessage;
        
        // Constructor and getters...
    }
    
    public ValidationResult validateCoordinates(double lat, double lon) {
        if (lat < -90 || lat > 90) {
            return new ValidationResult(false, 
                "Latitude must be between -90 and 90 degrees");
        }
        if (lon < -180 || lon > 180) {
            return new ValidationResult(false, 
                "Longitude must be between -180 and 180 degrees");
        }
        return new ValidationResult(true, null);
    }
    
    public ValidationResult validateGrid9Code(String code) {
        if (!UniformPrecisionCoordinateCompressor.isValidEncoding(code)) {
            return new ValidationResult(false, "Invalid Grid9 code format");
        }
        return new ValidationResult(true, null);
    }
}

Testing

# Run all tests
mvn test

# Run tests with coverage
mvn test jacoco:report

# Run performance tests
mvn test -Pperformance

# Run specific test class
mvn test -Dtest=UniformPrecisionCoordinateCompressorTest

Requirements

Build and Deployment

Maven Build Lifecycle

# Clean and compile
mvn clean compile

# Run tests and package
mvn clean package

# Install to local repository
mvn clean install

# Deploy to Maven Central (requires credentials)
mvn clean deploy

Docker Integration

# Dockerfile for Spring Boot app with Grid9
FROM openjdk:11-jre-slim

COPY target/my-location-app.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]

# Build and run
docker build -t my-location-app .
docker run -p 8080:8080 my-location-app

Need help? Check out the full source code and examples on GitHub or open an issue.

View on GitHub Back to Home