I have a string with a list of polygon coordinates in the following format:
var myString = "(38.35870116756209, 38.27089903372614),(38.3339292947434, 38.2743322612652),(38.33944984782068, 38.3017980815777),(38.35829734627614, 38.297678208530826)";
I want to convert that string to an array with lat / lng coordinates, like this:
const polygonCoords = [
{ lat: 38.35870116756209, lng: 38.27089903372614 },
{ lat: 38.3339292947434, lng: 38.2743322612652 },
{ lat: 38.33944984782068, lng: 38.3017980815777 },
{ lat: 38.35829734627614, lng: 38.297678208530826 },
{ lat: 38.35870116756209, lng: 38.27089903372614 } // first coordinate again
];
How can I do this?
CodePudding user response:
myString.split('),').map(x => x.replace(/[\n/(\)\ ]/g,'')).map(x => {
let [lat, lng] = x.split(', ');
return {lat, lng}
})
CodePudding user response:
You can do something like this
const string = "(38.35870116756209, 38.27089903372614),(38.3339292947434, 38.2743322612652),(38.33944984782068, 38.3017980815777),(38.35829734627614, 38.297678208530826)"
const coordinates = string.substring(1, string.length - 1).split('),(').map(s => {
const [lat, lng] = s.split(', ').map(Number)
return {lat, lng}
})
console.log(coordinates)
CodePudding user response:
You can do it using basic JavaScript array methods like this:
var myString = "(38.35870116756209, 38.27089903372614), \
(38.3339292947434, 38.2743322612652), \
(38.33944984782068, 38.3017980815777), \
(38.35829734627614, 38.297678208530826)"
const strArray = myString.split(', ') // Note the whitespace after the comma
let left = [];
let right = [];
strArray.forEach(str => {
if(str[0] === '(') {
left.push(str.substr(1, str.length -1))
}
if (str[str.length - 1] === ')') {
right.push(str.substr(0, str.length -2))
}
})
let polygonCoords = [];
if(left.length === right.length) {
for(let i = 0, n = left.length; i < n; i ) {
polygonCoords.push({
lat: left[i],
lng: right[i]
})
}
}
console.log(polygonCoords)
CodePudding user response:
In addition to the other provided answers, I wanted to add one that makes use of the named matching groups:
const str = "(38.35870116756209, 38.27089903372614),(38.3339292947434, 38.2743322612652),(38.33944984782068, 38.3017980815777),(38.35829734627614, 38.297678208530826)"
const result = str.match(/\(.*?\)/g)
.map(res => res.match(/((?<lat>[\d.]*), (?<lon>[\d.]*)\))/).groups)
console.log(result)
CodePudding user response:
Try using regular expressions, it's a powerful tool!
To simplify the task I removed the const access modifier from polygonCoords but you can always change it later in your code. Here's my solution:
String with data:
var coords="(38.35870116756209, 38.27089903372614),(38.3339292947434, 38.2743322612652),(38.33944984782068, 38.3017980815777),(38.35829734627614, 38.297678208530826)"
here goes the conversion
coords=coords.match(/[^(),] /g) //making a list of separate elements and removing commas and brackets
var polygonCoords=[]
for(var i=0;i<coords.length;i =2){
polygonCoords.push( {lat:coords[i], lng:coords[i 1]} )
}
//creating objects with our data and putting them in polygonCoords
As output it gives me : output
Output of polygonCoords:
0: {lat: '38.35870116756209', lng: ' 38.27089903372614'}
1: {lat: '38.3339292947434', lng: ' 38.2743322612652'}
2: {lat: '38.33944984782068', lng: ' 38.3017980815777'}
3: {lat: '38.35829734627614', lng: ' 38.297678208530826'}
I hope it helps
CodePudding user response:
IMO the most elegant way to approach this problem, is to...
- use String.prototype.replaceAll() to convert your string format into a JSON-compatible 2-dimensional array string
- use JSON.parse() to convert your array string to an actual array
- use Array.prototype.map() to convert your array to the desired format
- use Array.prototype.push() to duplicate a reference to the first coordinate and append
Working demo
var myString = "(38.35870116756209, 38.27089903372614),(38.3339292947434, 38.2743322612652),(38.33944984782068, 38.3017980815777),(38.35829734627614, 38.297678208530826)";
// 1. Convert string format to 2-dimensional array
myString = '[' myString.replaceAll('(', '[').replaceAll(')', ']') ']';
// 2. Parse array
const myArray = JSON.parse(myString);
// 3. Convert array format to polygonCoords
const polygonCoords = myArray.map(v => ({lat: v[0], lng: v[1]}));
// 4. Duplicate reference to first coordinate and append
polygonCoords.push(polygonCoords[0]);
console.log("OUTPUT :");
console.log(polygonCoords);
console.log("NUMBER OF COORDINATES :");
console.log(polygonCoords.length);
Or, if you prefer minimal code over readability, you can combine the first 3 statements, like this :
var myString = "(38.35870116756209, 38.27089903372614),(38.3339292947434, 38.2743322612652),(38.33944984782068, 38.3017980815777),(38.35829734627614, 38.297678208530826)";
// Convert string to polygonCoords
const polygonCoords = JSON.parse('[' myString.replaceAll('(', '[').replaceAll(')', ']') ']')
.map(v => ({lat: v[0], lng: v[1]}));
// Duplicate reference to first coordinate and append
polygonCoords.push(polygonCoords[0]);
console.log("OUTPUT :");
console.log(polygonCoords);
console.log("NUMBER OF COORDINATES :");
console.log(polygonCoords.length);
Note
polygonCoords.push(polygonCoords[0])
does not actually duplicate the first coordinate object itself. Instead it copies a reference to the same object. So, if you change the values of coordinate polygonCoords[0]
, you also change the values of coordinate polygonCoords[length-1]
and vice versa. Considering these should always be identical in polygons, I favor this approach.
If you nonetheless want to duplicate the object itself rather than a reference to the object, you will need to clone it first. To do this, use polygonCoords.push(Object.assign({}, polygonCoords[0]));
instead of polygonCoords.push(polygonCoords[0])
.