Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
47ee8c2
are we on the right track
gregbunce Dec 10, 2020
c626ec6
get branch update from origin
gregbunce Dec 10, 2020
6aee1eb
Merge branch 'feat/road-name-calculation' of https://github.com/agrc/…
gregbunce Dec 10, 2020
3290cb4
remove hardcoded path
gregbunce Dec 10, 2020
e0b5985
add xml schema doc
gregbunce Dec 23, 2020
b17874c
docs: update reference data
steveoh Dec 24, 2020
d43c004
fix: make rules execute
steveoh Dec 24, 2020
ebb54bd
chore: create version information table
steveoh Dec 24, 2020
82aae2d
fix: editable is not yes no any longer
steveoh Dec 24, 2020
dd489c9
refactor: remove for py3
steveoh Dec 24, 2020
8367ebd
fix: syntax error
steveoh Dec 24, 2020
3ac1701
fix: return null instead of setting value to true
steveoh Dec 24, 2020
a66b50e
chore: remove readme
steveoh Dec 24, 2020
0874837
fix: add localhost connection
steveoh Dec 24, 2020
bdfa788
chore: add proproject
steveoh Dec 24, 2020
46e1445
chore: ignore pro project cruft
steveoh Dec 24, 2020
bbb3eb2
chore: update dictionary
steveoh Dec 24, 2020
245f9b2
chore: update readme
gregbunce Dec 30, 2020
37b315b
chore: add road xml data
gregbunce Dec 30, 2020
134215a
chore: make reference data a list
gregbunce Dec 30, 2020
cdc57c1
update sde file name
gregbunce Jan 5, 2021
ca6ed6f
update stage and prod sde conn file names
gregbunce Jan 5, 2021
9a26889
fix null to zero expression
gregbunce Jan 22, 2021
e52be3e
fix null to zero expression
gregbunce Jan 22, 2021
d8e0f41
fix upper calculations
gregbunce Jan 22, 2021
11cac04
update arcpy install to conda
gregbunce Mar 16, 2021
fa4748e
add rules testing for fullname
gregbunce Mar 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ __pycache__
.DS_Store
cov.xml
.coverage
pro-project/Index
pro-project/.backups
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@
"instafail",
"isort",
"keycodes",
"metas",
"pylint",
"pytest",
"ruletypes",
"sysgen",
"utrans",
"yapf"
]
],
}
3,366 changes: 3,366 additions & 0 deletions data/roads_edit.xml

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions pro-project/.pyHistory
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
table = "Roads_Edit"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chore: add this file to the .gitignore please

disabled_rule_value = 'rule disabled'  calculated_attribute = 'FULLNAME'  fields = ['NAME', 'POSTTYPE', 'POSTDIR', TEST_ATTRIBUTE]  values = [  [None, None, None, disabled_rule_value],  ['', '', '', disabled_rule_value],  [' ', ' ', ' ', disabled_rule_value]  ]
disabled_rule_value = 'rule disabled' calculated_attribute = 'FULLNAME' fields = ['NAME', 'POSTTYPE', 'POSTDIR', TEST_ATTRIBUTE] values = [  [None, None, None, disabled_rule_value],  ['', '', '', disabled_rule_value],  [' ', ' ', ' ', disabled_rule_value]  ]
disabled_rule_value = 'rule disabled'  calculated_attribute = 'FULLNAME'  fields = ['NAME', 'POSTTYPE', 'POSTDIR', 'UTRANS_NOTES']  values = [  [None, None, None, disabled_rule_value],  ['', '', '', disabled_rule_value],  [' ', ' ', ' ', disabled_rule_value]  ]
disabled_rule_value = 'rule disabled'  calculated_attribute = 'FULLNAME'  fields = ['NAME', 'POSTTYPE', 'POSTDIR', 'UTRANS_NOTES']  values = [  [None, None, None, disabled_rule_value],  ['', '', '', disabled_rule_value],  ['
disabled_rule_value = 'rule disabled' TEST_ATTRIBUTE = 'UTRANS_NOTES' calculated_attribute = 'FULLNAME' fields = ['NAME', 'POSTTYPE', 'POSTDIR', TEST_ATTRIBUTE] values = [  [None, None, None, disabled_rule_value],  ['', '', '', disabled_rule_value],  [' ', ' ', ' ', disabled_rule_value] ]
TABLE = table
with arcpy.da.InsertCursor(TABLE, fields) as cursor:  for value in values:  cursor.insertRow(value)
edit = arcpy.da.Editor("Roads_Edit")
edit = arcpy.da.Editor("C:\\Users\\gbunce\\AppData\\Roaming\\Esri\\ArcGISPro\\Favorites\\localhost@utrans_old.sde")
edit.startEditing(False, True)
edit.startOperation()
edit.stopOperation()
edit.stopEditing(True)
edit = arcpy.da.Editor("C:\\Users\\gbunce\\AppData\\Roaming\\Esri\\ArcGISPro\\Favorites\\localhost@utrans.sde") edit.startEditing(False, True) edit.startOperation() edit.stopOperation() edit.stopEditing(True)
edit = arcpy.da.Editor("C:\\Users\\gbunce\\AppData\\Roaming\\Esri\\ArcGISPro\\Favorites\\localhost@utrans.sde")
edit.startEditing(False, True) edit.startOperation()
edit.stopOperation() edit.stopEditing(True)
Binary file added pro-project/localhost@utrans.sde
Binary file not shown.
Binary file added pro-project/pro-project.aprx
Binary file not shown.
Binary file added pro-project/pro-project.tbx
Binary file not shown.
5 changes: 0 additions & 5 deletions pro-project/readme.md

This file was deleted.

40 changes: 29 additions & 11 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

```py
import arcpy
arcpy.management.EnableEnterpriseGeodatabase(r'...\utrans-attribute-rules\pro-project\localhost.sde', r'C:\Program Files\ESRI\License10.6\sysgen\keycodes')
arcpy.management.EnableEnterpriseGeodatabase(r'...\utrans-attribute-rules\pro-project\localhost@utrans.sde', r'C:\Program Files\ESRI\License10.6\sysgen\keycodes')
```

_If you receive errors, you may need to execute the following sql_
Expand All @@ -20,16 +20,34 @@
SET READ_COMMITTED_SNAPSHOT ON
```

1. import the XML Workspace for the existing UTRANS database
1. import the XML Workspace for the existing UTRANS roads data

```py
arcpy.management.ImportXMLWorkspaceDocument(r'...\utrans-attribute-rules\pro-project\localhost.sde', r'...\utrans-attribute-rules\data\STAGING.XML', 'SCHEMA_ONLY', None)
arcpy.management.ImportXMLWorkspaceDocument(r'...\utrans-attribute-rules\pro-project\localhost@utrans.sde', r'...\utrans-attribute-rules\data\roads_edit.XML', 'DATA', None)
```

1. import the reference data from [open sgid](https://gis.utah.gov/sgid/open-sgid/)

- County boundaries
- Metro Townships
- Municipal boundaries
- Utah state boundary
- Zip code boundaries
- National Grid
- Address system quadrants

```py
import arcpy
arcpy.env.workspace = r' ...\agrc@opensgid.sde'
in_features = ['opensgid.boundaries.county_boundaries','opensgid.boundaries.metro_townships','opensgid.boundaries.municipal_boundaries','opensgid.boundaries.state_boundary','opensgid.boundaries.zip_code_areas','opensgid.indices.national_grid','opensgid.location.address_system_quadrants']
out_location = r'...\utrans-attribute-rules\pro-project\localhost@utrans.sde'
arcpy.FeatureClassToGeodatabase_conversion(in_features, out_location)
```

1. Create a python conda workspace for the project

```sh
conda create --clone arcgispro-py3 --name utrans
conda create --name utrans
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: niiiiiice!

```

1. Activate the environment
Expand All @@ -38,6 +56,12 @@
activate utrans
```

1. install [arcpy](https://pro.arcgis.com/en/pro-app/latest/arcpy/get-started/installing-arcpy.htm)

```sh
conda install arcpy -c esri
```

1. install the development requirements

```sh
Expand All @@ -48,15 +72,9 @@

### Database Migrations

#### Add reference data

1. County boundaries
1. Municipal boundaries
1. Zip code boundaries

### Attribute Rules

1. add `localhost.sde`, `stage.sde`, and `prod.sde` to the pro-project
1. add `localhost@utrans.sde`, `stage@utrans.sde`, and `prod@utrans.sde` to the pro-project
1. Install attribute rules
- `python ar.py update --env=local, dev, prod`

Expand Down
121 changes: 107 additions & 14 deletions src/ar.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# * coding: utf8 *
'''
"""
ar

Usage:
Expand All @@ -13,41 +13,134 @@
--env=<env> local, dev, prod
-h --help Shows this screen
-v --version Shows the version
'''
"""

import os
from datetime import datetime
from pathlib import Path

import arcpy
from arcgisscripting import ExecuteError # pylint: disable=no-name-in-module
from docopt import docopt

import arcpy
from config.config import get_sde_path_for
from models.rule import RuleGroup
from rules import roads

VERSION = '1.0.0'

def get_rules(sde):
roads_rules = RuleGroup(sde, roads.TABLE, roads.RULES)

rules = {
'roads': roads_rules,
}

return [rules]
def get_rules(connection, specific_rule=None):
if specific_rule == 'ALL':
tables = [
roads.TABLE,
]

for table in tables:
table = str(Path(connection) / table)
attribute_rules = arcpy.Describe(table).attributeRules

calculation_rules = ';'.join([ar.name for ar in attribute_rules if 'Calculation' in ar.type])
constraint_rules = ';'.join([ar.name for ar in attribute_rules if 'Constraint' in ar.type])

if calculation_rules:
print(' deleting calculation rules: {}'.format(calculation_rules))
try:
arcpy.management.DeleteAttributeRule(
in_table=table,
names=calculation_rules,
type='CALCULATION',
)
print(' deleted')
except ExecuteError as error:
message, = error.args

if message.startswith('ERROR 002556'):
print(' rule already deleted, skipping...')
else:
raise error

if constraint_rules:
print(' deleting constraint rules {}'.format(constraint_rules))
try:
arcpy.management.DeleteAttributeRule(
in_table=table,
names=constraint_rules,
type='CONSTRAINT',
)
print(' deleted')
except ExecuteError as error:
message, = error.args

if message.startswith('ERROR 002556'):
print(' rule already deleted, skipping...')
else:
raise error

return []

roads_rules = RuleGroup(sde, roads.TABLE, roads.RULES)

def update_version(sde, version):
with arcpy.da.InsertCursor(in_table=os.path.join(sde, 'Version_Information'), field_names=['name', 'version', 'date']) as cursor:
if specific_rule is None:
return [roads_rules]

rules = {'roads': roads_rules}

return [rules[specific_rule]]


def create_tables(tables, connection):
for table_name in tables:
print('creating {}'.format(table_name))
try:
arcpy.management.CreateTable(connection, table_name)

field_metas = tables[table_name]

for field_meta in field_metas:
import pdb
pdb.set_trace()
arcpy.management.AddField(**field_meta)
except Exception as error:
print('skipping {}'.format(table_name))
raise error


def update_version(connection, version):
table = str(Path(connection) / 'version_information')
if not arcpy.Exists(table):
version_table = {
'version_information': [
{
'in_table': table,
'field_name': 'Name',
'field_type': 'TEXT',
'field_length': 255
},
{
'in_table': table,
'field_name': 'Version',
'field_type': 'TEXT',
'field_length': 255
},
{
'in_table': table,
'field_name': 'Date',
'field_type': 'DATE',
},
]
}

create_tables(version_table, connection)

with arcpy.da.InsertCursor(in_table=table, field_names=['name', 'version', 'date']) as cursor:
date = datetime.datetime.now()
date_string = str(date).split(' ')[0]
cursor.insertRow(('attribute rules', version, date_string))


if __name__ == '__main__':
'''Main entry point for program. Parse arguments and pass to engine module
'''
'''Main entry point for program. Parse arguments and pass to engine module'''
args = docopt(__doc__, version=VERSION)

sde = get_sde_path_for(args['--env'])
Expand Down
11 changes: 7 additions & 4 deletions src/models/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@

import os

from arcgisscripting import ExecuteError # pylint: disable=no-name-in-module

import arcpy
from arcgisscripting import ExecuteError # pylint: disable=no-name-in-module


class RuleGroup(object):
class RuleGroup():

def __init__(self, sde, table, metas):
self.name = table
Expand Down Expand Up @@ -44,12 +43,16 @@ def execute(self):
exists = False

if not exists:
editable = 'EDITABLE'
if rule.editable == 'no':
editable = 'NONEDITABLE'

args = {
'in_table': self.table_path,
'name': rule.rule_name,
'type': rule.type,
'script_expression': rule.arcade,
'is_editable': rule.editable,
'is_editable': editable,
'triggering_events': rule.triggers,
'description': rule.description,
'subtype': '',
Expand Down
2 changes: 1 addition & 1 deletion src/models/ruletypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from config import config


class BaseType(object):
class BaseType():

def __init__(self):
self.type = config.rule_types.calculation
Expand Down
1 change: 1 addition & 0 deletions src/rules/arcade/roads/fullNameCalculation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
return iif(isempty($feature.NAME), null, Upper(Trim(Replace(Concatenate([$feature.NAME, $feature.POSTTYPE, $feature.POSTDIR], " "), " ", " "))));
2 changes: 1 addition & 1 deletion src/rules/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
}}, true);'''

CONVERT_NULL_TO_ZERO = '''
write arcade here
iif(isempty($feature.{0}) || $feature.{0} == '<null>', 0, true);
'''


Expand Down
7 changes: 4 additions & 3 deletions src/rules/roads.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
A module that holds the rules for the roads
'''

from . import common
from config import config
from services.loader import load_rule_for
from models.ruletypes import Calculation, Constant, Constraint
from services.loader import load_rule_for

from . import common

TABLE = 'Roads_Edit'
FOLDER = 'roads'
Expand All @@ -29,7 +30,7 @@
toaddress_right_calculation.triggers = [config.triggers.insert, config.triggers.update]

name_calculation = Calculation('Name', 'NAME', 'Upper(\'NAME\')')
alias_name_calculation = Calculation('Alias Name', 'A1_NAME', 'Upper(\'A1_AME\')')
alias_name_calculation = Calculation('Alias Name', 'A1_NAME', 'Upper(\'A1_NAME\')')
alias_alternate_name_calculation = Calculation('Alternate Alias Name', 'A2_NAME', 'Upper(\'A2_NAME\')')

predir_domain_constraint = Constraint('Prefix direction', 'PREDIR', common.constrain_to_domain('PREDIR', allow_null=True, domain='PreDirDomainName'))
Expand Down
Loading