TransWikia.com

Creating random points with "CreateRandomPoints_management()" function of ArcPy, with minimum distance

Geographic Information Systems Asked by caio.valente14 on February 16, 2021

I’ve been trying to create random points to sample some locations based, at first, on a field which contains the number of samples I want.
But when I tried at first, in almost every feature it was sampled less than the number of the field.

Then, I tested another way: since I was writting inside a loop through cursor, and one of the fields of the cursor was the area in hectares, and the number of samples is based on the area of the feature, I decided to calculate out of the field the number of samples, but the result was the same.

Then, I was wondering what could cause this problem, it was when I decided to try to run the function with the minimum_distance parameter set to zero, and it worked!

Apparently, what happened is that when I run the function with the minimum_distance parameter, if a random point falls near another point within the minimum distance, the point is removed and I cannot get the total number of samples I need.

Here is the part of the code:

        if 16 <= x[1] < 25:
            minimum_distance = 100
        elif x[1] > 25:
            minimum_distance = 150
        else:
            minimum_distance = 0

        number_of_samples = int(x[1]/8)
        if number_of_samples == 0:
            number_of_samples = 1
        print(number_of_samples)
        arcpy.CreateRandomPoints_management(out_path=arcpy.env.workspace,
                                            out_name='samples_{}'.format(x[0]),
                                            constraining_feature_class=negBuf_tal,
                                            number_of_points_or_field=number_of_samples,
                                            minimum_allowed_distance=minimum_distance)

Where:

x[0]: unique code of feature (inside a loop through cursor);
x[1]: Area in hectares of feature (inside a loop through cursor);
negBuf_tal: negative buffer area of the feature which the loop is going through (to avoid sampling on borders).
OBS: If after the negative buffer the area "desappears", the area to sample in becomes the area without the buffer itself.

How can I solve this without having to write a while structure or something like this?

One Answer

Since I had to hurry to finish my project, I decided to write the code into a loop while, using the arcpy.Near_analysis() function, even though it has increased some lines to the code.
Here is my solution to this problem (if anyone needs the full code to have a better understanding, I can provide, just add a comment, otherwise in this solution there is only a part of the code):

        if 16 <= x[1] < 25:
            minimum_distance = 100
        elif x[1] > 25:
            minimum_distance = 150
        else:
            minimum_distance = 0

        number_of_samples = int(x[1]/8)
        if number_of_samples == 0:
            number_of_samples = 1
        print(number_of_samples)

        list_of_pts = []
        dif = -1
        c = 1
        while dif != 0:
            if dif == -1:
                number_of_samples = number_of_samples
                arcpy.CreateRandomPoints_management(out_path=arcpy.env.workspace,
                                                    out_name='samples_{}_{}'.format(x[0], c),
                                                    constraining_feature_class=negBuf_tal,
                                                    number_of_points_or_field=number_of_samples,
                                                    minimum_allowed_distance=minimum_distance)

                count_sample = arcpy.GetCount_management('samples_{}_{}'.format(x[0], c))
                dif = number_of_samples - int(count_sample.getOutput(0))
            else:
                number_of_samples = dif
                near = True
                while near:
                    arcpy.CreateRandomPoints_management(out_path=arcpy.env.workspace,
                                                        out_name='samples_{}_{}'.format(x[0], c),
                                                        constraining_feature_class=negBuf_tal,
                                                        number_of_points_or_field=number_of_samples,
                                                        minimum_allowed_distance=minimum_distance)

                    arcpy.Near_analysis('samples_{}_{}'.format(x[0], c), list_of_pts, minimum_distance)
                    with arcpy.da.SearchCursor('samples_{}_{}'.format(x[0], c), "NEAR_FID") as near_cursor:
                        for y in near_cursor:
                            if y[0] != -1:
                                near = True
                                break
                            else:
                                near = False

                count_sample = arcpy.GetCount_management('samples_{}_{}'.format(x[0], c))
                dif = number_of_samples - int(count_sample.getOutput(0))

            samples_tmp = 'samples_{}_{}'.format(x[0], c)
            list_of_pts.append(samples_tmp)
            c = c + 1
        arcpy.Merge_management(list_of_pts, 'samples_{}'.format(x[0]))

Answered by caio.valente14 on February 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP