|
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
|
3200
|
|
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
|
1399
|
|
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
|
4900
|
|
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
|
4127
|
|
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
|
1940
|
|
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
|
1494
|
|
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
|
1029
|
|
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
|
1986
|
|
IDEA
|
My team's current maintenance process uses the arcpy "List" functions to only grab tables and feature classes to avoid this issue, it would be nice if you could throw an entire EGDB workspace at the maintenance tools and have it only process what it's capable of.
... View more
08-23-2024
08:09 AM
|
0
|
0
|
1104
|
|
POST
|
My org's in the same boat so I can't tell you what the proper process is. Based on the docs I think the first parameter is the line geometry to test against and the second parameter is a point. You might have to intersect the buffered line against the points to get a sensible set, run NearestCoordinate against every point, find the closest one, then use that for your results.
... View more
08-16-2024
04:44 PM
|
0
|
0
|
1908
|
|
POST
|
Does NearestCoordinate work for your use case? This requires Pro 3.3 and/or Enterprise 11.3 but it looks like it returns the side info.
... View more
08-16-2024
04:18 PM
|
0
|
3
|
1918
|
|
POST
|
If you configure the polygon symbology there's a Wrench icon that lets you modify how many layers the symbol has, which also allows you to add effects to each layer. If you have a "Wave effect" on the outline you can get an approximate effect, or throw in an "Offset effect" so the waves don't clip into the polygon interior. Something like this: Keep playing with layer effects and you might be able to replicate a cloud effect better.
... View more
08-15-2024
11:16 AM
|
1
|
0
|
1106
|
|
POST
|
Here's a simple implementation that spits out a point feature class in Web Mercator and nullable long integer fields, should be easy to alter this to suit your needs from os import path
def workbook_to_fc(file_path: str, fc_path: str):
excel = arcpy.conversion.ExcelToTable(file_path, "memory\\fields")[0]
arcpy.management.CreateFeatureclass(*path.split(fc_path), "POINT", spatial_reference=arcpy.SpatialReference(3857))
fields = [[name, "LONG", alias, None, None, None] for _, name, alias in arcpy.da.SearchCursor(excel, "*")]
arcpy.management.AddFields(fc_path, fields)
... View more
08-15-2024
10:59 AM
|
0
|
1
|
1493
|
|
POST
|
The "Shape" field in spatial data is a wrapper around however the format stores the geometry data. This could be some sort of text or binary data field in the table, or a separate table that's joined to the attribute data in real time. Either way, ArcGIS has to recognize the data format as something that stores features, if it thinks it's just a standard table then it'll just show the raw field data at best. In short, if you have your data in a CSV file or something like that you'll need to convert it to a spatial dataset of some sort -- usually a feature class in a file geodatabase. For point data the XY Table to Point tool should be good enough. For more complex geometries you'll have to figure out how each record stores the data and either dig up an appropriate conversion tool or write your own using arcpy. Once the data is copied to a feature class it can take advantage of all the ArcGIS tools and workflows
... View more
08-01-2024
02:18 PM
|
0
|
1
|
2292
|
|
POST
|
This is a known issue with the latest builds of Chrome, a deprecated feature used to display that bar was removed. There should be a hotfix patch available for your deployment.
... View more
07-30-2024
02:05 PM
|
2
|
1
|
11091
|
| 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
|