def get_airspaces(routes): for routename,coords,altspec in routes: sig=getsig(coords,altspec) if (routename,sig) in predef: #pobj=None #for sroutename,ssig in predef: # if routename==sroutename: pobj=(routename,sig) width_nm,floor,ceiling,coordstr=predef[pobj] rawcoords=re.findall(ur"(\d{6}N)\s*(\d{7}E)",coordstr) coords=[mapper.latlon2merc(mapper.from_str(mapper.parse_coords(lats,lons)),13) for lats,lons in rawcoords] width=float(mapper.approx_scale(coords[0],13,1.25*width_nm)) try: outline=get_outline(coords,width) except Exception: uprint(u"Trouble parsing %s"%(routename,)) raise yield dict(name=routename, floor=floor, ceiling=ceiling, freqs=[], type="RNAV", points=[mapper.to_str(mapper.merc2latlon(x,13)) for x in outline]) else: uprint("Need to have predefine for route %s, with md5: %s"%(routename,sig)) uprint("Altitude, and points") raise Exception('Missing predef for route. Use: ("%s","%s") : ( 10,"FL 65","FL 95","""\n\n """),'%(routename,sig))
def clean_up_polygon(poss): print "Clean poly:",poss def tov(merc): return Vertex(int(merc[0]),int(merc[1])) def fromv(v): return (v.get_x(),v.get_y()) vertices=[] last=None for pos in poss: #print pos if pos==last: continue last=pos vertices.append(tov(mapper.latlon2merc(mapper.from_str(pos),13))) poly=Polygon(vvector(vertices)) #print "calling tidy-up" shape=tidy_up_polygon(poly) ret=[] for poly in shape.get_polys(): #print "Got poly" vs=poly.get_vertices() out=[] for v in vs: out.append(mapper.to_str(mapper.merc2latlon(fromv(v),13))) ret.append(out) return ret
def clean_up_polygon(poss): print "Clean poly:", poss def tov(merc): return Vertex(int(merc[0]), int(merc[1])) def fromv(v): return (v.get_x(), v.get_y()) vertices = [] last = None for pos in poss: #print pos if pos == last: continue last = pos vertices.append(tov(mapper.latlon2merc(mapper.from_str(pos), 13))) poly = Polygon(vvector(vertices)) #print "calling tidy-up" shape = tidy_up_polygon(poly) ret = [] for poly in shape.get_polys(): #print "Got poly" vs = poly.get_vertices() out = [] for v in vs: out.append(mapper.to_str(mapper.merc2latlon(fromv(v), 13))) ret.append(out) return ret
def get_latlon_outline(latlonseq,width_nm): print "Width nm:",width_nm mercseq=[mapper.latlon2merc(mapper.from_str(ll),13) for ll in latlonseq] width=float(mapper.approx_scale(mercseq[0],13,width_nm)) mercout=get_merc_outline(mercseq,width) points=[mapper.to_str(mapper.merc2latlon(x,13)) for x in mercout] return points
def get_low_sun_near_route(rts): l=len(rts) out=[] dt=None for idx,rt in enumerate(rts): if rt.dt==None: continue #print "ord:",rt.a.ordering tottime=rt.dt-rt.startdt merca=rt.subposa mercb=rt.subposb curtime=timedelta(0) real_heading=rt.tt+rt.wca while True: if curtime>=tottime: break f=divide(curtime,tottime) fi=1.0-f merc=(fi*merca[0]+f*mercb[0],fi*merca[1]+f*mercb[1]) latlon=mapper.merc2latlon(merc,13) when=rt.startdt+curtime ele,azi=sun_position_in_sky(when,latlon[0],latlon[1]) #print "Sun position: ele=%s, azi=%s, heading=%s"%(ele,azi,real_heading) if (ele>-0.5 and ele<25): off=(azi-real_heading) if abs(off)<25: dirclock=int(round(off/15.0)) if dirclock<=0: dirclock+=12 out.append(dict( name="Low Sun Warning (Direction: %d o'clock, %.0f deg above horizon. Blinding?)"%( dirclock,max(0,ele)), pos=mapper.to_str(latlon), elev="", elevf=0, dist=0, bearing=azi, closestalt=None, kind='lowsun', dist_from_a=mapper.bearing_and_distance(mapper.from_str(rt.a.pos),latlon)[1], dist_from_b=mapper.bearing_and_distance(mapper.from_str(rt.b.pos),latlon)[1], dir_from_a=describe_dir(rt.tt), dir_from_b=describe_dir((rt.tt+180.0)%360.0), a=rt.a, b=rt.b, id=rt.a.id)) print "Generated sun warning:",out[-1] break curtime+=timedelta(minutes=2) return out
def get_airspaces(routes): for routename, coords, altspec in routes: sig = getsig(coords, altspec) if (routename, sig) in predef: #pobj=None #for sroutename,ssig in predef: # if routename==sroutename: pobj = (routename, sig) width_nm, floor, ceiling, coordstr = predef[pobj] rawcoords = re.findall(ur"(\d{6}N)\s*(\d{7}E)", coordstr) coords = [ mapper.latlon2merc( mapper.from_str(mapper.parse_coords(lats, lons)), 13) for lats, lons in rawcoords ] width = float( mapper.approx_scale(coords[0], 13, 1.25 * width_nm)) try: outline = get_outline(coords, width) except Exception: uprint(u"Trouble parsing %s" % (routename, )) raise yield dict(name=routename, floor=floor, ceiling=ceiling, freqs=[], type="RNAV", points=[ mapper.to_str(mapper.merc2latlon(x, 13)) for x in outline ]) else: uprint( "Need to have predefine for route %s, with md5: %s" % (routename, sig)) uprint("Altitude, and points") raise Exception( 'Missing predef for route. Use: ("%s","%s") : ( 10,"FL 65","FL 95","""\n\n """),' % (routename, sig))
def parse_airfields(): out = [] for item in csv.reader(open("fplan/extract/denmark.airfields.csv")): print item icao, empty, ICAO, name, d1, d2, pos, elev, owner, phone, d4, d5, webside = item if not pos[-1] in ['E', 'W']: pos = pos + "E" print "ICAO:", icao assert icao.upper() == ICAO name = coding(name) lat, lon = mapper.from_str(mapper.parsecoord(pos)) nasaelev = get_terrain_elev((lat, lon)) if elev == '': elev = nasaelev if nasaelev != 9999: assert abs(float(elev) - nasaelev) < 100 ad = dict(icao=ICAO, name=name, pos=mapper.to_str((lat, lon)), date="2010-01-01T00:00:00Z", elev=int(elev)) out.append(ad) return out
def parse_airfields(): out=[] for item in csv.reader(open("fplan/extract/denmark.airfields.csv")): print item icao,empty,ICAO,name,d1,d2,pos,elev,owner,phone,d4,d5,webside=item if not pos[-1] in ['E','W']: pos=pos+"E" print "ICAO:",icao assert icao.upper()==ICAO name=coding(name) lat,lon=mapper.from_str(mapper.parsecoord(pos)) nasaelev=get_terrain_elev((lat,lon)) if elev=='': elev=nasaelev if nasaelev!=9999: assert abs(float(elev)-nasaelev)<100 ad=dict( icao=ICAO, name=name, pos=mapper.to_str((lat,lon)), date="2010-01-01T00:00:00Z", elev=int(elev)) out.append(ad) return out
def getmap(self): #print "DAta:",request.params data=json.loads(request.params['data']) ad=data['ad'] perf=data['perf'] what=data['what'] #print "Perf:",perf imgsize=300 im=cairo.ImageSurface(cairo.FORMAT_RGB24,imgsize,imgsize) ctx=cairo.Context(im) def getpos(xd): return xd.get('usable_pos',xd['pos']) if not 'physical' in ad: rwy=ad['runways'][0] hdg=float(rwy["rwyhdg"]) hdgrad=(hdg/(180.0/math.pi)) runway_length=float(rwy["runway_length"]) threshold=float(rwy["threshold"]) posA=mapper.latlon2merc((59,18),20) meter=mapper.approx_scale(posA, 20, 1/1852.0) rwylen=meter*runway_length delta=(math.sin(hdgrad)*rwylen,-math.cos(hdgrad)*rwylen) print "Delta:",delta posB=(posA[0]+delta[0],posA[1]+delta[1]) latlonA=mapper.to_str(mapper.merc2latlon(posA,20)) latlonB=mapper.to_str(mapper.merc2latlon(posB,20)) ad['physical']=[ [dict(name=rwy['name'], usable_pos=latlonA, pos=latlonA, threshold=threshold), dict(name="^"+rwy['name'], usable_pos=latlonB, pos=latlonB, threshold=0)]] if 'physical' in ad: def getdist_meter(p1,p2): brg,dist=mapper.bearing_and_distance(mapper.merc2latlon(p1,20),mapper.merc2latlon(p2,20)) return dist*1852.0 def draw_cmds(): for d in ad['physical']: yield (mapper.latlon2merc(mapper.from_str(getpos(d[0])),20), mapper.latlon2merc(mapper.from_str(getpos(d[1])),20), d[0]['name'],d[1]['name'],d[0]['threshold'],d[1]['threshold']) def justmercs(): for p1,p2,n1,n2,t1,t2 in draw_cmds(): yield p1 yield p2 bb=bsptree.bb_from_mercs(justmercs()) center=(0.5*(bb.x1+bb.x2),0.5*(bb.y1+bb.y2)) #print "Center:",center mercradius=max(bb.x2-bb.x1,bb.y2-bb.y1) scaling=(imgsize/1.3)/mercradius def topixel(merc): off=(merc[0]-center[0],merc[1]-center[1]) return (off[0]*scaling+imgsize/2,off[1]*scaling+imgsize/2) def draw_marker(ctx,p1,p2,thresholdratio,msg,col=(1,0,0)): ninety=[p2[1]-p1[1],p2[0]-p1[0]] ninety=[ninety[0],-ninety[1]] #if ninety[0]<0: # ninety[0],ninety[1]=-ninety[0],-ninety[1] #print "ninety:",ninety p1=topixel(p1) p2=topixel(p2) d=[p1[0]+thresholdratio*(p2[0]-p1[0]), p1[1]+thresholdratio*(p2[1]-p1[1])] """ dB=[d[0]+ninety[0],d[1]+ninety[1]] if dB[0]>0.75*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] elif dB[0]<0.25*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] elif dB[1]<0.25*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] elif dB[1]>0.75*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] dB=[d[0]+ninety[0],d[1]+ninety[1]] """ ctx.new_path() ctx.set_source(cairo.SolidPattern(*(col+(1,)))) ctx.arc(d[0],d[1],6,0,2*math.pi) ctx.fill() ctx.new_path() ctx.move_to(*d) ctx.save() ang=math.atan2(ninety[1],ninety[0])*180.0/3.1415 if ang>90 or ang <-90: ang=(ang+180)%360 angrad=ang*(math.pi/180) ctx.translate(*d) ctx.rotate(angrad) ctx.set_font_size(17); ext=ctx.text_extents(msg)[:4] w=ext[2] cand1=ctx.user_to_device(10+w/2,0) cand2=ctx.user_to_device(-10-w/2,0) def edgedist(x): return min(x[0],x[0]-imgsize,x[1],x[1]-imgsize) if edgedist(cand1)>edgedist(cand2): dC=[10,-ext[1]/2] else: dC=[-10-w,-ext[1]/2] #dC=[dB[0],dB[1]] ctx.move_to(*dC) ctx.show_text(msg) ctx.restore() for p1,p2,n1,n2,t1,t2 in draw_cmds(): print "n1:",n1,"n2:",n2 print "p1:",mapper.merc2latlon(p1,20) print "p2:",mapper.merc2latlon(p2,20) pix1=topixel(p1) pix2=topixel(p2) ctx.set_source(cairo.SolidPattern(0.5,0.5,0.5,1)) ctx.new_path() ctx.set_line_width(10) ctx.move_to(*pix1) ctx.line_to(*pix2) ctx.stroke() for p1,p2,n1,n2,t1,t2 in draw_cmds(): print "Matching",n1,n2,"to",perf['name'] if n2==perf['name']: p1,n1,t1,p2,n2,t2=p2,n2,t2,p1,n1,t1 if n1==perf['name']: runwaylen=getdist_meter(p1,p2) startratio=perf["start"]/runwaylen start300ratio=perf["start300"]/runwaylen startrollratio=perf["start_roll"]/runwaylen safe_factor=1.43 if 'safe_factor' in perf: safe_factor=float(perf['safe_factor']) thresholdratio=t1/runwaylen landingratio=perf["land"]/runwaylen landingrollratio=landingratio-perf["landing_roll"]/runwaylen landingratio*=safe_factor landingrollratio*=safe_factor landingratio+=thresholdratio landingrollratio+=thresholdratio if what=='start': draw_marker(ctx,p1,p2,0,"Start",col=(1,0,0)) draw_marker(ctx,p1,p2,startrollratio,"Lättning",col=(1,0.5,0)) draw_marker(ctx,p1,p2,startratio,"tröskelhöjd",col=(1,1,0)) draw_marker(ctx,p1,p2,start300ratio,"300 fot höjd",col=(0,1,0)) if what=='landing': draw_marker(ctx,p1,p2,thresholdratio,"tröskelhöjd ",col=(1,0,0)) draw_marker(ctx,p1,p2,landingrollratio,"Senaste sättning",col=(1,0.5,0)) draw_marker(ctx,p1,p2,landingratio,"Senaste stopp",(0,1,0)) buf=StringIO.StringIO() im.write_to_png(buf) png=buf.getvalue() response.headers['Content-Type'] = 'image/png' return png
def osm_airfields_parse(): nameicao = parse_info() f = open("adnames.txt", "w") for name, icao in sorted(nameicao, key=lambda x: x[0]): f.write("%s: %s\n" % (icao.encode('utf8'), name.encode('utf8'))) f.close() ads = [] hits = 0 misses = [] name2icao = [] for name, icao in nameicao: name2icao.append((normalize(name), name, icao)) dupecheck = set() for lon, lat, name in csv.reader(open("fplan/extract/aerodromes.txt")): name = unicode(name, "utf8") if not name.strip(): continue icao = None n1 = normalize(name) if frozenset(n1) in dupecheck: continue dupecheck.add(frozenset(n1)) lastquality = 0 lastname = None for n2, iname, iicao in name2icao: #print repr(n1),"==",repr(n2) minlen = min(len(n1), len(n2)) if minlen > 2: minlen = minlen - 1 quality = len(n1.intersection(n2)) if quality >= minlen and quality > lastquality: if icao != None and icao != iicao: print "For name:", name, "Previous match:,", icao, "New match:", iicao, "Name:", iname, "last name:", lastname, "quality:", quality, "last:", lastquality, "minlen:", minlen #assert icao==None icao = iicao lastquality = quality lastname = iname #print "Ap with name:",name if icao: hits += 1 icao = icao else: icao = 'ZZZZ' misses.append(name) #print "Missed:",name d = dict(icao=icao, name=name, pos=mapper.to_str((float(lat), float(lon))), elev=int(gte.get_terrain_elev((float(lat), float(lon))))) if hits % 10 == 0: print "Hits: %d, Misses: %d, Perc: %.1f" % ( hits, len(misses), 100.0 * (float(hits) / (float(hits) + len(misses)))) ads.append(d) print "Misses:" f = open("missedads.txt", "w") for miss in sorted(misses): f.write((miss + " - " + repr(normalize(miss)) + u"\n").encode('utf8')) f.close() f = open("foundads.txt", "w") for norm, name, icao in name2icao: f.write((name + " - " + repr(norm) + u"\n").encode('utf8')) f.close() print "Hits: ", hits print "Misses: ", len(misses) return ads
def get_terrain_near_route(rts,vertdist,interval=10): l=len(rts) out=[] for idx,rt in enumerate(rts): #print "ord:",rt.a.ordering if rt.dt==None: continue merca=rt.subposa mercb=rt.subposb minstep=2 stepcount=rt.d/float(minstep) if stepcount>100: newstep=rt.d/100.0 if newstep>minstep: minstep=newstep if interval<minstep: interval=minstep df=rt.d if df<1e-3: df=1e-3 along_nm=0.0 #isfirstorlast=(idx==0 or idx==l-1) while True: alongf=float(along_nm)/float(df) end=False if alongf>1.0: alongf=1.0 end=True merc=((1.0-alongf)*merca[0]+(alongf)*mercb[0], (1.0-alongf)*merca[1]+(alongf)*mercb[1]) alt=(1.0-alongf)*rt.startalt+(alongf)*rt.endalt latlon=mapper.merc2latlon(merc,13) elev=get_terrain_elev_in_box_approx(latlon,2*minstep) dist_from_a=mapper.bearing_and_distance(mapper.from_str(rt.a.pos),latlon)[1] dist_from_b=rt.d-dist_from_a if dist_from_b<0: dist_from_b=0 #if isfirstorlast and (along_nm<2.5 or along_nm>d-2.5): # along_nm+=minstep # continue if (alt-elev<vertdist and not (rt.a.stay and dist_from_a<5) and not ((rt.b.stay or idx==l-1) and dist_from_b<5) ): #print "idx",idx,"ord:",rt.a.ordering #print "Terrain warning: ",dict(a=rt.a.waypoint,b=rt.b.waypoint,kind=rt.legpart,startalt=rt.startalt,endalt=rt.endalt,along=alongf,end=end) out.append(dict( name="Terrain warning", pos=mapper.to_str(latlon), elev="%.0f"%(elev,), elevf=elev, dist=0, bearing=0, closestalt=alt, kind='terrain', dist_from_a=dist_from_a, dir_from_a=describe_dir(rt.tt), dist_from_b=dist_from_b, dir_from_b=describe_dir((rt.tt+180.0)%360.0), a=rt.a, b=rt.b, id=rt.a.id)) along_nm+=interval else: along_nm+=minstep if end: break return out
if type(name) == str: name = unicode(name, "utf8") mercf = mapper.latlon2merc((lat, lon), 13) for a in origads: merca = mapper.latlon2merc(mapper.from_str(a["pos"]), 13) dist = math.sqrt((merca[0] - mercf[0]) ** 2 + (merca[1] - mercf[1]) ** 2) if dist < 120: found = a break if found: found["flygkartan_id"] = flygkartan_id else: d = dict( icao="ZZZZ", name=name, pos=mapper.to_str((lat, lon)), elev=int(get_terrain_elev((lat, lon))), flygkartan_id=flygkartan_id, ) if filtericao(d): ads.append(d) minor_ad_charts = extra_airfields.minor_ad_charts for ad in ads: if ad["name"].count(u"Långtora"): ad["pos"] = mapper.to_str(mapper.from_aviation_format("5944.83N01708.20E")) if ad["name"] in minor_ad_charts: charturl = minor_ad_charts[ad["name"]] arp = ad["pos"]
borders=[[mapper.latlon2merc(mapper.from_str(x),13) for x in points] for points in context] else: borders=get_borders(context) print "start,end",start,end part1,idx1,pos1=find_closest(borders,start) part2,idx2,pos2=find_closest(borders,end) print "Found",pos1,pos2 if part1!=part2: raise Exception("Start and endpoint are not on same island!") part=part1 print "from,to",idx1,idx2 if idx1==idx2: return [start,end] res1,dist1=circle(borders[part],pos1,idx1,idx2,pos2,-1) res2,dist2=circle(borders[part],pos1,idx1,idx2,pos2,1) if dist1<dist2: if longwayround: ret=res2 else: ret=res1 else: if longwayround: ret=res1 else: ret=res2 return [start]+ret+[end] if __name__=='__main__': fa=follow_along("sweden",(59.0,11.4),(61.0,12.5)) print " - ".join(mapper.to_str(pos) for pos in fa)
def getmap(self): #print "DAta:",request.params data = json.loads(request.params['data']) ad = data['ad'] perf = data['perf'] what = data['what'] #print "Perf:",perf imgsize = 300 im = cairo.ImageSurface(cairo.FORMAT_RGB24, imgsize, imgsize) ctx = cairo.Context(im) def getpos(xd): return xd.get('usable_pos', xd['pos']) if not 'physical' in ad: rwy = ad['runways'][0] hdg = float(rwy["rwyhdg"]) hdgrad = (hdg / (180.0 / math.pi)) runway_length = float(rwy["runway_length"]) threshold = float(rwy["threshold"]) posA = mapper.latlon2merc((59, 18), 20) meter = mapper.approx_scale(posA, 20, 1 / 1852.0) rwylen = meter * runway_length delta = (math.sin(hdgrad) * rwylen, -math.cos(hdgrad) * rwylen) print "Delta:", delta posB = (posA[0] + delta[0], posA[1] + delta[1]) latlonA = mapper.to_str(mapper.merc2latlon(posA, 20)) latlonB = mapper.to_str(mapper.merc2latlon(posB, 20)) ad['physical'] = [[ dict(name=rwy['name'], usable_pos=latlonA, pos=latlonA, threshold=threshold), dict(name="^" + rwy['name'], usable_pos=latlonB, pos=latlonB, threshold=0) ]] if 'physical' in ad: def getdist_meter(p1, p2): brg, dist = mapper.bearing_and_distance( mapper.merc2latlon(p1, 20), mapper.merc2latlon(p2, 20)) return dist * 1852.0 def draw_cmds(): for d in ad['physical']: yield (mapper.latlon2merc(mapper.from_str(getpos(d[0])), 20), mapper.latlon2merc(mapper.from_str(getpos(d[1])), 20), d[0]['name'], d[1]['name'], d[0]['threshold'], d[1]['threshold']) def justmercs(): for p1, p2, n1, n2, t1, t2 in draw_cmds(): yield p1 yield p2 bb = bsptree.bb_from_mercs(justmercs()) center = (0.5 * (bb.x1 + bb.x2), 0.5 * (bb.y1 + bb.y2)) #print "Center:",center mercradius = max(bb.x2 - bb.x1, bb.y2 - bb.y1) scaling = (imgsize / 1.3) / mercradius def topixel(merc): off = (merc[0] - center[0], merc[1] - center[1]) return (off[0] * scaling + imgsize / 2, off[1] * scaling + imgsize / 2) def draw_marker(ctx, p1, p2, thresholdratio, msg, col=(1, 0, 0)): ninety = [p2[1] - p1[1], p2[0] - p1[0]] ninety = [ninety[0], -ninety[1]] #if ninety[0]<0: # ninety[0],ninety[1]=-ninety[0],-ninety[1] #print "ninety:",ninety p1 = topixel(p1) p2 = topixel(p2) d = [ p1[0] + thresholdratio * (p2[0] - p1[0]), p1[1] + thresholdratio * (p2[1] - p1[1]) ] """ dB=[d[0]+ninety[0],d[1]+ninety[1]] if dB[0]>0.75*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] elif dB[0]<0.25*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] elif dB[1]<0.25*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] elif dB[1]>0.75*imgsize: ninety[0],ninety[1]=-ninety[0],-ninety[1] dB=[d[0]+ninety[0],d[1]+ninety[1]] """ ctx.new_path() ctx.set_source(cairo.SolidPattern(*(col + (1, )))) ctx.arc(d[0], d[1], 6, 0, 2 * math.pi) ctx.fill() ctx.new_path() ctx.move_to(*d) ctx.save() ang = math.atan2(ninety[1], ninety[0]) * 180.0 / 3.1415 if ang > 90 or ang < -90: ang = (ang + 180) % 360 angrad = ang * (math.pi / 180) ctx.translate(*d) ctx.rotate(angrad) ctx.set_font_size(17) ext = ctx.text_extents(msg)[:4] w = ext[2] cand1 = ctx.user_to_device(10 + w / 2, 0) cand2 = ctx.user_to_device(-10 - w / 2, 0) def edgedist(x): return min(x[0], x[0] - imgsize, x[1], x[1] - imgsize) if edgedist(cand1) > edgedist(cand2): dC = [10, -ext[1] / 2] else: dC = [-10 - w, -ext[1] / 2] #dC=[dB[0],dB[1]] ctx.move_to(*dC) ctx.show_text(msg) ctx.restore() for p1, p2, n1, n2, t1, t2 in draw_cmds(): print "n1:", n1, "n2:", n2 print "p1:", mapper.merc2latlon(p1, 20) print "p2:", mapper.merc2latlon(p2, 20) pix1 = topixel(p1) pix2 = topixel(p2) ctx.set_source(cairo.SolidPattern(0.5, 0.5, 0.5, 1)) ctx.new_path() ctx.set_line_width(10) ctx.move_to(*pix1) ctx.line_to(*pix2) ctx.stroke() for p1, p2, n1, n2, t1, t2 in draw_cmds(): print "Matching", n1, n2, "to", perf['name'] if n2 == perf['name']: p1, n1, t1, p2, n2, t2 = p2, n2, t2, p1, n1, t1 if n1 == perf['name']: runwaylen = getdist_meter(p1, p2) startratio = perf["start"] / runwaylen start300ratio = perf["start300"] / runwaylen startrollratio = perf["start_roll"] / runwaylen safe_factor = 1.43 if 'safe_factor' in perf: safe_factor = float(perf['safe_factor']) thresholdratio = t1 / runwaylen landingratio = perf["land"] / runwaylen landingrollratio = landingratio - perf[ "landing_roll"] / runwaylen landingratio *= safe_factor landingrollratio *= safe_factor landingratio += thresholdratio landingrollratio += thresholdratio if what == 'start': draw_marker(ctx, p1, p2, 0, "Start", col=(1, 0, 0)) draw_marker(ctx, p1, p2, startrollratio, "Lättning", col=(1, 0.5, 0)) draw_marker(ctx, p1, p2, startratio, "tröskelhöjd", col=(1, 1, 0)) draw_marker(ctx, p1, p2, start300ratio, "300 fot höjd", col=(0, 1, 0)) if what == 'landing': draw_marker(ctx, p1, p2, thresholdratio, "tröskelhöjd ", col=(1, 0, 0)) draw_marker(ctx, p1, p2, landingrollratio, "Senaste sättning", col=(1, 0.5, 0)) draw_marker(ctx, p1, p2, landingratio, "Senaste stopp", (0, 1, 0)) buf = StringIO.StringIO() im.write_to_png(buf) png = buf.getvalue() response.headers['Content-Type'] = 'image/png' return png
def fi_parse_tma(): p=parse.Parser(r"/ais/eaip/pdf/enr/EF_ENR_2_1_EN.pdf",fixuphref,country='fi') res=[] atsres=[] for pagenr in xrange(4,p.get_num_pages()): parsed,atsparsed=parse_page(p,pagenr)#pagenr) res.extend(parsed) atsres.extend(atsparsed) #break print "Len ouf out ",len(res) atsout=[] for space in atsres: #print "bef cut:",space['points'] mypolys=[makepoly.poly(space['points'])] for tmaitem in res: if tmaitem['type']!='TMA': continue outmypolys=[] assert len(mypolys)>=1 for mypoly in list(mypolys): tmapoly=makepoly.poly(tmaitem['points']) #print mypoly #print tmapoly shape=mypoly.subtract(tmapoly) newpolys=shape.get_polys() if len(newpolys)>1: print "Length is:", len(newpolys) #print "Cutting" outmypolys.extend([shapemerge2d.Polygon(x) for x in list(newpolys)]) #assert len(newpolys)==1 if len(outmypolys)>1: print "outmypolys:",outmypolys #print "Cut to:",mypoly mypolys=outmypolys for mypoly in mypolys: t=[] for mx,my in [(v.get_x(),v.get_y()) for v in mypoly.get_vertices()]: t.append(mapper.to_str(mapper.merc2latlon((mx,my),13))) #print "Aft cut:",t newspace=dict(space) newspace['points']=t atsout.append(newspace) if len(mypolys)>1: print "Space was split into ",len(mypolys),"parts" res.extend(atsout) res.append(dict( name="FINLAND FIR", icao="EFIN", floor='GND', ceiling='-', freqs=[], type='FIR', date=datetime(2011,4,9), points=mapper.parse_coord_str(""" 601130N 0190512E - 601803N 0190756E - 610000N 0191905E - 614000N 0193000E - 631000N 0201000E - 632830N 0204000E - 633700N 0213000E - 644100N 0225500E - 653148N 0240824E - Along the common X/Y state boundary to 690336N 0203255E - Along the common X/Y state boundary to 690307N 0285545E - Along the common X/Y state boundary to 601201N 0271735E - 600800N 0263300E - 595830N 0260642E - 595300N 0255200E - 595430N 0252000E - 595300N 0245100E - 590000N 0210000E - 591524N 0203239E - 593346N 0195859E - 601130N 0190512E """,context="finland"))) #for pa in res: # pretty(pa) return res
else: borders = get_borders(context) print "start,end", start, end part1, idx1, pos1 = find_closest(borders, start) part2, idx2, pos2 = find_closest(borders, end) print "Found", pos1, pos2 if part1 != part2: raise Exception("Start and endpoint are not on same island!") part = part1 print "from,to", idx1, idx2 if idx1 == idx2: return [start, end] res1, dist1 = circle(borders[part], pos1, idx1, idx2, pos2, -1) res2, dist2 = circle(borders[part], pos1, idx1, idx2, pos2, 1) if dist1 < dist2: if longwayround: ret = res2 else: ret = res1 else: if longwayround: ret = res1 else: ret = res2 return [start] + ret + [end] if __name__ == '__main__': fa = follow_along("sweden", (59.0, 11.4), (61.0, 12.5)) print " - ".join(mapper.to_str(pos) for pos in fa)
def fi_parse_tma(): p = parse.Parser(r"/ais/eaip/pdf/enr/EF_ENR_2_1_EN.pdf", fixuphref, country='fi') res = [] atsres = [] for pagenr in xrange(4, p.get_num_pages()): parsed, atsparsed = parse_page(p, pagenr) #pagenr) res.extend(parsed) atsres.extend(atsparsed) #break print "Len ouf out ", len(res) atsout = [] for space in atsres: #print "bef cut:",space['points'] mypolys = [makepoly.poly(space['points'])] for tmaitem in res: if tmaitem['type'] != 'TMA': continue outmypolys = [] assert len(mypolys) >= 1 for mypoly in list(mypolys): tmapoly = makepoly.poly(tmaitem['points']) #print mypoly #print tmapoly shape = mypoly.subtract(tmapoly) newpolys = shape.get_polys() if len(newpolys) > 1: print "Length is:", len(newpolys) #print "Cutting" outmypolys.extend( [shapemerge2d.Polygon(x) for x in list(newpolys)]) #assert len(newpolys)==1 if len(outmypolys) > 1: print "outmypolys:", outmypolys #print "Cut to:",mypoly mypolys = outmypolys for mypoly in mypolys: t = [] for mx, my in [(v.get_x(), v.get_y()) for v in mypoly.get_vertices()]: t.append(mapper.to_str(mapper.merc2latlon((mx, my), 13))) #print "Aft cut:",t newspace = dict(space) newspace['points'] = t atsout.append(newspace) if len(mypolys) > 1: print "Space was split into ", len(mypolys), "parts" res.extend(atsout) res.append( dict(name="FINLAND FIR", icao="EFIN", floor='GND', ceiling='-', freqs=[], type='FIR', date=datetime(2011, 4, 9), points=mapper.parse_coord_str( """ 601130N 0190512E - 601803N 0190756E - 610000N 0191905E - 614000N 0193000E - 631000N 0201000E - 632830N 0204000E - 633700N 0213000E - 644100N 0225500E - 653148N 0240824E - Along the common X/Y state boundary to 690336N 0203255E - Along the common X/Y state boundary to 690307N 0285545E - Along the common X/Y state boundary to 601201N 0271735E - 600800N 0263300E - 595830N 0260642E - 595300N 0255200E - 595430N 0252000E - 595300N 0245100E - 590000N 0210000E - 591524N 0203239E - 593346N 0195859E - 601130N 0190512E """, context="finland"))) #for pa in res: # pretty(pa) return res
def no_obstacles(): out = [] fnames = [ "/home/anders/saker/avl_fplan_world/norway_obst/20120903pkt.shp", "/home/anders/saker/avl_fplan_world/norway_obst/20120903linpkt.shp", "/home/anders/saker/avl_fplan_world/norway_obst/20120903lin.shp" ] for fname in fnames: r = shapefile.Reader(fname) utm = Proj(proj='utm', zone=33, ellps='WGS84') wgs84 = Proj(init='epsg:4326') untrans = set() osts = { unicode('Vindm\xef\xbf\xbdlle', 'utf8'): 'Wind turbine', u'T\ufffdrn': 'Tower', u'Mast TELE': 'Mast', u'Annet': 'Antenna', u'Heisekran': 'Crane', u'Tank': 'Tank', u'Fyr': 'Lighthouse', u'Bru': 'Bridge', u'Mast EL': 'Mast', u'Pipe': 'Chimney', u'Oljeinstallasjon': 'Oil Platform', u'Mast/stolpe veilys': 'Mast', u'Bygning': 'Building', u'Hoppbakke': 'Ski-jump', u'Silo': 'Silo', u'Skiheis': 'Ski lift', u'Kraftlinespenn': 'Power lines', u'LuftledningLH': 'Power lines', u'Gondolheis': 'Ski lift', u'Taubane': 'Aerial tramway', u'L\ufffdypestreng': 'Power lines' } """ "Wind turbine", "Mast", "Cathedral", "Pylon", "Building", "Platform", "Chimney", "Mine hoist", "Bridge pylon", "Crane", "W Tower", "Church", "Silo", "City Hall", "Gasometer", "Tower", "Bridge pylon, 60 per minute"] """ columns = [x[0] for x in r.fields] for rec in r.shapeRecords(): #print "col:",columns #print "rec:",rec.record d = dict(zip(columns[1:], rec.record)) def fixname(n): n = n.strip() if n == "": n = "Unknown" return n nortype = unicode(d['hindertype'], 'utf8') engtype = osts.get(nortype, nortype) if not nortype in osts: untrans.add(nortype) base = dict(name=fixname(unicode(d['lfh_navn'], 'utf8')), height=int(d['hoeydeover'] / 0.3048), elev=int(d['totalhoeyd'] / 0.3048), lighting=unicode(d['lyssetting'], 'utf8'), kind=engtype, date=datetime(2012, 9, 1)) if base['height'] < 300: continue for point in rec.shape.points: x, y = point lon, lat = transform(utm, wgs84, x, y) #print "Input: ",d,x,y,"output:",lat,lon cur = copy(base) cur['pos'] = mapper.to_str((lat, lon)) out.append(cur) #break print "missing translations", untrans return out
#encoding=utf8 import fplan.lib.mapper as mapper import rwy_constructor minor_ad_charts={ u"Frölunda":"http://www.swflightplanner.se:8080/frolunda.jpg" } frolunda=dict(icao="ESVF", name=u"Frölunda", pos=mapper.to_str(mapper.from_aviation_format("5927.5N01742.4E")), runways=rwy_constructor.get_rwys( [ dict(pos="59.458468, 17.70691",thr="16",usable_pos="59.459198, 17.70644"), dict(pos="59.45414, 17.71009",thr="34"), #dict(pos="59.458716, 17.707166",thr="07",usable_pos="59.458505, 17.705782"), #dict(pos="59.459343, 17.712018",thr="25",usable_pos="59.459343, 17.712018"), ] ), elev=30) extra_airfields=[ frolunda, dict(icao="ZZZZ", name=u"Finspång", pos=mapper.to_str(mapper.from_aviation_format("5843.990N01536.171E")), elev=164),#TODO: Add real elev dict(icao="ZZZZ", name=u"Motala/Skärstad", pos=mapper.to_str(mapper.from_aviation_format("5829.5N01506.2E")), elev=338),#TODO: Add real elev
def osm_airfields_parse(): nameicao=parse_info() f=open("adnames.txt","w") for name,icao in sorted(nameicao,key=lambda x:x[0]): f.write("%s: %s\n"%(icao.encode('utf8'),name.encode('utf8'))) f.close() ads=[] hits=0 misses=[] name2icao=[] for name,icao in nameicao: name2icao.append((normalize(name),name,icao)) dupecheck=set() for lon,lat,name in csv.reader(open("fplan/extract/aerodromes.txt")): name=unicode(name,"utf8") if not name.strip(): continue icao=None n1=normalize(name) if frozenset(n1) in dupecheck: continue dupecheck.add(frozenset(n1)) lastquality=0 lastname=None for n2,iname,iicao in name2icao: #print repr(n1),"==",repr(n2) minlen=min(len(n1),len(n2)) if minlen>2: minlen=minlen-1 quality=len(n1.intersection(n2)) if quality>=minlen and quality>lastquality: if icao!=None and icao!=iicao: print "For name:",name,"Previous match:,",icao,"New match:",iicao,"Name:",iname,"last name:",lastname,"quality:",quality,"last:",lastquality,"minlen:",minlen #assert icao==None icao=iicao lastquality=quality lastname=iname #print "Ap with name:",name if icao: hits+=1 icao=icao else: icao='ZZZZ' misses.append(name) #print "Missed:",name d=dict( icao=icao, name=name, pos=mapper.to_str((float(lat),float(lon))), elev=int(gte.get_terrain_elev((float(lat),float(lon)))) ) if hits%10==0: print "Hits: %d, Misses: %d, Perc: %.1f"%(hits,len(misses),100.0*(float(hits)/(float(hits)+len(misses)))) ads.append(d) print "Misses:" f=open("missedads.txt","w") for miss in sorted(misses): f.write((miss+" - "+repr(normalize(miss))+u"\n").encode('utf8')) f.close() f=open("foundads.txt","w") for norm,name,icao in name2icao: f.write((name+" - "+repr(norm)+u"\n").encode('utf8')) f.close() print "Hits: ",hits print "Misses: ",len(misses) return ads
def extract_airfields(filtericao=lambda x:True,purge=True): #print getxml("/AIP/AD/AD 1/ES_AD_1_1_en.pdf") ads=[] p=Parser("/AIP/AD/AD 1/ES_AD_1_1_en.pdf") points=dict() startpage=None for pagenr in xrange(p.get_num_pages()): page=p.parse_page_to_items(pagenr) if page.count("Aerodrome directory"): startpage=pagenr break if startpage==None: raise Exception("Couldn't find aerodrome directory in file") #print "Startpage: %d"%(startpage,) #nochartf=open("nochart.txt","w") for pagenr in xrange(startpage,p.get_num_pages()): row_y=[] page=p.parse_page_to_items(pagenr) allines=[x for x in (page.get_lines(page.get_partially_in_rect(0,0,15,100))) if x.strip()] for item,next in zip(allines,allines[1:]+[""]): #print "item:",item m=re.match(ur"^\s*[A-ZÅÄÖ]{3,}(?:/.*)?\b.*",item) if m: #print "Candidate, next is:",next if re.match(r"^\s*[A-Z]{4}\b.*",next): #print "Matched:",item #print "y1:",item.y1 row_y.append(item.y1) for y1,y2 in zip(row_y,row_y[1:]+[100.0]): #print "Extacting from y-range: %f-%f"%(y1,y2) items=list(page.get_partially_in_rect(0,y1-0.25,5.0,y2+0.25,ysort=True)) if len(items)>=2: #print "Extract items",items ad=dict(name=unicode(items[0].text).strip(), icao=unicode(items[1].text).strip() ) #print "Icao:",ad['icao'] assert re.match(r"[A-Z]{4}",ad['icao']) if not filtericao(ad): continue if len(items)>=3: #print "Coord?:",items[2].text m=re.match(r".*(\d{6}N)\s*(\d{7}E).*",items[2].text) if m: lat,lon=m.groups() ad['pos']=parse_coords(lat,lon) #print "Items3:",items[3:] elev=re.findall(r"(\d{1,5})\s*ft"," ".join(t.text for t in items[3:])) #print "Elev:",elev assert len(elev)==1 ad['elev']=int(elev[0]) ads.append(ad) big_ad=set() for ad in ads: if not ad.has_key('pos'): big_ad.add(ad['icao']) for ad in ads: icao=ad['icao'] if icao in big_ad: if icao in ['ESIB','ESNY','ESCM','ESPE']: continue try: p=Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_6_1_en.pdf"%(icao,icao)) except: p=Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_6-1_en.pdf"%(icao,icao)) ad['aipvacurl']=p.get_url() for pagenr in xrange(p.get_num_pages()): page=p.parse_page_to_items(pagenr) """ for altline in exitlines: m=re.match(r"(\w+)\s+(\d+N)\s*(\d+E.*)",altline) if not m: continue name,lat,lon=m.groups() try: coord=parse_coords(lat,lon) except Exception: continue points.append(dict(name=name,pos=coord)) """ for kind in xrange(2): if kind==0: hits=page.get_by_regex(r"H[Oo][Ll][Dd][Ii][Nn][Gg]") kind="holding point" if kind==1: hits=page.get_by_regex(r"[Ee]ntry.*[Ee]xit.*point") kind="entry/exit point" if len(hits)==0: continue for holdingheading in hits: items=sorted(page.get_partially_in_rect(holdingheading.x1+2.0,holdingheading.y2+0.1,holdingheading.x1+0.5,100), key=lambda x:x.y1) items=[x for x in items if not x.text.startswith(" ")] #print "Holding items:",items for idx,item in enumerate(items): print "Holding item",item y1=item.y1 if idx==len(items)-1: y2=100 else: y2=items[idx+1].y1 items2=[x for x in page.get_partially_in_rect(item.x1+1,y1+0.3,item.x1+40,y2-0.1) if x.x1>=item.x1-0.25 and x.y1>=y1-0.05 and x.y1<y2-0.05] s=(" ".join(page.get_lines(items2))).strip() print "Holding lines:",repr(page.get_lines(items2)) #if s.startswith("ft Left/3"): #Special case for ESOK # s,=re.match("ft Left/3.*?([A-Z]{4,}.*)",s).groups() #m=re.match("ft Left/\d+.*?([A-Z]{4,}.*)",s) #if m: # s,=m.groups() if s.startswith("LjUNG"): #Really strange problem with ESCF s=s[0]+"J"+s[2:] if s.lower().startswith("holding"): sl=s.split(" ",1) if len(sl)>1: s=sl[1] s=s.strip() if kind=="entry/exit point" and s.startswith("HOLDING"): continue #reached HOLDING-part of VAC #Check for other headings #Fixup strange formatting of points in some holding items: (whitespace between coord and 'E') s=re.sub(ur"(\d+)\s*(N)\s*(\d+)\s*(E)",lambda x:"".join(x.groups()),s) m=re.match(r"([A-Z]{2,}).*?(\d+N)\s*(\d+E).*",s) if not m: m=re.match(r".*?(\d+N)\s*(\d+E).*",s) if not m: continue assert m lat,lon=m.groups() #skavsta if icao=="ESKN": if s.startswith(u"Hold north of T"): name="NORTH" elif s.startswith(u"Hold south of B"): name="SOUTH" else: assert 0 #add more specials here else: continue else: name,lat,lon=m.groups() try: coord=parse_coords(lat,lon) except Exception: print "Couldn't parse:",lat,lon continue #print name,lat,lon,mapper.format_lfv(*mapper.from_str(coord)) if name.count("REMARK") or len(name)<=2: print "Suspicious name: ",name #sys.exit(1) continue points[icao+' '+name]=dict(name=icao+' '+name,icao=icao,pos=coord,kind=kind) #for point in points.items(): # print point #sys.exit(1) def fixhex11(s): out=[] for c in s: i=ord(c) if i>=0x20: out.append(c) continue if i in [0x9,0xa,0xd]: out.append(c) continue out.append(' ') return "".join(out) for ad in ads: icao=ad['icao'] if icao in big_ad: #print "Parsing ",icao p=Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_en.pdf"%(icao,icao),loadhook=fixhex11) ad['aiptexturl']=p.get_url() firstpage=p.parse_page_to_items(0) te="\n".join(firstpage.get_all_lines()) #print te coords=re.findall(r"ARP.*(\d{6}N)\s*(\d{7}E)",te) if len(coords)>1: raise Exception("First page of airport info (%s) does not contain exactly ONE set of coordinates"%(icao,)) if len(coords)==0: print "Couldn't find coords for ",icao #print "Coords:",coords ad['pos']=parse_coords(*coords[0]) elev=re.findall(r"Elevation.*?(\d{1,5})\s*ft",te,re.DOTALL) if len(elev)>1: raise Exception("First page of airport info (%s) does not contain exactly ONE elevation in ft"%(icao,)) if len(elev)==0: print "Couldn't find elev for ",icao ad['elev']=int(elev[0]) freqs=[] found=False thrs=[] #uprint("-------------------------------------") for pagenr in xrange(p.get_num_pages()): page=p.parse_page_to_items(pagenr) #uprint("Looking on page %d"%(pagenr,)) if 0: #opening hours are no longer stored in a separate document for any airports. No need to detect which any more (since none are). for item in page.get_by_regex(".*OPERATIONAL HOURS.*"): lines=page.get_lines(page.get_partially_in_rect(0,item.y2+0.1,100,100)) for line in lines: things=["ATS","Fuelling","Operating"] if not line.count("AIP SUP"): continue for thing in things: if line.count(thing): ad['aipsup']=True for item in page.get_by_regex(".*\s*RUNWAY\s*PHYSICAL\s*CHARACTERISTICS\s*.*"): #uprint("Physical char on page") lines=page.get_lines(page.get_partially_in_rect(0,item.y2+0.1,100,100)) seen_end_rwy_text=False for line,nextline in izip(lines,lines[1:]+[None]): #uprint("MAtching: <%s>"%(line,)) if re.match(ur"AD\s+2.13",line): break if line.count("Slope of"): break if line.lower().count("end rwy:"): seen_end_rwy_text=True if line.lower().count("bgn rwy:"): seen_end_rwy_text=True m=re.match(ur".*(\d{6}\.\d+)[\s\(\)\*]*(N).*",line) if not m:continue m2=re.match(ur".*(\d{6,7}\.\d+)\s*[\s\(\)\*]*(E).*",nextline) if not m2:continue latd,n=m.groups() lond,e=m2.groups() assert n=="N" assert e=="E" lat=latd+n lon=lond+e rwytxts=page.get_lines(page.get_partially_in_rect(0,line.y1+0.05,12,nextline.y2-0.05)) uprint("Rwytxts:",rwytxts) rwy=None for rwytxt in rwytxts: #uprint("lat,lon:%s,%s"%(lat,lon)) #uprint("rwytext:",rwytxt) m=re.match(ur"\s*(\d{2}[LRCM]?)\b.*",rwytxt) if m: assert rwy==None rwy=m.groups()[0] if rwy==None and seen_end_rwy_text: continue print "Cur airport:",icao already=False assert rwy!=None seen_end_rwy_text=False for thr in thrs: if thr['thr']==rwy: raise Exception("Same runway twice on airfield:"+icao) thrs.append(dict(pos=mapper.parse_coords(lat,lon),thr=rwy)) assert len(thrs)>=2 for pagenr in xrange(0,p.get_num_pages()): page=p.parse_page_to_items(pagenr) matches=page.get_by_regex(r".*ATS\s+COMMUNICATION\s+FACILITIES.*") #print "Matches of ATS COMMUNICATION FACILITIES on page %d: %s"%(pagenr,matches) if len(matches)>0: commitem=matches[0] curname=None callsign=page.get_by_regex_in_rect(ur"Call\s*sign",0,commitem.y1,100,commitem.y2+8)[0] for idx,item in enumerate(page.get_lines(page.get_partially_in_rect(callsign.x1-0.5,commitem.y1,100,100),fudge=0.3,order_fudge=15)): if item.strip()=="": curname=None if re.match(".*RADIO\s+NAVIGATION\s+AND\s+LANDING\s+AIDS.*",item): break #print "Matching:",item m=re.match(r"(.*?)\s*(\d{3}\.\d{1,3})\s*MHz.*",item) #print "MHZ-match:",m if not m: continue #print "MHZ-match:",m.groups() who,sfreq=m.groups() freq=float(sfreq) if abs(freq-121.5)<1e-4: if who.strip(): curname=who continue #Ignore emergency frequency, it is understood if not who.strip(): if curname==None: continue else: curname=who freqs.append((curname.strip().rstrip("/"),freq)) for pagenr in xrange(0,p.get_num_pages()): page=p.parse_page_to_items(pagenr) matches=page.get_by_regex(r".*ATS\s*AIRSPACE.*") #print "Matches of ATS_AIRSPACE on page %d: %s"%(pagenr,matches) if len(matches)>0: heading=matches[0] desigitem,=page.get_by_regex("Designation and lateral limits") vertitem,=page.get_by_regex("Vertical limits") airspaceclass,=page.get_by_regex("Airspace classification") lastname=None subspacelines=dict() subspacealts=dict() for idx,item in enumerate(page.get_lines(page.get_partially_in_rect(desigitem.x2+1,desigitem.y1,100,vertitem.y1-1))): if item.count("ATS airspace not established"): assert idx==0 break if item.strip()=="": continue m=re.match(r"(.*?)(\d{6}N\s+.*)",item) if m: name,coords=m.groups() name=name.strip() else: name=item.strip() coords=None if name: lastname=name if coords: subspacelines.setdefault(lastname,[]).append(coords) assert lastname lastname=None #print "Spaces:",subspacelines #print "ICAO",ad['icao'] #altlines=page.get_lines(page.get_partially_in_rect(vertitem.x2+1,vertitem.y1,100,airspaceclass.y1-0.2)) #print "Altlines:",altlines subspacealts=dict() subspacekeys=subspacelines.keys() allaltlines=" ".join(page.get_lines(page.get_partially_in_rect(vertitem.x1+0.5,vertitem.y1+0.5,100,airspaceclass.y1-0.2))) single_vertlim=False totalts=list(mapper.parse_all_alts(allaltlines)) #print "totalts:",totalts if len(totalts)==2: single_vertlim=True for subspacename in subspacekeys: ceil=None floor=None subnames=[subspacename] if subspacename.split(" ")[-1].strip() in ["TIA","TIZ","CTR","CTR/TIZ"]: subnames.append(subspacename.split(" ")[-1].strip()) #print "Parsing alts for ",subspacename,subnames try: for nametry in subnames: if single_vertlim: #there's only one subspace, parse all of vertical limits field for this single one. items=[vertitem] else: items=page.get_by_regex_in_rect(nametry,vertitem.x2+1,vertitem.y1,100,airspaceclass.y1-0.2) for item in items: alts=[] for line in page.get_lines(page.get_partially_in_rect(item.x1+0.5,item.y1+0.5,100,airspaceclass.y1-0.2)): #print "Parsing:",line line=line.replace(nametry,"").lower().strip() parsed=list(mapper.parse_all_alts(line)) if len(parsed): alts.append(mapper.altformat(*parsed[0])) if len(alts)==2: break if alts: #print "alts:",alts ceil,floor=alts raise StopIteration except StopIteration: pass assert ceil and floor subspacealts[subspacename]=dict(ceil=ceil,floor=floor) spaces=[] for spacename in subspacelines.keys(): altspacename=spacename #print "Altspacename: %s, subspacesalts: %s"%(altspacename,subspacealts) space=dict( name=spacename, ceil=subspacealts[altspacename]['ceil'], floor=subspacealts[altspacename]['floor'], points=parse_coord_str(" ".join(subspacelines[spacename])), freqs=list(set(freqs)) ) if True: vs=[] for p in space['points']: x,y=mapper.latlon2merc(mapper.from_str(p),13) vs.append(Vertex(int(x),int(y))) p=Polygon(vvector(vs)) if p.calc_area()<=30*30: pass#print space pass#print "Area:",p.calc_area() assert p.calc_area()>30*30 #print "Area: %f"%(p.calc_area(),) spaces.append(space) #print space ad['spaces']=spaces found=True if found: break assert found ad['runways']=rwy_constructor.get_rwys(thrs) #Now find any ATS-airspace chartblobnames=[] for ad in ads: icao=ad['icao'] if icao in big_ad: parse_landing_chart.help_plc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_2-1_en.pdf"%(icao,icao), icao,ad['pos'],"se",variant="") parse_landing_chart.help_plc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_6-1_en.pdf"%(icao,icao), icao,ad['pos'],"se",variant="vac") parse_landing_chart.help_plc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_2-3_en.pdf"%(icao,icao), icao,ad['pos'],"se",variant="parking") #aip_text_documents.help_parse_doc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_6_1_en.pdf"%(icao,icao), # icao,"se",title="General Information",category="general") aip_text_documents.help_parse_doc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_en.pdf"%(icao,icao), icao,"se",title="General Information",category="general") #if purge: # parse_landing_chart.purge_old(chartblobnames,country="se") #sys.exit(1) for extra in extra_airfields.extra_airfields: if filtericao(extra): ads.append(extra) print print for k,v in sorted(points.items()): print k,v,mapper.format_lfv(*mapper.from_str(v['pos'])) #print "Num points:",len(points) origads=list(ads) for flygkartan_id,name,lat,lon,dummy in csv.reader(open("fplan/extract/flygkartan.csv"),delimiter=";"): found=None lat=float(lat) lon=float(lon) if type(name)==str: name=unicode(name,'utf8') mercf=mapper.latlon2merc((lat,lon),13) for a in origads: merca=mapper.latlon2merc(mapper.from_str(a['pos']),13) dist=math.sqrt((merca[0]-mercf[0])**2+(merca[1]-mercf[1])**2) if dist<120: found=a break if found: found['flygkartan_id']=flygkartan_id else: d=dict( icao='ZZZZ', name=name, pos=mapper.to_str((lat,lon)), elev=int(get_terrain_elev((lat,lon))), flygkartan_id=flygkartan_id) if filtericao(d): ads.append(d) minor_ad_charts=extra_airfields.minor_ad_charts for ad in ads: if ad['name'].count(u"Långtora"): ad['pos']=mapper.to_str(mapper.from_aviation_format("5944.83N01708.20E")) if ad['name'] in minor_ad_charts: charturl=minor_ad_charts[ad['name']] arp=ad['pos'] if 'icao' in ad and ad['icao'].upper()!='ZZZZ': icao=ad['icao'].upper() else: icao=ad['fake_icao'] parse_landing_chart.help_plc(ad,charturl,icao,arp,country='raw',variant="landing") """ assert icao!=None lc=parse_landing_chart.parse_landing_chart( charturl, icao=icao, arppos=arp,country="raw") assert lc if lc: ad['adcharturl']=lc['url'] ad['adchart']=lc """ #print ads for ad in ads: print "%s: %s - %s (%s ft) (%s)"%(ad['icao'],ad['name'],ad['pos'],ad['elev'],ad.get('flygkartan_id','inte i flygkartan')) for space in ad.get('spaces',[]): for freq in space.get('freqs',[]): print " ",freq #if 'spaces' in ad: # print " spaces: %s"%(ad['spaces'],) #if 'aiptext' in ad: # print "Aip texts:",ad['aiptext'] #else: # print "No aiptext" print "Points:" for point in sorted(points.values(),key=lambda x:x['name']): print point f=codecs.open("extract_airfields.regress.txt","w",'utf8') for ad in ads: r=repr(ad) d=md5.md5(r).hexdigest() f.write("%s - %s - %s\n"%(ad['icao'],ad['name'],d)) f.close() f=codecs.open("extract_airfields.regress-details.txt","w",'utf8') for ad in ads: r=repr(ad) f.write(u"%s - %s - %s\n"%(ad['icao'],ad['name'],r)) f.close() return ads,points.values()
def fi_parse_ats_rte(tmapolys=[]): p = parse.Parser("/ais/eaip/pdf/enr/EF_ENR_3_3_EN.pdf", lambda x: x, country='fi') out = [] for pagenr in xrange(p.get_num_pages()): page = p.parse_page_to_items(pagenr) def isol_routes(): cur = None accum = [] for line in page.get_lines(page.get_all_items()): uprint("Looking at ", line) m = re.match(ur"(^[A-Z]{1,2}\d+)\s+\(.*", line) if m and line.x1 < 25: if cur: uprint("Yielding %s: %s because of found name:%s" % (cur, accum, m.groups())) yield cur, accum accum = [] cur, = m.groups() continue m = re.match(ur"(\d{6}N)\s*(\d{7}E).*", line) if m: accum.append((line.y1, line.y2, " ".join(m.groups()))) if cur: uprint("Yielding %s: %s because of end of page" % (cur, accum)) yield cur, accum accum = [] def getsig(coords, altspecs): poss = [] #print "Coords: <%s>"%(coords,) for y1, y2, pos in coords: poss.append(pos) uprint("poss: <%s>" % (poss, )) s = "-".join(poss) s2 = "-".join(altspecs) return md5.md5(s.encode('utf8') + s2.encode('utf8')).hexdigest() def low_routes(routes): for routename, coords in routes: uprint("Found route: %s, with %s cords" % (routename, coords)) assert len(coords) >= 2 y1 = coords[0][0] y2 = coords[-1][1] foundlow = False altspec = [] for item in page.get_partially_in_rect(0, y1, 100, y2): uprint("Looking for alt for %s in :" % (routename, ), item.text) m = re.match(ur".*FL\s+(\d{2,3})\b(?:\s.*|$)", item.text) if m: fl, = m.groups() uprint("Matched alt:", m.groups()) fli = int(fl, 10) if fli < 95: uprint("Foundlow for route %s: %d" % (routename, fli)) foundlow = True altspec.append(item.text) if foundlow: yield routename, coords, altspec def get_airspaces(routes): for routename, coords, altspec in routes: sig = getsig(coords, altspec) if (routename, sig) in predef: #pobj=None #for sroutename,ssig in predef: # if routename==sroutename: pobj = (routename, sig) width_nm, floor, ceiling, coordstr = predef[pobj] rawcoords = re.findall(ur"(\d{6}N)\s*(\d{7}E)", coordstr) coords = [ mapper.latlon2merc( mapper.from_str(mapper.parse_coords(lats, lons)), 13) for lats, lons in rawcoords ] width = float( mapper.approx_scale(coords[0], 13, 1.25 * width_nm)) try: outline = get_outline(coords, width) except Exception: uprint(u"Trouble parsing %s" % (routename, )) raise yield dict(name=routename, floor=floor, ceiling=ceiling, freqs=[], type="RNAV", points=[ mapper.to_str(mapper.merc2latlon(x, 13)) for x in outline ]) else: uprint( "Need to have predefine for route %s, with md5: %s" % (routename, sig)) uprint("Altitude, and points") raise Exception( 'Missing predef for route. Use: ("%s","%s") : ( 10,"FL 65","FL 95","""\n\n """),' % (routename, sig)) i1 = isol_routes() low1 = low_routes(i1) out.extend(list(get_airspaces(low1))) out2 = [] for space in out: mypoly = makepoly.poly[space['points']] for tmapoly in tmapolys: mypoly = shapemerge2d.shape_difference(mypoly, tmapoly) t = [] for mx, my in [(v.get_x(), v.get_y()) for v in mypoly.get_vertices()]: t.append(mapper.to_str(mapper.merc2latlon((mx, my), 13))) space['points'] = t return out2
def no_obstacles(): out=[] fnames=["/home/anders/saker/avl_fplan_world/norway_obst/20120903pkt.shp", "/home/anders/saker/avl_fplan_world/norway_obst/20120903linpkt.shp", "/home/anders/saker/avl_fplan_world/norway_obst/20120903lin.shp"] for fname in fnames: r=shapefile.Reader(fname) utm = Proj(proj='utm',zone=33,ellps='WGS84') wgs84 = Proj(init='epsg:4326') untrans=set() osts={unicode('Vindm\xef\xbf\xbdlle','utf8'):'Wind turbine', u'T\ufffdrn':'Tower', u'Mast TELE':'Mast', u'Annet':'Antenna', u'Heisekran':'Crane', u'Tank':'Tank', u'Fyr':'Lighthouse', u'Bru':'Bridge', u'Mast EL':'Mast', u'Pipe':'Chimney', u'Oljeinstallasjon':'Oil Platform', u'Mast/stolpe veilys':'Mast', u'Bygning':'Building', u'Hoppbakke':'Ski-jump', u'Silo':'Silo', u'Skiheis':'Ski lift', u'Kraftlinespenn':'Power lines', u'LuftledningLH':'Power lines', u'Gondolheis':'Ski lift', u'Taubane':'Aerial tramway', u'L\ufffdypestreng':'Power lines' } """ "Wind turbine", "Mast", "Cathedral", "Pylon", "Building", "Platform", "Chimney", "Mine hoist", "Bridge pylon", "Crane", "W Tower", "Church", "Silo", "City Hall", "Gasometer", "Tower", "Bridge pylon, 60 per minute"] """ columns=[x[0] for x in r.fields] for rec in r.shapeRecords(): #print "col:",columns #print "rec:",rec.record d=dict(zip(columns[1:],rec.record)) def fixname(n): n=n.strip() if n=="": n="Unknown" return n nortype=unicode(d['hindertype'],'utf8') engtype=osts.get(nortype,nortype) if not nortype in osts: untrans.add(nortype) base=dict( name=fixname(unicode(d['lfh_navn'],'utf8')), height=int(d['hoeydeover']/0.3048), elev=int(d['totalhoeyd']/0.3048), lighting=unicode(d['lyssetting'],'utf8'), kind=engtype, date=datetime(2012,9,1)) if base['height']<300: continue for point in rec.shape.points: x,y=point lon,lat=transform(utm,wgs84,x,y) #print "Input: ",d,x,y,"output:",lat,lon cur=copy(base) cur['pos']=mapper.to_str((lat,lon)) out.append(cur) #break print "missing translations",untrans return out
def fi_parse_ats_rte(tmapolys=[]): p=parse.Parser("/ais/eaip/pdf/enr/EF_ENR_3_3_EN.pdf",lambda x: x,country='fi') out=[] for pagenr in xrange(p.get_num_pages()): page=p.parse_page_to_items(pagenr) def isol_routes(): cur=None accum=[] for line in page.get_lines(page.get_all_items()): uprint("Looking at ",line) m=re.match(ur"(^[A-Z]{1,2}\d+)\s+\(.*",line) if m and line.x1<25: if cur: uprint("Yielding %s: %s because of found name:%s"%(cur,accum,m.groups())) yield cur,accum accum=[] cur,=m.groups() continue m=re.match(ur"(\d{6}N)\s*(\d{7}E).*",line) if m: accum.append((line.y1,line.y2," ".join(m.groups()))) if cur: uprint("Yielding %s: %s because of end of page"%(cur,accum)) yield cur,accum accum=[] def getsig(coords,altspecs): poss=[] #print "Coords: <%s>"%(coords,) for y1,y2,pos in coords: poss.append(pos) uprint("poss: <%s>"%(poss,)) s="-".join(poss) s2="-".join(altspecs) return md5.md5(s.encode('utf8')+s2.encode('utf8')).hexdigest() def low_routes(routes): for routename,coords in routes: uprint("Found route: %s, with %s cords"%(routename,coords)) assert len(coords)>=2 y1=coords[0][0] y2=coords[-1][1] foundlow=False altspec=[] for item in page.get_partially_in_rect(0,y1,100,y2): uprint("Looking for alt for %s in :"%(routename,),item.text) m=re.match(ur".*FL\s+(\d{2,3})\b(?:\s.*|$)",item.text) if m: fl,=m.groups() uprint("Matched alt:",m.groups()) fli=int(fl,10) if fli<95: uprint("Foundlow for route %s: %d"%(routename,fli)) foundlow=True altspec.append(item.text) if foundlow: yield routename,coords,altspec def get_airspaces(routes): for routename,coords,altspec in routes: sig=getsig(coords,altspec) if (routename,sig) in predef: #pobj=None #for sroutename,ssig in predef: # if routename==sroutename: pobj=(routename,sig) width_nm,floor,ceiling,coordstr=predef[pobj] rawcoords=re.findall(ur"(\d{6}N)\s*(\d{7}E)",coordstr) coords=[mapper.latlon2merc(mapper.from_str(mapper.parse_coords(lats,lons)),13) for lats,lons in rawcoords] width=float(mapper.approx_scale(coords[0],13,1.25*width_nm)) try: outline=get_outline(coords,width) except Exception: uprint(u"Trouble parsing %s"%(routename,)) raise yield dict(name=routename, floor=floor, ceiling=ceiling, freqs=[], type="RNAV", points=[mapper.to_str(mapper.merc2latlon(x,13)) for x in outline]) else: uprint("Need to have predefine for route %s, with md5: %s"%(routename,sig)) uprint("Altitude, and points") raise Exception('Missing predef for route. Use: ("%s","%s") : ( 10,"FL 65","FL 95","""\n\n """),'%(routename,sig)) i1=isol_routes() low1=low_routes(i1) out.extend(list(get_airspaces(low1))) out2=[] for space in out: mypoly=makepoly.poly[space['points']] for tmapoly in tmapolys: mypoly=shapemerge2d.shape_difference(mypoly,tmapoly) t=[] for mx,my in [(v.get_x(),v.get_y()) for v in mypoly.get_vertices()]: t.append(mapper.to_str(mapper.merc2latlon((mx,my),13))) space['points']=t return out2