Пример #1
0
	def inside(self,pos):
		"""
		are we inside the polygon? We don't use colission detection directly since we can do
		some time saving tests
		"""
		if self.aPInnerCircleM==None: #created yet?
			self.aPInnerCircleM, self.aPInnerCircleRadius=fun.getPolygonInnerCircle(self.areaPoly)
		if fun.insideCircle(pos, self.aPInnerCircleM, self.aPInnerCircleRadius):
			return True #much faster than below
		return col.pointInPolygon(pos,self.areaPoly)
Пример #2
0
	def __init__(self, pos, nodes, G,direction=None, machine=None, main=False, radius=None):
		Road.__init__(self, pos, nodes, G, direction,radius=radius)
		self.m=machine
		self.trees=[]
		self.harvestTrees=0 #used to take care of the overlapping problem..
		tL=G.terrain.GetTrees(self.pos, self.radius+1) #+1 to be sure...
		for tree in tL:
			if col.pointInPolygon(tree.pos, self.getNodes()): #tree inside road,
				#check if tree already belongs to a road:
				if not self._checkIfTaken(tree):
					self.harvestTrees+=1
				self.trees.append(tree)
		self.startPoint=None #the startpoint of a corridor is where it intersects the mainRoad.This is where the crane is supposed to begin.
		self.main=main
Пример #3
0
	def generateTrees(self,dens, dbh_mean, dbh_std):
		"""
		Generates trees. Can only handle square areas right now.
		This is only done once, so code is not optimized.
		"""
		self.dbh_mean=dbh_mean
		self.dens=dens
		self.dbh_std=dbh_std
		trees=dens*self.area
		idealCell=[5.0,5.0]
		W=self.xlim[1]-self.xlim[0] 
		L=self.ylim[1]-self.ylim[0]
		if self.G:
			self.G.xlim=self.xlim	#override. The polynomial for A given to terrain is master
			self.G.ylim=self.ylim
		cellW=W/float(ceil(W/idealCell[0])) #ideal 5*5m, but adapt to the polygon
		cellL=L/float(ceil(L/idealCell[1]))
		cellA=cellW*cellL
		treesPerCell=int(floor(trees*cellA/self.area)) #if the whole cell is in areaPoly
		xAr=np.arange(self.xlim[0], stop=self.xlim[1], step=cellW) #will omitt last row in x and y, correct
		yAr=np.arange(self.ylim[0], stop=self.ylim[1], step=cellW)
		n=0
		for x in xAr:
			for y in yAr:
				if not col.pointInPolygon((x,y), self.areaPoly): continue
				tint=[]
				neighGrids=self.getNeighborObst([x,y])
				for i in range(treesPerCell):
					r=-1
					while r<0: r=random.normalvariate(dbh_mean, dbh_std)*0.5
					placed=False
					while not placed:
						pos=[x+random.uniform(0,cellW), y+random.uniform(0,cellL)]
						placed=True
						for neigh in tint:
							if getDistance(pos, neigh.pos) < r+neigh.radius:
								placed=False
								break #just for negih, while is still on
						if pos[0]-x<r or pos[0]-x>cellW-r or pos[1]-y<r or pos[1]-y>cellL-r: #iterate through neighboring trees.
							for neigh in neighGrids:
								if getDistance(neigh.pos, pos)<r+neigh.radius: #collide
									placed=False
									break
					t=Tree(pos, r, terrain=self)
					if random.uniform(0,1)<0.4: t.marked=True
					tint.append(t)
					n=n+1
		print "trees left over during generation: ",trees-n, "this is a problem, solve it..."
		"""thoughts around this problem. These trees needs to be distributed inside the cells,
Пример #4
0
def makeLines(areaPoly, origin, L, C, thMin):
	"""
	given an origin and an areaPolygon, this function creates lines from a specific spidernet pattern.
	"""
	#first, determine if origin is on border lines.
	if pointOnPolygonBorder(origin,areaPoly) or not col.pointInPolygon(origin, areaPoly): raise Exception('origin has to be inside polygon')
	xnorm=[origin, (origin[0]+1, origin[1])] #xaxis, used for angle calc.
	baseL=None #standard value until determined
	baseR=None

	if origin in areaPoly: #origin is on intersection
		for i in range(len(areaPoly)): #find origin
			if areaPoly[i]==origin:
				origInd=i
		ray1=[areaPoly[origInd], areaPoly[origInd-1]]
		ray2=[areaPoly[origInd], areaPoly[origInd+1]]
		baseL=Line(ray1[0], ray1[1], getAngle(ray1, xnorm), order=1)
		baseR=Line(ray2[0], ray2[1], getAngle(ray2, xnorm), order=1)
	else: #see if it is on border lines
		last=areaPoly[-1]
		for node in areaPoly:
			ray=[last, node]
			if col.pointOnLine(ray, origin):
				"""
				something is wrong with the angles below. Change to vectors so we get different angles.
				"""
				ray1=[origin, ray[0]]
				ray2=[origin, ray[1]]
				baseL=Line(ray1[0], ray1[1],  angleToXAxis(ray1), order=1)
				baseR=Line(ray2[0], ray2[1], angleToXAxis(ray2), order=1)
				break
			last=node


	if baseL==None: #origin is inside areaPoly. Make x-axis baseL and baseR
		p2=findIntersection(list(origin), th=0, areaPoly=areaPoly)
		baseL=Line(origin, p2, angle=2*pi, order=1)
		baseR=Line(origin, p2, angle=0, order=1)  #smart, huh? :)
	else:	#so, we have the bases.. check if left and right is correct
		if baseL.angle<baseR.angle:
			tmp=baseL
			baseL=baseR
			baseR=tmp
		angle=baseL.angle-asin(L*0.5/getDistance(baseL.ray[0], baseL.ray[1]))
		p2=findIntersection(list(baseL.p1), angle, areaPoly)
		cyl=getCylindrical(p2, origin=origin) #take it further away from the border
		p2=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
		baseL=Line(p1=baseL.p1, p2=p2, angle=angle, order=baseL.order)
	
		angle=baseR.angle+asin(L*0.5/getDistance(baseR.ray[0], baseR.ray[1]))
		p2=findIntersection(list(baseR.p1), angle, areaPoly)
		cyl=getCylindrical(p2, origin=origin) #take it further away from the border
		p2=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
		baseR=Line(p1=baseR.p1, p2=p2, angle=angle, order=baseL.order)
	print "base lines are done..."
	lines=[baseR, baseL]
	th=baseL.angle-baseR.angle
	dth=th
	order=1
	while True: #create lines, base roads
		dth=dth/2.
		if dth<thMin: break
		#order+=1
		newList=copy.deepcopy(lines)
		for i in range(len(lines)): #iterate through, from right to left
			line=lines[i]
			if line.no != baseL.no:
				th=line.angle+dth
				point=findIntersection(origin, th, areaPoly)
				cyl=getCylindrical(point, origin=origin) #take it further away from the border
				if cyl[0]<=C: continue #line is very short, not worth it.
				point=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
				lnew=Line(origin, point, th, order=order)
				for ind,ltmp in enumerate(newList):
					if ltmp.no==line.no:
						newList.insert(ind+1, lnew)
						break
		lines=newList
	#the base roads are done.. now let's find the smaller lines.
	lines.remove(lines[-1]) #this is baseL..same as baseR, remember?
	baseL=lines[-1] #the one most to the left
	#strategy: insert a line between two lines as long as asin(0.5L/length(line))>L
	while True:
		added=False
		newList=copy.deepcopy(lines)
		order+=1
		for i in range(len(lines)): #iterate through, from right to left
			line=lines[i]
			if line.no != baseL.no:
				leftBuddy=lines[i+1] #the one "to the left"
				rightBuddy=line
				#in the future, taking terrain into consideration, the angles to left and right buddy wont be the same. But now they are.
				dth=(leftBuddy.angle-rightBuddy.angle)/2. #the angle between..
				th=rightBuddy.angle+dth #angle in rel. to xaxis
				point=findIntersection(origin, th, areaPoly) #point at other side of areaPoly
				#now, make it C distance away from border.
				cyl=getCylindrical(point, origin=origin)
				point=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
				d=getDistance(origin, point)
				if d/tan(dth)>L:
					#this means that it will be reasonable to place a grid point on line. Create line!
					y=0.5*L*(1+1/sin(dth))#/(sin(dth)**2)
					p1=getCartesian([0, y], fromLocalCart=True, origin=origin, direction=th) #where it all starts..
					if getDistance(p1, origin)>=d or getDistance(p1,point)<C:
						continue #don't make line, it has a "negative length" or is too short..
					if col.pointInPolygon(p1, areaPoly):
						lnew=Line(p1, point, th, order=order)
						for ind,ltmp in enumerate(newList):
							if ltmp.no==line.no:
								added=True
								newList.insert(ind+1, lnew)
		if not added: break #no more lines to add.
		lines=newList
	return lines, baseL, baseR, order
Пример #5
0
	def __init__(self,L=24, diagonals=False, angle=None, areaPoly=None, origin=None, globalOrigin=None, thMin=pi/7.):
		C=L/2.
		ExtendedGraph.__init__(self, origin=origin, globalOrigin=globalOrigin,areaPoly=areaPoly, L=L, C=C,gridtype='spiderGridGraph')
		G=self #remove later and change to self below.
		longest=L*1.4 #longest allowed distance between two nodes on a line.
		eqL=L/6. #length where two points should be merged to one,m which is done in some cases
		if not areaPoly: #use default
			areaPoly=[(0,0), (300,0), (200,300), (-100, 200)]
			if origin: raise Exception('if origin is given, so must areaPoly be...')
			origin=(0,0)
			if not origin in areaPoly: raise Exception('only origin at borderpoints supported right now ')
		else:
			if not origin:
				origin=(0,0)
			if not col.pointInPolygon(origin,areaPoly):
				raise Exception('so far, SpiderGrid only supports origins on one of the border points')
		#so, look if origin is on the lines... if it is, swift it just a bit.
		if pointOnPolygonBorder(origin, areaPoly):
			while True: #we should never be stuck in this loop. 
				xnew=round(random.uniform(-0.1,0.1),2)
				ynew=round(random.uniform(-0.1, 0.1),2)
				pnew=(origin[0]+xnew, origin[1]+ynew)
				if col.pointInPolygon(pnew, areaPoly):
					if not pointOnPolygonBorder(pnew, areaPoly):
						origin=pnew #we found our new one.
						self.origin=origin
						break
		lines=[]
		thMin*=2 #will be divided below
		while len(lines)<2:
			thMin*=0.5
			lines, baseL, baseR, orderMax=makeLines(areaPoly, origin, L, C, thMin)
		#make grid of lines.
		print "lines done, now make grid"

		el=0 #will later be filled.
		G.L=L
		G.overlap={} #will later be filled.
		#make a road segments to the ones "to the left". If road that ist drawn to is of higher order, that is the last one from this line.
		for index, line in enumerate(lines): #make line to the ones on the "left"
			if line==baseL: break
			occured=[] #a list of different orders that have occured.. pretty complex.
			#an order 1 line should not e.g. have lines to all order 4 lines to the left, only one.
			for left in lines[index+1:]: # the one to the left of "line"
				if line.order==1 and left.order==1: break
				#identify the point, p2. line between should be orthogonal to "line" or "left", depending on order.
				cont=False #continue...
				for o in occured:
					if o<=left.order: cont=True #strange procedure, but can't use "continue" here due to above for.
				if cont: continue #we jump over some lines..think about it and you'll udnerstand
				occured.append(left.order)
				if left.order>line.order: #make ray orthogonal to line

					p1=left.p1
					th2=line.angle-pi/2.
					pTmp=tuple(getCartesian([0, 10000], origin=p1, direction=th2, fromLocalCart=True))
					a, p2=col.linesIntersect(np.array([p1,pTmp]), np.array(line.ray), getPoint=True)
					if not a:
						p2=line.p2
					p2=tuple(p2)
					if not p2 in line.gridPoints:
						line.gridPoints.append(p2)
				else: #make it orthogonal to left
					p1=line.p1
					th2=left.angle+pi/2.
					pTmp=tuple(getCartesian([0, 10000], origin=p1, direction=th2, fromLocalCart=True))
					a, p2=col.linesIntersect(np.array([p1,pTmp]), np.array(left.ray), getPoint=True)
					if not a:
						p2=left.p2
					p2=tuple(p2)
					if not p2 in left.gridPoints:
						left.gridPoints.append(p2)
				if not a:
					pass #raise Exception('something wrong, did not find neighbor point')
				if G.has_node(p1):
					G.add_node(p1)
					el+=1
				if not p2 in G.nodes():
					G.add_node(p2)
					el+=1
				G.add_edge(p1,p2, weight=self.edgeWeightCalc(p1,p2), visits=0, visited_from_node=[], c=0)
				if left.order <= line.order: break
		print "add neighbors"
		#we have the pattern. Add edges to neighbors in not that dens regions
		for index,line in enumerate(lines): 	#end points. Usually between two endpoints but not always.
			if line.no==baseL.no: break #this is the end
			leftBuddy=lines[index+1]
			if leftBuddy.angle<line.angle: raise Exception('ordering wrong..')
			closest=leftBuddy.gridPoints[0]
			closDist=getDistance(closest, line.p2)
			for pTmp in leftBuddy.gridPoints[1:]:
				d=getDistance(pTmp, line.p2)
				if d<closDist:
					closDist=d
					closest=pTmp
			G.add_edge(line.p2, closest, weight=self.edgeWeightCalc(line.p2, closest), visits=0, visited_from_node=[], c=0)
		lOrdered=copy.copy(lines) #not deepcopy, line instances are the same
		lOrdered=sorted(lOrdered, key=lambda line: line.order)
		for line in lOrdered:
			#if line.no==baseL.no: continue
			#now, identify the potential neighbors first.
			candidatesL=[]
			candidatesR=[]
			for cand, left in [(candidatesL, True), (candidatesR, False)]: #left=True if left.. faster
				for o in range(orderMax+1):
					if o==0: continue
					lst=[]
					if left:
						lst=[l for l in lines if l.order==o and l.angle>line.angle]
						nearest=None
						minAng=1e10
						for l in lst:
							if l.angle<minAng:
								nearest=l
								minAng=nearest.angle
						if nearest: cand.append(nearest) #we have our candidate of this order.
					else:
						lst=[l for l in lines if l.order==o and l.angle<line.angle]
						nearest=None
						maxAng=-1e10
						for l in lst:
							if l.angle>maxAng:
								nearest=l
								maxAng=nearest.angle
						if nearest: cand.append(nearest) #we have our candidate of this order.
			line.gridPoints=sorted(line.gridPoints, key=lambda point: -getDistance(point, origin)) #closest first
			last=line.gridPoints[0]
			for pTmp in copy.copy(line.gridPoints[1:]):
				d=getDistance(last,pTmp)
				if d>longest:
					nPoints=int(ceil(d/longest))-1
					last=pTmp
					l=d/(nPoints+1) #distance between points
					for i in range(nPoints):
						p=tuple(getCartesian([0, (i+1)*l], origin=pTmp, direction=line.angle, fromLocalCart=True))
						candidatesL=sorted(candidatesL, key=lambda l: abs(l.angle-line.angle))
						candidatesR=sorted(candidatesR, key=lambda l: abs(l.angle-line.angle))
						leftRay=np.array([p, getCartesian([0,100], origin=p, direction=line.angle+pi/2., fromLocalCart=True)])
						rightRay=np.array([p, getCartesian([0,100], origin=p, direction=line.angle-pi/2., fromLocalCart=True)])
						pL=None
						pR=None
						for cand in candidatesL:
							a,p2=col.linesIntersect(np.array(cand.ray), leftRay, getPoint=True)
							if a: #cand:s are ordered so that this is "the one"
								for pT in cand.gridPoints:
									if getDistance(list(pT), p2)<eqL: #2 meters.. same
										p2=pT
										break
								pL=tuple(p2)
								if not pL in cand.gridPoints: cand.gridPoints.append(pL)
								break
						for cand in candidatesR:
							a,p2=col.linesIntersect(np.array(cand.ray), rightRay, getPoint=True)
							if a: #cand:s are ordered so that this is "the one"
								for pT in cand.gridPoints:
									if getDistance(list(pT), p2)<eqL: #2 meters.. same
										p2=pT
										break
								pR=tuple(p2)
								if not pR in cand.gridPoints: cand.gridPoints.append(pR)
								break
						#now, if both pL and pR, create a straight line.
						if pL and pR: #new p!
							a,p=col.linesIntersect(np.array(line.ray), np.array([pL,pR]), getPoint=True)
							if not a: raise Exception('expected to find p here..')
							p=tuple(p)
						if pL:
							G.add_edge(pL,p,weight=self.edgeWeightCalc(pL,p), visits=0, visited_from_node=[], c=0)
						if pR:
							G.add_edge(pR,p, weight=self.edgeWeightCalc(pR,p), visits=0, visited_from_node=[], c=0)
						if not pL and not pR:
							G.add_node(p)
						line.gridPoints.append(tuple(p))
						
				last=pTmp

		for line in lines: #add edges on the line
			if len(line.gridPoints)<=1: continue
			line.gridPoints=sorted(line.gridPoints, key=lambda point: -getDistance(point, origin))
			last=line.gridPoints[0]
			for node in line.gridPoints[1:]:
				G.add_edge(last, node,weight=self.edgeWeightCalc(last, node), visits=0, visited_from_node=[], c=0)
				last=node
		rem=True
		for n in self.nodes():
			if not self.inside(n):
				self.remove_node(n)
		while rem:
			rem=False
			for n in self.nodes(): #pretty ugly, but a must..
				if self.degree(n)<=1:
					rem=True
					self.remove_node(n)
					break
		self.overlap={} #will later be filled.
		self.roadWidth=4
		self.L=L
		if not self.origin in self.nodes():
			shortest=None
			short_dist=1e10
			for n in self.nodes():
				d=fun.getDistance(n, self.origin)
				if d<short_dist:
					short_dist=d
					shortest=n
			self.origin=shortest
		elements=len(self.nodes())
		self.elements=elements
		self.density=elements/self.A
		self.density=elements/self.A
Пример #6
0
def inside(pos,areaPoly):
	"""
	max is a list with two elements. max[0]==xmax, max[1]==ymax. 
	"""
	return col.pointInPolygon(pos,areaPoly)
Пример #7
0
def readTerrain(globalOrigin=None, areaPoly=None):
	"""
	reads in data and returns local grid  x,y,z coordinates.

	Notes:
	-sweref coordinates are basically in [m], useful. We just need to normalize them to our new origin.
	-Problem with intersections between the files... how to handle?
	"""
	if not globalOrigin: globalOrigin=(596120, 6727530) #located on map.. nice position..
	if not areaPoly: areaPoly=[(0,0), (200,0), (200,200), (0,200)] #default..
	globalPoly=getGlobalCoordinate(globalOrigin, areaPoly=areaPoly)
	corn=(595000, 6725000)
	bordersPoly=[corn, (corn[0]+5000, corn[1]), (corn[0]+5000, corn[1]+5000), (corn[0], corn[1]+5000)]
	#check if polygon is inside polygon
	for node in globalPoly:
		if not col.pointInPolygon(node, globalPoly): raise Exception('areaPolygon is outside of the area that we have maps for.')

	#so, read in the data for our areaPolygon, or rather square containing it, and
	#normalize the cooordinates with respect to our origin.
	range=fun.polygonLim(globalPoly)
	xrange=range[0:2]
	yrange=range[2:4]
	xrange=[xrange[0]-2, xrange[1]+2]
	yrange=[yrange[0]-2, yrange[1]+2]
	#now, we should find out which files we need...
	fileList=getFileList(globalPoly)
	x, y, z=None, None, None #will later be created
	xlist, ylist, zlist=[], [], []
	m=1 #modulu, to reduce the grid resolution.. should be set from area of polygon..
	yold=None
	if len(fileList)>1: raise Exception('we do not support file overlaps right now..')
	folder=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tab')
	for fname in fileList:
		f=open(os.path.join(folder, fname+'.asc'))
		for index, line in enumerate(f):
			l=line.split()
			xtmp=int(l[0])
			ytmp=int(l[1])
			if ytmp>yrange[1]: break #because of how file is organized, we can do this.
			if xtmp<=xrange[1] and xtmp>=xrange[0] and ytmp>=yrange[0] and xtmp%m==0 and ytmp%m==0:
				if yold==None: yold=ytmp
				ztmp=float(l[2])
				if ytmp != yold: #new row..
					#identify if we're gonna need the next file in line..
					if x==None:
						x=np.array(xlist)
						y=np.array(ylist)
						z=np.array(zlist)
					else:
						x=np.vstack((x, xlist))
						y=np.vstack((y, ylist))
						z=np.vstack((z, zlist))
					xlist, ylist, zlist = [], [], []
				xlist.append(xtmp)
				ylist.append(ytmp)
				zlist.append(ztmp)
				yold=ytmp
		f.close()
	x-=globalOrigin[0]
	y-=globalOrigin[1]
	x=np.transpose(x) #we want it in the standard form that scipy understands.
	y=np.transpose(y) #this form corresponds to numpy.mgrid standard, but not numpy.meshgrid
	z=np.transpose(z)
	return x,y,z