|
POST
|
Dan: I was trying to use your code, since I want to find the minimum distance to the actual vertice points in a polyline with the onMouseDownMap function of an addin tool. Here is the code I tried: class SplitLineToolClass(object):
"""Implementation for SplitLine_addin.SplitLinetool (Tool)"""
def __init__(self):
self.enabled = False
self.cursor = 3 # Crosshairs
def onMouseDownMap(self, x, y, button, shift):
# Pass if not a Left Mouse Button Click
if button != 1:
pass
return
addressLines = pythonaddins.GetSelectedTOCLayerOrDataFrame()
## Code that verifies a polyline layer is selected in the TOC
desc=arcpy.Describe(addressLines)
sr = arcpy.SpatialReference(desc.spatialReference.factoryCode)
origin = np.array([x,y],dtype="float64")
dests = arcpy.da.FeatureClassToNumPyArray(addressLines, ["SHAPE@X","SHAPE@Y"], "", sr, explode_to_points=True)
deltas = dests - origin
distances = np.hypot(deltas[:,0], deltas[:,1])
min_dist = np.min(distances)
wh = np.where(distances == min_dist)
closest = dests[wh[0]]
print("Closest Vertice = {0}".format(closest)) However, my adaptation of your code is throwing an error on the line that subtracts the two arrays (deltas = dests - origin on line 18 of the code above). Here is the error: Traceback (most recent call last): File ..., line ..., in onMouseDownMap deltas = dests - origin TypeError: unsupported operand type(s) for -: 'numpy.ndarray' and 'numpy.ndarray' When I added print lines for the origin and dest arrays, it showed that the Origin array created by line 16 is a list with a space a number a double space and a number, while the Dest array was a list of tuples containing two numbers separated by a comma and a space. What is the best way to get the two arrays compatible for line 18? Here is how the arrays printed: Origin Point = [ 6305489.12520918 2169986.76545799] Destination Points = [(6305087.957613736, 2169963.2243613005) (6305515.50958015, 2169962.629874304) ... (6305742.797839478, 2169860.239002958)] When I tried the "SHAPE@XY" field instead the result seemed worse: Destination Point = [([6305087.957613736, 2169963.2243613005],) ([6305515.50958015, 2169962.629874304],) ... ([6305742.797839478, 2169860.239002958],)]
... View more
03-27-2016
07:30 PM
|
0
|
6
|
6332
|
|
POST
|
Yes there was a missing parenthesis at the end of the Value Info expression. I have corrected the error in my post.
... View more
03-24-2016
07:20 AM
|
0
|
0
|
2457
|
|
POST
|
I wonder if somehow the geodatabases have been upgraded to 10.1 version and that is affecting Attribute Assistant, although I would have thought that would cause them to fail to draw in a 10.0 map. To test if Attribute Assistant is the problem I would create a new 10.0 geodatabase and two FCs with the same schema and names and run the rule on them to see if the error still occurs. It looks like Attribute Assistant was very new with 10.0, since it is not mentioned in the help and a blog was written by the Esri developers asking for user feedback on how it was being used. The link in that blog to the Attribute Assistant site now says only versions 10.1 and up are supported.
... View more
03-23-2016
07:57 AM
|
0
|
3
|
1415
|
|
POST
|
It looks like you can get a download of the 10.0 version here: http://www.arcgis.com/home/item.html?id=e35580f27bce4782b95ea8296ac60927 Let me know if that link has what you need.
... View more
03-22-2016
10:05 AM
|
1
|
5
|
1415
|
|
POST
|
I would use the EXPRESSION method, which can verify that the Node_ID field is not NULL before changing the other field to 1. The Expression record in the Dynamic Table must have been inserted after the record that intersects the node for this to work and the Rule Weight must be Equal To or Greater Than the value for the Rule Weight of the Node Intersect rule. OBJECTID * Table Name Field Name Value Method Value Info On Create On Change (Attribute) On Change (Geometry) Manual Only Rule Weight Comments 193 CENTERLINE CITY_LEFT EXPRESSION IIF(IsNull([NODE_ID]),[CITY_LEFT],1) False False False True 1 <Null> In the rule above, the expression determines if a field named NODE_ID is Null. If NODE_ID is Null it does not change the CITY_LEFT value (it sets the value of CITY_LEFT to itself so that it retains is current value), otherwise it sets CITY_LEFT to 1 Edit 3/24/2016 - Added missing end parenthesis to Value Info expression.
... View more
03-20-2016
05:29 PM
|
1
|
3
|
2457
|
|
POST
|
Here is an example of an INTERSECTING_FEATURE record in the DynamicValue table: OBJECTID * Table Name Field Name Value Method Value Info On Create On Change (Attribute) On Change (Geometry) Manual Only Rule Weight Comments 193 CENTERLINE CITY_LEFT INTERSECTING_FEATURE ZIP_CODES_WITH_CITIES|CITY|C True False True False 1 <Null> Table Name is the target layer with the field that needs to be completed by another intersecting layer Field Name is the field name in the target layer Value Method is INTERSECTING_FEATURE (any one of the Attribute Assistant methods) Value Info is made up of 3 components separated by a | character. The components are: Intersecting source Feature Class Name|Field Name in the source Feature Class|C(Centroid match) (alternatively I could have used P for Prompt for an option or F for using the first feature intersected) On Create is set to True so that the moment the feature creation is finished the attribute will be updated. On Change (Attribute) is set to False, since it doesn't need to refresh due to an attribute change. On Change (Geometry) is set to True so that any change in geometry refreshes the attribute (the intersecting feature should have been fixed first before the target feature geometry changes). Manual Only is false, but it could be true if I want to use the Attribute Assistant toolbar to force a refresh Rule Wieght is optional but I ususally set it to 1 Comments provides any explanation of the purpose or use of the rule. An Expression update does needs to have its Value Info written the same way you would write a VB Script field calculation. Use the field calculator to test your expressions and ask for help here if you have problems with a specific equation.
... View more
03-16-2016
02:57 PM
|
0
|
3
|
3540
|
|
POST
|
I downloaded the Address Data Management templates for the Local Government Information Model, since my main dataset deals with roads. However, it doesn't really matter which one you pick as far as the Attribute Assistant toolbar, since that will come with any of the templates and you would be customizing it for your specific needs anyway. So just download any of the LGIM templates to start.
... View more
03-13-2016
01:43 PM
|
1
|
1
|
3540
|
|
POST
|
You are correct. I never do this with the label expression and only use the field calculator since I always want to correct the items I noted in my amended response, but a label expression works for the data in this case.
... View more
03-10-2016
12:22 PM
|
0
|
1
|
2007
|
|
POST
|
Darren: I am sure you meant to use exclamation marks for the field delimiters with the Python Parser and not brackets, which are used with the VB Parser. So if the field is called "Name", the expression should instead be: !Name!.title() Capitalization will happen only for the first character at the beginning of the field and for the first alpha character that follows any white space, numbers, punctuation or special characters. So you have to check for things like numbered streets which will appear as "1St Street" to make it "1st Street". Also, no alpha characters of a word other than the first one will be capitalized, so you have to check for things like Scottish last names beginning with Mc to change "Mcdonald" to "McDonald". Also it capitalizes all words, including small words that normally are not capitalized in book titles like "a", "an", and "the".
... View more
03-10-2016
12:03 PM
|
2
|
3
|
2007
|
|
BLOG
|
The algorithm is definitely impacted by the number of points it has to compare, so unless you are willing to do some kind of point thinning this tool won't work for that amount of points. You could manually trace the shape faster than this tool given the number of points you are processing. I have not tested it for an upper limit, but I would estimate that this tool can only process a maximum of 1,000 points in a reasonable amount of time. The tool also does not consider or include Z in the line shape it creates, which would add add another level of complexity of the algorithm, so if that is important to you this tool may not work for what you want.
... View more
03-10-2016
08:01 AM
|
0
|
0
|
13091
|
|
POST
|
The formula by Brady is the only correct formula proposed above. The basic formula to calculate degrees from two points is only correct in Brady's formula: math.degrees(math.atan2((!Shape.lastPoint.X! - !Shape.firstPoint.X!),(!Shape.lastPoint.Y! - !Shape.firstPoint.Y!))) or math.atan2((!Shape.lastpoint.X! - !Shape.firstpoint.X!),(!Shape.lastpoint.Y! - !Shape.firstpoint.Y!)) * (180 / math.pi) This formula starts with 0 degrees pointing north and produces positive angles in the positive X axis (east half) and negative angles in the negative x axis (west half) of the quadrants: To make all angles positive so that it is clearer that they are all increasing in a clockwise direction, the formula needs to only add 360 to all of the negative angles in the West half of the quadrants. Brady's codeblock does this and using the codeblock this way is the only efficient way to do this calculation. Although the expression below runs much slower than Brady's codeblock, it is possible to do this calculation correctly without using a codeblock by using a single in-line if python expression: 360 + math.degrees(math.atan2((!Shape.lastpoint.X! - !Shape.firstpoint.X!),(!Shape.lastpoint.Y! - !Shape.firstpoint.Y!))) if math.degrees(math.atan2((!Shape.lastpoint.X! - !Shape.firstpoint.X!),(!Shape.lastpoint.Y! - !Shape.firstpoint.Y!))) < 0 else math.degrees(math.atan2((!Shape.lastpoint.X! - !Shape.firstpoint.X!),(!Shape.lastpoint.Y! - !Shape.firstpoint.Y!))) This code is slower than Brady's code since it has to extract the end points from the line and do the degree calculation multiple times, while his calculation only does those 2 steps once. By adding 180 degrees to the basic formula, Criss has made 0 and 360 degrees represent a line that is pointed South and messed up the quadrants of the angles. Marco's formula defaults to a South (180 degree) line orientation, but by swapping the points he has reversed the orientation of the line relative to its real orientation, which I believe restores the real line orientation to show north as 0 or 360 degrees and fixes the messed up quadrants of the angles. I think Marco's formula may actually work except when it is used with a closed line (both ends are the same point) which will be reported as 180 degrees and not as 0 degrees. However, closed lines are a special case, and none of the formulas make it possible to distinguish that situation from a line that is actually oriented due north (for Brady's formula) or due south (for Marco's formula). The Linear Directional Mean tool does produce angles that are compass oriented, and takes into consideration more than just the two end points of the line. So it provides a fuller analysis of the line direction for complex polylines and populates additional fields that make it possible to identify closed polylines and polylines where the angle between the end points does not really correspond to the overall directional trend of the polyline. The trig formula is really only accurate for two point lines that fall within the bounds that a Projected Coordinate System has been optimized to cover. It does not really work very well for polylines with many vertices that have severe changes in directions between the two end points or lines that extend beyond the appropriate bounds of a Projected Coordinate System.
... View more
03-09-2016
11:36 AM
|
3
|
1
|
3510
|
|
POST
|
It will work. One of the bug fixes mentions that it was specifically done to make one of the Attribute Assistant dialogs work correctly for a personal geodatabase.
... View more
03-09-2016
07:18 AM
|
1
|
0
|
3540
|
|
POST
|
Using Attribute Assistant is the only automation that happens as soon as you edit a feature. It has an an Intersecting_Feature method (or a few other options) for filling in the first field and an Equation or GenerateID method to fill in the second field.
... View more
03-09-2016
06:21 AM
|
1
|
0
|
3540
|
|
POST
|
Dan: Actually, the Dissolve tool will work to solve this problem, but not directly on the lines. 1. Buffer the lines a very small distance (0.01 meter/feet for instance). 2. Dissolve the buffers with the unique Case fields set for all fields that you want to group and uncheck the multi-part feature option. 3. Add a Long field called SUBSYSTEM to the dissolved buffers and calculate the ObjectID/FID into it. 4. Spatial Join the lines as the target and the dissolved buffer as the join features with the One to Many option. 5. Select all lines where the case fields of the original lines match the case fields of the dissolved buffers. 6. Dissolve the selected lines with the case fields including all of the original fields plus the SUBSYSTEM field and check the create multi-part feature option. The lines will be combined into a single multi-part feature that all have the same case field values, but only as long as they touch within the small distance you specified. Separate features will be created for any set of case field values where the line groups do not touch each other within the small distance you specified. Each multi-part line feature will have a unique SUBSYSTEM field value you can use for your relate. There is no need to loop through the separate case field value sets, since all sets are handled at once by the process above.
... View more
03-08-2016
10:17 AM
|
1
|
0
|
2689
|
|
BLOG
|
Elena: I have updated the script and fixed two bugs that only occur when a shapefile is used as the tool output. The attached tool should now work when you use a shapefile for either the input or the output. After you download the attached updated version the tool should work with the settings you were trying in your post. As far as using the tool with ModelBuilder, that would only work if my tool was the last tool used in your model before iterating the next file. The tool does not refresh ModelBuilder so that the tool output will be visible to the parameters of a tool you attached to it. I do not intend to make the tool refresh ModelBuilder. Iteration can be done in a Python Script. That is the way I would go if you needed to process the output of my tool through other tools as part of each iteration.
... View more
03-07-2016
03:44 PM
|
0
|
0
|
13091
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-24-2026 11:37 PM | |
| 1 | 03-24-2026 08:01 PM | |
| 7 | 02-23-2026 08:34 AM | |
| 1 | 03-31-2025 03:25 PM | |
| 1 | 03-28-2025 06:54 PM |
| Online Status |
Offline
|
| Date Last Visited |
2 weeks ago
|