Source: https://developers.woosmap.com/products/mobile/flutter/store-overlay/

> 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 - Displaying your stores



You are able to natively display your assets hosted in your Woosmap project by using the `StoreOverlay`

Configuring store overlay.

```dart
  ///Defined TypedStyleRule
  TypedStyleRule typedStyleRule = TypedStyleRule(
    color: "#1D1D1D",
    icon: WoosIcon(
        url: "https://images.woosmap.com/starbucks-marker-black.svg", 
        scaledSize: WoosSize(width: 34, height: 40)
      ),
    type: "takeaway",
    selectedIcon: WoosIcon(
      url: "https://images.woosmap.com/starbucks-marker-selected.svg", 
      scaledSize: WoosSize(width: 43, height: 50)
      )
  );
  
  ///Defined StyleRule
  StyleRule styleRule = StyleRule(
    color: "#008a2f",
    icon: WoosIcon(
        url: "https://images.woosmap.com/starbucks-marker.svg", 
        scaledSize: WoosSize(width: 34, height: 40)
      ),
    size: 8,
    minSize: 1,
    selectedIcon: WoosIcon(
        url: "https://images.woosmap.com/starbucks-marker-selected.svg", 
        scaledSize: WoosSize(width: 50, height: 43)
      )
  );
  
  ///Create Style with StyleRule and TypedStyleRule
  Style style = Style(
    breakPoint: 14,
    defaultStyleRule: styleRule,
    rules: [typedStyleRule]
  );
  
  storesOverlay = StoreOverlay.create(style, _controller!);
  storesOverlay?.add();
```

``` 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 StoreOverlaySnippet extends StatefulWidget {
  const StoreOverlaySnippet({super.key});

  @override
  State<StoreOverlaySnippet> createState() => _StoreOverlaySnippetState();
}

class _StoreOverlaySnippetState extends State<StoreOverlaySnippet> {
  WoosmapController? _controller;
  TextEditingController? txtLogController;
  StoreOverlay? storesOverlay;
  @override
  void initState() {
    super.initState();
    txtLogController = TextEditingController();
    if (_controller != null) {
      debugPrint("info ===> Indoor controller not initialize");
    }
  }

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

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

  Future<void> _onAddOverlay() async {
    if (storesOverlay == null) {
      storesOverlay = StoreOverlay.create(
          Style(
              breakPoint: 14,
              rules: [
                TypedStyleRule(
                    color: "#1D1D1D",
                    type: "takeaway",
                    icon: WoosIcon(
                        url:
                            "https://images.woosmap.com/starbucks-marker-black.svg",
                        scaledSize: WoosSize(height: 40, width: 34)),
                    selectedIcon: WoosIcon(
                        url:
                            "https://images.woosmap.com/starbucks-marker-selected.svg",
                        scaledSize: WoosSize(height: 50, width: 43)))
              ],
              defaultStyleRule: StyleRule(
                  color: "#008a2f",
                  size: 8,
                  minSize: 1,
                  icon: WoosIcon(
                      url: "https://images.woosmap.com/starbucks-marker.svg",
                      scaledSize: WoosSize(height: 40, width: 34)),
                  selectedIcon: WoosIcon(
                      url:
                          "https://images.woosmap.com/starbucks-marker-selected.svg",
                      scaledSize: WoosSize(height: 50, width: 43)))),
          _controller!);
      storesOverlay?.add();
    }
    return;
  }

  Future<void> _onRemoveOverlay() async {
    if (storesOverlay != null) {
      storesOverlay!.remove();
      storesOverlay = null;
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("No Store overlay on map")),
      );
    }
    return;
  }

  void menuActions(StoreOverlayMenuOptions menuId) {
    switch (menuId) {
      case StoreOverlayMenuOptions.addOverlay:
        _onAddOverlay();
        break;
      case StoreOverlayMenuOptions.removeOverlay:
        _onRemoveOverlay();
        break;
      case StoreOverlayMenuOptions.filterStore:
        storesOverlay?.setQuery('type:"takeaway"');
        break;
      case StoreOverlayMenuOptions.clearFilter:
        storesOverlay?.setQuery(null);
        break;
      case StoreOverlayMenuOptions.setSelection:
        storesOverlay?.setSelection({
          "type": "Feature",
          "properties": {
            "store_id": "345880058",
            "name": "Pret A Manger",
            "contact": null,
            "address": {
              "lines": ["Whitehall"],
              "country_code": null,
              "city": "London",
              "zipcode": null
            },
            "user_properties": null,
            "tags": [],
            "types": [],
            "last_updated": null
          },
          "geometry": {
            "type": "Point",
            "coordinates": [-0.127258, 51.507083]
          }
        });
        break;
      case StoreOverlayMenuOptions.clearSelection:
        storesOverlay?.clearSelection();
        break;
      default:
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Woosmap (Store Overlay)'),
        actions: <Widget>[
          StoreOverlayMenu(
            webViewController: _controller,
            onMenuSelected: (value) {
              menuActions(value);
            },
          ),
        ],
      ),
      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();
                        },
                        loader: const AssetImage("assets/spinner.gif"),
                        mapOptions: const {
                          "center": {"lat": 51.515, "lng": -0.12},
                          "zoom": 14
                        },
                        store_selected: (message) {
                          txtLogController?.text =
                              "store_selected, ${txtLogController?.text}";
                          ScaffoldMessenger.of(context).showSnackBar(
                            SnackBar(content: Text(jsonEncode(message))),
                          );
                        },
                        store_unselected: () {
                          txtLogController?.text =
                              "store_unselected, ${txtLogController?.text}";
                        }))),
            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 StoreOverlayMenuOptions {
  addOverlay,
  removeOverlay,
  filterStore,
  clearFilter,
  setSelection,
  clearSelection,
}

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

  final WoosmapController? webViewController;
  final Function(StoreOverlayMenuOptions)? onMenuSelected;

  @override
  Widget build(BuildContext context) {
    return PopupMenuButton<StoreOverlayMenuOptions>(
      key: const ValueKey<String>('ShowPopupMenu'),
      onSelected: (StoreOverlayMenuOptions value) {
        if (onMenuSelected != null) {
          onMenuSelected!(value);
        }
      },
      itemBuilder: (BuildContext context) =>
          <PopupMenuItem<StoreOverlayMenuOptions>>[
        const PopupMenuItem<StoreOverlayMenuOptions>(
          value: StoreOverlayMenuOptions.addOverlay,
          child: Text('Add Store Overlay'),
        ),
        const PopupMenuItem<StoreOverlayMenuOptions>(
          value: StoreOverlayMenuOptions.removeOverlay,
          child: Text('Remove Store Overlay'),
        ),
        const PopupMenuItem<StoreOverlayMenuOptions>(
          value: StoreOverlayMenuOptions.filterStore,
          child: Text('Filter Stores (setQuery)'),
        ),
        const PopupMenuItem<StoreOverlayMenuOptions>(
          value: StoreOverlayMenuOptions.clearFilter,
          child: Text('Clear Filter (setQuery(""))'),
        ),
        const PopupMenuItem<StoreOverlayMenuOptions>(
          value: StoreOverlayMenuOptions.setSelection,
          child: Text('setSelection'),
        ),
        const PopupMenuItem<StoreOverlayMenuOptions>(
          value: StoreOverlayMenuOptions.clearSelection,
          child: Text('clearSelection'),
        ),
      ],
    );
  }
}
```
