"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-77.155585,
40.056708,
0
],
[
-77.150315,
40.04536,
0
]
]
]
},
"id": 42001030101,
"Households": 1000,
"Income": 74597
},
I am using the google maps JS API. I cannot use the getProperty function because the data doesn't have the properties grouped together.
How can I access each of these pieces of data?
Here is what I tried before I realized that you can't use the properties function.
map.data.setStyle(
function(feature){
let income = feature.getProperty('Income');
let color = 'blue';
if (income > 10000){
color = 'red'
}
return {
fillColor: color,
//strokeColor: "green",
strokeWeight: 0.3,
};
}
);
According to the geojson spec:
A Feature object has a member with the name "properties". The value
of the properties member is an object (any JSON object or a JSON null
value).
As your feature doesn't have a properties member, you can 'repair' it so that any member that is neither type nor geometry is bundled as a member of properties.
This should enable your existing code using feature.getProperty().
const data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-77.155585, 40.056708, 0],
[-77.150315, 40.04536, 0]
]
]
},
"id": 42001030101,
"Households": 1000,
"Income": 74597
}
]
}
const repairGeoJsonProps = (fc) => {
return {
"type": "FeatureCollection",
"features": fc.features.map(ftr => {
const props = Object.entries(ftr).filter(k => ["type", "geometry"].indexOf(k[0]) < 0);
return {
"type": ftr.type,
"geometry": ftr.geometry,
"properties": Object.fromEntries(props)
}
})
}
}
console.log(repairGeoJsonProps(data));
Related
I have two object with some similer key values osmstartnode and osmendnode. i want to merge these two object and get the final object with new value having congestion_level.
First object
var object = [{
osmstartnode: 370705004,
osmendnode: 1369956654,
congestion_level: 1
},
{
osmstartnode: 42469049,
osmendnode: 42469053,
congestion_level: 2
}
];
Second object
var roadobjt = [{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-74.0048445, 40.7124759],
[-74.0048533, 40.71245],
[-74.0048604, 40.7124243],
[-74.0048578, 40.7123974],
[-74.0048468, 40.7123722],
[-74.0048252, 40.7123472],
[-74.0045725, 40.7121422]
]
},
properties: {
"osmhighway": "motorway_link",
"osmoneway": "yes",
"osmwayid": 5669636,
"osmstartnode": 370705004,
"osmendnode": 1369956654,
"speed_mean_mph": 16,
"pct_from_freeflow": 72,
"speed_freeflow_mph": 22
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-73.99866284812883, 40.59729307801823],
[-73.99879364640618, 40.59716957964474],
[-73.99913817998096, 40.596844447960684],
[-73.99931411513008, 40.596676614430145]
]
},
properties: {
"osmname": "Bay Parkway",
"osmhighway": "primary",
"osmoneway": "no",
"osmwayid": 5675398,
"osmstartnode": 42469049,
"osmendnode": 42469053,
"speed_mean_mph": 20,
"pct_from_freeflow": 67,
"speed_freeflow_mph": 29
}
}
];
to merge use:
var object = [{
osmstartnode: 370705004,
osmendnode: 1369956654,
congestion_level: 1
},
{
osmstartnode: 42469049,
osmendnode: 42469053,
congestion_level: 2
}
];
into properties of:
var roadobjt = [{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-74.0048445, 40.7124759],
[-74.0048533, 40.71245],
[-74.0048604, 40.7124243],
[-74.0048578, 40.7123974],
[-74.0048468, 40.7123722],
[-74.0048252, 40.7123472],
[-74.0045725, 40.7121422]
]
},
properties: {
"osmhighway": "motorway_link",
"osmoneway": "yes",
"osmwayid": 5669636,
"osmstartnode": 370705004,
"osmendnode": 1369956654,
"speed_mean_mph": 16,
"pct_from_freeflow": 72,
"speed_freeflow_mph": 22
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-73.99866284812883, 40.59729307801823],
[-73.99879364640618, 40.59716957964474],
[-73.99913817998096, 40.596844447960684],
[-73.99931411513008, 40.596676614430145]
]
},
properties: {
"osmname": "Bay Parkway",
"osmhighway": "primary",
"osmoneway": "no",
"osmwayid": 5675398,
"osmstartnode": 42469049,
"osmendnode": 42469053,
"speed_mean_mph": 20,
"pct_from_freeflow": 67,
"speed_freeflow_mph": 29
}
}
];
use :
roadobjt.map((r, i) => { r.properties = Object.assign(r.properties, object[i]); return r;})
results:
[{"type":"Feature","geometry":{"type":"LineString","coordinates":[[-74.0048445,40.7124759],[-74.0048533,40.71245],[-74.0048604,40.7124243],[-74.0048578,40.7123974],[-74.0048468,40.7123722],[-74.0048252,40.7123472],[-74.0045725,40.7121422]]},"properties":{"osmhighway":"motorway_link","osmoneway":"yes","osmwayid":5669636,"osmstartnode":370705004,"osmendnode":1369956654,"speed_mean_mph":16,"pct_from_freeflow":72,"speed_freeflow_mph":22,"congestion_level":1}},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[-73.99866284812883,40.59729307801823],[-73.99879364640618,40.59716957964474],[-73.99913817998096,40.596844447960684],[-73.99931411513008,40.596676614430145]]},"properties":{"osmname":"Bay Parkway","osmhighway":"primary","osmoneway":"no","osmwayid":5675398,"osmstartnode":42469049,"osmendnode":42469053,"speed_mean_mph":20,"pct_from_freeflow":67,"speed_freeflow_mph":29,"congestion_level":2}}]
I have a map with Geojson polygons where each polygon is identified by a unique ID. I have a separate Geojson of point markers where each point is associated with a polygon with the same polygon ID, as well as a unique identifier for each individual point.
The initial map display is of only polygons. Each polygon click will display the points that are associated with the clicked polygon. When a new polygon is clicked, I want to plot the points associated with the new polygon while simultaneously removing the previously plotted points. So each time the user clicks a polygon, ONLY points within that polygon are ever displayed.
Here is some minimally reproducible code: https://jsfiddle.net/3v7hd2vx/1146/
var polys = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"stroke": "#555555",
"stroke-width": 2,
"stroke-opacity": 1,
"fill": "#555555",
"fill-opacity": 0.5,
"polygon": "one"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-87.33032226562499,
37.90953361677018
],
[
-85.374755859375,
37.90953361677018
],
[
-85.374755859375,
39.036252959636606
],
[
-87.33032226562499,
39.036252959636606
],
[
-87.33032226562499,
37.90953361677018
]
]
]
}
},
{
"type": "Feature",
"properties": {
"stroke": "#555555",
"stroke-width": 2,
"stroke-opacity": 1,
"fill": "#555555",
"fill-opacity": 0.5,
"polygon": "two"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-85.3857421875,
37.90953361677018
],
[
-83.3642578125,
37.90953361677018
],
[
-83.3642578125,
39.04478604850143
],
[
-85.3857421875,
39.04478604850143
],
[
-85.3857421875,
37.90953361677018
]
]
]
}
},
{
"type": "Feature",
"properties": {
"stroke": "#555555",
"stroke-width": 2,
"stroke-opacity": 1,
"fill": "#555555",
"fill-opacity": 0.5,
"polygon": "three"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-87.34130859375,
36.90597988519294
],
[
-83.3642578125,
36.90597988519294
],
[
-83.3642578125,
37.91820111976663
],
[
-87.34130859375,
37.91820111976663
],
[
-87.34130859375,
36.90597988519294
]
]
]
}
}
]
};
var pts = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"marker-color": "#7e7e7e",
"marker-size": "medium",
"marker-symbol": "",
"id": "one",
"animal": "bear"
},
"geometry": {
"type": "Point",
"coordinates": [
-86.72607421875,
38.77121637244273
]
}
},
{
"type": "Feature",
"properties": {
"marker-color": "#7e7e7e",
"marker-size": "medium",
"marker-symbol": "",
"id": "one",
"animal": "fish"
},
"geometry": {
"type": "Point",
"coordinates": [
-86.583251953125,
38.487994609214795
]
}
},
{
"type": "Feature",
"properties": {
"marker-color": "#7e7e7e",
"marker-size": "medium",
"marker-symbol": "",
"id": "two",
"animal": "tiger"
},
"geometry": {
"type": "Point",
"coordinates": [
-84.276123046875,
38.38472766885085
]
}
},
{
"type": "Feature",
"properties": {
"marker-color": "#7e7e7e",
"marker-size": "medium",
"marker-symbol": "",
"id": "two",
"animal": "lizard"
},
"geometry": {
"type": "Point",
"coordinates": [
-85.067138671875,
38.70265930723801
]
}
},
{
"type": "Feature",
"properties": {
"marker-color": "#7e7e7e",
"marker-size": "medium",
"marker-symbol": "",
"id": "three",
"animal": "dog"
},
"geometry": {
"type": "Point",
"coordinates": [
-83.880615234375,
37.483576550426996
]
}
},
{
"type": "Feature",
"properties": {
"marker-color": "#7e7e7e",
"marker-size": "medium",
"marker-symbol": "",
"id": "three",
"animal": "horse"
},
"geometry": {
"type": "Point",
"coordinates": [
-85.93505859374999,
37.709899354855125
]
}
}
]
};
var map = L.map("map", {
center: [37.5, -85],
zoom: 7
});
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png").addTo(map);
var defaultStyle = {
fillColor: "whitesmoke",
color: "#171717",
fillOpacity: 1,
weight: 1
};
// create polygon geojson, add to map
var polyJson = L.geoJson(polys, defaultStyle).addTo(map);
// empty layer group to add markers to
var layerGroup = L.layerGroup();
// loop through polygon layers for events
polyJson.eachLayer(function(layer){
// zoom to bbox on each polygon click
layer.on("click", function(e){
var bbox = e.target.getBounds();
var sw = bbox.getSouthWest();
var ne = bbox.getNorthEast();
map.fitBounds([sw, ne]);
// the clicked polygon identifier
var clickedPoly = e.target.feature.properties.polygon;
// pts added to map when they match the clickedpoly id
L.geoJson(pts, {
pointToLayer: function(feature, latlng){
if(feature.properties.id === clickedPoly){
var clicked = L.circleMarker(latlng, {
color: "red"
}).addTo(map).addTo(layerGroup);
}
}
});
});
});
polyJson.on("click", function(){
if(map.hasLayer(layerGroup)){
map.removeLayer(layerGroup);
}else{
map.addLayer(layerGroup);
//layerGroup.removeLayers();
}
});
In this example, the entire layerGroup of points is removed every other click based on the conditional statement at the end of the code block. But each new click continues to append markers to the layerGroup, so ALL selected markers are displayed every other click.
My inclination is to have each "group" of markers named by the polygon that they lie within, so when displayed markers do not match the currently clicked polygon ID, they will be removed both from the map AND from the layerGroup. I've worked extensively with Leaflet in R, but I'm not sure how to accomplish this in JS (or if the logic is even the same in the different languages). I can't manually define each layer because I'll be iterating through many dynamically loaded polygons and points.
One simple way to fill your layer with teh desired points would be to:
make your layerGroup a permanent layer,
empty this layer when the user clicks on a polygon with layerGroup.clearLayers()
fill layerGroup with the valid markers (determined by the filter property) and let Leaflet handle the markers without interfering with pointToLayer.
Basically, simplify things:).
For example:
layer.on("click", function(e){
var bbox = e.target.getBounds();
var sw = bbox.getSouthWest();
var ne = bbox.getNorthEast();
map.fitBounds([sw, ne]);
// the clicked polygon identifier
var clickedPoly = e.target.feature.properties.polygon;
layerGroup.clearLayers();
layerGroup.addLayer(L.geoJson(pts, {
pointToLayer: function(feature, latlng){
return L.circleMarker(latlng, {
color: "red"
});
},
filter: function (feature) {
return feature.properties.id === clickedPoly;
}
}));
});
And a demo https://jsfiddle.net/3v7hd2vx/1147/
I'm trying to get some point inside multiple polygon using pointsWithinPolygon in turfjs, but the result is unexpected.
Is there any chance that pointsWithinPolygon isn't compatible with FeatureCollection?
Here is the example of my usage.
let points = {
"type": "Point",
"coordinates": [
106.866995, -6.261513
]
}
let filter = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"IdArea": 4
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
106.314674,
-6.6348689124
],
[
107.5781628906,
-6.6348689124
],
[
107.5781628906,
-5.9742195859
],
[
106.314674,
-5.9742195859
],
[
106.314674,
-6.6348689124
]
]
]
}
}
]
}
let result = turf.pointsWithinPolygon(points, filter);
console.log(result);
You are trying to use geoJsons as inputs to turf's pointsWithinPolygons function.
The function takes a turf.points array of points, and a turf.polygon array of polygon vertices.
Based on the variables you established, you would need to call:
let result = turf.pointsWithinPolygon(turf.points([points.coordinates]), turf.polygon(filter.features.geometry.coordinates));
I'm trying to display markers on a Webpage map from a JSON object (initially Firebase).
Here is my Javascript code , how do I manage with converting JSON Object to geoson array ?
// get character (points) reference from firebase
var refPOI = '{"-KiWVsBzdJ3EW3THO7bK":{"image":"3","lat":165.440135,"lon":-21.669071},"-KiWY9hLU12ebrlH7cXS":{"image":"5","lat":167.516824,"lon":-22.619914},"-KiWY9hMggrqlTNJMWzU":{"image":"8","lat":166.59579,"lon":-20.718007},"-KiWY9mpKP8gx7i8eGpo":{"image":"8","lat":167.100445,"lon":-20.961233},"-KiWY9oqGSHS_8Sdwpda":{"image":"9","lat":167.818109,"lon":-21.460377},"-KiWYA3hGwTUJGQjYx7O":{"image":"9","lat":165.458005,"lon":-21.770834}}';
var dataPOI = JSON.parse(refPOI);
var arr = [];
for(var x in dataPOI){
arr.push(dataPOI[x]);
}
console.log(dataPOI);
console.log(arr);
var geojson = {
"type": "FeatureCollection",
"features": [
]
};
dataPOI.$loaded().then(function(results) {
for(x=0;x<results.length;x++) {
geojson.features.push({
"type": "Feature",
"properties": {
"message": results[x].points,
"image": results[x].image,
"iconSize": [50, 50],
"id": results[x].$id
},
"geometry": {
"type": "Point",
"coordinates": [
results[x].lat,
results[x].lon
]
}
});
}
})
I have a list of features and I want to create a FeatureCollection to group them in one string, the features are from different types (polygons, lines and points).
Here is how they are written :
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
-31.640625,
15.623036831528264
],
[
-2.8125,
-14.264383087562637
],
[
-22.5,
-30.751277776257812
],
[
-30.937499999999996,
-38.54816542304657
]
]
}
}
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-24.960937499999996,
29.84064389983441
],
[
-2.109375,
21.616579336740603
],
[
2.4609375,
43.068887774169625
],
[
-31.289062500000004,
49.38237278700955
],
[
-24.960937499999996,
29.84064389983441
]
]
]
}
}
Is there a javascript function that deals with this, i'm stuck on it.
If you have an array of GeoJSON feature strings, you can create a GeoJSON feature collection string like this:
var features = [
'{ "type": "Feature", "properties": {}, ... }',
'{ "type": "Feature", "properties": {}, ... }'
];
var collection = JSON.stringify({
features: features.map(JSON.parse),
type: 'FeatureCollection'
});