Skip to content

Commit

Permalink
#57 Added marker clustering. Implemented Prototype Async loading noti…
Browse files Browse the repository at this point in the history
…fication. Limited the frequency of http requests by implementing a queue system and preventing simultaneous requests.
  • Loading branch information
kev007 committed May 18, 2016
1 parent 2abba6f commit 1785287
Show file tree
Hide file tree
Showing 8 changed files with 295 additions and 96 deletions.
3 changes: 2 additions & 1 deletion rest_service/src/main/resources/static/bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"ui-leaflet": "^1.0.0",
"angular-ui-layout": "^1.4.2",
"angular-bootstrap": "^1.3.2",
"angularjs-slider": "^2.13.0"
"angularjs-slider": "^2.13.0",
"leaflet.markercluster": "^0.5.0"
}
}
14 changes: 14 additions & 0 deletions rest_service/src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,26 @@
<link rel="stylesheet" href="bower_components/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="bower_components/angular-ui-layout/src/ui-layout.css"/>
<link rel="stylesheet" href="bower_components/angularjs-slider/dist/rzslider.min.css"/>
<link rel="stylesheet" href="bower_components/leaflet.markercluster/dist/MarkerCluster.css"/>
<link rel="stylesheet" href="bower_components/leaflet.markercluster/dist/MarkerCluster.Default.css"/>

</head>
<body>
<div ng-controller="MainCtrl">
<navigation></navigation>

<div class="container">
<uib-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</uib-alert>
<div class="loading" id="loading">
<uib-alert class="alert" type="danger" role="alert">
<button class="btn btn-danger btn-sm" ng-click="ignoreLoading()">Ignore</button>
Status: {{timePassed}} s
<br>
{{info}}

</uib-alert>
</div>

<div ng-view></div>
</div>

Expand All @@ -41,6 +54,7 @@
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="bower_components/leaflet/dist/leaflet.js"></script>
<script src="bower_components/leaflet.markercluster/dist/leaflet.markercluster.js"></script>
<script src="bower_components/ui-leaflet/dist/ui-leaflet.min.js"></script>
<script src="bower_components/angular-simple-logger/dist/angular-simple-logger.min.js"></script>
<script src="bower_components/angular-ui-layout/src/ui-layout.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
console.log();

$scope.dataSource = "accumulo";
document.getElementById("loading").style.visibility = "hidden";

/**
* Get the tweets array from the httpService
Expand All @@ -49,23 +48,38 @@
httpService.setSearchToken($scope.search.inputValue);
httpService.setSearchFields($scope.search.searchFields);


/**
* get the tweets from the REST interface
*/
if ($scope.dataSource == "accumulo") {
httpService.getTweetsFromServerByToken(); //Get by Token
//Get by GeoTime
httpService.getTweetsFromServerByToken().then(function (status) {
$scope.$emit('updateStatus', status);
});
} else if ($scope.dataSource == "restTest") {
httpService.getTweetsFromServerTest(); //Get using test REST API
//Get using test REST API
httpService.getTweetsFromServerTest().then(function (status) {
$scope.$emit('updateStatus', status);
});
} else if ($scope.dataSource == "static") {
httpService.getTweetsFromLocal(); //Get from local (debug)
//Get from local (debug)
httpService.getTweetsFromLocal().then(function (status) {
$scope.$emit('updateStatus', status);
});
} else {
httpService.getTweetsFromServerByToken(); //Get by Token
//Get by Token
httpService.getTweetsFromServerByToken().then(function (status) {
$scope.$emit('updateStatus', status);
});
}
// httpService.getTweetsFromServerByToken();

if (mode && mode === 'list') {

} else if (mode && mode === 'map') {
//TODO: Call Service to load Data for the Map view
}

$scope.$emit('updateStatus', "Loading: " + $scope.search.searchFields.text.checked + " | " + $scope.search.searchFields.user.checked + " | '" + $scope.search.inputValue + "'");
}
}
})();
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
* @type {string[]}
*/
MainCtrl.$inject = [
'$rootScope',
'$scope',
'$location'
'$interval',
'httpService'
];

/**
Expand All @@ -31,10 +33,61 @@
* @param $location
* @constructor
*/
function MainCtrl($scope,$location) {

function MainCtrl($rootScope, $scope, $interval, httpService) {
$scope.app = [];
$scope.app.name = "OSTMap";


document.getElementById("loading").style.visibility = "hidden";

$scope.timePassed = 0;
$scope.info = "";
var timestamp = 0;

$scope.alerts = [
// { type: 'danger', msg: 'Oh snap! Change a few things up and try submitting again.' },
// { type: 'success', msg: 'Well done! You successfully read this important alert message.' }
];

$scope.addAlert = function() {
$scope.alerts.push({msg: 'Another alert!'});
};

$scope.closeAlert = function(index) {
$scope.alerts.splice(index, 1);
};

$scope.ignoreLoading = function () {
httpService.setLoading(false);
document.getElementById("loading").style.visibility = "hidden";
}

$scope.$on('updateStatus', function(event, message){
if (message != 200) {
$scope.info = message;
}
$scope.setLoadingDisplay(httpService.getLoading(), message);
});

$scope.setLoadingDisplay = function (loadingStatus, message) {
if (loadingStatus) {
document.getElementById("loading").style.visibility = "visible";
} else {
document.getElementById("loading").style.visibility = "hidden";
}

timestamp = Date.now()
var intervalPromise = $interval(function () {
$scope.timePassed = Math.round((Date.now() - timestamp)/100)/10;

if(!httpService.getLoading()) {
$interval.cancel(intervalPromise);
}
}, 100);
};

$rootScope.$on('alertControl', function(event, message){
// $scope.alerts.push({msg: 'Another alert!'});
});
}
})();
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@
function MapCtrl($scope, httpService, $log, nemSimpleLogger, leafletData) {
mapInit($scope);

document.getElementById("loading").style.visibility = "hidden";

$scope.autoUpdateDisabled = true;
$scope.dataSource = "accumulo";
$scope.dataSource = "accumulo"; //default: "accumulo";

$scope.currentFilters = "";
$scope.timeFilter = 0.25;
Expand Down Expand Up @@ -77,45 +75,70 @@
/**
* Update filters
*/
var updateQueued = false;
$scope.search.updateFilters = function () {
/**
* Pass the filters to the httpService
*/
httpService.setSearchToken($scope.search.searchFilter);
// httpService.setSearchToken("yolo");
httpService.setTimeWindow(parseTimeFilter());
httpService.setBoundingBox($scope.getBounds());
/**
* get the tweets from the REST interface
*/
if ($scope.dataSource == "accumulo") {
httpService.getTweetsFromServerByGeoTime(); //Get by GeoTime
} else if ($scope.dataSource == "restTest") {
httpService.getTweetsFromServerTest(); //Get using test REST API
} else if ($scope.dataSource == "static") {
httpService.getTweetsFromLocal(); //Get from local (debug)
if (!httpService.getLoading()) {
/**
* Pass the filters to the httpService
*/
httpService.setSearchToken($scope.search.searchFilter);
httpService.setTimeWindow(parseTimeFilter());
httpService.setBoundingBox($scope.getBounds());
/**
* get the tweets from the REST interface
*/
httpService.queueAddGetTweetFrom($scope.dataSource, $scope.search);

if ($scope.dataSource == "accumulo") {
//Get by GeoTime
httpService.getTweetsFromServerByGeoTime().then(function (status) {
$scope.$emit('updateStatus', status);
});
} else if ($scope.dataSource == "restTest") {
//Get using test REST API
httpService.getTweetsFromServerTest().then(function (status) {
$scope.$emit('updateStatus', status);
});
} else if ($scope.dataSource == "static") {
//Get from local (debug)
httpService.getTweetsFromLocal().then(function (status) {
$scope.$emit('updateStatus', status);
});
} else {
//Get by Token
httpService.getTweetsFromServerByToken().then(function (status) {
$scope.$emit('updateStatus', status);
});
}

/**
* Update the filter display
* Check for null values, replace with Default
*
* @type {string}
*/
$scope.currentFilters = $scope.search.searchFilter + " | " +
$scope.search.hashtagFilter + " | " +
$scope.timeFilter + "h | " +
"[" + httpService.getBoundingBox().bbnorth.toFixed(2) +
", " + httpService.getBoundingBox().bbwest.toFixed(2) +
", " + httpService.getBoundingBox().bbsouth.toFixed(2) +
", " + httpService.getBoundingBox().bbeast.toFixed(2) + "]";

console.log("Filters updated: " + $scope.currentFilters + " | " + $scope.bounds);
$scope.$emit('updateStatus', "Loading: " + $scope.currentFilters + " | " + $scope.bounds);
} else {
httpService.getTweetsFromServerByToken(); //Get by Token
updateQueued = true;
}

/**
* Update the filter display
* Check for null values, replace with Default
*
* @type {string}
*/
$scope.currentFilters = $scope.search.searchFilter + " | " +
$scope.search.hashtagFilter + " | " +
$scope.timeFilter + "h | " +
"[" + httpService.getBoundingBox().bbnorth.toFixed(2) +
", " + httpService.getBoundingBox().bbwest.toFixed(2) +
", " + httpService.getBoundingBox().bbsouth.toFixed(2) +
", " + httpService.getBoundingBox().bbeast.toFixed(2) + "]";

console.log("Filters updated: " + $scope.currentFilters + " | " + $scope.bounds);

};

$scope.$on('updateStatus', function(event, message){
if(updateQueued) {
$scope.search.updateFilters();
updateQueued = false;
}
});

/**
* Move the map center to the coordinates of the clicked tweet
*
Expand All @@ -139,7 +162,7 @@
$scope.center ={
lat: lat,
lng: lng,
zoom: 6
zoom: 10
};

/**
Expand Down Expand Up @@ -218,12 +241,13 @@
*/
var newMarker = {
id: tweet.id,
layer: 'cluster',
lat: tweet.coordinates.coordinates[1],
lng: tweet.coordinates.coordinates[0],
focus: false,
draggable: false,
message: "@" + tweet.user.screen_name + ": " + tweet.text,
icon: $scope.icons.red
// icon: $scope.icons.red
};
// $scope.markers.push(newMarker)
// $scope.markers.push(tweet.id + ": " + newMarker)
Expand Down Expand Up @@ -292,6 +316,8 @@
$scope.onBounds()
});



/**
* Update the filters when the bounds are changed
*/
Expand All @@ -300,9 +326,9 @@
map.on('moveend', function() {
$scope.currentBounds = map.getBounds();
if($scope.autoUpdateDisabled) {
console.log("Map watcher triggered, autoUpdateDisabled: no action taken");
// console.log("Map watcher triggered, autoUpdateDisabled: no action taken");
} else {
console.log("Map watcher triggered, updating filters");
// console.log("Map watcher triggered, updating filters");
$scope.search.updateFilters();
}
});
Expand Down Expand Up @@ -450,7 +476,7 @@
$scope.currentMarkerID = 0;

/**
* Map event functions for future extensibility (Marker Clustering)
* Map functions for future extensibility (Marker Clustering)
* https://asmaloney.com/2015/06/code/clustering-markers-on-leaflet-maps/
* http://leafletjs.com/2012/08/20/guest-post-markerclusterer-0-1-released.html
*
Expand All @@ -466,5 +492,22 @@
logic: 'emit'
}
};

$scope.layers = {
baselayers: {
osm: {
name: "OpenStreetMap",
type: "xyz",
url: "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
}
},
overlays: {
cluster: {
name: "Clustered Markers",
type: "markercluster",
visible: true
}
}
}
}
})();
Loading

0 comments on commit 1785287

Please sign in to comment.