Skip to content

Instantly share code, notes, and snippets.

@fqborges
Created January 9, 2018 18:21
Show Gist options
  • Select an option

  • Save fqborges/92077c4dbde7b646447990a524f3c41a to your computer and use it in GitHub Desktop.

Select an option

Save fqborges/92077c4dbde7b646447990a524f3c41a to your computer and use it in GitHub Desktop.
make openlayers work with google maps
import ol from 'openlayers';
// View used to sync google maps with ol map
class GmapSyncView extends ol.View {
constructor(gmap, options) {
super(options);
this._gmap = gmap;
this._gmapInit();
const throttledChangeCenter = _.throttle(function () {
gmap.panTo(this.getLatLngCenter());
}, 32, { leading: false });
this.on('change:center', throttledChangeCenter);
this.on('change:resolution', function () {
if (!this.getAnimating()) {
gmap.setZoom(this.getZoom());
}
});
}
getLatLngCenter(coords) {
const input = coords || this.getCenter();
var center = ol.proj.transform(input, 'EPSG:3857', 'EPSG:4326');
return new google.maps.LatLng(center[1], center[0]);
}
_gmapInit() {
this._gmap.setCenter(this.getLatLngCenter());
this._gmap.setZoom(this.getZoom());
}
_gmapSync() {
this._gmap.panTo(this.getLatLngCenter());
this._gmap.setZoom(this.getZoom());
}
animate(...args) {
const animation = args[0];
if (animation.zoom) {
this._gmap.setZoom(animation.zoom);
} else if (animation.resolution) {
const zoom = this.getZoomForResolution(animation.resolution);
this._gmap.setZoom(zoom);
}
super.animate(...args);
}
}
// wherever you initialize your ol map
// in my case, I handle having google maps available or not
const init = function () {
let gmap;
let olMapDiv;
if (window.google) {
const rootDiv = document.getElementById('map');
const gmapDiv = document.createElement('div');
gmapDiv.style.height = '100%';
gmapDiv.style.width = '100%';
gmapDiv.style.position = 'absolute';
gmapDiv.style.top = 0;
gmapDiv.style.left = 0;
rootDiv.appendChild(gmapDiv);
gmap = new google.maps.Map(gmapDiv, {
disableDefaultUI: true,
disableDoubleClickZoom: true,
draggable: false,
fullscreenControl: false,
gestureHandling: 'none',
mapTypeControl: false,
panControl: false,
rotateControl: false,
scaleControl: false,
scrollwheel: false,
streetViewControl: false,
zoomControl: false,
});
olMapDiv = document.createElement('div');
olMapDiv.style.height = '100%';
olMapDiv.style.width = '100%';
olMapDiv.style.position = 'absolute';
olMapDiv.style.top = 0;
olMapDiv.style.left = 0;
rootDiv.appendChild(olMapDiv);
} else {
olMapDiv = document.getElementById('map');
}
const osmLayer = gmap ? null : new ol.layer.Tile({
source: new ol.source.OSM(),
});
// your other layers
const layers = [
// ...
]
const viewOptions = {
center: DEFAULT_POINT,
zoom: DEFAULT_ZOOM,
};
const view = gmap ? new GmapSyncView(gmap, viewOptions) : new ol.View(viewOptions);
var map = new ol.Map({
target: olMapDiv,
controls: ol.control.defaults({ attribution: false }).extend([attribution]),
layers: osmLayer ? [osmLayer, ...layers] : layers,
view: view,
logo: false
});
};
@darkyelox
Copy link

Hey i have two questions about this code: ¿can you do the same without the use of underscore throttle?, my project is quite huge and dont want to depend on this library for only use that function; and ¿which version of openlayers are you using? i have the latest one and the method getZoomForResolution is not part of the code in @types/openlayers v4 but for @types/openlayers/v2 is present, i'm using TypeScript in my project, but when i go to documentation i see the method is present in the ol.View class, so is safe to use (this as any).getZoomForResolution(...)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment