Get user position and display nearby people on map (close #2)
This commit is contained in:
parent
4ab25d09e5
commit
83bef5b3d5
@ -12,6 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cordova-android": "^8.0.0",
|
"cordova-android": "^8.0.0",
|
||||||
"cordova-plugin-app-version": "^0.1.9",
|
"cordova-plugin-app-version": "^0.1.9",
|
||||||
|
"cordova-plugin-geolocation": "^4.0.1",
|
||||||
"cordova-plugin-headercolor": "^1.0.0",
|
"cordova-plugin-headercolor": "^1.0.0",
|
||||||
"cordova-plugin-inappbrowser": "^3.0.0",
|
"cordova-plugin-inappbrowser": "^3.0.0",
|
||||||
"cordova-plugin-statusbar": "^2.4.2",
|
"cordova-plugin-statusbar": "^2.4.2",
|
||||||
@ -27,7 +28,8 @@
|
|||||||
"cordova-plugin-inappbrowser": {},
|
"cordova-plugin-inappbrowser": {},
|
||||||
"phonegap-plugin-barcodescanner": {
|
"phonegap-plugin-barcodescanner": {
|
||||||
"ANDROID_SUPPORT_V4_VERSION": "27.+"
|
"ANDROID_SUPPORT_V4_VERSION": "27.+"
|
||||||
}
|
},
|
||||||
|
"cordova-plugin-geolocation": {}
|
||||||
},
|
},
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"android"
|
"android"
|
||||||
|
@ -4,6 +4,15 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the API endpoint URL for an action
|
||||||
|
* @param {String} action
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
function getActionUrl(action) {
|
||||||
|
return SETTINGS["server"] + "/" + action;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call an API function on the server.
|
* Call an API function on the server.
|
||||||
* @param {string} action
|
* @param {string} action
|
||||||
@ -16,19 +25,66 @@ function callAPI(action, data, success, failure) {
|
|||||||
return $.ajax({
|
return $.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: SETTINGS["server"] + "/" + action,
|
url: getActionUrl(action),
|
||||||
data: data,
|
data: data,
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
success: function (data, textStatus) {
|
success: function (data, textStatus) {
|
||||||
if (data.status === "OK") {
|
if (data.status === "OK") {
|
||||||
success(data);
|
success(data);
|
||||||
} else if (data.status === "ERROR") {
|
return;
|
||||||
|
}
|
||||||
|
if (typeof failure != 'function') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.status === "ERROR") {
|
||||||
failure(data.msg);
|
failure(data.msg);
|
||||||
} else {
|
} else {
|
||||||
failure("The server sent an invalid response.");
|
failure("The server sent an invalid response.");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function (xhr, textStatus, errorThrown) {
|
error: function (xhr, textStatus, errorThrown) {
|
||||||
|
if (typeof failure != 'function') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (textStatus) {
|
||||||
|
case "timeout":
|
||||||
|
failure("Couldn't connect to the server (timeout).");
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
|
failure("Couldn't connect to the server (error).");
|
||||||
|
break;
|
||||||
|
case "parseerror":
|
||||||
|
failure("The server sent a malformed response.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
failure("Couldn't connect to the server.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call an API function on the server. Makes fewer assumptions about what
|
||||||
|
* constitutes a success response.
|
||||||
|
* @param {string} action
|
||||||
|
* @param {array} data key: value array of arguments for the server.
|
||||||
|
* @param {function} success Called with the JSON response object.
|
||||||
|
* @param {function} failure Called with an error message string.
|
||||||
|
* @return {undefined}
|
||||||
|
*/
|
||||||
|
function callAPIRawResponse(action, data, success, failure) {
|
||||||
|
return $.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: getActionUrl(action),
|
||||||
|
data: data,
|
||||||
|
timeout: 5000,
|
||||||
|
success: function (data, textStatus) {
|
||||||
|
success(data);
|
||||||
|
},
|
||||||
|
error: function (xhr, textStatus, errorThrown) {
|
||||||
|
if (typeof failure != 'function') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (textStatus) {
|
switch (textStatus) {
|
||||||
case "timeout":
|
case "timeout":
|
||||||
failure("Couldn't connect to the server (timeout).");
|
failure("Couldn't connect to the server (timeout).");
|
||||||
|
@ -18,7 +18,7 @@ $(".view-main").on("card:open", ".card-expandable", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$(".view-main").on("card:closed", "#map-card", function () {
|
$(".view-main").on("card:closed", "#map-card", function () {
|
||||||
leafletgllayer._glMap.setPitch(0);
|
//leafletgllayer._glMap.setPitch(0);
|
||||||
leafletmap.invalidateSize();
|
leafletmap.invalidateSize();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ function loadBalance(callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openMapCard() {
|
function openMapCard() {
|
||||||
leafletgllayer._glMap.setPitch(40);
|
//leafletgllayer._glMap.setPitch(40);
|
||||||
leafletmap.invalidateSize();
|
leafletmap.invalidateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
114
www/js/map.js
114
www/js/map.js
@ -4,12 +4,20 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var userPositionIsReal = false;
|
||||||
|
var userposition = {
|
||||||
|
coords: {
|
||||||
|
latitude: 46.595,
|
||||||
|
longitude: -112.019,
|
||||||
|
accuracy: 10000
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var leafletmap = L.map('map', {
|
var leafletmap = L.map('map', {
|
||||||
minZoom: 12,
|
minZoom: 12,
|
||||||
maxZoom: 20
|
maxZoom: 20
|
||||||
});
|
});
|
||||||
leafletmap.setView([46.595, -112.019], 13);
|
|
||||||
leafletmap.attributionControl.setPrefix("");
|
leafletmap.attributionControl.setPrefix("");
|
||||||
var leafletgllayer = L.mapboxGL({
|
var leafletgllayer = L.mapboxGL({
|
||||||
attribution: "© OpenMapTiles © OpenStreetMap contributors",
|
attribution: "© OpenMapTiles © OpenStreetMap contributors",
|
||||||
@ -19,3 +27,107 @@ var leafletgllayer = L.mapboxGL({
|
|||||||
});
|
});
|
||||||
|
|
||||||
leafletgllayer.addTo(leafletmap);
|
leafletgllayer.addTo(leafletmap);
|
||||||
|
|
||||||
|
L.control.scale().addTo(leafletmap);
|
||||||
|
|
||||||
|
var leafletpeoplelayer = L.geoJson(
|
||||||
|
{
|
||||||
|
name: "Nearby People",
|
||||||
|
type: "FeatureCollection",
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
type: "Feature",
|
||||||
|
geometry: {
|
||||||
|
type: "Point",
|
||||||
|
coordinates: [0, 0]
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
username: "",
|
||||||
|
verified: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onEachFeature: function (feature, layer) {
|
||||||
|
if (feature.properties && feature.properties.popupContent) {
|
||||||
|
layer.bindPopup(feature.properties.popupContent);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pointToLayer: function (feature, latlng) {
|
||||||
|
return L.marker(latlng);
|
||||||
|
// return L.circleMarker(latlng, {
|
||||||
|
// radius: 14,
|
||||||
|
// fillColor: "#f00",
|
||||||
|
// color: "#000",
|
||||||
|
// weight: 1,
|
||||||
|
// opacity: 1,
|
||||||
|
// fillOpacity: 0.6
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function updateMap() {
|
||||||
|
var diagonalMeters = leafletmap.getBounds().getNorthWest().distanceTo(leafletmap.getBounds().getSouthEast());
|
||||||
|
var radius = (diagonalMeters / 2.0) / 1609.344;
|
||||||
|
callAPIRawResponse("getnearby", {
|
||||||
|
key: localStorage.getItem("key"),
|
||||||
|
latitude: leafletmap.getCenter().lat,
|
||||||
|
longitude: leafletmap.getCenter().lng,
|
||||||
|
radius: radius,
|
||||||
|
format: "geojson"
|
||||||
|
}, function (data) {
|
||||||
|
if (data.type == "FeatureCollection") {
|
||||||
|
leafletpeoplelayer.clearLayers();
|
||||||
|
data.features.forEach(function (item) {
|
||||||
|
item.properties.popupContent = "<i class=\"fas fa-user\"></i> " + item.properties.name + "<br><br><a class=\"button button-small button-fill text-color-white\" href=\"/sendmoney/" + item.properties.id + "\">Send Money</a>";
|
||||||
|
leafletpeoplelayer.addData(item);
|
||||||
|
});
|
||||||
|
leafletmap.addLayer(leafletpeoplelayer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function recenterMapPosition() {
|
||||||
|
var zoom = 13;
|
||||||
|
if (userposition.coords.accuracy < 100) {
|
||||||
|
zoom = 15;
|
||||||
|
}
|
||||||
|
if (userposition.coords.accuracy < 50) {
|
||||||
|
zoom = 16;
|
||||||
|
}
|
||||||
|
leafletmap.setView([userposition.coords.latitude, userposition.coords.longitude], zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
function recenterMapToUserPosition() {
|
||||||
|
if (userPositionIsReal == false) {
|
||||||
|
getLocation(function (position) {
|
||||||
|
userposition = position;
|
||||||
|
userPositionIsReal = true;
|
||||||
|
recenterMapPosition();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
recenterMapPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to get user location
|
||||||
|
watchLocation(function (position) {
|
||||||
|
userposition = position;
|
||||||
|
if (userPositionIsReal == false) {
|
||||||
|
recenterMapPosition();
|
||||||
|
userPositionIsReal = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set map to default position
|
||||||
|
recenterMapPosition();
|
||||||
|
// Load nearby people
|
||||||
|
updateMap();
|
||||||
|
// Watch for map moving
|
||||||
|
leafletmap.on("moveend", function () {
|
||||||
|
updateMap();
|
||||||
|
});
|
@ -14,6 +14,38 @@ var openBrowser = function (url) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var getLocation = function (success, error) {
|
||||||
|
if ("geolocation" in navigator) {
|
||||||
|
navigator.geolocation.getCurrentPosition(function (position) {
|
||||||
|
success(position);
|
||||||
|
}, function (err) {
|
||||||
|
error(err.message);
|
||||||
|
}, {
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 5000,
|
||||||
|
maximumAge: 0
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
error("Location is unavailable.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var watchLocation = function (success, error) {
|
||||||
|
if ("geolocation" in navigator) {
|
||||||
|
navigator.geolocation.watchPosition(function (position) {
|
||||||
|
success(position);
|
||||||
|
}, function (err) {
|
||||||
|
error(err.message);
|
||||||
|
}, {
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 5000,
|
||||||
|
maximumAge: 0
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
error("Location is unavailable.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function initCordova() {
|
function initCordova() {
|
||||||
platform_type = "cordova";
|
platform_type = "cordova";
|
||||||
|
|
||||||
|
@ -84,17 +84,25 @@
|
|||||||
<div class="col-100 tablet-50 desktop-33">
|
<div class="col-100 tablet-50 desktop-33">
|
||||||
<div class="card card-expandable elevation-2" id="map-card" style="margin-top: var(--f7-card-margin-vertical);" onclick="openMapCard()">
|
<div class="card card-expandable elevation-2" id="map-card" style="margin-top: var(--f7-card-margin-vertical);" onclick="openMapCard()">
|
||||||
|
|
||||||
<div class="card-content text-align-center" style="min-height: 16.58em;">
|
|
||||||
|
|
||||||
<div class="card-header card-opened-fade-out" style="z-index: 9999999; background-color: rgba(255,255,255,0.5);">
|
<div class="card-header card-opened-fade-out" style="z-index: 9999999; background-color: rgba(255,255,255,0.5);">
|
||||||
Nearby
|
<div>Nearby</div>
|
||||||
|
<div>
|
||||||
|
<span class="link icon-only card-prevent-open" onclick="recenterMapToUserPosition()" style="margin-top: 0.1em; cursor: pointer;">
|
||||||
|
<i class="material-icons" style="font-size: 16pt;">my_location</i>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-content text-align-center" style="min-height: 16.58em;">
|
||||||
|
|
||||||
<div class="navbar card-opened-fade-in">
|
<div class="navbar card-opened-fade-in">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="title">Nearby</div>
|
<div class="title">Nearby</div>
|
||||||
|
|
||||||
<div class="right">
|
<div class="right">
|
||||||
|
<a href="" class="link icon-only" onclick="recenterMapToUserPosition()">
|
||||||
|
<i class="material-icons">my_location</i>
|
||||||
|
</a>
|
||||||
<a href="#" class="link icon-only card-close">
|
<a href="#" class="link icon-only card-close">
|
||||||
<i class="material-icons">close</i>
|
<i class="material-icons">close</i>
|
||||||
</a>
|
</a>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user