I have a geojson file of the following structure:
var areas = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "id": 0, "properties": { "name": "a", "count": "854" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 13.271687552328165, 29.359549285088008 ], [ 13.272222904657671, 29.357697459147403 ], [ 13.272586765837973, 29.35566049412985 ], [ 13.273062097784726, 29.354438105832578 ], [ 13.272652418199639, 29.360795108476978 ], [ 13.271320041078822, 29.360700647951568 ], [ 13.271687552328165, 29.359549285088008 ] ] ] } }
,
{ "type": "Feature", "id": 1, "properties": { "name": "b", "count": "254"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 13.277038163109875, 29.358442424220023 ], [ 13.276782949188294, 29.358122923383512 ], [ 13.275290999273452, 29.358508600578681 ], [ 13.274634727185679, 29.358485484466968 ], [ 13.282581930993208, 29.358635779719847 ], [ 13.278334024184868, 29.359814295404375 ], [ 13.277038163109875, 29.358442424220023 ] ] ] } }
,
{ "type": "Feature", "id": 2, "properties": {"name": "c", "count": "385"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 13.279484097462499, 29.349831113628788 ], [ 13.27792879702741, 29.349728966688758 ], [ 13.276089401418951, 29.349901260351807 ], [ 13.275677565886326, 29.349951087700632 ], [ 13.279484097462499, 29.349831113628788 ] ] ] } }
,
{ "type": "Feature", "id": 3, "properties": { "name": "d", "count": "243"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 13.290520299215724, 29.352306689134622 ], [ 13.289722088408338, 29.351802774685929 ], [ 13.289065241087885, 29.352101541350635 ], [ 13.28785814146197, 29.351114667998772 ], [ 13.290520299215724, 29.352306689134622 ] ] ] } }
]
}
Normally, to convert this data into an array I would create a loop to run through the appropriate variable storing this value in an array. However, I don't know if this is the best approach. Is there a way of pulling out all of the values for id into an array so that I would end up with:
[0,1,2,3]
I'm happy to use any external library to do this either - I'm mainly curious if there is a more efficient way than my current approach.
Not my code but there is a post on here regarding getting values from json quite efficiently.
refer to post
use jQuery's find() on JSON object
Answer from User Box9 is probably the best way
function getObjects(obj, key, val) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val));
} else if (i == key && obj[key] == val) {
objects.push(obj);
}
}
return objects;
}
Upvoted this answer in regards to this code block as well because it's about the best way I've found to pull out values
Something like this should work:
var arr = new Array();
for(var i = 0; i < areas.features.length; i++){
arr.push(areas.features[i].id)
}
To get a certain id value directly you can do something like this:
areas.features[0].id
which in this case would be 0.
EXAMPLE
If you're absolutely desperate to give something else a go, you could try underscore's map. The code would look something like this:
_.map(areas.features, function (item) { return item.id });
This will call the inner function on each item in features, and return an array containing each result.
I don't think there's anything too radical you can do here - ultimately, pulling values out of nested objects and arrays can't be dumbed down all too much.
Related
I added a geoJSON object to a map using. It creates around 200 polygons.
const geoJson = L.geoJSON(polygonsJSON).addTo(map);
The geoJSON object has structure:
{
"type": "FeatureCollection",
"name": "polygonsJSON",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"properties": {
"id": "23",
"NameSurname": "Namex Surnamex",
"r/s": "1823-1975"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
0.000165649338392,
-0.000006827196159
],
[
0.00014822202188,
-0.00002712912158
],
[
0.000138250722226,
-0.000018774789438
],
[
0.000155857701795,
0.000001347472926
],
[
0.000165649338392,
-0.000006827196159
]
]
]
]
}
},
I would like to modify (lets say change color) only one of the polygons based on its ID. How can I access it?
Thank you.
i have an array structure like below, which has combinedPorts as key with nested array. i can able to iterate and display the properties with .map function in ES6 if all the object has same number of combinedPorts key. But here in the first object the combinedPorts array appears three time whereas in second object the combinedPorts array appears twice. How to iterate the combinedPorts key if it appears different from one object to other.
[
{
"name": "Test Source",
"combinedPorts": [
{
"name": "PortGroup_1",
"templateId": "edfb5b72ec580b129465ea0e8029bad3",
"type": "SourcePorts",
"combinedPorts": [
{
"name": "Source_1",
"templateId": "2355fc02e18cd48c6b487aa8b6f75959",
"type": "SourcePorts",
"combinedPorts": [
{
"name": "Sami_TestSource",
"templateId": "0007ad49ea9b02b309a1248592a01981",
"type": "SourcePorts"
},
],
}
],
}
],
"portGroupInfo": []
},
{
"name": "Test Source",
"combinedPorts": [
{
"name": "PortGroup_1",
"templateId": "edfb5b72ec580b129465ea0e8029bad3",
"type": "SourcePorts",
"combinedPorts": [
{
"name": "Source_1",
"templateId": "2355fc02e18cd48c6b487aa8b6f75959",
"type": "SourcePorts"
}
],
}
],
"portGroupInfo": []
}
]
can someone guide me achieve this using ES6. Thanks in advance.
I would suggest using a recursive approach, this will deal with any level of nesting.
We'd create a function getNestedArrays() that will combine the elements in nested arrays of a given name: arrayName.
At each level, if we find the right array, we'll add the array to our output without any child arrays, then continue walking through the structure.
let input = [ { "name": "Test Source", "combinedPorts": [ { "name": "PortGroup_1", "templateId": "edfb5b72ec580b129465ea0e8029bad3", "type": "SourcePorts", "combinedPorts": [ { "name": "Source_1", "templateId": "2355fc02e18cd48c6b487aa8b6f75959", "type": "SourcePorts", "combinedPorts": [ { "name": "Sami_TestSource", "templateId": "0007ad49ea9b02b309a1248592a01981", "type": "SourcePorts" }, ], } ], } ], "portGroupInfo": [] }, { "name": "Test Source", "combinedPorts": [ { "name": "PortGroup_1", "templateId": "edfb5b72ec580b129465ea0e8029bad3", "type": "SourcePorts", "combinedPorts": [ { "name": "Source_1", "templateId": "2355fc02e18cd48c6b487aa8b6f75959", "type": "SourcePorts" } ], } ], "portGroupInfo": [] } ]
function getNestedArrays(obj, arrayName) {
let result = [];
for(let key in obj) {
if (obj[key] && typeof(obj[key]) === 'object') {
if ((key === arrayName) && Array.isArray(obj[key])) {
// We've found our array, add without child arrays...
result.push(...obj[key].map(({ [arrayName]: x, ...row}) => ({ ...row })))
}
result.push(...getNestedArrays(obj[key], arrayName));
}
}
return result;
}
console.log(input.map(obj => {
obj.combinedPorts = getNestedArrays(obj, 'combinedPorts');
return obj;
}));
.as-console-wrapper { max-height: 100% !important; }
Wondered if somebody could help me with some JavaScript.
I have a json file which looks similar to the one below, although this is a cut down version of the original one which is considerably larger. I'm attempting to grab some coordinates from it and use them to outline specific areas on a google map to which I set myself up a fiddle to test with:
https://jsfiddle.net/pork1977/up8rnf6d/
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"LEVEL1_COD": 1,
"LEVEL1_NAM": "EUROPE"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
24.128105619999872,
34.858005329767494
],
[
24.128505619999856,
34.808905329767484
],
[
24.044605619999857,
34.850005329767484
],
[
24.074605619999858,
34.868605329767476
],
[
20.819105619999874,
80.719105329767487
]
]
]
]
}
},
{
"type": "Feature",
"properties": {
"LEVEL1_COD": 2,
"LEVEL1_NAM": "AFRICA"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
32.954405619999847,
-26.058594670232509
],
[
32.895205619999871,
-26.040794670232515
],
[
32.980505619999889,
-25.972794670232517
],
[
32.982705619999848,
-25.98359467023252
],
[
32.954405619999847,
-26.058594670232509
]
]
]
]
}
},
{
"type": "Feature",
"properties": {
"LEVEL1_COD": 3,
"LEVEL1_NAM": "AUSTRALASIA"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
169.185405619999841,
-52.576994670232516
],
[
169.028205619999852,
-52.559194670232515
],
[
169.000705619999877,
-52.507194670232515
],
[
169.205205619999873,
-52.441394670232512
]
]
]
]
}
},
{
"type": "Feature",
"properties": {
"LEVEL1_COD": 4,
"LEVEL1_NAM": "ASIA-TROPICAL"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
96.914105619999845,
-12.198094670232521
],
[
96.902405619999882,
-12.199994670232513
],
[
96.914705619999864,
-12.151994670232511
],
[
96.924405619999874,
-12.182794670232511
],
[
96.914105619999845,
-12.198094670232521
]
]
]
]
}
},
{
"type": "Feature",
"properties": {
"LEVEL1_COD": 5,
"LEVEL1_NAM": "SOUTHERN AMERICA"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-67.212794380000133,
-55.893594670232517
],
[
-67.246994380000132,
-55.894994670232514
],
[
-67.41389438000013,
-55.832194670232518
],
[
-67.246994380000132,
-55.828094670232517
]
]
]
]
}
}
]
}
I'm attempting to filter some values on this. What I'm trying to do is get the "coordinates" when I specify a value for the LEVEL1_COD key in the filter.
I've managed to do this by running the below, and in this example it shows me the coordinates for EUROPE as this has it's LEVEL1_COD value set to 1. Note: the json variable here is using the full blown version of my snippet above.
var json = JSON.parse($.getJSON({'url': "https://raw.githubusercontent.com/tdwg/wgsrpd/master/geojson/level1.geojson", 'async': false}).responseText);
var coords = json.features.filter(function (el) {
return (el.properties.LEVEL1_COD == "1");
})[0].geometry.coordinates
console.log(coords);
Console.log shows me:
[ [ [ [ 24.128105619999872, 34.858005329767494 ], [
24.128505619999856, 34.808905329767484 ], [ 24.044605619999857, 34.850005329767484 ], [ 24.074605619999858, 34.868605329767476 ], [ 20.819105619999874, 80.719105329767487 ] ] ] ]
What I can't figure out, is how to change this from an 'equals' to a 'contains' type of filter.
For example, if I had a list of LEVEL1_COD values of say 1,2,5 and I wanted to filter on those values so I could see each set of coordinates, how would you go about doing that? I'd like to get the areas outlined on the map for each of these areas.
I'm sure the line which needs tweaking is:
return (el.properties.LEVEL1_COD == "1");
But after trying all sorts of things I can't get it to return more than one set. Do you need to loop through each item to do this? or is there a smarter way? Speed is somewhat important since the json files I'll be using are quite large.
Thanks
Paul
If you are looking to get more than one matching elements from the data based on the provided input(multiple values i.e., an array) Array.some can be used.
Below I've simulated few examples, hope this is what you are looking for
let data = {type:'FeatureCollection',features:[{type:'Feature',properties:{LEVEL1_COD:1,LEVEL1_NAM:'EUROPE',},geometry:{type:'MultiPolygon',coordinates:[[[[24.128105619999872,34.858005329767494],[24.128505619999856,34.808905329767484],[24.044605619999857,34.850005329767484],[24.074605619999858,34.868605329767476],[20.819105619999874,80.719105329767487],],],],},},{type:'Feature',properties:{LEVEL1_COD:2,LEVEL1_NAM:'AFRICA',},geometry:{type:'MultiPolygon',coordinates:[[[[32.954405619999847,-26.058594670232509],[32.895205619999871,-26.040794670232515],[32.980505619999889,-25.972794670232517],[32.982705619999848,-25.98359467023252],[32.954405619999847,-26.058594670232509],],],],},},{type:'Feature',properties:{LEVEL1_COD:3,LEVEL1_NAM:'AUSTRALASIA',},geometry:{type:'MultiPolygon',coordinates:[[[[169.185405619999841,-52.576994670232516],[169.028205619999852,-52.559194670232515],[169.000705619999877,-52.507194670232515],[169.205205619999873,-52.441394670232512],],],],},},{type:'Feature',properties:{LEVEL1_COD:4,LEVEL1_NAM:'ASIA-TROPICAL',},geometry:{type:'MultiPolygon',coordinates:[[[[96.914105619999845,-12.198094670232521],[96.902405619999882,-12.199994670232513],[96.914705619999864,-12.151994670232511],[96.924405619999874,-12.182794670232511],[96.914105619999845,-12.198094670232521],],],],},},{type:'Feature',properties:{LEVEL1_COD:5,LEVEL1_NAM:'SOUTHERN AMERICA',},geometry:{type:'MultiPolygon',coordinates:[[[[-67.212794380000133,-55.893594670232517],[-67.246994380000132,-55.894994670232514],[-67.41389438000013,-55.832194670232518],[-67.246994380000132,-55.828094670232517]]]]}}]};
const getFilteredData = (data, input) =>
data.features.filter(feature => {
return input.some(i => i === feature.properties.LEVEL1_COD);
});
let input = [1];
let filterdData = getFilteredData(data, input);
console.log(filterdData);
input = [1, 2, 5];
filterdData = getFilteredData(data, input);
console.log(filterdData);
input = [1, 7];
filterdData = getFilteredData(data, input);
console.log(filterdData);
.as-console-wrapper {
max-height: 100% !important;
}
It seems like you are populating your mapbox. You could use the package's filter
this.map.setFilter('YOUR_LAYER', ['==', 'LEVEL1_COD', 'YOUR_VALUE']);
I am working on something for checking what is the max value and whats is the min value. For this I am using Math.max.apply() and Math.min.apply().
Before I check that I convert an Object out of GeoJson code called from and to.
That looks like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
6.338356,
52.790868
],
[
6.378572,
52.648089
],
[
6.10522,
52.663572
],
[
6.089325,
52.798539
],
[
6.338356,
52.790868
]
]
]
},
"properties": {
"name": "DiggitTwoOne",
"regioFacetId": "tcm:106-353682-1024",
"level": 3,
"from": "10",
"to": "12"
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
6.105498,
52.663816
],
[
6.378605,
52.648187
],
[
6.417051,
52.520692
],
[
6.173867,
52.509454
],
[
6.105498,
52.663816
]
]
]
},
"properties": {
"name": "DiggitTwoTwo",
"regioFacetId": "tcm:106-353682-1024",
"level": 3,
"from": "13",
"to": "15"
}
}
]
}
For now the javascript code looks like this:
var from = event.feature.getProperty("from");
var to = event.feature.getProperty("to");
var mergeObjects = JSON.parse(from,to);
console.log(Math.max.apply(Math,mergeObjects));
console.log(Math.min.apply(Math, mergeObjects));
When I run the javascript code it gives an error like this:
CreateListFromArrayLike called on non-object.
I am using the Objects from and to.
Is there something I did wrong or am I getting it wrong of using it like this.
Your problem is that apply accepts an array and you're not passing it that:
var from = event.feature.getProperty("from"),
to = event.feature.getProperty("to"),
numArr = [from, to];
Math.max.apply(Math, numArr);
Math.min.apply(Math, numArr);
Is this what you're looking for?
I've a problem with a query matching items inside a BoundingBox.
How it's possible to match all items of type 2dsphere (GEO JSON)?
In this case I only got the data of type Point but the items of type LineString won't appear inside the result.
The schema definition looks like the following example:
/**
* Media location values (Point, LineString, Polygon)
* #property location
* #type {Object}
*/
location:{
"type":Object,
"index":"2dsphere"
},
I've e.g. this items in it:
[
{
"_account": "52796da308d618090b000001",
"_id": "5284e5798a1c039735000001",
"location": {
"coordinates": [
8.663705555555556,
50.10165277777778
],
"type": "Point"
},
"name": "Foto.JPG",
"preview": "/img/thumbs/13719-3zavxm.JPG",
"type": "image/jpeg",
"added": "2013-11-14T15:00:09.113Z",
"latlng": [ ],
"shares": [ ],
"shared": false,
"tags": [ ]
},
{
"_account": "52796da308d618090b000001",
"name": "Filtererd_Track.kml",
"type": "application/vnd.google-earth.kml+xml",
"_id": "5284e5c48a1c039735000002",
"added": "2013-11-14T15:01:24.280Z",
"latlng": [ ],
"shares": [ ],
"shared": false,
"tags": [ ]
},
{
"_account": "52796da308d618090b000001",
"_id": "5284e5c48a1c039735000003",
"location": {
"coordinates": [
[
9.49653,
50.94791
],
[
9.49731,
50.94811
],
[
9.49744,
50.94812
],
[
9.49755,
50.94808
],
[
9.4991,
50.94579
],
[
9.49969,
50.94545
],
[
9.50037,
50.94525
],
[
9.50136,
50.9452
],
[
9.50851,
50.98557
]
],
"type": "LineString"
},
"name": "test 2.gpx",
"preview": "/img/thumbs/13719-14rvt8w.png",
"type": "application/gpx+xml",
"added": "2013-11-14T15:01:24.529Z",
"latlng": [ ],
"shares": [ ],
"shared": false,
"tags": [ ]
}
]
The query to fetch the items looks like the following example but it does not match LineStrings / Polygons....
Think it's because of the subarrays but don't know how to include this in the query.
{
{
"location": {
"$geoWithin": {
"$box": [
[
-39.375,
36.73888412439431
],
[
76.640625,
56.897003921272606
]
]
}
}
}
}
I found a way to get everything in a bounding box by using $geoIntersects and create a Polygon from Bounding Box.
Like example below.
{
"location": {
"$geoIntersects": {
"$geometry": {
"type": "Polygon",
"coordinates": [
[
[
5.372314453125,
52.288322586002984
],
[
12.623291015625,
52.288322586002984
],
[
12.623291015625,
49.67829251994456
],
[
5.372314453125,
49.67829251994456
],
[
5.372314453125,
52.288322586002984
]
]
]
}
}
}
]
}