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?

Flutterで現在地から1km以内のコンビニを取得する

Posted at

はじめに

表題通り、GoogleMapAPIで現在地から1km以内のコンビニを取得する。

成果物

→1km以内のコンビニにマップを設定しています。

ソースコード

lib/main.dart
import 'package:flutter/material.dart';
import 'screens/nearby_places_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: NearbyPlacesScreen(),
    );
  }
}
lib/screens/nearby_places_screen.dart
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../services/location_service.dart';
import '../services/places_service.dart';
import '../models/place.dart';

class NearbyPlacesScreen extends StatefulWidget {
  @override
  _NearbyPlacesScreenState createState() => _NearbyPlacesScreenState();
}

class _NearbyPlacesScreenState extends State<NearbyPlacesScreen> {
  List<Place> _places = [];
  bool _loading = true;
  String _error = '';
  GoogleMapController? _mapController;
  Set<Marker> _markers = {};
  LatLng _initialPosition = LatLng(35.6895, 139.6917); // 東京の緯度経度をデフォルトに設定

  @override
  void initState() {
    super.initState();
    _loadPlaces();
  }

  Future<void> _loadPlaces() async {
    try {
      final position = await LocationService.getCurrentLocation();
      _initialPosition = LatLng(position.latitude, position.longitude);
      final places = await PlacesService.getNearbyPlaces(
          position.latitude, position.longitude);
      setState(() {
        _places = places;
        _markers.add(
          Marker(
            markerId: MarkerId('currentLocation'),
            position: _initialPosition,
            infoWindow: InfoWindow(title: 'Current Location'),
          ),
        );
        for (var place in places) {
          _markers.add(
            Marker(
              markerId: MarkerId(place.name),
              position: LatLng(place.lat, place.lng),
              infoWindow: InfoWindow(title: place.name),
            ),
          );
        }
        _loading = false;
      });
    } catch (e) {
      setState(() {
        _error = e.toString();
        _loading = false;
      });
    }
  }

  void _onMapCreated(GoogleMapController controller) {
    _mapController = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Nearby Convenience Stores'),
      ),
      body: _loading
          ? Center(child: CircularProgressIndicator())
          : _error.isNotEmpty
              ? Center(child: Text('Error: $_error'))
              : GoogleMap(
                  onMapCreated: _onMapCreated,
                  initialCameraPosition: CameraPosition(
                    target: _initialPosition,
                    zoom: 14.0,
                  ),
                  markers: _markers,
                ),
    );
  }
}
lib/services/location_service.dart
import 'package:geolocator/geolocator.dart';

class LocationService {
  static Future<Position> getCurrentLocation() async {
    bool serviceEnabled;
    LocationPermission permission;

    // Location services are not enabled don't continue
    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return Future.error('Location permissions are denied');
      }
    }

    if (permission == LocationPermission.deniedForever) {
      return Future.error(
          'Location permissions are permanently denied, we cannot request permissions.');
    }

    Position position = await Geolocator.getCurrentPosition();
    print('Current position: ${position.latitude}, ${position.longitude}');
    return position;
  }
}
lib/services/places_service.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/place.dart';

class PlacesService {
  static final String _apiKey = 'XXXXXXXXXXX';

  static Future<List<Place>> getNearbyPlaces(double lat, double lng) async {
    final String url =
        'https://maps.googleapis.com/maps/api/place/nearbysearch/json'
        '?location=$lat,$lng'
        '&radius=1000'
        '&type=convenience_store'
        '&key=$_apiKey';

    final response = await http.get(Uri.parse(url));

    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      print('API Response: $data'); // APIレスポンスをログ出力
      final results = data['results'] as List;
      return results.map((result) => Place.fromJson(result)).toList();
    } else {
      throw Exception('Failed to load nearby places');
    }
  }
}

lib/models/place.dart
class Place {
  final String name;
  final double lat;
  final double lng;

  Place({required this.name, required this.lat, required this.lng});

  factory Place.fromJson(Map<String, dynamic> json) {
    return Place(
      name: json['name'],
      lat: json['geometry']['location']['lat'],
      lng: json['geometry']['location']['lng'],
    );
  }
}
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <!-- 既存の設定項目 -->

    <!-- 位置情報の使用許可の説明を追加 -->
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>現在地を取得して近くのコンビニを検索するために、位置情報の使用を許可してください。</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>現在地を取得して近くのコンビニを検索するために、常時位置情報の使用を許可してください。</string>

    <!-- 既存の設定項目 -->
</dict>
</plist>
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?