Reputation: 53
When the Mapbox geocoder returns a search result, I need to get the city(place name) and country name text and put them into a text field on the web page.
This returns the data to the console.
<script>
geocoder.on('results', function(results) {
console.log(results);
})
</script>
A geocoder search for New york returns this GeoJSON object data. I need to get the country text data when a search result is returned and update a text field on the web page with the country name text.
<script>
features: Array(5)
0:
bbox: (4) [-74.2590879797556, 40.477399, -73.7008392055224, 40.917576401307]
center: (2) [-73.9808, 40.7648]
context: Array(2)
0: {id: "region.14044236392855570", short_code: "US-NY", wikidata: "Q1384", text_en-GB: "New York", language_en-GB: "en", …}
1:
id: "country.9053006287256050"
language: "en"
language_en-GB: "en"
short_code: "us"
text: "United States of America"
text_en-GB: "United States of America"
wikidata: "Q30"
__proto__: Object
length: 2
__proto__: Array(0)
geometry: {type: "Point", coordinates: Array(2)}
id: "place.15278078705964500"
language: "en"
language_en-GB: "en"
matching_place_name: "New York, New York, United States of America"
matching_text: "New York"
place_name: "New York City, New York, United States of America"
place_name_en-GB: "New York City, New York, United States of America"
place_type: ["place"]
properties: {wikidata: "Q60"}
relevance: 1
text: "New York City"
text_en-GB: "New York City"
type: "Feature"
__proto__: Object
</script>
The below code updates the text field. However, not with the actual data from the above data. How do I query/access the actual result data after every search to update the text field?
<script>
//listen for a search result
document.querySelector('.mapboxgl-ctrl-geocoder--input').addEventListener('change', titleTest);
function titleTest() {
var countryName = {
id: "country.9053006287256050",
language: "en",
language_enGB: "en",
short_code: "us",
text: "United States of America",
text_enGB: "United States of America",
wikidata: "Q30"
}
//update the input field
document.getElementById('titleinput').value = countryName.text.toUpperCase();
//add to map
document.getElementById("map_title").innerHTML = countryName.text.toUpperCase();
</script>
The below line returns the value for 'place_name: "New York City, New York, United States of America"'
<script>
let str = document.querySelector('.mapboxgl-ctrl-geocoder--input').value;
</script>
Let's try it in the script below..
<script>
// listen for a search
document.querySelector('.mapboxgl-ctrl-geocoder--input').addEventListener('change', updateTitle);
function updateTitle() {
//get the text value for place
let str = document.querySelector('.mapboxgl-ctrl-geocoder--input').value;
//split the string
let countryName = str.split(", ");
//loop over array items
for(var i = 0; i < countryName.length; i++)
{
console.log(countryName[i]);
}
//update the input field
document.getElementById('titleinput').value = countryName[1].toUpperCase();
//add to map
document.getElementById("map_title").innerHTML = countryName[1].toUpperCase();
</script>
The above code gets me the mapbox suggestion [place_name] as a string ("New York City, New York, United States of America"), which I then split to a list, and iterate over. It works well for place/city as this array position is always first [0]. However, it doesn't work well for getting the country name, which isn't always in the same position in the string, or the list. For example, if I set the countryName array value to [1] and search for 'London', the second item is 'Greater London', 'England' was [2] and 'United Kingdom' was [3], whereas if I search for 'Paris', [1] gives me 'France'.
I need to get the country name text when the geocoder returns a result so I can add it to the text field. How do I get the country name text from the object after every search result? Does anyone know?
Upvotes: 4
Views: 3177
Reputation: 23
Maybe that way will help you, that is how I resolved it. Note that you can do if-else-if instead of several if's as I did. You could even use switch if you wish so.
geocoder.on('result', (e) => {
for(let i=0; i < e.result.context.length; i++) {
if(e.result.context[i].id.includes('postcode')) {
this.form.postcode = e.result.context[i].text;
}
if(e.result.context[i].id.includes('locality')) {
this.form.line_2 = e.result.context[i].text;
}
if(e.result.context[i].id.includes('place')) {
this.form.city = e.result.context[i].text;
}
if(e.result.context[i].id.includes('district')) {
this.form.county = e.result.context[i].text;
}
if(e.result.context[i].id.includes('country')) {
this.form.country = e.result.context[i].text;
}
}
// First line of address
if(e.result.text || e.result.address) {
this.form.line_1 = (e.result.address ? e.result.address + ' ' : '') + (e.result.text ? e.result.text : '');
}
// Full Address
if(e.result.place_name) {
this.form.full_address = e.result.place_name;
}
// Coordinates
if(e.result.center) {
this.form.longitude = e.result.center[0];
this.form.latitude = e.result.center[1];
}
});
Upvotes: 1
Reputation: 604
geocoder.on("result", (e) => {
function getAddressByType(value, index, array) {
if (value.id.match(/country.*/)) {
console.log(value.text)
} else if (value.id.match(/region.*/)) {
console.log(value.text)
} else if (value.id.match(/postcode.*/)) {
console.log(value.text)
} else if (value.id.match(/district.*/)) {
console.log(value.text)
} else if (value.id.match(/place.*/)) {
console.log(value.text)
} else if (value.id.match(/neighborhood.*/)) {
console.log(value.text)
} else if (value.id.match(/address.*/)) {
console.log(value.text)
} else if (value.id.match(/poi.*/)) {
console.log(value.text)
}
}
e.result.context.forEach(getAddressByType);
console.log(JSON.stringify(e))
});
note : "results" and "result" return different data. This is how I fetch all data under the context of "result" function. I loop the e.result.context then use a function to access the object to make sure I can use all object return on that array.
Upvotes: 3
Reputation: 182
Take the the Json object a return the string you are looking for. You can do a split function on this string to get all the values individually like so.
var listOfNames = obj.place_name.split(", ");
ListOfNames[0] = "New York City"
ListOfNames[1] = "New York"
ListOfNames[2] = "United States"
Upvotes: 0