From d22d8f9d567433639557328b64f5c751311a7456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Antoine=20Marcus=20Dupr=C3=A9?= Date: Tue, 14 Nov 2023 14:59:26 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=93=9D=20[DOC]=20Improve=20help=20and?= =?UTF-8?q?=20doc=20for=20`loadinfrastructure`=20admin=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/install/import.rst | 115 ++++++++++++++---- .../management/commands/loadinfrastructure.py | 47 ++++--- 2 files changed, 124 insertions(+), 38 deletions(-) diff --git a/docs/install/import.rst b/docs/install/import.rst index c5f3a772f9..80ad05aad9 100644 --- a/docs/install/import.rst +++ b/docs/install/import.rst @@ -460,57 +460,61 @@ Import Infrastructure :: - usage: manage.py loadinfrastructure [-h] [--use-structure] [--encoding ENCODING] [--name-field NAME_FIELD] [--type-field TYPE_FIELD] [--category-field CATEGORY_FIELD] - [--condition-field CONDITION_FIELD] [--structure-field STRUCTURE_FIELD] [--description-field DESCRIPTION_FIELD] [--year-field YEAR_FIELD] - [--type-default TYPE_DEFAULT] [--category-default CATEGORY_DEFAULT] [--name-default NAME_DEFAULT] [--condition-default CONDITION_DEFAULT] - [--structure-default STRUCTURE_DEFAULT] [--description-default DESCRIPTION_DEFAULT] [--eid-field EID_FIELD] [--year-default YEAR_DEFAULT] - [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks] - point_layer + usage: manage.py loadinfrastructure [-h] [--use-structure] [--encoding ENCODING] [--name-field NAME_FIELD] + [--type-field TYPE_FIELD] [--category-field CATEGORY_FIELD] [--condition-field CONDITION_FIELD] + [--structure-field STRUCTURE_FIELD] [--description-field DESCRIPTION_FIELD] [--year-field YEAR_FIELD] + [--type-default TYPE_DEFAULT] [--category-default CATEGORY_DEFAULT] [--name-default NAME_DEFAULT] + [--condition-default CONDITION_DEFAULT] [--structure-default STRUCTURE_DEFAULT] + [--description-default DESCRIPTION_DEFAULT] [--eid-field EID_FIELD] [--year-default YEAR_DEFAULT] [--version] + [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] + [--skip-checks] point_layer - Load a layer with point geometries in te structure model + Load a layer with point geometries and import features as infrastructures objects (expected formats: shapefile or geojson) positional arguments: point_layer optional arguments: -h, --help show this help message and exit - --use-structure Allow to use structure for condition and type of infrastructures + --use-structure If set the given (or default) structure is used to select or create conditions and types of infrastructures. --encoding ENCODING, -e ENCODING File encoding, default utf-8 --name-field NAME_FIELD, -n NAME_FIELD - Base url + The field to be imported as the `name` of the infrastructure --type-field TYPE_FIELD, -t TYPE_FIELD - Base url + The field to select or create the type value of the infrastructure (field `InfrastructureType.label`) --category-field CATEGORY_FIELD, -i CATEGORY_FIELD - Base url + The field to select or create the type value of the infrastructure (field `InfrastructureType.type`) --condition-field CONDITION_FIELD, -c CONDITION_FIELD - Base url + The field to select or create the condition value of the infrastructure (field `InfrastructureCondition.label`) --structure-field STRUCTURE_FIELD, -s STRUCTURE_FIELD - Base url + The field to be imported as the structure of the infrastructure --description-field DESCRIPTION_FIELD, -d DESCRIPTION_FIELD - Base url + The field to be imported as the description of the infrastructure --year-field YEAR_FIELD, -y YEAR_FIELD - Base url + The field to be imported as the `implantation_year` of the infrastructure --type-default TYPE_DEFAULT - Default type of infrastructure, it will create the type if it doesn't exist + Default type for all infrastructures, fallback for entries without a type. --category-default CATEGORY_DEFAULT - Category by default for all infrastructures, B by default + Default category for all infrastructures, "B" by default. Fallback for entries without a category --name-default NAME_DEFAULT - Base url + Default name for all infrastructures, fallback for entries without a name --condition-default CONDITION_DEFAULT - Default Condition for all infrastructures, it will create the condition if it doesn't exist + Default condition for all infrastructures, fallback for entries without a category --structure-default STRUCTURE_DEFAULT Default Structure for all infrastructures --description-default DESCRIPTION_DEFAULT - Default description for all infrastructures + Default description for all infrastructures, fallback for entries without a description --eid-field EID_FIELD External ID field --year-default YEAR_DEFAULT - Default year for all infrastructures + Default year for all infrastructures, fallback for entries without a year --version show program's version number and exit -v {0,1,2,3}, --verbosity {0,1,2,3} Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output - --settings SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used. + --settings SETTINGS + The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, + the DJANGO_SETTINGS_MODULE environment variable will be used. --pythonpath PYTHONPATH A directory to add to the Python path, e.g. "/home/djangoprojects/myproject". --traceback Raise on CommandError exceptions @@ -519,6 +523,73 @@ Import Infrastructure --skip-checks Skip system checks. +Load a layer with point geometries and import entities as infrastructures objects. + +- expected formats for the `point_layer` file are shapefile or geojson (other geodjango supported-formats may work but untested), +- the command updates existing Infrastructure objects based on the `eid` field (external ID), +- if the Infrastructure object does not exist (or if `eid` is not specified) it is created. + + +**Usage example** + +:: + + sudo geotrek loadinfrastructure \ + --name-field "shpname" \ + --type-field "shptype" \ + --description-field "shpdesc" \ + --year-field "shpyear" \ + --eid-field "shpid" \ + --condition-default "Badly damaged" \ + --year-default "2023" \ + --category-default "A" \ + ./infrastructures_to_be_imported.shp + +- The command expects entries from `point_layer` file to have the the following fields: `shpname`, `shptype`, `shpdesc`, `shpyear` and `shpid`. +- A default value is provided for the condition. It will be set for all imported infrastructures. +- A default value is provided for the year in addition to the field mapping. In case the shapefile entry does not have a year attribute the command will take the default value instead. +- The command will select or create InfrastructureType values based on the `type` argument, taking the default value "A" for the category. + +**Required fields** + +The following fields are mandatory to create an Infrastructure object: `name`, `type` and `category`. For each of those fields either an import field and/or a default value MUST be provided. If the command is unable to determine values for those fields for a given layer, the layer is skipped with an error message. + +**Default values** + +- When a default value is provided without a fieldname to import the default value is set for all Infrastructure objects. +- When a default value is provided in addition to a fieldname to import it is used as a fallback for entries without the specified import field. + +**Selection and addition of parameterized values** + +Infrastructure objects have several values from Geotrek's parameterized values sets: + +- `type` from InfrastructureType values (and `category` which is implied by the `type` value), +- `condition` from InfrastructureCondition values. + +New parameterized values are created and added to Geotrek Admin if necessary. The command checks if the imported `type` value already exists by looking for an InfrastructureType with the right `type` + `category`. + +:: + + sudo geotrek loadinfrastructure --type-field "type" --category-field "cat" [...] + +Selected or added InfrastructureType value: + + - label <- value of `type` import field + - type <- value of `cat` import field + - optionnally if `--use-structure`: structure <- the structure value (import field or default) + +For InfrastructureCondition the check uses the `condition` argument. + +:: + + sudo geotrek loadinfrastructure --condition-field "cond" [...] + +Selected or added InfrastructureCondition value: + + - label <- value of `cond` field + - optionnally if `--use-structure`: structure <- the structure value (import field or default) + + Import Dive ----------- diff --git a/geotrek/infrastructure/management/commands/loadinfrastructure.py b/geotrek/infrastructure/management/commands/loadinfrastructure.py index 893a22d228..d854c136cd 100644 --- a/geotrek/infrastructure/management/commands/loadinfrastructure.py +++ b/geotrek/infrastructure/management/commands/loadinfrastructure.py @@ -15,38 +15,53 @@ class Command(BaseCommand): - help = 'Load a layer with point geometries in te structure model\n' + help = ( + "Load a layer with point geometries and import features as infrastructures objects " + "(expected formats: shapefile or geojson)" + ) can_import_settings = True counter = 0 def add_arguments(self, parser): parser.add_argument('point_layer') parser.add_argument('--use-structure', action='store_true', dest='use_structure', default=False, - help='Allow to use structure for condition and type of infrastructures') + help='If set the given (or default) structure is used to select or create ' + 'conditions and types of infrastructures.') parser.add_argument('--encoding', '-e', action='store', dest='encoding', default='utf-8', help='File encoding, default utf-8') - parser.add_argument('--name-field', '-n', action='store', dest='name_field', help='Base url') - parser.add_argument('--type-field', '-t', action='store', dest='type_field', help='Base url') - parser.add_argument('--category-field', '-i', action='store', dest='category_field', help='Base url') - parser.add_argument('--condition-field', '-c', action='store', dest='condition_field', help='Base url') - parser.add_argument('--structure-field', '-s', action='store', dest='structure_field', help='Base url') - parser.add_argument('--description-field', '-d', action='store', dest='description_field', help='Base url') - parser.add_argument('--year-field', '-y', action='store', dest='year_field', help='Base url') + parser.add_argument('--name-field', '-n', action='store', dest='name_field', + help='The field to be imported as the `name` of the infrastructure') + parser.add_argument('--type-field', '-t', action='store', dest='type_field', + help='The field to select or create the type value of the infrastructure ' + '(field `InfrastructureType.label`)') + parser.add_argument('--category-field', '-i', action='store', dest='category_field', + help='The field to select or create the type value of the infrastructure ' + '(field `InfrastructureType.type`)') + parser.add_argument('--condition-field', '-c', action='store', dest='condition_field', + help='The field to select or create the condition value of the infrastructure ' + '(field `InfrastructureCondition.label`)') + parser.add_argument('--structure-field', '-s', action='store', dest='structure_field', + help='The field to be imported as the structure of the infrastructure') + parser.add_argument('--description-field', '-d', action='store', dest='description_field', + help='The field to be imported as the description of the infrastructure') + parser.add_argument('--year-field', '-y', action='store', dest='year_field', + help='The field to be imported as the `implantation_year` of the infrastructure') parser.add_argument('--type-default', action='store', dest='type_default', - help="Default type of infrastructure, it will create the type if it doesn't exist") + help="Default type for all infrastructures, fallback for entries without a type.") parser.add_argument('--category-default', action='store', dest='category_default', - help='Category by default for all infrastructures, B by default', default='B') - parser.add_argument('--name-default', action='store', dest='name_default', help='Base url') + help='Default category for all infrastructures, "B" by default. Fallback for entries ' + 'without a category', default='B') + parser.add_argument('--name-default', action='store', dest='name_default', + help='Default name for all infrastructures, fallback for entries without a name') parser.add_argument('--condition-default', action='store', dest='condition_default', - help="Default Condition for all infrastructures, " - "it will create the condition if it doesn't exist") + help="Default condition for all infrastructures, fallback for entries without a category") parser.add_argument('--structure-default', action='store', dest='structure_default', help='Default Structure for all infrastructures') parser.add_argument('--description-default', action='store', dest='description_default', default="", - help='Default description for all infrastructures') + help='Default description for all infrastructures, fallback for entries without a description') parser.add_argument('--eid-field', action='store', dest='eid_field', help='External ID field') parser.add_argument('--year-default', action='store', dest='year_default', - help='Default year for all infrastructures') + help='Default year for all infrastructures, fallback for entries without a year') def handle(self, *args, **options): verbosity = options.get('verbosity') From ab17fa070334422583ec040f9365cd5a721444b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Antoine=20Marcus=20Dupr=C3=A9?= Date: Tue, 14 Nov 2023 15:05:13 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9D=20[DOC]=20Reorder=20`loadinfra?= =?UTF-8?q?structure`=20arguments=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/install/import.rst | 78 +++++++++++-------- .../management/commands/loadinfrastructure.py | 29 +++---- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/docs/install/import.rst b/docs/install/import.rst index 80ad05aad9..215e7b7ed0 100644 --- a/docs/install/import.rst +++ b/docs/install/import.rst @@ -460,61 +460,77 @@ Import Infrastructure :: - usage: manage.py loadinfrastructure [-h] [--use-structure] [--encoding ENCODING] [--name-field NAME_FIELD] - [--type-field TYPE_FIELD] [--category-field CATEGORY_FIELD] [--condition-field CONDITION_FIELD] - [--structure-field STRUCTURE_FIELD] [--description-field DESCRIPTION_FIELD] [--year-field YEAR_FIELD] - [--type-default TYPE_DEFAULT] [--category-default CATEGORY_DEFAULT] [--name-default NAME_DEFAULT] - [--condition-default CONDITION_DEFAULT] [--structure-default STRUCTURE_DEFAULT] - [--description-default DESCRIPTION_DEFAULT] [--eid-field EID_FIELD] [--year-default YEAR_DEFAULT] [--version] - [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] - [--skip-checks] point_layer - - Load a layer with point geometries and import features as infrastructures objects (expected formats: shapefile or geojson) + usage: manage.py loadinfrastructure [-h] [--use-structure] [--encoding ENCODING] + [--name-field NAME_FIELD] [--name-default NAME_DEFAULT] + [--type-field TYPE_FIELD] [--type-default TYPE_DEFAULT] + [--category-field CATEGORY_FIELD] [--category-default CATEGORY_DEFAULT] + [--condition-field CONDITION_FIELD] [--condition-default CONDITION_DEFAULT] + [--structure-field STRUCTURE_FIELD] [--structure-default STRUCTURE_DEFAULT] + [--description-field DESCRIPTION_FIELD] [--description-default DESCRIPTION_DEFAULT] + [--year-field YEAR_FIELD] [--year-default YEAR_DEFAULT] + [--eid-field EID_FIELD] + [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] + [--no-color] [--force-color] [--skip-checks] + point_layer + + Load a layer with point geometries and import features as infrastructures objects + (expected formats: shapefile or geojson) positional arguments: point_layer optional arguments: -h, --help show this help message and exit - --use-structure If set the given (or default) structure is used to select or create conditions and types of infrastructures. + --use-structure + If set the given (or default) structure is used to select or create + conditions and types of infrastructures. --encoding ENCODING, -e ENCODING File encoding, default utf-8 --name-field NAME_FIELD, -n NAME_FIELD The field to be imported as the `name` of the infrastructure + --name-default NAME_DEFAULT + Default name for all infrastructures, fallback for entries without a name --type-field TYPE_FIELD, -t TYPE_FIELD - The field to select or create the type value of the infrastructure (field `InfrastructureType.label`) - --category-field CATEGORY_FIELD, -i CATEGORY_FIELD - The field to select or create the type value of the infrastructure (field `InfrastructureType.type`) - --condition-field CONDITION_FIELD, -c CONDITION_FIELD - The field to select or create the condition value of the infrastructure (field `InfrastructureCondition.label`) - --structure-field STRUCTURE_FIELD, -s STRUCTURE_FIELD - The field to be imported as the structure of the infrastructure - --description-field DESCRIPTION_FIELD, -d DESCRIPTION_FIELD - The field to be imported as the description of the infrastructure - --year-field YEAR_FIELD, -y YEAR_FIELD - The field to be imported as the `implantation_year` of the infrastructure + The field to select or create the type value of the infrastructure + (field `InfrastructureType.label`) --type-default TYPE_DEFAULT Default type for all infrastructures, fallback for entries without a type. + --category-field CATEGORY_FIELD, -i CATEGORY_FIELD + The field to select or create the type value of the infrastructure + (field `InfrastructureType.type`) --category-default CATEGORY_DEFAULT - Default category for all infrastructures, "B" by default. Fallback for entries without a category - --name-default NAME_DEFAULT - Default name for all infrastructures, fallback for entries without a name + Default category for all infrastructures, "B" by default. Fallback for entries + without a category + --condition-field CONDITION_FIELD, -c CONDITION_FIELD + The field to select or create the condition value of the infrastructure + (field `InfrastructureCondition.label`) --condition-default CONDITION_DEFAULT Default condition for all infrastructures, fallback for entries without a category + --structure-field STRUCTURE_FIELD, -s STRUCTURE_FIELD + The field to be imported as the structure of the infrastructure --structure-default STRUCTURE_DEFAULT Default Structure for all infrastructures + --description-field DESCRIPTION_FIELD, -d DESCRIPTION_FIELD + The field to be imported as the description of the infrastructure --description-default DESCRIPTION_DEFAULT - Default description for all infrastructures, fallback for entries without a description - --eid-field EID_FIELD - External ID field + Default description for all infrastructures, fallback for entries + without a description + --year-field YEAR_FIELD, -y YEAR_FIELD + The field to be imported as the `implantation_year` of the infrastructure --year-default YEAR_DEFAULT Default year for all infrastructures, fallback for entries without a year + --eid-field EID_FIELD + The field to be imported as the `eid` of the infrastructure (external ID) --version show program's version number and exit -v {0,1,2,3}, --verbosity {0,1,2,3} - Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output + Verbosity level; 0=minimal output, + 1=normal output, + 2=verbose output, + 3=very verbose output --settings SETTINGS - The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, - the DJANGO_SETTINGS_MODULE environment variable will be used. + The Python path to a settings module, e.g. "myproject.settings.main". + If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable + will be used. --pythonpath PYTHONPATH A directory to add to the Python path, e.g. "/home/djangoprojects/myproject". --traceback Raise on CommandError exceptions diff --git a/geotrek/infrastructure/management/commands/loadinfrastructure.py b/geotrek/infrastructure/management/commands/loadinfrastructure.py index d854c136cd..ebaad1567e 100644 --- a/geotrek/infrastructure/management/commands/loadinfrastructure.py +++ b/geotrek/infrastructure/management/commands/loadinfrastructure.py @@ -31,37 +31,38 @@ def add_arguments(self, parser): help='File encoding, default utf-8') parser.add_argument('--name-field', '-n', action='store', dest='name_field', help='The field to be imported as the `name` of the infrastructure') + parser.add_argument('--name-default', action='store', dest='name_default', + help='Default name for all infrastructures, fallback for entries without a name') parser.add_argument('--type-field', '-t', action='store', dest='type_field', help='The field to select or create the type value of the infrastructure ' '(field `InfrastructureType.label`)') + parser.add_argument('--type-default', action='store', dest='type_default', + help="Default type for all infrastructures, fallback for entries without a type.") parser.add_argument('--category-field', '-i', action='store', dest='category_field', help='The field to select or create the type value of the infrastructure ' '(field `InfrastructureType.type`)') - parser.add_argument('--condition-field', '-c', action='store', dest='condition_field', - help='The field to select or create the condition value of the infrastructure ' - '(field `InfrastructureCondition.label`)') - parser.add_argument('--structure-field', '-s', action='store', dest='structure_field', - help='The field to be imported as the structure of the infrastructure') - parser.add_argument('--description-field', '-d', action='store', dest='description_field', - help='The field to be imported as the description of the infrastructure') - parser.add_argument('--year-field', '-y', action='store', dest='year_field', - help='The field to be imported as the `implantation_year` of the infrastructure') - parser.add_argument('--type-default', action='store', dest='type_default', - help="Default type for all infrastructures, fallback for entries without a type.") parser.add_argument('--category-default', action='store', dest='category_default', help='Default category for all infrastructures, "B" by default. Fallback for entries ' 'without a category', default='B') - parser.add_argument('--name-default', action='store', dest='name_default', - help='Default name for all infrastructures, fallback for entries without a name') + parser.add_argument('--condition-field', '-c', action='store', dest='condition_field', + help='The field to select or create the condition value of the infrastructure ' + '(field `InfrastructureCondition.label`)') parser.add_argument('--condition-default', action='store', dest='condition_default', help="Default condition for all infrastructures, fallback for entries without a category") + parser.add_argument('--structure-field', '-s', action='store', dest='structure_field', + help='The field to be imported as the structure of the infrastructure') parser.add_argument('--structure-default', action='store', dest='structure_default', help='Default Structure for all infrastructures') + parser.add_argument('--description-field', '-d', action='store', dest='description_field', + help='The field to be imported as the description of the infrastructure') parser.add_argument('--description-default', action='store', dest='description_default', default="", help='Default description for all infrastructures, fallback for entries without a description') - parser.add_argument('--eid-field', action='store', dest='eid_field', help='External ID field') + parser.add_argument('--year-field', '-y', action='store', dest='year_field', + help='The field to be imported as the `implantation_year` of the infrastructure') parser.add_argument('--year-default', action='store', dest='year_default', help='Default year for all infrastructures, fallback for entries without a year') + parser.add_argument('--eid-field', action='store', dest='eid_field', + help='The field to be imported as the `eid` of the infrastructure (external ID)') def handle(self, *args, **options): verbosity = options.get('verbosity') From d34b5c9a6287e7dd765f5b354573276d9073ae12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Antoine=20Marcus=20Dupr=C3=A9?= Date: Tue, 14 Nov 2023 15:35:42 +0100 Subject: [PATCH 3/3] Update changelog --- docs/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index d72ac73d1b..0ca96f2fdd 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,10 @@ CHANGELOG - Fix missing geometries for HD `view_points` in APIv2's `/poi/` and `/site/` routes (#3701) - Fix cannot click on objects after customizing map styles (#3800) +**Documentation** + +- Improve help and doc for the `loadinfrastructure` command + 2.101.3 (2023-10-26) ------------------------