(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.eyJ1IjoiaGlyb3NhamkiLCJhIjoiY2szOWlqZWNzMDJueTNjcWhyNjhqdXBnOSJ9._6mJT202QqpnMuK-jvMr3g'; var center = [lng, lat]; var radius = 0.122; var precision = 0.001525; var epsilon = 0.0001; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/hirosaji/ck39jbjve00bc1dohszauaski', 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 } }); // Insert the layer beneath any symbol layer var layers = map.getStyle().layers; var labelLayerId; for (var i = 0; i < layers.length; i++) { if (layers[i].type === 'symbol' && layers[i].layout['text-field']) { labelLayerId = layers[i].id; break; } } map.addLayer({ 'id': '3d-buildings', 'source': 'composite', 'source-layer': 'building', 'filter': ['==', 'extrude', 'true'], 'type': 'fill-extrusion', 'minzoom': 15, 'paint': { 'fill-extrusion-color': '#aaa', // add a smooth transition effect to the buildings as the user zooms in 'fill-extrusion-height': [ "interpolate", ["linear"], ["zoom"], 15, 0, 15.05, ["get", "height"] ], 'fill-extrusion-base': [ "interpolate", ["linear"], ["zoom"], 15, 0, 15.05, ["get", "min_height"] ], 'fill-extrusion-opacity': .6 } }, labelLayerId); }); }; }());