Created
January 9, 2018 18:21
-
-
Save fqborges/92077c4dbde7b646447990a524f3c41a to your computer and use it in GitHub Desktop.
make openlayers work with google maps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| }); | |
| }; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 methodgetZoomForResolutionis not part of the code in@types/openlayersv4 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 theol.Viewclass, so is safe to use(this as any).getZoomForResolution(...)?