0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【flutter(location)】位置情報の取得・距離計算

Posted at

表題の件、やってみた。

テスト環境の整備

  1. 基本は公式を見て設定すればOK
  2. 公式の設定だけではエラーが出たので追加(見逃しただけかも)
    Android の場合
       kotlin_version が最新じゃないといけないっぽい
       Kotlin_version : 1.9.0

コード

エミュレーターを起動して、"距離を計算する!"をクリックすればデバッグコンソールに計算結果が出てくる。

main


import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:location_sample/location.dart';



void main() {
	runApp(
		const ProviderScope(
      child: MaterialApp(home: MyApp(),)
		),
	);
}



class MyApp extends ConsumerStatefulWidget {
	const MyApp({super.key});

	@override
	ConsumerState<ConsumerStatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends ConsumerState<MyApp> {

	@override
	Widget build(BuildContext context) {

    bool isGetLocate = ref.watch( isGetLocateProvider );

    if ( isGetLocate ) {
      return Center(
        child: TextButton(
          child     : const Text( "距離を計算する!!" ),
          onPressed : () {
            final myLocateData = ref.watch( isLocateProvider )!;
            double  lon1 = myLocateData.longitude!;
            double  lat1 = myLocateData.latitude!;
            double  lon2 = 130.0;
            double  lat2 = 45.0;
            double  dist = calcDistance( lon1, lat1, lon2, lat2 );
            debugPrint( "x1 : $lon1    y2 : $lat1" );
            debugPrint( "x2 : $lon2    y2 : $lat2" );
            debugPrint( "dist : $dist" );
          },
        )
      );
    } else { return const Placeholder(); }

	}
}

location.dart


// flutter pub run build_runner build --delete-conflicting-outputs

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

import 'package:location/location.dart';

part 'location.freezed.dart';



// 
// State
// 
@freezed
class LocateState with _$LocateState {
	factory LocateState({
		
		required				Location			location,
		@Default(null)  LocationData? locateData,
		@Default(false)	bool					isGetLocation

	}) = _LocateState;

}


// 
// Notifier
// 
class LocationCnrl extends AsyncNotifier<LocateState> {

// 初期化
	@override
	Future<LocateState> build() async {

		Location			location		= Location();
		location.enableBackgroundMode( enable: true );
	
		bool							serviceEnabled;
		PermissionStatus	permissionGranted;

		// 位置情報使える?
		serviceEnabled = await location.serviceEnabled();
		if ( !serviceEnabled ) {
			serviceEnabled = await location.requestService();
			if ( !serviceEnabled ) {
				debugPrint( "位置情報が利用できません。。。" );
				return LocateState(
					location			: location,
					locateData		: null,
					isGetLocation	: false
				);
			}
		}

		// アプリに許可してる?
		permissionGranted = await location.hasPermission();
		if ( permissionGranted == PermissionStatus.denied ) {
			permissionGranted = await location.requestPermission();
			if ( permissionGranted != PermissionStatus.granted ) {
				debugPrint( "このアプリに対して位置情報の利用許可がおりていません。。。" );
				return LocateState(
					location		: location,
					locateData	: null,
					isGetLocation	: false
				);
			}
		}
		
		debugPrint( "正常に位置情報を取得しました!" );
		return LocateState(
			location			: location,
			locateData		: await location.getLocation(),
			isGetLocation	: true
		);

	}

// =============================================================================
// ログイン関係
// =============================================================================

// 変数の更新
	void updateState() async
	{

		state.when(
			error   : (e,s) => state = AsyncValue.error(e,s),
			loading : ()    => state = const AsyncValue.loading(),
			data    : (tmp) {
				tmp.location.onLocationChanged.listen( ( LocationData currentLocation ) {
					tmp	= tmp.copyWith( locateData: currentLocation );
				});
			}
		);
	}

}


// 
// Provider
// 
final userProvider = AsyncNotifierProvider<LocationCnrl, LocateState>(() {
	return LocationCnrl();
});

// 位置情報データ
final isLocateProvider = Provider<LocationData?>( ( ref ) =>
	ref.watch( userProvider ).when(
		error   : (e,s)   => null,
		loading : ()      => null,
		data    : (data)  => data.locateData
	)
);

// 位置情報はとれてる?
final isGetLocateProvider = Provider<bool>( ( ref ) =>
	ref.watch( userProvider ).when(
		error   : (e,s)   => false,
		loading : ()      => false,
		data    : (data)  => true
	)
);



// 
// function
// 

double calcDistance( double lon1, double lat1, double lon2, double lat2 ) {

	double x1	= lon1 / 180 * 3.14;
	double y1	= lat1 / 180 * 3.14;
	double x2	= lon2 / 180 * 3.14;
	double y2	= lat2 / 180 * 3.14;


	return 6378.137 * acos(
		( sin( y1 ) * sin( y2 ) ) +	( cos( y1 ) * cos( y2 ) * cos( x2 - x1 ) )
	);
}


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?