이 스크립트는 Google지도에서 지진 정보를 표시 할 수있는 웹 앱의 일부입니다. 이 스크립트는 Google지도를 비동기 적으로로드하고 Knockout ViewModel을 만듭니다. 사용자는 Knockout Observables (self.curFeedType
및 self.curFeedTimeHorizon
)와 연결된 일부 드롭 다운 메뉴를 통해 표시 할 지진을 선택할 수 있습니다. 그러면지도 뷰포트 경계에없는 지진 제목 목록이지도 옆에 표시됩니다. 지진 데이터는 USGS.gov의 AJAX 요청을 통해로드됩니다.Google지도의 바운더리로 필터링 된 geoJSON으로 녹아웃 뷰가 업데이트되지 않습니다.
피드 유형 업데이트 직후에 표시된 지진 제목 목록을 업데이트하고 싶습니다. 현재로서는 작동하지 않습니다. 이것은 비동기 문제라고 생각합니다. 디버거를 사용할 때 작동하지만 반대는 아닙니다.
지도 경계가 변경 될 때 UI를 업데이트하는 별도의 수신기가 있기 때문에 대부분의 기능이 작동하는 것으로 알고 있습니다. 그러나 지금은 지진 제목 목록이 피드가 변경되고지도가 이동 될 때까지 업데이트되지 않습니다.
function ControlViewModel() {
var self = this;
self.map = null;
self.loadedQuakes = [];
self.visibleQuakes = ko.observableArray();
// types of available earthquake feeds from USGS.gov
self.feedTypes = ["significant", "4.5", "2.5", "1.0", "all"];
self.feedTimeHorizons = ["hour", "day", "week", "month"];
// use significant and week as default feed when app loads
self.curFeedType = ko.observable("significant");
self.curFeedTimeHorizon = ko.observable("week");
function setVisibleQuakes (bounds, quakesToFilter) {
self.visibleQuakes(quakesToFilter.filter(quake => {
return bounds.contains(quake.latLon);
}));
}
self.updateVisibleQuakes = function(bounds, loadedQuakes) {
loadedQuakes ? setVisibleQuakes(bounds, loadedQuakes) :
setVisibleQuakes(bounds, self.loadedQuakes);
}
// Generate a url for the desired earthquake feed
self.generateFeedUrl = function() {
let baseFeedUrl = `https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/${self.curFeedType()}_${self.curFeedTimeHorizon()}.geojson`;
return baseFeedUrl;
}
// load quakes from USGS and create new model objects
async function getQuakeFeed() {
let loadedQuakes = [];
$.getJSON(self.generateFeedUrl(), function(data) {
for (var i = 0; i < data.features.length; i++) {
loadedQuakes.push(new earthQuakeModel(data.features[i]));
};
});
return loadedQuakes;
}
self.updateQuakeFeed = async function() {
if (self.map) {
let loadedQuakes = getQuakeFeed();
loadedQuakes.then(result => {
self.updateVisibleQuakes(self.map.getBounds(), result);
self.loadedQuakes = result;
});
}
}
// update the feed when either select menu changes
self.curFeedType.subscribe(self.updateQuakeFeed, null);
self.curFeedTimeHorizon.subscribe(self.updateQuakeFeed, null);
// call for inital setup
self.updateQuakeFeed();
}
var controlViewModel = new ControlViewModel();
// create a new Google Map
function initMap() {
let map = new google.maps.Map(document.getElementById('map_container'), {
center: {lat: 0, lng: 0},
zoom: 3
});
console.log(map);
controlViewModel.map = map;
// listener to let UI know that map bounds have changed
map.addListener('idle', function() {
let bounds = map.getBounds();
controlViewModel.updateVisibleQuakes(bounds, null);
});
}
ko.applyBindings(controlViewModel);