How to get access to GeoJSON FeatureCollection objects in JavaScript - javascript
I have a URL linking to a JSON file of a GeoJSON FeatureCollection object.
{"type": "FeatureCollection", "features": [{...}, {...}, ...]}
I insert an attribute "properties" into this FeatureCollection object and assign a value "myFeatureCollection" to the key "name".
{"type": "FeatureCollection", "features": [{...}, {...}, ...], "properties": {"name": "myFeatureCollection"}}
Can I get access to the value "myFeatureCollection" from the outside in JavaScript?
In a word, I am seeking a method to achieve the following objective (pseudo-code):
var fc = jsonRead("myJsonUrl");
var fcName = fc.properties.name;
Only if your data is stored in a external JavaScript file:
You need to consider that the file is loaded asynchronously, therefore must implement a function that returns a callback function.
function jsonRead(String url, Function callback){}
Where:
url = Location path where the file exists
(file:///D:/UserName/GeoJSON/data/geo.js).
callback = Callback function which is executed when a previous operation ends.
Within the context of the callback function you can use the file contents, to execute other functions.
I've made a little demo where you can see how it works.
In your local machine, you need these files.
index.html:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="lib/js/reader.js"></script>
</head>
<body>
<ul id="list"></ul>
</body>
</html>
reader.js:
(function ()
{
window.onload = function ()
{
// Calls the jsonRead function. The first parameter is the URL, the second one is a callback function.
jsonRead("file:///D:/YourDirectory/GeoJSON/data/geo.js", function (fc)
{
buildList(fc); // Demo function to build a list with the current data in «fc» parameter.
});
};
function jsonRead(url, callback)
{
var head, script
head = document.getElementsByTagName("head")[0];
script = document.createElement("script");
script.src = url;
script.type = "text/javascript";
head.appendChild(script);
script.onload = function ()
{
callback(freeBus);
};
}
/* Demo */
// Demo function. It uses the external javascript file content.
function buildList(data)
{
var fc = data;
var list, li, i, j, cant, coordinatesCant, ulCoordinates, liCoordinates;
list = document.getElementById("list");
cant = fc.features.length;
for (i = 0; i < cant; i++)
{
li = document.createElement("li");
li.innerHTML = fc.features[i].id;
coordinatesCant = fc.features[i].geometry.coordinates.length;
if (coordinatesCant > 0)
{
ulCoordinates = document.createElement("ul");
for (j = 0; j < coordinatesCant; j++)
{
liCoordinates = document.createElement("li");
liCoordinates.innerHTML = JSON.stringify(fc.features[i].geometry.coordinates[j]);
ulCoordinates.appendChild(liCoordinates);
}
li.appendChild(ulCoordinates);
}
list.appendChild(li);
}
document.body.appendChild(list);
}
})();
geo.js:
var freeBus = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-105.00341892242432, 39.75383843460583],
[-105.0008225440979, 39.751891803969535]
]
},
"properties": {
"popupContent": "This is free bus that will take you across downtown.",
"underConstruction": false
},
"id": 1
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-105.0008225440979, 39.751891803969535],
[-104.99820470809937, 39.74979664004068]
]
},
"properties": {
"popupContent": "This is free bus that will take you across downtown.",
"underConstruction": true
},
"id": 2
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-104.99820470809937, 39.74979664004068],
[-104.98689651489258, 39.741052354709055]
]
},
"properties": {
"popupContent": "This is free bus that will take you across downtown.",
"underConstruction": false
},
"id": 3
}
]
};
var lightRailStop = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"popupContent": "18th & California Light Rail Stop"
},
"geometry": {
"type": "Point",
"coordinates": [-104.98999178409576, 39.74683938093904]
}
}, {
"type": "Feature",
"properties": {
"popupContent": "20th & Welton Light Rail Stop"
},
"geometry": {
"type": "Point",
"coordinates": [-104.98689115047453, 39.747924136466565]
}
}
]
};
var bicycleRental = {
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9998241,
39.7471494
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 51
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9983545,
39.7502833
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 52
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9963919,
39.7444271
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 54
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9960754,
39.7498956
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 55
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9933717,
39.7477264
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 57
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9913392,
39.7432392
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 58
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9788452,
39.6933755
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 74
}
]
};
var campus = {
"type": "Feature",
"properties": {
"popupContent": "This is the Auraria West Campus",
"style": {
weight: 2,
color: "#999",
opacity: 1,
fillColor: "#B0DE5C",
fillOpacity: 0.8
}
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-105.00432014465332, 39.74732195489861],
[-105.00715255737305, 39.74620006835170],
[-105.00921249389647, 39.74468219277038],
[-105.01067161560059, 39.74362625960105],
[-105.01195907592773, 39.74290029616054],
[-105.00989913940431, 39.74078835902781],
[-105.00758171081543, 39.74059036160317],
[-105.00346183776855, 39.74059036160317],
[-105.00097274780272, 39.74059036160317],
[-105.00062942504881, 39.74072235994946],
[-105.00020027160645, 39.74191033368865],
[-105.00071525573731, 39.74276830198601],
[-105.00097274780272, 39.74369225589818],
[-105.00097274780272, 39.74461619742136],
[-105.00123023986816, 39.74534214278395],
[-105.00183105468751, 39.74613407445653],
[-105.00432014465332, 39.74732195489861]
], [
[-105.00361204147337, 39.74354376414072],
[-105.00301122665405, 39.74278480127163],
[-105.00221729278564, 39.74316428375108],
[-105.00283956527711, 39.74390674342741],
[-105.00361204147337, 39.74354376414072]
]
], [
[
[-105.00942707061768, 39.73989736613708],
[-105.00942707061768, 39.73910536278566],
[-105.00685214996338, 39.73923736397631],
[-105.00384807586671, 39.73910536278566],
[-105.00174522399902, 39.73903936209552],
[-105.00041484832764, 39.73910536278566],
[-105.00041484832764, 39.73979836621592],
[-105.00535011291504, 39.73986436617916],
[-105.00942707061768, 39.73989736613708]
]
]
]
}
};
var coorsField = {
"type": "Feature",
"properties": {
"popupContent": "Coors Field"
},
"geometry": {
"type": "Point",
"coordinates": [-104.99404191970824, 39.756213909328125]
}
};
Result:
Related
Leafleat Filter two geojson files and array string include separator
I'd like to filter an array of strings from two sources inside a leaflet code. How can i split a string and filter it. The Tags in my geojson have separate keywords and i will use i input field to filter and display only the coordinates with the keyword. here my sources json_one.json { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ -90.072755, 29.961909 ] }, "properties": { "name": "French Quarter", "Tags": "Louisiana, New Orleans, French Quarter, Hwy-61, Mississippi River, I-12, Outlet Shopping" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ -95.053883, 29.796708 ] }, "properties": { "name": "Leisure", "Tags": "Houston, Texas, I-45, Outlet Shopping, I-10" } } ] } and json_next.json { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ -80.941429, 25.138486 ] }, "properties": { "name": "Flamingo", "Tags": "Outlet Shopping, Louisiana" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ -112.121, 36.051 ] }, "properties": { "name": "Grand", "Tags": "Louisiana" } } ] } How can i filter the properties.Tags by "Outlet Shopping" with this leaflet code var one = L.geoJson.ajax("json_one.json", { pointToLayer: function (feature, latlng) { return L.marker(latlng) .bindTooltip("<b>" + feature.properties.name + '</b><br />') ;} }); var next = L.geoJson.ajax("json_next.json", { pointToLayer: function (feature, latlng) { return L.marker(latlng) .bindTooltip("<b>" + feature.properties.name + '</b><br />') ;} }); Please help me, thanks
How to get unique feature properties from geojson source in Mapbox GL JS?
I've defined a mapbox geojson source: map.addSource("places", { type: "geojson", data: "http://example.com/myfile.geojson", }); My geojson source file has this structure: { "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "icon": "theatre" }, "geometry": { "type": "Point", "coordinates": [-77.038659, 38.931567] }}, { "type": "Feature", "properties": { "icon": "music" }, "geometry": { "type": "Point", "coordinates": [-77.020945, 38.878241] }}, ...] } I would like to get the unique names of the 'icon' properties (here: theatre and music). How can I loop over source to get these unique values? The objective here is to add a layer from these unique names for filtering purposes.
I found here the answer to my question. Basically, add a layer to the source, use mapbox function queryRenderedFeatures to get the features and then get unique features with the help of dedicated function getUniqueFeatures. After I can loop over uniqueFeatures to print the elements: var features = map.queryRenderedFeatures({layers: ['my_layer']}); var uniqueFeatures = getUniqueFeatures(features, "icon"); uniqueFeatures.forEach(function(feature) { var prop = feature.properties; console.log(prop.icon); }) The getUniqueFeatures function: function getUniqueFeatures(array, comparatorProperty) { var existingFeatureKeys = {}; // Because features come from tiled vector data, feature geometries may be split // or duplicated across tile boundaries and, as a result, features may appear // multiple times in query results. var uniqueFeatures = array.filter(function(el) { if (existingFeatureKeys[el.properties[comparatorProperty]]) { return false; } else { existingFeatureKeys[el.properties[comparatorProperty]] = true; return true; } }); return uniqueFeatures; }
We can use JavaScript Set object to store unique values. const uniqueIcons = new Set(); const data = {}; // Your JSON data. data.features.forEach((item) => { uniqueIcons.add(item.properties.icon); }); Example: const uniqueIcons = new Set(); const data = { "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "icon": "theatre" }, "geometry": { "type": "Point", "coordinates": [-77.038659, 38.931567] } }, { "type": "Feature", "properties": { "icon": "music" }, "geometry": { "type": "Point", "coordinates": [-77.020945, 38.878241] } }, { "type": "Feature", "properties": { "icon": "theatre" }, "geometry": { "type": "Point", "coordinates": [-77.038659, 38.931567] } } ] }; data.features.forEach((item) => { uniqueIcons.add(item.properties.icon); }); for(let icon of uniqueIcons) { console.log(icon); }
Filtering GeoJson data by property to get a subset of data
I am trying to get a subset of Geojson Data by property. { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ -115.5578333,32.9646667 ] }, "properties": { "Year1979_03":2.92606854, "Year1979_06":2.963032273, "Year1979_09":2.968127935 } }] If a user chooses year "Year1979_03 then then it should return { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ -115.5578333,32.9646667 ] }, "properties": { "Year1979_03":2.92606854, } }]
Not sure if I understand your question correctly, but if you have a user input and you have it in a variable: let userInput = "Year1979_03" and you have the returned data in its original form let originalData = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ -115.5578333,32.9646667 ] }, "properties": { "Year1979_03":2.92606854, "Year1979_06":2.963032273, "Year1979_09":2.968127935 } } ] } then you can use es6 spread operator to create the object you wanted to create: let reformedData = { ...originalData, "features": [ { ...originalData.features[0], "properties": { [userInput]: originalData.features[0].properties[userInput] } }] } Above, I use the spread operator to retrieve all the keys and values I want to keep from the originalData object, but specify the ones I want to change/replace. This would bring you the object you wanted.
Getting error while using 'circle-color' data driven styling in Mapboxgl.js & GeoJSON, but working fine with default color
I am trying to create a map, put data points using GeoJSON and Mapbox. It works fine when I am using a default color code for all points, but when I try to use data driven styling to put different colors for different property values It is giving errors. I am using mapboxgl.js. I get the following errors in Chrome Inspect: net::ERR_INTERNET_DISCONNECTED exports.getJSON # ajax.js:33 evented.js:111 Error at XMLHttpRequest.r.onerror (ajax.js:18) Please help! Here are my GeoJSON and HTML files. mapboxgl.accessToken = 'pk.eyJ1Ijoicml0YW1iaGFyYSIsImEiOiJjajZuNGZjNHUwNHgxMzNwc29hZ2ZkbmRvIn0.4kTuXEpbJBeoN3jCp3pfwQ'; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/dark-v9', center: [-121.403732, 40.492392], zoom: 10 }); map.on("load", function() { map.addSource('pH', { 'type': 'geojson', 'data': 'test.json' }); map.addLayer({ id: 'heat-map', type: 'circle', source: 'pH', paint: { // 'circle-color': '#f1f075', 'circle-color': { property: 'value', stops: [ [6, '#f1f075'], [10, '#e55e5e'] ] }, "circle-radius": 6, 'circle-opacity': 0.8 }, }); }); GeoJSON file: { "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "value": "7" }, "geometry": { "type": "Point", "coordinates": [-121.415061, 40.506229] } }, { "type": "Feature", "properties": { "value": "8" }, "geometry": { "type": "Point", "coordinates": [-121.505184, 40.488084] } }, { "type": "Feature", "properties": { "value": "9" }, "geometry": { "type": "Point", "coordinates": [-121.354465, 40.488737] } }] }
I believe the problem is due to the fact that your values are in the geojson as strings not numbers. When I changed them to numbers as below your example code worked for me { "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "value": 7 }, "geometry": { "type": "Point", "coordinates": [-121.415061, 40.506229] } }, { "type": "Feature", "properties": { "value": 8 }, "geometry": { "type": "Point", "coordinates": [-121.505184, 40.488084] } }, { "type": "Feature", "properties": { "value": 9 }, "geometry": { "type": "Point", "coordinates": [-121.354465, 40.488737] } }] } If you still get the AJAX error you may need to run a local server ( you can do this with python -m SimpleHTTPServer in your project folder and then load localhost:8000/path/to/index.html in your browser)
geoJson not validated
I have the following geoJson polygons: {"type": "Feature","geometry":{"type":"MultiPolygon", "coordinates":[[[[103.76772700000001,1.47063],[103.76772700000001,1.4795775862068967],[103.758794,1.4795775862068967],[103.758794,1.47063],[103.76772700000001,1.47063]]]]},"properties": {"number":"01"}}, {"type": "Feature","geometry":{"type":"MultiPolygon", "coordinates":[[[[104.00891800000001,1.47063],[104.00891800000001,1.4795775862068967],[103.99998500000001,1.4795775862068967],[103.99998500000001,1.47063],[104.00891800000001,1.47063]]]]},"properties": {"number":"03"}} But when I validate this in geojson validator it throws an EOF error. But when I try each separately it validates as a eligible geoJSON. So I tried with this too. "type":"FeatureCollection","features":[ {"type": "Feature","geometry":{"type":"MultiPolygon", "coordinates":[[[[103.76772700000001,1.47063],[103.76772700000001,1.4795775862068967],[103.758794,1.4795775862068967],[103.758794,1.47063],[103.76772700000001,1.47063]]]]},"properties": {"number":"01"}}, {"type": "Feature","geometry":{"type":"MultiPolygon", "coordinates":[[[[104.00891800000001,1.47063],[104.00891800000001,1.4795775862068967],[103.99998500000001,1.4795775862068967],[103.99998500000001,1.47063],[104.00891800000001,1.47063]]]]},"properties": {"number":"03"}} ] But still throwing an EOF error. Any help is appreciated.
It should be an JSON object. You are missing the { and }. { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [103.76772700000001, 1.47063], [103.76772700000001, 1.4795775862068967], [103.758794, 1.4795775862068967], [103.758794, 1.47063], [103.76772700000001, 1.47063] ] ] ] }, "properties": { "number": "01" } }, { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [104.00891800000001, 1.47063], [104.00891800000001, 1.4795775862068967], [103.99998500000001, 1.4795775862068967], [103.99998500000001, 1.47063], [104.00891800000001, 1.47063] ] ] ] }, "properties": { "number": "03" } } ] }