Skip to content

Creating random (but believable) geographies

4 messages · Jim Lemon, Barry Rowlingson, Roger Bivand

#
I've recently been working on a web site for tropical disease mapping
in Africa. As a demo, I'm not using real data, but I have been using
real countries. I don't really want to use real countries just in case
there's any misunderstanding that this is simulated case numbers.

 So I've thought about constructing random polygons to represent a
fake country and its administrative subdivisions. Any ideas how to do
this? Here's some thoughts so far:

 * Generate some random points, create voronoi polygons, then wiggle
the edges to make them look more natural. Problem may be stopping the
wiggling from causing edges to overlap, but maybe that just needs a
bunch of point-in-poly tests... Hmmm...

 * Overlay two existing unassociated polygon geometries, such as UK
counties and Ethiopian districts, compute intersections and rebuild
the polygon topology. Then you should end up with polygonal regions
with outlines composed of both sets of polygons. You might end up with
lots of tiny polygons where two lines closely overlap along their
length, but maybe a post-processing step can fix this.

 * Raster-based methods: similar to the voronoi method, start with a
number of seed points on a grid and grow by some random method - then
do raster-vector conversion.

 Obviously there's lots of possible options such as creating islands
and holes, but I thought I'd start with the basics.

 If anyone has any existing fake geographies in digital form then it
might be an idea to create a repository of them...

Barry
#
On 12/28/2009 09:33 PM, Barry Rowlingson wrote:
Hi Barry,
The first thing I thought of was to specify nodes (intersections of 
borders = vertices of polygons) and then wiggle the lines between the 
nodes using something like this:

wigglyLine<-function(xstart,ystart,xend,yend,nseg=20,mult=1) {
  xvec<-seq(xstart,xend,length.out=nseg+1)
  yvec<-seq(ystart,yend,length.out=nseg+1)
  xvec[2:nseg]<-xvec[2:nseg]+(runif(nseg-1)-0.5)*mult
  yvec[2:nseg]<-yvec[2:nseg]+(runif(nseg-1)-0.5)*mult
  return(list(x=xvec,y=yvec))
}

Obviously there are a lot of things that you could fiddle with here, 
including the easiest way to specify the vertices and then turn the 
wiggled edges into polygons. It does solve the problem of having the 
polygons fit together, though.

Jim
#
On Mon, Dec 28, 2009 at 11:20 AM, Jim Lemon <jim at bitwrit.com.au> wrote:

            
My preferred wiggle algorithm is a fractal - for a line from points A
to B, choose a point C "between" A and B and create two lines AC and
CB. Repeat (recurse) for lines AC and CB up to a number of recursions.
Three or four should be enough.

 If you start with Voronoi polygon edges then you only have to check
that point C is inside either of the polygons on either side of AB to
keep the topology.

 There's some more choices here - you could either fully fractalise
one segment at a time, or do all the first divisions over the space,
then the subdivisions and so on. Also there's the definition of
"between", which strictly doesn't even have to be between A and B
(it's just more likely to be in one of the polygons if it is).

 May I also suggest that if anyone does generate some fake countries
that we place them in the middle of an ocean...

Barry
#
On Mon, 28 Dec 2009, Barry Rowlingson wrote:

            
Couldn't you rather start from a hexagon grid, given the typical number of 
neighbours of "real" entities? Snipping in some straight lines (parallels) 
and some rivers might also make sense. Are there suitable collections of 
entities in gaming etc.? Or generate a DEM and take drainage basins?

Roger