Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generate test cases for geojson rendering, currently supports generating spirals and sawtooth waves
#!/usr/bin/env python
from optparse import OptionParser
import json
import math
import re
import sys
def frange(start, stop, step):
""" Range for floats """
r = start
while r < stop:
yield r
r += step
def spiral_points(arc=0.01, separation=0.1, count=100):
"""
From http://stackoverflow.com/questions/13894715/draw-equidistant-points-on-a-spiral
generate points on an Archimedes' spiral
with `arc` giving the length of arc between two points
and `separation` giving the distance between consecutive
turnings
- approximate arc length with circle arc at given distance
- use a spiral equation r = b * phi
"""
def p2c(r, phi):
"""polar to cartesian
"""
return (r * math.cos(phi), r * math.sin(phi))
# yield a point at origin
yield (0, 0)
# initialize the next point in the required distance
r = arc
b = separation / (2 * math.pi)
# find the first phi to satisfy distance of `arc` to the second point
phi = float(r) / b
for i in range(0, count):
yield p2c(r, phi)
# advance the variables
# calculate phi that will give desired arc length at current radius
# (approximating with circle)
phi += float(arc) / r
r = b * phi
def sawtooth_points(start=0, count=100, step_increment=0.0001):
x = 0
y = 0.01
for i in frange(start, (step_increment*count) + step_increment, step_increment):
y *= -1
x += i
yield (x, y)
def _main():
usage = "usage: %prog shape shape2"
parser = OptionParser(usage=usage, add_help_option=False)
parser.add_option('-h', '--help', dest='help', action='store_true',
help='show this help message and exit')
(options, args) = parser.parse_args()
if options.help:
parser.print_help()
print """
Each arguement is a shape to generate, currently supported shapes are sawtooth and spiral.
Each shape can optionally include options, which are separated from the shape name by a ','.
valid options:
<number> The number of points to generate for that shape
x+<number> X coordinates will be offset by number
y+<number> Y coordinates will be offset by number
flip Flip x and x coordinates
"""
sys.exit()
features = []
shape_functions = {
'spiral': spiral_points,
'sawtooth': sawtooth_points
}
for arg in args:
shape_options = arg.split(',')
points_function = shape_functions[shape_options[0]]
shape_options = shape_options[1:]
x_offset = 0
y_offset = 0
count = 100
flip = False
for o in shape_options:
if o.startswith('x'):
x_offset = float(o.strip('x'))
elif o.startswith('y'):
y_offset = float(o.strip('y'))
elif re.match(r'^\d+$', o):
count = int(o)
elif o == 'flip':
flip = True
else:
print "Error, unknown option " + o
coordinates = list(points_function(count=count))
if flip:
coordinates = [(y, x) for x,y in coordinates]
coordinates = [(x + x_offset, y + y_offset) for x,y in coordinates]
features.append({
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": coordinates
}
})
print json.dumps({
"type": "FeatureCollection",
"features": features
})
if __name__ == "__main__":
_main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment