I am using ArcPy to export PDFs from my ArcGIS Server application. I want to move a TextElement in my layout view to the centroid of a selected feature. I can get the centroid of the feature, but that's in my projected coordinate system (PCS). I need to convert that point into inches in my layout view.
elements = arcpy.mapping.ListLayoutElements(mapDoc, "TEXT_ELEMENT")
for elem in elements:
if elem.name == "SiteText":
elem.elementPositionX = center.X
elem.elementPositionY = center.Y
center.X
and center.Y
are in a projected coordinate system (PCS), not inches. I know it can be done with ArcObjects, as I've done it in desktop addins using C#. I need to do it from ArcPy and I don't see how. Any ideas?
1 Answer 1
You can use the data frame extent to scale the projected coordinates to map coordinates. I believe this should work well for rectangular coordinate systems. The returned map coordinates can be used to update your text element positions
def proj2map(data_frame,proj_x,proj_y):
"""Convert projected coordinates to map coordinates"""
# This code relies on the data_frame specified having
# its anchor point at lower left
#get the data frame dimensions in map units
df_map_w = data_frame.elementWidth
df_map_h = data_frame.elementHeight
df_map_x = data_frame.elementPositionX
df_map_y = data_frame.elementPositionY
#get the data frame projected coordinates
df_min_x = data_frame.extent.XMin
df_min_y = data_frame.extent.YMin
df_max_x = data_frame.extent.XMax
df_max_y = data_frame.extent.YMax
df_proj_w = data_frame.extent.width
df_proj_h = data_frame.extent.height
#ensure the coordinates are in the dataframe
if proj_x < df_min_x or proj_x > df_max_x:
raise ValueError ('X coordinate is not within the data frame: %.1f - (%.1f, %.1f)' % (proj_x,df_min_x,df_max_x))
if proj_y < df_min_y or proj_y > df_max_y:
raise ValueError ('Y coordinate is not within the data frame: %.1f - (%.1f, %.1f)' % (proj_y,df_min_y,df_max_y))
#scale the projected coordinates to map units from the lower left of the data frame
map_x = (proj_x - df_min_x) / df_proj_w * df_map_w + df_map_x
map_y = (proj_y - df_min_y) / df_proj_h * df_map_h + df_map_y
return map_x,map_y
-
How does one know which units the page is in? This seems to assume that you are using inches for map units. What if you want to use metric and the projection is in imperial?Maps N Stuff– Maps N Stuff2018年06月18日 17:48:34 +00:00Commented Jun 18, 2018 at 17:48
-
-
I was trying to find where you could get a property like pageUnits. The dataFrame has its dimensions in page units. I understand that you set the page units in the MXD and cannot do that programmitally. I only need a read-only access anyways.Maps N Stuff– Maps N Stuff2018年06月18日 17:54:44 +00:00Commented Jun 18, 2018 at 17:54
-
1There is also a displayUnits property. You can get units for the spatial reference of the data frame and any layers you are working with. You'll have to work out the necessary conversion logic, but all the info you need should be there.tharen– tharen2018年06月18日 18:00:06 +00:00Commented Jun 18, 2018 at 18:00
-
I'm looking at displayUnits and mapUnits in a debugger and both are 'Meters'. The units are clearly in inches. It is confusing. I think displayUnits means the units shown in the arcmap whereas the mapUnits is the units of the current projection for the dataframe.Maps N Stuff– Maps N Stuff2018年06月18日 18:02:46 +00:00Commented Jun 18, 2018 at 18:02