|
IDEA
|
This would be a fantastic addition to all versioned datasets, the interactive view is insufficient for auditing large volumes of changes.
... View more
09-18-2024
10:11 AM
|
0
|
0
|
727
|
|
POST
|
If you're up to using Python, you can combine this function: def get_related_objects(parent_path: str) -> list[str]:
from os import path
desc = arcpy.da.Describe(parent_path)
root = path.dirname(desc["catalogPath"])
return [path.join(root, x) for x in desc.get("relationshipClassNames", [])] with your preferred export tools to dump the parent object and all related objects.
... View more
09-18-2024
09:55 AM
|
1
|
1
|
965
|
|
POST
|
You can generate these lines database side using Attribute Rules. Use Intersects to get all towers within a given range, loop over the results and use Distance to find which point is closest, then use Geometry to construct a line from the input feature to the closest tower and insert the results into another table. Unfortunately, this is the inverse of what you want, so you won't get any lines until you submit the location, the lines won't appear in offline areas and you'll have to regularly truncate the feature classes for reference points and lines. Unless someone can post a better hack I think you're out of luck as there's no way to customize the client-side part of Field Maps like you've described. Might be worth an Idea submission!
... View more
09-12-2024
12:39 PM
|
1
|
1
|
980
|
|
POST
|
Have you tried mapping the old schema to the new one using the Append Tool's Field Mapping options? If that isn't comprehensive enough you can use Modelbuilder or Python to transform your data into a new format, then append that instead.
... View more
09-12-2024
12:15 PM
|
1
|
0
|
1119
|
|
POST
|
The Import Toolbox docs has a section on how you have to format your toolbox URL to load it into arcpy. Note that for most services, you can't just call the tool function and then move on, you have to spin loop over the "status" property of the result object that's returned until you get one that lets you proceed, the docs have more info.
... View more
09-05-2024
12:53 PM
|
0
|
1
|
996
|
|
POST
|
I think the next best step is to look over this sample widget and see if you can adapt this pattern to a functional component. The React Reference should have examples of all hooks in class and function formats.
... View more
09-05-2024
11:39 AM
|
0
|
0
|
2842
|
|
POST
|
Is it possible to check if the map view is null in the render step of the appropriate component and return a placeholder fragment if it's null instead of the proper widget fragment? Haven't played with custom widgets much but if the view manager is passed into the component's props then React should handle the rest.
... View more
09-05-2024
10:17 AM
|
0
|
2
|
2865
|
|
POST
|
Add a new column to your "choices" after "label" and name it "enabled" or some other name you like. For every choice set the column to 1 if it's enabled or 0 if it isn't. Then go back to the "survey" tab, go to the "choice_filter" column and set it to "enabled=1". Now the only choices in the form are those that you've enabled, but the entire list is intact for compatibility. This might cause issues with editing forms if older data is edited through the inbox instead of another ArcGIS app. One thing you can try is adding a hidden field with the default set to a version number, then every time you adjust the list you bump the version number and make the "enabled" value that version. Then you can do "(enabled = 3 and ${version} = 3) or (enabled = 2 and ${version} = 2)" etc. This isn't something I've tried personally but it should be a step in the right direction.
... View more
08-30-2024
02:39 PM
|
0
|
0
|
1213
|
|
POST
|
I figured I'd use this as way to not only fix your script tool, but demonstrate some common newbie Python mistakes and a way to fix them. This isn't a condemnation of your skills or anything, I too was a new programmer once! Anyways: import arcpy
from os import path
from csv import writer
from typing import Iterable, Iterator
def get_rows(dataset: str) -> Iterator[tuple[str, str, str, str]]:
"""
Yield the workspace name, dataset name, feature class name and feature count for
every feature class in a dataset.
"""
workspace, dataset_name = path.split(dataset)
# EnvManager doesn't work, save and restore workspace like this
old_workspace = arcpy.env.workspace
arcpy.env.workspace = workspace
for feature_class in arcpy.ListFeatureClasses(feature_dataset=dataset_name):
name = feature_class.split(".")[-1]
count = arcpy.management.GetCount(feature_class)[0]
yield workspace, dataset_name, name, count
arcpy.env.workspace = old_workspace
def main(datasets: Iterable[str], output: str):
"""
Write a table of feature counts from the selected datasets.
"""
with open(output, "w", newline="") as f:
csv_writer = writer(f)
csv_writer.writerow(("Geodatabase", "DataSet", "FeatureClass", "NumFeatures"))
for dataset in datasets:
for row in get_rows(dataset):
csv_writer.writerow(row)
def execute(params: list[arcpy.Parameter]):
datasets = params[0].valueAsText.split(";")
output = params[1].valueAsText
main(datasets, output)
if __name__ == "__main__":
execute(arcpy.GetParameterInfo()) Now for the notes: I've split this script into roughly 3 parts: main, execute and the "main guard". The main function is where the real work starts, but all parameters are expressed as standard Python data types. The execute function translates a list of Parameter objects into standard Python objects and calls main; this would also set derived outputs using values returned from main if that were useful. This separates "doing the work" from "dealing with parameter objects" which makes it easier to reason about your code. Finally, the "main guard" will check if this script is being executed directly and will pass all parameters as a list of Parameter objects into execute, kickstarting the process. This means I can independently test the main function by, say, replacing that last line with a direct call to main, which lets me use a Python IDE like Visual Studio Code and its debugger without any hassle. The lesson in short: try to apply a separation of concerns to your code and it'll be easier to write, test, rewrite etc. Use type annotations whenever you can! Pro 3.3 has pretty good type hints for arcpy now so applying hints to your own code will let you run type analysis through an IDE. This isn't a big issue for a small script like this, but if your code gets into the thousands of lines range they can save a ton of headaches. In this example I used some imports from the "typing" module to make my types more generic, sticking to the standard types like "list[str]" is perfectly fine if you're just getting into this. Speaking of imports, Python has a massive standard library and Pro comes with dozens of third-party packages to leverage. Here I'm using two standard modules: "os.path" to handle path string manipulation and "csv.writer" to write CSV data without worrying about text formatting, escape codes etc. etc. Thanks to this the multiple file write calls in your original example have been condensed to one foolproof call per feature class. Your original tool had separate parameters for the workspace and the feature datasets. I tried this myself and discovered that it doesn't play well with the parameter's data types. The script above just has one parameter for a list of feature datasets. All the user has to do is use the file picker that comes with the parameter definition and the tool gets a list of full dataset paths which we can easily extract the workspace and dataset name from using "os.path.split". The lesson: try to work with the various parameter types as best you can, you'll discover with practice which ones are helpful and which ones are not. The stuff I'm doing with the environment workspace is very hacky, unfortunately my copy of Pro has a bug with the new EnvManager context manager object so I have to write it this way to temporarily set the workspace. That said, in general you should not overwrite environment variables in your script unless it's 100% necessary, and if you do try to restore the old value. These variables are set by the user and it's expected that all tools will honor their values. My version of the script has exactly three comments: the docstring for the main function, the docstring for get_rows, and an aside for that EnvManager workaround. As counter-intuitive as it may seem, your code should strive to have as few comments as possible. This is an extremely common new programmer mistake that seems to be drilled into people's heads, mostly by teachers and administrators who either write very little code or are applying obsolete doctrine. Comments do not make your code do the correct thing: your code does that. Excess comments can obscure mistakes very easily and make your code difficult to read. If you've written a block of code and feel it needs to be documented, extract that code into a function and write a docstring like I've done here. Save your "#" comments for hacky workarounds, complex chains of logic and other nuances that can't be expressed in the function's docstring. Whoops, wrote a whole essay! Hope this provided some guidance for your future work, if anyone takes umbrage with these tips please reply, I'm sure I'm making some mistakes of my own.
... View more
08-29-2024
05:22 PM
|
1
|
1
|
4380
|
|
IDEA
|
Following the usual precedence for "old function but good" these would be Data Access functions, say: my_workspace = r"C:\path\to\data.gdb"
my_dataset = "ImportantItems"
# Get all feature classes as some sort of proper object, including any dataset objects
all_fcs = [f.name for f in arcpy.da.ListFeatureClasses(my_workspace)]
# Now just the dataset
dataset_fcs = [f.featureType for f in arcpy.da.ListFeatureClasses(f"{my_workspace}\\{my_dataset}")]
alternatively = [f.featureType for f in arcpy.da.ListFeatureClasses(my_workspace, feature_datasets=[my_dataset])]
# Why call many functions when you can call one?
everything = arcpy.da.ListObjects(my_workspace)
# But some database-side filtering is good for large workspaces
special_photos = arcpy.da.ListRasters(my_workspace, "county_*")
special_lines = arcpy.da.ListFeatureClasses(my_workspace, "river_*", "POLYLINE") You get the idea, lots of room for more feature-rich, less stateful functions that play better with all those new typestubs.
... View more
08-29-2024
04:10 PM
|
0
|
0
|
3815
|
|
POST
|
Easiest way I can think of is an Arcade expression in your pop-up, something like: var value = "7,6,1,7";
var lookup = {
"1": "Apple",
"2": "Banana",
"3": "Pear",
"4": "Orange",
"5": "Cherry",
"6": "Pineapple",
"7": "Pen"
};
var items = Split(value, ",")
var retval = ""
for (var i in items) {
retval += lookup[items[i]] + ", "
}
return Left(retval, Count(retval) - 2) Replace that "value" variable with whatever you need to do to get the field. This will involve maintaining the name to label lookup in both the form and the Arcade script.
... View more
08-29-2024
03:33 PM
|
2
|
0
|
1637
|
|
POST
|
If you rewrite that list comprehension expression as a standard for loop does it produce a better traceback?
... View more
08-29-2024
03:23 PM
|
0
|
1
|
1377
|
|
POST
|
The magic word when you write Inbox filters is "CURRENT_DATE" does that work on the report end?
... View more
08-26-2024
03:48 PM
|
0
|
1
|
904
|
|
POST
|
Huh, I've only seen this script re-writing process during web tool publishing, I guess it makes sense the same functions are used for templates. Anyways, when you run a python script through a publishing process a preprocessor looks for potential strings that refer to the local file system and replaces them with modified paths, this is what those ESRI_VARIABLEs are. The catch is when the preprocessor messes up it can produce invalid Python as you've seen above. I bumped into some arcpy and GP tool members in San Diego and they mentioned avoiding modern format strings for now as they haven't locked the parsing down yet. You can convert f-strings like so: # F-String
f"Hello {name}, you are {age:02d} years old!"
# str.format with keyword args
"Hello {name}, you are {age:02d} years old!".format(name=name, age=age)
#str.format with positional args
"Hello {}, you are {:02d} years old!".format(name, age) Your specific case might be fixed with a 3.3 upgrade but it might not, if your org needs a reason to upgrade you might as well chuck this on the pile.
... View more
08-23-2024
08:26 AM
|
1
|
1
|
1818
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 05-24-2023 11:47 AM | |
| 2 | 04-09-2026 11:36 AM | |
| 1 | 09-08-2023 10:07 AM | |
| 3 | 03-26-2026 08:11 AM | |
| 2 | 03-12-2026 01:41 PM |
| Online Status |
Offline
|
| Date Last Visited |
Friday
|