I am trying to create a shapefile of equal population size buffer rings. Similar to the procedure of creating multi-ring buffers of distance around a point, find the intersects of the buffers with a polygonal layer, and then dissolve with the required statistics (e.g. https://support.esri.com/en/technical-article/000010582).
I have a point layer (Atlanta) and a polygon layer (Atlanta metropolitan area census block groups). I want to create a new polygon layer of equal population size (say 5% of total population) rings around the point layer, using population attribute from the census block groups. So a total of 20 rings around the city, each equal of 5% of population. Distance and area of each ring obviously differs.
So far I have tried to use ArcMap Grouping Analysis and modifying the process in the link above.
Any suggestions on how to implement this?
I can use Python for this if needed.
I expect to have an output similar to this:
-
1Population equality is significantly more complex than travel time, each census tract has a set population, including it adds that value to the cluster but there will be a point where the population accumulation is exceeded which then onflows to the next and next.. until the last band has way less than 5%. Finding the seed location is also a challenge, do you take town hall, geographic centre or mean feature? You could start from the outside and work in, iterating an inside buffer which will lead to a central point that may not be what you'd pick... not a trivial task by any means!Michael Stimson– Michael Stimson2020年10月07日 07:51:05 +00:00Commented Oct 7, 2020 at 7:51
-
Thanks for your quick reply @MichaelStimson. Indeed not a trivial task, though I was sure someone did it before me. Just for clarification, city centre will be city hall. From there I want to create buffers of block groups with equal population (5% of total pop). I was thinking on creating multi-ring buffer of DISTANCE every 500m. Then, using intersect and dissolve, calculate the population in each ring, and then aggregate adjacent rings hold 5% of population (or as close to it). The cons of this methods that it required strong computational capabilities, which I don't have access to. Thanks.ALCZ– ALCZ2020年10月07日 09:04:23 +00:00Commented Oct 7, 2020 at 9:04
-
If you're going to do it that way you need to express the population as an area, population per square unit (ppsu) then intersect/union multiple ring buffer (~25m should be suitable), calculating the intersecting area and then expanding ppsu * area to estimate the population of the fragment then dissolve the rings using estimated population as a statistic field then interactively select the dissolved rings from the centre in an edit session and dissolve as soon as you get within tolerance of the 5% threshold. It will require some processing power but should process over a weekend.Michael Stimson– Michael Stimson2020年10月08日 00:08:15 +00:00Commented Oct 8, 2020 at 0:08
-
Yes, exactly what I had in mind, though I hoped someone will come up with a better (faster) solution.ALCZ– ALCZ2020年10月08日 05:15:21 +00:00Commented Oct 8, 2020 at 5:15
1 Answer 1
Reasonably accurate results can be achieved without much iterations. Create 100 travel polygons with same small step to cover entire area. I did it via computing travel raster:
and raster calculator Int(travel/1499.816772)
Assuming that population spreads evenly over Census meshblock area:
Intersect it with travel polygons and summarize population in intersection bits pro-rata their area vs meshblock area. Accumulate population in travel belts into new column and convert to percentage of total:
enter image description here enter image description here
Next step is to find intersection points on the TravelDistance(Percentage) curve for given break points, e.g. 5,10,15...100:
and draw relevant contours on travel distance raster:
I used following script to derive contour values, although they can be computed using paper and pen from values in travel belts table:
import arcpy
import numpy as np
tbl = arcpy.da.TableToNumPyArray("BELTS",("PERCENT","TRAVEL"))
breaks = np.linspace(10, 100, 10)
contourList =[]
for breakValue in breaks:
level=np.interp(breakValue,tbl["PERCENT"],tbl["TRAVEL"])
contourList.append(level)
arcpy.gp.ContourList_sa(arcpy.Raster("TRAVEL"), "C:/SCRATCH/Contours", contourList)
-
That is an awesome metric, combining main roads network and population for a visually appealing result, more interesting than concentric circles radiating out from a centre point. Hopefully this meets the OP's needs and they don't need concentric circles for some sort of modelling. +1 from me and I'll tuck this away into my box of tricks, I'll whip it out when needed and look like a genius.Michael Stimson– Michael Stimson2020年10月08日 07:20:04 +00:00Commented Oct 8, 2020 at 7:20
-
Wow, thanks a lot @FelixIP, it looks great and much simple than what I intended to do. I got it all right, except your first fig. Could you please elaborate on how you created the travel raster?ALCZ– ALCZ2020年10月08日 08:10:50 +00:00Commented Oct 8, 2020 at 8:10
-
Are you dealing with travel distance of straight crow fly?FelixIP– FelixIP2020年10月08日 08:50:56 +00:00Commented Oct 8, 2020 at 8:50
-
Hi, yes I am. road network is not required.ALCZ– ALCZ2020年10月08日 08:56:41 +00:00Commented Oct 8, 2020 at 8:56
-
Use euclidean distance to point.FelixIP– FelixIP2020年10月08日 08:58:42 +00:00Commented Oct 8, 2020 at 8:58
Explore related questions
See similar questions with these tags.