# Points along irregular line: Euclidean distance

I need to generate points along the perimeter of an irregularly shaped area, and each points should be 40km away from its neighbors.

I tried doing this using the 'generate points along lines' tool, but here's the problem: my area is irregularly shaped, so while the distance between some points may be 40km where the perimeter is a straight line, it is less than that in most places. I am thus looking to space the points along the perimeter, but according to Euclidean distance.

Is there a tool that facilitates this in ArcGIS Pro?

• That area looks to be around Lake Nipigon. Borders of water bodies can be quite sinuous which leads to long traversals to get from point A to B. What tool are you using to measure distances between points in that area? And what distance(s) are you getting instead of 40km? Commented Oct 27, 2022 at 21:45
• So you are will to accept points as measured along the boundary to be more than 40Km apart? Also thinking about it the resulting distribution is entirely dependent on the initial starting location. I would be looking to script this in python doing some sort of iterative buffer and intersect until no more points can be added. Commented Oct 27, 2022 at 23:04
• I'm not entirely sure about the comments, what I want is points along the perimeter, with an euclidean distance of 40km between each point, and not as it is now, 40km measured according to the shape of the perimeter. @bixb0012 , I am using Generate points along line, which does the latter, the distances I'm getting is dependent on how 'sinuous' the traversels are, so often only 20km in euclidean distance. Commented Oct 28, 2022 at 3:31

The only algorithm that works for me is finding intersection points with circle of given radius. Next correct point is the one that is a) closest (in terms of chainage) to a given point AND b) further from line start (in terms of chainage) compared to given point. This guarantees that any point is at the same distance from point before and point after:

The only exception of course is starting point of closed line, polygon.

Doable in arcpy if you expect few hundred vertices, but I need 100s of thousands of them, so I use long retired ArcView 3, Avenue.

• Avenue? Old skool! :) Commented Oct 28, 2022 at 10:59
• Ok I don't really know how to do any of that.. Considering just doing it manually... Commented Oct 28, 2022 at 16:41
• Upload projected shape somewhere, not a big deal Commented Oct 28, 2022 at 18:10

Since the area in question is the southern portion of Lake Nipigon, I downloaded the Lake Nipigon polygon from Ontario Hydro Network (OHN) - Waterbody | Ontario GeoHub.

The results from using Generate Points Along Lines (Data Management) - ArcGIS Pro | Documentation with a distance of 40 km are:

Given the winding nature of the shoreline, 40 km of perimeter traversal results in points that are not 40 km apart when measuring Euclidean/straigh-line distance. Although expected, this isn't the desired outcome.

Given there are several factors that already introduce some arbitrariness to the point locations, e.g., choosing a distance between points and a starting point, going with an approximate solution will be quicker and easier than an exact solution.

As much as brute-force approaches aren't elegant, sometimes they are quick enough to get the job done. Below is a brute-force approach that iterates around a densified perimeter to the lake looking for the first point that is within a tolerance of 40 km of the last selected point. The code is written to only process the first polygon in `in_fc`, but it could be adapted to work on all polygons.

``````import arcpy
from arcpy.management import CopyFeatures, GeodeticDensify

in_fc =  # path to feature class or name of feature layer
out_fc = # path to output feature class containing Euclidean-equidistant points

den_fc = GeodeticDensify(in_fc, "memory/den_fc", "GEODESIC", "500 meters")
shp, = next(arcpy.da.SearchCursor(den_fc, "SHAPE@"))

point_geoms = []
parts_iter = iter(shp.getPart(0))
point = next(parts_iter)
prev_ptg = arcpy.FromWKT(f"POINT({point.X} {point.Y})", shp.spatialReference)
point_geoms.append(prev_ptg)
for point in parts_iter:
ptg = arcpy.FromWKT(f"POINT({point.X} {point.Y})", shp.spatialReference)
if ptg.angleAndDistanceTo(prev_ptg)[1] < 39750:  continue
prev_ptg = ptg
point_geoms.append(prev_ptg)

CopyFeatures(point_geoms, out_fc)
``````

The results from the code, rounded to the nearest km, are:

The code ran in around 15 seconds on my laptop. A vast majority of that time is spent creating PointGeometry - ArcGIS Pro | Documentation objects from the Point - ArcGIS Pro | Documentation objects returned by `Polygon.getPart()`; however, taking this approach allows both geographic and projected datasets to be processes by the same code.