How would you do this in Pro?

432
3
11-15-2018 11:43 AM
ThomasColson
MVP Frequent Contributor

I have a new requirement that, in some 200+ ArcGIS Feature Services on Server 10.6.1 (They are not hosted via a PTL), they all get an "ELEVATION" field and users will somehow magically populate the elevation using a local, Lidar-derived DEM (so it can't be the AGOL elevation service). 

Here's what's not going to work:

Use Extract Values to Points (which creates another FC), join back to the original feature service, calculate field using RASTERVALUE: To many steps, users mostly stop understanding the workflow after the word "join". GIS is not these folks job, they GPS some things, add the points to a feature service, need to know the elevation...

The requirement is the Lidar-derived elevation, not the GPS one

Z-enabling everything. Not possible in our environment, nor feasible given the number of SDE feature classes we'd have to modify. 

Can't use SQL on the back end like 

ELEVATION = (SELECT pdata.getValueByLoc(1,p.SHAPE.Long,p.SHAPE.Lat)  FROM [dbo].[DEM10MP]),

which uses ST_RASTER, an unsafe assembly which we're not allowed to use. 

Surely someone (many hundreds in fact) have had this requirement....and solved it? Some python toolbox is out there somewhere......

0 Kudos
3 Replies
KoryKramer
Esri Community Moderator

I haven't checked but would Add Surface Information—Help | ArcGIS Desktop work with the services?

0 Kudos
ThomasColson
MVP Frequent Contributor

yes and no, the problem is I then have to script, or otherwise automate, the calculation of Z for each new point added. 

0 Kudos
ThomasColson
MVP Frequent Contributor

Based on arcpy - Extracting value of raster for specific points (with X and Y coord) and write to column in A...  I baked the code sample into a toolbox which seems to be working well based on a morning of comparing tool results to spot checks: 

import arcpy
import numpy as np
update_feature_class = arcpy.GetParameterAsText(0)
source_dem= arcpy.GetParameterAsText(1)
elev_attrib= arcpy.GetParameterAsText(2)

rast = arcpy.Raster(source_dem)
desc = arcpy.Describe(rast)

ulx = desc.Extent.XMin
uly = desc.Extent.YMax
lly = desc.Extent.YMin
#Spatialrefernce
sr = desc.spatialReference


rstArray  = arcpy.RasterToNumPyArray(rast)

with arcpy.da.UpdateCursor(update_feature_class,["SHAPE@",elev_attrib]) as uc:
    for row in uc:
        pnt = row[0].projectAs(sr)
        #assuming every point falls to the left and below uperleft corner
        deltaX = pnt.centroid.X - ulx
        deltaY = lly- pnt.centroid.Y
        arow = int(deltaY/rast.meanCellHeight)
        acol = int(deltaX/rast.meanCellWidth)
        row[1] = rstArray[arow,acol]
        uc.updateRow(row)