我有一个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
这是我的测试地图,带有静态标记,以及我想要完成的填充数据应该是什么样子。
答案 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所指出的,主要问题是你的lat
和lng
数据使用了学位的方向(N,S,E,W)。您必须将这些数据解析为十进制的适当坐标值。以上是我的代码的一部分,它将解析lat
和lng
:
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>
希望这对你有帮助!