# Google Maps Jodit plugin

Jodit Google Maps is the plugin for easy inserting and editing Google Maps into the pages. You can specify your office
location, draw the route to it, place all of your travel targets or anything else.

[Demo](#demo)

The main features of this Jodit plugin are:

- Create points, routes, areas onto the map
- Customizing size, zoom or center of the map
- Configuring Google Map type (Roadmap / Sattelite / Hybrid / Relief)
- Search for objects by street addresses, cities, etc.
- Editing any of the maps you have inserted before
- Configuring layers (traffic etc.)

## Options

### googleMaps.API_KEY

- Type: String
- Default: ''
- Required: true

This option is required for Google Maps to work on your site. The cards won't work without it.

```js
Jodit.make('#editor', {
	googleMaps: {
		API_KEY: 'AIzaSyDjnR03hxN8fo0QJ85Jkkvk2DALTh3eynY'
	}
});
```

### googleMaps.apiUrl

- Type: String
- Default: 'https://maps.googleapis.com/maps/api/js?key=${j.o.googleMaps.API_KEY}&libraries=geometry,places&language=${j.o.language}&callback=GoogleReadyHandler'

Option for specifying JS API download url.

### googleMaps.useStaticImage

- Type: boolean
- Default: false

If True - Do not generate Google Maps JS API, but leave a static image.

### googleMaps.saveStateInStorage

- Type: Boolean
- Default: true

If this setting is enabled, the plugin will remember the position and zoom of the map in the local storage.

```js
Jodit.make('#editor', {
	googleMaps: {
		saveStateInStorage: false
	}
});
```

### googleMaps.inlineEditorOptions

- Type: Object
- Default:

```js
{ buttons: ['bold', 'italic', 'link', 'brush', 'fontsize', 'image'] }`;
```

Text editor settings for markers in the map. You can use any [options from Jodit](https://xdsoft.net/jodit/docs/classes/config.Config.html).

```js
Jodit.make('#editor', {
	googleMaps: {
		inlineEditorOptions: {
			buttons: ['bold', 'italic', 'link', 'googleMaps'], // Yes, it works! =)
			filebrowser: {
				// Options
			}
		}
	}
});
```

### googleMaps.map.type

- Type: 'hybrid' | 'roadmap' | 'satellite' | 'terrain'
- Default: 'roadmap'

Default card type.

```js
Jodit.make('#editor', {
	googleMaps: {
		map: {
			type: 'hybrid'
		}
	}
});
```

### googleMaps.map.center

- Type: 'auto' | [number, number]
- Default: 'auto'

The center of the map to which it will be installed at the first start. If the auto mode is enabled, then geolocation will be requested.

### googleMaps.map.zoom

- Type: number
- Default: 10

Default map zoom.

### googleMaps.map.layer

- Type: 'default' | 'traffic' | 'transit' | 'bicycling'
- Default: 'default'

The map layer that will be displayed by default.

```js
Jodit.make('#editor', {
    googleMaps: {
        map: {
            layer: 'traffic' // Show traffic information layer
        }
    }
});
```

### googleMaps.map.defaultCenter

- Type: [number, number]
- Default: [-34.397, 150.644]

Default map center coordinates that will be used if the user's location cannot be determined in 'auto' mode.

```js
Jodit.make('#editor', {
    googleMaps: {
        map: {
            defaultCenter: [55.7558, 37.6173] // Moscow
        }
    }
});
```

### googleMaps.map.defaultZoom

- Type: number
- Default: 10

Default map zoom level that will be used when the map is first opened.

```js
Jodit.make('#editor', {
    googleMaps: {
        map: {
            defaultZoom: 15
        }
    }
});
```

### googleMaps.map.size

- Type: [number, number]
- Default: [500, 400]

Default map size [width, height] in pixels.

```js
Jodit.make('#editor', {
    googleMaps: {
        map: {
            size: [800, 600]
        }
    }
});
```

### googleMaps.dialog.size

- Type: [number, number]
- Default: [700, 700]

Map editor dialog size [width, height] in pixels.

```js
Jodit.make('#editor', {
    googleMaps: {
        dialog: {
            size: [900, 800]
        }
    }
});
```

### googleMaps.map.defaultStates

- Type: Object
- Default:
```js
{
    polyline: {
        strokeColor: '#5ba4f3',
        strokeWeight: 3
    },
    polygon: {
        strokeColor: '#417706',
        fillColor: '#5b9302',
        strokeWeight: 1,
        fillOpacity: 0.5
    },
    marker: {},
    text: {},
    circle: {
        strokeColor: '#da767c',
        fillColor: '#f34ca8',
        strokeWeight: 1,
        fillOpacity: 0.5
    }
}
```

Default settings for various map elements (polylines, polygons, markers, text, circles).

```js
Jodit.make('#editor', {
    googleMaps: {
        map: {
            defaultStates: {
                polyline: {
                    strokeColor: '#FF0000',
                    strokeWeight: 5
                },
                polygon: {
                    strokeColor: '#0000FF',
                    fillColor: '#00FF00',
                    strokeWeight: 2,
                    fillOpacity: 0.7
                },
                circle: {
                    strokeColor: '#FFFF00',
                    fillColor: '#FFA500',
                    strokeWeight: 2,
                    fillOpacity: 0.6
                }
            }
        }
    }
});
```

## Examples

### Basic Usage

```js
const editor = Jodit.make('#editor', {
    extraPlugins: ['googleMaps'],
    googleMaps: {
        API_KEY: 'YOUR_GOOGLE_MAPS_API_KEY'
    }
});
```

### Configuring Map Type and Size

```js
const editor = Jodit.make('#editor', {
    extraPlugins: ['googleMaps'],
    googleMaps: {
        API_KEY: 'YOUR_GOOGLE_MAPS_API_KEY',
        map: {
            type: 'satellite',
            zoom: 12,
            size: [800, 500]
        }
    }
});
```

### Setting Map Center and Layer

```js
const editor = Jodit.make('#editor', {
    extraPlugins: ['googleMaps'],
    googleMaps: {
        API_KEY: 'YOUR_GOOGLE_MAPS_API_KEY',
        map: {
            center: [55.7558, 37.6173], // Moscow
            layer: 'traffic',
            zoom: 14
        }
    }
});
```

### Customizing Map Element Styles

```js
const editor = Jodit.make('#editor', {
    extraPlugins: ['googleMaps'],
    googleMaps: {
        API_KEY: 'YOUR_GOOGLE_MAPS_API_KEY',
        map: {
            defaultStates: {
                polyline: {
                    strokeColor: '#FF0000',
                    strokeWeight: 4
                },
                polygon: {
                    strokeColor: '#0000FF',
                    fillColor: '#00FF00',
                    strokeWeight: 2,
                    fillOpacity: 0.6
                },
                circle: {
                    strokeColor: '#FFFF00',
                    fillColor: '#FFA500',
                    strokeWeight: 2,
                    fillOpacity: 0.5
                }
            }
        }
    }
});
```

### Using Static Image

```js
const editor = Jodit.make('#editor', {
    extraPlugins: ['googleMaps'],
    googleMaps: {
        API_KEY: 'YOUR_GOOGLE_MAPS_API_KEY',
        useStaticImage: true
    }
});
```

## FAQ

> Q: do I need any API key to use Google Map?

A: Yes, you need API key. [How to create API_KEY for Google Maps](#how-to-create-api-key-for-google-maps). And need set option: [API_KEY](#googlemaps-api-key)

> Q: I see static image instead of Google Maps frame in the Jodit?

A: it is OK, it is just a preview in area of my editor. In the page where HTML code (which you a edit with editor) is
displayed, Google Maps widget is shown.

> Q: Why can't I see elements - circles - on a static picture?

A: [Google Maps Static API](https://developers.google.com/maps/documentation/maps-static/overview) does not support the Circle object.

> Q: Can I show static image on the result page too?

A: Yes, you can change options [useStaticImage](#googlemaps-usestaticimage)

> Q: How can I change the style of markers, polylines, and other map elements?

A: You can customize map element styles using the [defaultStates](#googlemaps-map-defaultstates) option

> Q: How can I change the map size?

A: You can change the map size using the [size](#googlemaps-map-size) option

## How to create API_KEY for Google Maps

You can find all the information on [this](https://developers.google.com/maps/documentation/maps-static/get-api-key).

In short, the algorithm is as follows:

1. You need create account [Google Cloud Console](https://console.cloud.google.com/project/_/google/maps-apis/overview) and create new project.
2. In your project you need enable 4 APIs: `Geocoding API`, `Maps JavaScript API`,` Maps Static API` and `Places API`
3. Go to the [Google Cloud Console](https://console.cloud.google.com/project/_/google/maps-apis/overview).
4. Click the project drop-down and select or create the project for which you want to add an API key.
5. Click the menu button and select `Google Maps Platform` > `Credentials`.
6. On the Credentials page, click + `Create Credentials` > `API key`.
7. The API key created dialog displays the newly created API key.
8. Click `Close`.
9. The new API key is listed on the `Credentials` page under API Keys.

> Remember to restrict the API key before using it in production.

1. Open the `Credentials` page and click on your key
2. In the `Application restrictions` field, select `HTTP referrers (websites)` so that your key can only be used on your websites.
3. In `Website restrictions` add all the sites where you allow your key to be used.
4. Here `API restrictions` select:` Geocoding API`, `Maps JavaScript API`,` Maps Static API` and `Places API`
5. Press `Save`

## API Reference

### Configuration Interface

The google-maps plugin extends the Jodit configuration with the following interface:

```typescript
interface Config {
    googleMaps: {
        saveStateInStorage: boolean;
        useStaticImage: boolean;
        apiUrl: string;
        API_KEY: string;
        inlineEditorOptions: DeepPartial<Config>;
        dialog: {
            size: [number, number];
        };
        map: {
            center: 'auto' | [number, number];
            type: IUIMapBaseState['type'];
            layer: IUIMapBaseState['layer'];
            defaultCenter: IUIMapBaseState['center'];
            defaultZoom: number;
            zoom: number;
            size: [number, number];
            defaultStates: {
                circle: Partial<ICircleState>;
                polygon: Partial<IPolygonState>;
                polyline: Partial<IPolylineState>;
                marker: Partial<IMarkerState>;
                text: Partial<ITextState>;
            };
        };
    };
}
```

### Map Element State Interfaces

#### IUIMapBaseState

Base interface for map state:

```typescript
interface IUIMapBaseState {
    type: 'hybrid' | 'roadmap' | 'satellite' | 'terrain';
    layer: 'default' | 'traffic' | 'transit' | 'bicycling';
    center: [number, number];
}
```

#### ICircleState

Interface for circle elements:

```typescript
interface ICircleState {
    strokeColor: string;
    fillColor: string;
    strokeWeight: number;
    fillOpacity: number;
}
```

#### IPolygonState

Interface for polygon elements:

```typescript
interface IPolygonState {
    strokeColor: string;
    fillColor: string;
    strokeWeight: number;
    fillOpacity: number;
}
```

#### IPolylineState

Interface for polyline elements:

```typescript
interface IPolylineState {
    strokeColor: string;
    strokeWeight: number;
}
```

#### IMarkerState

Interface for marker elements:

```typescript
interface IMarkerState {
    // Marker-specific properties
}
```

#### ITextState

Interface for text elements:

```typescript
interface ITextState {
    // Text-specific properties
}
```

### Control Configuration

The plugin registers controls with the following interfaces:

```typescript
interface GoogleMapsControl extends IControlType {
    tooltip: 'Google Maps';
    icon: 'map';
    command: string;
}

interface GMControl extends IControlType {
    hand: IControlType;
    marker: IControlType;
    polyline: IControlType;
    polygon: IControlType;
    circle: IControlType;
    text: IControlType;
}
```

### Events

#### changeCreateMode.gm

Fired when the map creation mode changes:

```js
editor.events.on('changeCreateMode.gm', (mode) => {
    console.log('Creation mode changed to:', mode);
    // mode can be: 'hand', 'marker', 'polyline', 'polygon', 'circle', 'text'
});

// Trigger mode change
editor.events.fire('changeCreateMode.gm', 'marker');
```
