199 lines
6.7 KiB
PHP
199 lines
6.7 KiB
PHP
<?php
|
|
/**
|
|
* Comarca resolution: maps incident towns to the comarques around Font del Bosc.
|
|
*
|
|
* @package Fontdelbosc_Transit
|
|
*/
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* Town-to-comarca mapping for Alt Penedès, Anoia, Baix Llobregat and Garraf.
|
|
*/
|
|
class Fontdelbosc_Transit_Comarques {
|
|
|
|
/**
|
|
* Supported comarca keys and their labels.
|
|
*
|
|
* @var array<string, string>
|
|
*/
|
|
public const COMARQUES = array(
|
|
'altpenedes' => 'Alt Penedès',
|
|
'anoia' => 'Anoia',
|
|
'baixllobregat' => 'Baix Llobregat',
|
|
'garraf' => 'Garraf',
|
|
);
|
|
|
|
/**
|
|
* Normalized town name to comarca key.
|
|
*
|
|
* @var array<string, string>
|
|
*/
|
|
public const TOWN_COMARCA = array(
|
|
/* Alt Penedès */
|
|
'AVINYONETDELPENEDES' => 'altpenedes',
|
|
'LESCABANES' => 'altpenedes',
|
|
'CASTELLVIDELAMARCA' => 'altpenedes',
|
|
'FONTRUBI' => 'altpenedes',
|
|
'GELIDA' => 'altpenedes',
|
|
'LAGRANADA' => 'altpenedes',
|
|
'MEDIONA' => 'altpenedes',
|
|
'OLERDOLA' => 'altpenedes',
|
|
'OLESADEBONESVALLS' => 'altpenedes',
|
|
'PACSDELPENEDES' => 'altpenedes',
|
|
'PLADELPENEDES' => 'altpenedes',
|
|
'PONTONS' => 'altpenedes',
|
|
'PUIGDALBER' => 'altpenedes',
|
|
'SANTCUGATSESGARRIGUES' => 'altpenedes',
|
|
'SANTLLORENCDHORTONS' => 'altpenedes',
|
|
'SANTMARTISARROCA' => 'altpenedes',
|
|
'SANTPEREDERIUDEBITLLES' => 'altpenedes',
|
|
'SANTQUINTIDEMEDIONA' => 'altpenedes',
|
|
'SANTAFEDELPENEDES' => 'altpenedes',
|
|
'SANTSADURNIDANOIA' => 'altpenedes',
|
|
'SANTAMARGARIDAILSMONJOS' => 'altpenedes',
|
|
'SANTAMARGARIDAIELSMONJOS' => 'altpenedes',
|
|
'SUBIRATS' => 'altpenedes',
|
|
'TORRELAVIT' => 'altpenedes',
|
|
'TORRELLESDEFOIX' => 'altpenedes',
|
|
'VILAFRANCADELPENEDES' => 'altpenedes',
|
|
'VILOVIDELPENEDES' => 'altpenedes',
|
|
/* Anoia */
|
|
'IGUALADA' => 'anoia',
|
|
'ODENA' => 'anoia',
|
|
'VILANOVADELCAMI' => 'anoia',
|
|
'SANTAMARGARIDADEMONTBUI' => 'anoia',
|
|
'POBLADECLARAMUNT' => 'anoia',
|
|
'JORBA' => 'anoia',
|
|
'PIERA' => 'anoia',
|
|
'CABRERADANOIA' => 'anoia',
|
|
'CAPELLADES' => 'anoia',
|
|
'CARME' => 'anoia',
|
|
'BRUC' => 'anoia',
|
|
'CASTELLFOLLITDERIUBREGOS' => 'anoia',
|
|
'CASTELLOLI' => 'anoia',
|
|
'COPONS' => 'anoia',
|
|
'ESTARAS' => 'anoia',
|
|
'RUBIO' => 'anoia',
|
|
'SANTMARTISESGUEIOLES' => 'anoia',
|
|
'SANTPERESALLAVINERA' => 'anoia',
|
|
'PUJALT' => 'anoia',
|
|
'PRATSDEREI' => 'anoia',
|
|
'VECIANA' => 'anoia',
|
|
'MONTMANEU' => 'anoia',
|
|
'ARGENSOLA' => 'anoia',
|
|
'BELLPRAT' => 'anoia',
|
|
/* Baix Llobregat */
|
|
'CORNELLADELLOBREGAT' => 'baixllobregat',
|
|
'SANTBOIDELLOBREGAT' => 'baixllobregat',
|
|
'SANTFEIUDELLOBREGAT' => 'baixllobregat',
|
|
'SANTJUSTDESVERN' => 'baixllobregat',
|
|
'ESPLUGUESDELLOBREGAT' => 'baixllobregat',
|
|
'SANTJOANDESPI' => 'baixllobregat',
|
|
'SANTVICENSDELSHORTS' => 'baixllobregat',
|
|
'SANTACOLOMADECERVELLO' => 'baixllobregat',
|
|
'SANTCLIMENTDELLOBREGAT' => 'baixllobregat',
|
|
'TORRELLESDELLOBREGAT' => 'baixllobregat',
|
|
'VILADECANS' => 'baixllobregat',
|
|
'PRATDELLOBREGAT' => 'baixllobregat',
|
|
'HOSPITALETDELLOBREGAT' => 'baixllobregat',
|
|
'CERVELLO' => 'baixllobregat',
|
|
'CORBERADELLOBREGAT' => 'baixllobregat',
|
|
'PALMADECERVELLO' => 'baixllobregat',
|
|
'PALLEJA' => 'baixllobregat',
|
|
'PAPIOL' => 'baixllobregat',
|
|
'MOLINSDEREI' => 'baixllobregat',
|
|
'SANTANDREUDELABARCA' => 'baixllobregat',
|
|
'CASTELLDEFELS' => 'baixllobregat',
|
|
'GAVA' => 'baixllobregat',
|
|
'BEGUES' => 'baixllobregat',
|
|
'ABRERA' => 'baixllobregat',
|
|
'MARTORELL' => 'baixllobregat',
|
|
'SANTESTEVESESROVIRES' => 'baixllobregat',
|
|
'CASTELLVIDEROSANES' => 'baixllobregat',
|
|
'COLLBATO' => 'baixllobregat',
|
|
'ESPARREGUERA' => 'baixllobregat',
|
|
'OLESADEMONTSERRAT' => 'baixllobregat',
|
|
'VALLIRANA' => 'baixllobregat',
|
|
/* Garraf */
|
|
'VILANOVAILAGELTRU' => 'garraf',
|
|
'SITGES' => 'garraf',
|
|
'CUBELLES' => 'garraf',
|
|
'CANYELLES' => 'garraf',
|
|
'SANTPEREDERIBES' => 'garraf',
|
|
'OLIVELLA' => 'garraf',
|
|
'GARRAF' => 'garraf',
|
|
);
|
|
|
|
/**
|
|
* Resolve the comarca key of an incident from its town.
|
|
*
|
|
* @param array<mixed> $incident Normalized incident.
|
|
* @return string Comarca key, or '' when unknown.
|
|
*/
|
|
public static function comarca_of( array $incident ): string {
|
|
$town = Fontdelbosc_Transit_Payload::str( $incident['town'] ?? null ) ?? '';
|
|
|
|
if ( '' === $town ) {
|
|
return '';
|
|
}
|
|
|
|
return self::TOWN_COMARCA[ self::normalize_town( $town ) ] ?? '';
|
|
}
|
|
|
|
/**
|
|
* Normalize a town name for lookup: uppercase, unaccented, letters only.
|
|
*
|
|
* @param string $town Raw town name.
|
|
* @return string
|
|
*/
|
|
public static function normalize_town( string $town ): string {
|
|
$ascii = iconv( 'UTF-8', 'ASCII//TRANSLIT', $town );
|
|
|
|
if ( false === $ascii ) {
|
|
$ascii = $town;
|
|
}
|
|
|
|
return preg_replace( '/[^A-Z]/', '', strtoupper( $ascii ) ) ?? '';
|
|
}
|
|
|
|
/**
|
|
* Parse a comma-separated comarca attribute into valid, unique keys.
|
|
*
|
|
* @param string $attr Raw attribute value, e.g. "anoia, garraf".
|
|
* @return array<int, string>
|
|
*/
|
|
public static function keys_from_attr( string $attr ): array {
|
|
$keys = array();
|
|
|
|
foreach ( explode( ',', $attr ) as $part ) {
|
|
$key = sanitize_key( trim( $part ) );
|
|
|
|
if ( '' !== $key && self::is_valid( $key ) && ! in_array( $key, $keys, true ) ) {
|
|
$keys[] = $key;
|
|
}
|
|
}
|
|
|
|
return $keys;
|
|
}
|
|
|
|
/**
|
|
* Whether a comarca key is supported.
|
|
*
|
|
* @param string $key Comarca key.
|
|
* @return bool
|
|
*/
|
|
public static function is_valid( string $key ): bool {
|
|
return isset( self::COMARQUES[ $key ] );
|
|
}
|
|
|
|
/**
|
|
* Label of a comarca key.
|
|
*
|
|
* @param string $key Comarca key.
|
|
* @return string
|
|
*/
|
|
public static function label( string $key ): string {
|
|
return self::COMARQUES[ $key ] ?? '';
|
|
}
|
|
}
|