Files
dev-chiefworks 47f4fad75c Added Other AP
2022-04-26 11:30:34 -04:00

150 lines
4.0 KiB
PHP

<?php
class HourlyAverages {
public static function get($db, $from_address, $to_address, $city, $country) {
$message = NULL;
$city_id = (int)$city;
$country_code = pg_escape_string($country);
$from_areas = [];
$to_areas = [];
$postal_areas = [];
$radius_areas = [];
$plygon_areas = [];
// Load areas for the city and country
$q = "SELECT * FROM geofence_area WHERE city_id=${city_id} AND country='${country_code}'";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
while ($f=pg_fetch_assoc($r)) {
if ($f["type"]=="postal") {
$postal_areas[] = $f;
}
if ($f["type"]=="radius") {
$radius_areas[] = $f;
}
if ($f["type"]=="polygon") {
$plygon_areas[] = $f;
}
$raw_areas[] = $f;
}
} else {
return [NULL,pg_last_error()];
}
if (count($postal_areas)<1 && count($radius_areas)<1 && count($plygon_areas)<1) {
return [NULL,"No areas defined for the city"];
}
$from_areas = AddressToArea::getAreasForAddress($db,$from_address,$postal_areas,$radius_areas,$plygon_areas);
if (!is_array($from_areas) || count($from_areas)<1) {
return [NULL,"Cannot geocode from address to an area"];
}
$to_areas = AddressToArea::getAreasForAddress($db,$to_address,$postal_areas,$radius_areas,$plygon_areas);
if (!is_array($to_areas) || count($to_areas)<1) {
return [NULL,"Cannot geocode to address to an area"];
}
$data = [];
$q = "SELECT * FROM geofence_area_average_quotes ";
$q.= " WHERE area_start_id=".$from_areas[0]["id"]." AND area_end_id=".$to_areas[0]["id"];
$q.= " ORDER BY transport_provider_id, hour";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
while ($f=pg_fetch_assoc($r)) {
if (!array_key_exists($f['transport_provider_id'],$data)) {
$data[$f['transport_provider_id']] = [];
}
$data[$f['transport_provider_id']][$f['hour']] = $f;
}
}
$certainty = HourlyAverages::calculateCertainty($data);
$result_areas = [
'from_areas' => $from_areas,
'to_areas' => $to_areas,
'hourlyaverages' => $data,
'certainty' => $certainty
];
return [$result_areas, $message];
}
public static function calculateCertainty($data) {
$vendors = []; // Vendors to process
$hours = []; // Transposition matrix
$Pi = []; // Certainity by vendor (current hour)
$Wi = []; // Weight by vendor (current hour)
$Si = []; // Sum by vendor per hout
$Ri = []; // Certainty per hour
foreach ($data as $key=>$val) {
$vendors[] = $key;
$Pi[$key] = 0;
$Wi[$key] = 0;
}
for ($i=0; $i<24; $i++) {
$hours[$i] = [];
$Si[$i] = 0;
$Ri[$i] = 0;
foreach ($vendors as $vendor) {
$hours[$i][$vendor] = NULL;
}
}
foreach ($data as $key=>$val) {
foreach ($val as $hour=>$f) {
$hours[$f['hour']][$f['transport_provider_id']] = [
'average_cost' => $f['average_cost'],
'average_total' => $f['average_total'],
'average_count' => $f['average_count']
];
$Si[$f['hour']] += $f['average_count'];
}
}
for ($i=0; $i<24; $i++) {
$d = $hours[$i];
foreach ($d as $vendor=>$f) {
if ($f===NULL) {
$Pi[$vendor] = 0;
} else {
if ($f['average_count']<10) {
$Pi[$vendor] = 0;
} else {
$Pi[$vendor] = 1-10/$f['average_count'];
}
if ($Si[$i]!==0) {
$Wi[$vendor] = $f['average_count']/$Si[$i];
} else {
$Wi[$vendor] = 0;
}
}
$Ri[$i] += 100.0 * $Pi[$vendor] * $Wi[$vendor];
}
}
return $Ri;
}
public static function getCityInfo($db, $cityId) {
$result = [];
$q = "SELECT gac.city, gac.country, atz.timezone
FROM geofence_area_city gac
LEFT JOIN address_view av on address_search @@ to_tsquery('simple', array_to_string(string_to_array(gac.city, ' '), ':* & ') || ':* & ' || gac.country)
LEFT JOIN address_timezone atz on av.timezone = atz.id
WHERE gac.id =${cityId}
LIMIT 1
";
$r = pg_query( $db, $q );
if ( $r && pg_num_rows( $r ) && $f = pg_fetch_assoc( $r ) ) {
$result = $f;
}
return $result;
}
}
// vi:ts=2