Flutter Filter for Nearest Place by Latitude/Longitude: A Step-by-Step Guide
Image by Feodoriya - hkhazo.biz.id

Flutter Filter for Nearest Place by Latitude/Longitude: A Step-by-Step Guide

Posted on

Are you tired of struggling to find the nearest restaurant, coffee shop, or gas station while on the go? Do you want to create a Flutter app that helps users discover nearby places based on their latitude and longitude? Look no further! In this article, we’ll take you on a journey to build a Flutter filter that finds the nearest place by latitude/longitude. Buckle up and let’s dive in!

Prerequisites

Before we begin, make sure you have the following:

  • Flutter installed on your machine (version 2.0 or later)
  • A code editor or IDE of your choice (e.g., Android Studio, Visual Studio Code)
  • A basic understanding of Dart programming language and Flutter framework

Step 1: Set up a New Flutter Project

Open your terminal or command prompt and create a new Flutter project using the following command:

flutter create flutter_filter_places

This will create a new Flutter project called `flutter_filter_places` in a directory with the same name. Navigate to the project directory:

cd flutter_filter_places

Step 2: Add the necessary dependencies

In your `pubspec.yaml` file, add the following dependencies:

dependencies:
  flutter:
    sdk: flutter
  geolocator: ^7.0.3
  http: ^0.13.3

The `geolocator` package is used to get the user’s current location, while the `http` package is used to make API requests to a backend service.

Step 3: Get the User’s Current Location

In your `main.dart` file, add the following code to get the user’s current location:

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State {
  Position _currentPosition;

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

  _getCurrentLocation() async {
    final position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    setState(() {
      _currentPosition = position;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Filter Places'),
        ),
        body: Center(
          child: Text(_currentPosition != null
              ? 'Latitude: ${_currentPosition.latitude}, Longitude: ${_currentPosition.longitude}'
              : 'Getting location...'),
        ),
      ),
    );
  }
}

Step 4: Create a Backend Service to Retrieve Nearby Places

In this step, we’ll create a simple backend service using Node.js and Express.js to retrieve nearby places based on the user’s latitude and longitude.

Create a new directory called `backend` inside your project directory and create a new file called `index.js`:

const express = require('express');
const app = express();

app.use(express.json());

const places = [
  {
    name: 'Place 1',
    latitude: 37.7749,
    longitude: -122.4194,
  },
  {
    name: 'Place 2',
    latitude: 37.7858,
    longitude: -122.4364,
  },
  {
    name: 'Place 3',
    latitude: 37.7963,
    longitude: -122.4574,
  },
  // Add more places here
];

app.get('/places', (req, res) => {
  const { latitude, longitude } = req.query;
  const nearbyPlaces = places.filter((place) => {
    const distance = getDistance(latitude, longitude, place.latitude, place.longitude);
    return distance <= 1; // Filter places within 1 km radius
  });
  res.json(nearbyPlaces);
});

const getDistance = (lat1, lon1, lat2, lon2) => {
  const R = 6371; // Radius of the earth in km
  const dLat = degToRad(lat2 - lat1);
  const dLon = degToRad(lon2 - lon1);
  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(degToRad(lat1)) * Math.cos(degToRad(lat2));
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  const distance = R * c;
  return distance;
};

const degToRad = (deg) => {
  return deg * (Math.PI / 180);
};

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

This backend service uses a simple array of places with their corresponding latitudes and longitudes. When the user requests nearby places, the service filters the places based on the user’s latitude and longitude using the Haversine formula.

Step 5: Make API Request to Retrieve Nearby Places

In your `main.dart` file, add the following code to make an API request to the backend service:

import 'package:http/http.dart' as http;

class _MyAppState extends State {
  // ...

  Future _getNearbyPlaces() async {
    final response = await http.get(Uri.parse('http://localhost:3000/places?latitude=${_currentPosition.latitude}&longitude=${_currentPosition.longitude}'));
    if (response.statusCode == 200) {
      final nearbyPlaces = jsonDecode(response.body);
      setState(() {
        _nearbyPlaces = nearbyPlaces;
      });
    } else {
      throw Exception('Failed to load nearby places');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // ...
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_currentPosition != null
                ? 'Latitude: ${_currentPosition.latitude}, Longitude: ${_currentPosition.longitude}'
                : 'Getting location...'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _getNearbyPlaces,
              child: Text('Get Nearby Places'),
            ),
            SizedBox(height: 20),
            _nearbyPlaces != null
                ? ListView.builder(
                    shrinkWrap: true,
                    itemCount: _nearbyPlaces.length,
                    itemBuilder: (context, index) {
                      return ListTile(
                        title: Text(_nearbyPlaces[index]['name']),
                      );
                    },
                  )
                : Text('No nearby places found'),
          ],
        ),
      ),
    );
  }
}

Step 6: Filter Nearby Places by Distance

In this final step, we’ll add a filter to sort the nearby places by distance. Add the following code to your `main.dart` file:

class _MyAppState extends State {
  // ...

  void _filterByDistance() {
    _nearbyPlaces.sort((a, b) {
      final distanceA = getDistance(_currentPosition.latitude, _currentPosition.longitude, a['latitude'], a['longitude']);
      final distanceB = getDistance(_currentPosition.latitude, _currentPosition.longitude, b['latitude'], b['longitude']);
      return distanceA.compareTo(distanceB);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // ...
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // ...
            ElevatedButton(
              onPressed: _filterByDistance,
              child: Text('Filter by Distance'),
            ),
            // ...
          ],
        ),
      ),
    );
  }
}

double getDistance(lat1, lon1, lat2, lon2) {
  const R = 6371; // Radius of the earth in km
  const dLat = degToRad(lat2 - lat1);
  const dLon = degToRad(lon2 - lon1);
  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(degToRad(lat1)) * Math.cos(degToRad(lat2));
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  const distance = R * c;
  return distance;
}

double degToRad(deg) {
  return deg * (Math.PI / 180);
}

That’s it! You now have a Flutter app that filters nearby places by latitude and longitude. Run the app, and you should see a list of nearby places sorted by distance.

Conclusion

In this article, we’ve covered the steps to create a Flutter filter for nearest place by latitude/longitude. We’ve used the `geolocator` package to get the user’s current location, created a backend service to retrieve nearby places, and implemented a filter to sort theHere are 5 Questions and Answers about “Flutter Filter for nearest Place by latitude/longitude”:

Frequently Asked Questions

Get the answers to the most frequently asked questions about filtering for the nearest place by latitude and longitude in Flutter!

How can I filter for the nearest place by latitude and longitude in Flutter?

You can use the distance formula to calculate the distance between the user’s location and the locations you want to filter. Then, sort the list by distance and take the top N results to get the nearest places. You can use the `geolocator` package to get the user’s current location and the `latlong` package to calculate the distance.

What is the most efficient way to filter a large list of locations by latitude and longitude?

To filter a large list of locations efficiently, you can use a spatial indexing data structure like a quadtree or a k-d tree. These data structures allow you to quickly search for locations within a certain radius of a given point. You can also use a library like `geo` which provides a `nearby` function to filter locations by distance.

Can I use a Firestore database to store and filter locations by latitude and longitude?

Yes, you can use a Firestore database to store and filter locations by latitude and longitude. Firestore provides a `geo` query feature that allows you to query locations within a certain radius of a given point. You can store the locations as GeoPoints in your Firestore database and use the `geo` query to filter them.

How can I handle cases where the user’s location is not available?

You can handle cases where the user’s location is not available by providing a default location or a fallback behavior. For example, you can use a default location like the city center or a popular landmark. Alternatively, you can ask the user to input their location manually or provide a list of nearby locations.

Can I use the same logic to filter locations on both iOS and Android?

Yes, the logic for filtering locations by latitude and longitude is platform-agnostic, so you can use the same logic on both iOS and Android. However, you may need to use platform-specific libraries or APIs to get the user’s current location and to calculate the distance between locations. For example, on iOS, you can use the Core Location framework, while on Android, you can use the Android Location API.

Leave a Reply

Your email address will not be published. Required fields are marked *