def get_notampoints_on_line(latlon1,latlon2,dist_nm): zoomlevel=13 distmax=mapper.approx_scale(mapper.latlon2merc(latlon1,zoomlevel),zoomlevel,dist_nm) px1,py1=mapper.latlon2merc(latlon1,zoomlevel) px2,py2=mapper.latlon2merc(latlon2,zoomlevel) a=Vertex(int(px1),int(py1)) b=Vertex(int(px2),int(py2)) line=Line(a,b) crosses=[] for kind,items in get_notam_objs_cached().items(): if kind!="areas": for item in items: x,y=mapper.latlon2merc(mapper.from_str(item['pos']),zoomlevel) d=line.approx_dist(Vertex(int(x),int(y))) clo=line.approx_closest(Vertex(int(x),int(y))) alongd=(clo-a).approxlength() totd=(a-b).approxlength() #print "AlongD: %s, totd: %s"%(alongd,totd) #print "Line: %s, notam coord: %s, closest: %s"%((a,b),(x,y),clo) #print "Item %s, d: %s, distmax: %s"%(item,d,distmax) if totd<1e-6: perc=0 else: perc=alongd/totd if d<distmax: #print "Yielding item." yield dict(item=item,alongperc=perc)
def test_intersection2(): def r(): return random.randint(-50,50) random.seed(0) for x in xrange(1000): la=Line(Vertex(r(),r()),Vertex(r(),r())) lb=Line(Vertex(r(),r()),Vertex(r(),r())) if not points(la).intersection(points(lb)): continue ls=list(la.intersect2(lb)) for a,b in all_pairs(ls): l2=list(a.intersect2(b)) if len(l2)!=0: print "Problematic intersect: %s %s"%(la,lb) visualize_diff([ (la,(255,0,0)), (lb,(0,255,0)), (ls[0],(0,0,255)), (ls[4],(0,0,255)), ],[]) visualize_diff([ (a,(255,0,0)), (b,(0,255,0)), (l2[0],(0,0,255)), ],[]) assert len(l2)==0
def get_stuff_near_route(rts,items,dist,vertdist): for item in items: try: itemmerc=mapper.latlon2merc(mapper.from_str(item['pos']),13) except Exception: print "Bad coord:",item['pos'] continue itemv=Vertex(int(itemmerc[0]),int(itemmerc[1])) onenm=mapper.approx_scale(itemmerc,13,1.0) for rt in rts: if rt.dt==None: continue #print "=========================================" av=Vertex(int(rt.subposa[0]),int(rt.subposa[1])) bv=Vertex(int(rt.subposb[0]),int(rt.subposb[1])) l=Line(av,bv) linelen=(bv-av).approxlength() actualclosest=l.approx_closest(itemv) #print item['name'],"A: ",av,"B: ",bv,"clo:",actualclosest actualdist=(actualclosest-itemv).approxlength()/onenm #print "Actualdist: ",actualdist ls=(actualclosest-av).approxlength() #print "Length from start:",ls #print "Linelen:",linelen if linelen>1e-3: along=ls/linelen else: along=0 #print "Along:",along #print "Startalt:",rt.startalt," endalt: ",rt.endalt alongnm=rt.d*along alongnm_a=rt.relstartd+alongnm #print "NM from ",rt.a.waypoint," is ",alongnm_a closealt=rt.startalt+(rt.endalt-rt.startalt)*along #print "Altitude at point: ",closealt, " before: ",rt.a.waypoint,rt.b.waypoint altmargin=0 if 'elev' in item: itemalt=mapper.parse_elev(item['elev']) altmargin=closealt-itemalt else: itemalt=None altmargin=0 if actualdist<dist and altmargin<vertdist: bear=mapper.approx_bearing_vec(actualclosest,itemv) d=dict(item) #print "Yielding." d['name']=d['kind']+': ' +d['name'] d['dist_from_a']=alongnm_a d['dist_from_b']=rt.outer_d-alongnm_a d['dir_from_a']=describe_dir(rt.tt) d['dir_from_b']=describe_dir((rt.tt+180.0)%360.0) d['dist']=actualdist d['bearing']=bear d['elevf']=itemalt if itemalt!=None: d['vertmargin']=altmargin d['closestalt']=closealt d['a']=rt.a d['b']=rt.b d['id']=rt.a.id yield d
def test_split(): l=Line(Vertex(0,0),Vertex(2,5)) for splitpoint in [Vertex(0,0), Vertex(1,3), Vertex(2,5) ]: la,lb=l.split(splitpoint) assert points(la).union(points(lb))==points(l)
def pypoly(data,kind="solid",mapmulti=None): assert data.count("\t")==0 xpos=1 ypos=data.count("\n") chs=dict() for c in data: if c=='\t': raise Exception("tab not allowed") if c=='\n': xpos=1 ypos-=1 else: if mapmulti: cs=mapmulti.get(c,[c]) else: cs=[c] for c in cs: if c!=' ': chs.setdefault(c,[]).append((xpos,ypos)) xpos+=1 lines=[] for c,poss in chs.items(): endpoints=[] for pos in poss: cnt=0 for aroundx in [-1,0,1]: for aroundy in [-1,0,1]: if aroundx==0 and aroundy==0: continue if (pos[0]+aroundx,pos[1]+aroundy) in poss: cnt+=1 if cnt==1 or cnt==0: endpoints.append(Vertex(*pos)) if len(endpoints)==1: endpoints.append(endpoints[0]) print len(endpoints) assert(len(endpoints)==2) lines.append((c,Line(endpoints[0],endpoints[1]))) lines.sort() #print "C,poss: ",lines outv=[] last=None for (n1,line1),(n2,line2) in izip(lines,lines[1:]+lines[:1]): if not ((line1.get_v2()-line2.get_v1()).taxilength()==1 or (line1.get_v2()-line2.get_v2()).taxilength()==1): line1=Line(line1.get_v2(),line1.get_v1()) if (line1.get_v2()-line2.get_v1()).taxilength()==1: outline=Line(line1.get_v1(),line2.get_v1()) elif (line1.get_v2()-line2.get_v2()).taxilength()==1: outline=Line(line1.get_v1(),line2.get_v2()) else: raise Exception("Unexpected error - bad input-data?") #print "Line: %s:%s"%(n1,outline) outv.append(outline.get_v1()) poly=Polygon(vvector(outv)) #if not poly.is_ccw(): # raise Exception("shouldn't be cw") if kind=="hole": poly.set_kind(Polygon.HOLE) return poly
def gen_cands(): for partnum,part in enumerate(parts): for idx,(a,b) in enumerate(izip(part,chain(part[1:],part[0:1]))): av=Vertex(int(a[0]),int(a[1])) bv=Vertex(int(b[0]),int(b[1])) l=Line(av,bv) clo=l.approx_closest(pointv) actualdist=(clo-pointv).approxlength() yield partnum,actualdist,(clo.get_x(),clo.get_y()),idx
def gen_cands(): for partnum, part in enumerate(parts): for idx, (a, b) in enumerate(izip(part, chain(part[1:], part[0:1]))): av = Vertex(int(a[0]), int(a[1])) bv = Vertex(int(b[0]), int(b[1])) l = Line(av, bv) clo = l.approx_closest(pointv) actualdist = (clo - pointv).approxlength() yield partnum, actualdist, (clo.get_x(), clo.get_y()), idx
def test_intersection_ex1(): la=Line(Vertex(5,5),Vertex(3,2)) lb=Line(Vertex(4,1),Vertex(4,5)) print "la: %s, lb: %s"%(la,lb) ls=list(la.intersection_points(lb)) print "ls:",ls #visualize_diff([ # (la,(255,0,0)), # (lb,(0,255,0)), # ],[]) ls=list(la.intersect2(lb)) print "Ls:",ls
def dump_cells(bo): for cell in list(bo.dbg_step5_get_cells()): sqs=[] for edge in list(cell.dbg_get_edges()): line=Line(edge.get_v1(),edge.get_v2()) sqs.append(visualize.Line( line.get_v1().get_x(), line.get_v1().get_y(), line.get_v2().get_x(), line.get_v2().get_y(), (255,0,0))) #print "Cell cover:",list(cell.get_shapes()) #print "Cell type:",cell.get_classification() draw_things(sqs)
def test_side_of4(): l=Line(Vertex(0,0),Vertex(0,10)) assert l.side_of_extrapolated_line(Vertex(5,5))==1 assert l.side_of_extrapolated_line(Vertex(-5,5))==-1 assert l.side_of_extrapolated_line(Vertex(0,5))==0 r=Line(Vertex(0,10),Vertex(0,0)) assert r.side_of_extrapolated_line(Vertex(5,5))==-1 assert r.side_of_extrapolated_line(Vertex(-5,5))==1 assert r.side_of_extrapolated_line(Vertex(0,5))==0
def get_polygons_on_line2(latlon1,latlon2,polyspaces): zoomlevel=13 px1,py1=mapper.latlon2merc(latlon1,zoomlevel) px2,py2=mapper.latlon2merc(latlon2,zoomlevel) line=Line(Vertex(int(px1),int(py1)),Vertex(int(px2),int(py2))) crosses=[] for poly,space in polyspaces: if len(poly.intersect_line(line))>0: crosses.append(space) #print "Is crossing" else: pass#print "Is NOT crossing" return crosses
def get_all_tiles_near(routes,zoomlevel,dist_nm,tilesize): resultset=set() for rt in routes: m1=mapper.latlon2merc(mapper.from_str(rt.a.pos),zoomlevel) m2=mapper.latlon2merc(mapper.from_str(rt.b.pos),zoomlevel) av=Vertex(int(m1[0]),int(m1[1])) bv=Vertex(int(m2[0]),int(m2[1])) l=Line(av,bv) startmerc=clampmerc(m1,tilesize) maxdist=mapper.approx_scale(startmerc,zoomlevel,dist_nm) maxdist+=3*tilesize/2 fill(l,startmerc,zoomlevel=zoomlevel,maxdist=maxdist,tilesize=tilesize,result=resultset) return resultset
def test_line_closest(): l=Line(Vertex(0,0),Vertex(10,0)) assert l.approx_closest(Vertex(5,0))==Vertex(5,0) assert l.approx_closest(Vertex(-5,0))==Vertex(0,0) assert l.approx_closest(Vertex(15,0))==Vertex(10,0) assert l.approx_closest(Vertex(5,5))==Vertex(5,0) assert abs(l.approx_dist(Vertex(5,5))-5)<1e-5 l=Line(Vertex(1127808,639680),Vertex(1120704,642752)) p=Vertex(1141685,587443) dist=l.approx_dist(p) print "Dist: ",dist assert abs(dist)<1141685
def get_fir_crossing(latlon1,latlon2): """ Returns tuple of: * airspace-dict * latlon of crossing """ px1,py1=mapper.latlon2merc(latlon1,13) px2,py2=mapper.latlon2merc(latlon2,13) bb0=BoundingBox(min(px1,px2),min(py1,py2),max(px1,px2),max(py1,py2)) line=Line(Vertex(int(px1),int(py1)),Vertex(int(px2),int(py2))) for poly,space in cache.get_firs_in_bb(bb0): a=poly.is_inside(Vertex(int(px1),int(py1))) b=poly.is_inside(Vertex(int(px2),int(py2))) print "Considering space %s, starting: %s, ending: %s"%( space['name'],a,b) if b and not a: cross=list(poly.first_entrance(line)) if cross: outlatlon=(cross[0].get_x(),cross[0].get_y()) return space,mapper.merc2latlon(outlatlon,13) return None
def get_polygons_on_line(latlon1,latlon2,polys): zoomlevel=13 px1,py1=mapper.latlon2merc(latlon1,zoomlevel) px2,py2=mapper.latlon2merc(latlon2,zoomlevel) line=Line(Vertex(int(px1),int(py1)),Vertex(int(px2),int(py2))) crosses=[] for space in polys: poly_coords=[] for coord in space['points']: x,y=mapper.latlon2merc(mapper.from_str(coord),zoomlevel) poly_coords.append(Vertex(int(x),int(y))) if len(poly_coords)<3: #print "Space %s has few points: %s "%(space['name'],space['points']) continue poly=Polygon(vvector(poly_coords)) #print "Checking if intersect poly:",space if len(poly.intersect_line(line))>0: crosses.append(space) #print "Is crossing" else: pass#print "Is NOT crossing" return crosses
def test_downslope(): l=Line(Vertex(0,5),Vertex(7,0)) vs=list(l.slow_all_vertices()) #visualize_diff([(l,(255,0,0))]) assert(Vertex(0,5) in vs) assert(Vertex(7,0) in vs)
def test_intersection_ex2(): la=Line(Vertex(0,2),Vertex(2,2)) lb=Line(Vertex(1,1),Vertex(1,4)) ls=list(la.intersection_points(lb)) assert set(ls)==set([Vertex(1,2)])
def get_obstacle_free_height_on_line(pos1, pos2): minimum_distance = 2.0 merc1 = mapper.latlon2merc(pos1, 13) merc2 = mapper.latlon2merc(pos2, 13) onenm = mapper.approx_scale(merc1, 13, 1.0) av = Vertex(int(merc1[0]), int(merc1[1])) bv = Vertex(int(merc2[0]), int(merc2[1])) linelen = (av - bv).approxlength() l = Line(av, bv) bb = BoundingBox(min(merc1[0], merc2[0]), min(merc1[1], merc2[1]), max(merc1[0], merc2[0]), max(merc1[1], merc2[1])).expanded(onenm * minimum_distance * 1.5) obstacles = [0] for item in chain(notam_geo_search.get_notam_objs_cached()['obstacles'], extracted_cache.get_obstacles_in_bb(bb)): if not 'pos' in item: continue if not 'elev' in item: continue try: itemmerc = mapper.latlon2merc(mapper.from_str(item['pos']), 13) except Exception: print "Bad coord:", item['pos'] continue itemv = Vertex(int(itemmerc[0]), int(itemmerc[1])) onenm = mapper.approx_scale(itemmerc, 13, 1.0) actualclosest = l.approx_closest(itemv) actualdist = (actualclosest - itemv).approxlength() / onenm if actualdist < minimum_distance: itemalt = mapper.parse_elev(item['elev']) obstacles.append(itemalt) minstep = 2 * onenm stepcount = linelen / float(minstep) if stepcount > 100: newstep = linelen / 100.0 if newstep > minstep: minstep = newstep if linelen < 1e-3: linelen = 1e-3 along = 0.0 #isfirstorlast=(idx==0 or idx==l-1) while True: alongf = float(along) / float(linelen) end = False if alongf > 1.0: alongf = 1.0 end = True merc = ((1.0 - alongf) * merc1[0] + (alongf) * merc2[0], (1.0 - alongf) * merc1[1] + (alongf) * merc2[1]) latlon = mapper.merc2latlon(merc, 13) elev = get_terrain_elev_in_box_approx(latlon, 2.0 * minstep / onenm) obstacles.append(elev) along += minstep if end: break return max(obstacles)
def get_obstacle_free_height_on_line(pos1,pos2): minimum_distance=2.0 merc1=mapper.latlon2merc(pos1,13) merc2=mapper.latlon2merc(pos2,13) onenm=mapper.approx_scale(merc1,13,1.0) av=Vertex(int(merc1[0]),int(merc1[1])) bv=Vertex(int(merc2[0]),int(merc2[1])) linelen=(av-bv).approxlength() l=Line(av,bv) bb=BoundingBox(min(merc1[0],merc2[0]), min(merc1[1],merc2[1]), max(merc1[0],merc2[0]), max(merc1[1],merc2[1])).expanded(onenm*minimum_distance*1.5) obstacles=[0] for item in chain(notam_geo_search.get_notam_objs_cached()['obstacles'], extracted_cache.get_obstacles_in_bb(bb)): if not 'pos' in item: continue if not 'elev' in item: continue try: itemmerc=mapper.latlon2merc(mapper.from_str(item['pos']),13) except Exception: print "Bad coord:",item['pos'] continue itemv=Vertex(int(itemmerc[0]),int(itemmerc[1])) onenm=mapper.approx_scale(itemmerc,13,1.0) actualclosest=l.approx_closest(itemv) actualdist=(actualclosest-itemv).approxlength()/onenm if actualdist<minimum_distance: itemalt=mapper.parse_elev(item['elev']) obstacles.append(itemalt) minstep=2*onenm stepcount=linelen/float(minstep) if stepcount>100: newstep=linelen/100.0 if newstep>minstep: minstep=newstep if linelen<1e-3: linelen=1e-3 along=0.0 #isfirstorlast=(idx==0 or idx==l-1) while True: alongf=float(along)/float(linelen) end=False if alongf>1.0: alongf=1.0 end=True merc=((1.0-alongf)*merc1[0]+(alongf)*merc2[0], (1.0-alongf)*merc1[1]+(alongf)*merc2[1]) latlon=mapper.merc2latlon(merc,13) elev=get_terrain_elev_in_box_approx(latlon,2.0*minstep/onenm) obstacles.append(elev) along+=minstep if end: break return max(obstacles)
def get_airspace(self): utcnow = datetime.utcnow() try: zoomlevel = int(request.params['zoom']) except Exception: zoomlevel = session.get('zoom', 5) lat = float(request.params.get('lat')) lon = float(request.params.get('lon')) clickmerc = mapper.latlon2merc((lat, lon), zoomlevel) user = session.get('user', None) out = [] spaces = chain(get_airspaces(lat, lon), userdata.get_airspaces(lat, lon, user)) print "Spaces:", spaces def anydate(s): if not 'date' in s: return "" d = s['date'] age = utcnow - d if age > timedelta(367): return "<span style=\"font-size:10px\">[%d]</span>" % ( d.year, ) if age > timedelta(2): return "<span style=\"font-size:10px\">[%d%02d%02d]</span>" % ( d.year, d.month, d.day) return "" spacelist = spaces spaces = u"".join(u"<li><b>%s</b>%s: %s - %s%s</li>" % (space['name'], anydate(space), space['floor'], space['ceiling'], format_freqs(space['freqs'])) for space in sorted(spacelist, key=sort_airspace_key) if space['type'] != 'sector') #sectors=u"".join(u"<li><b>%s</b>%s: %s - %s%s</li>"%( # space['name'],anydate(space),space['floor'],space['ceiling'],format_freqs(space['freqs'])) for space in sorted( # spacelist,key=sort_airspace_key) if space['type']=='sectoasdfr') try: sectors = u"".join( u"<li><b>%s</b>%s: %s - %s%s</li>" % (space['name'], anydate(space), space['floor'], space['ceiling'], format_freqs(space['freqs'])) for space in sorted(spacelist, key=sort_airspace_key) if space['type'] == 'sector') if sectors != "": sectors = "<b>Sectors:</b><ul>" + sectors + "</ul>" except: print traceback.format_exc() sectors = "" if spaces == "": spaces = "No airspace found" mapviewurl = h.url_for(controller="mapview", action="index") notamlist = chain(get_notam_areas(lat, lon), get_notampoints(lat, lon, zoomlevel)) notams = dict([(n['notam'].strip(), (n['notam_ordinal'], n['notam_line'])) for n in notamlist]) notamareas = "".join( "<li>%s <b><u><a href=\"javascript:navigate_to('%s#notam')\">Link</a></u></b></li>" % (text, h.url_for(controller="notam", action="show_ctx", backlink=mapviewurl, notam=notam, line=line)) for text, (notam, line) in notams.items()) if notamareas != "": notamareas = "<b>Area Notams:</b><ul>" + notamareas + "</ul>" aip_sup_strs = "".join([ "<li>%s <a href=\"%s\">link</a></li>" % (x['name'], x['url'].replace(" ", "%20")) for x in get_aip_sup_areas(lat, lon) ]) if aip_sup_strs: aip_sup_strs = "<b>AIP SUP:</b><ul>" + aip_sup_strs + "</ul>" obstbytype = dict() for obst in chain(get_obstacles(lat, lon, zoomlevel), userdata.get_obstacles(lat, lon, zoomlevel, user)): obstbytype.setdefault(obst['kind'], []).append(obst) print "processing", obst obstacles = [] if len(obstbytype): for kind, obsts in sorted(obstbytype.items()): obstacles.append("<b>" + kind + ":</b>") obstacles.append(u"<ul>") for obst in obsts: obstacles.append(u"<li><b>%s</b>: %s ft</li>" % (obst['name'], obst['elev'])) obstacles.append(u"</ul>") tracks = [] if session.get('showtrack', None) != None: track = session.get('showtrack') #print "%d points"%(len(track.points)) mindiff = 1e30 found = dict() hdg = 0 speed = 0 clickvec = Vertex(int(clickmerc[0]), int(clickmerc[1])) if len(track.points) > 0 and len(track.points[0]) == 2: pass #Old style track, not supported anymore else: for a, b in izip(track.points, track.points[1:]): merc = mapper.latlon2merc(a[0], zoomlevel) nextmerc = mapper.latlon2merc(b[0], zoomlevel) l = Line(Vertex(int(merc[0]), int(merc[1])), Vertex(int(nextmerc[0]), int(nextmerc[1]))) diff = l.approx_dist(clickvec) if diff < mindiff: mindiff = diff found = (a, b) if mindiff < 10: tracks.append( u"<b>GPS track:</b><ul><li>%(when)s - %(altitude)d ft hdg:%(heading)03d spd: %(speed)d kt</li></ul>" % (get_stats(*found))) airports = [] fields = list( chain(get_airfields(lat, lon, zoomlevel), userdata.get_airfields(lat, lon, zoomlevel, user))) if len(fields): airports.append("<b>Airfield:</b><ul>") for airp in fields: #print "clicked on ",airp linksstr = "" links = [] if 'flygkartan_id' in airp: links.append(('http://www.flygkartan.se/0%s' % (airp['flygkartan_id'].strip(), ), 'www.flygkartan.se')) if 'aiptexturl' in airp: links.append((airp['aiptexturl'], 'AIP Text')) if 'aipvacurl' in airp: links.append( (airp['aipvacurl'], 'AIP Visual Approach Chart')) if False and 'aipsup' in airp: #Using AIP SUP for opening hours has stopped. links.append((extracted_cache.get_se_aip_sup_hours_url(), "AIP SUP Opening Hours")) weather = "" if airp.get('icao', 'ZZZZ').upper() != 'ZZZZ': icao = airp['icao'].upper() metar = metartaf.get_metar(icao) taf = metartaf.get_taf(icao) weather = "<table>" def colorize(item, colfac=1): if item == None: col = "ffffff" agestr = "" else: age = metartaf.get_data_age(item) if age == None: col = "ffffff" agestr = "" elif age < timedelta(0, 60 * 35 * colfac): col = "c5c5c5" agestr = "%d minutes" % (int(age.seconds / 60)) elif age < timedelta(0, 60 * 60 * colfac): col = "ffff30" agestr = "%d minutes" % (int(age.seconds / 60)) else: col = "ff3030" if age < timedelta(2): if age < timedelta(0, 3600 * 1.5): agestr = "%d minutes" % int( age.seconds / 60) else: agestr = "%d hours" % int( 0.5 + (age.seconds) / 3600.0) else: agestr = "%d days" % (int(age.days)) return "style=\"background:#" + col + "\" title=\"" + agestr + " old.\"" if taf and taf.text: weather += "<tr valign=\"top\"><td>TAF:</td><td " + colorize( taf, 5) + ">" + taf.text + "</td></tr>" if metar and metar.text: weather += "<tr valign=\"top\"><td>METAR:</td><td " + colorize( metar) + ">" + metar.text + "</td></tr>" ack_cnt = meta.Session.query( NotamAck.appearnotam, NotamAck.appearline, sa.func.count('*').label('acks')).filter( NotamAck.user == session.get( 'user', None)).group_by( NotamAck.appearnotam, NotamAck.appearline).subquery() notams = meta.Session.query( NotamUpdate, ack_cnt.c.acks, Notam.downloaded ).outerjoin( (ack_cnt, sa.and_( NotamUpdate.appearnotam == ack_cnt.c.appearnotam, NotamUpdate.appearline == ack_cnt.c.appearline)) ).outerjoin( (Notam, Notam.ordinal == NotamUpdate.appearnotam)).order_by( sa.desc(Notam.downloaded)).filter( sa.and_( NotamUpdate.disappearnotam == sa.null(), NotamUpdate.category.like(icao.upper() + "/%"))).all() print "notams:", repr(notams) if notams: nots = [] for notam, ack, downloaded in notams: nots.append( "<div style=\"border:1px solid;margin:3px;border-color:#B8B8B8;padding:3px;\">%s</div>" % (cgi.escape(notam.text))) weather += "<tr valign=\"top\"><td colspan=\"2\">NOTAM:</td></tr><tr><td colspan=\"2\">%s</td></tr>" % ( "".join(nots)) weather += "</table>" meta.Session.flush() meta.Session.commit() if len(links) > 0 and 'icao' in airp: linksstr = helpers.foldable_links(airp['icao'] + "links", links) rwys = [] if 'runways' in airp: for rwy in airp['runways']: ends = [] for end in rwy['ends']: ends.append(end['thr']) surf = "" if 'surface' in rwy: surf = "(" + rwy['surface'] + ")" rwys.append("/".join(ends) + surf) if len(rwys): rwys = ["<b> Runways</b>: "] + [", ".join(rwys)] remark = "" if airp.get('remark'): remark = "<div style=\"border:1px solid;margin:3px;border-color:#B8B8B8;padding:3px;background-color:#ffffe0\"><b>Remark:</b> " + cgi.escape( airp['remark']) + "</div>" airports.append(u"<li><b>%s</b> - %s%s%s%s%s</li>" % (airp.get('icao', 'ZZZZ'), airp['name'], linksstr, remark, " ".join(rwys), weather)) airports.append("</ul>") sigpoints = [] sigps = list( chain(get_sigpoints(lat, lon, zoomlevel), userdata.get_sigpoints(lat, lon, zoomlevel, user))) if len(sigps): sigpoints.append("<b>Sig. points</b><ul>") for sigp in sigps: sigpoints.append( u"<li><b>%s</b>(%s)</li>" % (sigp['name'], sigp.get('kind', 'unknown point'))) sigpoints.append("</ul>") firs = [] for fir in list(get_firs( (lat, lon))) + list(userdata.get_firs(lat, lon, user)): if 'icao' in fir: firs.append("%s (%s)" % (fir['name'], fir['icao'])) if not firs: firs.append("Unknown") variation = '?' terrelev = get_terrain_elev((lat, lon), zoomlevel) try: varf = geomag.calc_declination((lat, lon), utcnow, (terrelev + 1000)) variation = u"%+.1f°" % (varf, ) except Exception: pass weather = "" try: when, valid, fct = gfs_weather.get_prognosis(datetime.utcnow()) qnh = fct.get_qnh(lat, lon) out = [ "<b>Weather</b><br/>Forecast: %sZ, valid: %sZ<br />" % (when.strftime("%Y-%m-%d %H:%M"), valid.strftime("%H:%M")) ] try: out.append("Surface wind: %.0f deg, %.1f knots<br />" % fct.get_surfacewind(lat, lon)) out.append("Surface RH: %.0f%%<br />" % (fct.get_surfacerh(lat, lon), )) except: print traceback.format_exc() out.append("<ul>") for fl, dir, st, temp in fct.get_winds(lat, lon): out.append("<li>FL%02d: %03d deg, %.1fkt, %.1f °C" % (int(fl), int(dir), float(st), temp)) out.append("</ul>QNH: %d<br/><br/>" % (qnh, )) weather = "".join(out) except Exception: print traceback.format_exc() return "<b>Airspace:</b><ul><li><b>FIR:</b> %s</li>%s</ul>%s%s%s%s%s%s%s<br/>%s<b>Terrain: %s ft, Var: %s</b>" % ( ", ".join(firs), spaces, sectors, aip_sup_strs, "".join(obstacles), "".join(airports), "".join(tracks), "".join(sigpoints), notamareas, weather, terrelev, variation)
def vistest_merge_shapes(): for x in xrange(10): x=5 poly_a=Polygon(vvector([ Vertex(0+x,0),Vertex(2+x,0), Vertex(2+x,2),Vertex(0+x,2)])) poly_b=Polygon(vvector([ Vertex(1,1),Vertex(3,1), Vertex(3,4),Vertex(1,4)])) shape_a=Shape("shape_a",poly_a) shape_b=Shape("shape_b",poly_b) # OOOO # OOOO # OOOOOO # OOOO # OOOO bo=BooleanOp() #print "Shape_a,shape_b: ",shape_a,shape_b bo.step1_add_lines(shape_a,shape_b) bo.step2_intersect_lines() splitset=set([NondirLine(x.get_v1(),x.get_v2()) for x in bo.dbg_step2_get_split_lines()]) #print "Split result: %s"%("\n".join(str(l) for l in splitset),) assert not NondirLine(Vertex(0,2),Vertex(2,2)) in splitset bo.step3_create_edges() edges=list(bo.dbg_step3_and_4_get_edges()) nondiredges=list(NondirLine(x.get_v1(),x.get_v2()) for x in bo.dbg_step3_and_4_get_edges()) sqs=[] cnt=0 #print "Edges: %s"%(edges,) for edge in edges: line=Line(edge.get_v1(),edge.get_v2()) r=(25*cnt)%128+128 g=(128*cnt)%128+128 b=(64*cnt)%128+128 sqs.append(visualize.Line( line.get_v1().get_x(), line.get_v1().get_y(), line.get_v2().get_x(), line.get_v2().get_y(), (r,g,b))) sqs.append(visualize.Square( line.get_v1().get_x()-0.1, line.get_v1().get_y()-0.1, line.get_v1().get_x()+0.1, line.get_v1().get_y()+0.1, (r,g,b))) cnt+=1 draw_things(sqs) assert not (NondirLine(Vertex(0,2),Vertex(2,2)) in nondiredges) bo.step4_eliminate_deadends() bo.step5_create_cells() bo.step6_determine_cell_cover() bas=BooleanOrStrategy() bo.step7_classify_cells(bas) for cell in list(bo.dbg_step5_get_cells()): sqs=[] for edge in list(cell.dbg_get_edges()): line=Line(edge.get_v1(),edge.get_v2()) sqs.append(visualize.Line( line.get_v1().get_x(), line.get_v1().get_y(), line.get_v2().get_x(), line.get_v2().get_y(), (255,0,0))) #print "Cell cover:",list(cell.get_shapes()) #print "Cell type:",cell.get_classification() draw_things(sqs) bo.step8_merge_cells() bo.step9_calc_result() shape=bo.step9_get_result() polys=list(shape.get_polys()) plines=set() for poly in polys: #print "Poly: %s %s"%(poly.get_kind_str(),list(poly.get_lines())) plines=plines.union(frozenset(poly.get_lines())) sqs=[] edges=set(bo.dbg_step3_and_4_get_edges()) for line in plines: sqs.append(visualize.Line( line.get_v1().get_x(), line.get_v1().get_y(), line.get_v2().get_x(), line.get_v2().get_y(), (0,200,0))) draw_things(sqs)
def test_intersection_ex3(): la=Line(Vertex(0,2),Vertex(2,2)) lb=Line(Vertex(1,4),Vertex(1,1)) ls=list(la.intersection_points(lb)) print "Actual: %s"%(ls,) assert set(ls)==set([Vertex(1,2)])
def test_intersection(): def r(): return random.randint(-50,50) random.seed(0) for x in xrange(1000): la=Line(Vertex(r(),r()),Vertex(r(),r())) lb=Line(Vertex(r(),r()),Vertex(r(),r())) if not points(la).intersection(points(lb)): continue try: ls=list(la.intersect(lb)) have_split=False assert len(ls)>0 middle=ls[0] a,b,c,d=ls[1:] have_split=True sqs=[] sm=points(middle) sa=points(a) sb=points(b) sc=points(c) sd=points(d) sla=points(la) slb=points(lb) aplusb=points(la).union(points(lb)) assert sm.intersection(aplusb)==sm assert sa.intersection(sla)==sa assert sb.intersection(slb)==sb assert sc.intersection(sla)==sc assert sd.intersection(slb)==sd splitted_union=sa.union(sc).union(sm).union(sb).union(sd) superf=splitted_union.difference(sla.union(slb)) assert len(superf)==0 #Note that not all points in la and lb are in m+a+b+c+d. except Exception,cause: print "Oops:",cause if have_split: visualize_diff([ (la,(255,0,0)), (lb,(0,255,0)), ],[]) visualize_diff([ (la,(255,0,0)), (lb,(0,255,0)), (middle,(0,0,255)) ],sqs) visualize_diff([ (a,(255,0,0)), (b,(128,0,0)), (c,(0,0,255)), (d,(0,0,128)), (middle,(0,255,0)) ],[]) else: print "Visualize two lines" #raise visualize_diff([ (la,(255,0,0)), (lb,(0,255,0)) ]) raise
def get_airspace(self): utcnow=datetime.utcnow() try: zoomlevel=int(request.params['zoom']) except Exception: zoomlevel=session.get('zoom',5) lat=float(request.params.get('lat')) lon=float(request.params.get('lon')) clickmerc=mapper.latlon2merc((lat,lon),zoomlevel) user=session.get('user',None) out=[] spaces=chain(get_airspaces(lat,lon),userdata.get_airspaces(lat,lon,user)) print "Spaces:",spaces def anydate(s): if not 'date' in s: return "" d=s['date'] age=utcnow-d if age>timedelta(367): return "<span style=\"font-size:10px\">[%d]</span>"%(d.year,) if age>timedelta(2): return "<span style=\"font-size:10px\">[%d%02d%02d]</span>"%( d.year,d.month,d.day) return "" spacelist=spaces spaces=u"".join(u"<li><b>%s</b>%s: %s - %s%s</li>"%( space['name'],anydate(space),space['floor'],space['ceiling'],format_freqs(space['freqs'])) for space in sorted( spacelist,key=sort_airspace_key) if space['type']!='sector') #sectors=u"".join(u"<li><b>%s</b>%s: %s - %s%s</li>"%( # space['name'],anydate(space),space['floor'],space['ceiling'],format_freqs(space['freqs'])) for space in sorted( # spacelist,key=sort_airspace_key) if space['type']=='sectoasdfr') try: sectors=u"".join(u"<li><b>%s</b>%s: %s - %s%s</li>"%( space['name'],anydate(space),space['floor'],space['ceiling'],format_freqs(space['freqs'])) for space in sorted( spacelist,key=sort_airspace_key) if space['type']=='sector') if sectors!="": sectors="<b>Sectors:</b><ul>"+sectors+"</ul>" except: print traceback.format_exc() sectors="" if spaces=="": spaces="No airspace found" mapviewurl=h.url_for(controller="mapview",action="index") notamlist=chain(get_notam_areas(lat,lon),get_notampoints(lat,lon,zoomlevel)) notams=dict([(n['notam'].strip(),(n['notam_ordinal'],n['notam_line']) ) for n in notamlist]) notamareas="".join("<li>%s <b><u><a href=\"javascript:navigate_to('%s#notam')\">Link</a></u></b></li>"%( text,h.url_for(controller="notam",action="show_ctx",backlink=mapviewurl,notam=notam,line=line)) for text,(notam,line) in notams.items()) if notamareas!="": notamareas="<b>Area Notams:</b><ul>"+notamareas+"</ul>" aip_sup_strs="".join(["<li>%s <a href=\"%s\">link</a></li>"%(x['name'],x['url'].replace(" ","%20")) for x in get_aip_sup_areas(lat,lon)]) if aip_sup_strs: aip_sup_strs="<b>AIP SUP:</b><ul>"+aip_sup_strs+"</ul>" obstbytype=dict() for obst in chain(get_obstacles(lat,lon,zoomlevel),userdata.get_obstacles(lat,lon,zoomlevel,user)): obstbytype.setdefault(obst['kind'],[]).append(obst) print "processing",obst obstacles=[] if len(obstbytype): for kind,obsts in sorted(obstbytype.items()): obstacles.append("<b>"+kind+":</b>") obstacles.append(u"<ul>") for obst in obsts: obstacles.append(u"<li><b>%s</b>: %s ft</li>"%(obst['name'],obst['elev'])) obstacles.append(u"</ul>") tracks=[] if session.get('showtrack',None)!=None: track=session.get('showtrack') #print "%d points"%(len(track.points)) mindiff=1e30 found=dict() hdg=0 speed=0 clickvec=Vertex(int(clickmerc[0]),int(clickmerc[1])) if len(track.points)>0 and len(track.points[0])==2: pass #Old style track, not supported anymore else: for a,b in izip(track.points,track.points[1:]): merc=mapper.latlon2merc(a[0],zoomlevel) nextmerc=mapper.latlon2merc(b[0],zoomlevel) l=Line(Vertex(int(merc[0]),int(merc[1])),Vertex(int(nextmerc[0]),int(nextmerc[1]))) diff=l.approx_dist(clickvec) if diff<mindiff: mindiff=diff found=(a,b) if mindiff<10: tracks.append(u"<b>GPS track:</b><ul><li>%(when)s - %(altitude)d ft hdg:%(heading)03d spd: %(speed)d kt</li></ul>"%(get_stats(*found))) airports=[] fields=list(chain(get_airfields(lat,lon,zoomlevel),userdata.get_airfields(lat,lon,zoomlevel,user))) if len(fields): airports.append("<b>Airfield:</b><ul>") for airp in fields: #print "clicked on ",airp linksstr="" links=[] if 'flygkartan_id' in airp: links.append(('http://www.flygkartan.se/0%s'%(airp['flygkartan_id'].strip(),), 'www.flygkartan.se')) if 'aiptexturl' in airp: links.append((airp['aiptexturl'], 'AIP Text')) if 'aipvacurl' in airp: links.append((airp['aipvacurl'], 'AIP Visual Approach Chart')) if False and 'aipsup' in airp: #Using AIP SUP for opening hours has stopped. links.append(( extracted_cache.get_se_aip_sup_hours_url(), "AIP SUP Opening Hours")) weather="" if airp.get('icao','ZZZZ').upper()!='ZZZZ': icao=airp['icao'].upper() metar=metartaf.get_metar(icao) taf=metartaf.get_taf(icao) weather="<table>" def colorize(item,colfac=1): if item==None: col="ffffff" agestr="" else: age=metartaf.get_data_age(item) if age==None: col="ffffff" agestr="" elif age<timedelta(0,60*35*colfac): col="c5c5c5" agestr="%d minutes"%(int(age.seconds/60)) elif age<timedelta(0,60*60*colfac): col="ffff30" agestr="%d minutes"%(int(age.seconds/60)) else: col="ff3030" if age<timedelta(2): if age<timedelta(0,3600*1.5): agestr="%d minutes"%int(age.seconds/60) else: agestr="%d hours"%int(0.5+(age.seconds)/3600.0) else: agestr="%d days"%(int(age.days)) return "style=\"background:#"+col+"\" title=\""+agestr+" old.\"" if taf and taf.text: weather+="<tr valign=\"top\"><td>TAF:</td><td "+colorize(taf,5)+">"+taf.text+"</td></tr>" if metar and metar.text: weather+="<tr valign=\"top\"><td>METAR:</td><td "+colorize(metar)+">"+metar.text+"</td></tr>" ack_cnt = meta.Session.query(NotamAck.appearnotam,NotamAck.appearline,sa.func.count('*').label('acks')).filter(NotamAck.user==session.get('user',None)).group_by(NotamAck.appearnotam,NotamAck.appearline).subquery() notams=meta.Session.query(NotamUpdate,ack_cnt.c.acks,Notam.downloaded).outerjoin( (ack_cnt,sa.and_( NotamUpdate.appearnotam==ack_cnt.c.appearnotam, NotamUpdate.appearline==ack_cnt.c.appearline))).outerjoin( (Notam,Notam.ordinal==NotamUpdate.appearnotam) ).order_by(sa.desc(Notam.downloaded)).filter( sa.and_(NotamUpdate.disappearnotam==sa.null(), NotamUpdate.category.like(icao.upper()+"/%") )).all() print "notams:",repr(notams) if notams: nots=[] for notam,ack,downloaded in notams: nots.append("<div style=\"border:1px solid;margin:3px;border-color:#B8B8B8;padding:3px;\">%s</div>"%(cgi.escape(notam.text))) weather+="<tr valign=\"top\"><td colspan=\"2\">NOTAM:</td></tr><tr><td colspan=\"2\">%s</td></tr>"%("".join(nots)) weather+="</table>" meta.Session.flush() meta.Session.commit() if len(links)>0 and 'icao' in airp: linksstr=helpers.foldable_links(airp['icao']+"links",links) rwys=[] if 'runways' in airp: for rwy in airp['runways']: ends=[] for end in rwy['ends']: ends.append(end['thr']) surf="" if 'surface' in rwy: surf="("+rwy['surface']+")" rwys.append("/".join(ends)+surf) if len(rwys): rwys=["<b> Runways</b>: "]+[", ".join(rwys)] remark="" if airp.get('remark'): remark="<div style=\"border:1px solid;margin:3px;border-color:#B8B8B8;padding:3px;background-color:#ffffe0\"><b>Remark:</b> "+cgi.escape(airp['remark'])+"</div>" airports.append(u"<li><b>%s</b> - %s%s%s%s%s</li>"%(airp.get('icao','ZZZZ'),airp['name'],linksstr,remark," ".join(rwys),weather)) airports.append("</ul>") sigpoints=[] sigps=list(chain(get_sigpoints(lat,lon,zoomlevel),userdata.get_sigpoints(lat,lon,zoomlevel,user))) if len(sigps): sigpoints.append("<b>Sig. points</b><ul>") for sigp in sigps: sigpoints.append(u"<li><b>%s</b>(%s)</li>"%(sigp['name'],sigp.get('kind','unknown point'))) sigpoints.append("</ul>") firs=[] for fir in list(get_firs((lat,lon)))+list(userdata.get_firs(lat,lon,user)): if 'icao' in fir: firs.append("%s (%s)"%(fir['name'],fir['icao'])) if not firs: firs.append("Unknown") variation='?' terrelev=get_terrain_elev((lat,lon),zoomlevel) try: varf=geomag.calc_declination((lat,lon),utcnow,(terrelev+1000)) variation=u"%+.1f°"%(varf,) except Exception: pass weather="" try: when,valid,fct=gfs_weather.get_prognosis(datetime.utcnow()) qnh=fct.get_qnh(lat,lon) out=["<b>Weather</b><br/>Forecast: %sZ, valid: %sZ<br />"%(when.strftime("%Y-%m-%d %H:%M"),valid.strftime("%H:%M"))] try: out.append("Surface wind: %.0f deg, %.1f knots<br />"%fct.get_surfacewind(lat,lon)) out.append("Surface RH: %.0f%%<br />"%(fct.get_surfacerh(lat,lon),)) except: print traceback.format_exc() out.append("<ul>") for fl,dir,st,temp in fct.get_winds(lat,lon): out.append("<li>FL%02d: %03d deg, %.1fkt, %.1f °C"%(int(fl),int(dir),float(st),temp)) out.append("</ul>QNH: %d<br/><br/>"%(qnh,)) weather="".join(out) except Exception: print traceback.format_exc() return "<b>Airspace:</b><ul><li><b>FIR:</b> %s</li>%s</ul>%s%s%s%s%s%s%s<br/>%s<b>Terrain: %s ft, Var: %s</b>"%(", ".join(firs),spaces,sectors,aip_sup_strs,"".join(obstacles),"".join(airports),"".join(tracks),"".join(sigpoints),notamareas,weather,terrelev,variation)
def test_side_of2(): l=Line(Vertex(0,0),Vertex(1,10)) assert l.side_of_extrapolated_line(Vertex(0,10))==-1 assert l.side_of_extrapolated_line(Vertex(1,0))==1 assert l.side_of_extrapolated_line(Vertex(1,8))==0 assert l.side_of_extrapolated_line(Vertex(0,2))==0
def test_downslope2(): l=Line(Vertex(7,0),Vertex(0,5)) vs=list(l.slow_all_vertices()) #visualize_diff(vs,vs,l,l) assert(Vertex(7,0) in vs) assert(Vertex(0,5) in vs)
def test_side_of3(): l=Line(Vertex(0,0),Vertex(1,1000000)) assert l.side_of_extrapolated_line(Vertex(1000000,0))==1 assert l.side_of_extrapolated_line(Vertex(-1000000,0))==-1 assert l.side_of_extrapolated_line(Vertex(0,100000))==0 assert l.side_of_extrapolated_line(Vertex(1000000,2000000))==1