(function () { 'use strict'; var successCallBackFunction, errorCallBackFunction; /** * Callback func at successful getting position */ successCallBackFunction = function (position) { var lng = position.coords.longitude; var lat = position.coords.latitude; // revert button element document.getElementById('input').innerHTML = ""; // remove dummy img var imgTag = document.getElementById('dummy'); if(imgTag != null){ imgTag.parentNode.removeChild(imgTag); } latlng2domePolygon(lng, lat); }; /** * Callback func at faild getting position */ errorCallBackFunction = function (positionError) { alert(positionError.code + ': ' + positionError.message); }; var option = { enableHighAccuracy: true, // Whether to use GPS to improve accuracy maximumAge: 0, // to hold cache ms timeout: 30000 // Timeout ms }; /** * Processing at the end of HTML loading */ window.addEventListener('load', function () { // Check whether Geolocation API is enabled/disabled if (!navigator.geolocation) { alert('Geolocation API is disabled'); return; } document.getElementById('button').addEventListener('click', function () { document.getElementById('input').innerHTML = ""; navigator.geolocation.getCurrentPosition(successCallBackFunction, errorCallBackFunction, option); }, false); }, false); // Generate domed polygons from [lng lat] function latlng2domePolygon(lng, lat) { mapboxgl.accessToken = 'pk.eyJ1IjoiaGlyb3NhamkiLCJhIjoiY2szOWljb210MDJxcjNjcXRwZGF6bmJnMiJ9.gin_FUY4wc61PoNKnUWL5Q'; var center = [lng, lat]; var radius = 0.122; var precision = 0.001525; var epsilon = 0.0001; var satelliteStyle = { "version": 8, "sources": { "satellite": { "type": "raster", "url": "mapbox://mapbox.satellite", "tileSize": 256 } }, "layers": [{ "id": "background", "type": "background", "paint": { "background-color": "rgb(4,7,14)" } }, { "id": "satellite", "type": "raster", "source": "satellite" }] }; var map = new mapboxgl.Map({ container: 'map', style: satelliteStyle, center: center, zoom: 16, pitch: 60 }); var grid = turf.hexGrid(turf.bbox(turf.circle(center, radius)), precision); var dome = turf.featureCollection(grid.features.map(function (feature) { var point = turf.centroid(feature); var distance = turf.distance(center, point); if (distance > radius) { return; } // sphere r^2 = x^2 + y^2 + z^2 // therefore z = Math.sqrt(r^2 - x^2 - y^2) // = Math.sqrt(r^2 - (x^2 + y^2)) // but distance^2 = x^2 + y^2 // so z = Math.sqrt(r^2 - distance^2) var z = Math.sqrt(Math.pow(radius, 2) - Math.pow(distance, 2)); var normHeight = 56.190 / 122; // to normalize height z = isNaN(z) ? 0 : z * normHeight; return turf.feature(feature.geometry, { base_height: z * 1000, // adopt z / m from z / km height: (z * 1000) + (distance * 1000 + epsilon) * 0.1, roof_base_height: (z * 1000) + (distance * 950 + epsilon) * 0.1, roof_height: (z * 1000) + (distance * 1000 + epsilon) * 0.1 }); }).filter(function (feature) { return feature; })); map.on('load', function () { map.addSource('dome', { type: 'geojson', data: dome }); map.addLayer({ id: 'dome', type: 'fill-extrusion', source: 'dome', paint: { 'fill-extrusion-color': 'pink', 'fill-extrusion-base': { type: 'identity', property: 'base_height' }, 'fill-extrusion-height': { type: 'identity', property: 'height' }, 'fill-extrusion-opacity': 0.5 } }); map.addSource('dome_roof', { type: 'geojson', data: dome }); map.addLayer({ id: 'dome_roof', type: 'fill-extrusion', source: 'dome_roof', paint: { 'fill-extrusion-color': 'red', 'fill-extrusion-base': { type: 'identity', property: 'roof_base_height' }, 'fill-extrusion-height': { type: 'identity', property: 'roof_height' }, 'fill-extrusion-opacity': 0.5 } }); }); }; }());