[GIS] Creating Random Points that respect minimal distance across features / strata using ArcGIS for Desktop

arcgis-desktoprandomsampling

I have a shapefile with multiple polygons in which I want to distribute random points. Each polygon should contain exactly one point. The minimal distance between the random points should be 200m.

Now the ArcGIS tool "Create Random Points" has an option "Minimum allowed distance". This distance is only respected for random points within a polygon / stratum (see 1). How can I distribute random points where the minimal distance is resptected across polygons / strata?

This question was already asked as How to generate random points with minimum distances between points in multiple polygons. However, in my view, the question was not sufficently answered.

Found in the ArcGIS 10.2 Help:

This value will determine the minimum allowed distance between random
points within each input feature. [..] Random points may be within the
minimum allowed distance if they were generated inside or along
different constraining feature parts.

Best Answer

I had initially posted the question on geonet. The matter being rather urgent, I posted the question here as well when I didn't recieve an answer there. In the meantime, Xander Bakker posted an excellent script that solves the problem neatly. The full answer can be view here, this is the section that solves the problem (with some slight modifications from me).

import arcpy
import random
import math

def main(path,fc_pol,fc_pnt,fc_mp,min_dist,number_of_points):
    # path = path for the input and output data
    # fc_pol = name of the input polygon shapefile
    # fc_pnt = name of the output point shapefile
    # fc_mp = name of the output point shapefile, used for visualization it and some manual checking
    arcpy.env.overwriteOutput = True

    arcpy.CreateFeatureclass_management(path, fc_pnt, "POINT")
    arcpy.CreateFeatureclass_management(path, fc_mp, "POINT")
    lst_all_pnts = []
    lst_mp = []
    cnt_pol = 0
    with arcpy.da.SearchCursor(path+fc_pol, "SHAPE@") as curs:
        for row in curs:
            cnt_pol += 1
            # print "polygon: {0}".format(cnt_pol)
            polygon = row[0]
            lst_pnts = []
            sr = polygon.spatialReference
            # create points inside polygons
            while len(lst_pnts) < number_of_points:
                print " - len(lst_pnts)={0}".format(len(lst_pnts))
                lst_pnts, bln_ok = add_random_point(lst_pnts, lst_all_pnts, polygon, min_dist)
                if bln_ok == False:
                    # saturation reached
                    print "saturation reached"
                    break
            # write points
            if len(lst_pnts) > 0:
                mp = create_multipoint(lst_pnts, sr)
                lst_mp.append(mp)
                lst_all_pnts.extend(lst_pnts)

    # create outputs
    sr = polygon.spatialReference
    lst_pntgeom = create_pointgeometry_list(lst_all_pnts, sr)
    arcpy.CopyFeatures_management(lst_pntgeom, path + fc_pnt)
    arcpy.CopyFeatures_management(lst_mp, path + fc_mp)