使用 MVC 框架将 day/night 叠加层添加到 google 地图

Add day/night overlay to google maps with MVC framework

我正在尝试使用 MVC5 框架将此 github:https://github.com/rossengeorgiev/nite-overlay 中的 day/night 叠加层添加到我的 google 地图视图中。我在 Whosebug 上找到了一些解决方案,但这些解决方案适用于不同的框架并且工作方式完全不同。

所以我的问题是:如何向我的代码添加 day/night 概览? 我的尝试:

    <!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
        html,
        body {
          margin: 0;
          padding: 0;
          width: 100%;
          height: 100%;
        }
        .map {
          width: 100vw;
          height:100vh;
        }
    </style>
</head>
<body>

    <script src="~/Scripts/jquery-3.4.1.min.js"></script>
    <div class="map" id="map"></div>
    <script>
var nite = {
    map: null,
    date: null,
    sun_position: null,
    earth_radius_meters: 6371008,
    marker_twilight_civil: null,
    marker_twilight_nautical: null,
    marker_twilight_astronomical: null,
    marker_night: null,

    init: function(map) {
        if(typeof google === 'undefined'
           || typeof google.maps === 'undefined') throw "Nite Overlay: no google.maps detected";

        this.map = map;
        this.sun_position = this.calculatePositionOfSun();

        this.marker_twilight_civil = new google.maps.Circle({
            map: this.map,
            center: this.getShadowPosition(),
            radius: this.getShadowRadiusFromAngle(0.566666),
            fillColor: "#000",
            fillOpacity: 0.1,
            strokeOpacity: 0,
            clickable: false,
            editable: false
        });
        this.marker_twilight_nautical = new google.maps.Circle({
            map: this.map,
            center: this.getShadowPosition(),
            radius: this.getShadowRadiusFromAngle(6),
            fillColor: "#000",
            fillOpacity: 0.1,
            strokeOpacity: 0,
            clickable: false,
            editable: false
        });
        this.marker_twilight_astronomical = new google.maps.Circle({
            map: this.map,
            center: this.getShadowPosition(),
            radius: this.getShadowRadiusFromAngle(12),
            fillColor: "#000",
            fillOpacity: 0.1,
            strokeOpacity: 0,
            clickable: false,
            editable: false
        });
        this.marker_night = new google.maps.Circle({
            map: this.map,
            center: this.getShadowPosition(),
            radius: this.getShadowRadiusFromAngle(18),
            fillColor: "#000",
            fillOpacity: 0.1,
            strokeOpacity: 0,
            clickable: false,
            editable: false
        });
    },
    getShadowRadiusFromAngle: function(angle) {
        var shadow_radius =  this.earth_radius_meters * Math.PI * 0.5;
        var twilight_dist = ((this.earth_radius_meters * 2 * Math.PI) / 360) * angle;
        return shadow_radius - twilight_dist;
    },
    getSunPosition: function() {
        return this.sun_position;
    },
    getShadowPosition: function() {
        return (this.sun_position) ? new google.maps.LatLng(-this.sun_position.lat(), this.sun_position.lng() + 180) : null;
    },
    refresh: function() {
        if(!this.isVisible()) return;
        this.sun_position = this.calculatePositionOfSun(this.date);
        var shadow_position = this.getShadowPosition();
        this.marker_twilight_civil.setCenter(shadow_position);
        this.marker_twilight_nautical.setCenter(shadow_position);
        this.marker_twilight_astronomical.setCenter(shadow_position);
        this.marker_night.setCenter(shadow_position);
    },
    jday: function(date) {
        return (date.getTime() / 86400000.0) + 2440587.5;
    },
    calculatePositionOfSun: function(date) {
        date = (date instanceof Date) ? date : new Date();

        var rad = 0.017453292519943295;

        // based on NOAA solar calculations
        var ms_past_midnight = ((date.getUTCHours() * 60 + date.getUTCMinutes()) * 60 + date.getUTCSeconds()) * 1000 + date.getUTCMilliseconds();
        var jc = (this.jday(date) - 2451545)/36525;
        var mean_long_sun = (280.46646+jc*(36000.76983+jc*0.0003032)) % 360;
        var mean_anom_sun = 357.52911+jc*(35999.05029-0.0001537*jc);
        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;
        var sun_true_long = mean_long_sun + sun_eq;
        var sun_app_long = sun_true_long - 0.00569 - 0.00478*Math.sin(rad*125.04-1934.136*jc);
        var mean_obliq_ecliptic = 23+(26+((21.448-jc*(46.815+jc*(0.00059-jc*0.001813))))/60)/60;
        var obliq_corr = mean_obliq_ecliptic + 0.00256*Math.cos(rad*125.04-1934.136*jc);

        var lat = Math.asin(Math.sin(rad*obliq_corr)*Math.sin(rad*sun_app_long)) / rad;

        var eccent = 0.016708634-jc*(0.000042037+0.0000001267*jc);
        var y = Math.tan(rad*(obliq_corr/2))*Math.tan(rad*(obliq_corr/2));
        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);
        var true_solar_time_in_deg = ((ms_past_midnight+rq_of_time*60000) % 86400000) / 240000;

        var lng = -((true_solar_time_in_deg < 0) ? true_solar_time_in_deg + 180 : true_solar_time_in_deg - 180);

        return new google.maps.LatLng(lat, lng);
    },
    setDate: function(date) {
        this.date = date;
        this.refresh();
    },
    setMap: function(map) {
        this.map = map;
        this.marker_twilight_civil.setMap(this.map);
        this.marker_twilight_nautical.setMap(this.map);
        this.marker_twilight_astronomical.setMap(this.map);
        this.marker_night.setMap(this.map);
    },
    show: function() {
        this.marker_twilight_civil.setVisible(true);
        this.marker_twilight_nautical.setVisible(true);
        this.marker_twilight_astronomical.setVisible(true);
        this.marker_night.setVisible(true);
        this.refresh();
    },
    hide: function() {
        this.marker_twilight_civil.setVisible(false);
        this.marker_twilight_nautical.setVisible(false);
        this.marker_twilight_astronomical.setVisible(false);
        this.marker_night.setVisible(false);
    },
    isVisible: function() {
        return this.marker_night.getVisible();
    }
}
var googleMap;
function initMap() {
        var uluru = {lat: -25.363, lng: 131.044};
        googleMap = new google.maps.Map(document.getElementById('map'), {
          zoom: 4,
          center: uluru
        });
        var marker = new google.maps.Marker({
          position: uluru,
          map: map
        });
      }

(() => {
  var nightMap = initMap()

  nite.init(googleMap);
})();
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=p"></script>
</body>
</html>

我得到的错误: 在网络控制台中:

在 visualstudio 中我没有收到任何错误,但是 var nightmap 显示为灰色(已声明但从未读取值)。 这对我来说似乎很重要。

编辑: 一旦成功,我想将它添加到我的代码中,如下所示:

    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="initial-scale=1.0">
        <meta charset="utf-8">
        <style>
            #map {
                position: absolute;
                width: 100%;
                height: 100%;
                top: 0;
                left: 0;
                bottom: 0;
                right: 0;
            }
            /* Optional: Makes the sample page fill the window. */
            html, body {
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }
        }

        table {
            width: 75%;
            border-collapse: collapse;
            border-spacing: 0;
        }

        hr {
            margin-top: 0px;
            margin-bottom: 0px;
        }

        h3, .h3 {
            margin-top: 0;
            margin-bottom: -12px;
            font-size: 19pt;
            font-weight: 100;
        }
        h5 {
            margin-top: 3px;
            margin-bottom: 3px;
            color: grey;
            font-weight: 100;
            font-size:10pt;
        }
    </style>
<script src="https://maps.googleapis.com/maps/api/js?key="></script>
</head>
<body>
    <script src="~/Scripts/jquery-3.4.1.min.js"></script>
    <div class="map"id="map"></div>
  
  <script>
//Code for day/night overlay starts here-----------------  

var nite = {
        map: null,
        date: null,
        sun_position: null,
        earth_radius_meters: 6371008,
        marker_twilight_civil: null,
        marker_twilight_nautical: null,
        marker_twilight_astronomical: null,
        marker_night: null,

        init: function (map) {
            if (typeof google === 'undefined' ||
                typeof google.maps === 'undefined') throw "Nite Overlay: no google.maps detected";

            this.map = map;
            this.sun_position = this.calculatePositionOfSun();

            this.marker_twilight_civil = new google.maps.Circle({
                map: this.map,
                center: this.getShadowPosition(),
                radius: this.getShadowRadiusFromAngle(0.566666),
                fillColor: "#000",
                fillOpacity: 0.1,
                strokeOpacity: 0,
                clickable: false,
                editable: false
            });
            this.marker_twilight_nautical = new google.maps.Circle({
                map: this.map,
                center: this.getShadowPosition(),
                radius: this.getShadowRadiusFromAngle(6),
                fillColor: "#000",
                fillOpacity: 0.1,
                strokeOpacity: 0,
                clickable: false,
                editable: false
            });
            this.marker_twilight_astronomical = new google.maps.Circle({
                map: this.map,
                center: this.getShadowPosition(),
                radius: this.getShadowRadiusFromAngle(12),
                fillColor: "#000",
                fillOpacity: 0.1,
                strokeOpacity: 0,
                clickable: false,
                editable: false
            });
            this.marker_night = new google.maps.Circle({
                map: this.map,
                center: this.getShadowPosition(),
                radius: this.getShadowRadiusFromAngle(18),
                fillColor: "#000",
                fillOpacity: 0.1,
                strokeOpacity: 0,
                clickable: false,
                editable: false
            });
        },
        getShadowRadiusFromAngle: function (angle) {
            var shadow_radius = this.earth_radius_meters * Math.PI * 0.5;
            var twilight_dist = ((this.earth_radius_meters * 2 * Math.PI) / 360) * angle;
            return shadow_radius - twilight_dist;
        },
        getSunPosition: function () {
            return this.sun_position;
        },
        getShadowPosition: function () {
            return (this.sun_position) ? new google.maps.LatLng(-this.sun_position.lat(), this.sun_position.lng() + 180) : null;
        },
        refresh: function () {
            if (!this.isVisible()) return;
            this.sun_position = this.calculatePositionOfSun(this.date);
            var shadow_position = this.getShadowPosition();
            this.marker_twilight_civil.setCenter(shadow_position);
            this.marker_twilight_nautical.setCenter(shadow_position);
            this.marker_twilight_astronomical.setCenter(shadow_position);
            this.marker_night.setCenter(shadow_position);
        },
        jday: function (date) {
            return (date.getTime() / 86400000.0) + 2440587.5;
        },
        calculatePositionOfSun: function (date) {
            date = (date instanceof Date) ? date : new Date();

            var rad = 0.017453292519943295;

            // based on NOAA solar calculations
            var ms_past_midnight = ((date.getUTCHours() * 60 + date.getUTCMinutes()) * 60 + date.getUTCSeconds()) * 1000 + date.getUTCMilliseconds();
            var jc = (this.jday(date) - 2451545) / 36525;
            var mean_long_sun = (280.46646 + jc * (36000.76983 + jc * 0.0003032)) % 360;
            var mean_anom_sun = 357.52911 + jc * (35999.05029 - 0.0001537 * jc);
            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;
            var sun_true_long = mean_long_sun + sun_eq;
            var sun_app_long = sun_true_long - 0.00569 - 0.00478 * Math.sin(rad * 125.04 - 1934.136 * jc);
            var mean_obliq_ecliptic = 23 + (26 + ((21.448 - jc * (46.815 + jc * (0.00059 - jc * 0.001813)))) / 60) / 60;
            var obliq_corr = mean_obliq_ecliptic + 0.00256 * Math.cos(rad * 125.04 - 1934.136 * jc);

            var lat = Math.asin(Math.sin(rad * obliq_corr) * Math.sin(rad * sun_app_long)) / rad;

            var eccent = 0.016708634 - jc * (0.000042037 + 0.0000001267 * jc);
            var y = Math.tan(rad * (obliq_corr / 2)) * Math.tan(rad * (obliq_corr / 2));
            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);
            var true_solar_time_in_deg = ((ms_past_midnight + rq_of_time * 60000) % 86400000) / 240000;

            var lng = -((true_solar_time_in_deg < 0) ? true_solar_time_in_deg + 180 : true_solar_time_in_deg - 180);

            return new google.maps.LatLng(lat, lng);
        },
        setDate: function (date) {
            this.date = date;
            this.refresh();
        },
        setMap: function (map) {
            this.map = map;
            this.marker_twilight_civil.setMap(this.map);
            this.marker_twilight_nautical.setMap(this.map);
            this.marker_twilight_astronomical.setMap(this.map);
            this.marker_night.setMap(this.map);
        },
        show: function () {
            this.marker_twilight_civil.setVisible(true);
            this.marker_twilight_nautical.setVisible(true);
            this.marker_twilight_astronomical.setVisible(true);
            this.marker_night.setVisible(true);
            this.refresh();
        },
        hide: function () {
            this.marker_twilight_civil.setVisible(false);
            this.marker_twilight_nautical.setVisible(false);
            this.marker_twilight_astronomical.setVisible(false);
            this.marker_night.setVisible(false);
        },
        isVisible: function () {
            return this.marker_night.getVisible();
        }
    }
    var googleMap;
    // this is double
    //function initMap() {
    //    var uluru = {
    //        lat: -25.363,
    //        lng: 131.044
    //    };
    //    googleMap = new google.maps.Map(document.getElementById('map'), {
    //        zoom: 2,
    //        center: uluru
    //    });
    //    var marker = new google.maps.Marker({
    //        position: uluru,
    //        map: googleMap
    //    });
    //}

    (() => {
        var nightMap = initMap()

        nite.init(googleMap);
    })();
  


        //Code for my existing worldmap starts here----------------------
        var map;
        function initMap() {

            google.maps.event.addDomListener(window, 'load', initMap);

            //Create locations
            var Isfanbul = { lat: 41.009633, lng: 28.965165 };
            var Miami = { lat: 25.774266, lng: -80.193659 };
            var NewHaven = { lat: 41.308214, lng: -72.925052 };
            var JejuIsland = { lat: 33.393992, lng: 126.562665 };
            var Encore = { lat: 50.896560, lng: 6.069610 };

            //Marker images
            var GreenStatus = "@ViewBag.GreenStatus";
            var OrangeStatus = "@ViewBag.OrangeStatus";
            var RedStatus = "@ViewBag.RedStatus";

            //Default map settings, map settings can be changed here
            map = new google.maps.Map(document.getElementById('map'),
                {
                    center: { lat: 51.34, lng: 5.53 },
                    disableDefaultUI: true,
                    zoom: 3,

            //Create marker
            var MiamiMarker = new google.maps.Marker
                ({
                    position: Miami,
                    map: map,
                    icon: GreenStatus
                });

            //HTML for info windows
            var MiamiContent ="test"


            //This is a function that pops up the right infowindow when a marker is clicked
            MiamiMarker.addListener('click', function () {
                MiamiInfoCard.open(map, MiamiMarker);
            });


    </script>

    <script type="text/javascript" src="~/Scripts/SwipeDetection.js"></script>
    <script src="http://code.jquery.com/jquery.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
    <script src="~/signalr/hubs"></script>
    <script type="text/javascript" src="~/signalr/hubs"></script>
    <script type="text/javascript">
    </script>

</body>
</html>

为了我的尝试,我遵循了这个例子:https://codepen.io/josephdburdick/pen/gGbLrV

但即使 copy/pasting 这在正确的地方对我也不起作用。我好像漏掉了什么

如果我从 API 包含中删除 &callback=initMap 并将包含移动到文档的 <head> 中,您的代码对我有用。 Google Maps Javascript API v3 需要在代码中引用之前加载。

你这里也有错别字:

    var marker = new google.maps.Marker({
      position: uluru,
      map: map
    });

您的 map 变量是 googleMap,所以应该是:

  var marker = new google.maps.Marker({
    position: uluru,
    map: googleMap
  });

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="initial-scale=1.0">
  <meta charset="utf-8">
  <style>
    html,
    body {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
    }
    
    .map {
      width: 100vw;
      height: 100vh;
    }
  </style>
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB2xrZ8iXAIwaF-Z900sOJx0SPPXu8JB18"></script>
</head>

<body>

  <script src="~/Scripts/jquery-3.4.1.min.js"></script>
  <div class="map" id="map"></div>
  <script>
    var nite = {
      map: null,
      date: null,
      sun_position: null,
      earth_radius_meters: 6371008,
      marker_twilight_civil: null,
      marker_twilight_nautical: null,
      marker_twilight_astronomical: null,
      marker_night: null,

      init: function(map) {
        if (typeof google === 'undefined' ||
          typeof google.maps === 'undefined') throw "Nite Overlay: no google.maps detected";

        this.map = map;
        this.sun_position = this.calculatePositionOfSun();

        this.marker_twilight_civil = new google.maps.Circle({
          map: this.map,
          center: this.getShadowPosition(),
          radius: this.getShadowRadiusFromAngle(0.566666),
          fillColor: "#000",
          fillOpacity: 0.1,
          strokeOpacity: 0,
          clickable: false,
          editable: false
        });
        this.marker_twilight_nautical = new google.maps.Circle({
          map: this.map,
          center: this.getShadowPosition(),
          radius: this.getShadowRadiusFromAngle(6),
          fillColor: "#000",
          fillOpacity: 0.1,
          strokeOpacity: 0,
          clickable: false,
          editable: false
        });
        this.marker_twilight_astronomical = new google.maps.Circle({
          map: this.map,
          center: this.getShadowPosition(),
          radius: this.getShadowRadiusFromAngle(12),
          fillColor: "#000",
          fillOpacity: 0.1,
          strokeOpacity: 0,
          clickable: false,
          editable: false
        });
        this.marker_night = new google.maps.Circle({
          map: this.map,
          center: this.getShadowPosition(),
          radius: this.getShadowRadiusFromAngle(18),
          fillColor: "#000",
          fillOpacity: 0.1,
          strokeOpacity: 0,
          clickable: false,
          editable: false
        });
      },
      getShadowRadiusFromAngle: function(angle) {
        var shadow_radius = this.earth_radius_meters * Math.PI * 0.5;
        var twilight_dist = ((this.earth_radius_meters * 2 * Math.PI) / 360) * angle;
        return shadow_radius - twilight_dist;
      },
      getSunPosition: function() {
        return this.sun_position;
      },
      getShadowPosition: function() {
        return (this.sun_position) ? new google.maps.LatLng(-this.sun_position.lat(), this.sun_position.lng() + 180) : null;
      },
      refresh: function() {
        if (!this.isVisible()) return;
        this.sun_position = this.calculatePositionOfSun(this.date);
        var shadow_position = this.getShadowPosition();
        this.marker_twilight_civil.setCenter(shadow_position);
        this.marker_twilight_nautical.setCenter(shadow_position);
        this.marker_twilight_astronomical.setCenter(shadow_position);
        this.marker_night.setCenter(shadow_position);
      },
      jday: function(date) {
        return (date.getTime() / 86400000.0) + 2440587.5;
      },
      calculatePositionOfSun: function(date) {
        date = (date instanceof Date) ? date : new Date();

        var rad = 0.017453292519943295;

        // based on NOAA solar calculations
        var ms_past_midnight = ((date.getUTCHours() * 60 + date.getUTCMinutes()) * 60 + date.getUTCSeconds()) * 1000 + date.getUTCMilliseconds();
        var jc = (this.jday(date) - 2451545) / 36525;
        var mean_long_sun = (280.46646 + jc * (36000.76983 + jc * 0.0003032)) % 360;
        var mean_anom_sun = 357.52911 + jc * (35999.05029 - 0.0001537 * jc);
        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;
        var sun_true_long = mean_long_sun + sun_eq;
        var sun_app_long = sun_true_long - 0.00569 - 0.00478 * Math.sin(rad * 125.04 - 1934.136 * jc);
        var mean_obliq_ecliptic = 23 + (26 + ((21.448 - jc * (46.815 + jc * (0.00059 - jc * 0.001813)))) / 60) / 60;
        var obliq_corr = mean_obliq_ecliptic + 0.00256 * Math.cos(rad * 125.04 - 1934.136 * jc);

        var lat = Math.asin(Math.sin(rad * obliq_corr) * Math.sin(rad * sun_app_long)) / rad;

        var eccent = 0.016708634 - jc * (0.000042037 + 0.0000001267 * jc);
        var y = Math.tan(rad * (obliq_corr / 2)) * Math.tan(rad * (obliq_corr / 2));
        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);
        var true_solar_time_in_deg = ((ms_past_midnight + rq_of_time * 60000) % 86400000) / 240000;

        var lng = -((true_solar_time_in_deg < 0) ? true_solar_time_in_deg + 180 : true_solar_time_in_deg - 180);

        return new google.maps.LatLng(lat, lng);
      },
      setDate: function(date) {
        this.date = date;
        this.refresh();
      },
      setMap: function(map) {
        this.map = map;
        this.marker_twilight_civil.setMap(this.map);
        this.marker_twilight_nautical.setMap(this.map);
        this.marker_twilight_astronomical.setMap(this.map);
        this.marker_night.setMap(this.map);
      },
      show: function() {
        this.marker_twilight_civil.setVisible(true);
        this.marker_twilight_nautical.setVisible(true);
        this.marker_twilight_astronomical.setVisible(true);
        this.marker_night.setVisible(true);
        this.refresh();
      },
      hide: function() {
        this.marker_twilight_civil.setVisible(false);
        this.marker_twilight_nautical.setVisible(false);
        this.marker_twilight_astronomical.setVisible(false);
        this.marker_night.setVisible(false);
      },
      isVisible: function() {
        return this.marker_night.getVisible();
      }
    }
    var googleMap;

    function initMap() {
      var uluru = {
        lat: -25.363,
        lng: 131.044
      };
      googleMap = new google.maps.Map(document.getElementById('map'), {
        zoom: 2,
        center: uluru
      });
      var marker = new google.maps.Marker({
        position: uluru,
        map: googleMap
      });
    }

    (() => {
      var nightMap = initMap()

      nite.init(googleMap);
    })();
  </script>
</body>

</html>