Verdichting
Het verdichten van polygoongrenzen of polylijnsegmenten is een veelvoorkomende taak.
In een eerdere versie schreef ik over het verdichten van geometrie op basis van een "factor", dat wil zeggen, het verdubbelen, verdrievoudigen... van het aantal punten langs een segment.
Vlakke verdichting kan worden uitgevoerd in de Bewerkingshulpmiddelen, met verschillende opties. Het is niet beschikbaar op het Basic licentieniveau om de een of andere reden.
Verdichten (Bewerken)—ArcGIS Pro | Documentatie
Deze boodschap richt zich op verdichting op basis van een vlakke afstandsstap langs de lijn/omtrek. Het is het meest voorkomende gebruik.
Het zal een paar van mijn toolsets bevatten (hieronder vermeld).
De code illustreert de kracht van numpy in geoprocessing.
def _pnts_on_line_(a, spacing=1, is_percent=False): # verdichten op afstand
"""Voeg punten toe, met vaste tussenafstand, aan een array die een lijn voorstelt.
Parameters
----------
a : array
Een reeks `punten`, x,y-paren, die de grenzen van een polygoon
of polylijnobject vertegenwoordigen.
spacing : nummer
Afstand tussen de toe te voegen punten aan de lijn.
is_percent : boolean
Druk de verdichting uit als een percentage van de totale lengte.
"""
a = _get_base_(a)
N = len(a) - 1 # segmenten
dxdy = a[1:, :] - a[:-1, :] # coördinaatverschillen
leng = np.sqrt(np.einsum('ij,ij->i', dxdy, dxdy)) # segmentlengtes
if is_percent: # als percentage
spacing = abs(spacing)
spacing = min(spacing / 100, 1.)
steps = (sum(leng) * spacing) / leng # stapafstand
else:
steps = leng / spacing # stapafstand
deltas = dxdy / (steps.reshape(-1, 1)) # coördinaatstappen
pnts = np.empty((N,), dtype='O') # maak een `O` array aan
for i in range(N): # doorloop de segmenten en maak
num = np.arange(steps[i]) # de nieuwe punten
pnts[i] = np.array((num, num)).T * deltas[i] + a[i]
a0 = a[-1].reshape(1, -1) # voeg het laatste punt toe en concateneer
return np.concatenate((*pnts, a0), axis=0)
Ik denk dat mijn favoriete 2 regels zijn ...
dxdy = a[1:, :] - a[:-1, :] # coördinaatverschillen
leng = np.sqrt(np.einsum('ij,ij->i', dxdy, dxdy)) # segmentlengtes
Einstein was een slimme kerel.
Zijn notatiesyntaxis is geïmplementeerd in veel talen en veroorzaakt hersenkraken totdat je eraan gewend bent (stof voor een andere blog).
Kort gezegd, dxdy vertegenwoordigt de opeenvolgende verschillen in de coördinaten van een array (lees polygon/polyline coördinaten).
Geen gedoe meer met het lezen van geometrie en het aftrekken van elke x- en y-coördinaat apart. Eén regel en je bent klaar.
Nu betekent a[1:, :] vanaf het tweede coördinatenpaar en a[:-1, :] betekent vanaf het eerste coördinatenpaar tot maar exclusief het laatste (indexering begint bij nul).
Hoofdpijn? Je hebt te lang gebruikgemaakt van Pandas of shapely too long.
Here is what a simple polygon looks like represented like an array (even an arcpy.Array )
a # ---- an array of x, y coordinates... first and last are the same
array([[ 0.00, 0.00],
[ 2.00, 8.00],
[ 8.00, 10.00],
[ 10.00, 10.00],
[ 10.00, 8.00],
[ 9.00, 1.00],
[ 0.00, 0.00]])
dxdy # ---- sequential, delta x and delta y between the pairs
array([[ 2.00, 8.00],
[ 6.00, 2.00],
[ 2.00, 0.00],
[ 0.00, -2.00],
[ -1.00, -7.00],
[ -9.00, -1.00]])
leng # ---- the inter-point pair distance
array([ 8.25, 6.32, 2.00, 2.00, 7.07, 9.06])
Now that the magic is done, the rest is just stuff to determine whether you want to densify based on an absolute distance or as a percentage of the total distance.
The for loop section can be simplified, however, I kept it as such since it shows how each segment gets densified and the results collected and then assembled into the final result,
So what does it look like? The simple polygon shown above and the densified version are as follows.
Plots done in Spyder using Matplotlib.
Finally, I will add this capability to my Polyline/Polygon tools and Free Tools tools shortly.
Free_Tools in Tools_for_ArcGIS_Pro (github.com)
PolygonLine Tools in Tools_for_ArcGIS_Pro (github.com)
If you are interested in geometry, computational geometry and numpy and its interface with arcpy and arcgis pro, then my Numpy Geometry link may be of interest. It is the foundation for all the toolset in my site.
numpy_geometry: A numpy geometry class and functions that work with arcpy and ESRI featureclasses
That's all for now. Give me a buzz if you need something you would like added... especially if it requires and Advance license 😉.
--------------------------
Previous work
Densification.... sometimes being dense is a good ... - GeoNet, The Esri Community