TL;DR: I apologise for how unnecessary this task is.
Outline:
I have a portfolio project that I had completed, but apparently, I haven't done it according to the specification. So I have been instructed to redo a large portion of it in line with their guidelines.
It is a Gazetteer website project using leaflet.js
and it must be constructed using jQuery, plain javaScript, and PHP routines to access multiple APIs to populate different Bootstrap Modals. I have produced something that I personally believe works perfectly well enough for the scope of this portfolio project.
You can try it out yourself here: https://kizzysinar.co.uk/project1/index.html
I was given this file: countryBorders.geo.json
, which contains a bunch of different features:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "Bahamas",
"iso_a2": "BS",
"iso_a3": "BHS",
"iso_n3": "044"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-77.53466,23.75975],
[-77.78,23.71],
[-78.03405,24.28615],
[-78.40848, 24.57564],
[-78.19087,25.2103],
[-77.89,25.17],
[-77.54,24.34],
[-77.53466,23.75975]
]
],
[
[
[-77.82,26.58],
[-78.91,26.42],
[-78.98,26.79],
[-78.51,26.87],
[-77.85,26.84],
[-77.82,26.58]
]
],
[
[
[-77,26.59],
[-77.17255,25.87918],
[-77.35641,26.00735],
[-77.34,26.53],
[-77.78802,26.92516],
[-77.79,27.04],
[-77,26.59]
]
]
]
}
},
{..... MORE FEATURES
]
}
I was under the impression that I could use the file to populate the <select>
dropdown options and to generate the map borders.
I utilised this locally stored file in the following ways:
- Used it to populate the
<select>
dropdown box:
result['data'].features.forEach(function (feature) {
$("<option>", {
value: feature.properties.iso_a3,
text: feature.properties.name
}).appendTo("#countrySelect")
- Since this is a locally stored file I chose to use the
leaflet.ajax
to parse the coordinates in thecountryBorders.geo.json
and create a layer of the multi polygons (features->properties->geometry->coordinates) for eachfeature
.
var geoJSONLayer = new L.GeoJSON.AJAX('vendors/json/countryBorders.geo.json',{
style: myStyle,
onEachFeature: onEachFeature
}).addTo(mymap);
To zoom into/ set the view of the map when the user selected a country, I used the stored value: feature.properties.iso_a3
to send an AJAX request to REST Countries API using the iso_a3 code to set the map view to the selected country according to the latlng
of the returned results:
function setView() {
$.ajax({
url: "libs/php/locateCountry.php",
type: 'POST',
dataType: 'json',
data: {
iso: $('#countrySelect option:selected').val()
},
success: function(result) {
if (result.status.name == "ok") {
mymap.setView(result['coordinates']);
}
},
Problem:
But I, apparently, must use jQuery/AJAX to make a PHP request to access that locally stored countryBorders.geo.json
and return the coordinates
that match a given iso_a3
. It's bonkers, and in my opinion, it makes almost zero sense to handle it this way.
Essentially, (what is meant to happen) when a user selects a country from the country list, the data stored in the selections value
is used in an AJAX call to a PHP file getCountryBorders.php
which I use the function file_get_contents
to get the JSON data and return with the correct featureCollection
/set of coordinates that matches the requested iso
code and that is then passed to create an L.geoJSON
layer in which the user can then trigger the bootstrap modal.
<select>/<option:selected>
-> value: iso_a3
-> AJAX iso: iso_a3
request iso
-> PHP cURL -> countryBorders.geo.json -> match feature.properties.iso_a3 == 'iso'
-> $output = border coordinates -> AJAX success function
generates a new L.geoJSON
of the border coordinates of that country.
What I need help with:
This is the example PHP file I was given which of course is a bit naff:
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$executionStartTime = microtime(true);
$result=file_get_contents('C:\xampp\htdocs\project1\vendors\json\countryBorders.geo.json');
$decode = json_decode($result,true);
$output['status']['code'] = "200";
$output['status']['name'] = "ok";
$output['status']['description'] = "success";
$output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms";
$output['data'] = $decode;
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($output);
?>
I've tried to rewrite it and thought an foreach
statement would suffice, but I've hit a bit of a brick wall regarding how to search through a .json
file in PHP and capture the corresponding object's coordinate array.
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$start=microtime( true );
$file=file_get_contents('vendors\json\countryBorders.geo.json');
$json=json_decode($file, true);
foreach ($json->features->properties as $object) {
if ($object->iso_a3 == $_REQUEST['iso']) {
$output=array(
'border' => $object->coordinates,
'status' => array(
'code' => 200,
'name' => 'ok',
'description' => 'success',
'returnedIn' => intval( ( microtime( true ) - $start ) * 1000 ) . 'ms'
),
);
} else {
$output=$json;
}
}
header('Content-Type: application/json; charset=UTF-8');
exit( json_encode( $output ) );
?>
function setView() {
$.ajax({
url: "libs/php/getCountryBorders.php",
type: 'POST',
dataType: 'json',
data: {
iso: $('#countrySelect option:selected').val() //getting iso from the value in the option
},
success: function(result) {
if (result.status.name == "ok") {
console.log(result['border']); //currently just logging the result
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
}
});
};
Right now, the code isn't searching/iterating through the countryBorders.geo.json
and I get a number of errors:
{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
script.js:69 parsererror
script.js:70 SyntaxError: Unexpected token < in JSON at position 0
at parse (<anonymous>)
at jquery.min.js:2
at l (jquery.min.js:2)
at XMLHttpRequest.<anonymous> (jquery.min.js:2)
Warning: foreach() argument must be of type array|object, null given in C:\xampp\htdocs\project1\libs\php\getCountryBorders.php on line 13
– Ranisimo Aug 26 '21 at 14:52