/** * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ import type {LngLatArray} from './marker-attributes'; type PositionFormat = { isValid(value: unknown): value is T; toLatLng(value: T): google.maps.LatLng; fromLatLng(value: google.maps.LatLng): T; }; const LatLngFormat: PositionFormat = { isValid(value: unknown): value is google.maps.LatLng { return typeof value === 'object' && value instanceof google.maps.LatLng; }, fromLatLng(value: google.maps.LatLng): google.maps.LatLng { return value; }, toLatLng(value: google.maps.LatLng): google.maps.LatLng { return value; } }; const LngLatArrayFormat: PositionFormat = { isValid(value: unknown): value is LngLatArray { return Array.isArray(value) && value.length === 2; }, fromLatLng(p: google.maps.LatLng): LngLatArray { return [p.lng(), p.lat()]; }, toLatLng(p: LngLatArray): google.maps.LatLng { return new google.maps.LatLng(p[1], p[0]); } }; const LatLngLiteralFormat: PositionFormat = { isValid(value: unknown): value is google.maps.LatLngLiteral { return ( value !== null && typeof value === 'object' && 'lat' in value && 'lng' in value ); }, fromLatLng(p: google.maps.LatLng): google.maps.LatLngLiteral { return p.toJSON(); }, toLatLng(p: google.maps.LatLngLiteral): google.maps.LatLng { return new google.maps.LatLng(p); } }; /** Union type of all position-formats supported by the markers. */ export type Position = | google.maps.LatLngLiteral | google.maps.LatLng | LngLatArray; /** The supported position-formats. */ export const positionFormats = [ LatLngFormat, LngLatArrayFormat, LatLngLiteralFormat ]; /** * Returns the position-format for the specified datum. * * @param p */ export function getPositionFormat(p: Position): PositionFormat { for (const fmt of positionFormats) { if (fmt.isValid(p)) return fmt; } throw new Error('unknown position format'); } /** * Converts the specified datum into the google.maps.LatLng format used * internally. * * @param p */ export function toLatLng(p: Position): google.maps.LatLng { return getPositionFormat(p).toLatLng(p); }