I have a Geojson file which name is countries.geojson.
I can read this file with get method. I want to create PBF files from this GeoJSON file. How can I do that?
var express = require("express");
const fs = require('fs');
var Pbf = require('pbf');
var protobuf = require('protocol-buffers')
const path = require('path');
var app = express();
app.get("/get/data", (req, res, next) => {
fs.readFile('data/countries.geojson', (err, data) => {
if (err) throw err;
let country = JSON.parse(data);
res.send(country);
});
});
app.get("/", (req, res, next) => {
// Create PBF file
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
To encode, use the example provided by Horatio Jeflea in that answer.
To decode, as in using the response in a web browser, use something like this or (more modernly, the fetch lib).
var xmlhttp = new XMLHttpRequest();
// Get the encoded geobuf file
xmlhttp.open("GET", "http://<somedomain>/uscty.pbf", true);
xmlhttp.responseType = "arraybuffer"; // important to know what the data type is
xmlhttp.onload = function () {
// convert the raw response to a pbf
var pbf = new Pbf(new Uint8Array(xmlhttp.response));
// use geobuf lib to decode it to GeoJSON
var decoded = geobuf.decode(pbf);
console.log("Decoded GeoJSON", decoded);
};
xmlhttp.send();
Use geobuf library:
var buffer = geobuf.encode(geojson, new Pbf());
Related
Here is my frontend JS. As a side note, FormData.append() does not work, so I have to set its properties explicitly. #data is an object with input name: value properties.
function http(data) {
const httpData = new FormData();
for (let prop in data) {
httpData[prop] = data[prop];
}
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4) {
const status = this.status;
const data = this.responseText;
}
};
xhttp.open('POST', '/api/login');
xhttp.setRequestHeader('Content-Type', 'x-www-form-urlencoded');
xhttp.send(httpData);
}
And on the server side
app.use(express.urlencoded({
extended: true
}));
express ready to parse form data, and in the /routes/api.js ( I am using express router )
router.post('/login', (req, res, next) => {
console.log(req.body);
res.end();
});
I got req.body as an {}
Where did I fuck up ?
Here is the working code, courtesy of #Quentin, frontend
function http(data) {
const httpData = new FormData();
for (let prop in data) {
httpData.append(prop, data[prop]);
}
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4) {
const status = this.status;
const data = this.responseText;
}
};
xhttp.open('POST', '/api/login');
xhttp.send(httpData);
}
and backend in /routes/api.js
const formidable = require('formidable');
router.post('/login', (req, res, next) => {
const form = formidable({ multiples: true });
form.parse(req, (err, fields, files) => {
console.log(fields);
res.end();
});
});
You have three problems.
append() does work. It just doesn't store the data in a way that shows up with console.log. Assigning arbitrary properties doesn't work.
You need to send the correct Content-Type header. This is multipart/form-data with a mandatory boundary parameter that you have no way of knowing. Don't try to set the Content-Type header manually. XMLHttpRequest will generate it automatically from the FormData object.
You need a body parser for Express that supports multipart/form-data. The built-in one does not. The documentation for it on npm suggests 4 alternatives.
I have this problem because I am sending data via JavaScript using XMLHttpRequest but not receiving it in node.js express post method. I don't know what I'm doing wrong.
My script - funcion form execute on window load
function form() {
const btn = document.getElementById("save-data");
let currentPage = window.location.href.split("/").at(-1);
function sendData(data) {
const XHR = new XMLHttpRequest();
XHR.open("POST", window.location.href);
XHR.setRequestHeader("Content-Type", "application/json");
console.log(data); // I get right data
XHR.send(data);
}
btn.addEventListener("click", () => {
switch (currentPage) {
case "settings":
const prefix = document.getElementById("prefix").value;
let buttonState = document.getElementById("module-state");
if (buttonState.hasAttribute("enable")) {
buttonState = "enable";
} else {
buttonState = "disable";
}
sendData({
prefix: prefix,
buttonState: buttonState,
announcements: {
giveawayChannelID: 123,
updateChannelID: 123,
},
});
}
});
}
My Node.js code
router.post('/:id/settings', (req, res) => {
console.log(req.body) // {}
})
Pleas help.
You need to install body-parser package by NPM, and require it in your code
Try
npm i body-parser
Then in your main node script, require it
const bodyParser = require('body-parser');
after that, you should set it as a middleware for express
app.use(bodyParser.json()); //Handles JSON requests
app.use(bodyParser.urlencoded({ extended: false })); //Handles normal post requests
after these steps, you can access values like req.body.value
I'm using n-readline npm package to read text files from the server.
I have a use case, where I had to read at least 300MB of data from those text files and will be using Redis or Mongoose to save around 40mb of data to be transferred to the browser where I use vue to process that or load data whenever needed.
Now I'm running into a problem where I'm unable to get the results when I call that function for the first time, if I call that again, the function provides me with results.
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const NreadLine = require('n-readline');
const app = express();
var asyncres = [];
var lines = []
const upload = multer({ storage });
async function nreadline(){
let linenumbers = [];
var rl = new NreadLine({
filepath: './uploads/6789765/serverout1.txt',
limit: 50
});
await rl.start();
await rl.on('line', (line, linenumer) => {
linenumbers.push(linenumer);
});
await rl.on('end', () => {
console.log('done');
asyncres = [...linenumbers];
});
//This is where I'm expecting the results to be returned
return asyncres;
}
function getresults() {
let ress = nreadline();
console.log(ress);
return ress;
}
// Express APIs defined below
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ "status": "success", file: req.file });
});
// API for multiple form upload
app.post('/multiple', upload.array('files'), (req, res) => {
// ticket = req.body.ticket
res.json({ "status": "success", files: req.files });
});
//Get Request for reading the files
app.get('/reader', (req, res) => {
let results = getresults();
res.json({ "status": results });
});
app.listen(port, () => {
console.log("running on 3344 port");
});
Please Help. I am not sure what I'm doing wrong.
To answer my own question, I found another npm package, that kinda solves my problem.
The package name is n-readlines and below the code that I modified.
const lineByLine = require('n-readlines');
function nreadline(filePath){
let logs = [];
try{
let rl = new lineByLine('./uploads/6789765/serverout0.txt');
let line;
while(line=rl.next()){
logs.push(line.toString('utf8'));
}
return logs;
}catch(err){
}
I'm using request-promise to request two JSON data files which exist locally in my local project directory folder.
ie:
However, I am getting a 500 internal server error, when trying to pass the data to the view and my node console outputs 'Error: Invalid URI "/"',
Please see below:
server.js
let express = require('express');
let app = express();
let path = require('path');
const rp = require("request-promise");
//STORE PATH for local JSON files on variables
let guest = require('./public/data/Companies');
let hotel = require('./public/data/Guests');
app.set("port", process.env.PORT || 5000);
//GET JSON
//Question: Is it okay to pass uri:guest
app.get('/data', function(req, res) {
Promise.all([rp({uri: guest, json: true}), rp({uri: hotel, json: true})]).then(function([hotels, guests]) {
//res.json({hotels, guests});
res.send({hotels, guests});
console.log(hotels, guests);
}).catch(function(err) {
console.log(err);
res.status(500).end();
});
});
//CATCHALL
app.get("/*", function(req,res){
let file = req.params[0] || "/views/index.html";
res.sendFile(path.join(__dirname, "/public/", file));
});
//SET PORT
app.listen(app.get("port"), function(){
console.log("Listening on port: " , app.get("port"));
});
then on client.js:
$(function() {
$.ajax({
type: "GET",
url: "/data",
success: function (res) {
console.log(res);
}
});
});
Why do you use request to get the data? Why don't you use the filesystem module from Node.js (fs) to get the data? When you call rp(), you should pass an absolute URI and not a local path.
To use it in your code, you need to "promisify" the readFile function:
let readFileAsAPromise = function(filename){
return new Promise(function(resolve, reject) {
fs.readFile(filename, (data, err) => {
if(err) reject(err);
resolve(data)
})
})
}
You can then you Promise.all.
Why aren't you simply returning the variables?
I mean:
app.get('/data', function(req, res) {
res.send({hotels, guests});
});
I'm trying to upload an image to a Node JS from a PCL Xamarin forms library. I've tried using the Multer Node JS library to pick up the the POST request. The request is received, however the photo is not saved. The file is always 'undefined'.
Node JS code:
var formidable = require('formidable');
var util = require('util');
var fs = require('fs');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './photouploads');
},
filename: function (req, file, callback) {
console.log(file.fieldname);
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage: storage }).single('image');
exports.post = function (req, res) {
console.log("Photo Api Hit");
upload(req, res, function (err) {
console.log(req.file);
if (err) {
console.log("error");
console.log(err);
return res.end("Error uploading file.");
}
console.log("File has been received");
res.end("File is uploaded");
});
};
C#/Xamarin Code
using Plugin.Media.Abstractions;
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
namespace Vigour.Controllers
{
class MediaController
{
public static void upload(MediaFile mediaFile)
{
try
{
StreamContent scontent = new StreamContent(mediaFile.GetStream());
scontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "newimage",
Name = "image"
};
scontent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var client = new HttpClient();
client.BaseAddress = new Uri(Constants.API_ROOT_URL);
var result = client.PostAsync("api/photo", scontent).Result;
Debug.WriteLine(result.ReasonPhrase);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
}
}
Does anyone know how the request should be formed in my C# code? Thanks
I found that using this method was effective for a PCL
The MediaFile is an object from the Xamarin.Plugins.Media Library
public static void upload(MediaFile mediaFile)
{
try
{
StreamContent scontent = new StreamContent(mediaFile.GetStream());
scontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "newimage",
Name = "image"
};
scontent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var client = new HttpClient();
var multi = new MultipartFormDataContent();
multi.Add(scontent);
client.BaseAddress = new Uri(Constants.API_ROOT_URL);
var result = client.PostAsync("api/photo", multi).Result;
Debug.WriteLine(result.ReasonPhrase);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
I used node js (hosted on azure) to receive the request.
var formidable = require('formidable');
var util = require('util');
var fs = require('fs');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
console.log(file.fieldname);
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage: storage }).single('image');
exports.post = function (req, res) {
console.log("Photo Api Hit");
upload(req, res, function (err) {
console.log(req.file);
if (err) {
console.log("Photo API ERROR: "+err);
return res.end("Error uploading file.");
}
console.log("SUCCESS");
res.end("File is uploaded");
});
};