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"
}
}
]
}

Categories