def finalDraw(self, event): p = event.coords dist = distancePointLinePerpendicular(p[2], p[0], p[1]) toLeft = computeOrientation(p[1], p[0], p[2]) == LEFT p[2] = GeoUtils.perpendicularVector(p[1], p[0], dist, toLeft) p.add(GeoUtils.vectorAdd(p[2], GeoUtils.vectorBetween(p[1], p[0]) )) #p.add(CoordUtils.add(p[2], CoordUtils.subtract(p[1], p[0]) )) #jts way p.add(Coordinate(p[0])) width = p[0].distance(p[1]) length = p[1].distance(p[2]) panel = event.wc.layerViewPanel statMsg = "[" + panel.format(width) + ", " + panel.format(length) + "]" event.statusMessage = statMsg
def corner(event): #this event handler won't fire until fireClicks points p = event.coords #set p to the current array of coordinates dist = p[2].distance(GeoUtils.getClosestPointOnLine(p[2], p[0], p[1])) toLeft = not GeoUtils.pointToRight(p[2], p[1], p[0]) p[2] = GeoUtils.perpendicularVector(p[1], p[0], dist, toLeft)
def _roadDraw(p, final=0): global _edit1, _laneWidths, _doBackup, _skip, _radius, _roadCenterLine roadEdgeLeft = ArrayList() roadEdgeRight = ArrayList() _roadCenterLine = ArrayList() try: laneWidth = float(_edit1.text) except: laneWidth = p[0].distance(p[1]) roadWidth = laneWidth * 2.0 if p.size() == 3: _laneWidths = [laneWidth, laneWidth] _edit1.text = "%f" % laneWidth p.remove(0) if len(_laneWidths) < p.size(): _laneWidths.append(laneWidth) else: _laneWidths[-1] = laneWidth #handle the backup button for skip in _skip: p.remove(skip) skip = 0 if _doBackup: skip = p.size() - 2 #index of prior point _skip.append(skip) #we'll need it next time we get p[] _doBackup = 0 if skip > 1: #lane width skips can be handled now _laneWidths = _laneWidths[:skip] + _laneWidths[skip + 1:] if skip > 1: p.remove(skip) left = 1 right = 0 #crank in the initial road rectangle left and right edges roadEdgeLeft.add( GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left)) roadEdgeRight.add( GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left)) roadEdgeRight.add( GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], right)) roadEdgeLeft.add( GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], right)) roadEdgeRight.add( GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], left)) _roadCenterLine.add(p[0]) _roadCenterLine.add(p[1]) #calculate the left and right edges of the rest of the road currPos = 1 endPos = p.size( ) - 1 #the last point in the array is the curr mouse pos adjusted by constraints perp1 = GeoUtils.perpendicularVector(p[1], p[0], roadWidth, right) while currPos < endPos: midPt = CU.add(p[currPos], CU.divide(CU.subtract(p[currPos + 1], p[currPos]), 2)) perp2 = GeoUtils.perpendicularVector(midPt, p[currPos], roadWidth, right) center = GeoUtils.getIntersection(p[currPos], perp1, midPt, perp2) if center.z == 0.0: #check for parallel vectors radius = center.distance(p[currPos]) d = p[currPos].distance(midPt) curved = radius / d < 50 #compare to tangent threshold else: curved = 0 if curved: #construct a circular curve circularArc = (_laneWidths[currPos] == _laneWidths[currPos + 1]) radius = center.distance(p[currPos]) toLeft = computeOrientation(p[currPos], perp1, p[currPos + 1]) == LEFT basePerp = GeoUtils.perpendicularVector(p[currPos], perp1, roadWidth, toLeft) toLeft = computeOrientation(p[currPos], basePerp, p[currPos + 1]) == LEFT radians = Angle.angleBetween(center, p[currPos], p[currPos + 1]) if circularArc: #left edge if toLeft: angle = -Angle.toDegrees(radians) ratio = (radius - _laneWidths[currPos]) / radius else: angle = Angle.toDegrees(radians) ratio = (radius + _laneWidths[currPos]) / radius arc = Arc(center, p[currPos], angle) arcPts = arc.getCoordinates() for pt in arcPts: _roadCenterLine.add(pt) start = CU.add( center, CU.multiply(ratio, CU.subtract(p[currPos], center))) arc = Arc(center, start, angle) arcPts = arc.getCoordinates() for pt in arcPts: roadEdgeLeft.add(pt) #right edge if toLeft: ratio = (radius + _laneWidths[currPos]) / radius else: ratio = (radius - _laneWidths[currPos]) / radius start = CU.add( center, CU.multiply(ratio, CU.subtract(p[currPos], center))) arc = Arc(center, start, angle) arcPts = arc.getCoordinates() for pt in arcPts: roadEdgeRight.add(pt) perp1.x = center.x perp1.y = center.y _radius = radius - _laneWidths[currPos] else: #smooth tangent non-circular curve #left edge if toLeft: angle = -Angle.toDegrees(radians) else: angle = Angle.toDegrees(radians) start = p[currPos] arc = Arc(center, start, angle) arcPts = arc.getCoordinates() for pt in arcPts: _roadCenterLine.add(pt) inc = (_laneWidths[currPos + 1] - _laneWidths[currPos]) / (arcPts.size() - 1) i = 0 for pt in arcPts: if toLeft: ratio = (radius - _laneWidths[currPos] - (i * inc)) / radius else: ratio = (radius + _laneWidths[currPos] + (i * inc)) / radius roadEdgeLeft.add( CU.add(center, CU.multiply(ratio, CU.subtract(pt, center)))) i += 1 #right edge i = 0 for pt in arcPts: if toLeft: ratio = (radius + _laneWidths[currPos] + (i * inc)) / radius else: ratio = (radius - _laneWidths[currPos] - (i * inc)) / radius roadEdgeRight.add( CU.add(center, CU.multiply(ratio, CU.subtract(pt, center)))) i += 1 perp1.x = center.x perp1.y = center.y _radius = radius - _laneWidths[currPos] else: #construct straight section of road roadEdgeLeft.add( GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], right)) roadEdgeRight.add( GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], left)) perp1 = GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], right) _roadCenterLine.add(p[currPos + 1]) _radius = 0 currPos += 1 #if final: #uncomment to display click point feedback for debugging p.clear() #clear the click point array and replace with road edges for pt in roadEdgeLeft: p.add(pt) #trace right return path back to start i = roadEdgeRight.size() - 1 while i >= 0: p.add(roadEdgeRight[i]) i -= 1
def _roadDraw(p, final=0): global _edit1, _laneWidths, _doBackup, _skip, _radius, _roadCenterLine roadEdgeLeft = ArrayList() roadEdgeRight = ArrayList() _roadCenterLine = ArrayList() try: laneWidth = float(_edit1.text) except: laneWidth = p[0].distance(p[1]) roadWidth = laneWidth * 2.0 if p.size() == 3: _laneWidths = [laneWidth, laneWidth] _edit1.text = "%f" % laneWidth p.remove(0) if len(_laneWidths) < p.size(): _laneWidths.append(laneWidth) else: _laneWidths[-1] = laneWidth #handle the backup button for skip in _skip: p.remove(skip) skip = 0 if _doBackup: skip = p.size() - 2 #index of prior point _skip.append(skip) #we'll need it next time we get p[] _doBackup = 0 if skip > 1: #lane width skips can be handled now _laneWidths = _laneWidths[:skip] + _laneWidths[skip+1:] if skip > 1: p.remove(skip) left = 1 right = 0 #crank in the initial road rectangle left and right edges roadEdgeLeft.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left)) roadEdgeRight.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], left)) roadEdgeRight.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], right)) roadEdgeLeft.add(GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], right)) roadEdgeRight.add(GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], left)) _roadCenterLine.add(p[0]) _roadCenterLine.add(p[1]) #calculate the left and right edges of the rest of the road currPos = 1 endPos = p.size() - 1 #the last point in the array is the curr mouse pos adjusted by constraints perp1 = GeoUtils.perpendicularVector(p[1], p[0], roadWidth, right) while currPos < endPos: midPt = CU.add( p[currPos], CU.divide(CU.subtract(p[currPos + 1], p[currPos]), 2)) perp2 = GeoUtils.perpendicularVector(midPt, p[currPos], roadWidth, right) center = GeoUtils.getIntersection(p[currPos], perp1, midPt, perp2) if center.z == 0.0: #check for parallel vectors radius = center.distance(p[currPos]) d = p[currPos].distance(midPt) curved = radius / d < 50 #compare to tangent threshold else: curved = 0 if curved: #construct a circular curve circularArc = (_laneWidths[currPos] == _laneWidths[currPos + 1]) radius = center.distance(p[currPos]) toLeft = computeOrientation(p[currPos], perp1, p[currPos + 1]) == LEFT basePerp = GeoUtils.perpendicularVector(p[currPos], perp1, roadWidth, toLeft) toLeft = computeOrientation(p[currPos], basePerp, p[currPos + 1]) == LEFT radians = Angle.angleBetween(center, p[currPos], p[currPos + 1]) if circularArc: #left edge if toLeft: angle = -Angle.toDegrees(radians) ratio = (radius - _laneWidths[currPos]) / radius else: angle = Angle.toDegrees(radians) ratio = (radius + _laneWidths[currPos]) / radius arc = Arc(center, p[currPos], angle) arcPts = arc.getCoordinates() for pt in arcPts: _roadCenterLine.add(pt) start = CU.add(center, CU.multiply(ratio, CU.subtract(p[currPos], center))) arc = Arc(center, start, angle) arcPts = arc.getCoordinates() for pt in arcPts: roadEdgeLeft.add(pt) #right edge if toLeft: ratio = (radius + _laneWidths[currPos]) / radius else: ratio = (radius - _laneWidths[currPos]) / radius start = CU.add(center, CU.multiply(ratio, CU.subtract(p[currPos], center))) arc = Arc(center, start, angle) arcPts = arc.getCoordinates() for pt in arcPts: roadEdgeRight.add(pt) perp1.x = center.x perp1.y = center.y _radius = radius - _laneWidths[currPos] else: #smooth tangent non-circular curve #left edge if toLeft: angle = -Angle.toDegrees(radians) else: angle = Angle.toDegrees(radians) start = p[currPos] arc = Arc(center, start, angle) arcPts = arc.getCoordinates() for pt in arcPts: _roadCenterLine.add(pt) inc = (_laneWidths[currPos + 1] - _laneWidths[currPos]) / (arcPts.size() - 1) i = 0 for pt in arcPts: if toLeft: ratio = (radius - _laneWidths[currPos] - (i * inc)) / radius else: ratio = (radius + _laneWidths[currPos] + (i * inc)) / radius roadEdgeLeft.add(CU.add(center, CU.multiply(ratio, CU.subtract(pt, center)))) i += 1 #right edge i = 0 for pt in arcPts: if toLeft: ratio = (radius + _laneWidths[currPos] + (i * inc)) / radius else: ratio = (radius - _laneWidths[currPos] - (i * inc)) / radius roadEdgeRight.add(CU.add(center, CU.multiply(ratio, CU.subtract(pt, center)))) i += 1 perp1.x = center.x perp1.y = center.y _radius = radius - _laneWidths[currPos] else: #construct straight section of road roadEdgeLeft.add(GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], right)) roadEdgeRight.add(GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], left)) perp1 = GeoUtils.perpendicularVector(p[currPos + 1], p[currPos], _laneWidths[currPos + 1], right) _roadCenterLine.add(p[currPos + 1]) _radius = 0 currPos += 1 #if final: #uncomment to display click point feedback for debugging p.clear() #clear the click point array and replace with road edges for pt in roadEdgeLeft: p.add(pt) #trace right return path back to start i = roadEdgeRight.size() - 1 while i >= 0: p.add(roadEdgeRight[i]) i -= 1