generated from spatie/package-skeleton-laravel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
last checkpoint: include cities in the nested set model calculation
Previously, the contents of the country files were read and inserted into the database in chunks of 1000. Then the Nested Set Model is built by reading the hierarchy.txt file and updating the records in the database(slow). At this point, the Nested Set Model is built first by reading the hierarchy.txt file, and combining it with the contents of the admin2Codes.txt file which contains the hierarchy for cities(Even though geonames.org has up to ADM5 division, it cuts-off at ADM2 for cities). After the nestedSet is built, the country files contents is mapped into a Geoname with the nestedSet properties(_lft, _rgt, depth and parent_id) and inserted into the database
- Loading branch information
Showing
12 changed files
with
598 additions
and
256 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Parables\Geo\Actions; | ||
|
||
use Illuminate\Support\Arr; | ||
use Parables\Geo\Actions\Concerns\HasToastable; | ||
|
||
class GenNestedSetModelAction | ||
{ | ||
use HasToastable; | ||
|
||
/** | ||
* @param array<int|string,mixed> $hierarchy | ||
* @return array | ||
*/ | ||
public function execute(array $hierarchy = [], bool $nestChildren = false): array | ||
{ | ||
ini_set('memory_limit', -1); | ||
|
||
if (empty($hierarchy)) { | ||
$this->toastable->toast('Hierarchy is empty... Skipping ...', 'error'); | ||
return []; | ||
} | ||
|
||
return $this->buildTree(hierarchy: $hierarchy, nestChildren: $nestChildren); | ||
} | ||
|
||
|
||
/** | ||
* @param array<int|string,mixed> $hierarchy | ||
* @return array | ||
*/ | ||
public function buildTree(array $hierarchy, int &$index = 1, bool $nestChildren = false): array | ||
{ | ||
$this->toastable->toast('Building Root Node ...'); | ||
$rootId = array_key_first($hierarchy); | ||
$depth = 0; | ||
|
||
$root = [ | ||
'id' => $rootId, | ||
'_lft' => $index++, | ||
'_rgt' => null, | ||
'depth' => $depth, | ||
'parent_id' => null, | ||
]; | ||
|
||
$this->toastable->toast('Building Children Nodes ...'); | ||
$children = $this->buildNodes( | ||
hierarchy: $hierarchy, | ||
parentId: $rootId, | ||
index: $index, | ||
depth: $depth, | ||
nestChildren: $nestChildren | ||
); | ||
|
||
$root['_rgt'] = $index++; | ||
|
||
if ($nestChildren) { | ||
$root['children'] = $children; | ||
return $root; | ||
} | ||
$this->toastable->toast('Tree Built successfully...'); | ||
return [$rootId => $root] + $children; | ||
// return array_merge([$rootId => $root], $children); | ||
//$children[$rootId] = $root; | ||
//return $children; | ||
} | ||
|
||
/** | ||
* @param array<int|string,mixed> $hierarchy | ||
* @return array | ||
*/ | ||
public function buildNodes(array $hierarchy, string|int $parentId, int &$index, int $depth, bool $nestChildren = false): array | ||
{ | ||
$depth += 1; | ||
$result = []; | ||
$children = []; | ||
foreach ($this->children($hierarchy, $parentId) as $id) { | ||
$node = | ||
[ | ||
'id' => $id, | ||
'_lft' => $index++, | ||
'_rgt' => null, | ||
'depth' => $depth, | ||
'parent_id' => $parentId, | ||
]; | ||
|
||
$this->toastable->toast('Getting sub nodes for: ' . $id); | ||
$children = $this->buildNodes( | ||
hierarchy: $hierarchy, | ||
parentId: $id, | ||
index: $index, | ||
depth: $depth, | ||
nestChildren: $nestChildren | ||
); | ||
|
||
$node['_rgt'] = $index++; | ||
|
||
if ($nestChildren) { | ||
$node['children'] = $children; | ||
$result[$id] = $node; | ||
} else { | ||
$result = $result + [$id => $node] + $children; | ||
} | ||
} | ||
$this->toastable->toast('Done.'); | ||
return $result; | ||
} | ||
|
||
/** | ||
* @param array<int|string, mixed> $hierarchy | ||
*/ | ||
public function children(array $hierarchy, string|int $parentId): array | ||
{ | ||
$this->toastable->toast('Getting children for parentId: ' . $parentId); | ||
if (array_key_exists($parentId, $hierarchy)) { | ||
return $hierarchy[$parentId] ?? []; | ||
} | ||
return []; | ||
} | ||
|
||
/** | ||
* @param array $tree | ||
* @param array $result | ||
* @param bool $includeLeaves | ||
* @return mixed | ||
*/ | ||
function flattenTree(array $tree, array &$result = [], bool $includeLeaves = false) | ||
{ | ||
foreach ($tree as $key => $value) { | ||
if (is_array($value) && !empty($value)) { | ||
$result[$key] = array_keys($value); | ||
$this->flattenTree($value, $result, $includeLeaves); | ||
} else { | ||
if ($includeLeaves) { | ||
$result[$key] = []; | ||
} | ||
} | ||
} | ||
|
||
return $result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.