arrow-left

All pages
gitbookPowered by GitBook
1 of 3

Loading...

Loading...

Loading...

Options

To dictate & restrict what the map can and should do, regardless of its contents, it needs some guidance!

It provides options that can be categorized into three main parts:

  • Initial positioning Defines the location of the map when it is first loaded

  • Permanent rules Defines restrictions that last throughout the map's lifetime

  • Defines methods that are called on specific map events

hashtag
Initial Positioning

circle-info

Changing these properties after the map has already been built for the first time will have no effect: they only apply on initialisation.

To control the map programatically, use a MapController: .

One part of MapOptions responsibilities is to define how the map should be positioned when first loaded. There's two ways to do this (that are incompatible):

  • initialCenter (LatLng) & initialZoom

  • initialCameraFit

It is possible to also set the map's initialRotation in degrees, if you don't want it North (0°) facing initially.

If rotation is enabled/allowed, if using initialCameraFit, prefer defining it by coordinates for a more intended/tight fit.

hashtag
Permanent Rules

One part of MapOptions responsibilities is to define the restrictions and limitations of the map and what users can/cannot do with it.

Some of the options are described elsewhere in this documentation, in context. In addition, the API docs show all the available options, and below is a partial list of options:

  • cameraConstraint

    • camera bounds inside bounds: CameraConstraint.bounds

circle-check

Instead of maxZoom (or in addition to), consider setting maxNativeZoom per TileLayer instead, to allow tiles to scale (and lose quality) on the final zoom level, instead of setting a hard limit.

hashtag
Custom CRS

FM does have some support for using alternative CRSs.

by bounds (circumscribed): CameraFit.bounds

  • by bounds (inscribed): CameraFit.insideBounds

  • by coordinates (circumscribed): CameraFit.coordinates

  • camera center inside bounds:
    CameraConstraint.center
  • unconstrained (default): CameraConstraint.unconstrained

  • maxZoom and minZoom Sets a hard limit on the maximum and minimum amounts that the map can be zoomed

  • interactionOptions Configures the gestures that the user can use to interact with the map - for example, disable rotation or configure cursor/keyboard rotation

  • Event handling
    Custom CRSschevron-right

    Interaction Options

    The InteractionOptions object passed to MapOptions.interactiveOptions configures the gestures that the user can use to interact with the map. For example, disable rotation or configure cursor/keyboard rotation.

    hashtag
    Flags

    flags is a bitfieldarrow-up-right that enables and disables the vast majority of gestures. Although technically the type is of int, it is usually set with a combination of InteractiveFlags.

    circle-exclamation

    Note that some gestures must be configured by other means, either instead of using flags, or in addition to.

    By default, all gestures are enabled, but a non-interactive map can be created using none (and other options in addition).

    circle-info

    The recommended way to create an entirely non-interactive map is to wrap the FlutterMap widget in an IgnorePointer widget.

    Otherwise, to set flags, there's two methods:

    • Allow ONLY specified interactions, with the bitwise 'OR' (|) operator For example, InteractiveFlag.drag | InteractiveFlag.rotate, allows the map to ONLY be dragged or rotated (by the touchscreen), except any other options configured separately (such as keyboard options)

    • Disable specified interactions, using the & and ~ operators For example, ~InteractiveFlag.rotate

    For example, to disable flinging:

    hashtag
    Cursor/Keyboard Rotation

    Cursor/keyboard rotation is designed for desktop platforms, and allows the cursor to be used to set the rotation of the map whilst a (customizable) keyboard key (by default, any of the 'Control' keys) is held down.

    The CursorKeyboardRotationOptions object passed to the property with the corresponding name configures this behaviour. The CursorKeyboardRotationOptions.disabled() constructor can be used to disable cursor/keyboard rotation.

    There's many customization options, see the API docs for more information:

    hashtag
    Keyboard Gestures

    Keyboard gestures can be configured through KeyboardOptions. By default, the map can be panned via the arrow keys. Additionally, panning using the WASD keys can be enabled, as well as rotation with Q & E, and zooming with R & F. All keys are physical and based on the QWERTY keyboard, so on other keyboards, the positions will be the same, not necessary the characters.

    Leaping occurs when the trigger key is pressed momentarily instead of being held down. This can also be customized.

    hashtag
    "Win" Gestures

    circle-exclamation

    This is advanced behaviour that affects how gestures 'win' in the gesture arena, and does not usually need changing.

    (which is equivalent to
    InteractiveFlag.all & ~InteractiveFlag.rotate
    )
    options: MapOptions(
        interactionOptions: InteractionOptions(
            flags: ~InteractiveFlag.flingAnimation,
        ),
    ),

    Custom CRSs

    hashtag
    Projection

    To define a Proj4Crs (custom CRS) you have to register a projection of proj4.Projection. For that you must import proj4dart library as follows:

    You can create and register your custom projection in multiple ways, but the recommended is to use a Proj4 definition string from epsg.ioarrow-up-right. For example for EPSG:3413 (WGS 84 / NSIDC Sea Ice Polar Stereographic North) you can find it . This is how a Proj4 definition string looks like:

    With this Proj4 definition string and a string identifier register your proj4.Projection like this:

    For more possible ways to register proj4.Projection see .

    hashtag
    Coordinate Reference System (CRS)

    You can use your previously registered proj4.Projection to create a custom CRS of type Proj4Crs. You can use the following parameters:

    • <String> code (required): string identifier for the selected CRS, e.g. EPSG:3413

    • <proj4.Projection> proj4Projection (required): the proj4.Projection object you wish to use

    An example:

    hashtag
    Usage

    Proj4Crs has multiple uses:

    • Set FlutterMap's default CRS:

    • Set a WMS layer's CRS

    For complete code (with point transformation from one projection to another) see the page source code. This is how it looks like:

    import 'package:proj4dart/proj4dart.dart' as proj4;

    <Bounds> bounds: bounds of the CRS in projected coordinates

  • <List<double>> resolutions: an array of zoom factors (projection units per pixel, eg. meters/pixel)

  • <List<double>> scales: scale factors (pixels per projection unit); specify either scales or resolutions, but not both!

  • <List<Point>> origins: tile origin in projected coordinates (for TileLayer). Why is it needed? GeoServer by default can define different origins (top left coordinates) for each zoom levels. In case of origin mismatch the tile will be drawn on the wrong place: the map will jump at such zoom levels. If your origins vary with zoom levels the number of origins must match the number of resolutions. You can get the desired origins from a GetCapabilities WMTS call from geoserver e.g. http://[ip:port]/geoserver/gwc/service/wmts?request=GetCapabilities. This results an XML, and you have to look up for the TopLeftCorners for each TileMatrix of your TileMatrixSet.

  • <Transformation> transformation: the transformation to use when transforming projected coordinates into pixel coordinates

  • herearrow-up-right
    proj4dart documentationarrow-up-right
    +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m + no_defs
    var customProjection = proj4.Projection.add('EPSG:3413',
        '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
    var epsg3413 = proj4.Projection.add('EPSG:3413',
        '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
    
    final resolutions = <double>[
      32768,
      16384,
      8192,
      4096,
      2048,
      1024,
      512,
      256,
      128,
    ];
    
    final epsg3413Bounds = Bounds<double>(
      Point<double>(-4511619.0, -4511336.0),
      Point<double>(4510883.0, 4510996.0),
    );
    
    var maxZoom = (resolutions.length - 1).toDouble();
    
    var epsg3413CRS = Proj4Crs.fromFactory(
      code: 'EPSG:3413',
      proj4Projection: epsg3413,
      resolutions: resolutions,
      bounds: epsg3413Bounds,
      origins: [Point(0, 0)],
      scales: null,
      transformation: null,
    );
      FlutterMap(
        options: MapOptions(
          // Set the default CRS
          crs: epsg3413CRS,
          center: LatLng(65.05166470332148, -19.171744826394896),
          zoom: 3.0,
          maxZoom: maxZoom,
        ),
        layers: [],
      );
      TileLayer(
        wmsOptions: WMSTileLayerOptions(
          // Set the WMS layer's CRS
          crs: epsg3413CRS,
          transparent: true,
          format: 'image/jpeg',
          baseUrl:
              'https://www.gebco.net/data_and_products/gebco_web_services/north_polar_view_wms/mapserv?',
          layers: ['gebco_north_polar_view'],
        ),
      );
    InteractiveFlag class - flutter_map library - Dart APIpub.devchevron-right
    Logo
    MapOptions class - flutter_map library - Dart APIpub.devchevron-right
    Logo
    CursorKeyboardRotationOptions class - flutter_map library - Dart APIpub.devchevron-right
    Logo
    InteractionOptions class - flutter_map library - Dart APIpub.devchevron-right
    Logo