nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

index.js (5128B)


      1 import L from 'leaflet';
      2 import {getSMap} from './apiLoader';
      3 import {CloseButtonMixin, DateLabelMixin, Events} from '../common';
      4 
      5 function getCoverageLayer(options) {
      6     return L.tileLayer('https://mapserver.mapy.cz/panorama_hybrid-m/{z}-{x}-{y}', options);
      7 }
      8 
      9 async function getPanoramaAtPos(latlng, searchRadiusMeters) {
     10     const smap = await getSMap();
     11     const request = smap.Pano.getBest(smap.Coords.fromWGS84(latlng.lng, latlng.lat), searchRadiusMeters);
     12     try {
     13         return {
     14             found: true,
     15             data: await request,
     16         };
     17     } catch (e) {
     18         return {found: false};
     19     }
     20 }
     21 
     22 const Viewer = L.Evented.extend({
     23     includes: [CloseButtonMixin, DateLabelMixin],
     24 
     25     initialize: function(smap, container) {
     26         // Disable keyboard events for panorama as they  conflict with other hotkeys.
     27         const orig_windowAddEventListener = window.addEventListener;
     28         window.addEventListener = (function(type, ...args) {
     29             if (!/^key/u.test(type)) {
     30                 orig_windowAddEventListener(type, ...args);
     31             }
     32         });
     33         this.panorama = new smap.Pano.Scene(container);
     34         window.addEventListener = orig_windowAddEventListener;
     35         this.createDateLabel(container);
     36         this.createCloseButton(container);
     37         window.addEventListener('resize', this.resize.bind(this));
     38         this.invalidateSize = L.Util.throttle(this._invalidateSize, 100, this);
     39         this._updateHandler = null;
     40         this._placeId = null;
     41         this._yaw = null;
     42         this._pitch = null;
     43         this._fov = null;
     44         this._yawPitchZoomChangeTimer = null;
     45     },
     46 
     47     showPano: function(place, yaw = null, pitch = 0, fov = 1.256637061) {
     48         if (yaw === null) {
     49             yaw = this.panorama.getCamera().yaw;
     50         }
     51         this.panorama.show(place, {yaw});
     52         this.panorama.setCamera({fov, pitch});
     53         if (!this._updateHandler) {
     54             this._updateHandler = setInterval(this.watchMapyStateChange.bind(this), 50);
     55         }
     56     },
     57 
     58     activate: function() {
     59         this.resize();
     60     },
     61 
     62     deactivate: function() {
     63         this._placeId = null;
     64         this._yaw = null;
     65         this._pitch = null;
     66         this._fov = null;
     67         clearInterval(this._updateHandler);
     68         this._updateHandler = null;
     69     },
     70 
     71     getState: function() {
     72         const camera = this.panorama.getCamera();
     73         const place = this.panorama.getPlace();
     74         if (!place) {
     75             return null;
     76         }
     77         const coords = place.getCoords().toWGS84();
     78         return [
     79             coords[1].toFixed(6),
     80             coords[0].toFixed(6),
     81             camera.yaw.toFixed(4),
     82             camera.pitch.toFixed(4),
     83             camera.fov.toFixed(4),
     84         ];
     85     },
     86 
     87     setState: function(state) {
     88         const lat = parseFloat(state[0]);
     89         const lng = parseFloat(state[1]);
     90         const yaw = parseFloat(state[2]);
     91         const pitch = parseFloat(state[3]);
     92         const fov = parseFloat(state[4]);
     93         if (!isNaN(lat) && !isNaN(lng) && !isNaN(yaw) && !isNaN(pitch) && !isNaN(fov)) {
     94             getPanoramaAtPos({lat, lng}, 0).then(({data: place, found}) => {
     95                 if (found) {
     96                     this.showPano(place, yaw, pitch, fov);
     97                 }
     98             });
     99             return true;
    100         }
    101         return false;
    102     },
    103 
    104     resize: function() {
    105         this.panorama.syncPort();
    106     },
    107 
    108     watchMapyStateChange: function() {
    109         const place = this.panorama.getPlace();
    110         if (!place) {
    111             return;
    112         }
    113         const placeId = place.getId();
    114         if (this._placeId !== placeId) {
    115             this._placeId = placeId;
    116             const coords = place.getCoords().toWGS84();
    117             this.updateDateLabel();
    118             this.fire(Events.ImageChange, {latlng: L.latLng(coords[1], coords[0])});
    119         }
    120         const camera = this.panorama.getCamera();
    121         if (this._yaw !== camera.yaw || this._pitch !== camera.pitch || this._fov !== camera.fov) {
    122             if (this._yaw !== camera.yaw) {
    123                 this.fire(Events.BearingChange, {bearing: (this._yaw * 180) / Math.PI});
    124             }
    125             this._yaw = camera.yaw;
    126             this._pitch = camera.pitch;
    127             this._fov = camera.fov;
    128             if (this._yawPitchZoomChangeTimer !== null) {
    129                 clearTimeout(this._yawPitchZoomChangeTimer);
    130                 this._yawPitchZoomChangeTimer = null;
    131             }
    132             this._yawPitchZoomChangeTimer = setTimeout(() => {
    133                 this.fire(Events.YawPitchZoomChangeEnd);
    134             }, 120);
    135         }
    136     },
    137 
    138     updateDateLabel: function() {
    139         const place = this.panorama.getPlace();
    140         const timestamp = Date.parse(place.getDate());
    141         DateLabelMixin.updateDateLabel.call(this, timestamp);
    142     },
    143 
    144     _invalidateSize: function() {
    145         this.panorama.syncPort();
    146     }
    147 });
    148 
    149 async function getViewer(container) {
    150     const smap = await getSMap();
    151     return new Viewer(smap, container);
    152 }
    153 
    154 const mapyczProvider = {getCoverageLayer, getPanoramaAtPos, getViewer};
    155 export default mapyczProvider;