【问题标题】:Is it at all possible to update markers in a Google Map using SignalR?是否可以使用 SignalR 更新 Google 地图中的标记?
【发布时间】:2015-12-29 00:28:58
【问题描述】:

如标题所说,是否可以使用 SignalR / jquery 来更新例如地图标记的颜色?

我正在开发一个网站,其中地图显示具有实时状态变化的不同单位,标记颜色应该反映这一点作为功能的一部分。

它可以以某种方式完成,还是在“运行时”设置颜色的唯一方法? 目前,地图以蓝色很好地显示了我的所有标记。

<script src="~/Scripts/GoogleAPI/markerclusterer.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script src="~/Scripts/GoogleAPI/oms.min.js"></script>
<script>
    var markerArray = [];    
    var usualColor = '0000FF';
    var spiderfiedColor = 'ffee22';
    var iconWithColor = function(color) {
        return 'http://chart.googleapis.com/chart?chst=d_map_xpin_letter&chld=pin|+|' +
            color + '|000000|ffff00';
    };
    var shadow = new google.maps.MarkerImage(
        'https://www.google.com/intl/en_ALL/mapfiles/shadow50.png',
        new google.maps.Size(37, 34), // size   - for sprite clipping
        new google.maps.Point(0, 0), // origin - ditto
        new google.maps.Point(10, 34) // anchor - where to meet map location
    );

    function initialize() {
        var bounds = new google.maps.LatLngBounds();
        var iw = new google.maps.InfoWindow();
        var mapOptions = {
            zoom: 12,
            panControl: false,
            zoomControl: false,
            scaleControl: false,
            mapTypeControlOptions: {
                style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
            },
            streetViewControl: false,
            overviewMapControl: true,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };

        var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        var oms = new OverlappingMarkerSpiderfier(map);
        var mcOptions = {
            maxZoom: 12
        };
        var markerCluster = new MarkerClusterer(map, [], mcOptions);

        //Overlapping marker spiderfier
        oms.addListener('click', function(marker) {
            iw.setContent(marker.desc);
            iw.open(map, marker);
        });
        oms.addListener('spiderfy', function(markers) {
            for (var i = 0; i < markers.length; i++) {
                markers[i].setIcon(iconWithColor(spiderfiedColor));
                markers[i].setShadow(null);
            }
            iw.close();
        });
        oms.addListener('unspiderfy', function(markers) {
            for (var i = 0; i < markers.length; i++) {
                markers[i].setIcon(iconWithColor(usualColor));
                markers[i].setShadow(shadow);
            }
        });

        //Populate data section
        var addMarker = function(lat, lon, name, locationName, unitHref, wellName, runNo, taskDesc, lastDepth, activityMessage, modeMessage) {
            var myLatlng = new google.maps.LatLng(parseFloat(lat), parseFloat(lon));

            bounds.extend(myLatlng);

            // COMMENTED OUT CUSTOM MARKER DESCRIPTION TO SAVE SPACE

            var marker = new google.maps.Marker({
                position: myLatlng,
                map: map,
                icon: iconWithColor(usualColor),
                shadow: shadow,
                maxWidth: 200
            });
            marker.desc = content;

            oms.addMarker(marker);
            markerArray.push(marker);
        };
        var populateUnits = function() {
            @foreach (var location in Model.Location)
            {
                if (location.Value != null && location.Key != null)
                {
                    @:addMarker('@location.Value.Latitude', '@location.Value.Longitude', '@location.Key.UnitName', '@location.Value.Name', '#', '@location.Key.ViewUnitContract.CurrentRun.Operation.WellContract.Name', '@location.Key.ViewUnitContract.CurrentRun.Id', '@location.Key.ViewUnitContract.CurrentRun.RunTask', '@location.Key.Depth', '@location.Key.ActivityMessage', '@location.Key.ModeMessage');
                }
            }
        };

        //Populate the units
        populateUnits();
        //Add cluster
        markerCluster.addMarkers(markerArray, true);
        //Fit map
        map.fitBounds(bounds);
    }
    google.maps.event.addDomListener(window, 'load', initialize);
</script>

这是我循环遍历数组的方式。

function changeMarkers(myArray) {
    for (var i = 0; i < myArray.length; i++) {
        myArray[i].setIcon(iconWithColor('a51720'));
    };
}

现在,我刚刚在执行脚本时调用了changeMarkers 函数,该函数有效。我已将 markerArray 从 initialize 函数中移出,但这也不起作用。

让我澄清一下我想做什么。假设页面加载,我与 SignalR 的连接启动并且没有可用的实时数据。我可能要过 10 秒或 10 小时才能更新标记的颜色。

比如说两个小时过去了,这就是我想做的;

function someFunc() {
    // Get a reference to the map object
    // Loop through its array of markers
    // if match between marker-id and SignalR data-id
    // update color of marker
}

如果我只是在任何给定时间之后循环遍历markerArray,那么脚本第一次执行时它每次都会返回一个空集。 我有点迷路了:)

【问题讨论】:

    标签: javascript jquery google-maps signalr


    【解决方案1】:

    您可以通过调用setIcon() 来设置标记颜色。在您的情况下,当您从 SignalR 获得更新时,请执行以下操作...

    var markerToChange = findMarker(markerArray, dataFromSignalR); // implement findMarker()
    markerToChange.setIcon(iconWithColor(dataFromSignalR.color));
    

    文档中的更多详细信息...https://developers.google.com/maps/documentation/javascript/reference#Marker

    【讨论】:

    • 我想我可以在运行时执行此操作,但 SignalR 值将不断更新。是否有可能以某种方式保存对地图的引用以便在以后的时间点进行交互?
    • 除非我误解了您的代码或您的意图,否则您的 markerArray 是对地图上所有标记的引用(您需要确保它在正确的范围内,以便 SignalR 回调可以访问它)。但是您应该能够使用该数组来找到您的标记并更新其颜色。无需重新绘制地图或任何东西。
    • 您的 SignalR 代码(特别是 SignalR 调用的回调)在哪里?它与这些脚本的其余部分在同一页面上吗?
    猜你喜欢
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 2019-05-21
    • 2019-09-03
    相关资源
    最近更新 更多