Source: https://developers.woosmap.com/products/mobile/flutter/direction/

> For clean Markdown of any page, append `.md` to the page URL.

> For a complete documentation index, see https://developers.woosmap.com/llms.txt

# Woosmap for Flutter - Driving Directions



You can calculate directions and plot by using the `WoosmapMapViewWidget.route` method. This method is an interface to the Route endpoint of Woosmap Distance API. This service compute travel distance, time and path for a pair of origin and destination.

You may either display these directions results using custom overlays or use the `WoosmapMapViewWidget.setRoute method` to render these results.

``` dart
_controller?.route(DirectionRequest(
    origin: LatLng(lat: 48.86288, lng: 2.34946),
    destination: LatLng(lat: 52.52457, lng: 13.42347),
    unitSystem: UnitSystem.metric,
    travelMode: TravelMode.driving,
    provideRouteAlternatives: true
  ))
  .then((route) {
    _controller?.setRoute(route: route);
  });

```

``` dart
import 'package:flutter/widgets.dart';

class AppConstants extends InheritedWidget {
  static AppConstants? of(BuildContext context) =>
      context.dependOnInheritedWidgetOfExactType<AppConstants>();

  const AppConstants({required super.child, super.key});

  final String privateKeyiOS = "<<Your private iOS woosmap key>>";
  final String privateKeyAndroid = "<<Your private Android woosmap key>>";
  @override
  bool updateShouldNotify(AppConstants oldWidget) => false;
}
```

``` dart
import 'dart:convert';
import 'dart:core';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:woosmap_flutter/woosmap_flutter.dart';
import './constants.dart';

class DirectionSnippet extends StatefulWidget {
  const DirectionSnippet({super.key});

  @override
  State<DirectionSnippet> createState() => _DirectionSnippetState();
}

class _DirectionSnippetState extends State<DirectionSnippet> {
  WoosmapController? _controller;
  TextEditingController? txtLogController;
  @override
  void initState() {
    super.initState();
    txtLogController = TextEditingController();
    if (_controller != null) {
      debugPrint("info ===> Direction controller not initialize");
    }
  }

  @override
  void dispose() {
    txtLogController?.dispose();
    super.dispose();
  }

  Future<void> reloadMenu() async {
    setState(() {});
  }

  void menuActions(DirectionMenuOptions menuId) {
    switch (menuId) {
      case DirectionMenuOptions.showRoute:
        _controller
            ?.route(DirectionRequest(
                origin: LatLng(lat: 48.86288, lng: 2.34946),
                destination: LatLng(lat: 52.52457, lng: 13.42347),
                language: "en",
                unitSystem: UnitSystem.metric,
                travelMode: TravelMode.driving,
                provideRouteAlternatives: true,
                avoidFerries: true,
                avoidHighways: true,
                avoidTolls: true,
                //method: DirectionMethod.distance,
                details: DirectionDetails.full,
                optimizeWaypoints: true,
                waypoints: [
              DirectionsWayPoint(
                  location: LatLng(lat: 52.52457, lng: 13.42347),
                  stopover: true)
            ],
                avoidZones: [
              [
                LatLng(lat: 48.86298, lng: 2.34946),
                LatLng(lat: 48.86283, lng: 2.34956),
                LatLng(lat: 48.86288, lng: 2.34946)
              ]
            ]))
            .then((route) {
          _controller?.setRoute(route: route);
          txtLogController?.text = jsonEncode(route);
        }).catchError((error) {
          txtLogController?.text = "An error occurred: ${error["message"]}";
        });
        break;

      case DirectionMenuOptions.hideRoute:
        _controller?.setRoute(route: null);
        txtLogController?.text = "";
        break;

      default:
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text("Not Implemented")),
        );
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Woosmap app (Directions)'),
        actions: <Widget>[
          DirectionEventsMenu(
              webViewController: _controller, onMenuSelected: menuActions),
        ],
      ),
      body: SafeArea(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Expanded(
                child: Align(
                    alignment: const AlignmentDirectional(-1, -1),
                    child: WoosmapMapViewWidget(
                      wooskey: Platform.isAndroid
                          ? AppConstants.of(context)?.privateKeyAndroid ?? ""
                          : AppConstants.of(context)?.privateKeyiOS ?? "",
                      onRef: (p0) async {
                        _controller = p0;
                        reloadMenu();
                      },
                      mapOptions: const {
                        "center": {"lat": 51.52, "lng": -0.13},
                        "zoom": 5
                      },
                      routeIndex_changed: (index) {
                        txtLogController?.text = jsonEncode(index);
                      },
                    ))),
            Container(
                width: 100,
                height: 100,
                decoration: const BoxDecoration(
                  color: Color(0xFFDEE6E6),
                ),
                child: Column(mainAxisSize: MainAxisSize.max, children: [
                  Expanded(
                      child: Padding(
                    padding: const EdgeInsetsDirectional.fromSTEB(10, 5, 10, 5),
                    child: TextFormField(
                      controller: txtLogController,
                      minLines: null,
                      maxLines: null,
                      autofocus: true,
                      enabled: false,
                      obscureText: false,
                      decoration: const InputDecoration(
                        labelText: 'Events Log\n',
                        hintText: 'Event fired',
                        enabledBorder: UnderlineInputBorder(
                          borderSide: BorderSide(
                            color: Color(0x00000000),
                            width: 1,
                          ),
                          borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(4.0),
                            topRight: Radius.circular(4.0),
                          ),
                        ),
                        focusedBorder: UnderlineInputBorder(
                          borderSide: BorderSide(
                            color: Color(0x00000000),
                            width: 1,
                          ),
                          borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(4.0),
                            topRight: Radius.circular(4.0),
                          ),
                        ),
                        errorBorder: UnderlineInputBorder(
                          borderSide: BorderSide(
                            color: Color(0x00000000),
                            width: 1,
                          ),
                          borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(4.0),
                            topRight: Radius.circular(4.0),
                          ),
                        ),
                        focusedErrorBorder: UnderlineInputBorder(
                          borderSide: BorderSide(
                            color: Color(0x00000000),
                            width: 1,
                          ),
                          borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(4.0),
                            topRight: Radius.circular(4.0),
                          ),
                        ),
                      ),
                    ),
                  ))
                ]))
          ],
        ),
      ),
    );
  }
}

enum DirectionMenuOptions {
  showRoute,
  hideRoute,
}

class DirectionEventsMenu extends StatelessWidget {
  const DirectionEventsMenu({
    super.key,
    required this.webViewController,
    required this.onMenuSelected,
  });

  final WoosmapController? webViewController;
  final Function(DirectionMenuOptions) onMenuSelected;
  @override
  Widget build(BuildContext context) {
    return PopupMenuButton<DirectionMenuOptions>(
      key: const ValueKey<String>('ShowPopupMenu'),
      onSelected: (DirectionMenuOptions value) {
        onMenuSelected(value);
      },
      itemBuilder: (BuildContext context) =>
          <PopupMenuItem<DirectionMenuOptions>>[
        const PopupMenuItem<DirectionMenuOptions>(
          value: DirectionMenuOptions.showRoute,
          child: Text('Show Route'),
        ),
        const PopupMenuItem<DirectionMenuOptions>(
          value: DirectionMenuOptions.hideRoute,
          child: Text('Hide Route'),
        ),
      ],
    );
  }
}
```

To clear displayed route on map.

``` dart
_controller?.setRoute(route: null);
```

Please check the javascript guide for more implementation. [javascript guide](/products/distance-api/reference/map-js-sdk/)

## Get Transit Route

You can calculate transit route by using the [TransitService](/products/mobile/react-native/services/#transit-api) object. This object is an interface to the Route endpoint of Woosmap Transit API. This service compute travel distance, time and path for a pair of origin and destination.

``` dart
TransitRouteRequest request = TransitRouteRequest(
        origin: LatLngLiteral(lat: 45.467, lng: 9.0516),
        destination: LatLngLiteral(lat: 45.4599, lng: 9.2822),
        mode: [
          'highSpeedTrain',
          'intercityTrain',
          'interRegionalTrain',
          'regionalTrain',
          'cityTrain',
          'bus',
          'ferry',
          'subway',
          'lightRail',
          'privateBus',
          'inclined',
          'aerial',
          'busRapid',
          'monorail',
          'flight'
        ],
        departureTime: null,
        arrivalTime: null);

WoosmapApi woosmapApi = WoosmapApi(WoosKey(
  privateKey: Platform.isAndroid
      ? AppConstants.of(context)?.privateKeyAndroid ?? ""
      : AppConstants.of(context)?.privateKeyiOS ?? "",
));

woosmapApi.transit.route(request).then((value) {
    _controller?.setTransitRoute(route: value);
  }).catchError((error) {
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('An error occurred: ${error.message}')),
      );
    }
  });
```

 To clear displayed route on map.

``` dart
  _controller?.setTransitRoute(undefined);
```

Please check the javascript guide for more implementation. [javascript guide](/products/map-api/guides/transit/)
