feat: accept ArcGIS ONSPD column aliases (PCD7/PCD8/PCDS) in postcodes:import
This commit is contained in:
@@ -41,8 +41,25 @@ final class ImportPostcodes extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
$headerCounts = array_count_values(array_map('strtolower', $header));
|
$headerCounts = array_count_values(array_map('strtolower', $header));
|
||||||
|
$columns = array_change_key_case(array_flip($header), CASE_LOWER);
|
||||||
|
|
||||||
foreach (['pcd', 'lat', 'long'] as $required) {
|
$pcdColumn = null;
|
||||||
|
|
||||||
|
foreach (['pcd', 'pcds', 'pcd7', 'pcd8'] as $candidate) {
|
||||||
|
if (isset($columns[$candidate])) {
|
||||||
|
$pcdColumn = $candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pcdColumn === null) {
|
||||||
|
$this->error('Missing required postcode column (expected one of: pcd, pcds, pcd7, pcd8).');
|
||||||
|
fclose($handle);
|
||||||
|
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ([$pcdColumn, 'lat', 'long'] as $required) {
|
||||||
if (($headerCounts[$required] ?? 0) > 1) {
|
if (($headerCounts[$required] ?? 0) > 1) {
|
||||||
$this->error("Column '{$required}' appears more than once — refusing to import.");
|
$this->error("Column '{$required}' appears more than once — refusing to import.");
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
@@ -51,9 +68,7 @@ final class ImportPostcodes extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$columns = array_change_key_case(array_flip($header), CASE_LOWER);
|
foreach (['lat', 'long'] as $required) {
|
||||||
|
|
||||||
foreach (['pcd', 'lat', 'long'] as $required) {
|
|
||||||
if (! isset($columns[$required])) {
|
if (! isset($columns[$required])) {
|
||||||
$this->error("Missing required column '{$required}'.");
|
$this->error("Missing required column '{$required}'.");
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
@@ -82,7 +97,7 @@ final class ImportPostcodes extends Command
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pcd = strtoupper(preg_replace('/\s+/', '', (string) $row[$columns['pcd']]));
|
$pcd = strtoupper(preg_replace('/\s+/', '', (string) $row[$columns[$pcdColumn]]));
|
||||||
|
|
||||||
if ($pcd === '' || strlen($pcd) < 5) {
|
if ($pcd === '' || strlen($pcd) < 5) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -63,6 +63,22 @@ CSV;
|
|||||||
->and(Postcode::find('BT11AA'))->toBeNull();
|
->and(Postcode::find('BT11AA'))->toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('accepts ArcGIS ONSPD exports that use PCD7 instead of PCD', function (): void {
|
||||||
|
$csv = <<<'CSV'
|
||||||
|
OBJECTID,PCD7,PCD8,PCDS,DOTERM,LAT,LONG,x,y
|
||||||
|
1,"SW1A 1AA","SW1A 1AA","SW1A 1AA","",51.501009,-0.141588,529090,179645
|
||||||
|
2,"M1 1AD","M1 1AD","M1 1AD","",53.480957,-2.237428,384730,398295
|
||||||
|
CSV;
|
||||||
|
|
||||||
|
$path = writeOnspdFixture($csv);
|
||||||
|
|
||||||
|
$this->artisan('postcodes:import', ['--file' => $path])->assertSuccessful();
|
||||||
|
|
||||||
|
expect(Postcode::count())->toBe(2)
|
||||||
|
->and(Postcode::find('SW1A1AA')->outcode)->toBe('SW1A')
|
||||||
|
->and(Postcode::find('M11AD')->outcode)->toBe('M1');
|
||||||
|
});
|
||||||
|
|
||||||
it('derives outcode centroids as the average of member postcodes', function (): void {
|
it('derives outcode centroids as the average of member postcodes', function (): void {
|
||||||
$csv = <<<'CSV'
|
$csv = <<<'CSV'
|
||||||
pcd,pcds,doterm,lat,long
|
pcd,pcds,doterm,lat,long
|
||||||
|
|||||||
Reference in New Issue
Block a user