A library for linear referencing on linestrings, including geographic calculations.
pip install ligeos==0.1.1
--== Description ==-- This library provides a simple OOP interface for linear referencing line strings and points. --== Known issues ==-- The GPoint and LineString(...,geographic=True) features have indeterminate behavior at the poles and certain operations that cross 180/-180 longitude. However, as this is rarely the case for a great many WGS (latitude/longitude) referenced datasets, the implementation ignores those edge cases. If you have a dataset with WGS geographic coordinates that cross at 180/-180 or over the poles, reproject the points first (see pyproj for a python implementation), then use LineString and Point. --== Prerequisites ==-- Python 2.4+ Cython >=0.10.3 (compilation only) --== Setup ==-- $ sudo python setup.py install --== Example ==-- import ligeos as l def test_basic(): assert int(157249.057369) == int(l.distance_earth(0,0,1,1)) p = l.GPoint(0,0); p2 = l.GPoint(1,1) assert int(157249.057369) == int(p.distance_pt(p2)) s = l.Line(p, p2) c = s.closest_pt(l.GPoint(0.5,0.5)) print c assert c.x == 0.5 and c.y == 0.5 c = s.closest_pt(l.GPoint(0,0.5)) assert c.x == 0.25 and c.y == 0.25 assert int(39312.8257487) == int(s.distance_pt(l.GPoint(0,0.5))) def test_linestring(): def tester(*args): s = l.LineString(*args) print "s len", len(s) assert len(s) == 2 print s.pts[0] print s.length() assert s.length() == 2**0.5 tester((0,0),(1,1)) tester([(0,0),(1,1)]) tester(((0,0),(1,1))) l1 = l.LineString([(0,0), (1,1)]) l2 = l.LineString([(1,0), (1,1)]) assert l1.distance_to_line(l2) == 0 l2 = l.LineString([(2,1), (100,100)]) print l1.distance_to_line(l2) assert l1.distance_to_line(l2) == 1 l1 = l.LineString([(0,0), (1,1), (2,2)]) assert l1.distance_pt(l.Point(1,1)) == 0 assert l1.distance_pt(l.Point(3,3)) == 2**0.5 assert l1.distance_pt(l.Point(0.5,0.5)) == 0 assert l1.closest_pt(l.Point(0,0.5)).x == 0.25 assert l1.length() == 2 * 2**0.5 def test_locating(): l1 = l.LineString([(0,0), (1,1), (2,2)]) assert l1.locate_point(l.Point(1,1)) == 0.5 l1 = l.LineString([(0,0), (1,1), (2,0)]) m = l1.locate_point(l.Point(1,3)) print m assert m == 0.5 m = l1.locate_point(l.Point(0.5,0.5)) print m assert m == 0.25 def test_closest_pt_seg(): p = l.seg_closest_pt(l.GPoint(-87.667542, 41.875746), l.GPoint(-87.671732, 41.875730), l.GPoint(-87.6685562134,41.8757400513)) assert int(p.x*1000000) == int(-87.6685562271*1000000) assert int(p.y*1000000) == int(41.8757430599*1000000) def test_substring(): l1 = l.LineString([(0,0), (1,1), (2,2)]) l2 = l1.substring(0, 0.5) print l2 assert l2.length() == 2**0.5 assert len(l2) == 2 l2 = l1.substring(0, 0.75) assert len(l2) == 3 assert l2.length() == 2**0.5 + (2*(0.5**2))**0.5 assert l2.pts[-1].x == 1.5 assert l2.pts[-1].y == 1.5 def test_concatenate(): l1 = l.LineString([(0,0), (1,1)]) l2 = l.LineString([(1,1), (2,2)]) l3 = l1.concatenate(l2) print l3 assert len(l3) == 3 l4 = l.LineString([(2,1), (2,2)]) l3 = l1.concatenate(l4) print l3 assert len(l3) == 4 # test merge strings l3 = l1.concatenate(l4, 1) print l3 assert len(l3) == 3 def test_intersect(): assert l.seg_intersect_seg(l.Point(0,0), l.Point(1,1), l.Point(2,2), l.Point(3,3)) == None assert l.seg_intersect_seg(l.Point(0,0), l.Point(1,1), l.Point(0,0), l.Point(3,3)).x == 0 assert l.seg_intersect_seg(l.Point(0,0), l.Point(1,1), l.Point(0,0), l.Point(3,3)).y == 0 assert l.seg_intersect_seg(l.Point(0,0), l.Point(1,1), l.Point(1,0), l.Point(0,1)).y == 0.5 assert l.seg_intersect_seg(l.Point(0,0), l.Point(1,1), l.Point(1,0), l.Point(0,1)).x == 0.5 assert l.seg_intersect_seg(l.Point(0,0), l.Point(1,1), l.Point(0,1), l.Point(1,0)).y == 0.5 assert l.seg_intersect_seg(l.Point(0,0), l.Point(1,1), l.Point(0,1), l.Point(1,0)).x == 0.5 assert l.seg_intersect_seg(l.Point(1,1), l.Point(0,0), l.Point(0,1), l.Point(1,0)).y == 0.5 assert l.seg_intersect_seg(l.Point(1,1), l.Point(0,0), l.Point(0,1), l.Point(1,0)).x == 0.5 l1 = l.LineString([(0,0), (1,1), (2,2)]) l2 = l.LineString([(0,0.5), (0, 1)]) assert l1.closest_pt_to_line(l2) != None assert l1.closest_pt_to_line(l2).x == 0.25 assert l1.closest_pt_to_line(l2).y == 0.25 if __name__ == '__main__': test_basic() test_linestring()