如何正确解析包含位置信息的 JSON 字符串数据以创建 Google 地图标记
How to properly parse JSON string data containing location information to create Google Maps Markers
我从 JSON 响应中获取字符串形式的纬度和经度。我正在解析响应,提取它们,然后将它们存储在一个数组中。然后我使用该数组使用 Google Maps.
在地图上填充标记
我的问题是,当我对位置数组中的值进行硬编码时,例如:
var locations = [["Happy Restaurant", 37.328255, -121.883693]];
标记已成功填充。但是当我使用 locations.push([f.restaurant_name, parseFloat(Number(f.address.latitude)), parseFloat(Number(f.address.longitude))]);
时,地图上没有填充标记。
硬编码值工作完美,但不知何故,它无法使用我的数组填充地图,该数组从具有相同数据的 JSON 解析响应中填充。我尝试使用 parseFloat
和 Number
方法。也试过toString
。似乎没有任何效果。我在这里错过了什么?
我的代码:
map.js:
var locations = [];
$.getJSON("http://localhost:63342/295%20Project/api/response.json?",
function(data) {
$.each(data, function(i, f) {
//Log prints accurate data
console.log(f.restaurant_name + " " + parseFloat(Number(f.address.latitude)) + " " + parseFloat(Number(f.address.longitude)));
// tried using Number() parseFloat() and parseFloat(Number()) without success
locations.push(f.restaurant_name, parseFloat(Number(f.address.latitude)), parseFloat(Number(f.address.longitude)));
});
});
//create the map
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: new google.maps.LatLng(37.328255, -121.883693),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker;
var i;
//populate the markers on map (works with hardocded values in the locations array)
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, "click", (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
//redirect markers to restaurant_detail.html
}
})(marker, i));
}
response.json:
[{
"restaurant_name": "Happy Eating",
"address": {
"longitude": -121.883693,
"city": "San Jose",
"zip": "95112",
"latitude": 37.328255,
"state": "CA",
"street_address": "545 S Second St"}
}]
html:
<div id="map" style="width: 100%; height: 400px;"></div>
您正在访问 locations[i][1]
,就好像 locations[i]
是一个数组,但您目前正在 push
将单个基元 locations
。尝试将 arrays 推到 locations
:
locations.push([f.restaurant_name, f.address.latitude, f.address.longitude]);
此外,与其乱用 IIFE 来处理 var
的函数作用域问题,您可能会发现使用 let
编写代码要容易得多,它具有块作用域并且是一个更容易处理。或者,更好的是,使用 forEach
直接迭代。
另一个问题是您需要确保在调用 localhost 之后 填充地图,而不是之前。照原样,您创建地图的代码会在发出请求后立即运行,而无需等待响应。相反,仅在响应返回后才创建地图:
fetch('http://localhost:63342/295%20Project/api/response.json?')
.then((data) => data.json())
.then((data) => {
const locations = data.map(({ restaurant_name, address: { latitude, longitude }}) => (
[restaurant_name, latitude, longitude]
));
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: new google.maps.LatLng(37.328255, -121.883693),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
const infowindow = new google.maps.InfoWindow();
locations.forEach(([name, lat, lng]) => {
const marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: map
});
google.maps.event.addListener(marker, "click", () => {
infowindow.setContent(name);
infowindow.open(map, marker);
});
});
});
我从 JSON 响应中获取字符串形式的纬度和经度。我正在解析响应,提取它们,然后将它们存储在一个数组中。然后我使用该数组使用 Google Maps.
在地图上填充标记我的问题是,当我对位置数组中的值进行硬编码时,例如:
var locations = [["Happy Restaurant", 37.328255, -121.883693]];
标记已成功填充。但是当我使用 locations.push([f.restaurant_name, parseFloat(Number(f.address.latitude)), parseFloat(Number(f.address.longitude))]);
时,地图上没有填充标记。
硬编码值工作完美,但不知何故,它无法使用我的数组填充地图,该数组从具有相同数据的 JSON 解析响应中填充。我尝试使用 parseFloat
和 Number
方法。也试过toString
。似乎没有任何效果。我在这里错过了什么?
我的代码:
map.js:
var locations = [];
$.getJSON("http://localhost:63342/295%20Project/api/response.json?",
function(data) {
$.each(data, function(i, f) {
//Log prints accurate data
console.log(f.restaurant_name + " " + parseFloat(Number(f.address.latitude)) + " " + parseFloat(Number(f.address.longitude)));
// tried using Number() parseFloat() and parseFloat(Number()) without success
locations.push(f.restaurant_name, parseFloat(Number(f.address.latitude)), parseFloat(Number(f.address.longitude)));
});
});
//create the map
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: new google.maps.LatLng(37.328255, -121.883693),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker;
var i;
//populate the markers on map (works with hardocded values in the locations array)
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, "click", (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
//redirect markers to restaurant_detail.html
}
})(marker, i));
}
response.json:
[{
"restaurant_name": "Happy Eating",
"address": {
"longitude": -121.883693,
"city": "San Jose",
"zip": "95112",
"latitude": 37.328255,
"state": "CA",
"street_address": "545 S Second St"}
}]
html:
<div id="map" style="width: 100%; height: 400px;"></div>
您正在访问 locations[i][1]
,就好像 locations[i]
是一个数组,但您目前正在 push
将单个基元 locations
。尝试将 arrays 推到 locations
:
locations.push([f.restaurant_name, f.address.latitude, f.address.longitude]);
此外,与其乱用 IIFE 来处理 var
的函数作用域问题,您可能会发现使用 let
编写代码要容易得多,它具有块作用域并且是一个更容易处理。或者,更好的是,使用 forEach
直接迭代。
另一个问题是您需要确保在调用 localhost 之后 填充地图,而不是之前。照原样,您创建地图的代码会在发出请求后立即运行,而无需等待响应。相反,仅在响应返回后才创建地图:
fetch('http://localhost:63342/295%20Project/api/response.json?')
.then((data) => data.json())
.then((data) => {
const locations = data.map(({ restaurant_name, address: { latitude, longitude }}) => (
[restaurant_name, latitude, longitude]
));
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: new google.maps.LatLng(37.328255, -121.883693),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
const infowindow = new google.maps.InfoWindow();
locations.forEach(([name, lat, lng]) => {
const marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: map
});
google.maps.event.addListener(marker, "click", () => {
infowindow.setContent(name);
infowindow.open(map, marker);
});
});
});