or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analytics-monetization.mdcamera-media.mddevice-sensors.mddevice-system.mdindex.mdinput-hardware.mdlocation-maps.mdnetwork-communication.mdnotifications-ui.mdsecurity-auth.mdsocial-sharing.mdstorage-files.md
tile.json

location-maps.mddocs/

0

# Location & Maps

1

2

Geolocation services, background location tracking, geofencing capabilities, and maps integration for location-aware applications.

3

4

## Capabilities

5

6

### Geolocation

7

8

Access device location services for current position and continuous location tracking with configurable accuracy options.

9

10

```typescript { .api }

11

/**

12

* Geographic coordinates interface

13

*/

14

interface Coordinates {

15

/** Latitude in decimal degrees */

16

latitude: number;

17

/** Longitude in decimal degrees */

18

longitude: number;

19

/** Altitude in meters above the reference ellipsoid */

20

altitude: number;

21

/** Accuracy of latitude and longitude coordinates in meters */

22

accuracy: number;

23

/** Accuracy of altitude coordinate in meters */

24

altitudeAccuracy: number;

25

/** Direction of travel in degrees (0-359.99) */

26

heading: number;

27

/** Current ground speed in meters per second */

28

speed: number;

29

}

30

31

/**

32

* Geographic position with timestamp

33

*/

34

interface Geoposition {

35

/** Geographic coordinates */

36

coords: Coordinates;

37

/** Timestamp when location was retrieved */

38

timestamp: number;

39

}

40

41

/**

42

* Position error information

43

*/

44

interface PositionError {

45

/** Error code (1: PERMISSION_DENIED, 2: POSITION_UNAVAILABLE, 3: TIMEOUT) */

46

code: number;

47

/** Error message */

48

message: string;

49

}

50

51

/**

52

* Geolocation options

53

*/

54

interface GeolocationOptions {

55

/** Enable high accuracy mode (uses GPS) */

56

enableHighAccuracy?: boolean;

57

/** Timeout for location request in milliseconds */

58

timeout?: number;

59

/** Maximum age of cached position in milliseconds */

60

maximumAge?: number;

61

}

62

63

/**

64

* Geolocation class for location services

65

*/

66

class Geolocation {

67

/**

68

* Get current device position

69

* @param options Location options

70

* @returns Promise resolving to current Geoposition

71

*/

72

static getCurrentPosition(options?: GeolocationOptions): Promise<Geoposition>;

73

74

/**

75

* Watch device position changes

76

* @param options Location options

77

* @returns Observable emitting Geoposition updates

78

*/

79

static watchPosition(options?: GeolocationOptions): Observable<Geoposition>;

80

}

81

```

82

83

**Usage Examples:**

84

85

```typescript

86

import { Geolocation, GeolocationOptions } from 'ionic-native';

87

88

// Get current location

89

async function getCurrentLocation() {

90

const options: GeolocationOptions = {

91

enableHighAccuracy: true,

92

timeout: 10000,

93

maximumAge: 60000

94

};

95

96

try {

97

const position = await Geolocation.getCurrentPosition(options);

98

99

console.log('Current position:');

100

console.log('Latitude:', position.coords.latitude);

101

console.log('Longitude:', position.coords.longitude);

102

console.log('Accuracy:', position.coords.accuracy, 'meters');

103

104

return {

105

lat: position.coords.latitude,

106

lng: position.coords.longitude,

107

accuracy: position.coords.accuracy

108

};

109

} catch (error) {

110

console.error('Error getting location:', error);

111

throw error;

112

}

113

}

114

115

// Watch position changes for navigation

116

function startLocationTracking() {

117

const options: GeolocationOptions = {

118

enableHighAccuracy: true,

119

timeout: 5000,

120

maximumAge: 0

121

};

122

123

return Geolocation.watchPosition(options).subscribe(

124

(position) => {

125

console.log('Position update:', {

126

lat: position.coords.latitude,

127

lng: position.coords.longitude,

128

accuracy: position.coords.accuracy,

129

speed: position.coords.speed,

130

heading: position.coords.heading,

131

timestamp: new Date(position.timestamp)

132

});

133

134

// Update map marker

135

updateMapPosition(position.coords);

136

137

// Log movement if speed > 0

138

if (position.coords.speed > 0) {

139

logMovement(position);

140

}

141

},

142

(error) => {

143

console.error('Location error:', error);

144

handleLocationError(error);

145

}

146

);

147

}

148

149

// Distance calculation between two points

150

function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number) {

151

const R = 6371e3; // Earth's radius in meters

152

const φ1 = lat1 * Math.PI/180;

153

const φ2 = lat2 * Math.PI/180;

154

const Δφ = (lat2-lat1) * Math.PI/180;

155

const Δλ = (lon2-lon1) * Math.PI/180;

156

157

const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +

158

Math.cos(φ1) * Math.cos(φ2) *

159

Math.sin(Δλ/2) * Math.sin(Δλ/2);

160

const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

161

162

return R * c; // Distance in meters

163

}

164

165

// Location-based features

166

async function findNearbyPlaces(radius: number = 1000) {

167

try {

168

const position = await getCurrentLocation();

169

170

// Find nearby places within radius

171

const nearbyPlaces = await searchNearbyPlaces(

172

position.lat,

173

position.lng,

174

radius

175

);

176

177

return nearbyPlaces;

178

} catch (error) {

179

console.error('Error finding nearby places:', error);

180

return [];

181

}

182

}

183

```

184

185

### Background Geolocation

186

187

Continuous location tracking that works when the app is in the background for tracking and navigation use cases.

188

189

```typescript { .api }

190

/**

191

* Background geolocation configuration

192

*/

193

interface BackgroundGeolocationConfig {

194

/** Desired accuracy in meters (iOS: kCLLocationAccuracyXXX) */

195

desiredAccuracy?: number;

196

/** Stationary radius in meters */

197

stationaryRadius?: number;

198

/** Distance filter in meters */

199

distanceFilter?: number;

200

/** Enable debug mode */

201

debug?: boolean;

202

/** Location timeout in milliseconds */

203

interval?: number;

204

/** Fastest location interval in milliseconds */

205

fastestInterval?: number;

206

/** Activity type for iOS (AutomotiveNavigation, Navigation, Fitness, Other) */

207

activityType?: string;

208

/** Defer location updates until later */

209

deferLocationUpdates?: boolean;

210

/** Stop on terminate */

211

stopOnTerminate?: boolean;

212

/** Start on boot */

213

startOnBoot?: boolean;

214

/** Start in foreground */

215

startForeground?: boolean;

216

/** Notification title (Android) */

217

notificationTitle?: string;

218

/** Notification text (Android) */

219

notificationText?: string;

220

/** Notification icon (Android) */

221

notificationIcon?: string;

222

/** Location provider (GPS_PROVIDER, NETWORK_PROVIDER, PASSIVE_PROVIDER) */

223

locationProvider?: number;

224

}

225

226

/**

227

* Background location data

228

*/

229

interface BackgroundLocation {

230

/** Latitude */

231

latitude: number;

232

/** Longitude */

233

longitude: number;

234

/** Accuracy in meters */

235

accuracy: number;

236

/** Altitude in meters */

237

altitude: number;

238

/** Speed in m/s */

239

speed: number;

240

/** Bearing in degrees */

241

bearing: number;

242

/** Location timestamp */

243

time: number;

244

/** Location provider used */

245

provider: string;

246

}

247

248

/**

249

* BackgroundGeolocation class for continuous location tracking

250

*/

251

class BackgroundGeolocation {

252

/**

253

* Configure background location tracking

254

* @param options Configuration options

255

* @returns Observable emitting location updates

256

*/

257

static configure(options: BackgroundGeolocationConfig): Observable<BackgroundLocation>;

258

259

/**

260

* Start background location tracking

261

*/

262

static start(): void;

263

264

/**

265

* Stop background location tracking

266

*/

267

static stop(): void;

268

269

/**

270

* Check if location services are enabled

271

* @returns Promise resolving to boolean

272

*/

273

static isLocationEnabled(): Promise<boolean>;

274

275

/**

276

* Show app-specific settings

277

*/

278

static showAppSettings(): void;

279

280

/**

281

* Show location settings

282

*/

283

static showLocationSettings(): void;

284

285

/**

286

* Check plugin status

287

* @returns Promise resolving to status object

288

*/

289

static checkStatus(): Promise<any>;

290

291

/**

292

* Get stationary location

293

* @returns Promise resolving to location

294

*/

295

static getStationaryLocation(): Promise<BackgroundLocation>;

296

297

/**

298

* Get plugin log entries

299

* @param limit Maximum number of entries

300

* @returns Promise resolving to log entries

301

*/

302

static getLogEntries(limit: number): Promise<any>;

303

}

304

```

305

306

**Usage Examples:**

307

308

```typescript

309

import { BackgroundGeolocation, BackgroundGeolocationConfig } from 'ionic-native';

310

311

// Configure and start background tracking

312

function startBackgroundTracking() {

313

const config: BackgroundGeolocationConfig = {

314

desiredAccuracy: 10,

315

stationaryRadius: 20,

316

distanceFilter: 30,

317

debug: false,

318

interval: 60000,

319

fastestInterval: 5000,

320

activitiesInterval: 300000,

321

activityType: 'AutomotiveNavigation',

322

stopOnTerminate: false,

323

startOnBoot: true,

324

startForeground: false,

325

notificationTitle: 'Location Tracking',

326

notificationText: 'Your location is being tracked',

327

locationProvider: 1 // GPS_PROVIDER

328

};

329

330

BackgroundGeolocation.configure(config).subscribe(

331

(location) => {

332

console.log('Background location update:', {

333

latitude: location.latitude,

334

longitude: location.longitude,

335

accuracy: location.accuracy,

336

speed: location.speed,

337

timestamp: new Date(location.time)

338

});

339

340

// Save location to local storage or send to server

341

saveLocationUpdate(location);

342

},

343

(error) => {

344

console.error('Background location error:', error);

345

}

346

);

347

348

// Start tracking

349

BackgroundGeolocation.start();

350

}

351

352

// Trip tracking functionality

353

class TripTracker {

354

private trackingSubscription: any;

355

private tripData: BackgroundLocation[] = [];

356

357

async startTrip() {

358

try {

359

const isEnabled = await BackgroundGeolocation.isLocationEnabled();

360

if (!isEnabled) {

361

BackgroundGeolocation.showLocationSettings();

362

return;

363

}

364

365

const config: BackgroundGeolocationConfig = {

366

desiredAccuracy: 10,

367

distanceFilter: 10,

368

interval: 5000,

369

debug: true,

370

notificationTitle: 'Trip in Progress',

371

notificationText: 'Recording your journey'

372

};

373

374

this.trackingSubscription = BackgroundGeolocation.configure(config).subscribe(

375

(location) => {

376

this.tripData.push(location);

377

this.updateTripStats(location);

378

}

379

);

380

381

BackgroundGeolocation.start();

382

console.log('Trip started');

383

} catch (error) {

384

console.error('Failed to start trip:', error);

385

}

386

}

387

388

stopTrip() {

389

if (this.trackingSubscription) {

390

this.trackingSubscription.unsubscribe();

391

}

392

393

BackgroundGeolocation.stop();

394

395

const tripSummary = this.calculateTripSummary();

396

console.log('Trip completed:', tripSummary);

397

398

return tripSummary;

399

}

400

401

private updateTripStats(location: BackgroundLocation) {

402

// Calculate distance, speed, etc.

403

if (this.tripData.length > 1) {

404

const prevLocation = this.tripData[this.tripData.length - 2];

405

const distance = this.calculateDistance(

406

prevLocation.latitude, prevLocation.longitude,

407

location.latitude, location.longitude

408

);

409

410

console.log(`Distance since last point: ${distance.toFixed(2)}m`);

411

}

412

}

413

414

private calculateTripSummary() {

415

if (this.tripData.length < 2) {

416

return { distance: 0, duration: 0, avgSpeed: 0 };

417

}

418

419

let totalDistance = 0;

420

for (let i = 1; i < this.tripData.length; i++) {

421

const prev = this.tripData[i - 1];

422

const curr = this.tripData[i];

423

424

totalDistance += this.calculateDistance(

425

prev.latitude, prev.longitude,

426

curr.latitude, curr.longitude

427

);

428

}

429

430

const startTime = this.tripData[0].time;

431

const endTime = this.tripData[this.tripData.length - 1].time;

432

const duration = (endTime - startTime) / 1000; // seconds

433

const avgSpeed = totalDistance / duration; // m/s

434

435

return {

436

distance: totalDistance,

437

duration,

438

avgSpeed,

439

points: this.tripData.length

440

};

441

}

442

443

private calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number) {

444

// Haversine formula implementation

445

const R = 6371e3;

446

const φ1 = lat1 * Math.PI/180;

447

const φ2 = lat2 * Math.PI/180;

448

const Δφ = (lat2-lat1) * Math.PI/180;

449

const Δλ = (lon2-lon1) * Math.PI/180;

450

451

const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +

452

Math.cos(φ1) * Math.cos(φ2) *

453

Math.sin(Δλ/2) * Math.sin(Δλ/2);

454

const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

455

456

return R * c;

457

}

458

}

459

```

460

461

### Geofencing

462

463

Set up geographic boundaries and receive notifications when entering or leaving defined areas.

464

465

```typescript { .api }

466

/**

467

* Geofence configuration options

468

*/

469

interface GeofenceOptions {

470

/** Unique geofence identifier */

471

id: string;

472

/** Latitude of geofence center */

473

latitude: number;

474

/** Longitude of geofence center */

475

longitude: number;

476

/** Radius in meters */

477

radius: number;

478

/** Transition types to monitor (1: ENTER, 2: EXIT, 3: BOTH) */

479

transitionType: number;

480

/** Notification configuration */

481

notification?: {

482

/** Notification ID */

483

id?: number;

484

/** Notification title */

485

title?: string;

486

/** Notification text */

487

text?: string;

488

/** Small icon */

489

smallIcon?: string;

490

/** Large icon */

491

icon?: string;

492

/** Open app on click */

493

openAppOnClick?: boolean;

494

/** Vibration pattern */

495

vibrate?: number[];

496

/** Data payload */

497

data?: any;

498

};

499

}

500

501

/**

502

* Geofence transition event

503

*/

504

interface GeofenceTransition {

505

/** Geofence ID */

506

fenceKey: string;

507

/** Transition type (ENTER or EXIT) */

508

transitionType: string;

509

/** Device location when transition occurred */

510

location: {

511

latitude: number;

512

longitude: number;

513

accuracy: number;

514

speed: number;

515

altitude: number;

516

};

517

}

518

519

/**

520

* Geofence class for location-based triggers

521

*/

522

class Geofence {

523

/**

524

* Initialize geofencing service

525

* @returns Promise indicating initialization completion

526

*/

527

static initialize(): Promise<any>;

528

529

/**

530

* Add or update geofences

531

* @param geofences Array of geofence configurations

532

* @returns Promise indicating operation completion

533

*/

534

static addOrUpdate(geofences: GeofenceOptions[]): Promise<any>;

535

536

/**

537

* Remove geofences by ID

538

* @param geofenceIds Array of geofence IDs to remove

539

* @returns Promise indicating removal completion

540

*/

541

static remove(geofenceIds: string[]): Promise<any>;

542

543

/**

544

* Remove all geofences

545

* @returns Promise indicating removal completion

546

*/

547

static removeAll(): Promise<any>;

548

549

/**

550

* Get list of watched geofences

551

* @returns Promise resolving to array of geofence IDs

552

*/

553

static getWatched(): Promise<string[]>;

554

555

/**

556

* Observable for geofence transition events

557

* @returns Observable emitting GeofenceTransition events

558

*/

559

static onTransitionReceived(): Observable<GeofenceTransition>;

560

561

/**

562

* Observable for notification click events

563

* @returns Observable emitting notification click events

564

*/

565

static onNotificationClicked(): Observable<any>;

566

}

567

```

568

569

**Usage Examples:**

570

571

```typescript

572

import { Geofence, GeofenceOptions } from 'ionic-native';

573

574

// Initialize geofencing service

575

async function initializeGeofencing() {

576

try {

577

await Geofence.initialize();

578

console.log('Geofencing initialized');

579

580

// Set up event listeners

581

setupGeofenceListeners();

582

} catch (error) {

583

console.error('Geofencing initialization failed:', error);

584

}

585

}

586

587

// Set up geofence event listeners

588

function setupGeofenceListeners() {

589

// Listen for geofence transitions

590

Geofence.onTransitionReceived().subscribe((transition) => {

591

console.log('Geofence transition:', {

592

fence: transition.fenceKey,

593

type: transition.transitionType,

594

location: transition.location

595

});

596

597

handleGeofenceTransition(transition);

598

});

599

600

// Listen for notification clicks

601

Geofence.onNotificationClicked().subscribe((notificationData) => {

602

console.log('Geofence notification clicked:', notificationData);

603

handleNotificationClick(notificationData);

604

});

605

}

606

607

// Create geofences for important locations

608

async function createLocationGeofences() {

609

const geofences: GeofenceOptions[] = [

610

{

611

id: 'home',

612

latitude: 37.7749,

613

longitude: -122.4194,

614

radius: 100,

615

transitionType: 3, // Both enter and exit

616

notification: {

617

id: 1,

618

title: 'Home',

619

text: 'Welcome home!',

620

openAppOnClick: true,

621

vibrate: [1000, 1000, 1000],

622

data: { type: 'home', action: 'arrived' }

623

}

624

},

625

{

626

id: 'work',

627

latitude: 37.7849,

628

longitude: -122.4094,

629

radius: 200,

630

transitionType: 1, // Enter only

631

notification: {

632

id: 2,

633

title: 'Work',

634

text: 'You have arrived at work',

635

openAppOnClick: false,

636

data: { type: 'work', action: 'checkin' }

637

}

638

},

639

{

640

id: 'gym',

641

latitude: 37.7649,

642

longitude: -122.4294,

643

radius: 50,

644

transitionType: 3, // Both

645

notification: {

646

id: 3,

647

title: 'Gym',

648

text: 'Time for your workout!',

649

openAppOnClick: true,

650

data: { type: 'gym', action: 'workout' }

651

}

652

}

653

];

654

655

try {

656

await Geofence.addOrUpdate(geofences);

657

console.log('Geofences created successfully');

658

659

const watched = await Geofence.getWatched();

660

console.log('Currently watched geofences:', watched);

661

} catch (error) {

662

console.error('Failed to create geofences:', error);

663

}

664

}

665

666

// Handle geofence transitions

667

function handleGeofenceTransition(transition: GeofenceTransition) {

668

const { fenceKey, transitionType, location } = transition;

669

670

switch (fenceKey) {

671

case 'home':

672

if (transitionType === 'ENTER') {

673

// Arrived home

674

console.log('Welcome home!');

675

setHomeMode(true);

676

} else if (transitionType === 'EXIT') {

677

// Left home

678

console.log('Left home');

679

setHomeMode(false);

680

}

681

break;

682

683

case 'work':

684

if (transitionType === 'ENTER') {

685

// Arrived at work

686

console.log('Checking in at work');

687

checkInAtWork(location);

688

}

689

break;

690

691

case 'gym':

692

if (transitionType === 'ENTER') {

693

// Entered gym

694

console.log('Starting workout session');

695

startWorkoutSession();

696

} else if (transitionType === 'EXIT') {

697

// Left gym

698

console.log('Ending workout session');

699

endWorkoutSession();

700

}

701

break;

702

}

703

}

704

705

// Dynamic geofence management

706

class GeofenceManager {

707

private activeGeofences: Set<string> = new Set();

708

709

async addTemporaryGeofence(id: string, lat: number, lng: number, radius: number, durationMinutes: number) {

710

const geofence: GeofenceOptions = {

711

id,

712

latitude: lat,

713

longitude: lng,

714

radius,

715

transitionType: 3,

716

notification: {

717

title: 'Temporary Alert',

718

text: `You are near ${id}`,

719

openAppOnClick: true

720

}

721

};

722

723

await Geofence.addOrUpdate([geofence]);

724

this.activeGeofences.add(id);

725

726

// Auto-remove after duration

727

setTimeout(async () => {

728

await this.removeGeofence(id);

729

}, durationMinutes * 60 * 1000);

730

}

731

732

async removeGeofence(id: string) {

733

if (this.activeGeofences.has(id)) {

734

await Geofence.remove([id]);

735

this.activeGeofences.delete(id);

736

console.log(`Geofence ${id} removed`);

737

}

738

}

739

740

async clearAllGeofences() {

741

await Geofence.removeAll();

742

this.activeGeofences.clear();

743

console.log('All geofences cleared');

744

}

745

746

getActiveGeofences(): string[] {

747

return Array.from(this.activeGeofences);

748

}

749

}

750

```

751

752

### Google Maps Integration

753

754

Integrate Google Maps with native map functionality and custom controls.

755

756

```typescript { .api }

757

/**

758

* Google Map configuration options

759

*/

760

interface GoogleMapOptions {

761

/** Map center coordinates */

762

center?: { lat: number; lng: number; };

763

/** Initial zoom level */

764

zoom?: number;

765

/** Map type (MAP_TYPE_NORMAL, MAP_TYPE_ROADMAP, MAP_TYPE_SATELLITE, MAP_TYPE_HYBRID, MAP_TYPE_TERRAIN) */

766

mapType?: string;

767

/** Enable user location */

768

myLocationEnabled?: boolean;

769

/** Show my location button */

770

myLocationButtonEnabled?: boolean;

771

/** Enable indoor maps */

772

indoorEnabled?: boolean;

773

/** Show compass */

774

compassEnabled?: boolean;

775

/** Show zoom controls */

776

zoomControlsEnabled?: boolean;

777

/** Allow map rotation */

778

rotateGesturesEnabled?: boolean;

779

/** Allow map scrolling */

780

scrollGesturesEnabled?: boolean;

781

/** Allow map tilting */

782

tiltGesturesEnabled?: boolean;

783

/** Allow zoom gestures */

784

zoomGesturesEnabled?: boolean;

785

/** Map padding */

786

padding?: { top: number; right: number; bottom: number; left: number; };

787

}

788

789

/**

790

* Google Map instance interface

791

*/

792

interface GoogleMapObject {

793

/**

794

* Add marker to map

795

* @param options Marker options

796

* @returns Promise resolving to marker instance

797

*/

798

addMarker(options: MarkerOptions): Promise<any>;

799

800

/**

801

* Move camera to position

802

* @param target Camera target options

803

* @returns Promise indicating animation completion

804

*/

805

animateCamera(target: CameraPosition): Promise<any>;

806

807

/**

808

* Move camera to position instantly

809

* @param target Camera target options

810

*/

811

moveCamera(target: CameraPosition): void;

812

813

/**

814

* Get current camera position

815

* @returns Promise resolving to current camera position

816

*/

817

getCameraPosition(): Promise<CameraPosition>;

818

819

/**

820

* Set map bounds

821

* @param bounds Array of coordinates defining bounds

822

* @returns Promise indicating completion

823

*/

824

setMyLocationEnabled(enabled: boolean): Promise<any>;

825

826

/**

827

* Remove the map

828

*/

829

remove(): void;

830

831

/**

832

* Clear all overlays from map

833

*/

834

clear(): void;

835

836

/**

837

* Add event listener

838

* @param event Event name

839

* @returns Observable emitting map events

840

*/

841

on(event: string): Observable<any>;

842

}

843

844

/**

845

* Camera position for map view

846

*/

847

interface CameraPosition {

848

/** Target coordinates */

849

target?: { lat: number; lng: number; };

850

/** Zoom level */

851

zoom?: number;

852

/** Tilt angle */

853

tilt?: number;

854

/** Bearing angle */

855

bearing?: number;

856

/** Animation duration */

857

duration?: number;

858

}

859

860

/**

861

* Marker configuration options

862

*/

863

interface MarkerOptions {

864

/** Marker position */

865

position: { lat: number; lng: number; };

866

/** Marker title */

867

title?: string;

868

/** Marker snippet (subtitle) */

869

snippet?: string;

870

/** Marker icon */

871

icon?: string | any;

872

/** Marker anchor point */

873

anchor?: { x: number; y: number; };

874

/** Whether marker is draggable */

875

draggable?: boolean;

876

/** Whether marker is visible */

877

visible?: boolean;

878

/** Marker z-index */

879

zIndex?: number;

880

/** Custom data */

881

data?: any;

882

}

883

884

/**

885

* GoogleMap class for map integration

886

*/

887

class GoogleMap {

888

/**

889

* Check if Google Maps is available

890

* @returns Promise resolving to availability status

891

*/

892

static isAvailable(): Promise<boolean>;

893

894

/**

895

* Create Google Map instance

896

* @param element HTML element or selector for map container

897

* @param options Map configuration options

898

* @returns GoogleMapObject instance

899

*/

900

static create(element: string | HTMLElement, options?: GoogleMapOptions): GoogleMapObject;

901

}

902

```

903

904

**Usage Examples:**

905

906

```typescript

907

import { GoogleMap, GoogleMapOptions } from 'ionic-native';

908

909

// Initialize map

910

async function initializeMap(elementId: string) {

911

try {

912

const isAvailable = await GoogleMap.isAvailable();

913

if (!isAvailable) {

914

console.error('Google Maps not available');

915

return;

916

}

917

918

const options: GoogleMapOptions = {

919

center: { lat: 37.7749, lng: -122.4194 },

920

zoom: 12,

921

mapType: 'MAP_TYPE_NORMAL',

922

myLocationEnabled: true,

923

myLocationButtonEnabled: true,

924

compassEnabled: true,

925

zoomControlsEnabled: false,

926

scrollGesturesEnabled: true,

927

zoomGesturesEnabled: true,

928

rotateGesturesEnabled: true,

929

tiltGesturesEnabled: true

930

};

931

932

const map = GoogleMap.create(elementId, options);

933

934

// Set up event listeners

935

map.on('MAP_READY').subscribe(() => {

936

console.log('Map is ready');

937

addMapFeatures(map);

938

});

939

940

map.on('MAP_CLICK').subscribe((event) => {

941

console.log('Map clicked at:', event.latLng);

942

});

943

944

return map;

945

} catch (error) {

946

console.error('Map initialization failed:', error);

947

}

948

}

949

950

// Add markers and features to map

951

async function addMapFeatures(map: GoogleMapObject) {

952

// Add custom markers

953

const locations = [

954

{ lat: 37.7749, lng: -122.4194, title: 'San Francisco', snippet: 'The Golden City' },

955

{ lat: 37.7849, lng: -122.4094, title: 'North Beach', snippet: 'Italian District' },

956

{ lat: 37.7649, lng: -122.4294, title: 'Mission District', snippet: 'Vibrant Neighborhood' }

957

];

958

959

for (const location of locations) {

960

await map.addMarker({

961

position: { lat: location.lat, lng: location.lng },

962

title: location.title,

963

snippet: location.snippet,

964

icon: 'blue',

965

draggable: false,

966

data: { type: 'poi', id: location.title.toLowerCase() }

967

});

968

}

969

970

// Add marker click listener

971

map.on('MARKER_CLICK').subscribe((marker) => {

972

console.log('Marker clicked:', marker.title);

973

showMarkerDetails(marker);

974

});

975

}

976

977

// Location-based map features

978

class LocationMap {

979

private map: GoogleMapObject;

980

private userMarker: any;

981

private locationWatcher: any;

982

983

async initialize(elementId: string) {

984

this.map = GoogleMap.create(elementId, {

985

myLocationEnabled: true,

986

myLocationButtonEnabled: true,

987

zoom: 15

988

});

989

990

await this.map.on('MAP_READY').toPromise();

991

this.startLocationTracking();

992

}

993

994

async startLocationTracking() {

995

try {

996

const position = await Geolocation.getCurrentPosition({

997

enableHighAccuracy: true

998

});

999

1000

// Center map on user location

1001

this.map.animateCamera({

1002

target: {

1003

lat: position.coords.latitude,

1004

lng: position.coords.longitude

1005

},

1006

zoom: 16,

1007

duration: 1000

1008

});

1009

1010

// Add user marker

1011

this.userMarker = await this.map.addMarker({

1012

position: {

1013

lat: position.coords.latitude,

1014

lng: position.coords.longitude

1015

},

1016

title: 'You are here',

1017

icon: 'red'

1018

});

1019

1020

// Watch position changes

1021

this.locationWatcher = Geolocation.watchPosition({

1022

enableHighAccuracy: true,

1023

timeout: 10000,

1024

maximumAge: 1000

1025

}).subscribe((pos) => {

1026

this.updateUserPosition(pos.coords.latitude, pos.coords.longitude);

1027

});

1028

1029

} catch (error) {

1030

console.error('Location tracking failed:', error);

1031

}

1032

}

1033

1034

private async updateUserPosition(lat: number, lng: number) {

1035

if (this.userMarker) {

1036

// Update marker position

1037

this.userMarker.setPosition({ lat, lng });

1038

1039

// Optionally animate camera to follow user

1040

this.map.animateCamera({

1041

target: { lat, lng },

1042

duration: 500

1043

});

1044

}

1045

}

1046

1047

async addNearbyPlaces(places: any[]) {

1048

for (const place of places) {

1049

await this.map.addMarker({

1050

position: { lat: place.lat, lng: place.lng },

1051

title: place.name,

1052

snippet: place.description,

1053

icon: this.getPlaceIcon(place.type),

1054

data: place

1055

});

1056

}

1057

}

1058

1059

private getPlaceIcon(type: string): string {

1060

const iconMap: { [key: string]: string } = {

1061

restaurant: 'orange',

1062

gas_station: 'green',

1063

hospital: 'red',

1064

school: 'blue',

1065

park: 'green'

1066

};

1067

1068

return iconMap[type] || 'gray';

1069

}

1070

1071

destroy() {

1072

if (this.locationWatcher) {

1073

this.locationWatcher.unsubscribe();

1074

}

1075

1076

if (this.map) {

1077

this.map.remove();

1078

}

1079

}

1080

}

1081

```