| // 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 'package:collection/collection.dart'; |
| import 'package:flutter/foundation.dart' |
| show immutable, listEquals, VoidCallback; |
| import 'package:flutter/material.dart' show Color, Colors; |
| |
| import 'types.dart'; |
| |
| /// Uniquely identifies a [Polygon] among [GoogleMap] polygons. |
| /// |
| /// This does not have to be globally unique, only unique among the list. |
| @immutable |
| class PolygonId extends MapsObjectId<Polygon> { |
| /// Creates an immutable identifier for a [Polygon]. |
| const PolygonId(super.value); |
| } |
| |
| /// Draws a polygon through geographical locations on the map. |
| @immutable |
| class Polygon implements MapsObject<Polygon> { |
| /// Creates an immutable representation of a polygon through geographical locations on the map. |
| const Polygon({ |
| required this.polygonId, |
| this.consumeTapEvents = false, |
| this.fillColor = Colors.black, |
| this.geodesic = false, |
| this.points = const <LatLng>[], |
| this.holes = const <List<LatLng>>[], |
| this.strokeColor = Colors.black, |
| this.strokeWidth = 10, |
| this.visible = true, |
| this.zIndex = 0, |
| this.onTap, |
| }); |
| |
| /// Uniquely identifies a [Polygon]. |
| final PolygonId polygonId; |
| |
| @override |
| PolygonId get mapsId => polygonId; |
| |
| /// True if the [Polygon] consumes tap events. |
| /// |
| /// If this is false, [onTap] callback will not be triggered. |
| final bool consumeTapEvents; |
| |
| /// Fill color in ARGB format, the same format used by Color. The default value is black (0xff000000). |
| final Color fillColor; |
| |
| /// Indicates whether the segments of the polygon should be drawn as geodesics, as opposed to straight lines |
| /// on the Mercator projection. |
| /// |
| /// A geodesic is the shortest path between two points on the Earth's surface. |
| /// The geodesic curve is constructed assuming the Earth is a sphere |
| final bool geodesic; |
| |
| /// The vertices of the polygon to be drawn. |
| /// |
| /// Line segments are drawn between consecutive points. A polygon is not closed by |
| /// default; to form a closed polygon, the start and end points must be the same. |
| final List<LatLng> points; |
| |
| /// To create an empty area within a polygon, you need to use holes. |
| /// To create the hole, the coordinates defining the hole path must be inside the polygon. |
| /// |
| /// The vertices of the holes to be cut out of polygon. |
| /// |
| /// Line segments of each points of hole are drawn inside polygon between consecutive hole points. |
| final List<List<LatLng>> holes; |
| |
| /// True if the marker is visible. |
| final bool visible; |
| |
| /// Line color in ARGB format, the same format used by Color. The default value is black (0xff000000). |
| final Color strokeColor; |
| |
| /// Width of the polygon, used to define the width of the line to be drawn. |
| /// |
| /// The width is constant and independent of the camera's zoom level. |
| /// The default value is 10. |
| final int strokeWidth; |
| |
| /// The z-index of the polygon, 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 int zIndex; |
| |
| /// Callbacks to receive tap events for polygon placed on this map. |
| final VoidCallback? onTap; |
| |
| /// Creates a new [Polygon] object whose values are the same as this instance, |
| /// unless overwritten by the specified parameters. |
| Polygon copyWith({ |
| bool? consumeTapEventsParam, |
| Color? fillColorParam, |
| bool? geodesicParam, |
| List<LatLng>? pointsParam, |
| List<List<LatLng>>? holesParam, |
| Color? strokeColorParam, |
| int? strokeWidthParam, |
| bool? visibleParam, |
| int? zIndexParam, |
| VoidCallback? onTapParam, |
| }) { |
| return Polygon( |
| polygonId: polygonId, |
| consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents, |
| fillColor: fillColorParam ?? fillColor, |
| geodesic: geodesicParam ?? geodesic, |
| points: pointsParam ?? points, |
| holes: holesParam ?? holes, |
| strokeColor: strokeColorParam ?? strokeColor, |
| strokeWidth: strokeWidthParam ?? strokeWidth, |
| visible: visibleParam ?? visible, |
| onTap: onTapParam ?? onTap, |
| zIndex: zIndexParam ?? zIndex, |
| ); |
| } |
| |
| /// Creates a new [Polygon] object whose values are the same as this instance. |
| @override |
| Polygon clone() { |
| return copyWith(pointsParam: List<LatLng>.of(points)); |
| } |
| |
| /// 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('polygonId', polygonId.value); |
| addIfPresent('consumeTapEvents', consumeTapEvents); |
| addIfPresent('fillColor', fillColor.value); |
| addIfPresent('geodesic', geodesic); |
| addIfPresent('strokeColor', strokeColor.value); |
| addIfPresent('strokeWidth', strokeWidth); |
| addIfPresent('visible', visible); |
| addIfPresent('zIndex', zIndex); |
| |
| json['points'] = _pointsToJson(); |
| |
| json['holes'] = _holesToJson(); |
| |
| return json; |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is Polygon && |
| polygonId == other.polygonId && |
| consumeTapEvents == other.consumeTapEvents && |
| fillColor == other.fillColor && |
| geodesic == other.geodesic && |
| listEquals(points, other.points) && |
| const DeepCollectionEquality().equals(holes, other.holes) && |
| visible == other.visible && |
| strokeColor == other.strokeColor && |
| strokeWidth == other.strokeWidth && |
| zIndex == other.zIndex; |
| } |
| |
| @override |
| int get hashCode => polygonId.hashCode; |
| |
| Object _pointsToJson() { |
| final List<Object> result = <Object>[]; |
| for (final LatLng point in points) { |
| result.add(point.toJson()); |
| } |
| return result; |
| } |
| |
| List<List<Object>> _holesToJson() { |
| final List<List<Object>> result = <List<Object>>[]; |
| for (final List<LatLng> hole in holes) { |
| final List<Object> jsonHole = <Object>[]; |
| for (final LatLng point in hole) { |
| jsonHole.add(point.toJson()); |
| } |
| result.add(jsonHole); |
| } |
| return result; |
| } |
| } |