Skip to content
Snippets Groups Projects
Select Git revision
  • 0653c3181444c2c52ece5470b136be52cd5655b2
  • main default protected
  • backup-includeCitiesInInfo
  • includeCitiesInInfo
  • statusEndPoint
  • KombinereAPI
6 results

populasjonhandler.go

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    populasjonhandler.go 4.08 KiB
    package handelers
    
    import (
    	"encoding/json"
    	"fmt"
    	"math"
    	"net/http"
    	"strconv"
    	"strings"
    )
    
    // responsstruktur for befolkningsdata
    type PopulationResponse struct {
    	Error bool     `json:"error"`
    	Msg   string   `json:"msg"`
    	Data  []Country `json:"data"`
    }
    
    // land og dens befolkningsdata
    type Country struct {
    	Name             string            `json:"country"`
    	Code             string            `json:"iso3"` // Trebokstavskode (ISO 3166-1 alpha-3)
    	PopulationCounts []PopulationCount `json:"populationCounts"`
    }
    
    
    
    
    // befolkningsdate for et bestemt år (brukes i den endelige repsonsen under values)
    type PopulationCount struct {
    	Year  int `json:"year"`
    	Value int `json:"value"`
    }
    
    // Responsstruktur for vårt API(det som vises på skjerm)
    type PopulationAPIResponse struct {
    	Name           string            `json:"land"`
    	Gjennomsnitt   int               `json:"gjennomsnittlig populasjon"`
    	Values        []PopulationCount  `json:"årlige populasjoner"`
    }
    
    
    
    
    
    
    
    // ISO 3166-1 alpha-2 til alpha-3 landkoder
    var isoAlpha2ToAlpha3 = make(map[string]string)
    
    // Henter befolkningsdata fra eksternt API
    func fetchPopulationData() (*PopulationResponse, error) {
    	url := "https://countriesnow.space/api/v0.1/countries/population"
    	resp, err := http.Get(url)
    	if err != nil {
    		return nil, err
    	}
    	defer resp.Body.Close()
    
    	var data PopulationResponse
    	err = json.NewDecoder(resp.Body).Decode(&data)
    	if err != nil {
    		return nil, err
    	}
    
    	// Bygg dynamisk oppslagskart for landkoder
    	for _, country := range data.Data {
    		if len(country.Code) >= 2 {
    			isoAlpha2ToAlpha3[strings.ToUpper(country.Code[:2])] = country.Code // F.eks. NO → NOR
    		}
    	}
    
    	return &data, nil
    }
    
    // Henter befolkningsdata for et spesifikt land og filtrerer etter år
    func getPopulationForCountry(alpha2Code string, startYear, endYear int) (*PopulationAPIResponse, error) {
    	data, err := fetchPopulationData()
    	if err != nil {
    		return nil, err
    	}
    
    	// Konverter ISO 3166-1 alpha-2 til alpha-3
    	alpha3Code, exists := isoAlpha2ToAlpha3[strings.ToUpper(alpha2Code)]
    	if !exists {
    		return nil, fmt.Errorf("invalid country code: %s", alpha2Code)
    	}
    
    	// Finn landet basert på ISO 3166-1 alpha-3 kode
    	var countryData *Country
    	for _, c := range data.Data {
    		if c.Code == alpha3Code {
    			countryData = &c
    			break
    		}
    	}
    
    	if countryData == nil {
    		return nil, fmt.Errorf("country not found")
    	}
    
    	// Filtrer basert på år
    
    	// en tom liste fyllt med PopulationCount, altså fylles med spesifikke år og antall
    	var filteredValues []PopulationCount
    	var total int
    	count := 0
    
    	// itererer over alle verdiene som følger med et land sin populasjonsdata
    		// over alle årstall-verdi strukturene
    	for _, stk := range countryData.PopulationCounts {
    		if (startYear == 0 || stk.Year >= startYear) && (endYear == 0 || stk.Year <= endYear) {
    			filteredValues = append(filteredValues, stk)
    			total += stk.Value
    			count++
    		}
    	}
    
    	// Beregn gjennomsnitt
    	mean := 0
    	if count > 0 {
    		mean = int(math.Round(float64(total) / float64(count)))
    	}
    
    	return &PopulationAPIResponse{
    		Name:         countryData.Name,
    		Gjennomsnitt: mean,
    		Values:       filteredValues,
    	}, nil
    }
    
    
    
    
    func PopulationHandler(w http.ResponseWriter, r *http.Request) {
    	// r.URL.Path er den fulle URL som ble sendt til serveren altså /population/NO
    	// deretter fjerner den /population/ så vi sitter igjen med NO
        path := strings.TrimPrefix(r.URL.Path, "/population/")
    			// NO
    	countryCode := strings.ToUpper(path) // ISO 3166-2-kode
    
    
    	query := r.URL.RawQuery
    	limit := strings.Replace(query, "limit=","",1)
    
    
        startYear, endYear := 0, 0
    
        if len(limit)>0 {
            yearRange := strings.Split(limit, "-")
            if len(yearRange) == 2 {
                startYear, _ = strconv.Atoi(yearRange[0])
                endYear, _ = strconv.Atoi(yearRange[1])
            } else {
                fmt.Println("Year range format is incorrect")
            }
        }
    
        result, err := getPopulationForCountry(countryCode, startYear, endYear)
        if err != nil {
            http.Error(w, err.Error(), http.StatusNotFound)
            return
        }
    
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(result)
    }