Skip to content

[Map][Google] Fix InfoWindow compatibility with Circle and Rectangle #2858

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Map/src/Bridge/Google/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# CHANGELOG

## 2.27

- Fix `InfoWindow` compatibility with new `Circle` and `Rectangle` supported elements.

This fix led to a refactoring that can impact the `InfoWindow` position when used with `Polygon` or `Polyline`,
because their shapes are too complex.
Instead, listen to the `ux:map:info-window:before-create` event to set the position manually.
```js
this.element.addEventListener('ux:map:info-window:before-create', (event) => {
const { google, element, definition } = event.detail;

if (element instanceof google.maps.Polygon) {
// Set the position to the center of the polygon
const bounds = new google.maps.LatLngBounds();

element.getPath().forEach((latLng) => bounds.extend(latLng));
definition.infoWindow.rawOptions.position = bounds.getCenter();
}
});
```

## 2.25

- Downgrade PHP requirement from 8.3 to 8.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class extends AbstractMapController<MapOptions, google.maps.Map,
protected doRemoveRectangle(rectangle: google.maps.Rectangle): void;
protected doCreateInfoWindow({ definition, element, }: {
definition: InfoWindowWithoutPositionDefinition<google.maps.InfoWindowOptions>;
element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline;
element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline | google.maps.Circle | google.maps.Rectangle;
}): google.maps.InfoWindow;
protected doFitBoundsToMarkers(): void;
private createTextOrElement;
Expand Down
52 changes: 24 additions & 28 deletions src/Map/src/Bridge/Google/assets/dist/map_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,40 +294,36 @@ class map_controller extends default_1 {
rectangle.setMap(null);
}
doCreateInfoWindow({ definition, element, }) {
const { headerContent, content, extra, rawOptions = {}, ...otherOptions } = definition;
const infoWindow = new _google.maps.InfoWindow({
const { headerContent, content, opened, autoClose, rawOptions = {} } = definition;
let position = null;
if (element instanceof google.maps.Circle) {
position = element.getCenter();
}
else if (element instanceof google.maps.Rectangle) {
position = element.getBounds()?.getCenter() || null;
}
else if (element instanceof google.maps.Polygon || element instanceof google.maps.Polyline) ;
const infoWindowOptions = {
headerContent: this.createTextOrElement(headerContent),
content: this.createTextOrElement(content),
...otherOptions,
position,
...rawOptions,
});
if (element instanceof google.maps.marker.AdvancedMarkerElement) {
element.addListener('click', () => {
if (definition.autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}
infoWindow.open({ map: this.map, anchor: element });
});
if (definition.opened) {
infoWindow.open({ map: this.map, anchor: element });
};
const infoWindow = new _google.maps.InfoWindow(infoWindowOptions);
element.addListener('click', (event) => {
if (autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}
}
else if (element instanceof google.maps.Polygon) {
element.addListener('click', (event) => {
if (definition.autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}
if (infoWindowOptions.position === null) {
infoWindow.setPosition(event.latLng);
infoWindow.open(this.map);
});
if (definition.opened) {
const bounds = new google.maps.LatLngBounds();
element.getPath().forEach((point) => {
bounds.extend(point);
});
infoWindow.setPosition(bounds.getCenter());
infoWindow.open({ map: this.map, anchor: element });
}
infoWindow.open({ map: this.map, anchor: element });
});
if (opened) {
if (autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}
infoWindow.open({ map: this.map, anchor: element });
}
return infoWindow;
}
Expand Down
66 changes: 37 additions & 29 deletions src/Map/src/Bridge/Google/assets/src/map_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,45 +296,53 @@ export default class extends AbstractMapController<
element,
}: {
definition: InfoWindowWithoutPositionDefinition<google.maps.InfoWindowOptions>;
element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline;
element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline | google.maps.Circle | google.maps.Rectangle;
}): google.maps.InfoWindow {
const { headerContent, content, extra, rawOptions = {}, ...otherOptions } = definition;
const { headerContent, content, opened, autoClose, rawOptions = {} } = definition;

let position: google.maps.LatLng | null = null;
if (element instanceof google.maps.Circle) {
position = element.getCenter();
} else if (element instanceof google.maps.Rectangle) {
position = element.getBounds()?.getCenter() || null;
} else if (element instanceof google.maps.Polygon || element instanceof google.maps.Polyline) {
// Note: We do not compute the center of Polygons or Polylines here, since shapes can be complex.
// Instead, listen to the `ux:map:polygon:before-create` or `ux:map:polyline:before-create` events to set the position manually.
// ```js
// const bounds = new google.maps.LatLngBounds();
// element.getPath().forEach((latLng) => bounds.extend(latLng));
// event.definition.infoWindow.rawOptions.position = bounds.getCenter();
// ```
}

const infoWindow = new _google.maps.InfoWindow({
const infoWindowOptions: google.maps.InfoWindowOptions = {
headerContent: this.createTextOrElement(headerContent),
content: this.createTextOrElement(content),
...otherOptions,
position,
...rawOptions,
});
};

if (element instanceof google.maps.marker.AdvancedMarkerElement) {
element.addListener('click', () => {
if (definition.autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}
infoWindow.open({ map: this.map, anchor: element });
});
const infoWindow = new _google.maps.InfoWindow(infoWindowOptions);

if (definition.opened) {
infoWindow.open({ map: this.map, anchor: element });
element.addListener('click', (event: google.maps.MapMouseEvent) => {
if (autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}
} else if (element instanceof google.maps.Polygon) {
element.addListener('click', (event: any) => {
if (definition.autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}

// Don't override the position if it was already set (e.g. through "rawOptions")
if (infoWindowOptions.position === null) {
infoWindow.setPosition(event.latLng);
infoWindow.open(this.map);
});

if (definition.opened) {
const bounds = new google.maps.LatLngBounds();
element.getPath().forEach((point: google.maps.LatLng) => {
bounds.extend(point);
});
infoWindow.setPosition(bounds.getCenter());
infoWindow.open({ map: this.map, anchor: element });
}

infoWindow.open({ map: this.map, anchor: element });
});

if (opened) {
if (autoClose) {
this.closeInfoWindowsExcept(infoWindow);
}

infoWindow.open({ map: this.map, anchor: element });
}

return infoWindow;
Expand Down