GEOCODING.md 3.4 KB

后端反向地理编码 API 规范

接口定义

反向地理编码接口

请求:

GET /api/geocoding/reverse?lat={latitude}&lng={longitude}

参数:

  • lat (必填): 纬度,如 35.6762
  • lng (必填): 经度,如 139.6503

响应 (成功):

{
  "success": true,
  "data": {
    "address": "渋谷区",
    "city": "東京都",
    "district": "渋谷区",
    "country": "日本",
    "latitude": 35.6762,
    "longitude": 139.6503
  }
}

响应 (失败):

{
  "success": false,
  "message": "Geocoding failed"
}

Java 后端实现建议

1. Spring Boot Controller

@RestController
@RequestMapping("/api/geocoding")
public class GeocodingController {

    @Autowired
    private GeocodingService geocodingService;

    @GetMapping("/reverse")
    public ResponseEntity<ApiResponse<GeocodingResult>> reverseGeocode(
        @RequestParam Double lat,
        @RequestParam Double lng
    ) {
        try {
            GeocodingResult result = geocodingService.reverseGeocode(lat, lng);
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (Exception e) {
            return ResponseEntity.ok(ApiResponse.error("Geocoding failed"));
        }
    }
}

2. Service 层(带缓存)

@Service
public class GeocodingService {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${google.maps.api.key}")
    private String googleApiKey;

    @Cacheable(value = "geocoding", key = "#lat + '_' + #lng")
    public GeocodingResult reverseGeocode(Double lat, Double lng) {
        String url = String.format(
            "https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&key=%s&language=ja",
            lat, lng, googleApiKey
        );

        GoogleGeocodingResponse response = restTemplate.getForObject(
            url,
            GoogleGeocodingResponse.class
        );

        if (response != null && "OK".equals(response.getStatus())) {
            return parseGoogleResponse(response);
        }

        throw new RuntimeException("Geocoding failed");
    }

    private GeocodingResult parseGoogleResponse(GoogleGeocodingResponse response) {
        // 解析 Google Maps API 响应
        // ...
        return result;
    }
}

3. 配置缓存(Redis)

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofDays(30)); // 缓存30天

        return RedisCacheManager.builder(factory)
            .cacheDefaults(config)
            .build();
    }
}

4. application.yml

google:
  maps:
    api:
      key: ${GOOGLE_MAPS_API_KEY}

spring:
  redis:
    host: localhost
    port: 6379

优势

  1. 安全: API Key 保存在后端环境变量中
  2. 缓存: 相同坐标不会重复调用 Google API,节省费用
  3. 灵活: 可以随时切换地图服务商(Google/高德/百度)
  4. 监控: 统一记录调用日志,便于分析和优化

前端调用示例

前端只需发送坐标到后端:

const result = await reverseGeocode(35.6762, 139.6503);
// 后端会返回: "渋谷区"

如果后端接口不可用,会自动降级到 Nominatim(免费服务)。