How do you convert a dictionary with objects into geoJson? - javascript

We have a dictionary with cities, using a uniqe id as the key:
cities: {
'adfjlx9w': {
name: 'New York',
latitude: 4,
longitude: -7
},
'favkljsl9': {
name: 'Copenhagen',
latitude: 2,
longitude: -18
}
}
We need to convert our dictionary into Geojson in order to place the cities on a map, but cannot use the typical route below, as it is not an array of objects:
GeoJSON.parse(cities, {
Point: ['latitude', 'longitude']
});
What is the fastest and best way to do this?

If I understand correctly, you need to extract the latitude and longitude data for each value of the cities object to an array of latitude/longitude values of shape:
{ latitude, longitude }
One approach would be to use Object#values which returns an array of the values for cities, and, optional use Array#map to transform each object to a new object (with only the latitude, longitude values):
const cities = {
'adfjlx9w': {
name: 'New York',
latitude: 4,
longitude: -7
},
'favkljsl9': {
name: 'Copenhagen',
latitude: 2,
longitude: -18
}
}
const latlngArray = Object
// Extract value array from cities
.values(cities)
// Map each value to lat/lng only object
.map(item => ({ latitude : item.latitude, longitude : item.longitude }))
console.log(latlngArray);
/* Pass latlngArray to GeoJSON.parse
GeoJSON.parse(latlngArray, {
Point: ['latitude', 'longitude']
});
*/
Hope that helps!

Something like this should work.
const citiesArray = Object.values(cities);
GeoJSON.parse(citiesArray, {
Point: ['latitude', 'longitude']
});

According to the GeoJSON Specification, to include the id and name properties with latitude/longitude coordinates, you would need to parse the object as type FeatureCollection with a property features.
Each features array object should be of type Feature, with properties and geometry values. The properties value should contain the metadata, and the geometry value should be of type Point with coordinates property containing latitude/longitude.
const cities = {
'adfjlx9w': {
name: 'New York',
latitude: 4,
longitude: -7
},
'favkljsl9': {
name: 'Copenhagen',
latitude: 2,
longitude: -18
}
}
let citiesGeoJSON = Object.entries(cities)
.reduce((
_cities,
[cityID, cityData],
) => {
let city = {
"type": "Feature",
"properties": {
"id": cityID,
"name": cityData.name,
},
"geometry": {
"type": 'Point',
"coordinates": [
cityData.latitude,
cityData.longitude,
],
},
}
_cities.features.push(city)
return _cities
}, {
"type": "FeatureCollection",
"features": [],
})
There is a GeoJSON Linter online.

Related

Why are markers not showing - Leaflet and JSON response format?

I'm using leaflet and a json response from API call.Data shows up in the variables for marker, properties and geometry in the debugger, but it won't display a marker. Is my JSON format wrong? I am new at this..
data response looks like this: Array of 6. Longitude is a positive string in the response.
0: {sampleID: "4531", visitNum: "1083", gearType: "EZ cast net 4 ft
radius, 0.75 lb", habitatID: "511", seineCode: "", …}
I have tried pointToLayer, OnEachFeature. I would like to show popups for the markers if I get them to show.
I tried to stringify with JSON.stringify(data); I'm not sure what format I should have.
var jsonstring;
$.getJSON("http://localhost:29694/api/Sample?VisitNum=1083", function (data) {
jsonstring = JSON.stringify(data);
jsondata = JSON.parse(jsonstring);
var outGeoJson = {}
for (i = 0 ; i < data.length; i++) {
var longdata = data[i]["longStart"] * -1;
var latdata = data[i]["latStart"] * 1;
var latlng = [];
latlng = [longdata, latdata];
outGeoJson['properties'] = data[i]
outGeoJson['type'] = "Feature"
outGeoJson['geometry'] = {
"type": "Point", "coordinates":
[longdata, latdata]
}
console.log(outGeoJson);
var properties = [];
properties = outGeoJson.properties;
L.geoJSON(outGeoJson, {
pointToLayer: function (feature, latlng) {
var pmarker = L.circleMarker(latlng, {
radius: 5,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
});
return pmarker;
}
}).addTo(map);
}
function lngLatToLatLng(lngLat) {
return [latlng[1], latlng[0]];
}
});
The console.log output is:
{properties: {…}, type: "Feature", geometry: {…}}
geometry:
coordinates: (2) [-132.12211, 32.12122]
type: "Point"
__proto__: Object
properties:
depthSample: ""
depthWater: ""
duration: ""
endTime: "3/18/2019 12:00:00 AM"
gearType: "backpack efishing"
habitatID: "512"
latEnd: ""
latStart: "32.12122"
lengthTrawl: ""
longEnd: ""
longStart: "132.12211"
netter: "6"
notes: ""
percentOpen: ""
sampleCode: "EFISHBP1-HONK-18Mar2019"
sampleID: "4544"
seineCode: ""
startTime: "3/18/2019 12:00:00 AM"
towDirection: ""
visitNum: "1083"
volts: ""
width: ""
__proto__: Object
type: "Feature"
__proto__: Object
Welcome to SO!
You just forgot to return your newly created pmarker Circle Marker from your pointToLayer function.
BTW, there is no need to build a GeoJSON object at runtime just for the sake of displaying in Leaflet; you can directly build Leaflet layers. See Leaflet with markers and line

how to convert array of arrays to array of objects

I am trying to create a json file to test out some react-native map polygon functionality. I have geoJson available from a project using leaflet maps. I need to format the lat/lng points. I have drilled down from the top level-geometry-coordinates. but I am stuck on what to do next. Since i only need the end result for testing any library can be used in the plunker to get the desired result.
here is where i am at.
[
[
[
-106.75845,
34.659846
],
[
-106.81188,
34.649485
],
[
-106.80648,
34.646378
],
[
-106.75845,
34.659846
]
],
[
[
-106.70432,
34.650473
],
[
-106.79663,
34.720663
],
[
-106.7278,
34.637498
],
[
-106.70432,
34.650473
]
]
]
this is the what i need the end result to look like. plunker
// desired result
var result = [[{
latitude: 0,
longitude: 0
}, {
latitude: 0,
longitude: 0
}, {
latitude: 0,
longitude: 0
}], [{
latitude: 0,
longitude: 0
}, {
latitude: 0,
longitude: 0
}, {
latitude: 0,
longitude: 0
}]];
try this updated plunker
obj = obj.map(function(innerArray){
return innerArray.map(function(value){
return {latitude:value[0], longitude:value[1]} ;
});
});
console.log(obj);

(javascript) Is it possible to split an array of different object types into multiple arrays of one object type

So I have an array that contains objects with different attributes and I want to know how I can make multiple arrays with objects with the same attributes of the whole array.
I want to go from this
[
{name:”test”, place:”country”},
{name:”walkAndEat”, Long=100,Lat:15,Location:”place name”},
{name:”test2”,place:”Europe”}
]
To
[
{name:”test”, place:”country”},
{name:”test2”,place:”Europe”}
]
[
{name:”walkAndEat”, Long:100,Lat:15,Location:”place name”}
]
If you see objects being equal as having the same properties, you can keep the keys as (stringified) indices in a collection object and check if a properties-key already exists:
var arrcoll = {};
function add(o){
var keys = JSON.stringify(Object.keys(o).sort());
var arr = arrcoll[keys];
if(arr)
arr.push(o);
else
arrcoll[keys] = [o];
return arr;
}
This can be done on the fly or on a pre existing array as shown in this Fiddle
Suppose you have a list of objects that have different properties like so:
var placesOrPeople = [
{ name: 'Seymour Skinner', occupation: 'Principal' },
{ name: 'Kwik-E-Mart', lat: 23, long: 100 },
{ name: 'Sideshow Bob', occupation: 'Comic Foil' },
{ name: 'Flaming Tyre Yard', lat: 12, long: 88 },
{ name: 'Joe Quimby', occupation: 'Mayor' }
];
And you want them sorted into separate lists like so:
places = [
{ name: 'Kwik-E-Mart', lat: 23, long: 100 },
{ name: 'Flaming Tyre Yard', lat: 12, long: 88 }
];
people = [
{ name: 'Seymour Skinner', occupation: 'Principal' },
{ name: 'Sideshow Bob', occupation: 'Comic Foil' },
{ name: 'Joe Quimby', occupation: 'Mayor' }
];
You can use the built-in Array.filter command like so:
var places = placesOrPeople.filter(function(currentPlaceOrPerson) {
if (currentPlaceOrPerson.occupation !== undefined) {
// it must be a person, since locations don't have occupations
return true;
} else {
return false;
}
});
var people = placesOrPeople.filter(function(currentPlaceOrPerson) {
if (currentPlaceOrPerson.lat !== undefined && currentPlaceOrPerson.long !== undefined) {
// it must be a place, since people don't have co-ordinates
return true;
} else {
return false;
}
});
Javascript Objects are not set types, they are dynamic, meaning you can change them during execution.
JavaScript is a loosely typed or a dynamic language. That means you don't have to declare the type of a variable ahead of time. The type will get determined automatically while the program is being processed. That also means that you can have the same variable as different types:
var anything = arrayOfAnyOtherType[0];
is valid... If you loop your source array and populate it, you can define any behavior to each object

how to call an array of keys from an array of objects?

If I have the following array
someArray = [{id: 1, coordinates: {latitude: 1212, longitude: 13324}},{id: 2, coordinates: {latitude: 1314, longitude: 15151}}]
is there anyway to call someArray so I get just the array of the coordinates keys without having to make a new array? someArray.coordinates gives me undefined.
Expected output:
[{latitude: 1212, longitude: 13324}, {latitude: 1314, longitude: 15151}]
You can use Array#map (spec, MDN) for that:
someArray = someArray.map(function(entry) {
return entry.coordinates;
});
Array#map produces a new array from the entries you return from the iteration function you pass into it.
Live Example:
var someArray = [{id: 1, coordinates: {latitude: 1212, longitude: 13324 }}, {id: 2, coordinates: {latitude: 1314,longitude: 15151}}];
snippet.log("Before:");
snippet.log(JSON.stringify(someArray));
someArray = someArray.map(function(entry) {
return entry.coordinates;
});
snippet.log("After:");
snippet.log(JSON.stringify(someArray));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
You can try with a map function:
someArray.map(function(current, index, array){ array[index] = current.coordinates});
This will, though, modify your original. You can get it as another array like:
var coordinates = [];
someArray.map(function(current){coordinates.push(current.coordinates)});
And yes, sorry, I forgot, the easiest is:
var coordinates = someArray.map(function(current) { return current.coordinates; });
Or you can write it yourself:
function getCoordinates(objectArray) {
var coordinates = [];
for (var i in objectArray) {
var current = objectArray[i];
coordinates.push(current.coordinates);
}
}
var onlyCoordinates = getCoordinates(someArray);
EDITED: Just use following snippet
var someArray = [{id: 1, coordinates: {latitude: 1212, longitude: 13324}},{id: 2, coordinates: {latitude: 1314, longitude: 15151}}];
var i = -1;
while(someArray[++i]){
someArray[i] = someArray[i].coordinates;
}
document.write("<pre>"+JSON.stringify(someArray,0,3)+"</pre>");

Want to get a specific Element from a json array,

I havethe following JSON array and want to fetch a specific element from it for example the first element "long_name"
this is my JSON array:
({results:[{address_components:[{long_name:"Lahore", short_name:"Lahore", types:["locality", "political"]}, {long_name:"Lahore District", short_name:"Lahore District", types:["administrative_area_level_2", "political"]}, {long_name:"Punjab", short_name:"Punjab", types:["administrative_area_level_1", "political"]}, {long_name:"Pakistan", short_name:"PK", types:["country", "political"]}], formatted_address:"Lahore, Pakistan", geometry:{bounds:{northeast:{lat:31.6332872, lng:74.505512}, southwest:{lat:31.3342113, lng:74.1469001}}, location:{lat:31.55460609999999, lng:74.3571581}, location_type:"APPROXIMATE", viewport:{northeast:{lat:31.6332872, lng:74.505512}, southwest:{lat:31.3342113, lng:74.1469001}}}, place_id:"ChIJ2QeB5YMEGTkRYiR-zGy-OsI", types:["locality", "political"]}], status:"OK"})
Please help me on this..Thanks1
var data = {results:[{address_components:[{long_name:"Lahore", short_name:"Lahore", types:["locality", "political"]}, {long_name:"Lahore District", short_name:"Lahore District", types:["administrative_area_level_2", "political"]}, {long_name:"Punjab", short_name:"Punjab", types:["administrative_area_level_1", "political"]}, {long_name:"Pakistan", short_name:"PK", types:["country", "political"]}], formatted_address:"Lahore, Pakistan", geometry:{bounds:{northeast:{lat:31.6332872, lng:74.505512}, southwest:{lat:31.3342113, lng:74.1469001}}, location:{lat:31.55460609999999, lng:74.3571581}, location_type:"APPROXIMATE", viewport:{northeast:{lat:31.6332872, lng:74.505512}, southwest:{lat:31.3342113, lng:74.1469001}}}, place_id:"ChIJ2QeB5YMEGTkRYiR-zGy-OsI", types:["locality", "political"]}], status:"OK"};
alert(data.results[0].address_components[0].long_name);
You need to parse the JSON results, like so
var results = '{"results":[{"address_components":[{"long_name":"Lahore", "short_name":"Lahore", "types":["locality", "political"]}, {"long_name":"Lahore District", "short_name":"Lahore District", "types":["administrative_area_level_2", "political"]}, {"long_name":"Punjab", "short_name":"Punjab", "types":["administrative_area_level_1", "political"]}, {"long_name":"Pakistan", "short_name":"PK", "types":["country", "political"]}], "formatted_address":"Lahore, Pakistan", "geometry":{"bounds":{"northeast":{"lat":31.6332872, "lng":74.505512}, "southwest":{"lat":31.3342113, "lng":74.1469001}}, "location":{"lat":31.55460609999999, "lng":74.3571581}, "location_type":"APPROXIMATE", "viewport":{"northeast":{"lat":31.6332872, "lng":74.505512}, "southwest":{"lat":31.3342113, "lng":74.1469001}}}, "place_id":"ChIJ2QeB5YMEGTkRYiR-zGy-OsI", "types":["locality", "political"]}], "status":"OK"}';
var json = JSON.parse(results);
alert(json.results[0].address_components[0].long_name); //will show 'Lahore'
A JSON object is a list of lists. In order to access lower layers you first need to parse the JSON object and create an array.
var jsonArray = JSON.parse(json_object);
Then you need to create an array from the array index that you need to reach.
var address_components = jsonArray[0];
Then you would need to go a step down again.
var long_name = address_components[0].long_name;
It is difficult to see the exact path with the JSON all on one line. Formatting it in a more "human viewable" format renders as follows:
({
results: [
{
address_components: [
{
long_name: "Lahore",
short_name: "Lahore",
types: [
"locality",
"political"
]
},
{
long_name: "Lahore District",
short_name: "Lahore District",
types: [
"administrative_area_level_2",
"political"
]
},
{
long_name: "Punjab",
short_name: "Punjab",
types: [
"administrative_area_level_1",
"political"
]
},
{
long_name: "Pakistan",
short_name: "PK",
types: [
"country",
"political"
]
}
],
formatted_address: "Lahore, Pakistan",
geometry: {
bounds: {
northeast: {
lat: 31.6332872,
lng: 74.505512
},
southwest: {
lat: 31.3342113,
lng: 74.1469001
}
},
location: {
lat: 31.55460609999999,
lng: 74.3571581
},
location_type: "APPROXIMATE",
viewport: {
northeast: {
lat: 31.6332872,
lng: 74.505512
},
southwest: {
lat: 31.3342113,
lng: 74.1469001
}
}
},
place_id: "ChIJ2QeB5YMEGTkRYiR-zGy-OsI",
types: [
"locality",
"political"
]
}
],
status: "OK"
})
This way you can see that the json object contains a property of results which is an array. The elements of results contain an address_components property which is also an array. The elements of address_components contain the long_name property. To access this, you would do the following, assuming you have a JSON string stored in jsonString:
var jsonObject = JSON.parse(jsonString);
var firstLongNameProperty = jsonObject.results[0].address_components[0].long_name;
First off you should construct a valid JSON string so you need to put quotes around your keys like so...
'{"results": [{"address_components": [{"long_name": "Lahore","short_name": "Lahore","types": ["locality","political"]},{"long_name": "Lahore District","short_name": "Lahore District","types": ["administrative_area_level_2","political"]},{"long_name": "Punjab","short_name": "Punjab","types": ["administrative_area_level_1","political"]},{"long_name": "Pakistan","short_name": "PK","types": ["country","political"]}],"formatted_address": "Lahore, Pakistan","geometry": {"bounds": {"northeast": {"lat": 31.633287,"lng": 74.50551},"southwest": {"lat": 31.334211,"lng": 74.1469}},"location": {"lat": 31.554605,"lng": 74.357155},"location_type": "APPROXIMATE","viewport": {"northeast": {"lat": 31.633287,"lng": 74.50551},"southwest": {"lat": 31.334211,"lng": 74.1469}}},"place_id": "ChIJ2QeB5YMEGTkRYiR-zGy-OsI","types": ["locality","political"]}],"status": "OK"}'
Better View JSON
After that you just have to parse your JSON text and append the values wherever needed
HTML
<div id="test"></div>
JavaScript
var obj = JSON.parse(text);
var text_div = document.getElementById('test');
for (i = 0; i < obj.results[0].address_components.length; i++) {
text_div.innerHTML = text_div.innerHTML + obj.results[0].address_components[i].long_name + '<br>';
}
JSFIDDLE

Categories