Рубрики
Без рубрики

Как создать свое собственное приложение Uber-For-X (часть 2)

Избранные в топ-десять в десятке Nodejs Mybridge’s Ten Nodejs от Jan-Feb 2017 и Top 50 Nodejs статей года (V.2018) Обновление: прочитайте обновленную версию этой статьи на моем технологическом блоге Добро пожаловать в часть 2 этой серии, создавая свое собственное приложение Uber-For-X. В части 1 вы использовали

Извлеченный в MyBridge ‘s Top Ten Nodejs Статьи от Jan-Feb 2017 и Топ 50 Nodejs Статьи года (v.2018)

Обновление: Прочитайте обновленную версию этой статьи на моем Tech Blog

Добро пожаловать в часть 2 этой серии Строить свое собственное приложение Uber-For-X Отказ В части 1 вы использовали пример приложения Ciatic-COP и узнали, как извлечь полицейские, расположенные вблизи данной пары широты и долготных координат. В этой части вы будете продолжать построить одно и то же приложение и научиться реализовывать эти функции:

  • Обмен данными между полицейскими и гражданами в режиме реального времени, используя веб-розетки
  • Используя карты, чтобы показать информацию о местонахождении гражданина и КС.
  • Визуализация преступных данных

Обязательно прочитайте часть 1 тщательно и попробуйте примеры, прежде чем продолжить оставшуюся часть этого руководства.

Организация набора проекта и папки

Давайте проанализируем файлы проекта, которые у нас есть, из предыдущей части:

  • app.js Содержит настройки вашего сервера и конфиги базы данных. Каждый раз, когда вам нужно запустить сервер, вы будете использовать этот файл, набрав Узел App.js в вашем терминале.
  • Marross.js – Вы будете использовать этот файл для записи конечных точек и обработчиков
  • DB-операции – Где вы пишете операции базы данных
  • Виды будет содержать ваши HTML-страницы
  • публичный будет содержать подпункты для хранения Javascripts, styleshe листания и изображений

Если вы использовали Uber раньше, вы осознаете, что есть приложение для водителя, и приложение для всадника. Давайте попробуем реализовать то же самое – Citizen.html покажет гражданин, облицовочную сторону приложения и Cop.html покажет приложение для лица Вы сохраните эти файлы внутри Виды папка. Открыть Citizen.html. В вашем текстовом редакторе и добавьте это:





    
    Citizen <%= userId %> 


    

Hello Citizen <%= userId %>

Повторите этот шаг для Cop.html а также заменить слово Гражданин с КС Отказ

data-userid это атрибут, который начинается с префикса Дата-, Что вы можете использовать для хранения некоторой информации в качестве строк, которые не обязательно должны иметь визуальное представление. <%= UserID%> Похоже, кажется странным видом синтаксиса, но не волнуйтесь, наш шаблон двигатель понимает, что все, что между <% = и %> это переменная, и она заменит переменную userid Для фактического значения на стороне сервера до того, как страница подана. Вы поймете это лучше, когда вы прогрессируете.

Если вы вспомните в более ранней части, у вас были эти линии app.js:

app.set('views', 'views'); 
app.use(express.static('./public'));
app.set('view engine','html');
app.engine('html',consolidate.underscore);

Первая строка сообщает вашему приложению искать HTML-файлы внутри Виды Папка всякий раз, когда она получает запрос на определенную страницу. Вторая строка устанавливает папку, из которой статические активы, такие как таблицы стилей и JavaScript, будут поданы при нагрузке страницы на браузере. Следующие две строки говорят наше приложение использовать подчеркивание Шаблон двигатель для анализа наших HTML-файлов.

Теперь, когда структура каталогов устанавливается, и представления готовы, пришло время начать реализацию функций! Перед продолжением, это будет полезно сохранить следующие моменты:

  • Написать код JS внутри Сценарий Тег в документе HTML. Вы можете записать его внутри .js файл, в этом случае вы должны сохранить файл JS внутри /public/js папка и загрузить ее на свою страницу. Убедитесь, что вы загружаете библиотеки и другие зависимости в первую очередь!
  • Это будет полезно, если вы сохраните консоль разработчиков открыть в своем браузере, чтобы проверить наличие сообщений об ошибках в случае, если что-то не работает. Держите часы на выходе терминала тоже.
  • Слова событие и сигнал Будет использоваться взаимозаменяемо в этом руководстве – оба значат одно и то же.

Давайте начнем взломать!

Обслуживание страниц граждан и КС

Давайте представьте страницу гражданина на пути к http://localhost: 8000/Citizen.html, и страница КС о том, чтобы идти в http://localhost: 8000/cop.html . Сделать это, открыть app.js и добавьте эти строки внутри функции обратного вызова mongoclient.connect :

app.get('/citizen.html', function(req, res){
    res.render('citizen.html',{
        userId: req.query.userId
    });
});

app.get('/cop.html', function(req, res){
    res.render('cop.html', {
        userId: req.query.userId
    });
});

Сохраните ваши файлы, повторно запустите свой сервер и загрузите страницы граждан и КС Отказ Вы должны увидеть Привет Граждан на странице. Если вы пройдете userid Как параметры запроса в URL, например – http://localhost: 8000/Citizen.html? usid = YourName Тогда вы увидите Здравствуйте гражданина Yourname . Это потому, что ваш шаблон двигатель замещен переменной userid со значением, которое вы передали из параметров запроса, и обратно подали страницу.

Почему вам нужны веб-сокеты, а как они работают?

Событие или сигнальная связь всегда была интуитивно понятным способом передачи сообщений с историческими временами. Самые ранние методы были довольно элементарными – вроде используя пожарные сигналы для различных целей, в основном, чтобы предупредить о опасности для людей.

На протяжении веков появились новые и лучшие формы связи. Приключение компьютеров и Интернет вызвало что-то действительно инновационное – и с развитием модели OSI, программирование розетки и революцию Smart-Phone, однонаправленное общение стало довольно сложной. Основные принципы остаются прежними, но теперь гораздо интереснее, чем настроить что-то в огне и бросать его.

Используя розетки, вы можете отправлять и получать информацию через События, или другими словами сигналы Отказ Таких сигналов могут быть разные типы, и если задействованные стороны знают, какой сигнал «слушать», то может быть обмен информацией.

Но почему бы не просто использовать HTTP-запросы?

Я прочитал очень хорошую статью на Разница между HTTP-запросами и веб-сокетами Отказ Это короткая, так что вы можете прочитать его, чтобы понять концепцию веб-розеток лучше.

Но кратко поставить, традиционные HTTP-запросы, такие как Get и Post, инициируют новое запрос на соединение, а затем закрыть соединение после того, как сервер отправит обратно ответ. Если вы должны были попытаться построить приложение в режиме реального времени, используя HTTP, клиент должен настроить запросы через регулярные промежутки времени для проверки новой информации (которая может быть или может быть доступна). Это из-за того, что сам сервер не может толчок информация самостоятельно.

И это крайне неэффективно – клиент будет впустить ресурсы в постоянном прерывании сервера и говорит « Привет, я XYZ – давай пожать друг другу руки. У вас есть что-то новое для меня? «И сервер будет похож – « Привет (пожимая руки). Нет, я не знаю. До свидания!” снова и снова, что означает, что даже сервер трает ресурсы!

Однако веб-розетки создают постоянное соединение между клиентом и сервером. Таким образом, так клиент не должен продолжать задавать сервер, сервер может толчок информация, когда она должна. Этот метод гораздо более эффективен для создания приложений в реальном времени.

Веб-розетки У вас есть поддержка во всех основных браузерах, но для нескольких браузеров, которые не являются другими параметрами/методами/методами для полагаться, как длительное голосование. Эти подпасные методы и API Web Sockets соединяются в сокете. IO, так что вам не придется беспокоиться о совместимости браузера. Вот и Отличный ответ на переполнении стека, который сравнивает множество этих вариантов.

Интеграция сокета. И.

Начнем с помощью Socket.IO с Express Server, а также загрузить библиотеку клиентской библиотеки Socket.io на страницах HTML. Также вы также будете использовать jQuery – это не нужно для работы socket.io, но ваше приложение понадобится для создания запросов AJAX и тонн других вещей. Так что идите вперед, напишите это на обоих страницах:









Первый Сценарий Теги загружает сокет. Клиентская библиотека IO (как только мы обслуживаем страницу с помощью Socket.io Server), которая обнародовала глобальный Ио объект. Ваше приложение будет использовать этот объект для излучения событий/сигналов на сервер и прослушивание событий с сервера.

Теперь вы должны изменить app.js использовать socket.io:

var http = require("http");
var express = require("express");
var consolidate = require("consolidate"); //1
var _ = require("underscore");
var bodyParser = require('body-parser');

var routes = require('./routes'); //File that contains our endpoints
var mongoClient = require("mongodb").MongoClient;

var app = express();
app.use(bodyParser.urlencoded({
    extended: true,
}));

app.use(bodyParser.json({
    limit: '5mb'
}));

app.set('views', 'views'); //Set the folder-name from where you serve the html page. 
app.use(express.static('./public')); //setting the folder name (public) where all the static files like css, js, images etc are made available

app.set('view engine', 'html');
app.engine('html', consolidate.underscore); //Use underscore to parse templates when we do res.render

var server = http.Server(app);
var portNumber = 8000; //for locahost:8000

var io = require('socket.io')(server); //Creating a new socket.io instance by passing the HTTP server object

server.listen(portNumber, function() { //Runs the server on port 8000
    console.log('Server listening at port ' + portNumber);

    var url = 'mongodb://localhost:27017/myUberApp'; //Db name
    mongoClient.connect(url, function(err, db) { //a connection with the mongodb is established here.
        console.log("Connected to Database");

        app.get('/citizen.html', function(req, res) { //a request to /citizen.html will render our citizen.html page
            //Substitute the variable userId in citizen.html with the userId value extracted from query params of the request.
            res.render('citizen.html', {
                userId: req.query.userId
            });
        });

        app.get('/cop.html', function(req, res) {
            res.render('cop.html', {
                userId: req.query.userId
            });
        });

        io.on('connection', function(socket) { //Listen on the 'connection' event for incoming sockets
            console.log('A user just connected');

            socket.on('join', function(data) { //Listen to any join event from connected users
                socket.join(data.userId); //User joins a unique room/channel that's named after the userId 
                console.log("User joined room: " + data.userId);
            });

            routes.initialize(app, db, socket, io); //Pass socket and io objects that we could use at different parts of our app
        });
    });
});

/* 1. Not all the template engines work uniformly with express, hence this library in js, (consolidate), is used to make the template engines work uniformly. Altough it doesn't have any 
modules of its own and any template engine to be used should be seprately installed!*/

Обязательно измените инициализация Функция в Marross.js принять Четыре Параметры вместо двух, как это – Функция инициализация (приложение, БД, сокет , Ио Несомненно .

Если вы перезагрузите сервер и обновите свои страницы, вы увидите сообщение Пользователь только что подключен в вашем терминале. Сервер также создаст новую комнату, как только оно получает Присоединяйтесь к Событие от подключенных клиентов, так что вы увидите еще одно сообщение – Пользователь присоединился к комнате. Попробуйте это с http://localhost: 8000/cop.html? userId = 02 , вы должны получить аналогичный выход.

Идеально – теперь, когда вы интегрированы Socket.io, вы можете начать строить остальную часть вашего приложения.

Гражданин-полицейский коммуникация:

Весь процесс может быть широко разделен на два набора функций:

  1. Запрос на помощь и уведомление близлежащих полицейских
  2. Принятие запроса и уведомление гражданина

Давайте попробуем понять, как подробно реализовать каждую из этих функций.

Запрос на помощь и уведомление близлежащих полицейских:

  • Сначала создайте конечную точку /Cops/info внутри Marals.js, Это позвонит функцию, чтобы получить информацию о профиле полиции и вернуть результаты в виде JSON на клиент –
// GET request to '/cops/info?userId=02'
app.get('/cops/info', function(req, res){
    var userId = req.query.userId //extract userId from query params
    dbOperations.fetchCopDetails(db, userId, function(results){
        res.json({
            copDetails: results //return results to client
        });
    });
});
  • Далее вы напишите функции fetchcopdetails. в db-options.js, который принимает экземпляр БД, КС userid и функция обратного вызова. Эта функция будет использовать MongoDB indone. Запрос, чтобы получить информацию КС с данным userid из базы данных, а затем вернуть результат к обратным вызовам:
function fetchCopDetails(db, userId, callback) {
    db.collection("policeData").findOne({
        userId: userId
    }, function(err, results) {
        if (err) {
            console.log(err);
        } else {
            callback({
                copId: results.userId,
                displayName: results.displayName,
                phone: results.phone,
                location: results.location
            });
        }
    });
}
exports.fetchCopDetails = fetchCopDetails;
  • Внутри Cop.html. :

Теперь, когда вы создали конечную точку, вы можете вызвать его, используя функцию ajax jQuery, чтобы получить информацию о профиле COP и отображать ее внутри пустой Div Отказ Вы также настроим страницу COP, чтобы начать слушать любые запросы справки:

//First send a GET request using JQuery AJAX and get the cop's details and save it
$.ajax({
    url: "/cops/info?userId="+userId,
    type: "GET",
    dataType: "json",
    success: function(data){ //Once response is successful
        copDetails = data.copDetails; //Save the cop details
        copDetails.location = {
            address: copDetails.location.address,
            longitude: copDetails.location.coordinates[0],
            latitude: copDetails.location.coordinates[1] 
        };
        document.getElementById("copDetails").innerHTML = JSON.stringify(data.copDetails);
    },
    error: function(httpRequest, status, error){
        console.log(error);
    }
});

//Listen for a "request-for-help" event
socket.on("request-for-help", function(eventData){
    //Once request is received, do this:
    
    //Save request details
    requestDetails = eventData; //Contains info of citizen
    
    //display the data received from the event
    document.getElementById("notification").innerHTML = "Someone's being attacked by a wildling! \n" + JSON.stringify(requestDetails);
});

Если вы перезагрузите сервер и перейдите в http://localhost: 8000/cop.html? userId = 02 , (Передача UserID сохраненного полицейского в параметрах запроса), вы найдете информацию КС, отображаемую на странице. Ваша страница Cop также начала слушать любой Запрос – оправдание События.

Внутри гражданина.html.

Следующим шагом является создание кнопки для граждан, который можно нажать в случае чрезвычайной ситуации. После нажатия он будет стрелять Запрос – оправдание Сигнал и сигнал могут нести информацию о том, чтобы вернуться к ответственности граждан к серверу:

Напишите обработчик для генерации события в Сценарий ярлык:

//Citizen's info
requestDetails = {
    citizenId: userId,
    location: {
        address: "Indiranagar, Bengaluru, Karnataka 560038, India",
        latitude: 12.9718915,
        longitude: 77.64115449999997
    }
}

//When button is clicked, fire request-for-help and send citizen's userId and location
function requestForHelp(){
    socket.emit("request-for-help", requestDetails);
}
  • Наконец, сервер должен обрабатывать это событие, как показано на рисунке. Перейти к db-options.js и создать новую функцию, которая может быть использована для сохранения данных запроса в новой таблице requestsdata :
//Saves details like citizen's location, time
function saveRequest(db, issueId, requestTime, location, citizenId, status, callback){

    db.collection('requestsData').insert({
        "_id": issueId,
        "requestTime": requestTime,
        "location": location,
        "citizenId": citizenId,
        "status": status
    }, function(err, results){
           if(err) {
               console.log(err);
           }else{
               callback(results);
           }
    });
}
exports.saveRequest = saveRequest;

Статус Поле скажет, ответил ли полицейский на запрос или нет. Наконец, в Marals.js, Добавьте это внутри инициализировать Функция:

//Listen to a 'request-for-help' event from connected citizens
socket.on('request-for-help', function(eventData) {
    /*
        eventData contains userId and location
        1. First save the request details inside a table requestsData
        2. AFTER saving, fetch nearby cops from citizen's location
        3. Fire a request-for-help event to each of the cop's room
    */

    var requestTime = new Date(); //Time of the request

    var ObjectID = require('mongodb').ObjectID;
    var requestId = new ObjectID; //Generate unique ID for the request

    //1. First save the request details inside a table requestsData.
    //Convert latitude and longitude to [longitude, latitude]
    var location = {
        coordinates: [
            eventData.location.longitude,
            eventData.location.latitude
        ],
        address: eventData.location.address
    };
    dbOperations.saveRequest(db, requestId, requestTime, location, eventData.citizenId, 'waiting', function(results) {

        //2. AFTER saving, fetch nearby cops from citizen's location
        dbOperations.fetchNearestCops(db, location.coordinates, function(results) {
            eventData.requestId = requestId;
            //3. After fetching nearest cops, fire a 'request-for-help' event to each of them
            for (var i = 0; i < results.length; i++) {
                io.sockets.in(results[i].userId).emit('request-for-help', eventData);
            }
        });
    });
});

Вот и все, вы построили первый набор функций! Перезапустите сервер и проверим это, открывая 4 вкладка, по одному для страниц гражданина и копья 01 , 02 и 03 Отказ

Как только вы нажмете кнопку «Справка», вы заметите, что КС 01 Не получает запрос, потому что этот полицейский далеко от местонахождения гражданина. Однако КС 02 и КС 03 Страницы показывают запрос справки.

Потрясающе, вам удалось отправить запрос от гражданина и уведомить всех близлежащих полицейских! Теперь для второго набора особенностей – это включает уведомление гражданина после того, как полицейский принимает запрос.

Принятие запроса и уведомление гражданина

Внутри COP.HTML

КС должен иметь возможность щелкнуть кнопку для информирования гражданина, что запрос был принят. При нажатии, эта кнопка будет стрелять Запрос принимается Событие, а также отправьте поддержку информации КС к серверу:

И обработчик событий будет выглядеть так:

function helpCitizen(){
    //Fire a "request-accepted" event/signal and send relevant info back to server
    socket.emit("request-accepted", {
        requestDetails: requestDetails,
        copDetails: copDetails
    });
 }

Внутри гражданина.html.

Страница гражданина начнет слушать любой Запрос принимается События с сервера. Как только он получает сигнал, вы можете отобразить информацию КС внутри пустой Div :

//Listen for a "request-accepted" event
socket.on("request-accepted", function(eventData){
    copDetails = data; //Save cop details

   //Display Cop details
    document.getElementById("notification").innerHTML = "A cop is coming to your rescue! \n" + JSON.stringify(copDetails);
});

Теперь сервер должен обрабатывать Запрос принимается событие, как показано на рисунке. Сначала вы напишите функцию в DB-Operations.js. Это будет обновлять запрос в базе данных с помощью Cop userid и изменить Статус поле из Ожидание к заниматься :

function updateRequest(db, requestId, copId, status, callback) {
    db.collection('requestsData').update({
        "_id": requestId //Perform update for the given requestId
    }, {
        $set: {
            "status": status, //Update status to 'engaged'
            "copId": copId  //save cop's userId
        }
    }, function(err, results) {
        if (err) {
            console.log(err);
        } else {
            callback("Issue updated")
        }
    });
}
exports.updateRequest = updateRequest;

Когда сервер слушает Запрос принимается Событие, это будет использовать приведенную выше функцию для сохранения данных запроса, а затем выделяют Запрос принимается мероприятие для гражданина. Так что идите вперед, напишите это в твоем Marross.js файл:

//Listen to a 'request-accepted' event from connected cops
socket.on('request-accepted', function(eventData){

    //Convert string to MongoDb's ObjectId data-type
    var ObjectID = require('mongodb').ObjectID;
    var requestId = new ObjectID(eventData.requestDetails.requestId);
    //For the request with requestId, update request details
    dbOperations.updateRequest(db, requestId, eventData.copDetails.copId, 'engaged', function(results){
                               
       //Fire a 'request-accepted' event to the citizen and send cop details
    io.sockets.in(eventData.requestDetails.citizenId).emit('request-accepted', eventData.copDetails);
       });
 
 });

Отлично, вы построили готовое здание второго набора функций! Перезапустите свой сервер, обновите свои страницы и попробуйте!

Что дальше?

К настоящему времени это могло бы стать очевидным для вас – страница гражданина отправляет жесткокодируемое значение радости каждый раз, когда нажата кнопка для справки. Точно так же информация о местоположении для всех ваших образцов полицейских уже подана в базу данных ранее и являются фиксированными значениями.

Однако в реальном мире и гражданин и КС не имеют фиксированного местоположения, потому что они продолжают двигаться, и поэтому вам понадобится способ проверить это поведение!

Введите карты

Там есть много вариантов картирования. API Google Maps очень надежны и богатыми. Я лично люблю mapbox тоже, он использует протоколы OpenStreetMap под капотом, а вот самая лучшая часть – это открытый источник и чрезвычайно настраивается! Итак, давайте будем использовать это для создания остальной части вашего приложения.

Используя API MapBox

  • Чтобы начать использовать эти API, вам необходимо сначала создать учетную запись на MapBox и получить ключ аутентификации здесь . В зависимости от ваших потребностей, MapBox предлагает разные планы ценообразования Чтобы использовать эти API в ваших приложениях – на данный момент бесплатный стартовый план достаточно.
  • Далее вы будете загружаться mapbox.js Библиотека (текущая версия 2.4.0) как на страницах, используя тег скрипта. Он построен на вершине Листовка (Еще одна библиотека JavaScript).

Вы также загрузите таблицу стилей, используемые MapBox.js внутри голова Тег вашего HTML:

Как только вы сделали это, пришло время для вас начать писать логику –

  • Сначала загрузите карту и установите его, чтобы показать некоторое местоположение по умолчанию
  • Показать маркер на карте
  • Используйте функцию автозаполнения, предлагаемой API MapBox Geocoder. Это позволяет вам вводить для места и выбрать из автозаполнения предложений. После выбора места вы можете извлечь информацию о месте и делать все, что вы хотите с этим.

Листовка открывает все это API внутри глобальной переменной L. С mapbox.js построен на вершине листовки, API, которые вы собираетесь использовать, также будут выставлены в глобальном Л Переменная.

  • В Citizen.html Напишите это в вашем JavaScript
L.mapbox.accessToken = "YOUR_API_KEY";

//Load the map and give it a default style
map = L.mapbox.map("map", "mapbox.streets");

//set it to a given lat-lng and zoom level
map.setView([12.9718915, 77.64115449999997], 9);

//Display a default marker
marker = L.marker([12.9718915, 77.64115449999997]).addTo(map);

//This will display an input box
map.addControl(L.mapbox.geocoderControl("mapbox.places", {
    autocomplete: true, //will suggest for places as you type
}).on("select", function(data){
    //This function runs when a place is selected

    //data contains the geocoding results
    console.log(data);

    //Do something with the results
    //Extract address and coordinates from the results and save it
    requestDetails.location = {
        address: data.feature["place_name"],
        latitude: data.feature.center[1],
        longitude: data.feature.center[0]
    };

    //Set the marker to new location
    marker.setLatLng( [data.feature.center[1], data.feature.center[0]]);
}));

Приведенный выше код извлекает информацию о месте, как только вы выберете место и обновляем детали местоположения, поэтому в следующий раз, когда вы нажмете Помогите Кнопка, вы отправите новое место вместе с вашим запросом.

Как только COP принимает запрос, вы можете показать расположение полицейского с помощью пользовательского маркера. Сначала сохраните Это изображение внутри /public/Изображения Затем напишите этот код внутри обработчика событий Запрос принимается мероприятие:

//Show cop location on the map
L.marker([
    copDetails.location.latitude,
    copDetails.location.longitude
],{
    icon: L.icon({
        iconUrl: "/images/police.png", //image path
        iconSize: [60, 28] //in pixels
    })
}).addTo(map);

Вот и все! Теперь давайте повторю то же самое для страницы COP, а также внутри Cop.html Отказ

Страница вашего полицейского извлекает информацию о местоположении COP с сервера, используя AJAX, поэтому все, что вам нужно сделать, это установить карту и маркер, чтобы указать на него. Давайте напишем этот код внутри Успех Обратный вызов вашей функции Ajax:

L.mapbox.accessToken = "YOUR_API_KEY";

//Load the map and give it a default style
map = L.mapbox.map("map", "mapbox.streets");

//set it to a cop's lat-lng and zoom level
map.setView( [copDetails.location.latitude, copDetails.location.longitude ], 9);

//Display a default marker
marker = L.marker([copDetails.location.latitude, copDetails.location.longitude]).addTo(map);

//This will display an input box
map.addControl(L.mapbox.geocoderControl("mapbox.places", {
    autocomplete: true, //will suggest for places as you type
}).on("select", function(data){
    //This function runs when a place is selected
    
    //data contains the geocoding results
    console.log(data);
    
    //Do something with the results
    
    //Set the marker to new location
    marker.setLatLng([
        data.feature.center[1],
        data.feature.center[0]
    ]);
}));

Как только COP получит запрос, вы можете использовать пользовательский маркер для отображения местоположения гражданина. Скачать Маркер изображения и сохранить его в /public/Изображения. Далее, давайте напишем логику внутри обработчика событий вашего Запрос – оправдание мероприятие:

//Show citizen location on the map
L.marker([
    requestDetails.location.latitude,
    requestDetails.location.longitude
],{
    icon: L.icon({
       iconUrl: "/images/citizen.png",
       iconSize: [50,50]
    })
}).addTo(map);

Cool, давайте попробуем это – открыть страницы COP 04 , 05. и 06 Отказ На странице гражданина типа ” форум бенгалуру”, Выберите первый результат и посмотрите приложение в действии, когда вы просите помощи!

Визуализация данных

Люди любят визуализацию данных. Это поможет вам лучше понять определенную тему. Например, в метрической системе я не совсем осознал, насколько велик действительно гигамметр, но я понял его лучше после того, как увидел эту картину:

В отличие от компьютеров, люди очень легко не понимают числа, выложенные на электронные таблицы – чем больше, чем набор данных, тем сложнее становится для нас, чтобы определить любые значимые узоры. Лот значимой информации может пойти незамеченной, просто потому, что человеческий мозг не обучен налить большим количеством таблиц, заполненных текстом и цифрами.

Намного проще обработать информацию и определить шаблоны, если данные могут быть визуализированы. Есть много способов сделать это, в виде графов, диаграмм и т. Д. И есть несколько библиотек, которые позволяют делать эти вещи на экране.

На данный момент я предполагаю, что вы, вероятно, играли с вашим приложением немного и сохраненные запросы справки в MongoDB. Если нет, вы можете Скачать Набор данных, а затем импортировать его в базу данных, набрав это в своем терминале:

mongoimport --db myUberApp --collection requestsData --drop --file ./path/to/jsonfile.json

Как вы уже знаете, сохраненные запросы содержат полезную информацию, такую как Расположение Детали, Статус Поле, которое указывает, получил ли гражданин помощи или нет, и так далее. Идеально подходит для использования этой информации для визуализации данных преступности на тепловой карте! Вот и Пример от mapbox.

Я собираюсь использовать Mapbox GL JS. – Это библиотека, которая использует WebGL, чтобы помочь визуализировать данные внутри карты и сделать их очень интерактивными. Это чрезвычайно настраивается – с особенностями, такими как цвета, переходы и освещение. Не стесняйтесь попробовать свои собственные стили позже!

Для функции тепловой карты библиотека принимает наборы данных в формате Geojson, а затем сюжет точек данных на карте. Геойсон это формат для кодирования различных структур географических данных. Следовательно, вам необходимо преобразовать ваши сохраненные данные, чтобы придерживаться этого формата.

Итак, вот следующие шаги:

  1. Конечная точка для обслуживания вашей визуализации страницы data.html.
  2. Далее есть конечная точка – /Запросы/Информация Это извлекает ваши запросы от Mongodb, преобразует их в формат Geojson и возвращает их клиенту.
  3. Создать страницу data.html. Это загружает библиотеку визуализации и таблицу стилей.
  4. Использование AJAX, извлеките данные, установленные из MongOdb и создайте тепловую карту!

Шаг 1:

Открыть app.js, И напишите этот код для обслуживания страницы визуализации:

app.get('/data.html', function(req, res) {
    res.render('data.html');
});

Шаг 2:

Давайте напишем функцию в db-options.js что выбирает все результаты ваших requestsdata стол:

function fetchRequests(db, callback) {
    var collection = db.collection('requestsData');
    //Using stream to process potentially huge records
    var stream = collection.find({}, {
        requestTime: true,
        status: true,
        location: true
    }).stream();
    
    var requestsData = [];
    
    stream.on('data', function(request) {
        requestsData.push(request);
    });
    
    //Runs after results are fetched
    stream.on('end', function() {
        callback(requestsData);
    });
}
exports.fetchRequests = fetchRequests;

В приведенном выше коде вы запрашиваете requestsdata Таблица, чтобы вернуть все документы. Вы можете указать, какие поля включают и исключите из результатов с использованием логических значений – правда включить поле и ложь исключить поле. Результаты затем возвращаются обратно в функцию обратного вызова.

Как выглядит Geojson?

Информация, хранящаяся в Geojson, имеет следующий формат:

{
    type: "FeatureCollection",
    features: [
        {
             type: "Feature",
             geometry: {
                 type: "Point",
                 coordinates: [, ]
             },
             properties: {
                 : ,
                 : ,
                        ...
             }
        }
        ...
    ]
}

Вам нужно будет преобразовать каждый объект, возвращаемый вашей функцией в объекты функции. свойства Поле может удерживать дополнительные мета-данные, такие как Статус, время запроса, адрес и т.п. Вы напишите ручку в Marross.js Это позвонит функции, преобразуйте его в Geojson, а затем верните его назад:

app.get('/requests/info', function(req, res){
    dbOperations.fetchRequests(db, function(results){
        var features = [];
        
        for(var i=0; i

Шаг 3:

Создать страницу data.html В вашем Виды Папка и загрузить таблицу стилей и библиотеку для визуализации:






    
    Visualize Data
    




    

Теперь вы будете использовать AJAX, чтобы позвонить в вашу конечную точку и получить данные Geojson:

$.ajax({
    url: "/requests/info",
    type: "GET",
    dataType: "json",
    
    success: function(data) {
        console.log(data);
    }
    error: function(httpRequest, status, error) {
        console.log(error);
    }
});

Cool – Сохраните свой код, перезапустите свой сервер и укажите браузер на http://localhost:8000/data.html . Вы увидите результаты вашего вызова AJAX в консоли.

Теперь давайте будем использовать его для создания тепловой карты. Напишите это внутри Успех Обратный вызов вашего звонка AJAX:

var map = new mapboxgl.Map({
    container: "map",
    style: "mapbox://styles/mapbox/dark-v9",
    center: [77.64115449999997, 12.9718915],
    zoom: 10
});

map.on("load", function() {
    
    //Add a new source from our GeoJSON data
    map.addSource("help-requests", {
       type: "geojson",
       data: data
    });
    
//we can specify different color and styling formats by adding different layers
    
    map.addLayer({
        "id": "help-requests",
        "type": "circle",
        "source": "help-requests",
        "paint": {
        //Apply a different color to different status fields
            "circle-color": {
                property: "status",
                type: "categorical",
                stops: [
                    //For waiting, show in red
                    ["waiting", "rgba(255,0,0,0.5)"],
                    
                    //For engaged, show in green
                    ["engaged", "rgba(0,255,0,0.5)"]
                ]
            },
            "circle-radius": 20, //Radius of the circle
            "circle-blur": 1 //Amount of blur
        }
    });
});

Обновите свою страницу, чтобы увидеть прохладный вид тепломапа, генерируемый из вашего набора данных!

Заключение

Если вы сделали это так далеко, поздравляемся! Надеюсь, что этот учебник серии дал вам представление о том, как создать веб-приложение в реальном времени с легкостью – все, что теперь нужно, это следующая большая идея!

Я уверен, что вы знаете, что в приложении все еще есть много мест, которые вы просто построили. Вы можете попробовать добавить больше возможностей для него и сделать его более «интеллектуальным», например:

  • Имимирует движущийся полицейский и движущийся гражданин, который постоянно отправляет обновления местоположения друг на друга в режиме реального времени и обновлять значки маркеров на карте.
  • Установите Статус поле до закрыто Как только КС поможет гражданину. Затем вы можете назначить другой цвет для визуализации замкнутых проблем на тепловой карте. Таким образом, у вас будет понимание того, насколько эффективными полицейскими являются в данной области.
  • Создайте рейтинговую систему, с которой гражданин и полицейский могут оценивать друг друга. Таким образом, ни один гражданин, ни полицейский не злоупотребляют систему, и полицейские могут получить отчеты о производительности.
  • Удально прохладно выглядящий пользовательский интерфейс, как материал UI.
  • Наконец, есть механизм регистрации и входа в систему!

Использование библиотеки, такой как ReCv или Alloy Angular, может помочь вам реализовывать функции прочными и масштабируемыми способами. Вы также можете экспериментировать с библиотеками Charting, такие как D3.js, чтобы визуализировать информацию в виде бар-диаграмм, пирожных графиков, линейных диаграмм и т. Д.

В какой-то момент вы можете развернуть свое приложение на поставщике услуг облачного хостинга – например, Amazon Web Services или платформу Google Cloud, чтобы показать людям, что вы сделали, и у них тестируются функции. Это будет хороший способ получить обратную связь и идеи, а кто знает – ваше приложение может оказаться спасателем жизни когда-нибудь!

Спасибо за чтение.

Рекомендую это, если это поможет вам. В случае, если у вас есть вопросы по любому аспекту этой учебной серии или нужна моя помощь в понимании чего-либо, не стесняйтесь чирикать или оставить комментарий здесь Отказ Я хотел бы услышать о вашем Uber-for-X Идеи! Вы можете прочитать больше таких статей в моем Технический блог тоже.

И вот что вы ждали, полный исходный код!

Понравилось то, что вы читаете? Вы должны подписаться. Я не буду тратить свое время.

Проверьте мою страницу Патреона! Стать покровителем!

Оригинал: “https://www.freecodecamp.org/news/how-to-build-your-own-uber-for-x-app-part-2-8ba6ffa2573d/”