Parcourir la source

(WIP) added a map to the panorama view

Nouph il y a 8 ans
Parent
commit
94ed6975d1
1 fichiers modifiés avec 119 ajouts et 0 suppressions
  1. 119 0
      panorama/templates/panorama/view.html

+ 119 - 0
panorama/templates/panorama/view.html

@@ -79,5 +79,124 @@
       <input type="button" id="do-cancel" value="annuler"/>
     </p>
     <p id="res"></p>
+
+    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
+    <div id="mapid" style="height: 1000px; "></div>
+    <style type="text/css">
+      body{overflow : scroll;}
+    </style>
+    <script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
+    <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
+    <script>
+      function toRad(n) {
+        return n * Math.PI / 180;
+      }
+      function toDeg(n) {
+        return n * 180 / Math.PI;
+      }
+      function destVincenty(lat1, lon1, brng, dist) {
+        /* JavaScript function to calculate the destination point given start point
+         * latitude / longitude (numeric degrees), bearing (numeric degrees) and
+         * distance (in m).
+         * Original scripts by Chris Veness
+         * Taken from http://movable-type.co.uk/scripts/latlong-vincenty-direct.html
+         * and optimized / cleaned up by Mathias Bynens <http://mathiasbynens.be/>
+         *
+         * Based on the Vincenty direct formula by T. Vincenty, “Direct and Inverse
+         * Solutions of Geodesics on the Ellipsoid with application of nested
+         * equations”, Survey Review, vol XXII no 176, 1975
+         * <http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf>
+         */
+        var a = 6378137,
+            b = 6356752.3142,
+            f = 1 / 298.257223563, // WGS-84 ellipsiod
+            s = dist,
+            alpha1 = toRad(brng),
+            sinAlpha1 = Math.sin(alpha1),
+            cosAlpha1 = Math.cos(alpha1),
+            tanU1 = (1 - f) * Math.tan(toRad(lat1)),
+            cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1,
+            sigma1 = Math.atan2(tanU1, cosAlpha1),
+            sinAlpha = cosU1 * sinAlpha1,
+            cosSqAlpha = 1 - sinAlpha * sinAlpha,
+            uSq = cosSqAlpha * (a * a - b * b) / (b * b),
+            A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))),
+            B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))),
+            sigma = s / (b * A),
+            sigmaP = 2 * Math.PI;
+        while (Math.abs(sigma - sigmaP) > 1e-12) {
+          var cos2SigmaM = Math.cos(2 * sigma1 + sigma),
+              sinSigma = Math.sin(sigma),
+              cosSigma = Math.cos(sigma),
+              deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
+          sigmaP = sigma;
+          sigma = s / (b * A) + deltaSigma;
+        };
+        var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1,
+            lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1, (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp)),
+            lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1),
+            C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)),
+            Lo = lambda - (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))),
+            revAz = Math.atan2(sinAlpha, -tmp); // final bearing	
+
+        return {lat: toDeg(lat2), lng: lon1 + toDeg(Lo)};
+      };
+
+
+      function getCone(lat, lng, bearing, angle, distance){
+        /* Returns a polygon to be drawn to the map to show the current visual field
+         */
+        var conepoints = [];
+        // by default, points are drawn every 5°, but if the angle to draw is
+        // smaller than 5°, we draw no intermediary points
+        var delta = 5;
+        if (angle < 5){delta=angle};
+
+        conepoints.push ([lat,lng]);
+
+        for (i=0; i<=angle; i+=delta){
+          conepoints.push([destVincenty(lat, lng, bearing-(angle/2.0)+i, distance).lat,
+              destVincenty(lat, lng, bearing-(angle/2.0)+i, distance).lng]);
+        }
+
+        var p = L.polygon(conepoints, {
+            color: 'grey',
+            fillColor: 'grey',
+            fillOpacity: 0.5
+        });
+        return p;
+      };
+
+      var viewField ;
+
+      var map = L.map('mapid').setView([{{ panorama.latitude }}, {{ panorama.longitude }}], 13);
+      // create the tile layer with correct attribution
+      var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
+      var osmAttrib='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
+      var osm = new L.TileLayer(osmUrl, {attribution: osmAttrib});		
+      // start the map in Grenoble
+      map.setView(new L.LatLng(45.1842, 5.7218),13);
+      map.addLayer(osm);
+
+      L.marker([{{ panorama.latitude }}, {{ panorama.longitude }}]).addTo(map);
+      L.circle([{{ panorama.latitude }}, {{ panorama.longitude }}], 200, {
+        color: 'grey',
+        fillColor: 'grey',
+        fillOpacity: 0.5
+      }).addTo(map);
+
+      var bearing = $('#angle_ctrl').val();
+
+      viewField = getCone({{panorama.latitude}},{{panorama.longitude}},bearing,90,5000);
+
+      viewField.addTo(map);
+
+      $('#mon-canvas').on('mouseup', function(e) {
+          bearing = $('#angle_ctrl').val();
+          map.removeLayer(viewField);
+          viewField = getCone({{panorama.latitude}},{{panorama.longitude}},bearing,90,5000);
+          viewField.addTo(map);
+          });
+    </script>
   </body>
 </html>