Esempio n. 1
0
def get_stuff_near_route(rts,items,dist,vertdist):
    for item in items:
        try:
            itemmerc=mapper.latlon2merc(mapper.from_str(item['pos']),13)
        except Exception:
            print "Bad coord:",item['pos']
            continue
        itemv=Vertex(int(itemmerc[0]),int(itemmerc[1]))
        onenm=mapper.approx_scale(itemmerc,13,1.0)
        for rt in rts:
            if rt.dt==None: continue
            #print "========================================="
            av=Vertex(int(rt.subposa[0]),int(rt.subposa[1]))
            bv=Vertex(int(rt.subposb[0]),int(rt.subposb[1]))
            l=Line(av,bv)
            linelen=(bv-av).approxlength()
            actualclosest=l.approx_closest(itemv)
            #print item['name'],"A: ",av,"B: ",bv,"clo:",actualclosest
            actualdist=(actualclosest-itemv).approxlength()/onenm
            #print "Actualdist: ",actualdist
            ls=(actualclosest-av).approxlength()
            #print "Length from start:",ls
            #print "Linelen:",linelen
            if linelen>1e-3:
                along=ls/linelen
            else:
                along=0
            #print "Along:",along
            #print "Startalt:",rt.startalt," endalt: ",rt.endalt
            alongnm=rt.d*along
            alongnm_a=rt.relstartd+alongnm
            #print "NM from ",rt.a.waypoint," is ",alongnm_a
            closealt=rt.startalt+(rt.endalt-rt.startalt)*along
            #print "Altitude at point: ",closealt, " before: ",rt.a.waypoint,rt.b.waypoint
            altmargin=0
            if 'elev' in item:
                itemalt=mapper.parse_elev(item['elev'])
                altmargin=closealt-itemalt
            else:
                itemalt=None
                altmargin=0
            if actualdist<dist and altmargin<vertdist:
                bear=mapper.approx_bearing_vec(actualclosest,itemv)            
                d=dict(item)
                #print "Yielding."
                d['name']=d['kind']+': ' +d['name']
                d['dist_from_a']=alongnm_a
                d['dist_from_b']=rt.outer_d-alongnm_a
                d['dir_from_a']=describe_dir(rt.tt)
                d['dir_from_b']=describe_dir((rt.tt+180.0)%360.0)
                d['dist']=actualdist
                d['bearing']=bear
                d['elevf']=itemalt
                if itemalt!=None:
                    d['vertmargin']=altmargin
                d['closestalt']=closealt
                d['a']=rt.a
                d['b']=rt.b
                d['id']=rt.a.id
                yield d
Esempio n. 2
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))
Esempio n. 3
0
def get_notampoints_on_line(latlon1,latlon2,dist_nm):
    zoomlevel=13
    distmax=mapper.approx_scale(mapper.latlon2merc(latlon1,zoomlevel),zoomlevel,dist_nm)
    px1,py1=mapper.latlon2merc(latlon1,zoomlevel)
    px2,py2=mapper.latlon2merc(latlon2,zoomlevel)
    a=Vertex(int(px1),int(py1))
    b=Vertex(int(px2),int(py2))
    line=Line(a,b)    
    crosses=[]
    for kind,items in get_notam_objs_cached().items():
        if kind!="areas":
            for item in items:
                x,y=mapper.latlon2merc(mapper.from_str(item['pos']),zoomlevel)
                d=line.approx_dist(Vertex(int(x),int(y)))
                clo=line.approx_closest(Vertex(int(x),int(y)))
                alongd=(clo-a).approxlength()
                totd=(a-b).approxlength()
                #print "AlongD: %s, totd: %s"%(alongd,totd)
                #print "Line: %s, notam coord: %s, closest: %s"%((a,b),(x,y),clo)
                #print "Item %s, d: %s, distmax: %s"%(item,d,distmax)
                if totd<1e-6:
                    perc=0
                else:                    
                    perc=alongd/totd
                if d<distmax:
                    #print "Yielding item."
                    yield dict(item=item,alongperc=perc)
Esempio n. 4
0
def get_pixel_radius(o,zoomlevel):
    merc=mapper.latlon2merc(mapper.from_str(o['pos']),zoomlevel)
    draw_radius_nm=(int(o['height'])*2.0*0.16e-3)
    draw_radius_pixels=mapper.approx_scale(merc,zoomlevel,draw_radius_nm)
    radius=draw_radius_pixels
    if radius<4:
        radius=4
    return radius
Esempio n. 5
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    
Esempio n. 6
0
def get_all_tiles_near(routes,zoomlevel,dist_nm,tilesize):
    resultset=set()
    for rt in routes:
        m1=mapper.latlon2merc(mapper.from_str(rt.a.pos),zoomlevel)
        m2=mapper.latlon2merc(mapper.from_str(rt.b.pos),zoomlevel)
        
        av=Vertex(int(m1[0]),int(m1[1]))
        bv=Vertex(int(m2[0]),int(m2[1]))
        l=Line(av,bv)
        startmerc=clampmerc(m1,tilesize)
        maxdist=mapper.approx_scale(startmerc,zoomlevel,dist_nm)
        maxdist+=3*tilesize/2
        fill(l,startmerc,zoomlevel=zoomlevel,maxdist=maxdist,tilesize=tilesize,result=resultset)
    return resultset
Esempio n. 7
0
def get_terrain_elev_in_box_approx(latlon, nautmiles):
    #nautmiles/=2
    zoomlevel = 8
    merc_ = mapper.latlon2merc(latlon, zoomlevel)
    merc = (int(merc_[0]), int(merc_[1]))
    pixels = mapper.approx_scale(merc, zoomlevel, nautmiles)
    #print "Num pixels on zoomlevel 8",pixels," naut",nautmiles
    del merc
    del merc_
    while pixels > 4 and zoomlevel > 0:
        zoomlevel -= 1
        pixels /= 2
        #print "Pixels on zoom",zoomlevel,": ",pixels
    pixels = int(pixels + 0.5)
    if pixels <= 1: pixels = 1
    if zoomlevel >= 8: zoomlevel = 8

    merc_ = mapper.latlon2merc(latlon, zoomlevel)
    merc = (int(merc_[0]), int(merc_[1]))
    #print "Getting terrain zoomlevel ",zoomlevel
    return get_terrain_elev_merc(merc, zoomlevel, (pixels, pixels))
Esempio n. 8
0
def get_terrain_elev_in_box_approx(latlon,nautmiles):
    #nautmiles/=2
    zoomlevel=8
    merc_=mapper.latlon2merc(latlon,zoomlevel)
    merc=(int(merc_[0]),int(merc_[1]))
    pixels=mapper.approx_scale(merc, zoomlevel, nautmiles)
    #print "Num pixels on zoomlevel 8",pixels," naut",nautmiles
    del merc
    del merc_
    while pixels>4 and zoomlevel>0:
        zoomlevel-=1
        pixels/=2
        #print "Pixels on zoom",zoomlevel,": ",pixels
    pixels=int(pixels+0.5)
    if pixels<=1: pixels=1
    if zoomlevel>=8: zoomlevel=8

    merc_=mapper.latlon2merc(latlon,zoomlevel)
    merc=(int(merc_[0]),int(merc_[1]))
    #print "Getting terrain zoomlevel ",zoomlevel
    return get_terrain_elev_merc(merc,zoomlevel,(pixels,pixels))
Esempio n. 9
0
def filter_bad_airfields(bad,good):
    toadd=[]
    try:
        bspitems=[]
        for item in good:
            bspitems.append(BspTree.Item(                                           
                mapper.latlon2merc(mapper.from_str(item['pos']),13),item) )
        bsp=BspTree(bspitems)
        for abad in bad:
            m=mapper.latlon2merc(mapper.from_str(abad['pos']),13)
            twonm=mapper.approx_scale(m,13,2)   
            bb=BoundingBox(m[0],m[1],m[0],m[1]).expanded(twonm)
            
            for ap in bsp.findall_in_bb(bb):
                print "Not adding bad airfield:",ap.val['name']
                break
            else:
                toadd.append(abad)
    except:
        print "Failed to add bad airfields"
        raise
    return toadd
Esempio n. 10
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))
Esempio n. 11
0
def filter_bad_airfields(bad, good):
    toadd = []
    try:
        bspitems = []
        for item in good:
            bspitems.append(
                BspTree.Item(
                    mapper.latlon2merc(mapper.from_str(item['pos']), 13),
                    item))
        bsp = BspTree(bspitems)
        for abad in bad:
            m = mapper.latlon2merc(mapper.from_str(abad['pos']), 13)
            twonm = mapper.approx_scale(m, 13, 2)
            bb = BoundingBox(m[0], m[1], m[0], m[1]).expanded(twonm)

            for ap in bsp.findall_in_bb(bb):
                print "Not adding bad airfield:", ap.val['name']
                break
            else:
                toadd.append(abad)
    except:
        print "Failed to add bad airfields"
        raise
    return toadd
Esempio n. 12
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
Esempio n. 13
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)
Esempio n. 14
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)
Esempio n. 15
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
Esempio n. 16
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)
Esempio n. 17
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)
Esempio n. 18
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
Esempio n. 19
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