|
| 1 | +/* Nite v1.0 |
| 2 | + * A tiny library to create a night overlay over the map |
| 3 | + * Author: Rossen Georgiev @ https://github.com/rossengeorgiev |
| 4 | + * Requires: GMaps API 3 |
| 5 | + */ |
| 6 | + |
| 7 | + |
| 8 | +var nite = { |
| 9 | + map: null, |
| 10 | + marker_sun: null, |
| 11 | + marker_shadow: null, |
| 12 | + marker_shadow_lite: null, |
| 13 | + shadow_radius: parseInt(6371 * Math.PI * 500), |
| 14 | + sun_position: null, |
| 15 | + |
| 16 | + init: function(map) { |
| 17 | + if(typeof google === 'undefined' |
| 18 | + || typeof google.maps === 'undefined') throw "Nite Overlay: no google.maps detected"; |
| 19 | + |
| 20 | + this.map = map; |
| 21 | + this.refreshSunZenith(); |
| 22 | + |
| 23 | + this.marker_shadow = new google.maps.Circle({ |
| 24 | + map: this.map, |
| 25 | + center: this.getShadowPosition(), |
| 26 | + radius: this.shadow_radius, |
| 27 | + fillColor: "#000", |
| 28 | + fillOpacity: 0.1, |
| 29 | + strokeOpacity: 0, |
| 30 | + clickable: false, |
| 31 | + editable: false |
| 32 | + }); |
| 33 | + |
| 34 | + this.marker_shadow_lite = new google.maps.Circle({ |
| 35 | + map: this.map, |
| 36 | + center: this.getShadowPosition(), |
| 37 | + radius: this.shadow_radius * 0.96, |
| 38 | + fillColor: "#000", |
| 39 | + fillOpacity: 0.1, |
| 40 | + strokeOpacity: 0, |
| 41 | + clickable: false, |
| 42 | + editable: false |
| 43 | + }); |
| 44 | + }, |
| 45 | + getShadowPosition: function() { |
| 46 | + return new google.maps.LatLng(-this.sun_position.lat(), -this.sun_position.lng() + 180); |
| 47 | + }, |
| 48 | + refresh: function() { |
| 49 | + this.refreshSunZenith(); |
| 50 | + this.marker_shadow.setCenter(this.getShadowPosition()); |
| 51 | + this.marker_shadow_lite.setCenter(this.getShadowPosition()); |
| 52 | + }, |
| 53 | + refreshSunZenith: function() { |
| 54 | + var rad = 0.017453292519943295; |
| 55 | + |
| 56 | + // based on NOAA solar calculations |
| 57 | + var utc = new Date(); |
| 58 | + utc = new Date(utc.getTime() + utc.getTimezoneOffset() * 60000); |
| 59 | + var mins_past_midnight = (utc.getHours() * 60 + utc.getMinutes()) / 1440; |
| 60 | + var jd = 2415018.5 - ((new Date("01/01/1900 00:00:00 UTC")).getTime() - utc.getTime()) / 1000 / 60 / 60 / 24; |
| 61 | + var jc = (jd - 2451545)/36525; |
| 62 | + var mean_long_sun = (280.46646+jc*(36000.76983+jc*0.0003032)) % 360; |
| 63 | + var mean_anom_sun = 357.52911+jc*(35999.05029-0.0001537*jc); |
| 64 | + var sun_eq = Math.sin(rad*mean_anom_sun)*(1.914602-jc*(0.004817+0.000014*jc))+Math.sin(rad*2*mean_anom_sun)*(0.019993-0.000101*jc)+Math.sin(rad*3*mean_anom_sun)*0.000289; |
| 65 | + var sun_true_long = mean_long_sun + sun_eq; |
| 66 | + var sun_app_long = sun_true_long - 0.00569 - 0.00478*Math.sin(rad*125.04-1934.136*jc); |
| 67 | + var mean_obliq_ecliptic = 23+(26+((21.448-jc*(46.815+jc*(0.00059-jc*0.001813))))/60)/60; |
| 68 | + var obliq_corr = mean_obliq_ecliptic + 0.00256*Math.cos(rad*125.04-1934.136*jc); |
| 69 | + |
| 70 | + var lat = Math.asin(Math.sin(rad*obliq_corr)*Math.sin(rad*sun_app_long)) / rad; |
| 71 | + |
| 72 | + var eccent = 0.016708634-jc*(0.000042037+0.0000001267*jc); |
| 73 | + var y = Math.tan(rad*(obliq_corr/2))*Math.tan(rad*(obliq_corr/2)); |
| 74 | + var rq_of_time = 4*((y*Math.sin(2*rad*mean_long_sun)-2*eccent*Math.sin(rad*mean_anom_sun)+4*eccent*y*Math.sin(rad*mean_anom_sun)*Math.cos(2*rad*mean_long_sun)-0.5*y*y*Math.sin(4*rad*mean_long_sun)-1.25*eccent*eccent*Math.sin(2*rad*mean_anom_sun))/rad); |
| 75 | + var true_solar_time = (mins_past_midnight*1440+rq_of_time) % 1440; |
| 76 | + var lng = (true_solar_time/4 < 0) ? true_solar_time/4 + 180 : true_solar_time/4 - 180; |
| 77 | + |
| 78 | + this.sun_position = new google.maps.LatLng(lat, lng); |
| 79 | + }, |
| 80 | + setMap: function(map) { |
| 81 | + this.map = map; |
| 82 | + }, |
| 83 | + show: function() { |
| 84 | + this.marker_shadow.setVisible(true); |
| 85 | + this.marker_shadow_lite.setVisible(true); |
| 86 | + }, |
| 87 | + hide: function() { |
| 88 | + this.marker_shadow.setVisible(false); |
| 89 | + this.marker_shadow_lite.setVisible(false); |
| 90 | + } |
| 91 | +} |
0 commit comments