Solar Terminator with layers clipping.
Path generated by Leaflet.Terminator
plugin used for clipping layers, night effect on tiles created with help of SVG filter. Your location marked with red star. All works great on firefox.
Leaflet + Leaflet.Terminator.
Last active
August 29, 2015 14:05
-
-
Save KoGor/ce6ae9160977b59633a2 to your computer and use it in GitHub Desktop.
Solar Terminator with layers clipping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset=UTF-8 /> | |
<title>Solar Terminator with layers clipping</title> | |
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="L.Terminator.js"></script> | |
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" /> | |
<style> | |
body { margin:0; padding:0; } | |
#map { position:absolute; top:0; bottom:0; width: 960px; height: 500px; } | |
</style> | |
</head> | |
<body> | |
<div id='map'></div> | |
<script> | |
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', | |
stamenUrl = 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png', | |
attrib = '© Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> | <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors', | |
main = L.tileLayer(osmUrl, {maxZoom: 18, attribution: attrib}), | |
map = new L.Map('map', { | |
layers: [main], | |
center: new L.LatLng(0, 0), | |
zoom: 1, | |
minZoom: 1 | |
}), | |
terminator = L.terminator({ | |
color: '#666666', | |
resolution: 5 | |
}), | |
overlay = L.tileLayer(stamenUrl).addTo(map); | |
overlay.getContainer().style.filter = "url(#luminance_mask)"; | |
overlay.getContainer().style.WebkitFilter = "url(#luminance_mask)"; | |
terminator.addTo(map); | |
var myIcon = L.icon({ | |
iconUrl: 'star.svg', | |
iconSize: [20, 20], | |
iconAnchor: [10, 10], | |
popupAnchor: [-3, -76] | |
}); | |
map.locate(); | |
map.on("locationfound", function(e) { | |
L.marker(e.latlng, {icon: myIcon}).addTo(map); | |
}); | |
setInterval(function() {updateTerminator(terminator)}, 500); | |
function updateTerminator(t) { | |
var t2 = L.terminator({resolution: 5}); | |
t.setLatLngs(t2.getLatLngs()); | |
t.redraw(); | |
clip(); | |
}; | |
var svg = d3.select(".leaflet-overlay-pane").select("svg"), | |
defs = svg.append("defs"), | |
clipMask = defs.append("clipPath").attr("id", "clipMask"); | |
clipPath = clipMask.append("path") | |
.attr("id", "clipPath") | |
.attr("d", d3.select(terminator._path).attr("d")) | |
.attr('fill', 'white') | |
.attr('opacity', 1); | |
function clip() { | |
setTimeout(function() { | |
//Get path from Solar terminator plugin | |
var pathData = d3.select(terminator._path).attr("d"); | |
clipPath.attr("d", pathData); | |
overlay.getContainer().style.clipPath = 'url(#clipMask)'; | |
overlay.getContainer().style['-webkit-clip-path'] = 'url(#clipMask)'; | |
}, 100); | |
}; | |
clip(); | |
map.on('moveend', clip); | |
map.on('zoomend', clip); | |
</script> | |
<svg> | |
<defs> | |
<filter id="grayscale"> | |
<feColorMatrix type="saturate" values="0"/> | |
</filter> | |
<filter id="luminance_mask"> | |
<feColorMatrix type="luminanceToAlpha"/> | |
</filter> | |
</defs> | |
</svg> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Terminator.js -- Overlay day/night region on a Leaflet map */ | |
Date.prototype.getJulian = function() { | |
/* Calculate the present UTC Julian Date. Function is valid after | |
* the beginning of the UNIX epoch 1970-01-01 and ignores leap | |
* seconds. */ | |
return (this / 86400000) + 2440587.5; | |
} | |
Date.prototype.getGMST = function() { | |
/* Calculate Greenwich Mean Sidereal Time according to | |
http://aa.usno.navy.mil/faq/docs/GAST.php */ | |
var julianDay = this.getJulian(); | |
var d = julianDay - 2451545.0; | |
// Low precision equation is good enough for our purposes. | |
return (18.697374558 + 24.06570982441908 * d) % 24; | |
} | |
L.Terminator = L.Polygon.extend({ | |
options: { | |
color: '#00', | |
opacity: 0.5, | |
fillColor: '#00', | |
fillOpacity: 0.5, | |
resolution: 2 | |
}, | |
initialize: function(options) { | |
this.version = '0.1.0'; | |
this._R2D = 180 / Math.PI; | |
this._D2R = Math.PI / 180; | |
L.Util.setOptions(this, options); | |
var latLng = this._compute(this.options.time || null) | |
this.setLatLngs(latLng); | |
}, | |
_sunEclipticPosition: function(julianDay) { | |
/* Compute the position of the Sun in ecliptic coordinates at | |
julianDay. Following | |
http://en.wikipedia.org/wiki/Position_of_the_Sun */ | |
// Days since start of J2000.0 | |
var n = julianDay - 2451545.0; | |
// mean longitude of the Sun | |
var L = 280.460 + 0.9856474 * n; | |
L %= 360; | |
// mean anomaly of the Sun | |
var g = 357.528 + 0.9856003 * n; | |
g %= 360; | |
// ecliptic longitude of Sun | |
var lambda = L + 1.915 * Math.sin(g * this._D2R) + | |
0.02 * Math.sin(2 * g * this._D2R); | |
// distance from Sun in AU | |
var R = 1.00014 - 0.01671 * Math.cos(g * this._D2R) - | |
0.0014 * Math.cos(2 * g * this._D2R); | |
return {"lambda": lambda, "R": R}; | |
}, | |
_eclipticObliquity: function(julianDay) { | |
// Following the short term expression in | |
// http://en.wikipedia.org/wiki/Axial_tilt#Obliquity_of_the_ecliptic_.28Earth.27s_axial_tilt.29 | |
var n = julianDay - 2451545.0; | |
// Julian centuries since J2000.0 | |
var T = n / 36525; | |
var epsilon = 23.43929111 - | |
T * (46.836769 / 3600 | |
- T * (0.0001831 / 3600 | |
+ T * (0.00200340 / 3600 | |
- T * (0.576e-6 / 3600 | |
- T * 4.34e-8 / 3600)))); | |
return epsilon; | |
}, | |
_sunEquatorialPosition: function(sunEclLng, eclObliq) { | |
/* Compute the Sun's equatorial position from its ecliptic | |
* position. Inputs are expected in degrees. Outputs are in | |
* degrees as well. */ | |
var alpha = Math.atan(Math.cos(eclObliq * this._D2R) | |
* Math.tan(sunEclLng * this._D2R)) * this._R2D; | |
var delta = Math.asin(Math.sin(eclObliq * this._D2R) | |
* Math.sin(sunEclLng * this._D2R)) * this._R2D; | |
var lQuadrant = Math.floor(sunEclLng / 90) * 90; | |
var raQuadrant = Math.floor(alpha / 90) * 90; | |
alpha = alpha + (lQuadrant - raQuadrant); | |
return {"alpha": alpha, "delta": delta}; | |
}, | |
_hourAngle: function(lng, sunPos, gst) { | |
/* Compute the hour angle of the sun for a longitude on | |
* Earth. Return the hour angle in degrees. */ | |
var lst = gst + lng / 15; | |
return lst * 15 - sunPos.alpha; | |
}, | |
_latitude: function(ha, sunPos) { | |
/* For a given hour angle and sun position, compute the | |
* latitude of the terminator in degrees. */ | |
var lat = Math.atan(-Math.cos(ha * this._D2R) / | |
Math.tan(sunPos.delta * this._D2R)) * this._R2D; | |
return lat; | |
}, | |
_compute: function(time) { | |
if (time == null) | |
var today = new Date(); | |
else | |
var today = new Date(time); | |
var julianDay = today.getJulian(); | |
var gst = today.getGMST(); | |
var latLng = []; | |
var ha, lat; | |
var sunEclPos = this._sunEclipticPosition(julianDay); | |
var eclObliq = this._eclipticObliquity(julianDay); | |
var sunEqPos = this._sunEquatorialPosition(sunEclPos.lambda, eclObliq); | |
for (var i = 0; i <= 720 * this.options.resolution; i++) { | |
lng = -360 + i / this.options.resolution; | |
ha = this._hourAngle(lng, sunEqPos, gst); | |
lat = this._latitude(ha, sunEqPos); | |
latLng[i+1] = [lat, lng]; | |
} | |
if (sunEqPos.delta < 0) { | |
latLng[0] = [90, -360]; | |
latLng[latLng.length] = [90, 360]; | |
} else { | |
latLng[0] = [-90, -360]; | |
latLng[latLng.length] = [-90, 360]; | |
} | |
return latLng; | |
} | |
}); | |
L.terminator = function(options) { | |
return new L.Terminator(options); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The MIT License (MIT) | |
Copyright (c) 2014 [KoGor](https://github.com/KoGor) | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
SOFTWARE. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment