|
POST
|
My initial reaction is that it should be written as field = some value, therefore: OWNERSHIP_NUMBER = LEFT(Layer,3) This is assuming that ownership number is text, as Left is a text function. It might be helpful if you could share an example of ownership_number and layer, if you are still having problems. Hope this helps.
... View more
01-28-2019
09:24 AM
|
0
|
1
|
7644
|
|
POST
|
The additional explanation helps - one feature to one or more photos. I've dabbled a little with exif data. My August 24/25 comments in this thread might be of help. You could read the feature attributes into a dictionary using the globalID as the key with a search cursor. Then work through your related table to get the attached photos with the related globalID to access the dictionary's saved attributes. Then save the image with new exif data. UPDATE: Here's some sample code that links the parent data with the related image data: import arcpy, os
masterFC = r'C:\Path\to\file.gdb\feature'
masterFlds = [ 'GlobalID', 'SHAPE@XY', 'OBJECTID', 'Field1', 'Field2' ] # [ 'GlobalID', and fields you want... ]
relatedTbl = r'C:\Path\to\file.gdb\feature'__ATTACH'
relatedFlds = ['REL_GLOBALID', 'ATTACHMENTID', 'DATA', 'CONTENT_TYPE']
# Use list comprehension to build a dictionary from a da SearchCursor
masterDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(masterFC, masterFlds)}
# print masterDict
# looks something like { '{6656FDEC-6BD8CF4E16AF}': ((-14962237.7272, 8031520.472999997), 421, 'attribute', ... ), ... }
sr = arcpy.Describe(masterFC).spatialReference # get spatial reference of parent feature, if desired
print sr.factoryCode
with arcpy.da.SearchCursor(relatedTbl, relatedFlds) as cursor:
for item in cursor:
# item[3] is Content Type
if item[3] == 'image/jpeg': # process only images; where clause can also be used to limit results
# item[0] is related GlobalID; use it as key to masterDict and access tuple with indexing
x,y = masterDict[item[0]][0] # use [0] to access SHAPE@XY
print x, y
# get Longitude/Latitude
ptGeometry = arcpy.PointGeometry(arcpy.Point(x,y),arcpy.SpatialReference(sr.factoryCode)).projectAs(arcpy.SpatialReference(4326))
lon, lat = ptGeometry.firstPoint.X, ptGeometry.firstPoint.Y
parentOID = masterDict[item[0]][1] # use [1] to access parent ObjectID
attribute1 = masterDict[item[0]][2] # use [2], [3], etc. to access parent feature's attributes
attribute2 = masterDict[item[0]][3] # use [2], [3], etc. to access parent feature's attributes
attID = item[1] # this is the Attachment ID in related table
# make new filename for image
filename = "ATT_{}_{}.jpg".format(parentOID, attID)
print filename
print lon, lat, parentOID, attribute1, attribute2
# do your exif stuff here
# save the image to the desired location
# saveName = os.path.join(saveLocation, fileName)
# f = open(saveName, 'wb').write(item[2].tobytes())
del cursor
del item Code still needs the exif stuff. Hope this helps.
... View more
01-24-2019
04:10 PM
|
0
|
0
|
1925
|
|
POST
|
When you say 'in the "properties" of the image file', do you mean something like saving data in the exif of a jpg, or saving a text file that would have the same name as the image file? An old thread Query a related table and export it with joined feature attributes? might give you some ideas if you want to write data to a similarly named text file.
... View more
01-23-2019
05:05 PM
|
0
|
0
|
1925
|
|
POST
|
Here is the code I've been working with: import arcpy
import math
def rotate(origin, point, angle):
"""
Rotate a point counterclockwise by a given angle around a given origin.
The angle should be given in radians.
"""
ox, oy = origin
px, py = point
qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
return qx, qy
def make_lines(origin, num_lines, length, spacing, bearing):
'''
origin = (x,y), num_lines = number of lines to draw
length = 1/2 length of line, spacing = spacing between lines
bearing = angle to rotate points
'''
angle = math.radians(360.0 - bearing)
lines = []
x, y = origin
# set up line points before rotation
xx = x - (spacing*(num_lines-1))/2.0
y1 = y + length*1.0
y2 = y - length*1.0
# rotate points around origin
for lns in range(1,num_lines+1):
qx1,qy1 = rotate((x,y),(xx,y1),angle)
qx2,qy2 = rotate((x,y),(xx,y2),angle)
lines.append([qx1,qy1,qx2,qy2])
xx += spacing
return lines
# set input/output parameters
polyFC = arcpy.GetParameterAsText(0) # input polygons : feature layer, input
angleField = arcpy.GetParameterAsText(1) # field containing rotation: field, input (obtained from param0)
numLines = arcpy.GetParameterAsText(2) # number of lines: long, input
lineSpacing = arcpy.GetParameterAsText(3) # line spacing : linear unit, input
buffDist = arcpy.GetParameterAsText(4) # inner buffer distance : linear unit, input
outLines = arcpy.GetParameterAsText(5) # output parallel lines : feature class, output
desc = arcpy.Describe(polyFC)
SR = desc.spatialReference # get spatial reference of polygon feature
arcpy.env.overwriteOutput = True # output will be overwritten
arcpy.env.outputCoordinateSystem = SR # set default spatial reference
D2M = { # dictionary for converting distance to meters
'CENTIMETERS': .01,
'DECIMALDEGREES': 1.0, # no conversion
'DECIMETERS': 0.1,
'FEET': 0.3048, # 0.304800609601 Foot_US
'INCHES': 0.0254,
'KILOMETERS': 1000.0,
'METERS': 1.0, # no conversion
'MILES': 1609.344,
'MILLIMETERS': 0.001,
'NAUTICALMILES': 1852.0,
'POINTS': 0.000352778,
'UNKNOWN': 1.0, # no conversion, tool may select data frame default
'YARDS': 0.9144,
}
# parse numbers from parameters
numLines = int(numLines)
lineSpacing = lineSpacing.split(' ')
if lineSpacing[1].upper() not in D2M.keys():
lineSpacing[1] = 'UNKNOWN'
spacing = float(lineSpacing[0]) * D2M[lineSpacing[1].upper()] * SR.metersPerUnit # convert spacing unit to meters, then to SR units
buffDist = buffDist.split(' ')
if buffDist[1].upper() not in D2M.keys():
buffDist[1] = 'UNKNOWN'
buffNum = float(buffDist[0]) * D2M[buffDist[1].upper()] * SR.metersPerUnit # convert buffer unit to meters, then to SR units
# list to save lines
lines = []
with arcpy.da.SearchCursor(polyFC,['SHAPE@', angleField]) as cursor:
for row in cursor:
# buffer for trimming lines to polygon
polyBuff = row[0].buffer(buffNum * -1)
# get centroid of polygon
centroid = row[0].centroid
# find distance from centroid to farthest point, this will be used as 1/2 line length
dist = 0
for part in row[0]:
for pnt in part:
cent_vert_dist = arcpy.PointGeometry(pnt).distanceTo(centroid)
if cent_vert_dist > dist:
dist = cent_vert_dist
# pass centroid, dist for 1/2 line length, and other variables to make lines
mkLns = make_lines(((centroid.X, centroid.Y)), numLines, dist, spacing, row[1])
# make polyline and trim to buffer
for ln in mkLns:
pl = arcpy.Polyline(arcpy.Array([arcpy.Point(ln[0],ln[1]), arcpy.Point(ln[2],ln[3])]), SR)
bufLn = pl.intersect(polyBuff,2)
lines.append(bufLn)
# save lines to feature class
arcpy.CopyFeatures_management(lines,outLines) I added some code to better deal with the linear units; the original tool ignored the type of unit selection and used the default from the spatial reference. I create points for the ends of the lines and then rotate the points using the polygon's centroid as the rotation origin. The length for the lines (before buffering) is twice the distance from the centroid to the far point. I've modified and added to the tool parameters: And the results: Hope this helps.
... View more
01-20-2019
05:30 PM
|
3
|
3
|
2667
|
|
POST
|
I've been experimenting with some code that I will post later today or this weekend. Right now I'm wondering if the spatial reference is getting messed with when creating "polyBuff". Lines 1-2 and 6 clarify the spatial reference. desc = arcpy.Describe(polyFC)
SR = desc.spatialReference
# ...
with arcpy.da.SearchCursor(polyFC,['SHAPE@', 'AVGAzimuth'], spatial_reference=SR) as cursor:
for row in cursor:
polyBuff = row[0].buffer(buffNum * -1)
... View more
01-18-2019
03:03 PM
|
0
|
1
|
2667
|
|
POST
|
Can you show the parameters tab? I assume the second parameter is a derived string data type set for output.
... View more
01-18-2019
09:20 AM
|
0
|
1
|
2985
|
|
POST
|
I added some code to my previous post. I found TableToDomain to be faster than AddCodedValueToDomain when there were lots of values. Also, I'm not sure how AddCodedValueToDomain would react if it the code was already in the domain, but I expect it will generate an error. TableToDomain will create the domain and can also append to an existing one. If the domain exists and the coded value is in the domain, an error will be generated if the update option is "APPEND". If using "REPLACE", the code and description are overwritten.
... View more
01-16-2019
07:37 PM
|
1
|
1
|
2931
|
|
POST
|
It should just be in your print output. For line 12 in your code, you can use: print x[0]
... View more
01-16-2019
04:56 PM
|
0
|
0
|
2931
|
|
POST
|
I would use a search cursor to read unique values into a dictionary (key and value being the same). A list set would probably accomplish the same thing. Sort if desired. Convert that into a table (possibly in_memory). And then use the Table to domain tool. UPDATE: Here's an example: gdb = r"C:\Path\to\file.gdb"
domainName = "DomainName"
domainDesc = "Domain Description"
layer = "featureLayer"
field = ['TextField']
# create a table in memory
arcpy.CreateTable_management('in_memory', 'domainValues')
arcpy.AddField_management("domainValues","CODE","TEXT")
arcpy.AddField_management("domainValues","DESCRIPT","TEXT")
# read field into dictionary (these will be unique values - not tested for None value)
domainDict = {r[0]:r[0] for r in arcpy.da.SearchCursor(layer, field)}
# sort the dictionary keys (optional, you can also sort the domain later)
codes = sorted(k for k in domainDict)
# insert the codes into the in memory table
rows = arcpy.da.InsertCursor('in_memory\domainValues', ['CODE','DESCRIPT'])
for c in codes:
rows.insertRow((c,c))
del rows
# table to domain
arcpy.TableToDomain_management(in_table="domainValues", # in_memory\domainValues table
code_field='CODE', # code
description_field='DESCRIPT', # description
in_workspace=gdb,
domain_name=domainName,
domain_description=domainDesc,
update_option="REPLACE" # or "APPEND"
)
arcpy.Delete_management("in_memory\domainValues") I did a quick check of the script inside Arcmap 10.5. I found creating an in memory table and using TableToDomain to be faster than AddCodedValueToDomain (particularly with lots of values).
... View more
01-16-2019
04:09 PM
|
1
|
4
|
2931
|
|
POST
|
You need the geometry field (SHAPE@) in the search cursor for the centroid. Untested, but try something like (note code changes in rows 2 and 6): # ...
with arcpy.da.SearchCursor(polyFC,['SHAPE@', 'AVGAzimuth']) as cursor:
for row in cursor:
centroid = row[0].centroid
points.append(arcpy.PointGeometry(centroid))
azimuth = row[1]
dist = 0
for part in row[0]:
# ...
... View more
01-16-2019
02:40 PM
|
2
|
1
|
3853
|
|
POST
|
Just some thoughts... Distance is measured in the units of the spatial reference so you may need to do some conversion. Depending upon false northing value in the spatial reference, you may wish to adjust your azimuth setting. For distance between lines, you would need to calculate an x value offset. With the desired distance being one side of a right triangle that is perpendicular to the line, you would use the hypotenuse value as an x offset. Adding/subtracting this value from the x value at the ends of the first line should provide parallel lines at the proper distance If you have an odd number of lines, you can draw the first line through the centroid. If you want an even number of lines, use half the x offset value to move the first line to the right or left of the centroid and then add the rest of your lines. Hope this helps.
... View more
01-16-2019
02:22 PM
|
2
|
3
|
3853
|
|
POST
|
Here's some code that I have been experimenting with that may give you some ideas. It takes a polygon feature class and creates a layer of points marking each polygon's centroid. It also creates a line through the centroid at a given azimuth. From here, you need to add additional parallel lines and clip them to the polygon. import arcpy
import math
def draw_line(point, distance, bearing):
angle = 90 - bearing
bearing = math.radians(bearing)
angle = math.radians(angle)
cosa = math.cos(angle)
cosb = math.cos(bearing)
x1, y1 = \
(point[0] + (distance * cosa), point[1] + (distance * cosb))
x2, y2 = \
(point[0] - (distance * cosa), point[1] - (distance * cosb))
return [[x1, y1], [x2, y2]]
polyFC = "poly_line" # the polygon feature layer
azimuth = 347
desc = arcpy.Describe(polyFC)
SR = desc.spatialReference
arcpy.env.overwriteOutput = True
arcpy.env.outputCoordinateSystem = SR
points = []
lines = []
with arcpy.da.SearchCursor(polyFC,['SHAPE@']) as cursor:
for row in cursor:
centroid = row[0].centroid
points.append(arcpy.PointGeometry(centroid))
dist = 0
for part in row[0]:
for pnt in part:
cent_vert_dist = arcpy.PointGeometry(pnt).distanceTo(centroid)
if cent_vert_dist > dist:
dist = cent_vert_dist
# far_point = arcpy.PointGeometry(pnt)
# points.append(far_point)
feature_info = [ draw_line((centroid.X, centroid.Y), dist, azimuth) ]
for feature in feature_info:
lines.append(
arcpy.Polyline(
arcpy.Array([arcpy.Point(*coords) for coords in feature])))
arcpy.CopyFeatures_management(points,'in_memory\points')
arcpy.CopyFeatures_management(lines,'in_memory\lines')
... View more
01-16-2019
12:17 PM
|
2
|
5
|
10569
|
|
POST
|
It should be possible to use the polygon's centroid and draw lines using an azimuth. Several of Dan Patterson's Py... blog articles give code examples that might work into this project (or at least, to provide some ideas). Geometry: Points in the field calculator (see: Line direction or Azimuth to Compass Bearing and Convert Azimuth to Compass Bearing sections) Origin, distances and bearings... geometry wanderings Numpy Snippets # 3 ... Phish_Nyet ... creating sampling grids using numpy and arcpy Hexagons, Rectangles and Triangles... Sampling Frameworks
... View more
01-15-2019
09:59 AM
|
1
|
6
|
6717
|
|
POST
|
Here is some of the code from the stackexchange page (the part where it loops through the polygon feature): for row in arcpy.da.SearchCursor(polyFC, ["SHAPE@"], spatial_reference=SR):
# create inner buffer
polyBuff = row[0].buffer(buffNum * -1)
# create hull rectangle to establish a rotated area of interest
coordSplit = row[0].hullRectangle.split(' ')
# collect corner coordinates
coordList = arcpy.Array([arcpy.Point(coordSplit[0],coordSplit[1]),arcpy.Point(coordSplit[2],coordSplit[3]),arcpy.Point(coordSplit[4],coordSplit[5]),arcpy.Point(coordSplit[6],coordSplit[7]),arcpy.Point(coordSplit[0],coordSplit[1])])
# create lines from hull rectangle
currentLines = []
for pointNum in range(0,4):
arcpy.Array([coordList.getObject(pointNum),coordList.getObject(pointNum+1)])
hullRecLine = arcpy.Polyline(arcpy.Array([coordList.getObject(pointNum),coordList.getObject(pointNum+1)]))
currentLines.append(hullRecLine)
# compare first and second line to determine if first line is short or long
firstLong = 0
if currentLines[0].length > currentLines[1].length:
firstLong = 1
# calculate number of points needed along short axis
numPoints = int(math.floor(currentLines[firstLong].length/lineSpaceNum))
# create and join points to create parallel lines
for point in range(1,numPoints+1):
shortPoint1 = currentLines[firstLong].positionAlongLine(lineSpaceNum*point)
shortPoint2 = currentLines[firstLong + 2].positionAlongLine(currentLines[firstLong + 2].length - (lineSpaceNum*point))
parallel = arcpy.Polyline(arcpy.Array([shortPoint1.centroid,shortPoint2.centroid]), SR)
# intersect parallel lines with buffer
parallelBuff = parallel.intersect(polyBuff,2)
parallels.append(parallelBuff)
In lines 6-17, the code is creating a hull rectangle and getting the lines that make up the rectangle. At lines 20-22, it is comparing the lines to see which side is the long side. The code then goes on to draw the lines. If you were to compare the starting xy coordinates and ending coordinates of the first and second lines, you should be able to determine which is the most northerly of the lines. Then set the index ( firstLong ) to indicate which line to use.
... View more
01-14-2019
03:50 PM
|
2
|
1
|
6717
|
|
POST
|
The tool you mention creates a hull rectangle for each polygon and makes the lines parallel to what is determined as the longest side of the hull rectangle. Are most or all of your polygons rectangles (and not irregular shapes)? If they are rectangles, would you always want the lines parallel to the most north/south sides?
... View more
01-14-2019
03:06 PM
|
0
|
3
|
6717
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 10-27-2016 02:23 PM | |
| 1 | 09-09-2017 08:27 PM | |
| 2 | 08-20-2020 06:15 PM | |
| 1 | 10-21-2021 09:15 PM | |
| 1 | 07-19-2018 12:33 PM |
| Online Status |
Offline
|
| Date Last Visited |
02-12-2026
07:13 PM
|