I want to randomly select 50 points from a point layer of 3,000, but no two points can be within 100 miles of each other. Having difficulty moving beyond a theoretical framework into something practical. I have access to ArcGIS and QGIS, if one or the other's better suited for this. I also know some python but haven't figured out what to do.
You can achieve this with one tool if you have an advance level license in ArcMap. No need for any code or complex modelling and looping.
- Create your point layer with 3,000 points
- Run the Create Random Points tool. The trick here is to set the constraining featureclass to be your 3,000 point layer, set number of points to 50 and minimum allowed distance to 100 miles.
The output will have a CID field which you can use to join any attribution from your 3,000 points layer or if you wish use your new layer to select from the 3,000 layer.
The very loose theoretical workflow that I could see being useful for this is:
- Get the ObjectID or other unique identifier for all of the features and store them, maybe in a python list of all features to choose randomly from. (In arcpy I would do this with a search cursor)
- Choose a random item from the list, using python's random module (https://docs.python.org/2/library/random.html#random.choice) and save that unique identifier to a new list (this will be your output list of random points). Remove that unique ID from the list of all features' unique IDs.
- Select all of the points within 100 miles of this first chosen random point, get their unique IDs, and remove these ID's from the list of all features to choose from. (In ArcGIS I would likely do this with select by location, then a search cursor on the selected features)
- Repeat step 2 & 3 until you have 50 feature's unique IDs in your second list. Each iteration would progressively shrink the list of features to choose from, ensuring you don't get a feature within the specified distance.
- Use the new list of 50 feature unique ID's to select the features you are wanting, and presumably export the selected set? (In ArcGIS I would do this with Select by Attribute)
Note: this workflow assumes you have enough features, dispersed enough, that you can select the points randomly. Depending on your input dataset, if most of your points are densely clustered, there may not be enough points left by the end to select all 50 points.
If any of that isn't clear, let me know and I will try and clarify.
An algorithm for this can be implemented in Python:
- Instantiate an empty RTree.
- Load your three thousand points into an array.
- Shuffle the array.
- Add a point into the RTree from your array.
- For the next point, if the nearest neighbor in the RTree meets a minimum distance threshold, insert the point into the RTree, otherwise discard it.
- Once 50 points are inserted into the RTree, stop and collect the entries.