| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:ui' show Offset; |
| |
| import 'package:flutter/foundation.dart' |
| show immutable, ValueChanged, VoidCallback; |
| |
| import 'types.dart'; |
| |
| Object _offsetToJson(Offset offset) { |
| return <Object>[offset.dx, offset.dy]; |
| } |
| |
| /// Text labels for a [Marker] info window. |
| @immutable |
| class InfoWindow { |
| /// Creates an immutable representation of a label on for [Marker]. |
| const InfoWindow({ |
| this.title, |
| this.snippet, |
| this.anchor = const Offset(0.5, 0.0), |
| this.onTap, |
| }); |
| |
| /// Text labels specifying that no text is to be displayed. |
| static const InfoWindow noText = InfoWindow(); |
| |
| /// Text displayed in an info window when the user taps the marker. |
| /// |
| /// A null value means no title. |
| final String? title; |
| |
| /// Additional text displayed below the [title]. |
| /// |
| /// A null value means no additional text. |
| final String? snippet; |
| |
| /// The icon image point that will be the anchor of the info window when |
| /// displayed. |
| /// |
| /// The image point is specified in normalized coordinates: An anchor of |
| /// (0.0, 0.0) means the top left corner of the image. An anchor |
| /// of (1.0, 1.0) means the bottom right corner of the image. |
| final Offset anchor; |
| |
| /// onTap callback for this [InfoWindow]. |
| final VoidCallback? onTap; |
| |
| /// Creates a new [InfoWindow] object whose values are the same as this instance, |
| /// unless overwritten by the specified parameters. |
| InfoWindow copyWith({ |
| String? titleParam, |
| String? snippetParam, |
| Offset? anchorParam, |
| VoidCallback? onTapParam, |
| }) { |
| return InfoWindow( |
| title: titleParam ?? title, |
| snippet: snippetParam ?? snippet, |
| anchor: anchorParam ?? anchor, |
| onTap: onTapParam ?? onTap, |
| ); |
| } |
| |
| Object _toJson() { |
| final Map<String, Object> json = <String, Object>{}; |
| |
| void addIfPresent(String fieldName, Object? value) { |
| if (value != null) { |
| json[fieldName] = value; |
| } |
| } |
| |
| addIfPresent('title', title); |
| addIfPresent('snippet', snippet); |
| addIfPresent('anchor', _offsetToJson(anchor)); |
| |
| return json; |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is InfoWindow && |
| title == other.title && |
| snippet == other.snippet && |
| anchor == other.anchor; |
| } |
| |
| @override |
| int get hashCode => Object.hash(title.hashCode, snippet, anchor); |
| |
| @override |
| String toString() { |
| return 'InfoWindow{title: $title, snippet: $snippet, anchor: $anchor}'; |
| } |
| } |
| |
| /// Uniquely identifies a [Marker] among [GoogleMap] markers. |
| /// |
| /// This does not have to be globally unique, only unique among the list. |
| @immutable |
| class MarkerId extends MapsObjectId<Marker> { |
| /// Creates an immutable identifier for a [Marker]. |
| const MarkerId(super.value); |
| } |
| |
| /// Marks a geographical location on the map. |
| /// |
| /// A marker icon is drawn oriented against the device's screen rather than |
| /// the map's surface; that is, it will not necessarily change orientation |
| /// due to map rotations, tilting, or zooming. |
| @immutable |
| class Marker implements MapsObject<Marker> { |
| /// Creates a set of marker configuration options. |
| /// |
| /// Default marker options. |
| /// |
| /// Specifies a marker that |
| /// * is fully opaque; [alpha] is 1.0 |
| /// * uses icon bottom center to indicate map position; [anchor] is (0.5, 1.0) |
| /// * has default tap handling; [consumeTapEvents] is false |
| /// * is stationary; [draggable] is false |
| /// * is drawn against the screen, not the map; [flat] is false |
| /// * has a default icon; [icon] is `BitmapDescriptor.defaultMarker` |
| /// * anchors the info window at top center; [infoWindowAnchor] is (0.5, 0.0) |
| /// * has no info window text; [infoWindowText] is `InfoWindowText.noText` |
| /// * is positioned at 0, 0; [position] is `LatLng(0.0, 0.0)` |
| /// * has an axis-aligned icon; [rotation] is 0.0 |
| /// * is visible; [visible] is true |
| /// * is placed at the base of the drawing order; [zIndex] is 0.0 |
| /// * reports [onTap] events |
| /// * reports [onDragEnd] events |
| const Marker({ |
| required this.markerId, |
| this.alpha = 1.0, |
| this.anchor = const Offset(0.5, 1.0), |
| this.consumeTapEvents = false, |
| this.draggable = false, |
| this.flat = false, |
| this.icon = BitmapDescriptor.defaultMarker, |
| this.infoWindow = InfoWindow.noText, |
| this.position = const LatLng(0.0, 0.0), |
| this.rotation = 0.0, |
| this.visible = true, |
| this.zIndex = 0.0, |
| this.onTap, |
| this.onDrag, |
| this.onDragStart, |
| this.onDragEnd, |
| }) : assert(alpha == null || (0.0 <= alpha && alpha <= 1.0)); |
| |
| /// Uniquely identifies a [Marker]. |
| final MarkerId markerId; |
| |
| @override |
| MarkerId get mapsId => markerId; |
| |
| /// The opacity of the marker, between 0.0 and 1.0 inclusive. |
| /// |
| /// 0.0 means fully transparent, 1.0 means fully opaque. |
| final double alpha; |
| |
| /// The icon image point that will be placed at the [position] of the marker. |
| /// |
| /// The image point is specified in normalized coordinates: An anchor of |
| /// (0.0, 0.0) means the top left corner of the image. An anchor |
| /// of (1.0, 1.0) means the bottom right corner of the image. |
| final Offset anchor; |
| |
| /// True if the marker icon consumes tap events. If not, the map will perform |
| /// default tap handling by centering the map on the marker and displaying its |
| /// info window. |
| final bool consumeTapEvents; |
| |
| /// True if the marker is draggable by user touch events. |
| final bool draggable; |
| |
| /// True if the marker is rendered flatly against the surface of the Earth, so |
| /// that it will rotate and tilt along with map camera movements. |
| final bool flat; |
| |
| /// A description of the bitmap used to draw the marker icon. |
| final BitmapDescriptor icon; |
| |
| /// A Google Maps InfoWindow. |
| /// |
| /// The window is displayed when the marker is tapped. |
| final InfoWindow infoWindow; |
| |
| /// Geographical location of the marker. |
| final LatLng position; |
| |
| /// Rotation of the marker image in degrees clockwise from the [anchor] point. |
| final double rotation; |
| |
| /// True if the marker is visible. |
| final bool visible; |
| |
| /// The z-index of the marker, used to determine relative drawing order of |
| /// map overlays. |
| /// |
| /// Overlays are drawn in order of z-index, so that lower values means drawn |
| /// earlier, and thus appearing to be closer to the surface of the Earth. |
| final double zIndex; |
| |
| /// Callbacks to receive tap events for markers placed on this map. |
| final VoidCallback? onTap; |
| |
| /// Signature reporting the new [LatLng] at the start of a drag event. |
| final ValueChanged<LatLng>? onDragStart; |
| |
| /// Signature reporting the new [LatLng] at the end of a drag event. |
| final ValueChanged<LatLng>? onDragEnd; |
| |
| /// Signature reporting the new [LatLng] during the drag event. |
| final ValueChanged<LatLng>? onDrag; |
| |
| /// Creates a new [Marker] object whose values are the same as this instance, |
| /// unless overwritten by the specified parameters. |
| Marker copyWith({ |
| double? alphaParam, |
| Offset? anchorParam, |
| bool? consumeTapEventsParam, |
| bool? draggableParam, |
| bool? flatParam, |
| BitmapDescriptor? iconParam, |
| InfoWindow? infoWindowParam, |
| LatLng? positionParam, |
| double? rotationParam, |
| bool? visibleParam, |
| double? zIndexParam, |
| VoidCallback? onTapParam, |
| ValueChanged<LatLng>? onDragStartParam, |
| ValueChanged<LatLng>? onDragParam, |
| ValueChanged<LatLng>? onDragEndParam, |
| }) { |
| return Marker( |
| markerId: markerId, |
| alpha: alphaParam ?? alpha, |
| anchor: anchorParam ?? anchor, |
| consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents, |
| draggable: draggableParam ?? draggable, |
| flat: flatParam ?? flat, |
| icon: iconParam ?? icon, |
| infoWindow: infoWindowParam ?? infoWindow, |
| position: positionParam ?? position, |
| rotation: rotationParam ?? rotation, |
| visible: visibleParam ?? visible, |
| zIndex: zIndexParam ?? zIndex, |
| onTap: onTapParam ?? onTap, |
| onDragStart: onDragStartParam ?? onDragStart, |
| onDrag: onDragParam ?? onDrag, |
| onDragEnd: onDragEndParam ?? onDragEnd, |
| ); |
| } |
| |
| /// Creates a new [Marker] object whose values are the same as this instance. |
| @override |
| Marker clone() => copyWith(); |
| |
| /// Converts this object to something serializable in JSON. |
| @override |
| Object toJson() { |
| final Map<String, Object> json = <String, Object>{}; |
| |
| void addIfPresent(String fieldName, Object? value) { |
| if (value != null) { |
| json[fieldName] = value; |
| } |
| } |
| |
| addIfPresent('markerId', markerId.value); |
| addIfPresent('alpha', alpha); |
| addIfPresent('anchor', _offsetToJson(anchor)); |
| addIfPresent('consumeTapEvents', consumeTapEvents); |
| addIfPresent('draggable', draggable); |
| addIfPresent('flat', flat); |
| addIfPresent('icon', icon.toJson()); |
| addIfPresent('infoWindow', infoWindow._toJson()); |
| addIfPresent('position', position.toJson()); |
| addIfPresent('rotation', rotation); |
| addIfPresent('visible', visible); |
| addIfPresent('zIndex', zIndex); |
| return json; |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is Marker && |
| markerId == other.markerId && |
| alpha == other.alpha && |
| anchor == other.anchor && |
| consumeTapEvents == other.consumeTapEvents && |
| draggable == other.draggable && |
| flat == other.flat && |
| icon == other.icon && |
| infoWindow == other.infoWindow && |
| position == other.position && |
| rotation == other.rotation && |
| visible == other.visible && |
| zIndex == other.zIndex; |
| } |
| |
| @override |
| int get hashCode => markerId.hashCode; |
| |
| @override |
| String toString() { |
| return 'Marker{markerId: $markerId, alpha: $alpha, anchor: $anchor, ' |
| 'consumeTapEvents: $consumeTapEvents, draggable: $draggable, flat: $flat, ' |
| 'icon: $icon, infoWindow: $infoWindow, position: $position, rotation: $rotation, ' |
| 'visible: $visible, zIndex: $zIndex, onTap: $onTap, onDragStart: $onDragStart, ' |
| 'onDrag: $onDrag, onDragEnd: $onDragEnd}'; |
| } |
| } |