def weather(self): dummy, routes = get_route(tripuser(), request.params['tripname']) ret = [] alts = request.params.get('alts', '') if alts == None: altvec = [] else: altvec = alts.split(",") for route, altitude in zip(routes, altvec): #print("Looking for waypoint: %s"%(way.pos,)) try: mapper.parse_elev(altitude) except mapper.NotAnAltitude, cause: ret.append(['', '']) continue #skip this alt #N+1 selects.... merc1 = mapper.latlon2merc(mapper.from_str(route.a.pos), 14) merc2 = mapper.latlon2merc(mapper.from_str(route.a.pos), 14) center = (0.5 * (merc1[0] + merc2[0]), 0.5 * (merc1[1] + merc2[1])) lat, lon = mapper.merc2latlon(center, 14) #print "Fetching weather for %s,%s, %s"%(lat,lon,route.altitude) when = route.depart_dt + (route.arrive_dt - route.depart_dt) / 2 dummy1, dummy2, we = gfs_weather.get_prognosis(when) if we == None: return "" #Fail completely we don't have the weather here. We only succeed if we have weather for all parts of the journey. else: try: wi = we.get_wind(lat, lon, mapper.parse_elev(altitude)) except: print traceback.format_exc() return "" #print "Got winds:",wi ret.append([wi['direction'], wi['knots']])
def follow_along(context,start,end,longwayround=False): out=[] for merc in follow_along13(context, mapper.latlon2merc(start,13), mapper.latlon2merc(end,13),longwayround=longwayround): out.append( mapper.merc2latlon(merc,13) ) 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 weather(self): dummy,routes=get_route(tripuser(),request.params['tripname']) ret=[] alts=request.params.get('alts','') if alts==None: altvec=[] else: altvec=alts.split(",") for route,altitude in zip(routes,altvec): #print("Looking for waypoint: %s"%(way.pos,)) try: mapper.parse_elev(altitude) except mapper.NotAnAltitude,cause: ret.append(['','']) continue #skip this alt #N+1 selects.... merc1=mapper.latlon2merc(mapper.from_str(route.a.pos),14) merc2=mapper.latlon2merc(mapper.from_str(route.a.pos),14) center=(0.5*(merc1[0]+merc2[0]),0.5*(merc1[1]+merc2[1])) lat,lon=mapper.merc2latlon(center,14) #print "Fetching weather for %s,%s, %s"%(lat,lon,route.altitude) when=route.depart_dt+(route.arrive_dt-route.depart_dt)/2 dummy1,dummy2,we=gfs_weather.get_prognosis(when) if we==None: return ""; #Fail completely we don't have the weather here. We only succeed if we have weather for all parts of the journey. else: try: wi=we.get_wind(lat,lon,mapper.parse_elev(altitude)) except: print traceback.format_exc() return "" #print "Got winds:",wi ret.append([wi['direction'],wi['knots']])
def load_recording(rec): # print "Rec.trip type:",type(rec.trip) path = decode_flightpath(str(rec.trip), rec.version) dynamic_id = md5(rec.trip).hexdigest() out = Track() out.points = [] maxlat = -1000 maxlon = -1000 minlat = 1000 minlon = 1000 laststamp = None numpoints = path["path"] le = len(numpoints) cutoff = le / 2 for idx, (pos, stamp, altitude) in enumerate(path["path"]): lat, lon = mapper.merc2latlon(pos, 17) maxlat = max(maxlat, lat) minlat = min(minlat, lat) maxlon = max(maxlon, lon) minlon = min(minlon, lon) if laststamp == None or stamp - laststamp > cutoff or idx == le - 1: out.points.append(((lat, lon), altitude * 0.3048, datetime.utcfromtimestamp(stamp / 1000.0))) laststamp = stamp print "Took %d points" % (len(out.points),) out.bb1 = (maxlat, minlon) out.bb2 = (minlat, maxlon) out.dynamic_id = dynamic_id return out
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 set_pos_zoom(self, latlon=None, zoom=None): #print "Setting pos to %s"%(latlon,) if latlon == None: assert zoom == None zoomlevel = session.get('zoom', None) if zoomlevel == None: zoomlevel = 5 merc_x, merc_y = mapper.latlon2merc((58, 18), zoomlevel) else: merc_x, merc_y = session['last_pos'] else: assert zoom != None zoomlevel = zoom if zoomlevel < 5: zoomlevel = 5 if session.get('mapvariant', None) == 'elev': if zoomlevel > 8: zoomlevel = 8 else: if zoomlevel > 13: zoomlevel = 13 merc_x, merc_y = mapper.latlon2merc(latlon, zoomlevel) merc_limx1, merc_limy1, merc_limx2, merc_limy2 = merc_limits( zoomlevel, conservative=False, hd=True) if merc_x > merc_limx2: merc_x = merc_limx2 if merc_y > merc_limy2: merc_y = merc_limy2 if merc_x < merc_limx1: merc_x = merc_limx1 if merc_y < merc_limy1: merc_y = merc_limy1 session['last_pos'] = (merc_x, merc_y) session['zoom'] = zoomlevel print "Setting pos to %s, zoom = %d" % (mapper.merc2latlon( session['last_pos'], zoomlevel), zoomlevel) session.save()
def set_pos_zoom(self,latlon=None,zoom=None): #print "Setting pos to %s"%(latlon,) if latlon==None: assert zoom==None zoomlevel=session.get('zoom',None) if zoomlevel==None: zoomlevel=5 merc_x,merc_y=mapper.latlon2merc((58,18),zoomlevel) else: merc_x,merc_y=session['last_pos'] else: assert zoom!=None zoomlevel=zoom if zoomlevel<5: zoomlevel=5 if session.get('mapvariant',None)=='elev': if zoomlevel>8: zoomlevel=8 else: if zoomlevel>13: zoomlevel=13 merc_x,merc_y=mapper.latlon2merc(latlon,zoomlevel) merc_limx1,merc_limy1,merc_limx2,merc_limy2=merc_limits(zoomlevel,conservative=False,hd=True) if merc_x>merc_limx2: merc_x=merc_limx2 if merc_y>merc_limy2: merc_y=merc_limy2 if merc_x<merc_limx1: merc_x=merc_limx1 if merc_y<merc_limy1: merc_y=merc_limy1 session['last_pos']=(merc_x,merc_y) session['zoom']=zoomlevel print "Setting pos to %s, zoom = %d"%(mapper.merc2latlon(session['last_pos'],zoomlevel),zoomlevel) session.save()
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 load_recording(rec): #print "Rec.trip type:",type(rec.trip) path = decode_flightpath(str(rec.trip), rec.version) dynamic_id = md5(rec.trip).hexdigest() out = Track() out.points = [] maxlat = -1000 maxlon = -1000 minlat = 1000 minlon = 1000 laststamp = None numpoints = path['path'] le = len(numpoints) cutoff = le / 2 for idx, (pos, stamp, altitude) in enumerate(path['path']): lat, lon = mapper.merc2latlon(pos, 17) maxlat = max(maxlat, lat) minlat = min(minlat, lat) maxlon = max(maxlon, lon) minlon = min(minlon, lon) if laststamp == None or stamp - laststamp > cutoff or idx == le - 1: out.points.append(((lat, lon), altitude * 0.3048, datetime.utcfromtimestamp(stamp / 1000.0))) laststamp = stamp print "Took %d points" % (len(out.points), ) out.bb1 = (maxlat, minlon) out.bb2 = (minlat, maxlon) out.dynamic_id = dynamic_id return out
def follow_along(context, start, end, longwayround=False): out = [] for merc in follow_along13(context, mapper.latlon2merc(start, 13), mapper.latlon2merc(end, 13), longwayround=longwayround): out.append(mapper.merc2latlon(merc, 13)) return out
def generate_tile(pixelsize, x1, y1, zoomlevel): print "Making tile at %s/%s, zoomlevel: %d" % (x1, y1, zoomlevel) #print "Generating tile" mapfile = os.path.join(os.getenv("SWFP_DATADIR"), "mapnik_render/osm.xml") #--------------------------------------------------- # Change this to the bounding box you want # # lon lat lon lat #ll = (center[1], hilat, center[1], lolat) #--------------------------------------------------- meta = 50 imgx, imgy = pixelsize mapx = imgx + 2 * meta mapy = imgy + 2 * meta lat1, lon1 = mapper.merc2latlon((x1 - meta, y1 - meta), zoomlevel) lat2, lon2 = mapper.merc2latlon((x1 + imgx + meta, y1 + imgy + meta), zoomlevel) m = mapnik.Map(mapx, mapy) mapnik.load_map(m, mapfile) c0 = prj.forward(mapnik.Coord(lon1, lat1)) c1 = prj.forward(mapnik.Coord(lon2, lat2)) if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: #bbox = mapnik.Box2d(0,0,256<<zoomlevel,256<<zoomlevel) bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) #bbox = mapnik.Envelope(0,0,256<<zoomlevel,256<<zoomlevel) m.zoom_to_box(bbox) im = mapnik.Image(mapx, mapy) mapnik.render(m, im) view = im.view(meta, meta, imgx, imgy) # x,y,width,height temphandle, temppath = tempfile.mkstemp(suffix="fplantile") try: os.close(temphandle) view.save(temppath, 'png') data = open(temppath).read() finally: os.unlink(temppath) print "Tile complete" return data
def generate_tile(pixelsize,x1,y1,zoomlevel): print "Making tile at %s/%s, zoomlevel: %d"%(x1,y1,zoomlevel) #print "Generating tile" mapfile = os.path.join(os.getenv("SWFP_DATADIR"),"mapnik_render/osm.xml") #--------------------------------------------------- # Change this to the bounding box you want # # lon lat lon lat #ll = (center[1], hilat, center[1], lolat) #--------------------------------------------------- meta=50 imgx,imgy=pixelsize mapx=imgx+2*meta mapy=imgy+2*meta lat1,lon1=mapper.merc2latlon((x1-meta,y1-meta),zoomlevel) lat2,lon2=mapper.merc2latlon((x1+imgx+meta,y1+imgy+meta),zoomlevel) m = mapnik.Map(mapx,mapy) mapnik.load_map(m,mapfile) c0 = prj.forward(mapnik.Coord(lon1,lat1)) c1 = prj.forward(mapnik.Coord(lon2,lat2)) if hasattr(mapnik,'mapnik_version') and mapnik.mapnik_version() >= 800: #bbox = mapnik.Box2d(0,0,256<<zoomlevel,256<<zoomlevel) bbox = mapnik.Box2d(c0.x,c0.y,c1.x,c1.y) else: bbox = mapnik.Envelope(c0.x,c0.y,c1.x,c1.y) #bbox = mapnik.Envelope(0,0,256<<zoomlevel,256<<zoomlevel) m.zoom_to_box(bbox) im = mapnik.Image(mapx,mapy) mapnik.render(m, im) view = im.view(meta,meta,imgx,imgy) # x,y,width,height temphandle,temppath=tempfile.mkstemp(suffix="fplantile") try: os.close(temphandle) view.save(temppath,'png') data=open(temppath).read() finally: os.unlink(temppath) print "Tile complete" return data
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 run(path): f = open(path) lines = list(f) calib = None for line in lines: if line.strip() == "": continue name, coords = parse_line(line) if name.count("(") == 1 and name.count(")") == 1: #print "Calib:",name,coords assert calib == None #only one calibration line per file, please dummy, rest = name.split("(") assert rest.endswith(")") rest = rest[:-1] geo_points = [] for c_str in rest.split("-"): geo_point = [] for comp_str in c_str.split(","): geo_point.append(float(comp_str.strip())) geo_points.append( tuple( mapper.latlon2merc((geo_point[0], geo_point[1]), zoomlevel))) assert len(geo_points) == 2 #print "Geo_points:",geo_points #print "Coords:",coords geo_dist = vec_len(vec_sub(*geo_points)) coord_dist = vec_len(vec_sub(*coords)) geo_angle = get_angle(vec_sub(geo_points[1], geo_points[0])) coord_angle = get_angle(vec_sub(coords[1], coords[0])) ##print "Geo angle: %f"%(geo_angle*180.0/math.pi) #print "Coord angle: %f"%(coord_angle*180.0/math.pi) coord_offset = vec_sub(geo_points[0], coords[0]) calib = dict(center_coord=coords[0], center_geo_points=geo_points[0], rotate=geo_angle - coord_angle, scale=float(geo_dist) / float(coord_dist)) assert calib != None #print calib ret = dict() for line in lines: if line.strip() == "": continue name, coords = parse_line(line) #if name.count("(")!=1 or name.count(")")!=1: geo_points = [] for cd in coords: geo_points.append(fixup(cd, calib)) ret[name] = [mapper.merc2latlon(c, zoomlevel) for c in geo_points] #print "Coords: %s, geo points: %s"%(coords,geo_points) #print name,":","; ".join(format_latlon(mapper.merc2latlon(c,zoomlevel)) for c in geo_points) return ret
def run(path): f=open(path) lines=list(f) calib=None for line in lines: if line.strip()=="": continue name,coords=parse_line(line) if name.count("(")==1 and name.count(")")==1: #print "Calib:",name,coords assert calib==None #only one calibration line per file, please dummy,rest=name.split("(") assert rest.endswith(")") rest=rest[:-1] geo_points=[] for c_str in rest.split("-"): geo_point=[] for comp_str in c_str.split(","): geo_point.append(float(comp_str.strip())) geo_points.append(tuple(mapper.latlon2merc((geo_point[0],geo_point[1]),zoomlevel))) assert len(geo_points)==2 #print "Geo_points:",geo_points #print "Coords:",coords geo_dist=vec_len(vec_sub(*geo_points)) coord_dist=vec_len(vec_sub(*coords)) geo_angle=get_angle(vec_sub(geo_points[1],geo_points[0])) coord_angle=get_angle(vec_sub(coords[1],coords[0])) ##print "Geo angle: %f"%(geo_angle*180.0/math.pi) #print "Coord angle: %f"%(coord_angle*180.0/math.pi) coord_offset=vec_sub(geo_points[0],coords[0]) calib=dict( center_coord=coords[0], center_geo_points=geo_points[0], rotate=geo_angle-coord_angle, scale=float(geo_dist)/float(coord_dist)) assert calib!=None #print calib ret=dict() for line in lines: if line.strip()=="": continue name,coords=parse_line(line) #if name.count("(")!=1 or name.count(")")!=1: geo_points=[] for cd in coords: geo_points.append(fixup(cd,calib)) ret[name]=[mapper.merc2latlon(c,zoomlevel) for c in geo_points] #print "Coords: %s, geo points: %s"%(coords,geo_points) #print name,":","; ".join(format_latlon(mapper.merc2latlon(c,zoomlevel)) for c in geo_points) return ret
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 create_merc_elevmap(dest): zoomlevel = 8 limitx1, limity1, limitx2, limity2 = merc_limits(zoomlevel, hd=True) tilesizemask = tilesize - 1 #a,b=mapper.latlon2merc((61,15),zoomlevel) #limitx1,limity1=int(a),int(b) #limity1=int(19000) #limity2=limity1+tilesize*16 #limitx1=int(35000) #limitx2=limitx1+tilesize*16 #tilesizemask=tilesize-1 #limitx1&=~tilesizemask #limity1&=~tilesizemask #limitx2&=~tilesizemask #limity2&=~tilesizemask assert (limitx1 & tilesizemask) == 0 assert (limity1 & tilesizemask) == 0 assert (limitx2 & tilesizemask) == 0 assert (limity2 & tilesizemask) == 0 if os.path.exists(dest): os.unlink(dest) blob = BlobFile(dest, zoomlevel, limitx1, limity1, limitx2, limity2, "w", tilesize=tilesize) for by in xrange(limity1, limity2, tilesize): for bx in xrange(limitx1, limitx2, tilesize): f = StringIO() for y in xrange(tilesize): for x in xrange(tilesize): mx = bx + x my = by + y latlon = mapper.merc2latlon((mx, my), zoomlevel) elev = int(get_terrain_elev(latlon)) #f.write(pack(">h",elev)) #min f.write(pack(">h", elev)) #max buf = f.getvalue() assert (len(buf) == tilesize * tilesize * 2) blob.add_tile(bx, by, buf) print "Perc complete: %.1f%%" % (100.0 * (by - limity1) / float(limity2 - limity1)) blob.close()
def invent_matrix(self,cksum,variant): print "Variant:",variant for ad in ec.get_airfields(): if not 'adcharts' in ad: continue dbb=False for adchart in ad['adcharts'].values(): if adchart['checksum']==cksum: lat,lon=mapper.from_str(ad['pos']) w,h=adchart['render_width'],adchart['render_height'] print "adpos:",ad['pos'],lat,lon dbb=True break if dbb:break else: raise Exception("Can't find this chart in aipdata") if variant.lower().count('vac'): mercsizex=w mercsizey=h scale=7 else: mercsizex=w mercsizey=h scale=1 print "lat,lon",lat,lon m1=mapper.latlon2merc((lat,lon),13) print "corner merc",m1 ns=[] for offx,offy in [(0,0), (mercsizex,0), (0,mercsizey), (mercsizex,mercsizey)]: merc2=(m1[0]+(offx-mercsizex/2)*scale,m1[1]+(offy-mercsizey/2)*scale) n=AirportMarker() n.latitude,n.longitude=mapper.merc2latlon(merc2,13) n.x,n.y=(offx,offy) ns.append(n) error,A,T=customproj.solve(ns) matrix=list(A)+list(T) print "Fake projection:",matrix return matrix
def invent_matrix(self, cksum, variant): print "Variant:", variant for ad in ec.get_airfields(): if not 'adcharts' in ad: continue dbb = False for adchart in ad['adcharts'].values(): if adchart['checksum'] == cksum: lat, lon = mapper.from_str(ad['pos']) w, h = adchart['render_width'], adchart['render_height'] print "adpos:", ad['pos'], lat, lon dbb = True break if dbb: break else: raise Exception("Can't find this chart in aipdata") if variant.lower().count('vac'): mercsizex = w mercsizey = h scale = 7 else: mercsizex = w mercsizey = h scale = 1 print "lat,lon", lat, lon m1 = mapper.latlon2merc((lat, lon), 13) print "corner merc", m1 ns = [] for offx, offy in [(0, 0), (mercsizex, 0), (0, mercsizey), (mercsizex, mercsizey)]: merc2 = (m1[0] + (offx - mercsizex / 2) * scale, m1[1] + (offy - mercsizey / 2) * scale) n = AirportMarker() n.latitude, n.longitude = mapper.merc2latlon(merc2, 13) n.x, n.y = (offx, offy) ns.append(n) error, A, T = customproj.solve(ns) matrix = list(A) + list(T) print "Fake projection:", matrix return matrix
def create_merc_elevmap(dest): zoomlevel = 8 limitx1, limity1, limitx2, limity2 = merc_limits(zoomlevel, hd=True) tilesizemask = tilesize - 1 # a,b=mapper.latlon2merc((61,15),zoomlevel) # limitx1,limity1=int(a),int(b) # limity1=int(19000) # limity2=limity1+tilesize*16 # limitx1=int(35000) # limitx2=limitx1+tilesize*16 # tilesizemask=tilesize-1 # limitx1&=~tilesizemask # limity1&=~tilesizemask # limitx2&=~tilesizemask # limity2&=~tilesizemask assert (limitx1 & tilesizemask) == 0 assert (limity1 & tilesizemask) == 0 assert (limitx2 & tilesizemask) == 0 assert (limity2 & tilesizemask) == 0 if os.path.exists(dest): os.unlink(dest) blob = BlobFile(dest, zoomlevel, limitx1, limity1, limitx2, limity2, "w", tilesize=tilesize) for by in xrange(limity1, limity2, tilesize): for bx in xrange(limitx1, limitx2, tilesize): f = StringIO() for y in xrange(tilesize): for x in xrange(tilesize): mx = bx + x my = by + y latlon = mapper.merc2latlon((mx, my), zoomlevel) elev = int(get_terrain_elev(latlon)) # f.write(pack(">h",elev)) #min f.write(pack(">h", elev)) # max buf = f.getvalue() assert len(buf) == tilesize * tilesize * 2 blob.add_tile(bx, by, buf) print "Perc complete: %.1f%%" % (100.0 * (by - limity1) / float(limity2 - limity1)) blob.close()
def cleanup_poly(latlonpoints, name="?"): for minstep in [0, 10, 100, 1000, 10000, 100000]: mercpoints = [] lastmerc = None for latlon in latlonpoints: merc = mapper.latlon2merc(latlon, 13) if lastmerc != None: dist = math.sqrt( sum([(lastmerc[i] - merc[i])**2 for i in xrange(2)])) if dist < minstep: continue if merc == lastmerc: continue lastmerc = merc mercpoints.append(Vertex(int(merc[0]), int(merc[1]))) if len(mercpoints) < 50: break if len(mercpoints) <= 2: return None if mercpoints[0] == mercpoints[-1]: del mercpoints[-1] if len(mercpoints) <= 2: return None poly = Polygon(vvector(mercpoints)) if len(mercpoints) == 4: swapped = [mercpoints[1], mercpoints[0]] + mercpoints[2:] swappedpoly = Polygon(vvector(swapped)) #print "Found 4-corner area: ",name," areas:",swappedpoly.calc_area(),poly.calc_area() if abs(swappedpoly.calc_area()) > abs(1.1 * poly.calc_area()): print "Untwisting an area", name mercpoints = swapped poly = swappedpoly backtomerc = [ mapper.merc2latlon((m.get_x(), m.get_y()), 13) for m in mercpoints ] if poly.is_ccw(): return backtomerc else: #print "Reversed "+latlonpoints return reversed(backtomerc)
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 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 cleanup_poly(latlonpoints,name="?"): for minstep in [0,10,100,1000,10000,100000]: mercpoints=[] lastmerc=None for latlon in latlonpoints: merc=mapper.latlon2merc(latlon,13) if lastmerc!=None: dist=math.sqrt(sum([(lastmerc[i]-merc[i])**2 for i in xrange(2)])) if dist<minstep: continue if merc==lastmerc: continue lastmerc=merc mercpoints.append(Vertex(int(merc[0]),int(merc[1]))) if len(mercpoints)<50: break if len(mercpoints)<=2: return None if mercpoints[0]==mercpoints[-1]: del mercpoints[-1] if len(mercpoints)<=2: return None poly=Polygon(vvector(mercpoints)) if len(mercpoints)==4: swapped=[mercpoints[1],mercpoints[0]]+mercpoints[2:] swappedpoly=Polygon(vvector(swapped)) #print "Found 4-corner area: ",name," areas:",swappedpoly.calc_area(),poly.calc_area() if abs(swappedpoly.calc_area())>abs(1.1*poly.calc_area()): print "Untwisting an area",name mercpoints=swapped poly=swappedpoly backtomerc=[mapper.merc2latlon((m.get_x(),m.get_y()),13) for m in mercpoints] if poly.is_ccw(): return backtomerc else: #print "Reversed "+latlonpoints return reversed(backtomerc)
def getdist_meter(p1, p2): brg, dist = mapper.bearing_and_distance( mapper.merc2latlon(p1, 20), mapper.merc2latlon(p2, 20)) return dist * 1852.0
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 getdist_meter(p1,p2): brg,dist=mapper.bearing_and_distance(mapper.merc2latlon(p1,20),mapper.merc2latlon(p2,20)) return dist*1852.0
def zoom(self): print "zoom called" #user=meta.Session.query(User).filter( # User.user==tripuser()).one() if request.params['zoom']=='auto': if session.get('showarea','')!='': zoom=13 minx=1e30 maxx=-1e30 miny=1e30 maxy=-1e30 for vert in mapper.parse_lfv_area(session.get('showarea')): merc=mapper.latlon2merc(mapper.from_str(vert),zoom) minx=min(minx,merc[0]) miny=min(miny,merc[1]) maxx=max(maxx,merc[0]) maxy=max(maxy,merc[1]) if maxy<-1e29: self.set_pos_zoom((59,18),6,) else: size=max(maxx-minx,maxy-miny) if (maxx==minx and maxy==miny): zoom=10 else: nominal_size=400 while zoom>=0 and size>nominal_size: zoom-=1 size/=2.0 pos=(int(0.5*(maxx+minx)),int(0.5*(maxy+miny))) latlon=mapper.merc2latlon(pos,13) self.set_pos_zoom(latlon,zoom) elif session.get('showtrack',None)!=None: strack=session.get('showtrack') zoom=13 minx,miny=mapper.latlon2merc(strack.bb1,13) maxx,maxy=mapper.latlon2merc(strack.bb2,13) pos=(int(0.5*(maxx+minx)),int(0.5*(maxy+miny))) latlon=mapper.merc2latlon(pos,13) print "AutoZooming to pos",latlon size=max(maxx-minx,maxy-miny,1) nominal_size=400 while zoom>=0 and size>nominal_size: zoom-=1 size/=2.0 self.set_pos_zoom(latlon,zoom) else: #mapper.parse_lfv_area() self.set_pos_zoom((59,18),6) print "Autozoom zooming to level %d at %s"%(session['zoom'],session['last_pos']) else: zoomlevel=float(request.params['zoom']) if zoomlevel<0: zoomlevel=0 pos=mapper.merc2latlon(tuple([int(x) for x in request.params['center'].split(",")]),zoomlevel) if session.get('mapvariant',None)=='elev': if zoomlevel>8: zoomlevel=8 else: if zoomlevel>13: zoomlevel=13 print "Zoomlevel: %s"%(zoomlevel,) print "Pos:",pos self.set_pos_zoom(pos,zoomlevel) redirect(h.url_for(controller='mapview',action="index"))
def index(self): print "Index called", session.get('zoom',-1) #print "index called",request.params #user=meta.Session.query(User).filter( # User.user==tripuser()).one() user=meta.Session.query(User).filter( User.user==session['user']).one() ua=request.headers.get('User-Agent','').lower() c.ie=False if ua.count("msie") and not (ua.count("firefox") or ua.count("chrom") or ua.count("safari")): c.ie=True #print "IE mode:",c.ie c.all_trips=list(meta.Session.query(Trip).filter(Trip.user==session['user']).all()) print "current trip:",session.get('current_trip',None) if not ('current_trip' in session) or session['current_trip']==None: if user.lasttrip!=None: print "Reusing lasttrip:",user.lasttrip session['current_trip']=user.lasttrip if 'current_trip' in session and meta.Session.query(Trip).filter(sa.and_( Trip.user==tripuser(), Trip.trip==session['current_trip'] )).count()==0: session['current_trip']=None if not 'current_trip' in session or session['current_trip']==None: trips=meta.Session.query(Trip).filter( Trip.user==tripuser()).all() if len(trips)==0: trip = Trip(tripuser(), "Default Trip") meta.Session.add(trip) meta.Session.flush() meta.Session.commit() else: trip=min(trips,key=lambda x:x.trip) #Select first trip, alphabetically - we have no better idea. session['current_trip']=trip.trip session.save() trip=None if session.get('current_trip',None)!=user.lasttrip: user.lasttrip=session.get('current_trip',None) print "Storing lasttrip=",user.lasttrip meta.Session.flush() meta.Session.commit() c.mapvariant=session.get('mapvariant',"airspace") self.set_pos_zoom() zoomlevel=session['zoom'] if c.mapvariant=="elev": if zoomlevel>8: session['zoom']=8 session.save() try: session['last_pos']=mapper.latlon2merc(mapper.merc2latlon(session['last_pos'],zoomlevel),8) except Exception: session['last_pos']=mapper.latlon2merc((59,18),8) print "Setting session last pos to 59,18",session['last_pos'] zoomlevel=8 print "Last pos is:",mapper.merc2latlon(session['last_pos'],zoomlevel) c.merc_x,c.merc_y=session['last_pos'] c.merc5_limx1,c.merc5_limy1,c.merc5_limx2,c.merc5_limy2=merc_limits(5,conservative=False,hd=True) c.waypoints=list(meta.Session.query(Waypoint).filter(sa.and_( Waypoint.user==tripuser(),Waypoint.trip==session['current_trip'])).order_by(Waypoint.ordering).all()) c.tripname=session['current_trip'] c.showarea=session.get('showarea','') c.showtrack=session.get('showtrack',None)!=None c.fastmap=user.fastmap; #print "Zoomlevel active: ",zoomlevel c.zoomlevel=zoomlevel c.dynamic_id='' c.sharing=tripsharing.sharing_active() c.mtime=maptilereader.get_mtime() for way in c.waypoints: print "Name:",way.waypoint if len(c.waypoints): c.next_waypoint_id=max([way.id for way in c.waypoints])+1 else: c.next_waypoint_id=100 assert type(c.next_waypoint_id)==int if c.sharing: c.shared_by=tripuser() if session.get('showarea',''): c.dynamic_id=session.get('showarea_id','') if session.get('showtrack',''): if hasattr(session['showtrack'],'dynamic_id'): c.dynamic_id=session['showtrack'].dynamic_id return render('/mapview.mako')
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
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 show(self): ad=request.params['ad'] cksum=request.params['checksum'] chartobj=None for adobj in ec.get_airfields(): bb=False if adobj['name']==ad and 'adcharts' in adobj: for adchart in adobj['adcharts'].values(): if adchart['checksum']==cksum: chartobj=adchart bb=True break if bb: break else: self.error("No such airport/picture "+ad+"/"+cksum) projs=meta.Session.query(AirportProjection).filter(sa.and_( AirportProjection.user==session['user'], AirportProjection.airport==ad, AirportProjection.mapchecksum==adchart['checksum'])).all() c.markers=meta.Session.query(AirportMarker).filter(sa.and_( AirportMarker.user==session['user'], AirportMarker.airport==ad, AirportMarker.mapchecksum==adchart['checksum'])).order_by(AirportMarker.latitude,AirportMarker.longitude,AirportMarker.x,AirportMarker.y).all() if not projs: proj=AirportProjection() proj.user=session['user'] proj.airport=ad proj.mapchecksum=str(adchart['checksum']) proj.updated=datetime.utcnow() proj.matrix=(1,0,0,1,0,0) proj.scale=None proj.north=None meta.Session.add(proj) meta.Session.flush() meta.Session.commit() else: proj,=projs proj.mapchecksum=str(proj.mapchecksum) if all([x==0 for x in proj.matrix[4:6]]): projmatrix=self.invent_matrix(proj.mapchecksum,adchart['variant']) else: projmatrix=proj.matrix A=projmatrix[0:4] T=projmatrix[4:6] transform=customproj.Transform(A,T) c.matrix=projmatrix c.initial_scroll_x=request.params.get("scroll_x",0) c.initial_scroll_y=request.params.get("scroll_y",0) c.maptype=request.params.get("maptype","chart") c.variant=adchart['variant'] c.curadmarker=session.get('curadmarker',(0,0)) c.img=adchart['blobname']+","+adchart['checksum'] c.flash=None c.ad=ad c.mapchecksum=adchart['checksum'] c.mapsize=adchart.get('mapsize',(210,297)) c.scale=proj.scale if proj.scale!=None else "" c.north=proj.north if proj.north!=None else "" c.runways=[] c.arp=transform.to_pixels(mapper.from_str(adobj['pos'])) arp1m=mapper.latlon2merc(mapper.from_str(adobj['pos']),17) arp2m=mapper.latlon2merc(mapper.from_str(adobj['pos']),17) arp1m=(arp1m[0],arp1m[1]-250) arp2m=(arp2m[0]+250,arp2m[1]) c.arp1=transform.to_pixels(mapper.merc2latlon(arp1m,17)) c.arp2=transform.to_pixels(mapper.merc2latlon(arp2m,17)) def dist(x,y): return math.sqrt((x[0]-y[0])**2+(x[1]-y[1])**2) c.ratio=abs(dist(c.arp,c.arp1)-dist(c.arp,c.arp2))/max(dist(c.arp,c.arp1),dist(c.arp,c.arp2)); c.transform_reasonable=True x,y=c.arp if x<-200 or y<-200 or x>=4000 or y>=4000: c.transform_reasonable=False c.revmarkers=[] c.width,c.height=chartobj['render_width'],chartobj['render_height'] try: c.base_coords=\ [mapper.latlon2merc(transform.to_latlon((0,0)),13), mapper.latlon2merc(transform.to_latlon((c.width,0)),13), mapper.latlon2merc(transform.to_latlon((0,c.height)),13), mapper.latlon2merc(transform.to_latlon((c.width,c.height)),13)] except Exception: print "problem with basecoords:",traceback.format_exc() c.base_coords=[(0,0) for x in xrange(4)] for mark in c.markers: lat,lon=transform.to_latlon((mark.x,mark.y)) if mark.latitude: lat=mark.latitude if mark.longitude: lon=mark.longitude pos=transform.to_pixels((lat,lon)) c.revmarkers.append(pos) for rwy in adobj.get('runways',[]): ends=rwy['ends'] latlon1=mapper.from_str(ends[0]['pos']) latlon2=mapper.from_str(ends[1]['pos']) print rwy,"Runway pos",latlon1," to ",latlon2 p1=transform.to_pixels(latlon1) p2=transform.to_pixels(latlon2) for p in [p1,p2]: x,y=p if x<-200 or y<-200 or x>=4000 or y>=4000: c.transform_reasonable=False c.runways.append(( (int(p1[0]),int(p1[1])), (int(p2[0]),int(p2[1])) )) c.random=md5.md5(pickle.dumps(projmatrix)).hexdigest() return render('/airportproj.mako')
def save(self): print request.params ad=request.params['ad'] chartobj=None mapchecksum=request.params['mapchecksum'] for adobj in ec.get_airfields(): if adobj['name']==ad: bb=False for adchart in adobj['adcharts'].values(): if adchart['checksum']==mapchecksum: chartobj=adchart bb=True break if bb: break else: self.error("No such airport"+ad) marks=dict() for param,val in request.params.items(): if param in ["save","ad",'mapchecksum','scroll_x','scroll_y','maptype','scale','north']: continue if param.startswith("del"): continue if param.startswith("set_"): x,y=[int(v) for v in param.split("_")[1:]] session['curadmarker']=(x,y) session.save() continue if param=="add": xs=meta.Session.query(AirportMarker.x).filter(sa.and_( AirportMarker.user==session['user'], AirportMarker.airport==ad )).all() if xs: maxx=max(xs)[0]+1 else: maxx=0 marks[(maxx,0)]=dict(latitude=None,longitude=None,x=maxx,y=0) session['curadmarker']=(maxx,0) session.save() continue sx,sy,attrib=re.match(ur"mark_(\d+)_(\d+)_(\w*)",param).groups() x=int(sx) y=int(sy) marks.setdefault((x,y),dict())[attrib]=val thresholds=dict() for rwy in adobj.get('runways',[]): ends=rwy['ends'] for end in ends: thresholds[end['thr']]=mapper.from_str(end['pos']) for param,val in request.params.items(): if param.startswith("del_"): x,y=[int(v) for v in param.split("_")[1:]] marks.pop((x,y)) continue meta.Session.query(AirportMarker).filter(sa.and_( AirportMarker.user==session['user'], AirportMarker.airport==ad)).delete() ms=[] arppos=mapper.from_str(adobj['pos']) for (x,y),val in marks.items(): m=AirportMarker() m.user=session['user'] m.airport=ad m.mapchecksum=str(mapchecksum) m.x=int(val['x']) m.y=int(val['y']) m.latitude,w1=parselatlon(val['latitude'],arppos,thresholds,0) m.longitude,w2=parselatlon(val['longitude'],arppos,thresholds,1) if w1 or w2: m.weight=w1+w2 else: m.weigth=1 meta.Session.add(m) ms.append(m) proj=meta.Session.query(AirportProjection).filter(sa.and_( AirportProjection.user==session['user'], AirportProjection.airport==ad, AirportProjection.mapchecksum==str(mapchecksum))).one() try: proj.scale=float(request.params['scale'].strip()) except: proj.scale=None try: proj.north=float(request.params['north'].strip()) except: proj.north=None def both_lat_lon(x): return x.latitude and x.longitude def neither_lat_lon(x): return not x.latitude and not x.longitude def just_lat(x): return x.latitude and not x.longitude def just_lon(x): return not x.latitude and x.longitude ms=[m for m in ms if not neither_lat_lon(m)] """ if (len(ms)==4 and len([m for m in ms if just_lat(m)])==2 and len([m for m in ms if just_lon(m)])==2): extra=[] for m in ms: n=AirportMarker() n.x=m.x n.y=m.y if just_lat(m): n.latitude=m.latitude n.x+=1000 extra.append(n) if just_lon(m): n.y+=1000 n.longitude=m.longitude extra.append(n) ms.extend(extra) """ if len(ms)==1 and both_lat_lon(ms[0]) and proj.scale and proj.north!=None: print "Scale/north triggered" print "Adchart:",chartobj if chartobj!=None: render_height=chartobj['render_height'] mark,=ms pixelpos=(mark.x,mark.y) mapsize=adchart.get('mapsize',(210,297)) mapheight_meter=mapsize[1]/1000.0 * proj.scale mapheight_km=mapheight_meter/1000.0 merc=mapper.latlon2merc((mark.latitude,mark.longitude),17) pixels=mapper.approx_scale(merc,17,mapheight_km/1.852) newmerc=(merc[0],merc[1]-pixels) northrad=proj.north/(180.0/math.pi) newpixelpos=(pixelpos[0]+render_height*math.sin(northrad), pixelpos[1]-render_height*math.cos(northrad)) m=AirportMarker() m.x=newpixelpos[0] m.y=newpixelpos[1] latlon=mapper.merc2latlon(newmerc,17) m.latitude=latlon[0] m.longitude=latlon[1] m.weight=1 ms.append(m) if len(ms)==2 and all(both_lat_lon(x) for x in ms): print "Have exactly two marks now" mark1,mark2=ms lm1,lm2=[mapper.latlon2merc((mark.latitude,mark.longitude),17) for mark in [mark1,mark2]] ld=(lm2[0]-lm1[0],lm2[1]-lm1[1]) pd=(mark2.x-mark1.x,mark2.y-mark1.y) lm3=(lm1[0]-ld[1],lm1[1]+ld[0]) pm3=(mark1.x-pd[1],mark1.y+pd[0]) llm3=mapper.merc2latlon(lm3,17) m=AirportMarker() m.x=pm3[0] m.y=pm3[1] m.latitude,w1=llm3[0],1 m.longitude,w2=llm3[1],1 ms.append(m) print "delta pixels",pd print "delta latlon",ld print "extra end pixels",m.x,m.y print "extra end latlon",m.latitude,m.longitude eqns=0 for m in ms: if both_lat_lon(m): eqns+=2 elif just_lat(m): eqns+=1 elif just_lon(m): eqns+=1 try: if eqns<4: raise Exception("Unsolvable") error,A,T=customproj.solve(ms) matrix=list(A)+list(T) if proj.matrix: oldmatrix=list(proj.matrix) newmatrix=list(A)+list(T) diff=sum(abs(a-b) for a,b in zip(oldmatrix,newmatrix)) else: diff=1e30 #enough to trigger update if diff>1e-12: proj.matrix=tuple(newmatrix) proj.updated=datetime.utcnow().replace(microsecond=0) except Exception,cause: print "Couldn't solve projection equation %s"%(cause,) proj.matrix=[1,0,0,1,0,0] proj.updated=datetime.utcnow().replace(microsecond=0) meta.Session.add(proj)
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 index(self): print "Index called", session.get('zoom', -1) #print "index called",request.params #user=meta.Session.query(User).filter( # User.user==tripuser()).one() user = meta.Session.query(User).filter( User.user == session['user']).one() ua = request.headers.get('User-Agent', '').lower() c.ie = False if ua.count("msie") and not (ua.count("firefox") or ua.count("chrom") or ua.count("safari")): c.ie = True #print "IE mode:",c.ie c.all_trips = list( meta.Session.query(Trip).filter( Trip.user == session['user']).all()) print "current trip:", session.get('current_trip', None) if not ('current_trip' in session) or session['current_trip'] == None: if user.lasttrip != None: print "Reusing lasttrip:", user.lasttrip session['current_trip'] = user.lasttrip if 'current_trip' in session and meta.Session.query(Trip).filter( sa.and_(Trip.user == tripuser(), Trip.trip == session['current_trip'])).count() == 0: session['current_trip'] = None if not 'current_trip' in session or session['current_trip'] == None: trips = meta.Session.query(Trip).filter( Trip.user == tripuser()).all() if len(trips) == 0: trip = Trip(tripuser(), "Default Trip") meta.Session.add(trip) meta.Session.flush() meta.Session.commit() else: trip = min( trips, key=lambda x: x.trip ) #Select first trip, alphabetically - we have no better idea. session['current_trip'] = trip.trip session.save() trip = None if session.get('current_trip', None) != user.lasttrip: user.lasttrip = session.get('current_trip', None) print "Storing lasttrip=", user.lasttrip meta.Session.flush() meta.Session.commit() c.mapvariant = session.get('mapvariant', "airspace") self.set_pos_zoom() zoomlevel = session['zoom'] if c.mapvariant == "elev": if zoomlevel > 8: session['zoom'] = 8 session.save() try: session['last_pos'] = mapper.latlon2merc( mapper.merc2latlon(session['last_pos'], zoomlevel), 8) except Exception: session['last_pos'] = mapper.latlon2merc((59, 18), 8) print "Setting session last pos to 59,18", session[ 'last_pos'] zoomlevel = 8 print "Last pos is:", mapper.merc2latlon(session['last_pos'], zoomlevel) c.merc_x, c.merc_y = session['last_pos'] c.merc5_limx1, c.merc5_limy1, c.merc5_limx2, c.merc5_limy2 = merc_limits( 5, conservative=False, hd=True) c.waypoints = list( meta.Session.query(Waypoint).filter( sa.and_(Waypoint.user == tripuser(), Waypoint.trip == session['current_trip'])).order_by( Waypoint.ordering).all()) c.tripname = session['current_trip'] c.showarea = session.get('showarea', '') c.showtrack = session.get('showtrack', None) != None c.fastmap = user.fastmap #print "Zoomlevel active: ",zoomlevel c.zoomlevel = zoomlevel c.dynamic_id = '' c.sharing = tripsharing.sharing_active() c.mtime = maptilereader.get_mtime() for way in c.waypoints: print "Name:", way.waypoint if len(c.waypoints): c.next_waypoint_id = max([way.id for way in c.waypoints]) + 1 else: c.next_waypoint_id = 100 assert type(c.next_waypoint_id) == int if c.sharing: c.shared_by = tripuser() if session.get('showarea', ''): c.dynamic_id = session.get('showarea_id', '') if session.get('showtrack', ''): if hasattr(session['showtrack'], 'dynamic_id'): c.dynamic_id = session['showtrack'].dynamic_id return render('/mapview.mako')
def zoom(self): print "zoom called" #user=meta.Session.query(User).filter( # User.user==tripuser()).one() if request.params['zoom'] == 'auto': if session.get('showarea', '') != '': zoom = 13 minx = 1e30 maxx = -1e30 miny = 1e30 maxy = -1e30 for vert in mapper.parse_lfv_area(session.get('showarea')): merc = mapper.latlon2merc(mapper.from_str(vert), zoom) minx = min(minx, merc[0]) miny = min(miny, merc[1]) maxx = max(maxx, merc[0]) maxy = max(maxy, merc[1]) if maxy < -1e29: self.set_pos_zoom( (59, 18), 6, ) else: size = max(maxx - minx, maxy - miny) if (maxx == minx and maxy == miny): zoom = 10 else: nominal_size = 400 while zoom >= 0 and size > nominal_size: zoom -= 1 size /= 2.0 pos = (int(0.5 * (maxx + minx)), int(0.5 * (maxy + miny))) latlon = mapper.merc2latlon(pos, 13) self.set_pos_zoom(latlon, zoom) elif session.get('showtrack', None) != None: strack = session.get('showtrack') zoom = 13 minx, miny = mapper.latlon2merc(strack.bb1, 13) maxx, maxy = mapper.latlon2merc(strack.bb2, 13) pos = (int(0.5 * (maxx + minx)), int(0.5 * (maxy + miny))) latlon = mapper.merc2latlon(pos, 13) print "AutoZooming to pos", latlon size = max(maxx - minx, maxy - miny, 1) nominal_size = 400 while zoom >= 0 and size > nominal_size: zoom -= 1 size /= 2.0 self.set_pos_zoom(latlon, zoom) else: #mapper.parse_lfv_area() self.set_pos_zoom((59, 18), 6) print "Autozoom zooming to level %d at %s" % (session['zoom'], session['last_pos']) else: zoomlevel = float(request.params['zoom']) if zoomlevel < 0: zoomlevel = 0 pos = mapper.merc2latlon( tuple([int(x) for x in request.params['center'].split(",")]), zoomlevel) if session.get('mapvariant', None) == 'elev': if zoomlevel > 8: zoomlevel = 8 else: if zoomlevel > 13: zoomlevel = 13 print "Zoomlevel: %s" % (zoomlevel, ) print "Pos:", pos self.set_pos_zoom(pos, zoomlevel) redirect(h.url_for(controller='mapview', action="index"))
def generate_big_tile(pixelsize, x1, y1, zoomlevel, osmdraw, tma=False, return_format="PIL", user=None, only_user=False): """ set osmdraw==True and make sure a full working openstreetmap mapnik environment is available, in order to draw using mapnik. If false, a basemap must already have been drawn, and all that can be done is that new airspaces etc an be filled in. """ def only(x): if only_user: #print "Ignoring ",len(x) return [] return x print "TMA:", tma imgx, imgy = pixelsize assert osmdraw in [True, False] if not osmdraw: #osmdraw should probably be renamed use 'use_existing_basemap' print "Making %dx%d tile at %s/%s, zoomlevel: %d" % ( pixelsize[0], pixelsize[1], x1, y1, zoomlevel) print "Generating tile" print "mapnikstyle file:", os.getenv("SWFP_MAPNIK_STYLE") mapfile = os.path.join(os.getenv("SWFP_MAPNIK_STYLE"), "osm.xml") #--------------------------------------------------- # Change this to the bounding box you want # # lon lat lon lat #ll = (center[1], hilat, center[1], lolat) #--------------------------------------------------- lat1, lon1 = mapper.merc2latlon((x1, y1), zoomlevel) lat2, lon2 = mapper.merc2latlon((x1 + imgx, y1 + imgy), zoomlevel) m = mapnik.Map(imgx, imgy) mapnik.load_map(m, mapfile) c0 = prj.forward(mapnik.Coord(lon1, lat1)) c1 = prj.forward(mapnik.Coord(lon2, lat2)) if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: #bbox = mapnik.Box2d(0,0,256<<zoomlevel,256<<zoomlevel) bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) #bbox = mapnik.Envelope(0,0,256<<zoomlevel,256<<zoomlevel) m.zoom_to_box(bbox) im = mapnik.Image(imgx, imgy) mapnik.render(m, im) buf = im.tostring() #print "len im tostring:" ,len(buf) assert len(buf) % 4 == 0 num_pixels = len(buf) / 4 as_array = numpy.fromstring(buf, numpy.dtype("u1")) assert len(as_array) == len(buf) r, g, b, a = numpy.hsplit(as_array.reshape(num_pixels, 4), (1, 2, 3)) assert len(r) == num_pixels print "Num pixels: ", num_pixels swapped = numpy.column_stack((b, g, r, a)).reshape(4 * num_pixels) assert len(swapped) == num_pixels * 4 assert num_pixels == imgx * imgy im = cairo.ImageSurface.create_for_data(swapped, cairo.FORMAT_RGB24, imgx, imgy) #as_array=numpy.fromstring(buf,numpy.dtype("u4")) #as_array.byteswap(True) else: #print "Reading existing map instead" im = Image.new("RGBA", (imgx, imgy)) for i in xrange(0, pixelsize[0], 256): for j in xrange(0, pixelsize[1], 256): rawtile, tilemeta = maptilereader.gettile( "plain", zoomlevel, x1 + i, y1 + j) io = StringIO.StringIO(rawtile) io.seek(0) sub = Image.open(io) im.paste(sub, (i, j, i + 256, j + 256)) buf = im.tostring() #print "len im tostring:" ,len(buf) assert len(buf) % 4 == 0 num_pixels = len(buf) / 4 assert num_pixels == imgx * imgy as_array = numpy.fromstring(buf, numpy.dtype("u1")) assert len(as_array) == len(buf) r, g, b, a = numpy.hsplit(as_array.reshape(num_pixels, 4), (1, 2, 3)) assert len(r) == num_pixels #print "Num pixels: ",num_pixels swapped = numpy.column_stack((b, g, r, a)).reshape(4 * num_pixels) im = cairo.ImageSurface.create_for_data(swapped, cairo.FORMAT_RGB24, imgx, imgy) ctx = cairo.Context(im) if tma: def tolocal(merc): return (merc[0] - x1, merc[1] - y1) merc13 = mapper.merc2merc((x1 - 50, y1 - 50), zoomlevel, 13) merc13b = mapper.merc2merc((x1 + imgx + 50, y1 + imgy + 50), zoomlevel, 13) bb13 = BoundingBox(merc13[0], merc13[1], merc13b[0], merc13b[1]) bycolor = dict() for space in chain(only(get_airspaces_in_bb2(bb13)), get_notam_objs_cached()['areas'], only(get_aip_sup_areas()), get_firs(), userdata.get_all_airspaces(user)): if space['type'] == 'sector': continue #Don't draw "sectors" vertices = [] for coord in space['points']: merc = mapper.latlon2merc(mapper.from_str(coord), zoomlevel) vertices.append(tolocal(merc)) #merc[0]-x1,merc[1]-y1) try: areacol, solidcol = get_airspace_color(space['type']) except Exception: print space raise bycolor.setdefault((areacol, solidcol), []).append(vertices) def colorsorter(col): if col[0] > 0.5: return (110, 0, 0, 0) return col for (areacol, solidcol), polygons in sorted(bycolor.items(), key=lambda x: colorsorter(x[0])): if areacol[3] <= 0.05: continue surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, imgx, imgy) ctx2 = cairo.Context(surface2) ctx2.set_operator(cairo.OPERATOR_DEST_OUT) ctx2.rectangle(0, 0, imgx, imgy) ctx2.set_source(cairo.SolidPattern(0, 0, 0, 1.0)) ctx2.paint() ctx2.set_operator(cairo.OPERATOR_OVER) for poly in polygons: ctx2.new_path() for vert in poly: ctx2.line_to(*vert) ctx2.close_path() ctx2.set_source( cairo.SolidPattern(areacol[0], areacol[1], areacol[2], 1.0)) ctx2.fill_preserve() ctx2.set_operator(cairo.OPERATOR_DEST_OUT) ctx2.rectangle(0, 0, imgx, imgy) ctx2.set_source(cairo.SolidPattern(0, 0, 0, 1.0 - areacol[3])) ctx2.paint() #ctx2.set_operator(cairo.OPERATOR_OVER) ctx.set_source_surface(surface2) ctx.rectangle(0, 0, imgx, imgy) ctx.paint() for (areacol, solidcol), polygons in sorted(bycolor.items(), key=lambda x: colorsorter(x[1])): for poly in polygons: ctx.new_path() for vert in poly: ctx.line_to(*vert) ctx.close_path() ctx.set_source(cairo.SolidPattern(*solidcol)) ctx.stroke() for obst in chain(only(get_obstacles_in_bb(bb13)), userdata.get_all_obstacles(user)): if zoomlevel >= 9: ctx.set_source(cairo.SolidPattern(1.0, 0.0, 1.0, 0.25)) merc = mapper.latlon2merc(mapper.from_str(obst['pos']), zoomlevel) pos = tolocal(merc) #(merc[0]-x1,merc[1]-y1) radius = parse_obstacles.get_pixel_radius(obst, zoomlevel) ctx.new_path() ctx.arc(pos[0], pos[1], radius, 0, 2 * math.pi) ctx.fill_preserve() ctx.set_source(cairo.SolidPattern(1.0, 0.0, 1.0, 0.75)) ctx.new_path() ctx.arc(pos[0], pos[1], radius, 0, 2 * math.pi) ctx.stroke() for sigp in chain(only(get_sig_points_in_bb(bb13)), userdata.get_all_sigpoints(user)): if zoomlevel >= 9: #print sigp if zoomlevel == 9 and sigp.get( 'kind', '') in ['entry/exit point', 'holding point']: continue if sigp.get('kind', '') in ['town', 'city']: continue merc = mapper.latlon2merc(mapper.from_str(sigp['pos']), zoomlevel) pos = tolocal(merc) #(merc[0]-x1,merc[1]-y1) ctx.set_source(cairo.SolidPattern(0.0, 0.0, 1.0, 0.65)) ctx.new_path() ctx.line_to(pos[0], pos[1] - 3) ctx.line_to(pos[0] + 3, pos[1]) ctx.line_to(pos[0], pos[1] + 3) ctx.line_to(pos[0] - 3, pos[1]) ctx.close_path() ctx.stroke() for notamtype, items in get_notam_objs_cached().items(): if notamtype == "areas": continue for item in items: if zoomlevel >= 8: ctx.set_source(cairo.SolidPattern(0.25, 1, 0.25, 0.25)) merc = mapper.latlon2merc(mapper.from_str(item['pos']), zoomlevel) pos = tolocal(merc) #(merc[0]-x1,merc[1]-y1) radius = 5 ctx.new_path() ctx.arc(pos[0], pos[1], radius, 0, 2 * math.pi) ctx.fill_preserve() ctx.set_source(cairo.SolidPattern(0, 1.0, 0, 0.75)) ctx.new_path() ctx.arc(pos[0], pos[1], radius, 0, 2 * math.pi) ctx.stroke() for airfield in chain(only(get_airfields_in_bb(bb13)), userdata.get_all_airfields(user)): if zoomlevel < 6: continue ctx.set_source(cairo.SolidPattern(0.8, 0.5, 1.0, 0.25)) merc = mapper.latlon2merc(mapper.from_str(airfield['pos']), zoomlevel) pos = (merc[0] - x1, merc[1] - y1) if zoomlevel <= 11: radius = 5 else: radius = 5 << (zoomlevel - 11) ctx.new_path() ctx.arc(pos[0], pos[1], radius, 0, 2 * math.pi) ctx.fill_preserve() ctx.set_source(cairo.SolidPattern(0.8, 0.5, 1.0, 0.75)) ctx.new_path() ctx.arc(pos[0], pos[1], radius, 0, 2 * math.pi) ctx.stroke() for rwy in airfield.get('runways', []): ends = rwy['ends'] mercs = [] #print "Ends:",ends surface = rwy.get('surface', 'hard').lower() for end in ends: #print "pos:",end['pos'] latlon = mapper.from_str(end['pos']) #print "latlon:",latlon merc = mapper.latlon2merc(latlon, zoomlevel) #print "Merc:",merc mercs.append(merc) if len(mercs) == 2: a, b = mercs #print "Drawing:",airfield['icao'],a,b if surface == 'gravel': ctx.set_source(cairo.SolidPattern(0.5, 0.3, 0.0, 1)) elif surface == 'grass': ctx.set_source(cairo.SolidPattern(0.0, 0.65, 0.0, 1)) else: ctx.set_source(cairo.SolidPattern(0.0, 0.0, 0.0, 1)) lwidth = mapper.approx_scale(a, zoomlevel, 40.0 / 1852.0) if lwidth <= 2: lwidth = 2.0 ctx.set_line_width(lwidth) ctx.new_path() ctx.move_to(*tolocal(a)) ctx.line_to(*tolocal(b)) ctx.stroke() if return_format == "PIL": b, g, r, a = numpy.hsplit(swapped.reshape(num_pixels, 4), (1, 2, 3)) back = numpy.column_stack((r, g, b)).reshape(3 * num_pixels) im = Image.frombuffer("RGB", (imgx, imgy), back, 'raw', 'RGB', 0, 1) else: assert return_format == "cairo" pass #print "Returning rendered image and map" return im
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 generate_work_packages(tma,blobs,cachedir,maxzoomlevel=13,meta=0,cutoff=8): meta=meta #Change back to if using mapnik #if meta==0: # print "\n\n\n\n\n=====================================================================\nWARNING! meta==0!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n" packcnt=0 for zoomlevel in xrange(maxzoomlevel+1): if zoomlevel<=cutoff: lat1,lon1,lat2,lon2=latlon_limits_hd() else: lat1,lon1,lat2,lon2=latlon_limits() lat1=float(lat1) lat2=float(lat2) lon1=float(lon1) lon2=float(lon2) maxy=mapper.max_merc_y(zoomlevel) maxx=mapper.max_merc_x(zoomlevel) hd=False if zoomlevel<=cutoff: hd=True limitx1,limity1,limitx2,limity2=merc_limits(zoomlevel,hd=hd) assert limitx2>limitx1 assert limity2>limity1 print "Limits: %f,%f - %f,%f"%(limitx1,limity1,limitx2,limity2) blobs[zoomlevel]=BlobFile(os.path.join(cachedir,"level"+str(zoomlevel)),zoomlevel, limitx1,limity1,limitx2,limity2,'w') for my1 in xrange(limity1,limity2,2048): for mx1 in xrange(limitx1,limitx2,2048): already=True for i in xrange(0,2048,256): for j in xrange(0,2048,256): if blobs[zoomlevel].get_tile(mx1+i,my1+j)==None: already=False break if already: print "Already have %d,%d,%d"%(mx1,my1,zoomlevel) continue print "Creating new tile %d,%d,%d (tma=%s)"%(mx1,my1,zoomlevel,tma) mx2=mx1+2048 my2=my1+2048 if my2>maxy: my2=maxy if mx2>maxx: mx2=maxx if my1>=meta: metay1=meta else: metay1=0 if mx1>=meta: metax1=meta else: metax1=0 if my2<=maxy-meta: metay2=meta else: metay2=0 if mx2<=maxx-meta: metax2=meta else: metax2=0 latb,lona=mapper.merc2latlon((mx1,my1),zoomlevel) lata,lonb=mapper.merc2latlon((mx2,my2),zoomlevel) if latb<lat1: continue if lata>lat2: continue if lonb<lon1: continue if lona>lon2: continue coord=(zoomlevel,mx1,my1,mx2,my2) packcnt+=1 yield (coord,dict( checkedout=None, metax1=metax1, metay1=metay1, metax2=metax2, metay2=metay2, render_tma=tma )) print "Finished initializing work. Created %d work items. Cutoff=%d"%(packcnt,cutoff)
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 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 ats(self): try: #waypoints=meta.Session.query(Waypoint).filter(sa.and_( # Waypoint.user==tripuser(),Waypoint.trip==session['current_trip'])).order_by(Waypoint.ordering).all() #c.waypoints=[] self.standard_prep(c) #print "Routes:",c.route def break_subtrips(routes): out=[] T=0.0 for i,rt in enumerate(routes): out.append(rt) if rt.time_hours: T+=rt.time_hours if rt.b.stay or i==len(routes)-1: if len(out): yield dict(T=T),out T=0.0 out=[] def format_cruise(tas): if tas>999: tas=999 if tas<0: tas=0 return "N%04d"%(tas,) def format_alt(alt): try: alt=alt.upper().strip() if alt.startswith("FL"): ialt=int(float(alt[2:].strip())) return "F%03d"%(ialt,) ialt=int(float(alt))/100 print "parsed alt %s"%(repr(alt,)),"as",ialt return "A%03d"%(ialt,) except Exception: raise AtsException("Bad altitude specification for some leg: <%s>"%(alt)) c.atstrips=[] last_fuel_left=None nr_persons=None for meta,routes in break_subtrips(c.route): print "===============New subtrip..............." spaces=set() fir_whenposname=[] accum_time=0 #print "broke ruote",meta if len(routes)==0: continue at=dict() at['T']=meta['T'] waypoints=[routes[0].a] for rt in routes: waypoints.append(rt.b) wps=[] stay=routes[0].a.stay dep_ad="ZZZZ" dep_ad_name=waypoints[0].waypoint dep_ad_coords=mapper.format_lfv_ats(*mapper.from_str(waypoints[0].pos)) dest_ad="ZZZZ" dest_ad_name=waypoints[-1].waypoint dest_ad_coords=mapper.format_lfv_ats(*mapper.from_str(waypoints[-1].pos)) extra_remarks=[] lastwppos=None lastaltspeed=None for i,wp in enumerate(waypoints): print "Subtrip:",i,wp.waypoint at['T']=meta['T'] lat,lon=mapper.from_str(wp.pos) if lastwppos: assert i>=1 curpos=(lat,lon) crossing1=airspace.get_fir_crossing(lastwppos,curpos) for sub in routes[i-1].subs: if crossing1: posa,posb=mapper.merc2latlon(sub.subposa,13),\ mapper.merc2latlon(sub.subposb,13) crossing=airspace.get_fir_crossing(posa,posb) if crossing: fir,enterpos=crossing bearing,along=mapper.bearing_and_distance(posa,enterpos) if sub.gs>1e-6: curtime=accum_time+along/sub.gs fir_whenposname.append((curtime,enterpos,fir['icao'])) if sub.time!=None: accum_time+=sub.time else: accum_time=9999 for space in get_any_space_on_line(lastwppos,curpos): spaces.add((space['name'],space.get('floor',"<Unknown>"),space.get('ceiling',"<Unknown>"))) lastwppos=(lat,lon) symbolicpos=None airport=None if i==0 or i==len(waypoints)-1: for ad in airspace.get_airfields(lat,lon,11): if not ad['icao'].upper() in ['ZZZZ','ESVF']: airport=ad symbolicpos=ad['icao'].upper() if i==0: dep_ad=ad['icao'].upper() if i==len(waypoints)-1: dest_ad=ad['icao'].upper() break else: for sigp in airspace.get_sigpoints(lat,lon,11): if sigp['kind']=="sig. point": if len(sigp['name'])==5: sigfound=sigp symbolicpos=sigp['name'] break if symbolicpos==None: symbolicpos=mapper.format_lfv_ats(lat,lon) if i<len(routes): altspeed=(format_alt(routes[i].altitude),format_cruise(routes[i].tas)) if lastaltspeed!=None: if lastaltspeed!=altspeed: alt,speed=altspeed symbolicpos+="/"+speed+alt lastaltspeed=altspeed wps.append(dict( name=wp.waypoint, airport=airport, symbolicpos="DCT "+symbolicpos, exactpos=mapper.format_lfv(lat,lon), decimalpos="%.5f,%.5f"%(lat,lon) )) for when,pos,fir in fir_whenposname: hour,minute=divmod(int(60*when),60) extra_remarks.append("EET/%s%02d%02d"%(fir,hour,minute)) if dep_ad=="ZZZZ": extra_remarks.append(u"DEP/%s %s"%(dep_ad_coords,strip_accents(dep_ad_name.upper()))) if dest_ad=="ZZZZ": extra_remarks.append(u"DEST/%s %s"%(dest_ad_coords,strip_accents(dest_ad_name.upper()))) if stay.date_of_flight.strip(): dof=stay.date_of_flight.replace("-","").strip() if len(dof)==8 and dof.startswith("20"): dof=dof[2:] else: dof=routes[0].depart_dt.strftime("%y%m%d") print "dof:",dof if len(dof)!=6: raise AtsException(u"ATS flight plans need takeoff date for all takeoffs!") else: extra_remarks.append(u"DOF/%s"%(dof,)) if stay and stay.nr_persons: nr_persons=stay.nr_persons else: if nr_persons==None: raise AtsException(u"You must enter the the number of persons who will be flying!") tas=routes[0].tas altitude=routes[0].altitude at['wps']=wps if any(rt.time_hours==None for rt in routes): raise AtsException("TAS is less than headwind for some part of trip.") enroute_time=sum(rt.time_hours for rt in routes) fuel=last_fuel_left if stay and stay.fuel: fuel=stay.fuel if not c.ac: raise AtsException("You must choose an aircraft type for this journey to be able to create an ATS flight plan") if c.ac.cruise_burn>1e-3 and fuel: endurance=float(fuel)/float(c.ac.cruise_burn) else: endurance=0.0 if endurance<=0.0: if fuel==None: raise AtsException("Enter a value for 'Fuel at takeoff'!") else: raise AtsException("You do not have enough fuel for the entire journey! This means your endurance would be 0 or negative for one or more legs. Add a fuel stop, shorten the journey, or bring more fuel!") if not c.user.realname: raise AtsException("You should enter your name under profile settings, for use as the name of the commander in the flight plan") phonenr="" if c.user.phonenr: phonenr=c.user.phonenr fir_whenposname.sort() def eqp(x,s): x="".join(re.findall('[A-Z]',x.upper())) if len(x)==0: return s return x dummy=u""" FPL-SEVLI-VG -ULAC/L-V/C -EFKG1330 -N0075F065 DCT 5959N02016E DCT 5949N01936E DCT 5929N01818E DCT 5927N01742E -ZZZZ0130 -DEST/5927N01742E FRÖLUNDA RMK/BORDER CROSSING 40MIN AFTER TAKEOFF DOF/101002 ORGN/ESSAZPZX -E/0300 P/2 A/R W C/ANDERS MUSIKKA +4670123123""" atsfplan=u""" (FPL-%(acreg)s-%(flight_rules)s%(type_of_flight)s -%(actype)s/%(turbulence_category)s-%(equipment)s/%(transponder)s -%(dep_ad)s%(eobt)s -%(cruise_speed)s%(level)s %(route)s DCT -%(dest_ad)s%(ete)s -%(extra_remarks)s -E/%(endurance)s P/%(nr_passengers)s A/%(markings)s%(extra_equipment)s C/%(commander)s %(phonenr)s)"""%(dict( acreg=c.ac.aircraft.replace("-",""), actype=c.ac.atstype, turbulence_category='L', flight_rules='V', type_of_flight='G', equipment=eqp(c.ac.com_nav_equipment,'V'), transponder=eqp(c.ac.transponder_equipment,'C'), extra_equipment=u" %s"%(c.ac.extra_equipment,) if c.ac.extra_equipment else "", dep_ad=dep_ad, eobt=routes[0].depart_dt.strftime("%H%M"), cruise_speed=format_cruise(tas), level=format_alt(altitude), route=(" ".join("%s"%(w['symbolicpos'],) for w in wps[1:-1])), dest_ad=dest_ad, ete=lfvclockfmt(enroute_time), extra_remarks=" ".join(extra_remarks), endurance=lfvclockfmt(endurance), nr_passengers=nr_persons, markings=c.ac.markings, commander=strip_accents(c.user.realname if c.user.realname else u"UNKNOWN").replace(" ",""), phonenr=c.user.phonenr if c.user.phonenr else "")) at['atsfplan']=atsfplan.strip() #print "Adding atstrip:",atsfplan at['spacesummary']=spaces last_fuel_left=routes[-1].accum_fuel_left c.atstrips.append(at) c.atstrips=[at for at in c.atstrips if len(at['wps'])] #response.headers['Content-Type'] = 'application/xml' return render('/ats.mako') except AtsException,ats: redirect(h.url_for(controller='flightplan',action="index",flash=unicode(ats)))
def ats(self): try: #waypoints=meta.Session.query(Waypoint).filter(sa.and_( # Waypoint.user==tripuser(),Waypoint.trip==session['current_trip'])).order_by(Waypoint.ordering).all() #c.waypoints=[] self.standard_prep(c) #print "Routes:",c.route def break_subtrips(routes): out = [] T = 0.0 for i, rt in enumerate(routes): out.append(rt) if rt.time_hours: T += rt.time_hours if rt.b.stay or i == len(routes) - 1: if len(out): yield dict(T=T), out T = 0.0 out = [] def format_cruise(tas): if tas > 999: tas = 999 if tas < 0: tas = 0 return "N%04d" % (tas, ) def format_alt(alt): try: alt = alt.upper().strip() if alt.startswith("FL"): ialt = int(float(alt[2:].strip())) return "F%03d" % (ialt, ) ialt = int(float(alt)) / 100 print "parsed alt %s" % (repr(alt, )), "as", ialt return "A%03d" % (ialt, ) except Exception: raise AtsException( "Bad altitude specification for some leg: <%s>" % (alt)) c.atstrips = [] last_fuel_left = None nr_persons = None for meta, routes in break_subtrips(c.route): print "===============New subtrip..............." spaces = set() fir_whenposname = [] accum_time = 0 #print "broke ruote",meta if len(routes) == 0: continue at = dict() at['T'] = meta['T'] waypoints = [routes[0].a] for rt in routes: waypoints.append(rt.b) wps = [] stay = routes[0].a.stay dep_ad = "ZZZZ" dep_ad_name = waypoints[0].waypoint dep_ad_coords = mapper.format_lfv_ats( *mapper.from_str(waypoints[0].pos)) dest_ad = "ZZZZ" dest_ad_name = waypoints[-1].waypoint dest_ad_coords = mapper.format_lfv_ats( *mapper.from_str(waypoints[-1].pos)) extra_remarks = [] lastwppos = None lastaltspeed = None for i, wp in enumerate(waypoints): print "Subtrip:", i, wp.waypoint at['T'] = meta['T'] lat, lon = mapper.from_str(wp.pos) if lastwppos: assert i >= 1 curpos = (lat, lon) crossing1 = airspace.get_fir_crossing( lastwppos, curpos) for sub in routes[i - 1].subs: if crossing1: posa,posb=mapper.merc2latlon(sub.subposa,13),\ mapper.merc2latlon(sub.subposb,13) crossing = airspace.get_fir_crossing( posa, posb) if crossing: fir, enterpos = crossing bearing, along = mapper.bearing_and_distance( posa, enterpos) if sub.gs > 1e-6: curtime = accum_time + along / sub.gs fir_whenposname.append( (curtime, enterpos, fir['icao'])) if sub.time != None: accum_time += sub.time else: accum_time = 9999 for space in get_any_space_on_line(lastwppos, curpos): spaces.add((space['name'], space.get('floor', "<Unknown>"), space.get('ceiling', "<Unknown>"))) lastwppos = (lat, lon) symbolicpos = None airport = None if i == 0 or i == len(waypoints) - 1: for ad in airspace.get_airfields(lat, lon, 11): if not ad['icao'].upper() in ['ZZZZ', 'ESVF']: airport = ad symbolicpos = ad['icao'].upper() if i == 0: dep_ad = ad['icao'].upper() if i == len(waypoints) - 1: dest_ad = ad['icao'].upper() break else: for sigp in airspace.get_sigpoints(lat, lon, 11): if sigp['kind'] == "sig. point": if len(sigp['name']) == 5: sigfound = sigp symbolicpos = sigp['name'] break if symbolicpos == None: symbolicpos = mapper.format_lfv_ats(lat, lon) if i < len(routes): altspeed = (format_alt(routes[i].altitude), format_cruise(routes[i].tas)) if lastaltspeed != None: if lastaltspeed != altspeed: alt, speed = altspeed symbolicpos += "/" + speed + alt lastaltspeed = altspeed wps.append( dict(name=wp.waypoint, airport=airport, symbolicpos="DCT " + symbolicpos, exactpos=mapper.format_lfv(lat, lon), decimalpos="%.5f,%.5f" % (lat, lon))) for when, pos, fir in fir_whenposname: hour, minute = divmod(int(60 * when), 60) extra_remarks.append("EET/%s%02d%02d" % (fir, hour, minute)) if dep_ad == "ZZZZ": extra_remarks.append( u"DEP/%s %s" % (dep_ad_coords, strip_accents(dep_ad_name.upper()))) if dest_ad == "ZZZZ": extra_remarks.append( u"DEST/%s %s" % (dest_ad_coords, strip_accents(dest_ad_name.upper()))) if stay.date_of_flight.strip(): dof = stay.date_of_flight.replace("-", "").strip() if len(dof) == 8 and dof.startswith("20"): dof = dof[2:] else: dof = routes[0].depart_dt.strftime("%y%m%d") print "dof:", dof if len(dof) != 6: raise AtsException( u"ATS flight plans need takeoff date for all takeoffs!" ) else: extra_remarks.append(u"DOF/%s" % (dof, )) if stay and stay.nr_persons: nr_persons = stay.nr_persons else: if nr_persons == None: raise AtsException( u"You must enter the the number of persons who will be flying!" ) tas = routes[0].tas altitude = routes[0].altitude at['wps'] = wps if any(rt.time_hours == None for rt in routes): raise AtsException( "TAS is less than headwind for some part of trip.") enroute_time = sum(rt.time_hours for rt in routes) fuel = last_fuel_left if stay and stay.fuel: fuel = stay.fuel if not c.ac: raise AtsException( "You must choose an aircraft type for this journey to be able to create an ATS flight plan" ) if c.ac.cruise_burn > 1e-3 and fuel: endurance = float(fuel) / float(c.ac.cruise_burn) else: endurance = 0.0 if endurance <= 0.0: if fuel == None: raise AtsException( "Enter a value for 'Fuel at takeoff'!") else: raise AtsException( "You do not have enough fuel for the entire journey! This means your endurance would be 0 or negative for one or more legs. Add a fuel stop, shorten the journey, or bring more fuel!" ) if not c.user.realname: raise AtsException( "You should enter your name under profile settings, for use as the name of the commander in the flight plan" ) phonenr = "" if c.user.phonenr: phonenr = c.user.phonenr fir_whenposname.sort() def eqp(x, s): x = "".join(re.findall('[A-Z]', x.upper())) if len(x) == 0: return s return x dummy = u""" FPL-SEVLI-VG -ULAC/L-V/C -EFKG1330 -N0075F065 DCT 5959N02016E DCT 5949N01936E DCT 5929N01818E DCT 5927N01742E -ZZZZ0130 -DEST/5927N01742E FRÖLUNDA RMK/BORDER CROSSING 40MIN AFTER TAKEOFF DOF/101002 ORGN/ESSAZPZX -E/0300 P/2 A/R W C/ANDERS MUSIKKA +4670123123""" atsfplan = u""" (FPL-%(acreg)s-%(flight_rules)s%(type_of_flight)s -%(actype)s/%(turbulence_category)s-%(equipment)s/%(transponder)s -%(dep_ad)s%(eobt)s -%(cruise_speed)s%(level)s %(route)s DCT -%(dest_ad)s%(ete)s -%(extra_remarks)s -E/%(endurance)s P/%(nr_passengers)s A/%(markings)s%(extra_equipment)s C/%(commander)s %(phonenr)s)""" % (dict( acreg=c.ac.aircraft.replace("-", ""), actype=c.ac.atstype, turbulence_category='L', flight_rules='V', type_of_flight='G', equipment=eqp(c.ac.com_nav_equipment, 'V'), transponder=eqp(c.ac.transponder_equipment, 'C'), extra_equipment=u" %s" % (c.ac.extra_equipment, ) if c.ac.extra_equipment else "", dep_ad=dep_ad, eobt=routes[0].depart_dt.strftime("%H%M"), cruise_speed=format_cruise(tas), level=format_alt(altitude), route=(" ".join("%s" % (w['symbolicpos'], ) for w in wps[1:-1])), dest_ad=dest_ad, ete=lfvclockfmt(enroute_time), extra_remarks=" ".join(extra_remarks), endurance=lfvclockfmt(endurance), nr_passengers=nr_persons, markings=c.ac.markings, commander=strip_accents(c.user.realname if c.user.realname else u"UNKNOWN").replace(" ", ""), phonenr=c.user.phonenr if c.user.phonenr else "")) at['atsfplan'] = atsfplan.strip() #print "Adding atstrip:",atsfplan at['spacesummary'] = spaces last_fuel_left = routes[-1].accum_fuel_left c.atstrips.append(at) c.atstrips = [at for at in c.atstrips if len(at['wps'])] #response.headers['Content-Type'] = 'application/xml' return render('/ats.mako') except AtsException, ats: redirect( h.url_for(controller='flightplan', action="index", flash=unicode(ats)))
def save(self): try: if 'pos' in request.params and 'zoomlevel' in request.params: save_merc_x,save_merc_y=[int(x) for x in request.params['pos'].split(",")] save_zoom=int(request.params['zoomlevel']) pos=mapper.merc2latlon((save_merc_x,save_merc_y),save_zoom) self.set_pos_zoom(pos,save_zoom) wps=self.get_waypoints(request.params) oldname=request.params.get('oldtripname','') tripname=request.params.get('tripname','') if tripsharing.sharing_active(): #Can't rename trips while tripsharing is active! tripname=session['current_trip'] if oldname!=session['current_trip']: #In some strange way a non-tripsharing oldname appeared in the post. This #means that something has gone awry. Don't save! print "Bad trip oldname while tripsharing active!" return "notok" if 'showarea' in request.params and request.params['showarea']: sha=request.params['showarea'] if (sha=='.'): session['showarea']='' session['showarea_id']='' session['showtrack']=None else: session['showarea']=sha session['showarea_id']=md5(sha.encode('utf8')).hexdigest() session['showtrack']=None session['mapvariant']=request.params.get('mapvariant','airspace') #print "Req:",request.params oldtrip=None if not oldname.strip(): oldname=tripname oldtrips=meta.Session.query(Trip).filter(sa.and_(Trip.user==tripuser(),Trip.trip==oldname)).all() if len(oldtrips)==1: oldtrip=oldtrips[0] if oldtrip: trip=oldtrip if trip.trip!=tripname: if tripsharing.sharing_active(): #attempt to rename someone elses trip! Can't be allowed! set tripname to old name print "Attempt to rename trip while viewing shared trip (tripsharing)" return "notok" else: trip.trip=self.get_free_tripname(tripname) if session['current_trip']!=trip.trip and tripsharing.sharing_active(): #internal error if we get here - the earlier test for current_trip not changing failed. print "Unexpected tripsharing error #2" return "notok" session['current_trip']=trip.trip else: if tripsharing.sharing_active(): #we use sharing, but the shared trip can't be found! print "Tripsharing active, but named trip didn't exist (deleted, probably)" return "notok" tripname=self.get_free_tripname(tripname) trip = Trip(tripuser(), tripname) acs=meta.Session.query(Aircraft).filter(sa.and_( Aircraft.user==tripuser())).all() if len(acs): trip.aircraft=acs[0].aircraft meta.Session.add(trip) session['current_trip']=tripname oldwps=set([(wp.id) for wp in meta.Session.query(Waypoint).filter(sa.and_( Waypoint.user==tripuser(),Waypoint.trip==trip.trip)).all()]) newwps=set(wps.keys()) #print "NEW WPS",wps removed=oldwps.difference(newwps) added=newwps.difference(oldwps) updated=newwps.intersection(oldwps) print "Removed: ",removed addedwps=added removedwps=removed updatedwps=updated ordering2wpid=dict() for remord in removed: meta.Session.query(Waypoint).filter( sa.and_(Waypoint.user==tripuser(),Waypoint.trip==trip.trip, Waypoint.id==remord)).delete() #print "\n\n====DELETING!=====\n%s\n\n"%(rem,) resultant_by_order=dict() resultant_id2order=dict() waypointlink=dict() for add in added: wp=wps[add] waypoint=Waypoint(tripuser(),trip.trip,wp['pos'],int(wp['id']),int(wp['ordering']),wp['name'],wp['altitude']) resultant_by_order[int(wp['ordering'])]=waypoint resultant_id2order[int(wp['id'])]=wp['ordering'] #print "\n\n====ADDING!=====\n%s %s %s\n\n"%(waypoint.id,waypoint.pos,waypoint.waypoint) meta.Session.add(waypoint) for upd in updated: wp=wps[upd] us=meta.Session.query(Waypoint).filter( sa.and_(Waypoint.user==tripuser(),Waypoint.trip==trip.trip, Waypoint.id==upd)).all() if len(us)>0: u=us[0] prevpos=mapper.from_str(u.pos) newpos=mapper.from_str(wp['pos']) approxdist=(prevpos[0]-newpos[0])**2+(prevpos[1]-newpos[1])**2 if approxdist>(1.0/36000.0)**2: #if moved more than 0.1 arc-second, otherwise leave be. u.pos=wp['pos'] print "Waypoint %d moved! (%f deg)"%(u.id,math.sqrt(approxdist)) else: print "Waypoint %d has only moved a little (%f deg)"%(u.id,math.sqrt(approxdist)) u.waypoint=wp['name'] assert u.id==int(wp['id']) u.ordering=wp['ordering'] u.altitude=wp['altitude'] resultant_by_order[int(wp['ordering'])]=u resultant_id2order[int(wp['id'])]=wp['ordering'] #print "\n\n====UPDATING!=====\n%s %s %s\n\n"%(u.id,u.pos,u.waypoint) #print "Resultant by ordering: %s"%(resultant_by_order,) seq=list(sorted(resultant_by_order.items())) newroutes=set() for (ord1,waypoint1),(ord2,waypoint2) in zip(seq[:-1],seq[1:]): if not int(ord1)+1==int(ord2): print "Waypoints %s and %s not consecutive (#%d, #%d)"%(waypoint1,waypoint2,int(ord1),int(ord2)) assert int(ord1)+1==int(ord2) newroutes.add((waypoint1.id,waypoint2.id)) oldrouteobjs=list(meta.Session.query(Route).filter(sa.and_( Route.user==tripuser(),Route.trip==trip.trip)).all()) oldroutes=set([(route.waypoint1,route.waypoint2) for route in oldrouteobjs]) prevalts=dict() for rt in oldrouteobjs: prevalts[(rt.a.id,+1)]=rt.altitude prevalts[(rt.b.id,-1)]=rt.altitude #Routes: removed=oldroutes.difference(newroutes) added=newroutes.difference(oldroutes) updated=newroutes.intersection(oldroutes) print "Removed routes:",removed print "Added routes:",added print "Kept routes: ",updated for rem1,rem2 in removed: meta.Session.query(Route).filter( sa.and_(Route.user==tripuser(),Route.trip==trip.trip, Route.waypoint1==rem1,Route.waypoint2==rem2)).delete() sel_acs=meta.Session.query(Aircraft).filter(sa.and_( Aircraft.aircraft==trip.aircraft,Aircraft.user==tripuser())).all() if len(sel_acs): tas=sel_acs[0].cruise_speed else: tas=75 for a1,a2 in added: cruisealt="" a=None if a1 in addedwps: startord=resultant_id2order.get(int(a1),0) elif a2 in addedwps: startord=resultant_id2order.get(int(a2),0) else: startord=resultant_id2order.get(int(a1),0) print "Ordering of new wp: %d is %d"%(a1,startord) num_waypoints=len(resultant_by_order) def searchpattern(begin,num): assert begin>=0 and begin<num down=begin-1 up=begin+1 while True: work=False if down>=0: yield down down-=1 work=True if up<num: yield up up+=1 work=True if not work: break for wpord in searchpattern(startord,num_waypoints): wp=resultant_by_order.get(wpord,None) print "Searchpattern visiting order: %d"%(wpord,) if wp: if wpord<startord: cruisealt=prevalts.get((wp.id,+1),'') print "Looking for alt previously after wp %d, got: %s"%(wp.id,cruisealt) else: cruisealt=prevalts.get((wp.id,-1),'') print "Looking for alt previously before wp %d, got: %s"%(wp.id,cruisealt) if cruisealt!="": break if cruisealt=="": cruisealt="1500" r=Route(tripuser(),trip.trip, a1,a2,0,0,tas,None,cruisealt) meta.Session.add(r) session.save() meta.Session.flush() meta.Session.commit(); ret=json.dumps([tripname]) print "mapview returning json:",ret return ret except Exception,cause: #print line number and stuff as well print cause #TODO: ONLY FOR TESTING!!!! raise return "notok"
def generate_work_packages(tma, blobs, cachedir, maxzoomlevel=13, meta=0, cutoff=8): meta = meta #Change back to if using mapnik #if meta==0: # print "\n\n\n\n\n=====================================================================\nWARNING! meta==0!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n" packcnt = 0 for zoomlevel in xrange(maxzoomlevel + 1): if zoomlevel <= cutoff: lat1, lon1, lat2, lon2 = latlon_limits_hd() else: lat1, lon1, lat2, lon2 = latlon_limits() lat1 = float(lat1) lat2 = float(lat2) lon1 = float(lon1) lon2 = float(lon2) maxy = mapper.max_merc_y(zoomlevel) maxx = mapper.max_merc_x(zoomlevel) hd = False if zoomlevel <= cutoff: hd = True limitx1, limity1, limitx2, limity2 = merc_limits(zoomlevel, hd=hd) assert limitx2 > limitx1 assert limity2 > limity1 print "Limits: %f,%f - %f,%f" % (limitx1, limity1, limitx2, limity2) blobs[zoomlevel] = BlobFile( os.path.join(cachedir, "level" + str(zoomlevel)), zoomlevel, limitx1, limity1, limitx2, limity2, 'w') for my1 in xrange(limity1, limity2, 2048): for mx1 in xrange(limitx1, limitx2, 2048): already = True for i in xrange(0, 2048, 256): for j in xrange(0, 2048, 256): if blobs[zoomlevel].get_tile(mx1 + i, my1 + j) == None: already = False break if already: print "Already have %d,%d,%d" % (mx1, my1, zoomlevel) continue print "Creating new tile %d,%d,%d (tma=%s)" % (mx1, my1, zoomlevel, tma) mx2 = mx1 + 2048 my2 = my1 + 2048 if my2 > maxy: my2 = maxy if mx2 > maxx: mx2 = maxx if my1 >= meta: metay1 = meta else: metay1 = 0 if mx1 >= meta: metax1 = meta else: metax1 = 0 if my2 <= maxy - meta: metay2 = meta else: metay2 = 0 if mx2 <= maxx - meta: metax2 = meta else: metax2 = 0 latb, lona = mapper.merc2latlon((mx1, my1), zoomlevel) lata, lonb = mapper.merc2latlon((mx2, my2), zoomlevel) if latb < lat1: continue if lata > lat2: continue if lonb < lon1: continue if lona > lon2: continue coord = (zoomlevel, mx1, my1, mx2, my2) packcnt += 1 yield (coord, dict(checkedout=None, metax1=metax1, metay1=metay1, metax2=metax2, metay2=metay2, render_tma=tma)) print "Finished initializing work. Created %d work items. Cutoff=%d" % ( packcnt, cutoff)
def show(self): ad = request.params['ad'] cksum = request.params['checksum'] chartobj = None for adobj in ec.get_airfields(): bb = False if adobj['name'] == ad and 'adcharts' in adobj: for adchart in adobj['adcharts'].values(): if adchart['checksum'] == cksum: chartobj = adchart bb = True break if bb: break else: self.error("No such airport/picture " + ad + "/" + cksum) projs = meta.Session.query(AirportProjection).filter( sa.and_( AirportProjection.user == session['user'], AirportProjection.airport == ad, AirportProjection.mapchecksum == adchart['checksum'])).all() c.markers = meta.Session.query(AirportMarker).filter( sa.and_( AirportMarker.user == session['user'], AirportMarker.airport == ad, AirportMarker.mapchecksum == adchart['checksum'])).order_by( AirportMarker.latitude, AirportMarker.longitude, AirportMarker.x, AirportMarker.y).all() if not projs: proj = AirportProjection() proj.user = session['user'] proj.airport = ad proj.mapchecksum = str(adchart['checksum']) proj.updated = datetime.utcnow() proj.matrix = (1, 0, 0, 1, 0, 0) proj.scale = None proj.north = None meta.Session.add(proj) meta.Session.flush() meta.Session.commit() else: proj, = projs proj.mapchecksum = str(proj.mapchecksum) if all([x == 0 for x in proj.matrix[4:6]]): projmatrix = self.invent_matrix(proj.mapchecksum, adchart['variant']) else: projmatrix = proj.matrix A = projmatrix[0:4] T = projmatrix[4:6] transform = customproj.Transform(A, T) c.matrix = projmatrix c.initial_scroll_x = request.params.get("scroll_x", 0) c.initial_scroll_y = request.params.get("scroll_y", 0) c.maptype = request.params.get("maptype", "chart") c.variant = adchart['variant'] c.curadmarker = session.get('curadmarker', (0, 0)) c.img = adchart['blobname'] + "," + adchart['checksum'] c.flash = None c.ad = ad c.mapchecksum = adchart['checksum'] c.mapsize = adchart.get('mapsize', (210, 297)) c.scale = proj.scale if proj.scale != None else "" c.north = proj.north if proj.north != None else "" c.runways = [] c.arp = transform.to_pixels(mapper.from_str(adobj['pos'])) arp1m = mapper.latlon2merc(mapper.from_str(adobj['pos']), 17) arp2m = mapper.latlon2merc(mapper.from_str(adobj['pos']), 17) arp1m = (arp1m[0], arp1m[1] - 250) arp2m = (arp2m[0] + 250, arp2m[1]) c.arp1 = transform.to_pixels(mapper.merc2latlon(arp1m, 17)) c.arp2 = transform.to_pixels(mapper.merc2latlon(arp2m, 17)) def dist(x, y): return math.sqrt((x[0] - y[0])**2 + (x[1] - y[1])**2) c.ratio = abs(dist(c.arp, c.arp1) - dist(c.arp, c.arp2)) / max( dist(c.arp, c.arp1), dist(c.arp, c.arp2)) c.transform_reasonable = True x, y = c.arp if x < -200 or y < -200 or x >= 4000 or y >= 4000: c.transform_reasonable = False c.revmarkers = [] c.width, c.height = chartobj['render_width'], chartobj['render_height'] try: c.base_coords=\ [mapper.latlon2merc(transform.to_latlon((0,0)),13), mapper.latlon2merc(transform.to_latlon((c.width,0)),13), mapper.latlon2merc(transform.to_latlon((0,c.height)),13), mapper.latlon2merc(transform.to_latlon((c.width,c.height)),13)] except Exception: print "problem with basecoords:", traceback.format_exc() c.base_coords = [(0, 0) for x in xrange(4)] for mark in c.markers: lat, lon = transform.to_latlon((mark.x, mark.y)) if mark.latitude: lat = mark.latitude if mark.longitude: lon = mark.longitude pos = transform.to_pixels((lat, lon)) c.revmarkers.append(pos) for rwy in adobj.get('runways', []): ends = rwy['ends'] latlon1 = mapper.from_str(ends[0]['pos']) latlon2 = mapper.from_str(ends[1]['pos']) print rwy, "Runway pos", latlon1, " to ", latlon2 p1 = transform.to_pixels(latlon1) p2 = transform.to_pixels(latlon2) for p in [p1, p2]: x, y = p if x < -200 or y < -200 or x >= 4000 or y >= 4000: c.transform_reasonable = False c.runways.append( ((int(p1[0]), int(p1[1])), (int(p2[0]), int(p2[1])))) c.random = md5.md5(pickle.dumps(projmatrix)).hexdigest() return render('/airportproj.mako')
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 save(self): print request.params ad = request.params['ad'] chartobj = None mapchecksum = request.params['mapchecksum'] for adobj in ec.get_airfields(): if adobj['name'] == ad: bb = False for adchart in adobj['adcharts'].values(): if adchart['checksum'] == mapchecksum: chartobj = adchart bb = True break if bb: break else: self.error("No such airport" + ad) marks = dict() for param, val in request.params.items(): if param in [ "save", "ad", 'mapchecksum', 'scroll_x', 'scroll_y', 'maptype', 'scale', 'north' ]: continue if param.startswith("del"): continue if param.startswith("set_"): x, y = [int(v) for v in param.split("_")[1:]] session['curadmarker'] = (x, y) session.save() continue if param == "add": xs = meta.Session.query(AirportMarker.x).filter( sa.and_(AirportMarker.user == session['user'], AirportMarker.airport == ad)).all() if xs: maxx = max(xs)[0] + 1 else: maxx = 0 marks[(maxx, 0)] = dict(latitude=None, longitude=None, x=maxx, y=0) session['curadmarker'] = (maxx, 0) session.save() continue sx, sy, attrib = re.match(ur"mark_(\d+)_(\d+)_(\w*)", param).groups() x = int(sx) y = int(sy) marks.setdefault((x, y), dict())[attrib] = val thresholds = dict() for rwy in adobj.get('runways', []): ends = rwy['ends'] for end in ends: thresholds[end['thr']] = mapper.from_str(end['pos']) for param, val in request.params.items(): if param.startswith("del_"): x, y = [int(v) for v in param.split("_")[1:]] marks.pop((x, y)) continue meta.Session.query(AirportMarker).filter( sa.and_(AirportMarker.user == session['user'], AirportMarker.airport == ad)).delete() ms = [] arppos = mapper.from_str(adobj['pos']) for (x, y), val in marks.items(): m = AirportMarker() m.user = session['user'] m.airport = ad m.mapchecksum = str(mapchecksum) m.x = int(val['x']) m.y = int(val['y']) m.latitude, w1 = parselatlon(val['latitude'], arppos, thresholds, 0) m.longitude, w2 = parselatlon(val['longitude'], arppos, thresholds, 1) if w1 or w2: m.weight = w1 + w2 else: m.weigth = 1 meta.Session.add(m) ms.append(m) proj = meta.Session.query(AirportProjection).filter( sa.and_(AirportProjection.user == session['user'], AirportProjection.airport == ad, AirportProjection.mapchecksum == str(mapchecksum))).one() try: proj.scale = float(request.params['scale'].strip()) except: proj.scale = None try: proj.north = float(request.params['north'].strip()) except: proj.north = None def both_lat_lon(x): return x.latitude and x.longitude def neither_lat_lon(x): return not x.latitude and not x.longitude def just_lat(x): return x.latitude and not x.longitude def just_lon(x): return not x.latitude and x.longitude ms = [m for m in ms if not neither_lat_lon(m)] """ if (len(ms)==4 and len([m for m in ms if just_lat(m)])==2 and len([m for m in ms if just_lon(m)])==2): extra=[] for m in ms: n=AirportMarker() n.x=m.x n.y=m.y if just_lat(m): n.latitude=m.latitude n.x+=1000 extra.append(n) if just_lon(m): n.y+=1000 n.longitude=m.longitude extra.append(n) ms.extend(extra) """ if len(ms) == 1 and both_lat_lon( ms[0]) and proj.scale and proj.north != None: print "Scale/north triggered" print "Adchart:", chartobj if chartobj != None: render_height = chartobj['render_height'] mark, = ms pixelpos = (mark.x, mark.y) mapsize = adchart.get('mapsize', (210, 297)) mapheight_meter = mapsize[1] / 1000.0 * proj.scale mapheight_km = mapheight_meter / 1000.0 merc = mapper.latlon2merc((mark.latitude, mark.longitude), 17) pixels = mapper.approx_scale(merc, 17, mapheight_km / 1.852) newmerc = (merc[0], merc[1] - pixels) northrad = proj.north / (180.0 / math.pi) newpixelpos = (pixelpos[0] + render_height * math.sin(northrad), pixelpos[1] - render_height * math.cos(northrad)) m = AirportMarker() m.x = newpixelpos[0] m.y = newpixelpos[1] latlon = mapper.merc2latlon(newmerc, 17) m.latitude = latlon[0] m.longitude = latlon[1] m.weight = 1 ms.append(m) if len(ms) == 2 and all(both_lat_lon(x) for x in ms): print "Have exactly two marks now" mark1, mark2 = ms lm1, lm2 = [ mapper.latlon2merc((mark.latitude, mark.longitude), 17) for mark in [mark1, mark2] ] ld = (lm2[0] - lm1[0], lm2[1] - lm1[1]) pd = (mark2.x - mark1.x, mark2.y - mark1.y) lm3 = (lm1[0] - ld[1], lm1[1] + ld[0]) pm3 = (mark1.x - pd[1], mark1.y + pd[0]) llm3 = mapper.merc2latlon(lm3, 17) m = AirportMarker() m.x = pm3[0] m.y = pm3[1] m.latitude, w1 = llm3[0], 1 m.longitude, w2 = llm3[1], 1 ms.append(m) print "delta pixels", pd print "delta latlon", ld print "extra end pixels", m.x, m.y print "extra end latlon", m.latitude, m.longitude eqns = 0 for m in ms: if both_lat_lon(m): eqns += 2 elif just_lat(m): eqns += 1 elif just_lon(m): eqns += 1 try: if eqns < 4: raise Exception("Unsolvable") error, A, T = customproj.solve(ms) matrix = list(A) + list(T) if proj.matrix: oldmatrix = list(proj.matrix) newmatrix = list(A) + list(T) diff = sum(abs(a - b) for a, b in zip(oldmatrix, newmatrix)) else: diff = 1e30 #enough to trigger update if diff > 1e-12: proj.matrix = tuple(newmatrix) proj.updated = datetime.utcnow().replace(microsecond=0) except Exception, cause: print "Couldn't solve projection equation %s" % (cause, ) proj.matrix = [1, 0, 0, 1, 0, 0] proj.updated = datetime.utcnow().replace(microsecond=0) meta.Session.add(proj)
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 generate_big_tile(pixelsize,x1,y1,zoomlevel,osmdraw,tma=False,return_format="PIL",user=None,only_user=False): """ set osmdraw==True and make sure a full working openstreetmap mapnik environment is available, in order to draw using mapnik. If false, a basemap must already have been drawn, and all that can be done is that new airspaces etc an be filled in. """ def only(x): if only_user: #print "Ignoring ",len(x) return [] return x print "TMA:",tma imgx,imgy=pixelsize assert osmdraw in [True,False] if not osmdraw: #osmdraw should probably be renamed use 'use_existing_basemap' print "Making %dx%d tile at %s/%s, zoomlevel: %d"%(pixelsize[0],pixelsize[1],x1,y1,zoomlevel) print "Generating tile" print "mapnikstyle file:",os.getenv("SWFP_MAPNIK_STYLE") mapfile = os.path.join(os.getenv("SWFP_MAPNIK_STYLE"),"osm.xml") #--------------------------------------------------- # Change this to the bounding box you want # # lon lat lon lat #ll = (center[1], hilat, center[1], lolat) #--------------------------------------------------- lat1,lon1=mapper.merc2latlon((x1,y1),zoomlevel) lat2,lon2=mapper.merc2latlon((x1+imgx,y1+imgy),zoomlevel) m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) c0 = prj.forward(mapnik.Coord(lon1,lat1)) c1 = prj.forward(mapnik.Coord(lon2,lat2)) if hasattr(mapnik,'mapnik_version') and mapnik.mapnik_version() >= 800: #bbox = mapnik.Box2d(0,0,256<<zoomlevel,256<<zoomlevel) bbox = mapnik.Box2d(c0.x,c0.y,c1.x,c1.y) else: bbox = mapnik.Envelope(c0.x,c0.y,c1.x,c1.y) #bbox = mapnik.Envelope(0,0,256<<zoomlevel,256<<zoomlevel) m.zoom_to_box(bbox) im = mapnik.Image(imgx,imgy) mapnik.render(m, im) buf=im.tostring() #print "len im tostring:" ,len(buf) assert len(buf)%4==0 num_pixels=len(buf)/4 as_array=numpy.fromstring(buf,numpy.dtype("u1")) assert len(as_array)==len(buf) r,g,b,a=numpy.hsplit(as_array.reshape(num_pixels,4),(1,2,3)) assert len(r)==num_pixels print "Num pixels: ",num_pixels swapped=numpy.column_stack((b,g,r,a)).reshape(4*num_pixels) assert len(swapped)==num_pixels*4 assert num_pixels==imgx*imgy im=cairo.ImageSurface.create_for_data(swapped,cairo.FORMAT_RGB24,imgx,imgy) #as_array=numpy.fromstring(buf,numpy.dtype("u4")) #as_array.byteswap(True) else: #print "Reading existing map instead" im=Image.new("RGBA",(imgx,imgy)) for i in xrange(0,pixelsize[0],256): for j in xrange(0,pixelsize[1],256): rawtile,tilemeta=maptilereader.gettile("plain",zoomlevel,x1+i,y1+j) io=StringIO.StringIO(rawtile) io.seek(0) sub=Image.open(io) im.paste(sub,(i,j,i+256,j+256)) buf=im.tostring() #print "len im tostring:" ,len(buf) assert len(buf)%4==0 num_pixels=len(buf)/4 assert num_pixels==imgx*imgy as_array=numpy.fromstring(buf,numpy.dtype("u1")) assert len(as_array)==len(buf) r,g,b,a=numpy.hsplit(as_array.reshape(num_pixels,4),(1,2,3)) assert len(r)==num_pixels #print "Num pixels: ",num_pixels swapped=numpy.column_stack((b,g,r,a)).reshape(4*num_pixels) im=cairo.ImageSurface.create_for_data(swapped,cairo.FORMAT_RGB24,imgx,imgy) ctx=cairo.Context(im) if tma: def tolocal(merc): return (merc[0]-x1,merc[1]-y1) merc13=mapper.merc2merc((x1-50,y1-50),zoomlevel,13) merc13b=mapper.merc2merc((x1+imgx+50,y1+imgy+50),zoomlevel,13) bb13=BoundingBox(merc13[0],merc13[1],merc13b[0],merc13b[1]) bycolor=dict() for space in chain( only(get_airspaces_in_bb2(bb13)),get_notam_objs_cached()['areas'], only(get_aip_sup_areas()),get_firs(),userdata.get_all_airspaces(user)): if space['type']=='sector': continue #Don't draw "sectors" vertices=[] for coord in space['points']: merc=mapper.latlon2merc(mapper.from_str(coord),zoomlevel) vertices.append(tolocal(merc))#merc[0]-x1,merc[1]-y1) try: areacol,solidcol=get_airspace_color(space['type']) except Exception: print space raise bycolor.setdefault((areacol,solidcol),[]).append(vertices) def colorsorter(col): if col[0]>0.5: return (110,0,0,0) return col for (areacol,solidcol),polygons in sorted(bycolor.items(),key=lambda x:colorsorter(x[0])): if areacol[3]<=0.05: continue surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, imgx, imgy) ctx2=cairo.Context(surface2) ctx2.set_operator(cairo.OPERATOR_DEST_OUT) ctx2.rectangle(0,0,imgx,imgy) ctx2.set_source(cairo.SolidPattern(0,0,0,1.0)) ctx2.paint() ctx2.set_operator(cairo.OPERATOR_OVER) for poly in polygons: ctx2.new_path() for vert in poly: ctx2.line_to(*vert) ctx2.close_path() ctx2.set_source(cairo.SolidPattern(areacol[0],areacol[1],areacol[2],1.0)) ctx2.fill_preserve() ctx2.set_operator(cairo.OPERATOR_DEST_OUT) ctx2.rectangle(0,0,imgx,imgy) ctx2.set_source(cairo.SolidPattern(0,0,0,1.0-areacol[3])) ctx2.paint() #ctx2.set_operator(cairo.OPERATOR_OVER) ctx.set_source_surface(surface2) ctx.rectangle(0,0,imgx,imgy) ctx.paint() for (areacol,solidcol),polygons in sorted(bycolor.items(),key=lambda x:colorsorter(x[1])): for poly in polygons: ctx.new_path() for vert in poly: ctx.line_to(*vert) ctx.close_path() ctx.set_source(cairo.SolidPattern(*solidcol)) ctx.stroke() for obst in chain(only(get_obstacles_in_bb(bb13)),userdata.get_all_obstacles(user)): if zoomlevel>=9: ctx.set_source(cairo.SolidPattern(1.0,0.0,1.0,0.25)) merc=mapper.latlon2merc(mapper.from_str(obst['pos']),zoomlevel) pos=tolocal(merc)#(merc[0]-x1,merc[1]-y1) radius=parse_obstacles.get_pixel_radius(obst,zoomlevel) ctx.new_path() ctx.arc(pos[0],pos[1],radius,0,2*math.pi) ctx.fill_preserve() ctx.set_source(cairo.SolidPattern(1.0,0.0,1.0,0.75)) ctx.new_path() ctx.arc(pos[0],pos[1],radius,0,2*math.pi) ctx.stroke() for sigp in chain(only(get_sig_points_in_bb(bb13)),userdata.get_all_sigpoints(user)): if zoomlevel>=9: #print sigp if zoomlevel==9 and sigp.get('kind','') in ['entry/exit point','holding point']: continue if sigp.get('kind','') in ['town','city']:continue merc=mapper.latlon2merc(mapper.from_str(sigp['pos']),zoomlevel) pos=tolocal(merc)#(merc[0]-x1,merc[1]-y1) ctx.set_source(cairo.SolidPattern(0.0,0.0,1.0,0.65)) ctx.new_path() ctx.line_to(pos[0],pos[1]-3) ctx.line_to(pos[0]+3,pos[1]) ctx.line_to(pos[0],pos[1]+3) ctx.line_to(pos[0]-3,pos[1]) ctx.close_path() ctx.stroke() for notamtype,items in get_notam_objs_cached().items(): if notamtype=="areas": continue for item in items: if zoomlevel>=8: ctx.set_source(cairo.SolidPattern(0.25,1,0.25,0.25)) merc=mapper.latlon2merc(mapper.from_str(item['pos']),zoomlevel) pos=tolocal(merc)#(merc[0]-x1,merc[1]-y1) radius=5 ctx.new_path() ctx.arc(pos[0],pos[1],radius,0,2*math.pi) ctx.fill_preserve() ctx.set_source(cairo.SolidPattern(0,1.0,0,0.75)) ctx.new_path() ctx.arc(pos[0],pos[1],radius,0,2*math.pi) ctx.stroke() for airfield in chain(only(get_airfields_in_bb(bb13)),userdata.get_all_airfields(user)): if zoomlevel<6: continue ctx.set_source(cairo.SolidPattern(0.8,0.5,1.0,0.25)) merc=mapper.latlon2merc(mapper.from_str(airfield['pos']),zoomlevel) pos=(merc[0]-x1,merc[1]-y1) if zoomlevel<=11: radius=5 else: radius=5<<(zoomlevel-11) ctx.new_path() ctx.arc(pos[0],pos[1],radius,0,2*math.pi) ctx.fill_preserve() ctx.set_source(cairo.SolidPattern(0.8,0.5,1.0,0.75)) ctx.new_path() ctx.arc(pos[0],pos[1],radius,0,2*math.pi) ctx.stroke() for rwy in airfield.get('runways',[]): ends=rwy['ends'] mercs=[] #print "Ends:",ends surface=rwy.get('surface','hard').lower() for end in ends: #print "pos:",end['pos'] latlon=mapper.from_str(end['pos']) #print "latlon:",latlon merc=mapper.latlon2merc(latlon,zoomlevel) #print "Merc:",merc mercs.append(merc) if len(mercs)==2: a,b=mercs #print "Drawing:",airfield['icao'],a,b if surface=='gravel': ctx.set_source(cairo.SolidPattern(0.5,0.3,0.0,1)) elif surface=='grass': ctx.set_source(cairo.SolidPattern(0.0,0.65,0.0,1)) else: ctx.set_source(cairo.SolidPattern(0.0,0.0,0.0,1)) lwidth=mapper.approx_scale(a,zoomlevel,40.0/1852.0) if lwidth<=2: lwidth=2.0 ctx.set_line_width(lwidth) ctx.new_path() ctx.move_to(*tolocal(a)) ctx.line_to(*tolocal(b)) ctx.stroke() if return_format=="PIL": b,g,r,a=numpy.hsplit(swapped.reshape(num_pixels,4),(1,2,3)) back=numpy.column_stack((r,g,b)).reshape(3*num_pixels) im=Image.frombuffer("RGB",(imgx,imgy),back,'raw','RGB',0,1) else: assert return_format=="cairo" pass #print "Returning rendered image and map" return im
def save(self): try: if 'pos' in request.params and 'zoomlevel' in request.params: save_merc_x, save_merc_y = [ int(x) for x in request.params['pos'].split(",") ] save_zoom = int(request.params['zoomlevel']) pos = mapper.merc2latlon((save_merc_x, save_merc_y), save_zoom) self.set_pos_zoom(pos, save_zoom) wps = self.get_waypoints(request.params) oldname = request.params.get('oldtripname', '') tripname = request.params.get('tripname', '') if tripsharing.sharing_active(): #Can't rename trips while tripsharing is active! tripname = session['current_trip'] if oldname != session['current_trip']: #In some strange way a non-tripsharing oldname appeared in the post. This #means that something has gone awry. Don't save! print "Bad trip oldname while tripsharing active!" return "notok" if 'showarea' in request.params and request.params['showarea']: sha = request.params['showarea'] if (sha == '.'): session['showarea'] = '' session['showarea_id'] = '' session['showtrack'] = None else: session['showarea'] = sha session['showarea_id'] = md5( sha.encode('utf8')).hexdigest() session['showtrack'] = None session['mapvariant'] = request.params.get('mapvariant', 'airspace') #print "Req:",request.params oldtrip = None if not oldname.strip(): oldname = tripname oldtrips = meta.Session.query(Trip).filter( sa.and_(Trip.user == tripuser(), Trip.trip == oldname)).all() if len(oldtrips) == 1: oldtrip = oldtrips[0] if oldtrip: trip = oldtrip if trip.trip != tripname: if tripsharing.sharing_active(): #attempt to rename someone elses trip! Can't be allowed! set tripname to old name print "Attempt to rename trip while viewing shared trip (tripsharing)" return "notok" else: trip.trip = self.get_free_tripname(tripname) if session[ 'current_trip'] != trip.trip and tripsharing.sharing_active( ): #internal error if we get here - the earlier test for current_trip not changing failed. print "Unexpected tripsharing error #2" return "notok" session['current_trip'] = trip.trip else: if tripsharing.sharing_active(): #we use sharing, but the shared trip can't be found! print "Tripsharing active, but named trip didn't exist (deleted, probably)" return "notok" tripname = self.get_free_tripname(tripname) trip = Trip(tripuser(), tripname) acs = meta.Session.query(Aircraft).filter( sa.and_(Aircraft.user == tripuser())).all() if len(acs): trip.aircraft = acs[0].aircraft meta.Session.add(trip) session['current_trip'] = tripname oldwps = set([(wp.id) for wp in meta.Session.query(Waypoint).filter( sa.and_(Waypoint.user == tripuser(), Waypoint.trip == trip.trip)).all()]) newwps = set(wps.keys()) #print "NEW WPS",wps removed = oldwps.difference(newwps) added = newwps.difference(oldwps) updated = newwps.intersection(oldwps) print "Removed: ", removed addedwps = added removedwps = removed updatedwps = updated ordering2wpid = dict() for remord in removed: meta.Session.query(Waypoint).filter( sa.and_(Waypoint.user == tripuser(), Waypoint.trip == trip.trip, Waypoint.id == remord)).delete() #print "\n\n====DELETING!=====\n%s\n\n"%(rem,) resultant_by_order = dict() resultant_id2order = dict() waypointlink = dict() for add in added: wp = wps[add] waypoint = Waypoint(tripuser(), trip.trip, wp['pos'], int(wp['id']), int(wp['ordering']), wp['name'], wp['altitude']) resultant_by_order[int(wp['ordering'])] = waypoint resultant_id2order[int(wp['id'])] = wp['ordering'] #print "\n\n====ADDING!=====\n%s %s %s\n\n"%(waypoint.id,waypoint.pos,waypoint.waypoint) meta.Session.add(waypoint) for upd in updated: wp = wps[upd] us = meta.Session.query(Waypoint).filter( sa.and_(Waypoint.user == tripuser(), Waypoint.trip == trip.trip, Waypoint.id == upd)).all() if len(us) > 0: u = us[0] prevpos = mapper.from_str(u.pos) newpos = mapper.from_str(wp['pos']) approxdist = (prevpos[0] - newpos[0])**2 + (prevpos[1] - newpos[1])**2 if approxdist > ( 1.0 / 36000.0 )**2: #if moved more than 0.1 arc-second, otherwise leave be. u.pos = wp['pos'] print "Waypoint %d moved! (%f deg)" % ( u.id, math.sqrt(approxdist)) else: print "Waypoint %d has only moved a little (%f deg)" % ( u.id, math.sqrt(approxdist)) u.waypoint = wp['name'] assert u.id == int(wp['id']) u.ordering = wp['ordering'] u.altitude = wp['altitude'] resultant_by_order[int(wp['ordering'])] = u resultant_id2order[int(wp['id'])] = wp['ordering'] #print "\n\n====UPDATING!=====\n%s %s %s\n\n"%(u.id,u.pos,u.waypoint) #print "Resultant by ordering: %s"%(resultant_by_order,) seq = list(sorted(resultant_by_order.items())) newroutes = set() for (ord1, waypoint1), (ord2, waypoint2) in zip(seq[:-1], seq[1:]): if not int(ord1) + 1 == int(ord2): print "Waypoints %s and %s not consecutive (#%d, #%d)" % ( waypoint1, waypoint2, int(ord1), int(ord2)) assert int(ord1) + 1 == int(ord2) newroutes.add((waypoint1.id, waypoint2.id)) oldrouteobjs = list( meta.Session.query(Route).filter( sa.and_(Route.user == tripuser(), Route.trip == trip.trip)).all()) oldroutes = set([(route.waypoint1, route.waypoint2) for route in oldrouteobjs]) prevalts = dict() for rt in oldrouteobjs: prevalts[(rt.a.id, +1)] = rt.altitude prevalts[(rt.b.id, -1)] = rt.altitude #Routes: removed = oldroutes.difference(newroutes) added = newroutes.difference(oldroutes) updated = newroutes.intersection(oldroutes) print "Removed routes:", removed print "Added routes:", added print "Kept routes: ", updated for rem1, rem2 in removed: meta.Session.query(Route).filter( sa.and_(Route.user == tripuser(), Route.trip == trip.trip, Route.waypoint1 == rem1, Route.waypoint2 == rem2)).delete() sel_acs = meta.Session.query(Aircraft).filter( sa.and_(Aircraft.aircraft == trip.aircraft, Aircraft.user == tripuser())).all() if len(sel_acs): tas = sel_acs[0].cruise_speed else: tas = 75 for a1, a2 in added: cruisealt = "" a = None if a1 in addedwps: startord = resultant_id2order.get(int(a1), 0) elif a2 in addedwps: startord = resultant_id2order.get(int(a2), 0) else: startord = resultant_id2order.get(int(a1), 0) print "Ordering of new wp: %d is %d" % (a1, startord) num_waypoints = len(resultant_by_order) def searchpattern(begin, num): assert begin >= 0 and begin < num down = begin - 1 up = begin + 1 while True: work = False if down >= 0: yield down down -= 1 work = True if up < num: yield up up += 1 work = True if not work: break for wpord in searchpattern(startord, num_waypoints): wp = resultant_by_order.get(wpord, None) print "Searchpattern visiting order: %d" % (wpord, ) if wp: if wpord < startord: cruisealt = prevalts.get((wp.id, +1), '') print "Looking for alt previously after wp %d, got: %s" % ( wp.id, cruisealt) else: cruisealt = prevalts.get((wp.id, -1), '') print "Looking for alt previously before wp %d, got: %s" % ( wp.id, cruisealt) if cruisealt != "": break if cruisealt == "": cruisealt = "1500" r = Route(tripuser(), trip.trip, a1, a2, 0, 0, tas, None, cruisealt) meta.Session.add(r) session.save() meta.Session.flush() meta.Session.commit() ret = json.dumps([tripname]) print "mapview returning json:", ret return ret except Exception, cause: #print line number and stuff as well print cause #TODO: ONLY FOR TESTING!!!! raise return "notok"