-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathleaflet-pegman.min.js
9 lines (9 loc) · 15.8 KB
/
leaflet-pegman.min.js
1
2
3
4
5
6
7
8
9
/**
* leaflet-pegman
*
* @author Raruto
* @license GPL-3.0+
* @link https://github.com/Raruto/leaflet-pegman
* @desc Leaflet plugin that allows an easy integration with the Google StreetView Service API
*/
L.Control.Pegman=L.Control.extend({includes:L.Evented?L.Evented.prototype:L.Mixin.Events,options:{position:"bottomright",theme:"leaflet-pegman-v3-default",debug:!1,apiKey:"",libraries:"",mutant:{attribution:'Map data: © <a href="https://www.google.com/intl/en/help/terms_maps.html">Google</a>',pane:"overlayPane",type:null},pano:{enableCloseButton:!0,fullscreenControl:!1,imageDateControl:!0},marker:{draggable:!0,icon:L.icon({className:"pegman-marker",iconSize:[52,52],iconAnchor:[24,33],iconUrl:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAFElEQVR4XgXAAQ0AAABAMP1L30IDCPwC/o5WcS4AAAAASUVORK5CYII="})}},__interactURL:"https://unpkg.com/interactjs@1.2.9/dist/interact.min.js",__gmapsURL:"https://maps.googleapis.com/maps/api/js?v=3",__mutantURL:"https://unpkg.com/leaflet.gridlayer.googlemutant@0.10.0/Leaflet.GoogleMutant.js",initialize:function(options){void 0!==options.logging&&(options.debug=options.logging),L.Util.setOptions(this,options),this._mousePos={direction:{},old:{}},this._pegmanMarkerCoords=null,this._streetViewCoords=null,this._streetViewLayerEnabled=!1,this._dropzoneMapOpts={accept:".draggable",overlap:.75,ondropactivate:L.bind(this.onDropZoneActivated,this),ondragenter:L.bind(this.onDropZoneDragEntered,this),ondragleave:L.bind(this.onDropZoneDragLeaved,this),ondrop:L.bind(this.onDropZoneDropped,this),ondropdeactivate:L.bind(this.onDropZoneDeactivated,this)},this._draggableMarkerOpts={inertia:!1,onmove:L.bind(this.onDraggableMove,this),onend:L.bind(this.onDraggableEnd,this)},this._lazyLoaderAdded=!1},onAdd:function(map){return this._map=map,this._container=L.DomUtil.create("div","leaflet-pegman pegman-control leaflet-bar"),this._pegman=L.DomUtil.create("div","pegman draggable drag-drop",this._container),this._pegmanButton=L.DomUtil.create("div","pegman-button",this._container),this._pegmanMarker=L.marker([0,0],this.options.marker),this._panoDiv=this.options.panoDiv?document.querySelector(this.options.panoDiv):L.DomUtil.create("div","",this._map._container),L.DomUtil.addClass(this._panoDiv,"pano-canvas"),L.DomUtil.addClass(this._map._container,this.options.theme),L.DomEvent.disableClickPropagation(this._panoDiv),L.DomEvent.on(this._container,"click mousedown dblclick",this._disableClickPropagation,this),this._container.addEventListener("touchstart",this._loadScripts.bind(this,!L.Browser.touch),{once:!0}),this._container.addEventListener("mousedown",this._loadScripts.bind(this,!0),{once:!0}),this._container.addEventListener("mouseover",this._loadScripts.bind(this,!1),{once:!0}),this._loadInteractHandlers(),this._loadGoogleHandlers(),L.DomEvent.on(document,"mousemove",this.mouseMoveTracking,this),L.DomEvent.on(document,"keyup",this.keyUpTracking,this),this._pegmanMarker.on("dragend",this.onPegmanMarkerDragged,this),this._map.on("click",this.onMapClick,this),this._map.on("layeradd",this.onMapLayerAdd,this),this._container},onRemove:function(map){interact(this._pegman).unset(),interact(this._map._container).unset(),interact(this._container).unset(),this._googleStreetViewLayer&&this._googleStreetViewLayer.remove(),this._pegmanMarker&&this._pegmanMarker.remove(),L.DomUtil.remove(this._panoDiv),L.DomEvent.off(document,"mousemove",this.mouseMoveTracking,this),L.DomEvent.off(document,"keyup",this.keyUpTracking,this),map.off("mousemove",this._setMouseCursor,this)},_log:function(args){this.options.debug&&console.log(args)},_addClasses:function(el,classNames){for(var s in classNames=classNames.split(" "))L.DomUtil.addClass(el,classNames[s])},_removeClasses:function(el,classNames){for(var s in classNames=classNames.split(" "))L.DomUtil.removeClass(el,classNames[s])},_removeAttributes:function(el,attrNames){for(var a in attrNames)el.removeAttribute(attrNames[a])},_insertAfter:function(targetNode,newNode){targetNode.parentNode.insertBefore(newNode,targetNode.nextSibling)},_translateElement:function(el,dx,dy){!1===dx&&!1===dy&&this._removeAttributes(this._pegman,["style","data-x","data-y"]);var x=(parseFloat(el.getAttribute("data-x"))||0)+dx,y=(parseFloat(el.getAttribute("data-y"))||0)+dy;el.style.webkitTransform=el.style.transform="translate("+x+"px, "+y+"px)",el.setAttribute("data-x",x),el.setAttribute("data-y",y)},_updateClasses:function(action){switch(action){case"pegman-dragging":this._removeClasses(this._pegman,"dropped"),this._addClasses(this._container,"dragging");break;case"pegman-dragged":this._removeClasses(this._pegman,"can-drop dragged left right active dropped"),this._removeAttributes(this._pegman,["style","data-x","data-y"]);break;case"dropzone-actived":this._addClasses(this._map._container,"drop-active");break;case"dropzone-drag-entered":this._addClasses(this._pegman,"active can-drop"),this._addClasses(this._map._container,"drop-target");break;case"dropzone-drag-leaved":this._removeClasses(this._map._container,"drop-target"),this._removeClasses(this._pegman,"can-drop");break;case"dropzone-drop":this._removeClasses(this._container,"dragging"),this._removeClasses(this._pegman,"active left right"),this._addClasses(this._pegman,"dropped"),this._removeClasses(this._pegman,"can-drop dragged left right active dropped");break;case"dropzone-deactivated":this._removeClasses(this._pegman,"active left right"),this._removeClasses(this._map._container,"drop-active drop-target");break;case"mousemove-top":this._addClasses(this._pegman,"top"),this._removeClasses(this._pegman,"bottom right left");break;case"mousemove-bottom":this._addClasses(this._pegman,"bottom"),this._removeClasses(this._pegman,"top right left");break;case"mousemove-left":this._addClasses(this._pegman,"left"),this._removeClasses(this._pegman,"right top bottom");break;case"mousemove-right":this._addClasses(this._pegman,"right"),this._removeClasses(this._pegman,"left top bottom");break;case"pegman-added":this._addClasses(this._container,"active");break;case"pegman-removed":this._removeClasses(this._container,"active");break;case"streetview-shown":this._addClasses(this._container,"streetview-layer-active");break;case"streetview-hidden":this._removeClasses(this._container,"streetview-layer-active");break;default:throw"Unhandled event:"+action}this.fire("svpc_"+action)},onDraggableMove:function(e){this.mouseMoveTracking(e),this.pegmanRemove(),this._updateClasses("pegman-dragging"),this._translateElement(this._pegman,e.dx,e.dy)},onDraggableEnd:function(e){this._pegmanMarkerCoords=this._map.mouseEventToLatLng(e),this.pegmanAdd(),this.findStreetViewData(this._pegmanMarkerCoords.lat,this._pegmanMarkerCoords.lng),this._updateClasses("pegman-dragged")},onDropZoneActivated:function(e){this._updateClasses("dropzone-actived")},onDropZoneDragEntered:function(e){this.showStreetViewLayer(),this._updateClasses("dropzone-drag-entered")},onDropZoneDragLeaved:function(e){this._updateClasses("dropzone-drag-leaved")},onDropZoneDropped:function(e){this._updateClasses("dropzone-drop"),this._translateElement(this._pegman,!1,!1)},onDropZoneDeactivated:function(e){this._updateClasses("dropzone-deactivated")},onPegmanMarkerDragged:function(e){this._pegmanMarkerCoords=this._pegmanMarker.getLatLng(),this.findStreetViewData(this._pegmanMarkerCoords.lat,this._pegmanMarkerCoords.lng)},onMapClick:function(e){this._streetViewLayerEnabled&&this.findStreetViewData(e.latlng.lat,e.latlng.lng)},onMapLayerAdd:function(e){this._googleStreetViewLayer&&this._googleStreetViewLayer.bringToFront()},onStreetViewPanoramaClose:function(){this.clear()},onPanoramaPositionChanged:function(){var pos=this._panorama.getPosition();pos=L.latLng(pos.lat(),pos.lng()),this._map&&!this._map.getBounds().pad(-.05).contains(pos)&&this._map.panTo(pos),this._pegmanMarker.setLatLng(pos)},onPanoramaPovChanged:function(){var pov=this._panorama.getPov();this._pegmanMarker.getElement().style.backgroundPosition="0 "+-Math.abs(Math.round(pov.heading/22.5)%16*Math.round(835/16))+"px"},clear:function(){this.pegmanRemove(),this.hideStreetViewLayer(),this.closeStreetViewPanorama()},toggleStreetViewLayer:function(e){this._streetViewLayerEnabled?this.clear():this.showStreetViewLayer(),this._log("streetview-layer-toggled")},pegmanAdd:function(){this._pegmanMarker.addTo(this._map),this._pegmanMarker.setLatLng(this._pegmanMarkerCoords),this.findStreetViewData(this._pegmanMarkerCoords.lat,this._pegmanMarkerCoords.lng),this._updateClasses("pegman-added")},pegmanRemove:function(){this._pegmanMarker.removeFrom(this._map),this._updateClasses("pegman-removed")},closeStreetViewPanorama:function(){this._panoDiv.style.display="none"},openStreetViewPanorama:function(){this._panoDiv.style.display="block"},hideStreetViewLayer:function(){this._googleStreetViewLayer&&(this._googleStreetViewLayer.removeFrom(this._map),this._streetViewLayerEnabled=!1,this._updateClasses("streetview-hidden"))},showStreetViewLayer:function(){this._googleStreetViewLayer&&(this._googleStreetViewLayer.addTo(this._map),this._streetViewLayerEnabled=!0,this._updateClasses("streetview-shown"))},findStreetViewData:function(lat,lng){if("undefined"==typeof google)return this._loadScripts(!0),this.once("svpc_streetview-shown",L.bind(this.findStreetViewData,this,lat,lng));if(!this._pegmanMarker._map&&this._map)return this._pegmanMarkerCoords=L.latLng(lat,lng),this.pegmanAdd();this._streetViewCoords=new google.maps.LatLng(lat,lng);var zoom=this._map.getZoom(),searchRadius=100;searchRadius=zoom<6?5e3:zoom<10?500:zoom<15?250:zoom>=17?50:100,this._streetViewService.getPanoramaByLocation(this._streetViewCoords,searchRadius,L.bind(this.processStreetViewServiceData,this))},processStreetViewServiceData:function(data,status){status==google.maps.StreetViewStatus.OK?(this.openStreetViewPanorama(),this._panorama.setPano(data.location.pano),this._panorama.setPov({heading:google.maps.geometry.spherical.computeHeading(data.location.latLng,this._streetViewCoords),pitch:0,zoom:0}),this._panorama.setVisible(!0)):console.warn("Street View data not found for this location.")},mouseMoveTracking:function(e){var mousePos=this._mousePos;e.pageY<mousePos.old.y?(mousePos.direction.y="top",this._updateClasses("mousemove-top")):e.pageY>mousePos.old.y&&(mousePos.direction.y="bottom",this._updateClasses("mousemove-bottom")),e.pageX<mousePos.old.x?(mousePos.direction.x="left",this._updateClasses("mousemove-left")):e.pageX>mousePos.old.x&&(mousePos.direction.x="right",this._updateClasses("mousemove-right")),mousePos.old.x=e.pageX,mousePos.old.y=e.pageY},keyUpTracking:function(e){27==e.keyCode&&(this._log("escape pressed"),this.clear())},_disableClickPropagation:function(e){L.DomEvent.stopPropagation(e),L.DomEvent.preventDefault(e)},_loadGoogleHandlers:function(toggleStreetView){"object"==typeof google&&"object"==typeof google.maps&&"function"==typeof L.GridLayer.GoogleMutant&&(this._initGoogleMaps(toggleStreetView),this._initMouseTracker())},_initGoogleMaps:function(toggleStreetView){this._googleStreetViewLayer=L.gridLayer.googleMutant(this.options.mutant),this._googleStreetViewLayer.addGoogleLayer("StreetViewCoverageLayer"),this._panorama=new google.maps.StreetViewPanorama(this._panoDiv,this.options.pano),this._streetViewService=new google.maps.StreetViewService,this._panorama.addListener("closeclick",L.bind(this.onStreetViewPanoramaClose,this)),this._panorama.addListener("position_changed",L.bind(this.onPanoramaPositionChanged,this)),this._panorama.addListener("pov_changed",L.bind(this.onPanoramaPovChanged,this)),toggleStreetView&&this.showStreetViewLayer()},_initMouseTracker:function(){if(this._googleStreetViewLayer){var tileSize=this._googleStreetViewLayer.getTileSize();this.tileWidth=tileSize.x,this.tileHeight=tileSize.y,this.defaultDraggableCursor=this._map._container.style.cursor,this._map.on("mousemove",this._setMouseCursor,this)}},_setMouseCursor:function(e){var coords=this._getTileCoords(e.latlng.lat,e.latlng.lng,this._map.getZoom()),img=this._getTileImage(coords),pixel=this._getTilePixelPoint(img,e.originalEvent),hasTileData=this._hasTileData(img,pixel);this._map._container.style.cursor=hasTileData?"pointer":this.defaultDraggableCursor},_getTileCoords:function(lat,lon,zoom){var xtile,ytile;return{x:parseInt(Math.floor((lon+180)/360*(1<<zoom))),y:parseInt(Math.floor((1-Math.log(Math.tan(this._toRad(lat))+1/Math.cos(this._toRad(lat)))/Math.PI)/2*(1<<zoom))),z:zoom}},_getTileImage:function(coords){if(this._googleStreetViewLayer&&this._googleStreetViewLayer._tiles){var key=this._googleStreetViewLayer._tileCoordsToKey(coords),tile=this._googleStreetViewLayer._tiles[key];if(tile){var img=tile.el.querySelector("img");if(img)return this._downloadTile(img.src,this._tileLoaded),img}}},_getTilePixelPoint:function(img,e){if(img){var imgRect=img.getBoundingClientRect(),imgPos_pageY=(imgRect.top+window.scrollY).toFixed(0),imgPos_pageX=(imgRect.left+window.scrollX).toFixed(0),mousePos;return{x:e.pageX-imgPos_pageX,y:e.pageY-imgPos_pageY}}},_hasTileData:function(img,pixelPoint){var pixelData,alpha,hasTileData;if(this.tileContext&&pixelPoint)return 0!=this.tileContext.getImageData(pixelPoint.x,pixelPoint.y,1,1).data[3]},_toRad:function(number){return number*Math.PI/180},_downloadTile:function(imageSrc,callback){if(imageSrc){var img=new Image;img.crossOrigin="Anonymous",img.addEventListener("load",callback.bind(this,img),!1),img.src=imageSrc}},_tileLoaded:function(img){this.tileCanvas=document.createElement("canvas"),this.tileContext=this.tileCanvas.getContext("2d"),this.tileCanvas.width=this.tileWidth,this.tileCanvas.height=this.tileHeight,this.tileContext.drawImage(img,0,0)},_loadInteractHandlers:function(){"function"==typeof interact&&(this._draggable=interact(this._pegman).draggable(this._draggableMarkerOpts),this._dropzone=interact(this._map._container).dropzone(this._dropzoneMapOpts),this._draggable.styleCursor(!1),interact(this._container).on("tap",L.bind(this.toggleStreetViewLayer,this)),L.DomEvent.on(this._container,"touchstart",(function(e){this._map.dragging.disable()}),this),L.DomEvent.on(this._container,"touchend",(function(e){this._map.dragging.enable()}),this))},_loadScripts:function(toggleStreetView){this._lazyLoaderAdded||(this._lazyLoaderAdded=!0,this._loadJS(this.__interactURL,this._loadInteractHandlers.bind(this),"function"!=typeof interact),this._loadJS(this.__gmapsURL+"&key="+this.options.apiKey+"&libraries="+this.options.libraries+"&callback=?",this._loadGoogleHandlers.bind(this,toggleStreetView),"object"!=typeof google||"object"!=typeof google.maps),this._loadJS(this.__mutantURL,this._loadGoogleHandlers.bind(this,toggleStreetView),"function"!=typeof L.GridLayer.GoogleMutant))},_loadJS:function(url,callback,condition){if(condition)if(-1!==url.indexOf("callback=?"))this._jsonp(url,callback);else{var script=document.createElement("script");script.src=url;var loaded=function(){script.onload=script.onreadystatechange=null,this._log(url+" loaded"),callback()}.bind(this);script.onload=script.onreadystatechange=loaded;var head=document.head||document.getElementsByTagName("head")[0]||document.documentElement;head.insertBefore(script,head.firstChild)}else callback()},_jsonp:function(url,callback,params){var query=-1===url.indexOf("?")?"?":"&";for(var key in params=params||{})params.hasOwnProperty(key)&&(query+=encodeURIComponent(key)+"="+encodeURIComponent(params[key])+"&");var timestamp,jsonp="json_call_"+(new Date).getUTCMilliseconds();window[jsonp]=function(data){callback(data),window[jsonp]=void 0};var script=document.createElement("script");-1!==url.indexOf("callback=?")?script.src=url.replace("callback=?","callback="+jsonp)+query.slice(0,-1):script.src=url+query+"callback="+jsonp;var loaded=function(){this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState||(script.onload=script.onreadystatechange=null,script&&script.parentNode&&script.parentNode.removeChild(script))};script.async=!0,script.onload=script.onreadystatechange=loaded;var head=document.head||document.getElementsByTagName("head")[0]||document.documentElement;head.insertBefore(script,head.firstChild)}}),L.control.pegman=function(options){return new L.Control.Pegman(options)};