def main(self): pts_segs = ToPointsAndSegments() pts_segs.add_polygon([[(0, 0), (10, 0), (5, 10), (0, 0)], [(0, 0), (8, 2), (6, 4), (5, 7), (0, 0)]], ) #pts_segs.add_polygon([[(10,0), (15,10), (5,10), (10,0)], #[(2,2), (8,2), (6,4), (5,7), (2,2)] #], #) dt = triangulate(pts_segs.points, pts_segs.infos, pts_segs.segments) with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/path.wkt", "w") as fh: fh.write("i;group;depth;wkt\n") it = RegionatedTriangleIterator(dt) for i, (g, d, t) in enumerate(it, start=1): fh.write("{0};{1};{2};{3}\n".format(i, g, d, t)) with open("/tmp/later.wkt", "w") as fh: fh.write("wkt\n") for t in it.later: fh.write("{0}\n".format(t))
def main(): with open('curvy.geojson') as fh: t = json.load(fh) rings = [] for ring in t['features'][0]['geometry']['coordinates']: rings.append( #densify( [tuple(pt) for pt in ring[0]] # ) ) conv = ToPointsAndSegments() conv.add_polygon(rings) dt = triangulate(conv.points, conv.infos, conv.segments) with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) visitor = NarrowPartFinder([t for t in ConvexHullTriangleIterator(dt)]) visitor.find_narrows() with open("/tmp/filtered.wkt", "w") as fh: output_triangles(visitor.filtered, fh) with open("/tmp/remaining.wkt", "w") as fh: l = [] filtered = frozenset(visitor.filtered) for t in ConvexHullTriangleIterator(dt): if t not in filtered: l.append(t) output_triangles(l, fh) with open("/tmp/path.wkt", "w") as fh: fh.write("i;group;depth;wkt\n") it = RegionatedTriangleIterator(dt) for i, (g, d, t) in enumerate(it, start=1): fh.write("{0};{1};{2};{3}\n".format(i, g, d, t)) it = RegionatedTriangleIterator(dt) zero_tris = [] for (g, d, t) in it: if g == 1: for i in xrange(3): if t.constrained[i]: break else: zero_tris.append(t) else: break with open("/tmp/outside_zero.wkt", "w") as fh: output_triangles(zero_tris, fh) visitor = EdgeEdgeHarvester([t for t in ConvexHullTriangleIterator(dt)]) visitor.skeleton_segments() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write( "LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format( seg))
def main(): logging.basicConfig(filename='test_logging.log', level=logging.DEBUG) pts_segs = ToPointsAndSegments() pts_segs.add_polygon([[(0,0), (10,0), (5,10), (0,0)], [(0,0), (8,2), (6,4), (5,7), (0,0)] ], ) dt = triangulate(pts_segs.points, pts_segs.infos, pts_segs.segments)
def test_polygon_with_hole(self): conv = ToPointsAndSegments() outside_edges, polygon = recs() for edge_id, start_node_id, end_node_id, _, _, geom in polygon: face = None if edge_id == 1003: # interior ring face = -1 for i, pt in enumerate(geom): if i == len(geom) - 1: # last pt node = end_node_id tp = 1 if edge_id == 1003: # we need a bridge vertex tp = 2 elif i == 0: # first pt node = start_node_id tp = 1 if edge_id == 1003: tp = 2 else: # intermediate pt node = None tp = 0 conv.add_point((pt.x, pt.y), VertexInfo(tp, face, node)) for (start, end) in zip(geom[:-1], geom[1:]): (sx, sy) = start (ex, ey) = end conv.add_segment((sx, sy), (ex, ey)) points, segments, infos = conv.points, conv.segments, conv.infos dt = triangulate(points, infos, segments) visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() pick = ConnectorPicker(visitor) pick.pick_connectors() skeleton, new_edge_id = make_graph(outside_edges, visitor, new_edge_id=10000, universe_id=0, srid=-1) label_sides(skeleton) assert new_edge_id == 10001 # -- remove unwanted skeleton parts (same face id on both sides) prune_branches(skeleton) groups = define_groups(skeleton) new_edges, new_edge_id = make_new_edges(groups, new_edge_id) assert len(new_edges) == 1 assert new_edge_id == 10001
# print conv.points # skel = calc_skel(conv, pause=True, output=True) # with open("/tmp/out.wkt", "w") as fh: # print >> fh, "wkt\n" # for line in segments: # print >> fh, "LINESTRING({0[0][0]} {0[0][1]}, {0[1][0]} {0[1][1]})\n".format(line) # ############### #with open("/home/martijn/Documents/work/2016-01_grassfire_for_building_generalization/data/goes_zeeland/in-out/inwards_0276.geojson") as fh: #outwards_0276.geojson") as fh: # with open("/home/martijn/Documents/work/2016-01_grassfire_for_building_generalization/data/goes_zeeland/input_outline.geojson") as fh: #outwards_0276.geojson") as fh: # s = fh.read() # # # # import json # x = json.loads(s) # # parse segments from geo-json # segments = [] # for y in x['features']: # segments.append(tuple(map(tuple, y['geometry']['coordinates']))) # # # # # convert to triangulation input conv = ToPointsAndSegments() for line in segments: conv.add_point(line[0]) conv.add_point(line[1]) conv.add_segment(*line) ############### # skeletonize / offset skel = calc_skel(conv, pause=False, output=False, shrink=True)
def main(): import json # pts_segs = ToPointsAndSegments() # pts_segs.add_polygon([[(0,0), (10,0), (5,10), (0,0)], # #[(2,2), (8,2), (6,4), (5,7), (2,2)] # ], # ) # pts_segs.add_polygon([[(10,0), (15,10), (5,10), (10,0)], # #[(2,2), (8,2), (6,4), (5,7), (2,2)] # ], # ) # FIXME: does not work with this dataset yet, as the vertex density is not # high enough: should add more vertices (densify) with open('/home/martijn/workspace/splitarea/data/sandro/poly.geojson' ) as fh: c = json.loads(fh.read()) conv = ToPointsAndSegments() poly = c['features'][0]['geometry']['coordinates'] rings = [] for ring in poly: rings.append( # densify( [tuple(pt) for pt in ring] # , 5) ) del poly conv.add_polygon(rings) dt = triangulate(conv.points, conv.infos, conv.segments) trafo = VoronoiTransformer(dt) trafo.transform() with open("/tmp/vroni.wkt", "w") as fh: fh.write("wkt;start;end;left;right\n") for (start, end, lft, rgt) in trafo.segments: fh.write( "LINESTRING({0[0]} {0[1]}, {1[0]} {1[1]});{2};{3};{4};{5}\n". format(trafo.centers[start], trafo.centers[end], start, end, lft, rgt)) # FIXME: this should be part of the VoronoiTransformer ! tm = TopoMap() for i, (start, end, lft, rgt) in enumerate(trafo.segments, start=1): tm.add_edge(i, start, end, lft, rgt, LineString([trafo.centers[start], trafo.centers[end]])) find_loops(tm) with open("/tmp/geom.wkt", "w") as fh: fh.write("wkt\n") for face in tm.faces.itervalues(): try: fh.write("{0}\n".format(face.multigeometry()[0])) except: pass # visitor = MidpointHarvester([t for t in InteriorTriangleIterator(dt)]) # visitor.skeleton_segments() # with open("/tmp/skel.wkt", "w") as fh: # fh.write("wkt\n") # for seg in visitor.segments: # fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) with open("/tmp/inside.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh)
def test(): conv = ToPointsAndSegments() a, b, c, d, e = (0, 0), (10, 20), (20, 0), (10, 25), (25, 0) conv.add_point(a, info=VertexInfo(0, None, None)) conv.add_point(b, info=VertexInfo(1, None, 1001)) conv.add_point(c, info=VertexInfo(0, None, 1002)) conv.add_segment(a, b) conv.add_segment(b, c) conv.add_segment(c, a) points, segments, infos = conv.points, conv.segments, conv.infos pprint(points) pprint(segments) pprint(infos) dt = triangulate(points, infos, segments) for vertex in dt.vertices: print vertex, vertex.info with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/allvertices.wkt", "w") as fh: output_vertices(dt.vertices, fh) with open("/tmp/interiortris.wkt", "w") as fh: output_triangles([t for t in InteriorTriangleIterator(dt)], fh) with open("/tmp/hull.wkt", "w") as fh: output_triangles([t for t in ConvexHullTriangleIterator(dt)], fh) visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write( "LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format( seg)) visitor.pick_connectors() outside_edges = [ # #eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf (4000, LineString([d, b], ), 5001, False, 5001, 1001, False, 1001, "A", "B"), (4001, LineString([e, c], ), 5002, False, 5002, 1002, False, 1002, "B", "A"), ] # outside_edges = [] skeleton = SkeletonGraph() print """ ADDING OUTSIDE EDGES """ # first add outside edges for outside_edge in outside_edges: eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf, = outside_edge skeleton.add_segment(geom, external=True, edge_id=eid, left_face_id=lf, right_face_id=rf, start_node_id=sn, end_node_id=en, start_vertex_id=svtxid, end_vertex_id=evtxid, start_external=sn_ext, end_external=en_ext) # print """ # # BRIDGE CONNECTORS # """ # # add nodes from inner rings ("bridge" connectors) # for i, segment in enumerate(visitor.ext_segments): # v0, v1, = segment # ln = LineString() # ln.append(Point(*v0.point)) # ln.append(Point(*v1.point)) # skeleton.add_segment(ln, # external = True, # edge_id = i, # start_vertex_id = v0.gid, # end_vertex_id = v1.gid, # left_face_id = v0.label, # right_face_id = v0.label, # # start_external = True, # # end_external = True # ) # # print """ # # UNLABELED EDGES # """ # # then add all segments which are unlabeled for i, segment in enumerate(visitor.segments): v0, v1, = segment ln = LineString() ln.append(Point(v0.x, v0.y)) ln.append(Point(v1.x, v1.y)) start_vertex_id = v0.info.vertex_id if start_vertex_id is None: start_vertex_id = ( id(v0), ) # note, not an int but tuple to prevent duplicate with external ids end_vertex_id = v1.info.vertex_id if end_vertex_id is None: end_vertex_id = ( id(v1), ) # note, not an int but tuple to prevent duplicate with external ids print start_vertex_id print end_vertex_id skeleton.add_segment(ln, start_vertex_id=start_vertex_id, end_vertex_id=end_vertex_id, external=False, edge_id=i + len(visitor.ext_segments)) with open('/tmp/edges.wkt', 'w') as fh: fh.write("geometry;leftface;rightface;sn;en\n") for edge in skeleton.edges: print >> fh, edge.geometry, ";", edge.left_face_id, ";", edge.right_face_id, ";", edge.start_node.id, ";", edge.end_node.id skeleton.visualize_nodes() skeleton.label_sides() skeleton.prune_branches() skeleton.find_new_edges(new_edge_id=90000, new_node_id=80000) with open("/tmp/edges_new.wkt", "w") as fh: fh.write("eid;sn;en;lf;rf;length;geom\n") for eid, sn, en, lf, rf, length, geom, in skeleton.new_edges: print >> fh, eid, ";", sn, ";", en, ";", lf, ";", rf, ";", length, ";", geom
from tri import ToPointsAndSegments from grassfire import calc_skel #from simplegeom.wkt import loads """Centre in Goes """ if True: import logging import sys root = logging.getLogger() root.setLevel(logging.DEBUG) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') formatter = logging.Formatter('%(asctime)s - %(message)s') ch.setFormatter(formatter) root.addHandler(ch) conv = ToPointsAndSegments() polygon = [[(0, 3), (0.5, 5), (9, 8.5), (10, 2), (6, 4), (3.5, 1), (0, 3)]] conv.add_polygon(polygon) skel = calc_skel(conv, pause=True, output=True, shrink=True) # skeletonize / offset
def test(): # Test: # ===== # - straight forward split over 2 neighbours # outcome: 1 new edge conv = ToPointsAndSegments() outside_edges, polygon = recs() for _, start_node_id, end_node_id, _, _, geom in polygon: for i, pt in enumerate(geom): if i == len(geom) - 1: # last pt node = end_node_id tp = 1 elif i == 0: # first pt node = start_node_id tp = 1 else: # intermediate pt node = None tp = 0 conv.add_point((pt.x, pt.y), VertexInfo(tp, None, node)) for (start, end) in zip(geom[:-1],geom[1:]): (sx, sy) = start (ex, ey) = end conv.add_segment((sx, sy), (ex,ey)) points, segments, infos = conv.points, conv.segments, conv.infos pprint(points) pprint(segments) pprint(infos) dt = triangulate(points, infos, segments) for vertex in dt.vertices: print "POINT(", vertex.x, vertex.y, ")" #vertex.info with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/allvertices.wkt", "w") as fh: output_vertices(dt.vertices, fh) with open("/tmp/interiortris.wkt", "w") as fh: output_triangles([t for t in InteriorTriangleIterator(dt)], fh) with open("/tmp/hull.wkt", "w") as fh: output_triangles([t for t in ConvexHullTriangleIterator(dt)], fh) visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) with open("/tmp/skel1.wkt", "w") as fh: fh.write("wkt\n") for lst in visitor.bridges.itervalues(): print lst for seg in lst: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) pick = ConnectorPicker(visitor) pick.pick_connectors() with open("/tmp/skel2.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.ext_segments: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) # outside_edges = [ # # #eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf # (4000, # LineString([d, b],), # 5001, False, 5001, # 1001, False, 1001, # "A", "B" # ), # (4001, # LineString([e, c],), # 5002, False, 5002, # 1002, False, 1002, # "B", "A" # ), # ] # outside_edges = [] skeleton = SkeletonGraph() skeleton.srid = 32632 print """ ADDING OUTSIDE EDGES """ # first add outside edges for outside_edge in outside_edges: eid, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf, geom, = outside_edge skeleton.add_segment(geom, external = True, edge_id = eid, left_face_id = lf, right_face_id = rf, start_node_id = sn, end_node_id = en, start_vertex_id = svtxid, end_vertex_id = evtxid, start_external = sn_ext, end_external = en_ext ) print """ BRIDGE CONNECTORS """ # # add nodes from inner rings ("bridge" connectors) for i, segment in enumerate(visitor.ext_segments): print segment v0, v1, lf, rf = segment ln = LineString(srid=skeleton.srid) ln.append(Point(v0.x, v0.y)) ln.append(Point(v1.x, v1.y)) skeleton.add_segment(ln, external = True, edge_id = i, start_vertex_id = v0.info.vertex_id, end_vertex_id = v1.info.vertex_id, left_face_id = lf, right_face_id = rf, # start_external = True, # end_external = True ) print """ UNLABELED EDGES """ # # then add all segments which are unlabeled for i, segment in enumerate(visitor.segments, start = len(visitor.ext_segments)): v0, v1, = segment ln = LineString(srid=skeleton.srid) ln.append(Point(v0.x, v0.y)) ln.append(Point(v1.x, v1.y)) start_vertex_id = v0.info.vertex_id if start_vertex_id is None: start_vertex_id = (id(v0), ) # note, not an int but tuple to prevent duplicate with external ids end_vertex_id = v1.info.vertex_id if end_vertex_id is None: end_vertex_id = (id(v1), ) # note, not an int but tuple to prevent duplicate with external ids print start_vertex_id print end_vertex_id skeleton.add_segment(ln, start_vertex_id = start_vertex_id, end_vertex_id = end_vertex_id, external = False, edge_id = i) with open('/tmp/edges.wkt', 'w') as fh: fh.write("geometry;leftface;rightface;sn;en\n") for edge in skeleton.edges: print >> fh, edge.geometry,";", edge.left_face_id,";", edge.right_face_id, ";", edge.start_node.id,";", edge.end_node.id skeleton.label_sides() skeleton.prune_branches() skeleton.find_new_edges(new_edge_id=90000, new_node_id=80000) skeleton.visualize_nodes() with open("/tmp/edges_new.wkt", "w") as fh: fh.write("eid;sn;en;lf;rf;length;geom\n") for eid, sn, en, lf, rf, length, geom, in skeleton.new_edges: print >> fh, eid, ";", sn,";", en, ";", lf, ";", rf, ";", length,";", geom
def test(): # Test: # ===== # Triangle with *touching* hole # FIXME: # unnecessary nodes -->>> too short edges conv = ToPointsAndSegments() outside_edges, polygon = recs() for _, start_node_id, end_node_id, _, _, geom in polygon: for i, pt in enumerate(geom): if i == len(geom) - 1: # last pt node = end_node_id tp = 1 elif i == 0: # first pt node = start_node_id tp = 1 else: # intermediate pt node = None tp = 0 conv.add_point((pt.x, pt.y), VertexInfo(tp, None, node)) for (start, end) in zip(geom[:-1], geom[1:]): (sx, sy) = start (ex, ey) = end conv.add_segment((sx, sy), (ex, ey)) points, segments, infos = conv.points, conv.segments, conv.infos dt = triangulate(points, infos, segments) with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/allvertices.wkt", "w") as fh: output_vertices(dt.vertices, fh) with open("/tmp/interiortris.wkt", "w") as fh: output_triangles([t for t in InteriorTriangleIterator(dt)], fh) with open("/tmp/hull.wkt", "w") as fh: output_triangles([t for t in ConvexHullTriangleIterator(dt)], fh) visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write( "LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format( seg)) with open("/tmp/skel1.wkt", "w") as fh: fh.write("wkt\n") for lst in visitor.bridges.itervalues(): for seg in lst: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n". format(seg)) pick = ConnectorPicker(visitor) pick.pick_connectors() with open("/tmp/skel2.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.ext_segments: fh.write( "LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format( seg)) skeleton = make_graph(outside_edges, visitor) label_sides(skeleton) prune_branches(skeleton) groups = define_groups(skeleton) new_edges = make_new_edges(groups) with open("/tmp/edges_new.wkt", "w") as fh: fh.write("eid;sn;en;lf;rf;geom\n") for eid, sn, en, lf, rf, geom, in new_edges: print >> fh, eid, ";", sn, ";", en, ";", lf, ";", rf, ";", geom
def test_replace_kvertex(self): class QueueMock(object): """Mock for the priority queue """ def add(self, one): pass def remove(self, one): pass def discard(self, one): pass # init skeleton structure conv = ToPointsAndSegments() polygon = [[(-2, -1), (-1, 0), (1, 0), (1.5, -.5), (1.2, .7), (.4, 1.2), (-.6, 1.1), (-1.7, .7), (-2, -1)]] conv.add_polygon(polygon) dt = triangulate(conv.points, None, conv.segments) output_dt(dt) skel = init_skeleton(dt) # queue = QueueMock() newv = KineticVertex() newv.origin = (1, 0) newv.velocity = (0.5, 0.5) found = None for t in skel.triangles: if t.finite: if [v.position_at(0) for v in t.vertices] == [(1.0, 0.0), (0.4, 1.2), (-1.0, 0.0)]: found = t break assert found is not None a, b, c = None, None, None for v in t.vertices: if v.position_at(0) == (-1, 0): a = v if v.position_at(0) == (1, 0): b = v if v.position_at(0) == (0.4, 1.2): c = v assert a is not None assert b is not None assert c is not None # precondition: # no vertex equal to the new kinetic vertex for t in skel.triangles: assert newv not in t.vertices replace_kvertex(found, b, newv, 0, cw, queue) # postcondition # we should have replaced 3 vertices ct = 0 for t in skel.triangles: if newv in t.vertices: ct += 1 assert ct == 3 newv = KineticVertex() newv.origin = (-1, 0) newv.velocity = (-0.5, 0.5) # precondition: # no vertex equal to the new kinetic vertex for t in skel.triangles: assert newv not in t.vertices replace_kvertex(found, a, newv, 0, ccw, queue) # we should have replaced 4 vertices ct = 0 for t in skel.triangles: if newv in t.vertices: ct += 1 assert ct == 4
def test_square(self): conv = ToPointsAndSegments() outside_edges, polygon = recs() for edge_id, start_node_id, end_node_id, _, _, geom in polygon: face = None weights = [] for i, pt in enumerate(geom): if i == len(geom) - 1: # last pt node = end_node_id tp = 1 weights = [0, 10] elif i == 0: # first pt node = start_node_id tp = 1 weights = [0, 10] else: # intermediate pt node = None tp = 0 if edge_id == 1001: weights = [10] elif edge_id == 1002: weights = [0] else: raise ValueError('encountered unknown edge') conv.add_point((pt.x, pt.y), VertexInfo(tp, face, node)) for (start, end) in zip(geom[:-1], geom[1:]): (sx, sy) = start (ex, ey) = end conv.add_segment((sx, sy), (ex, ey)) points, segments, infos = conv.points, conv.segments, conv.infos dt = triangulate(points, infos, segments) # for v in dt.vertices: # print v.info visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() # with open("/tmp/skel0_unweighted.wkt", "w") as fh: # fh.write("wkt\n") # for seg in visitor.segments: # fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) # # with open("/tmp/skel1_unweighted.wkt", "w") as fh: # fh.write("wkt\n") # for lst in visitor.bridges.itervalues(): # for seg in lst: # fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) pick = ConnectorPicker(visitor) pick.pick_connectors() skeleton, new_edge_id = make_graph(outside_edges, visitor, new_edge_id=10000, universe_id=0, srid=-1) label_sides(skeleton) # lines = ["id;geometry\n"] # for he in skeleton.half_edges.itervalues(): # lines.append("{};{}\n".format(he.id, he.geometry)) # with open("/tmp/edges.wkt", "w") as fh: # fh.writelines(lines) # -- remove unwanted skeleton parts (same face id on both sides) prune_branches(skeleton) groups = define_groups(skeleton) new_edges, new_edge_id = make_new_edges(groups, new_edge_id) assert new_edge_id == 10000 assert len(new_edges) == 1 assert new_edges[0] == (10000, 5, 4, -1, 501, LineString([ Point(x=10.0, y=120.0, srid=0), Point(x=10.0, y=110.0, srid=0), Point(x=7.5, y=104.5, srid=0), Point(x=2.5, y=104.5, srid=0), Point(x=0.0, y=110.0, srid=0), Point(x=0.0, y=120.0, srid=0) ], srid=0))
def test(): conv = ToPointsAndSegments() conv.add_point((0, 0), info=VertexInfo(0, None, None)) conv.add_point((9, 1), info=VertexInfo(1, None, 1001)) conv.add_point((10, 10), info=VertexInfo(0, None, None)) conv.add_point((1, 9), info=VertexInfo(1, None, 1002)) conv.add_point((0, 0), info=VertexInfo(0, None, None)) conv.add_segment((0, 0), (9, 1)) conv.add_segment((9, 1), (10, 10)) conv.add_segment((10, 10), (1, 9)) conv.add_segment((1, 9), (0, 0)) points, segments, infos = conv.points, conv.segments, conv.infos dt = triangulate(points, infos, segments) with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/allvertices.wkt", "w") as fh: output_vertices(dt.vertices, fh) with open("/tmp/interiortris.wkt", "w") as fh: output_triangles([t for t in InteriorTriangleIterator(dt)], fh) with open("/tmp/hull.wkt", "w") as fh: output_triangles([t for t in ConvexHullTriangleIterator(dt)], fh) visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write( "LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format( seg)) pick = ConnectorPicker(visitor) pick.pick_connectors() # visitor = MidpointHarvester([t for t in InteriorTriangleIterator(dt)]) # visitor.skeleton_segments() # with open("/tmp/skel.wkt", "w") as fh: # fh.write("wkt\n") # for seg in visitor.segments: # fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) # with open("/tmp/centres.wkt", "w") as fh: # fh.write("wkt\n") # for t, point in visitor.triangle_point.iteritems(): # fh.write("POINT({0})\n".format(point)) outside_edges = [ #eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf (4000, LineString([(0, 20), (1, 9)]), 5002, True, (0, 20), 1002, False, (1, 9), 10000, 10005), (4001, LineString([(20, 1), (9, 1)]), 5001, True, (20, 1), 1001, False, (9, 1), 10005, 10000), ] skeleton = make_graph(outside_edges, visitor) label_sides(skeleton) prune_branches(skeleton) groups = define_groups(skeleton) new_edges = make_new_edges(groups) with open("/tmp/edges_new.wkt", "w") as fh: fh.write("eid;sn;en;lf;rf;geom\n") for eid, sn, en, lf, rf, geom, in new_edges: print >> fh, eid, ";", sn, ";", en, ";", lf, ";", rf, ";", geom
def test(): wkt = """ POLYGON ((0 0, 9 1, 10 10, 1 9, 0 0)) """ poly = loads(wkt) print poly conv = ToPointsAndSegments() conv.add_point((0, 0), info=VertexInfo(0, None, None)) conv.add_point((9, 1), info=VertexInfo(1, None, 1001)) conv.add_point((10, 10), info=VertexInfo(0, None, None)) conv.add_point((1, 9), info=VertexInfo(1, None, 1002)) conv.add_point((0, 0), info=VertexInfo(0, None, None)) conv.add_segment((0, 0), (9, 1)) conv.add_segment((9, 1), (10, 10)) conv.add_segment((10, 10), (1, 9)) conv.add_segment((1, 9), (0, 0)) points, segments, infos = conv.points, conv.segments, conv.infos pprint(points) pprint(segments) pprint(infos) dt = triangulate(points, infos, segments) for vertex in dt.vertices: print vertex, vertex.info with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/allvertices.wkt", "w") as fh: output_vertices(dt.vertices, fh) with open("/tmp/interiortris.wkt", "w") as fh: output_triangles([t for t in InteriorTriangleIterator(dt)], fh) with open("/tmp/hull.wkt", "w") as fh: output_triangles([t for t in ConvexHullTriangleIterator(dt)], fh) # #if DEBUG: print poly # ln = [] # for ring in poly: # for vtx in ring: # ln.append(vtx) # # ev = poly.envelope # #if DEBUG: print ev # eps = 10000 # half_dx = (ev.xmax - ev.xmin) / 2.0 # dy = (ev.ymax - ev.ymin) # # top - middle # top_y = ev.ymax + dy + eps # top_x = ev.xmin + half_dx # # bottom - left # left_x = ev.xmin - half_dx - eps # left_y = ev.ymin - eps # # bottom - right # right_x = ev.xmax + half_dx + eps # right_y = ev.ymin - eps # # bnd = [Vertex(left_x,left_y), # Vertex(right_x,right_y), # Vertex(top_x,top_y)] # # return # mesh = Mesh(boundary = bnd) # # mesh = Mesh() # prev_pt = None # seed("ab") # for i, pt in enumerate(ln): # vtx = Vertex(pt.x, pt.y) # # if i == 2: # vtx.flag = 1 # ext_end = Point(pt.x, pt.y) # # elif i == 60: # vtx.flag = 1 # ext_end2 = Point(pt.x, pt.y) # else: # vtx.flag = 0 # int(randint(0, 10) in (5, )) # # vtx = mesh.insert(vtx) # vtx.gid = i # if i == 2: # ext_end_id = vtx.gid # elif i == 60: # ext_end2_id = vtx.gid # # if i > 0: # mesh.add_constraint( prev_pt, vtx ) # prev_pt = vtx # # fh = open('/tmp/tris.wkt', 'w') # fh.write("geometry\n") # MeshVisualizer(mesh).list_triangles_wkt(fh) # fh.close() visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write( "LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format( seg)) visitor.pick_connectors() # visitor = MidpointHarvester([t for t in InteriorTriangleIterator(dt)]) # visitor.skeleton_segments() # with open("/tmp/skel.wkt", "w") as fh: # fh.write("wkt\n") # for seg in visitor.segments: # fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) # with open("/tmp/centres.wkt", "w") as fh: # fh.write("wkt\n") # for t, point in visitor.triangle_point.iteritems(): # fh.write("POINT({0})\n".format(point)) # visitor = TriangleVisitor(dt) # visitor.skeleton_segments() # visitor.pick_connectors() # # visitor.list_table_sg() # visitor.list_segments_pg() # visitor.list_connectors_pg() # visitor.list_pg() # visualizer = MeshVisualizer(mesh) # visualizer.list_pg() # make artificial external edges # ext_start = Point(1747940, 5136656) # ln = LineString() # ln.append(ext_start) # ln.append(ext_end) # outside_edges = [ # (500000, ln, 100, True, -1, 101, False, ext_end_id, 200, 201)] # #(eid, geom, sn, sn_ext, en, en_ext, lf, rf) # # ext_start2 = Point(1748550, 5136537) # ln = LineString() # ln.append(ext_start2) # ln.append(ext_end2) # outside_edges.append((600000, ln, 200, True, -2, 201, False, ext_end2_id, 201, 200)) # outside_edges = [ #eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf (4000, LineString([(1, 9), (0, 20), (20, 20), (20, 1), (9, 1)], ), 1002, False, 1002, 1001, False, 1001, "C", "B"), (4001, LineString([(0, 9), (1, 9)], ), 5002, False, 5002, 1002, False, 1002, "C", "D"), (4002, LineString([(9, 0), (9, 1)], ), 5001, False, 5001, 1001, False, 1001, "D", "C"), ] # outside_edges = [] skeleton = SkeletonGraph() print """ ADDING OUTSIDE EDGES """ # first add outside edges for outside_edge in outside_edges: eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf, = outside_edge skeleton.add_segment(geom, external=True, edge_id=eid, left_face_id=lf, right_face_id=rf, start_node_id=sn, end_node_id=en, start_vertex_id=svtxid, end_vertex_id=evtxid, start_external=sn_ext, end_external=en_ext) # print """ # # BRIDGE CONNECTORS # """ # # add nodes from inner rings ("bridge" connectors) # for i, segment in enumerate(visitor.ext_segments): # v0, v1, = segment # ln = LineString() # ln.append(Point(*v0.point)) # ln.append(Point(*v1.point)) # skeleton.add_segment(ln, # external = True, # edge_id = i, # start_vertex_id = v0.gid, # end_vertex_id = v1.gid, # left_face_id = v0.label, # right_face_id = v0.label, # # start_external = True, # # end_external = True # ) # # print """ # # UNLABELED EDGES # """ # # then add all segments which are unlabeled for i, segment in enumerate(visitor.segments): v0, v1, = segment ln = LineString() ln.append(Point(v0.x, v0.y)) ln.append(Point(v1.x, v1.y)) start_vertex_id = v0.info.vertex_id if start_vertex_id is None: start_vertex_id = ( id(v0), ) # note, not an int but tuple to prevent duplicate with external ids end_vertex_id = v1.info.vertex_id if end_vertex_id is None: end_vertex_id = ( id(v1), ) # note, not an int but tuple to prevent duplicate with external ids print start_vertex_id print end_vertex_id skeleton.add_segment(ln, start_vertex_id=start_vertex_id, end_vertex_id=end_vertex_id, external=False, edge_id=i + len(visitor.ext_segments)) with open('/tmp/edges.wkt', 'w') as fh: fh.write("geometry;leftface;rightface;sn;en\n") for edge in skeleton.edges: print >> fh, edge.geometry, ";", edge.left_face_id, ";", edge.right_face_id, ";", edge.start_node.id, ";", edge.end_node.id skeleton.visualize_nodes() skeleton.label_sides() skeleton.prune_branches() skeleton.find_new_edges(new_edge_id=90000, new_node_id=80000) with open("/tmp/edges_new.wkt", "w") as fh: fh.write("eid;sn;en;lf;rf;length;geom\n") for eid, sn, en, lf, rf, length, geom, in skeleton.new_edges: print >> fh, eid, ";", sn, ";", en, ";", lf, ";", rf, ";", length, ";", geom
""" from tri import ToPointsAndSegments from grassfire import calc_skel if True: import logging import sys root = logging.getLogger() root.setLevel(logging.DEBUG) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(message)s') ch.setFormatter(formatter) root.addHandler(ch) conv = ToPointsAndSegments() with open("segments.wkt") as fh: for line in fh: if line.startswith("LINESTRING"): seg = line[line.find("(")+1:-2] parta, partb = seg.split(",") start = tuple(map(float, parta.strip().split(" "))) end = tuple(map(float, partb.strip().split(" "))) conv.add_point(start) conv.add_point(end) conv.add_segment(start, end) # skeletonize / offset skel = calc_skel(conv, pause=False, output=True, shrink=True)
def test(): # Test: # ===== # Triangle with *touching* hole # FIXME: # unnecessary node which is the start of the inner ring remains # as edges around this node are flagged as external conv = ToPointsAndSegments() a, b, c, = (0,0), (10,20), (20,0) d, e = (10,25), (25,0) g, h = (10,16), (16,2) alpha3 = angle(a, b) alpha2 = angle(a, g) alpha1 = angle(a, h) alpha0 = angle(a, c) # node sector # (he.twin.face.id, he.twin.next.id, he.twin.next.angle, he.id, he.angle) sectors = [ ("Z", 9001, alpha0, 9002, alpha1), ("C", 9002, alpha1, 9002, alpha2), ("Z", 9002, alpha2, 9003, alpha3), ("B", 9003, alpha3, 9001, alpha0) # ("Z", alpha1, 9002, alpha0, 9001), # ("C", alpha2, 9002, alpha1, 9002), # ("Z", alpha3, 9003, alpha2, 9002), # ("B", alpha0, 9001, alpha3, 9003) ] conv.add_point(b, info = VertexInfo(1, None, 1001)) conv.add_point(c, info = VertexInfo(0, None, 1002)) conv.add_point(a, info = VertexInfo(3, sectors, 1003)) conv.add_point(g, info = VertexInfo(0, None, None)) conv.add_point(h, info = VertexInfo(0, None, None)) conv.add_segment(a, b) conv.add_segment(b, c) conv.add_segment(c, a) conv.add_segment(a, g) conv.add_segment(g, h) conv.add_segment(h, a) points, segments, infos = conv.points, conv.segments, conv.infos pprint(points) pprint(segments) pprint(infos) dt = triangulate(points, infos, segments) for vertex in dt.vertices: print vertex, vertex.info with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/allvertices.wkt", "w") as fh: output_vertices(dt.vertices, fh) with open("/tmp/interiortris.wkt", "w") as fh: output_triangles([t for t in InteriorTriangleIterator(dt)], fh) with open("/tmp/hull.wkt", "w") as fh: output_triangles([t for t in ConvexHullTriangleIterator(dt)], fh) visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) with open("/tmp/skel1.wkt", "w") as fh: fh.write("wkt\n") for lst in visitor.bridges.itervalues(): print lst for seg in lst: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) visitor.pick_connectors() with open("/tmp/skel2.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.ext_segments: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n".format(seg)) outside_edges = [ # #eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf (4000, LineString([d, b],), 5001, False, 5001, 1001, False, 1001, "A", "B" ), (4001, LineString([e, c],), 5002, False, 5002, 1002, False, 1002, "B", "A" ), ] # outside_edges = [] skeleton = SkeletonGraph() print """ ADDING OUTSIDE EDGES """ # first add outside edges for outside_edge in outside_edges: eid, geom, sn, sn_ext, svtxid, en, en_ext, evtxid, lf, rf, = outside_edge skeleton.add_segment(geom, external = True, edge_id = eid, left_face_id = lf, right_face_id = rf, start_node_id = sn, end_node_id = en, start_vertex_id = svtxid, end_vertex_id = evtxid, start_external = sn_ext, end_external = en_ext ) print """ BRIDGE CONNECTORS """ # # add nodes from inner rings ("bridge" connectors) for i, segment in enumerate(visitor.ext_segments): print segment v0, v1, lf, rf = segment ln = LineString() ln.append(Point(v0.x, v0.y)) ln.append(Point(v1.x, v1.y)) skeleton.add_segment(ln, external = True, edge_id = i, start_vertex_id = v0.info.vertex_id, end_vertex_id = v1.info.vertex_id, left_face_id = lf, right_face_id = rf, # start_external = True, # end_external = True ) print """ UNLABELED EDGES """ # # then add all segments which are unlabeled for i, segment in enumerate(visitor.segments, start = len(visitor.ext_segments)): v0, v1, = segment ln = LineString() ln.append(Point(v0.x, v0.y)) ln.append(Point(v1.x, v1.y)) start_vertex_id = v0.info.vertex_id if start_vertex_id is None: start_vertex_id = (id(v0), ) # note, not an int but tuple to prevent duplicate with external ids end_vertex_id = v1.info.vertex_id if end_vertex_id is None: end_vertex_id = (id(v1), ) # note, not an int but tuple to prevent duplicate with external ids print start_vertex_id print end_vertex_id skeleton.add_segment(ln, start_vertex_id = start_vertex_id, end_vertex_id = end_vertex_id, external = False, edge_id = i) with open('/tmp/edges.wkt', 'w') as fh: fh.write("geometry;leftface;rightface;sn;en\n") for edge in skeleton.edges: print >> fh, edge.geometry,";", edge.left_face_id,";", edge.right_face_id, ";", edge.start_node.id,";", edge.end_node.id skeleton.label_sides() skeleton.prune_branches() skeleton.find_new_edges(new_edge_id=90000, new_node_id=80000) skeleton.visualize_nodes() with open("/tmp/edges_new.wkt", "w") as fh: fh.write("eid;sn;en;lf;rf;length;geom\n") for eid, sn, en, lf, rf, length, geom, in skeleton.new_edges: print >> fh, eid, ";", sn,";", en, ";", lf, ";", rf, ";", length,";", geom
def test_polygon_with_hole(self): """Splitting of face with for which the skeleton is a cycle There should be a bridge connector made at node 1332 """ conv = ToPointsAndSegments() outside_edges, polygon = recs() for edge_id, start_node_id, end_node_id, _, _, geom in polygon: face = None # loop edge: 1010852 (start node == end node) for i, pt in enumerate(geom): if i == len(geom) - 1: # last pt node = end_node_id tp = 1 if node == 1332: # we need a bridge vertex face = 1006189 tp = 3 print "setting type to", tp, "face to", face elif i == 0: # first pt node = start_node_id tp = 1 if node == 1332: face = 1006189 tp = 3 print "setting type to", tp, "face to", face else: # intermediate pt node = None tp = 0 conv.add_point((pt.x, pt.y), VertexInfo(tp, face, node)) for (start, end) in zip(geom[:-1], geom[1:]): (sx, sy) = start (ex, ey) = end conv.add_segment((sx, sy), (ex, ey)) points, segments, infos = conv.points, conv.segments, conv.infos dt = triangulate(points, infos, segments) with open("/tmp/alltris.wkt", "w") as fh: output_triangles([t for t in TriangleIterator(dt)], fh) with open("/tmp/allvertices.wkt", "w") as fh: output_vertices(dt.vertices, fh) with open("/tmp/interiortris.wkt", "w") as fh: output_triangles([t for t in InteriorTriangleIterator(dt)], fh) with open("/tmp/hull.wkt", "w") as fh: output_triangles([t for t in ConvexHullTriangleIterator(dt)], fh) visitor = EdgeEdgeHarvester([t for t in InteriorTriangleIterator(dt)]) visitor.skeleton_segments() pick = ConnectorPicker(visitor) pick.pick_connectors() with open("/tmp/skel0.wkt", "w") as fh: fh.write("wkt\n") for seg in visitor.segments: fh.write("LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n". format(seg)) with open("/tmp/skel1.wkt", "w") as fh: fh.write("wkt\n") for lst in visitor.bridges.itervalues(): for seg in lst: fh.write( "LINESTRING({0[0].x} {0[0].y}, {0[1].x} {0[1].y})\n". format(seg)) skeleton, new_edge_id = make_graph(outside_edges, visitor, new_edge_id=10000, universe_id=0, srid=-1) label_sides(skeleton) # assert new_edge_id == 10001 # -- remove unwanted skeleton parts (same face id on both sides) prune_branches(skeleton) groups = define_groups(skeleton) new_edges, new_edge_id = make_new_edges(groups, new_edge_id) from pprint import pprint pprint(new_edges) with open("/tmp/edges_new.wkt", "w") as fh: fh.write("eid;sn;en;lf;rf;geom\n") for eid, sn, en, lf, rf, geom, in new_edges: print >> fh, eid, ";", sn, ";", en, ";", lf, ";", rf, ";", geom