Is there a way to rotate a label in ArcGIS using an Arcade expression? By default the labels are horizontal, but I'd like them to be parallel with the polygons.
When I use the Basic Polygon labeling in ArcGIS Pro it will rotate the label (if it doesn't fit, so not always):
However, after publishing the map as a web map, the label rotation disappears:
If you label on the "center line" you will be able to obtain rotated labels, although some funky stuff is going on:
The rotation was based on the "center line" of the polygon. This was achieved by using first:
Minimum Bounding Geometry—Help | ArcGIS Desktop (with the RECTANGLE_BY_AREA option) and then running a snippet of code to create the lines:
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">main</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">import</SPAN> arcpy <SPAN class="keyword token">import</SPAN> os fc_in <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\ParcelsMinArea\test.gdb\Parcels_MinBoundAreaRect'</SPAN> fc_out <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\GeoNet\ParcelsMinArea\test.gdb\Parcels_MinBoundAreaRect_lines2'</SPAN> fld_lbl <SPAN class="operator token">=</SPAN> <SPAN class="string token">'ParcelID'</SPAN> <SPAN class="comment token"># create output fc</SPAN> sr <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Describe<SPAN class="punctuation token">(</SPAN>fc_in<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>spatialReference ws<SPAN class="punctuation token">,</SPAN> fc_name <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>split<SPAN class="punctuation token">(</SPAN>fc_out<SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>CreateFeatureclass_management<SPAN class="punctuation token">(</SPAN>ws<SPAN class="punctuation token">,</SPAN> fc_name<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"POLYLINE"</SPAN><SPAN class="punctuation token">,</SPAN> None<SPAN class="punctuation token">,</SPAN> None<SPAN class="punctuation token">,</SPAN> None<SPAN class="punctuation token">,</SPAN> sr<SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>AddField_management<SPAN class="punctuation token">(</SPAN>fc_out<SPAN class="punctuation token">,</SPAN> fld_lbl<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"TEXT"</SPAN><SPAN class="punctuation token">,</SPAN> None<SPAN class="punctuation token">,</SPAN> None<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">20</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>InsertCursor<SPAN class="punctuation token">(</SPAN>fc_out<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'SHAPE@'</SPAN><SPAN class="punctuation token">,</SPAN> fld_lbl<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> curs_out<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc_in<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'SHAPE@'</SPAN><SPAN class="punctuation token">,</SPAN> fld_lbl<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> curs<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> curs<SPAN class="punctuation token">:</SPAN> polygon <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> parcelID <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> polyline <SPAN class="operator token">=</SPAN> GetCenterLineFromRectangle<SPAN class="punctuation token">(</SPAN>polygon<SPAN class="punctuation token">)</SPAN> curs_out<SPAN class="punctuation token">.</SPAN>insertRow<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">(</SPAN>polyline<SPAN class="punctuation token">,</SPAN> parcelID<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">def</SPAN> <SPAN class="token function">GetCenterLineFromRectangle</SPAN><SPAN class="punctuation token">(</SPAN>polygon<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> lst_pnts <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> part <SPAN class="keyword token">in</SPAN> polygon<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> pnt <SPAN class="keyword token">in</SPAN> part<SPAN class="punctuation token">:</SPAN> lst_pnts<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>pnt<SPAN class="punctuation token">)</SPAN> mid_pnts <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> i <SPAN class="keyword token">in</SPAN> range<SPAN class="punctuation token">(</SPAN>len<SPAN class="punctuation token">(</SPAN>lst_pnts<SPAN class="punctuation token">)</SPAN><SPAN class="operator token">-</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> pnt_i <SPAN class="operator token">=</SPAN> lst_pnts<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN> pnt_n <SPAN class="operator token">=</SPAN> lst_pnts<SPAN class="punctuation token">[</SPAN>i<SPAN class="operator token">+</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> mid_pnt <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Point<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">(</SPAN>pnt_i<SPAN class="punctuation token">.</SPAN>X <SPAN class="operator token">+</SPAN> pnt_n<SPAN class="punctuation token">.</SPAN>X<SPAN class="punctuation token">)</SPAN><SPAN class="operator token">/</SPAN><SPAN class="number token">2.0</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="punctuation token">(</SPAN>pnt_i<SPAN class="punctuation token">.</SPAN>Y <SPAN class="operator token">+</SPAN> pnt_n<SPAN class="punctuation token">.</SPAN>Y<SPAN class="punctuation token">)</SPAN><SPAN class="operator token">/</SPAN><SPAN class="number token">2.0</SPAN><SPAN class="punctuation token">)</SPAN> mid_pnts<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>mid_pnt<SPAN class="punctuation token">)</SPAN> sr <SPAN class="operator token">=</SPAN> polygon<SPAN class="punctuation token">.</SPAN>spatialReference line1 <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Polyline<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Array<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN>mid_pnts<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> mid_pnts<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> sr<SPAN class="punctuation token">)</SPAN> line2 <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Polyline<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>Array<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN>mid_pnts<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> mid_pnts<SPAN class="punctuation token">[</SPAN><SPAN class="number token">3</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> sr<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> line1<SPAN class="punctuation token">.</SPAN>length <SPAN class="operator token">></SPAN> line2<SPAN class="punctuation token">.</SPAN>length<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">return</SPAN> line1 <SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">return</SPAN> line2 <SPAN class="keyword token">if</SPAN> __name__ <SPAN class="operator token">==</SPAN> <SPAN class="string token">'__main__'</SPAN><SPAN class="punctuation token">:</SPAN> main<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Labeling is based on the lines, and a transparent color is used for the lines (using on the line alignment).
If you look at the when creating labels for polygons, you will notice that there is no setting for rotation. The only labels that can be rotated are for lines and they will follow the orientation of the line.
If it is really necessary to have rotated labels in you web map, the only way to achieve that is to create lines for each polygon with the proper orientation and label the lines while using a transparent color for the lines.
What about instead of publishing a hosted feature layer, you publish a map service and have custom labels that way (maybe with a label rotation value)? Would that retain the label rotation to be displayed in AGOL?
Tutorial: Publishing a map service—Documentation | ArcGIS Enterprise
Xander,
I understand what you are saying but I am wondering if publishing a map service to a server (enterprise) would answer the problem here, as opposed to publishing straight to ArcGIS Online. I do not have a server to test with but there is enhanced functionality with ArcGIS Enterprise publishing for labels versus AGOL.
https://enterprise.arcgis.com/en/server/10.3/publish-services/linux/supported-functionality-in-map-services.htm#GUID-4A082EAC-FC97-4CC7-86B7-DE5516369ED8
The Standard Label Engine is available, as well as annotation. The Maplex Label Engine is available but is recommended for cached maps only. VBScript-based label expressions are not supported on ArcGIS for Server (Linux). JavaScript and Python-based label expressions are supported.
With this, I presume you would likely want to use a cached map, maybe.
Hmmm, I guess I was looking at a linux-based article initially. Here is the link for the windows-based, 10.6 version (which has less info):
https://enterprise.arcgis.com/en/server/latest/publish-services/windows/supported-functionality-in-map-services.htm
The Standard Label Engine is available, as well as annotation. The Maplex Label Engine is available but is recommended for cached maps only.
This article may be relevant as well in regards to labeling in a map service:
Labels in map caches—Documentation | ArcGIS Enterprise
Is this still the only solution to this or does the new map viewer allow for label rotation or parallel labeling in polygons? I prefer not to run code to convert to center line of polygon each time I have new updates.
Thanks!
I'm running into the same problem. AGOL doesn't support annotation, so I converted it to polygons and in ArcGIS Pro set the font size and rotation angle from the old annotation fields. Worked fine and looked good in Pro, but unfortunately it doesn't seem any of that is supported in AGOL. Sad, but mostly frustrating.
Přihlášení členové mohou přispívat, sledovat aktualizace a další. Jste tu noví? Zaregistrujte si bezplatný účet.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.