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