First commit
This commit is contained in:
commit
53ae3e2998
8 changed files with 1551 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
.env
|
43
README.md
Normal file
43
README.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# GPS Tracker
|
||||||
|
|
||||||
|
A web interface to render GPS data points stored in a PostgreSQL database on a map.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/yourusername/gps-tracker.git
|
||||||
|
cd gps-tracker
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install dependencies:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Create a `.env` file with the following content:
|
||||||
|
```env
|
||||||
|
DATABASE_URL=postgres://username:password@localhost:5432/gpstracker
|
||||||
|
PORT=3000
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Create the `gps_data` table in your PostgreSQL database:
|
||||||
|
```sql
|
||||||
|
CREATE TABLE gps_data (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
latitude FLOAT NOT NULL,
|
||||||
|
longitude FLOAT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Start the server:
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Open your browser and navigate to `http://localhost:3000`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add your GPS data points to the PostgreSQL ▋
|
56
app.js
Normal file
56
app.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
const express = require('express');
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
const { Sequelize, DataTypes } = require('sequelize');
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const port = process.env.PORT || 3000;
|
||||||
|
|
||||||
|
// PostgreSQL connection using Sequelize
|
||||||
|
const sequelize = new Sequelize(process.env.DATABASE_URL, {
|
||||||
|
dialect: 'postgres',
|
||||||
|
logging: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define GPS model
|
||||||
|
const GpsData = sequelize.define('GpsData', {
|
||||||
|
latitude: {
|
||||||
|
type: DataTypes.FLOAT,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
longitude: {
|
||||||
|
type: DataTypes.FLOAT,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
defaultValue: DataTypes.NOW
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
tableName: 'location_history',
|
||||||
|
timestamps: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Middleware
|
||||||
|
app.use(express.static('public'));
|
||||||
|
app.set('view engine', 'ejs');
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
app.get('/', async (req, res) => {
|
||||||
|
res.render('index')
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/get', async (req, res) => {
|
||||||
|
const apiResponse = await GpsData.findAll({
|
||||||
|
limit: 1000,
|
||||||
|
offset: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const gpsData = apiResponse.map((p) => p.dataValues);
|
||||||
|
res.json(gpsData);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Server is running on port ${port}`);
|
||||||
|
});
|
1390
package-lock.json
generated
Normal file
1390
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
16
package.json
Normal file
16
package.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "gps-tracker",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A web interface to render GPS data points on a map",
|
||||||
|
"main": "app.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node app.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
|
"ejs": "^3.1.6",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"pg": "^8.7.1",
|
||||||
|
"sequelize": "^6.6.5"
|
||||||
|
}
|
||||||
|
}
|
3
public/css/styles.css
Normal file
3
public/css/styles.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#map {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
26
public/js/main.js
Normal file
26
public/js/main.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
async function getGpsData() {
|
||||||
|
return await fetch('/get')
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const map = L.map('map').setView([0, 0], 2);
|
||||||
|
|
||||||
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
|
getGpsData().then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Response status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.json().then((gpsData) => {
|
||||||
|
console.log(gpsData);
|
||||||
|
gpsData.forEach(point => {
|
||||||
|
L.marker([point.latitude, point.longitude]).addTo(map)
|
||||||
|
.bindPopup(`Latitude: ${point.latitude}, Longitude: ${point.longitude}`)
|
||||||
|
.openPopup();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
15
views/index.ejs
Normal file
15
views/index.ejs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>GPS Tracker</title>
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
|
||||||
|
<link rel="stylesheet" href="/css/styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="map"></div>
|
||||||
|
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||||
|
<script src="/js/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Reference in a new issue