코딩/♠♠기술 구현

geodecoding 위치 한글로 변경

흑백 개발자 2024. 11. 21. 07:01
728x90

Flutter 실시간 위치 기반 주소 변환 구현

핵심 구현 내용

  1. 실시간 위치 추적
  2. 위도/경도를 한글 주소로 동적 변환
  3. Stream을 활용한 실시간 업데이트

상세 구현 과정

  1. 위치 데이터 모델 설계
class LocationData {
  final Position position;        // 위도/경도 정보
  final String address;          // 변환된 한글 주소
  final DateTime timestamp;      // 업데이트 시간
  
  LocationData({
    required this.position,
    required this.address,
    DateTime? timestamp,
  }) : timestamp = timestamp ?? DateTime.now();
}

2. 위치-주소 변환 처리 (Geocoding)

Future<String> getAddressFromPosition(Position position) async {
  try {
    List<Placemark> placemarks = await placemarkFromCoordinates(
      position.latitude,
      position.longitude,
    );

    if (placemarks.isNotEmpty) {
      Placemark place = placemarks[0];
      // 행정구역 + 하위지역명으로 주소 구성
      return '${place.administrativeArea ?? ''} ${place.subLocality ?? ''}'.trim();
    }
    return '주소를 찾을 수 없습니다';
  } catch (e) {
    return '주소 변환 중 오류 발생';
  }
}

3.실시간 위치 스트림 처리

Stream<LocationData> getLocationDataStream() {
  return Geolocator.getPositionStream(
    locationSettings: const LocationSettings(
      accuracy: LocationAccuracy.high,
      distanceFilter: 30,  // 30m 이상 이동시 업데이트
    ),
  ).asyncMap((position) async {
    final address = await getAddressFromPosition(position);
    return LocationData(position: position, address: address);
  });
}

4.BLoC 패턴을 활용한 상태 관리

class LocationBloc extends Bloc<LocationEvent, LocationState> {
  final LocationRepository _repository;
  StreamSubscription<LocationData>? _locationSubscription;

  // 위치 업데이트 시작
  on<StartLocationUpdates>((event, emit) async {
    _locationSubscription = _repository.getLocationDataStream().listen(
      (locationData) {
        add(_LocationDataReceived(locationData));
      },
    );
  });

  // 위치 데이터 수신 시 상태 업데이트
  on<_LocationDataReceived>((event, emit) {
    emit(LocationSuccess(
      position: event.locationData.position,
      address: event.locationData.address,
    ));
  });
}

5.UI에서 동적 표시

class LocationWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<LocationBloc, LocationState>(
      builder: (context, state) {
        if (state is LocationSuccess) {
          return Text(state.address); // 예: "성남시 분당구"
        }
        return Text('위치 확인 중...');
      },
    );
  }
}

주요 특징

  1. 실시간성
    • Stream을 활용한 지속적인 위치 모니터링
    • 사용자 이동에 따른 자동 주소 업데이트
  2. 최적화
    • 불필요한 업데이트 방지를 위한 거리 기반 필터링
    • 중복 데이터 제거로 성능 향상
  3. 에러 처리
    • 위치 서비스 비활성화 대응
    • 주소 변환 실패 시 적절한 피드백
  4. 사용자 경험
    • 부드러운 상태 전환
    • 로딩 상태 표시
    • 직관적인 한글 주소 표시

기술적 고려사항

  1. 리소스 관리
    • StreamSubscription 적절한 해제
    • 메모리 누수 방지
  2. 성능 최적화
    • 불필요한 API 호출 최소화
    • 효율적인 상태 업데이트
  3. 배터리 효율성
    • 위치 업데이트 간격 최적화
    • 백그라운드 처리 고려
728x90