4

I have geocoded address data, and I am wishing to randomly position it within the census tracts that they are in to obfuscate... So the points are still within the feature but randomly move around so as to not be exact address locations, and to spread out some of the points that are all aggregated to a single point.

Is there a way to do this in QGIS?

One additional thing I need to point out, is that the geocoded data has additional data attached to it that I would like to preserve.

  • Do you have the "containing feature" i.e. the census tract polygon? – underdark May 10 '16 at 19:54
  • What do you mean by that exactly? I have geocoded address points, and I have census tract polygons. Would I have to encode that to a column? – twilliams May 10 '16 at 19:59
  • do you need the randomising to move each point to somewhere within a specific distance of the original location (but still inside the tract), or is it OK to randomly scatter each point inside a census tract to a completely random point within the tract? In other words, do you still need to keep some sort of resemblance to the original spatial distribution? – Steven Kay May 10 '16 at 20:47
  • Ideally I'd go with the latter of what you said. – twilliams May 10 '16 at 20:55
3

I can suggest a two-step process, which will randomize any number of points inside each census tract:

  1. First, perform a Points in Polygon Analysis. You will find this tool in Vector > Analysis Tools > Points in Polygon. This will add a new field in your census tracts layer with the number of points inside each tract.

  2. Create random points inside your tracts, with Vector > Research Tools > Random Points. Choose the Use value from input field option (with of course the previously created field).

Edit 2: new workaround. As Steven Kay suggested in the comments, there is a simpler solution if you want to keep the original fields (no need of CSV exporting/importing). I've kept my initial workaround at the end of the answer, if for some reason the following process doesn't work. Steps 1 and 2 are still required beforehand.

  1. [This assumes that each census tract has some unique identifier. If not, create one beforehand.] Perform a spatial joint between points1 and your census tracts layer: Vector > Data Management Tools > Join Attributes by Location. Target layer is points1, join layer is the census tracts. Don't change the default options. This will add to each point the attributes of the corresponding census tract, including its ID. Follow the same process with points2.

  2. Install the Sort and Number plugin. You will find it in the regular QGIS plugin repository. Open it, choose points1 as input layer, then "census tract ID" as 1st field. Click OK to create a new field (which creates new point IDs, following the order of their census tract). Follow the same process with points2.

  3. Open points2 properties window. In the "Joins" section, click on the bottom "+". Choose points1 as join layer, "order" (or whatever field name you chose in step 4) as join field and target field. Click on "Choose which fields are joined" to select relevant points1 attributes.

Voilà, you can now access points1 attributes in points2 layer. Fully tested with QGIS 2.8.

Edit 1: original workaround. Keeping the original fields is much more difficult. There is no easy way to do this, but I thought of a convoluted workaround (steps 1 and 2 are still required):

  1. Add x and y fields to the new random points layer (let's call it points2, and the original layer points1). To do so, use the field calculator with the $x and $y formulas.

  2. [This assumes that each census tract has some unique identifier. If not, create one beforehand.] Perform a spatial joint between points1 and your census tracts layer: Vector > Data Management Tools > Join Attributes by Location. Target layer is points1, join layer is the census tracts. Don't change the default options. This will add to each point the attributes of the corresponding census tract, including its ID. Follow the same process with points2.

  3. Export points1 and points2 as CSV (Save As..., in Format choose CSV). Open the CSVs with Excel or something similar. Sort the points by census tract ID (this is important!). Copy the x and y columns from points2 to points1, then save points1.

  4. Import the new points1 CSV to QGIS, following this tutorial. In "Geometry definition", choose "Points coordinates" and the corresponding x and y fields. This should finally result in displaying your original points with random locations.

I didn't completely test this part, so I hope it will work for you. I'd be interested to know if someone can come with a simpler way to solve your issue!

  • One complication to that, which I should have mentioned... each point has numerous additional data about it, that I would like to retain for filtering purposes. – twilliams May 11 '16 at 13:45
  • 1
    This is definitely more complicated ;) I edited my answer to add a workaround. – ArMoraer May 11 '16 at 16:17
  • 1
    @ArMoraer your recent plugin Sort and Number could be used for this, if it could supply sequential ids within sort levels (e.g. numbering points 1..N within each tract after you do the spatial join). That way you could add a tractid_N compound key to each point, do the same to each randomised point, and join point layers on this compound key? (does that make sense?) – Steven Kay May 11 '16 at 20:28
  • @StevenKay This makes sense ;) I was actually trying to find a way to do this easily (without success), since it would obviously simplify the last steps. I didn't think of adding this feature to my plugin, but this is a great idea (thanks!). You will probably find it in the next version! – ArMoraer May 12 '16 at 7:23
  • @ArMoraer actually thinking about it, that way might work with the existing plugin, assuming you're assigning sequential numbers at the table level - the numbers will still be unique within each group. – Steven Kay May 12 '16 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.