|
POST
|
Check/Repair Geometry won't do anything for most of these cases, at least the examples provided, since they are valid geometries. A line that folds back onto itself isn't simple but it is valid, unless you are using SQL Server where Microsoft is the oddball with how they deal with these types of cases. A quick example using the Check Geometry tool: >>> SR = arcpy.SpatialReference(26915)
>>> ln = arcpy.FromWKT('LINESTRING(575000 5250000, 576000 5250000, 575500 5250000)')
>>> arcpy.CheckGeometry_management(ln, 'in_memory/ln_chk')
<Result 'in_memory\\ln_chk'>
>>> arcpy.GetCount_management("ln_chk")
<Result '0'>
... View more
09-22-2015
02:21 PM
|
0
|
3
|
3480
|
|
POST
|
The "extra" comma in my code wasn't extra, it was purposeful to allow for list/sequence unpacking. Removing the comma changed the shape variable from a geometry object to a list, hence the error message. Try re-running the code as is and see if it works for you.
... View more
09-22-2015
04:49 AM
|
0
|
0
|
3480
|
|
POST
|
Starting with ArcGIS 10.4, Esri's documentation should clearly state which SQL Server spatial data objects, or instance types, are supported and which ones are not supported. There was a documentation bug on this omission, and it has been closed as fixed.
... View more
09-21-2015
08:02 AM
|
1
|
0
|
2693
|
|
POST
|
What exactly is your error message? I agree with Dan Patterson that the "exceeding 255 characters" error seems odd in this situation. Are you using an enterprise database? If so, have you thought about using a Query Layer instead? The Make Query Table documentation is, interesting let's say. The syntax table for the tool shows the in_field parameter with a list format, but the Data Type is listed as Value Table. The example provided reinforces the notion of using a list, but I believe the Data Type part is more accurate in that a Value Table is what is likely being processed by the tool. The tool seems to accept a Python list and converts it into a Value Table, but there appears to be limits to that convenience. Instead of creating a really long list, I would try creating and populating a Value Table and then pass that into the tool.
... View more
09-21-2015
07:51 AM
|
1
|
1
|
2303
|
|
POST
|
Your error message indicates that the cursor is returning a None object for a shape, which happens when there is a NULL record or empty geometry in the feature class. To avoid the error, just check a geometry object exists before trying to union it. with arcpy.da.UpdateCursor(fc, ["SHAPE@"]) as cur:
for shape, in cur:
if shape:
shape = shape.union(shape)
cur.updateRow(shape)
... View more
09-21-2015
07:07 AM
|
0
|
0
|
3480
|
|
POST
|
I think the ball is still in Esri's court. The community of users has already done its part by creating enhancement requests, logging ideas, and promoting those ideas. The community has played by the rules laid out by Esri, now it is their turn to make a decision one way or the other.
... View more
09-21-2015
06:57 AM
|
2
|
5
|
3811
|
|
POST
|
Strings are a Sequence Type in Python, which means they support indexing and slicing. Since you have a standard number of characters to the left and variable number to the right of the underscore, you can just slice off the right-hand side of the string. val = 'C000004N_37'
val = int(val[9:])
... View more
09-17-2015
01:54 PM
|
1
|
0
|
6762
|
|
POST
|
As I alluded to in my previous comment, identifying the lines with "self overlaps" is not easy using the ArcPy Geometry classes. One could, if so inclined, write his/her own Shamos-Hoey or Bentley–Ottmann algorithm to identify self-intersections with lines, but it might just be easier at that point to convert ArcPy geometry objects over to Shapely or GeoDjango geometry objects and run an is_simple test on them. Another option could be generating a list of problem lines first, using Esri topology tools for example, and then using that list to only process lines that you know have issues. I can't say it will work in all situations, but one approach worth looking into is using the union() method of the ArcPy Geometry class. >>> #OBJECTID 1
>>> l1.length
6000.0
>>> l1u = l1.union(l1)
>>> l1u.length
5000.0
>>> l1u.WKT
u'MULTILINESTRING ((9700614.7830810547 4427945.8558959961, '
'9700614.7830810547 4428945.8558959961,'
'9700614.7830810547 4432945.8558959961))'
>>>
>>> #OBJECTID 2
>>> l2.length
3000.0002500005094
>>> l2u = l2.union(l2)
>>> l2u.length
3000.0001831054788
>>> l2u.WKT
u'MULTILINESTRING ((9702086.5311279297 4431846.6370849609,'
'9702086.5308837891 4428846.6369018555))'
>>>
>>> #OBJECTID 3
>>> l3.length
5182.8322396370995
>>> l3u = l3.union(l3)
>>> l3u.length
5182.832314284238
>>> l3u.WKT
u'MULTILINESTRING ((9703086.5311279297 4431846.6370849609,'
'9703086.5308837891 4427846.6369018555,'
'9704269.3479003906 4427852.6165161133))'
>>> As you can see, the union() method of the ArcPy Geometry class does some amount of geometry validating when it creates a new geometry. For OBJECTID 1, the line was cleaned up by reordering the vertices so the line no longer folded back onto itself. For OBJECTID 2, the duplicate vertex was simply removed. For OBJECTID 3, the union operation effectively recreated the original line.
... View more
09-17-2015
12:18 PM
|
1
|
4
|
4024
|
|
POST
|
Thanks for providing the WKT representations, quite helpful. A quick, or not so quick, aside before moving on. When talking about valid geometries and spatial relationships, the nuance and complexity of the topics are often lost or oversimplified in conversation. There are very specific definitions, and sometimes there are disagreements or discrepancies between different groups/companies/organizations when it comes to the meaning and implementation of those definitions. Looking at the examples provided in the context of ArcPy Geometry classes: >>> #OBJECTID 1
>>> l1 = arcpy.FromWKT('MULTILINESTRING((9700614.7831249982 4432945.8557500001,'
... '9700614.7831249982 4427945.8557500001,'
... '9700614.7831249982 4428945.8557500001))')
...
>>> l1.overlaps(l1)
False
>>> l1.crosses(l1)
False
>>> l1.touches(l1)
False
>>>
>>> #OBJECTID 2
>>> l2 = arcpy.FromWKT('MULTILINESTRING((9702086.5310000032 4431846.6370000001,'
... '9702086.5308749974 4428846.6367499996,'
... '9702086.5308749974 4428846.6367499996))')
...
>>> l2.overlaps(l2)
False
>>> l2.crosses(l2)
False
>>> l2.touches(l2)
False
>>>
>>> #OBJECTID 3
>>> l3 = arcpy.FromWKT('MULTILINESTRING((9703086.5310000032 4431846.6370000001,'
... '9703086.5308749974 4427846.6367499996,'
... '9704269.3477500007 4427852.6163749993))')
...
>>> l3.overlaps(l2)
False
>>> l3.crosses(l3)
False
>>> l3.touches(l3)
False
>>> From one set of definitions, the examples don't overlap, cross, or even touch themselves, which makes it fairly difficult to identify the geometries that "self overlap." The ArcPy Geometry classes, unfortunately, do not have a self-overlap method or anything similar. For the Python implementations (Shapely, GeoDjango) of JTS/GEOS, the closest approximation to a self-overlap method for lines is is_simple: >>> from shapely import wkt
>>>
>>> #OBJECTID 1
>>> _l1 = wkt.loads('MULTILINESTRING((9700614.7831249982 4432945.8557500001,'
... '9700614.7831249982 4427945.8557500001,'
... '9700614.7831249982 4428945.8557500001))')
...
>>> _l1.is_simple
False
>>>
>>> #OBJECTID 2
>>> _l2 = wkt.loads('MULTILINESTRING((9702086.5310000032 4431846.6370000001,'
... '9702086.5308749974 4428846.6367499996,'
... '9702086.5308749974 4428846.6367499996))')
...
>>> _l2.is_simple
True
>>>
>>> #OBJECTID 3
>>> l3 = wkt.loads('MULTILINESTRING((9703086.5310000032 4431846.6370000001,'
... '9703086.5308749974 4427846.6367499996,'
... '9704269.3477500007 4427852.6163749993))')
...
>>> _l3.is_simple
True
>>> While it is clear that OBJECTID 1 is not simple because it "self overlaps," or folds back onto itself, it is less clear why OBJECTID 2 is simple. Since JTS/GEOS libraries are OGC compliant, consecutive equal vertices are allowed in a LineString. A basic simplify operation will remove not only redundant vertices but also some intermediate vertices if not necessary to the topology of the line. >>> _lc = wkt.loads('LINESTRING(0 0, 1 0, 1 0, 2 0, 2 0, 3 0, 3 0, 3 0)')
>>> _lc.is_simple
True
>>> _lc.simplify(0).wkt
'LINESTRING (0 0, 3 0)'
>>> Instead of continuing this already-too-long comment, I will wrap us this aside and post another comment with additional thoughts. UPDATE: OBJECTID 2 in my code above is not the same as OBJECTID 2 provided by OP. I must have miscopied the WKT representation of OBJECTID 2 and created a line with duplicate end points. Instead of correcting OBJECTID 2, I will leave it as is to discuss the situation when a line has consecutive vertices that are equal.
... View more
09-17-2015
11:04 AM
|
0
|
0
|
4024
|
|
POST
|
I was wondering about that extra nested list. I will update my original code with your modification so the correct answer works correctly.
... View more
09-17-2015
08:13 AM
|
2
|
0
|
4003
|
|
POST
|
The Python sys documentation explains what is going on: sys.exit([arg]) Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level. ... Since exit() ultimately “only” raises an exception, it will only exit the process when called from the main thread, and the exception is not intercepted. You are raising the SystemExit exception, promptly trapping it, and then ignoring it with your pass statement.
... View more
09-15-2015
02:41 PM
|
1
|
0
|
8026
|
|
POST
|
That was my initial thought, but the OP's JSON string doesn't work directly with arcpy.AsShape, it generates an AssertionError. Since the original string needs to be manipulated, I figured just go straight to using the native JSON library to restructure the input.
... View more
09-15-2015
02:10 PM
|
0
|
1
|
4003
|
|
POST
|
I find manipulating JSON strings as strings to be challenging. I recommend using the Python JSON library to convert JSON to Python and back again. See if the following works for you: def geo_convert(ring_string):
from json import loads, dumps
rings = loads(ring_string)
feat_coll = {'type': 'FeatureCollection',
'features':[]}
for ring in rings:
feat_coll['features'].append(
{'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [ring['rings'][0]]
}})
return dumps(feat_coll) Pass your input to the function to get main_json_string back. A couple of comments: It appeared from your example that you only wanted the first/outer ring to create a polygon, so the function only grabs the first ring. I am not sure how the nested lists for the coordinates are handled down stream. You may need to add an additional nesting list on line 13. UPDATE: Changed line #13 to include correction from James Crandall.
... View more
09-15-2015
01:39 PM
|
3
|
7
|
4003
|
|
POST
|
Since you are working with an SDE feature class, why not go with the built-in unique identifier, ObjectID? You seem to be after a basic, incremental unique identifier, which isn't much different than the ObjectID that SDE is already managing for you.
... View more
09-15-2015
07:41 AM
|
0
|
6
|
7644
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 2 weeks ago | |
| 2 | 3 weeks ago | |
| 1 | 3 weeks ago | |
| 2 | 06-05-2026 10:30 AM | |
| 1 | 05-29-2026 08:22 AM |
| Online Status |
Online
|
| Date Last Visited |
8 hours ago
|