从Google MAPS API v3的JSON数据中放置标记

时间:2016-11-03 17:54:50

标签: javascript json google-maps google-maps-api-3

我有一个MySQL数据库,我已经创建了一个PHP脚本来将该数据转换为JSON格式。我知道需要获取JSON输出并在Google Map上创建标记。看起来很简单但是,我只需要标记来显示JSON输出中的一个值是否返回true。我将概述标记应该如何显示。

JSON输出

gpsStatus": "true", = Show streamOffline.png icon/marker

If gpsStatus & "streamStatus": "true", Then show the streamOnine.png icon/marker

If gpsStatus": "false" the show or remove from map the streamOffline.png icon/marker

所以基本上唯一一次应该显示一个图标/制造商是gpsStatus“:”true“但是取决于streamStatus的状态确定它是否显示streamOffline.png图标/标记或streamOnline.png图标/ marker.gpsStatus” :“false”删除或不显示标记,无论streamStatus值如何。

另一个转折是我试图让标记更新/刷新,而不是根据来自JSON输出的lat / lng值的数据重新加载地图。如果我还试图从JSON输出中提取其他值,那么我可以将数据放入infowidows等。

我一直在搜索有关如何在Stack,Google搜索和YouTube上执行此操作并尝试不同的事情(在此处列出和发布的内容太多)的几个月,但是,大多数示例以太不适用于我或已经过时了,我无法满足我的需求。在JavaScript和谷歌地图方面,我很可怕。

那么有没有人可以根据我的情况给我一个例子,说明如何获取JSON数据并循环遍历它以根据某些对象的值/ s绘制地图上的动态标记并刷新/更新当lat / lng值改变时,它们会在“gpsStatus”显示为false时删除标记,以及知道在其他区域使用哪些键?

这是我的JSON输出。

http://stream.dfwstormforce.com/test/api.php

这是我的测试地图,带有静态标记,以及我想要完成的填充数据应该是什么样子。

http://stream.dfwstormforce.com/test/test.html

3 个答案:

答案 0 :(得分:3)

我试图通过我从上面的描述中理解的更改代码,您现在可以扩展它。

            var customIcons = {
                  offline: {
                    icon: 'http://stream.dfwstormforce.com/images/icons/gpsOffline.png'
                  },
                  online: {
                    icon: 'http://stream.dfwstormforce.com/images/icons/gpsOnline.png'
                  }
                };

            var getCustomIcons= function (streamdata){
                    var iconUrl=customIcons.online;
                      if(streamdata.gpsStatus=='false')
                      {
                        iconUrl=customIcons.offline.icon;
                      }else
                      {
                        iconUrl=customIcons.online.icon;
                      }
                      return iconUrl;
                }


               $.getJSON('http://stream.dfwstormforce.com/inc/api.php', function(responsedata) { 
                        $.each( responsedata.streamers, function(i, value) {
                             if(value.lat!="" && value.lng!="" )
                             {
                                  var marker = new google.maps.Marker({
                                      position: {lat: parseFloat(value.lat), lng: parseFloat(value.lng)},
                                      animation: google.maps.Animation.DROP,
                                      title: value.DisplayName+','+ value.ChaserLocation,
                                      icon: getCustomIcons(value),
                                      map: map
                                    });

                                  marker.addListener('click', function() {
                                          infowindow.open(map, marker);
                                        });
                            }
                         });
            });

答案 1 :(得分:1)

问题在于,当您使用仅使用parseFloat转换它们的$.getJSON获取响应时,您将经度和经度绘制为标记,但是lat / lng包含N,E,W和S因为parseFloat方法失败了。

即。你lat / lng是这样的

        "lat": "N32.95421",
        "lng": "W96.38196",

因此,当您在此部分代码中使用parseFloat时,结果为NaN

$.each(responsedata.streamers, function(i, value) {
  if (value.lat != "" && value.lng != "") {

    var myLat = parseFloat(value.lat);

    // HERE on this line check in your CONSOLE the result is NaN
    console.log(myLat);

    var marker = new google.maps.Marker({
      position: {
        lat: value.lat,
        lng: value.lng
      },
      animation: google.maps.Animation.DROP,
      title: value.DisplayName + ',' + value.ChaserLocation,
      map: map
    });
  }
});

所以你需要做的是首先将纬度和经度转换为十进制格式:

$.each(responsedata.streamers, function(i, value) {
  if (value.lat != "" && value.lng != "") {
    var myLat = ConvertPoint(value.lat); //parseFloat(value.lat);

    var myLng = ConvertPoint(value.lng);

    var marker = new google.maps.Marker({
      position: {
        lat: myLat,
        lng: myLng
      },
      animation: google.maps.Animation.DROP,
      title: value.DisplayName + ',' + value.ChaserLocation,
      //icon: getcustomicons(value),
      map: map
    });

    //marker.addlistener('click', function() {
    //      infowindow.open(map, marker);
    //   });
  }
});

将此功能添加到您的JS代码

  function ConvertPoint(stringVal) {
  // This function will convert you lat, lng - instead of using parseFloat

    var direction = stringVal.substring(0, 1);

    var withOutChar = stringVal.substring(1);

    var point = parseFloat(withOutChar);

    if (direction == "S" || direction == "W") {
      point = point * -1;
    } // Don't do anything for N or E

    return point;
  }

试试这个让我知道标记是否正确。

与多个标记和信息窗口相关,然后刷新它们,如果它们发生变化,你将需要做更多的工作 - 但首先要绘制标记 - 现在尝试没有自定义图标。保持简单,然后继续下一步。

答案 2 :(得分:1)

以下是您网页的完整工作示例。在此简化版本上,您的JSON API http://stream.dfwstormforce.com/test/api.php将每10秒定期获取一次,合格数据(gpsStatus = true)将显示在地图上。

显示的标记图标取决于streamStatus值。

<!doctype html>
<html>
<head>
    <title>Google Map Test Page</title>
    <style>
        html, body, .map {
            width: 100%;
            height: 100%;
            background-color: #eee;
        }
    </style>
</head>
<body>
    <div id="map" class="map"></div>

    <script>
        var map = null;
        var markers = [];

        // Reload interval in milliseconds.
        var reloadInterval = 10000;

        var intervalId = window.setInterval(loadData, reloadInterval);

        function initMap() {
            var northTexasPosition = { lat: 32.836, lng: -96.995 };

            map = new google.maps.Map(document.getElementById('map'), {
                center: northTexasPosition,
                zoom: 7,
                mapTypeControl: true,
                mapTypeControlOptions: {
                    style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
                    position: google.maps.ControlPosition.TOP_RIGHT
                },
            });

            loadData();
        }

        // Load the markers data from API and display them on the map.
        function loadData() {
            $.getJSON('http://stream.dfwstormforce.com/test/api.php', function(responsedata) {
                clearMarkers();

                $.each(responsedata.streamers, function (key, item) {
                    item.lat = parseCoordinateNumber(item.lat);
                    item.lng = parseCoordinateNumber(item.lng);
                    item.gpsStatus = parseBoolean(item.gpsStatus);
                    item.streamStatus = parseBoolean(item.streamStatus);

                    if (shouldAddToMap(item)) {
                        addToMap(item);
                    }
                });
            });
        }

        // Clear all markers from the map.  
        function clearMarkers() {
            $.each(markers, function (key, marker) {
                marker.setMap(null);
            });

            markers = [];
        }

        // Add marker to the map.
        function addToMap(item) {
            var marker = new google.maps.Marker({
                position: { lat: item.lat, lng: item.lng },
                title: item.DisplayName + ', ' + item.ChaserLocation,
                icon: getIcon(item.streamStatus),
                map: map
            });

            markers.push(marker);
        }

        // Get the appropiate image url for marker icon.
        function getIcon(streamStatus) {
            if (! streamStatus) {
                return 'http://stream.dfwstormforce.com/images/icons/streamOffline.png';
            }

            return 'http://stream.dfwstormforce.com/images/icons/streamOnline.png';
        }

        // Should we add the marker to the map?
        function shouldAddToMap(item) {
            if ($.type(item.lat) === 'null' || $.type(item.lng) === 'null') {
                return false;
            }

            return item.gpsStatus === true;
        }

        // Parse coordinate number like 'W96.38188' to appropiate decimal value: -96.38188
        // return null if it's invalid.
        function parseCoordinateNumber(val) {
            if ($.type(val) === 'number') {
                return parseFloat(val);
            }

            if ($.type('val') !== 'string') {
                return null;
            }

            val = val.trim();

            if (val.length === 0) {
                return null;
            }

            var directionPart = val.substr(0, 1).toUpperCase();
            var valuePart = parseFloat(val.substring(1));

            if ($.inArray(directionPart, ['N', 'E']) >= 0) {
                return isNaN(valuePart) ? null : valuePart;
            }

            if ($.inArray(directionPart, ['S', 'W']) >= 0) {
                return isNaN(valuePart) ? null : -valuePart;
            }

            val = parseFloat(val);

            return isNaN(val) ? null : val;
        }

        // Parse boolean value.
        function parseBoolean(val) {
            if ($.type(val) === 'boolean') {
                return val;
            }

            if (val === 1) {
                return true;
            }

            if (val === 0) {
                return false;
            }

            if ($.type('val') !== 'string') {
                return null;
            }

            val = val.trim().toUpperCase();

            if (val === 'TRUE') {
                return true;
            }

            if (val === 'FALSE') {
                return false;
            }

            return null;
        }
    </script>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async="defer"></script>
</body>
</html>

正如@Dawood Awan所指出的,主要问题是你的latlng数据使用了学位的方向(N,S,E,W)。您必须将这些数据解析为十进制的适当坐标值。以上是我的代码的一部分,它将解析latlng

function parseCoordinateNumber(val) {
    if ($.type(val) === 'number') {
        return parseFloat(val);
    }

    if ($.type('val') !== 'string') {
        return null;
    }

    val = val.trim();

    if (val.length === 0) {
        return null;
    }

    var directionPart = val.substr(0, 1).toUpperCase();
    var valuePart = parseFloat(val.substring(1));

    if ($.inArray(directionPart, ['N', 'E']) >= 0) {
        return isNaN(valuePart) ? null : valuePart;
    }

    if ($.inArray(directionPart, ['S', 'W']) >= 0) {
        return isNaN(valuePart) ? null : -valuePart;
    }

    val = parseFloat(val);

    return isNaN(val) ? null : val;
}

它将允许数字中的坐标值或方向(N,S,E或W)的字符串。我没有处理正确的纬度或经度范围,但你也可以添加它。如果给定的坐标无效,该函数将返回null

另外,请不要忘记将google maps API替换为您的:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async="defer"></script>

希望这对你有帮助!