index.js (4453B)
1 import L from 'leaflet'; 2 import getGoogle from '~/lib/googleMapsApi'; 3 import {Events} from "../common"; 4 5 function getCoverageLayer(options) { 6 return L.tileLayer( 7 'https://maps.googleapis.com/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m8!1e2!2ssvv!4m2!1scb_client!2sapiv3!4m2!1scc!2s*211m3*211e3*212b1*213e2*211m3*211e2*212b1*213e2!3m5!3sUS!12m1!1e40!12m1!1e18!4e0', // eslint-disable-line max-len 8 options 9 ); 10 } 11 12 async function getStreetViewService() { 13 const google = await getGoogle(); 14 return new google.maps.StreetViewService(); 15 } 16 17 async function getPanoramaAtPos(latlng, searchRadiusMeters) { 18 const google = await getGoogle(); 19 const service = await getStreetViewService(); 20 const {data, status} = await new Promise((resolve) => { 21 service.getPanorama({ 22 location: latlng, 23 radius: searchRadiusMeters, 24 preference: google.maps.StreetViewPreference.NEAREST 25 }, (data, status) => resolve({data, status}) 26 ); 27 } 28 ); 29 if (status === google.maps.StreetViewStatus.OK) { 30 return {found: true, data}; 31 } 32 return {found: false}; 33 } 34 35 const Viewer = L.Evented.extend({ 36 initialize: function(google, container) { 37 this.google = google; 38 const panorama = this.panorama = new google.maps.StreetViewPanorama(container, { 39 enableCloseButton: true, 40 imageDateControl: true, 41 motionTracking: false, 42 motionTrackingControl: false, 43 } 44 ); 45 panorama.addListener('position_changed', () => this.onPanoramaPositionChanged()); 46 panorama.addListener('pov_changed', () => this.onPanoramaPovChanged()); 47 panorama.addListener('closeclick', () => this.onCloseClick()); 48 this.invalidateSize = L.Util.throttle(this._invalidateSize, 50, this); 49 this._yawPitchZoomChangeTimer = null; 50 }, 51 52 showPano: function(data) { 53 this.panorama.setPosition(data.location.latLng); 54 this.panorama.setZoom(1); 55 const heading = this.panorama.getPov().heading; 56 this.panorama.setPov({heading, pitch: 0}); 57 }, 58 59 onPanoramaPositionChanged: function() { 60 if (!this._active) { 61 return; 62 } 63 const pos = this.panorama.getPosition(); 64 this.fire(Events.ImageChange, {latlng: L.latLng(pos.lat(), pos.lng())}); 65 }, 66 67 onPanoramaPovChanged: function() { 68 const pov = this.panorama.getPov(); 69 this.fire(Events.BearingChange, {bearing: pov.heading}); 70 if (this._yawPitchZoomChangeTimer !== null) { 71 clearTimeout(this._yawPitchZoomChangeTimer); 72 this._yawPitchZoomChangeTimer = null; 73 } 74 this._yawPitchZoomChangeTimer = setTimeout(() => { 75 this.fire(Events.YawPitchZoomChangeEnd); 76 }, 120); 77 }, 78 79 onCloseClick: function() { 80 this.fire('closeclick'); 81 }, 82 83 activate: function() { 84 this._active = true; 85 this.panorama.setVisible(true); 86 }, 87 88 deactivate: function() { 89 this._active = false; 90 this.panorama.setVisible(false); 91 }, 92 93 getState: function() { 94 const pos = this.panorama.getPosition(); 95 const pov = this.panorama.getPov(); 96 if (pos && pov) { 97 return [ 98 pos.lat().toFixed(6), 99 pos.lng().toFixed(6), 100 (pov.heading || 0).toFixed(1), 101 (pov.pitch || 0).toFixed(1), 102 (pov.zoom || 1).toFixed(1) 103 ]; 104 } 105 return null; 106 }, 107 108 setState: function(state) { 109 const lat = parseFloat(state[0]); 110 const lng = parseFloat(state[1]); 111 const heading = parseFloat(state[2]); 112 const pitch = parseFloat(state[3]); 113 const zoom = parseFloat(state[4]); 114 if (!isNaN(lat) && !isNaN(lng) && !isNaN(heading) && !isNaN(pitch) && !isNaN(zoom)) { 115 this.panorama.setPosition({lat, lng}); 116 this.panorama.setPov({heading, pitch, zoom}); 117 return true; 118 } 119 return false; 120 }, 121 122 _invalidateSize: function() { 123 this.google.maps.event.trigger(this.panorama, 'resize'); 124 } 125 }); 126 127 async function getViewer(container) { 128 const google = await getGoogle(); 129 return new Viewer(google, container); 130 } 131 132 const googleProvider = {getCoverageLayer, getPanoramaAtPos, getViewer}; 133 export default googleProvider;