Пример #1
0
    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']])
Пример #2
0
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
Пример #3
0
 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))
Пример #4
0
    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']])
Пример #5
0
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
Пример #6
0
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
Пример #7
0
    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()
Пример #8
0
 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()
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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    
Пример #15
0
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
Пример #16
0
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
Пример #17
0
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
Пример #18
0
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()
Пример #19
0
 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
Пример #20
0
    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
Пример #21
0
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()
Пример #22
0
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)
Пример #23
0
 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))
Пример #24
0
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
Пример #25
0
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)
Пример #26
0
 def getdist_meter(p1, p2):
     brg, dist = mapper.bearing_and_distance(
         mapper.merc2latlon(p1, 20), mapper.merc2latlon(p2, 20))
     return dist * 1852.0
Пример #27
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
Пример #28
0
 def getdist_meter(p1,p2):
     brg,dist=mapper.bearing_and_distance(mapper.merc2latlon(p1,20),mapper.merc2latlon(p2,20))
     return dist*1852.0
Пример #29
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"))
Пример #30
0
    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')
Пример #31
0
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
Пример #32
0
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
Пример #33
0
    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')
Пример #34
0
    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)
Пример #35
0
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
Пример #36
0
    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')
Пример #37
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"))
Пример #38
0
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
Пример #39
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
Пример #40
0
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)
Пример #41
0
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)
Пример #42
0
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
Пример #43
0
    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)))
Пример #44
0
    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)))
Пример #45
0
    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"        
Пример #46
0
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)
Пример #47
0
    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')
Пример #48
0
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
Пример #49
0
    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)
Пример #50
0
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)
Пример #51
0
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
Пример #52
0
    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"