Search code examples
jsonmaxp5.jsminimum

Finding the minimum and maximum value from an array in a JSON File in p5.js


I have a JSON data showing the bus shelters of Gold Coast

this is my data = https://data.gov.au/geoserver/gold-coast/wfs?request=GetFeature&typeName=ckan_be880d63_175a_4383_b0f2_ef88b831eba9&outputFormat=json

from there I want to find out the minimum and maximum latitude and longitude using p5.js and plot them on the graph here is my code up until now

function preload(){
  shelters = loadJSON('https://data.gov.au/geoserver/gold-coast/wfs?request=GetFeature&typeName=ckan_be880d63_175a_4383_b0f2_ef88b831eba9&outputFormat=json')
}

function setup() {
  createCanvas(400, 400`enter code here`);
  print(shelters)
  noLoop()
}

function draw() {
  background(220);
  bus  = shelters.features
  max_min()
  
}

function max_min(){
  for(let i = 0; i < bus.length; i ++ ){
    latitudes = createDiv('h1', bus[i].geometry.coordinate)
    max_lat = Math.max(latitudes)
  }
  console.log(...max_lat)
}

I am having trouble finding the max and min latitude and longitude


Solution

  • You have a few things which can't work in your code, let's first have a look at that:

    • First, in your createCanvas(400, 400``enter code here``); lines you have a syntax error here, you need to remove the enter code here string.

    • Then in your max_min() function, you iterate on all the buses and get bus[i].geometry.coordinate. My understanding is that this is an array containing the latitude and longitude of the bus, so using Math.max on this array will return the max value between the latitude and the longitude of the current bus, which is not what you want.

    You have several options to do what you want. If you really want to use Math.max() and Math.min() and are familiar with map you could:

    • Build an array of all the latitudes: bus.map(b => b.geometry.coordinates[0]) i.e take all the items in the bus array and transform that to an array with only the first item of each buse's geometry.coordinates property. (replace [0] by [1] to get the longitude)
    • Deconstruct it with the ... operator because Math.max() doesn't take an array but a list of arguments
    • And assign that to a value, you function would look like this:
    function max_min() {
        const maxLat = Math.max(...bus.map(b => b.geometry.coordinates[0]));
        const minLat = Math.min(...bus.map(b => b.geometry.coordinates[0]));
        const maxLong = Math.max(...bus.map(b => b.geometry.coordinates[1]));
        const minLong = Math.min(...bus.map(b => b.geometry.coordinates[1]));
    
        return { maxLat, minLat, maxLong, minLong };
    }
    
    

    Here the code is short but you iterate 4 times over the bus array, which is not especially efficient. So you could also take another approach where you would create a short helper function to get the latitude and longitude of a bus:

    // Given a feature return its latitude and longitude in an object
    function getLatLong(feature) {
        const [lat, long] = feature.geometry.coordinates;
        return { lat, long };
    }
    

    And then iterate over all the buses and given these information update the min and max values like this:

    // Find the max and min longitude and latitude and return them in an object
    function max_min() {
        // Use the first feature of the list to initialize the max and min values
        const { lat: firstLat, long: firstLong } = getLatLong(bus[0]);
        let maxLat = firstLat;
        let minLat = firstLat;
        let maxLong = firstLong;
        let minLong = firstLong;
    
        // Iterate through all the features to update the max and min values
        for (let i = 1; i < bus.length; i++) {
            const { lat, long } = getLatLong(bus[i]);
            if (lat > maxLat) {
                maxLat = lat;
            }
            if (lat < minLat) {
                minLat = lat;
            }
            if (long > maxLong) {
                maxLong = long;
            }
            if (long < minLong) {
                minLong = long;
            }
        }
    
        // Return the updated max and min values
        return { maxLat, minLat, maxLong, minLong };
    }
    

    Finally in draw() you can do whatever you want with them, for the example I only write them in the canvas:

    function draw() {
        background(220);
    
        // Get the max and min values with our helper function
        const { maxLat, minLat, maxLong, minLong } = max_min();
    
        // Show the values
        text(`max lat ${maxLat}`, 0, 10);
        text(`min lat ${minLat}`, 0, 30);
        text(`max long ${maxLong}`, 0, 50);
        text(`min long ${minLong}`, 0, 70);
    }
    

    I created this codepen with the complete code working so that you can have a look at how the parts work together.