예제 #1
0
    def get_obstacles(self,routes,vertdist=1000.0,interval=10):        
        byid=dict()
        items=chain(notam_geo_search.get_notam_objs_cached()['obstacles'],
                    get_obstacles())
        print "Get terrain"
        for closeitem in chain(geo.get_stuff_near_route(routes,items,3.0,vertdist),
                        geo.get_terrain_near_route(routes,vertdist,interval=interval),
                        geo.get_low_sun_near_route(routes)
                        ):
            byid.setdefault(closeitem['id'],[]).append(closeitem)

        for v in byid.values():
            v.sort(key=lambda x:x['dist_from_a'])                        
        #print byid
        return byid
예제 #2
0
    def get_obstacles(self, routes, vertdist=1000.0, interval=10):
        byid = dict()
        items = chain(notam_geo_search.get_notam_objs_cached()['obstacles'],
                      get_obstacles())
        print "Get terrain"
        for closeitem in chain(
                geo.get_stuff_near_route(routes, items, 3.0, vertdist),
                geo.get_terrain_near_route(routes, vertdist,
                                           interval=interval),
                geo.get_low_sun_near_route(routes)):
            byid.setdefault(closeitem['id'], []).append(closeitem)

        for v in byid.values():
            v.sort(key=lambda x: x['dist_from_a'])
        #print byid
        return byid
예제 #3
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
예제 #4
0
    def get_airspaces(self):
        print "Get airspaces called"

        getsectors = int(request.params.get("sectors", "0"))

        out = []
        if 1:
            for space in extracted_cache.get_airspaces(
            ) + get_notam_objs_cached(
            )['areas'] + extracted_cache.get_aip_sup_areas():
                lat, lon = mapper.from_str(space['points'][0])
                #if lat<57 or lat>62:
                #    continue
                if getsectors == 0 and space.get('type', None) == 'sector':
                    continue
                name = space['name']
                if space['type'] == "notamarea":
                    name = "NOTAM:" + name
                clnd = cleanup_poly(
                    [mapper.from_str(x) for x in space['points']], name)
                if not clnd:
                    print "Skipped area", name, space
                    continue
                out.append(
                    dict(
                        name=name,
                        freqs=space['freqs'] if space.get('freqs', "") else [],
                        floor=space.get('floor', ""),
                        type=space['type'],
                        ceiling=space.get('ceiling', ""),
                        points=[dict(lat=p[0], lon=p[1]) for p in clnd]))

        aiptexts = []
        points = []
        version = request.params.get("version", None)
        getaiptext = int(request.params.get("aip", "0"))
        print "version", version
        if version and int(version.strip()) >= 5:
            user_aipgen = request.params.get("aipgen", "")
        else:
            user_aipgen = ""
        for airp in extracted_cache.get_airfields():
            lat, lon = mapper.from_str(airp['pos'])
            if lat < 54 or lon < 4 or lon >= 30.5:
                try:
                    if not version or int(version.strip()) <= 7:
                        continue
                except:
                    continue

            #if lat<58.5 or lat>60.5:
            #    continue
            aname = airp['name']

            notams = []
            icao = None
            taf = None
            metar = None
            kind = 'field'
            if airp.get('icao', 'zzzz').lower() != 'zzzz':
                icao = airp['icao']
                notams = notam_geo_search.get_notam_for_airport(icao)
                metar = metartaf.get_metar(icao)
                taf = metartaf.get_taf(icao)
                kind = 'port'

            ap = dict(name=aname,
                      lat=lat,
                      lon=lon,
                      kind=kind,
                      notams=notams,
                      remark=airp.get('remark', ''),
                      alt=float(airp.get('elev', 0)))
            if 'runways' in airp:
                ap['runways'] = airp['runways']
            if icao:
                ap['icao'] = icao
                if taf.text:
                    ap['taf'] = taf.text
                if metar.text:
                    ap['metar'] = metar.text

                if getaiptext and 'aiptext' in airp:
                    for aiptext in airp['aiptext']:
                        if aip_text_documents.check_doc(
                                aiptext['icao'], aiptext['category'],
                                aiptext['checksum']):
                            #^^^Okay, this really needs an explanation^^^
                            #Nominally, each aiptext item in aipdata.cache (from which the get_airfields() function
                            #ultimately gets all its data, should always have its corresponding aiptext in html format
                            #available on disk. Now, if the on-disk file is deleted (should never happen), we will
                            #get an exception later down where we try to send this data (with the checksum we have here)
                            #over http to the client. Unfortunately, the routine that sends the data is not at liberty
                            #to modify "what was sent", so the entire sync operation fails. This hack here makes the
                            #failure happen earlier, and in that case the given aiptext-document is suppressed
                            #completely, meaning that the sync operation succeeds, albeit without one specific document
                            #(hey, better than nothing!).
                            #
                            #Of course, the real question is why a document may be missing. A bug of some sort right now,
                            #2012-08-28, makes this bug occur every now and then. Investigation is ongoing.
                            aiptexts.append(
                                dict(name=icao + "_" + aiptext['category'],
                                     icao=icao,
                                     data=aiptext))

            if 'adcharts' in airp and '' in airp['adcharts'] and airp[
                    'adcharts'][""]['blobname']:
                ret = airp['adcharts'][""]
                try:
                    cksum = ret['checksum']
                    try:
                        aprojmatrix = get_proj(cksum).matrix
                    except Exception:
                        #print traceback.format_exc()
                        #print "Using 0-proj for ",aname
                        aprojmatrix = [0 for x in xrange(6)]

                    ap['adchart_matrix'] = list(aprojmatrix)
                    ap['adchart_width'] = ret['render_width']
                    ap['adchart_height'] = ret['render_height']
                    ap['adchart_name'] = ret['blobname']
                    ap['adchart_checksum'] = cksum
                    ap['adchart_url'] = ret['url']
                except Exception, cause:
                    print "Couldn't get projection for airport %s (%s)" % (
                        aname, cause)

            points.append(ap)
예제 #5
0
class ApiController(BaseController):

    no_login_required = True  #But we don't show personal data without user/pass

    def get_airspaces(self):
        print "Get airspaces called"

        getsectors = int(request.params.get("sectors", "0"))

        out = []
        if 1:
            for space in extracted_cache.get_airspaces(
            ) + get_notam_objs_cached(
            )['areas'] + extracted_cache.get_aip_sup_areas():
                lat, lon = mapper.from_str(space['points'][0])
                #if lat<57 or lat>62:
                #    continue
                if getsectors == 0 and space.get('type', None) == 'sector':
                    continue
                name = space['name']
                if space['type'] == "notamarea":
                    name = "NOTAM:" + name
                clnd = cleanup_poly(
                    [mapper.from_str(x) for x in space['points']], name)
                if not clnd:
                    print "Skipped area", name, space
                    continue
                out.append(
                    dict(
                        name=name,
                        freqs=space['freqs'] if space.get('freqs', "") else [],
                        floor=space.get('floor', ""),
                        type=space['type'],
                        ceiling=space.get('ceiling', ""),
                        points=[dict(lat=p[0], lon=p[1]) for p in clnd]))

        aiptexts = []
        points = []
        version = request.params.get("version", None)
        getaiptext = int(request.params.get("aip", "0"))
        print "version", version
        if version and int(version.strip()) >= 5:
            user_aipgen = request.params.get("aipgen", "")
        else:
            user_aipgen = ""
        for airp in extracted_cache.get_airfields():
            lat, lon = mapper.from_str(airp['pos'])
            if lat < 54 or lon < 4 or lon >= 30.5:
                try:
                    if not version or int(version.strip()) <= 7:
                        continue
                except:
                    continue

            #if lat<58.5 or lat>60.5:
            #    continue
            aname = airp['name']

            notams = []
            icao = None
            taf = None
            metar = None
            kind = 'field'
            if airp.get('icao', 'zzzz').lower() != 'zzzz':
                icao = airp['icao']
                notams = notam_geo_search.get_notam_for_airport(icao)
                metar = metartaf.get_metar(icao)
                taf = metartaf.get_taf(icao)
                kind = 'port'

            ap = dict(name=aname,
                      lat=lat,
                      lon=lon,
                      kind=kind,
                      notams=notams,
                      remark=airp.get('remark', ''),
                      alt=float(airp.get('elev', 0)))
            if 'runways' in airp:
                ap['runways'] = airp['runways']
            if icao:
                ap['icao'] = icao
                if taf.text:
                    ap['taf'] = taf.text
                if metar.text:
                    ap['metar'] = metar.text

                if getaiptext and 'aiptext' in airp:
                    for aiptext in airp['aiptext']:
                        if aip_text_documents.check_doc(
                                aiptext['icao'], aiptext['category'],
                                aiptext['checksum']):
                            #^^^Okay, this really needs an explanation^^^
                            #Nominally, each aiptext item in aipdata.cache (from which the get_airfields() function
                            #ultimately gets all its data, should always have its corresponding aiptext in html format
                            #available on disk. Now, if the on-disk file is deleted (should never happen), we will
                            #get an exception later down where we try to send this data (with the checksum we have here)
                            #over http to the client. Unfortunately, the routine that sends the data is not at liberty
                            #to modify "what was sent", so the entire sync operation fails. This hack here makes the
                            #failure happen earlier, and in that case the given aiptext-document is suppressed
                            #completely, meaning that the sync operation succeeds, albeit without one specific document
                            #(hey, better than nothing!).
                            #
                            #Of course, the real question is why a document may be missing. A bug of some sort right now,
                            #2012-08-28, makes this bug occur every now and then. Investigation is ongoing.
                            aiptexts.append(
                                dict(name=icao + "_" + aiptext['category'],
                                     icao=icao,
                                     data=aiptext))

            if 'adcharts' in airp and '' in airp['adcharts'] and airp[
                    'adcharts'][""]['blobname']:
                ret = airp['adcharts'][""]
                try:
                    cksum = ret['checksum']
                    try:
                        aprojmatrix = get_proj(cksum).matrix
                    except Exception:
                        #print traceback.format_exc()
                        #print "Using 0-proj for ",aname
                        aprojmatrix = [0 for x in xrange(6)]

                    ap['adchart_matrix'] = list(aprojmatrix)
                    ap['adchart_width'] = ret['render_width']
                    ap['adchart_height'] = ret['render_height']
                    ap['adchart_name'] = ret['blobname']
                    ap['adchart_checksum'] = cksum
                    ap['adchart_url'] = ret['url']
                except Exception, cause:
                    print "Couldn't get projection for airport %s (%s)" % (
                        aname, cause)

            points.append(ap)
        for sigp in extracted_cache.get_sig_points():
            lat, lon = mapper.from_str(sigp['pos'])
            kind = sigp.get('kind', 'sigpoint')
            if kind == 'sig. point':
                kind = 'sigpoint'
            if not kind in ['sigpoint', 'city', 'town']:
                kind = 'sigpoint'
            points.append(
                dict(name=sigp['name'],
                     lat=lat,
                     lon=lon,
                     kind=kind,
                     alt=-9999.0))

        user = request.params.get('user', None)
        correct_pass = False
        if user:
            try:
                print "Received password", request.params[
                    'password'], "user:"******"Bad password")
                correct_pass = True
                trips = get_user_trips(user)
            except Exception:
                print traceback.format_exc()
                trips = []
        else:
            trips = []

            #print "Just added:",points[-1]
        #add sig. points!
        if 1:
            for obst in chain(
                    notam_geo_search.get_notam_objs_cached()['obstacles'],
                    extracted_cache.get_obstacles()):
                lat, lon = mapper.from_str(obst['pos'])
                #if lat<58.5 or lat>59.5:
                #    continue
                tname = obst.get('name', 'Unknown')
                if obst.get('kind', '').startswith("notam"):
                    tname = "Notam Obst."
                points.append(
                    dict(name=tname,
                         lat=lat,
                         lon=lon,
                         kind="obstacle",
                         alt=float(obst['elev'])))

        if request.params.get('csv', '').strip() != "":
            #use CSV format
            meta.Session.flush()
            meta.Session.commit()
            buf = StringIO.StringIO()
            w = csv.writer(buf)
            for space in out:
                freq = ''
                if len(space['freqs']) > 0:
                    freq = " ".join(u"%s" % (x[1], ) for x in space['freqs'])
                    freq = freq
                line = [
                    space['name'], '*', freq, '*', space['floor'],
                    space['ceiling']
                ]
                for point in space['points']:
                    lat, lon = point['lat'], point['lon']
                    line.append(lat)
                    line.append(lon)
                for i in xrange(len(line)):
                    if type(line[i]) == unicode:
                        line[i] = line[i].encode('utf8')
                w.writerow(line)
            response.headers['Content-Type'] = 'text/plain'
            return buf.getvalue()
        elif request.params.get('binary', '').strip() != '':
            response.headers['Content-Type'] = 'application/binary'
            ret = android_fplan_map_format(airspaces=out,
                                           points=points,
                                           aiptexts=aiptexts,
                                           trips=trips,
                                           version=version,
                                           user_aipgen=user_aipgen,
                                           correct_pass=correct_pass)

            print "meta.Session.flush/commit"
            meta.Session.flush()
            meta.Session.commit()
            if 'zip' in request.params:
                zobj = zlib.compressobj(9)  #,zlib.DEFLATED,14)
                ret = zobj.compress(ret)
                ret += zobj.flush()
            print "Android map download from:", request.environ.get(
                "REMOTE_ADDR", 'unknown'), " size: ", len(ret), "bytes"
            return ret
        else:
            meta.Session.flush()
            meta.Session.commit()

            rawtext = json.dumps(dict(airspaces=out, points=points), indent=1)

            if 'zip' in request.params:
                response.headers[
                    'Content-Type'] = 'application/x-gzip-compressed'
                return zlib.compress(rawtext)
            else:
                response.headers['Content-Type'] = 'text/plain'
                return rawtext
예제 #6
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)
예제 #7
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
예제 #8
0
파일: api.py 프로젝트: avl/SwFlightPlanner
    def get_airspaces(self):
        print "Get airspaces called"
        
        getsectors=int(request.params.get("sectors","0"))
        
        out=[]
        if 1:
            for space in extracted_cache.get_airspaces()+get_notam_objs_cached()['areas']+extracted_cache.get_aip_sup_areas():
                lat,lon=mapper.from_str(space['points'][0])
                #if lat<57 or lat>62:
                #    continue
                if getsectors==0 and space.get('type',None)=='sector':
                    continue
                name=space['name']
                if space['type']=="notamarea":
                    name="NOTAM:"+name
                clnd=cleanup_poly([mapper.from_str(x) for x in space['points']],name)
                if not clnd:
                    print "Skipped area",name,space 
                    continue
                out.append(dict(
                    name=name,
                    freqs=space['freqs'] if space.get('freqs',"") else [],
                    floor=space.get('floor',""),
                    type=space['type'],
                    ceiling=space.get('ceiling',""),
                    points=[dict(lat=p[0],lon=p[1]) for p in clnd]))
            
        aiptexts=[]
        points=[]
        version=request.params.get("version",None)
        getaiptext=int(request.params.get("aip","0"))
        print "version",version
        if version and int(version.strip())>=5:
            user_aipgen=request.params.get("aipgen","")
        else:
            user_aipgen=""
        for airp in extracted_cache.get_airfields():
            lat,lon=mapper.from_str(airp['pos'])
            if lat<54 or lon<4 or lon>=30.5:
                try:
                    if not version or int(version.strip())<=7:
                        continue
                except:
                    continue

            #if lat<58.5 or lat>60.5:
            #    continue
            aname=airp['name']
            
            notams=[]
            icao=None
            taf=None
            metar=None
            kind='field'
            if airp.get('icao','zzzz').lower()!='zzzz':
                icao=airp['icao']
                notams=notam_geo_search.get_notam_for_airport(icao)
                metar=metartaf.get_metar(icao)
                taf=metartaf.get_taf(icao)
                kind='port'
                
            ap=dict(
                name=aname,
                lat=lat,
                lon=lon,
                kind=kind,
                notams=notams,
                remark=airp.get('remark',''),
                alt=float(airp.get('elev',0)))
            if 'runways' in airp:
                ap['runways']=airp['runways']
            if icao:
                ap['icao']=icao
                if taf.text:
                    ap['taf']=taf.text
                if metar.text:
                    ap['metar']=metar.text
            
                if getaiptext and 'aiptext' in airp:
                    for aiptext in airp['aiptext']:
                        if aip_text_documents.check_doc(aiptext['icao'],aiptext['category'],aiptext['checksum']):
                            #^^^Okay, this really needs an explanation^^^
                            #Nominally, each aiptext item in aipdata.cache (from which the get_airfields() function
                            #ultimately gets all its data, should always have its corresponding aiptext in html format
                            #available on disk. Now, if the on-disk file is deleted (should never happen), we will
                            #get an exception later down where we try to send this data (with the checksum we have here)
                            #over http to the client. Unfortunately, the routine that sends the data is not at liberty
                            #to modify "what was sent", so the entire sync operation fails. This hack here makes the
                            #failure happen earlier, and in that case the given aiptext-document is suppressed
                            #completely, meaning that the sync operation succeeds, albeit without one specific document
                            #(hey, better than nothing!).
                            #
                            #Of course, the real question is why a document may be missing. A bug of some sort right now,
                            #2012-08-28, makes this bug occur every now and then. Investigation is ongoing.
                            aiptexts.append(
                                dict(name=icao+"_"+aiptext['category'],
                                     icao=icao,
                                     data=aiptext))
                        
            if 'adcharts' in airp and '' in airp['adcharts'] and airp['adcharts'][""]['blobname']:
                ret=airp['adcharts'][""]
                try:
                    cksum=ret['checksum']
                    try:
                        aprojmatrix=get_proj(cksum).matrix
                    except Exception:
                        #print traceback.format_exc()
                        #print "Using 0-proj for ",aname
                        aprojmatrix=[0 for x in xrange(6)]
                        
                    ap['adchart_matrix']=list(aprojmatrix)
                    ap['adchart_width']=ret['render_width']
                    ap['adchart_height']=ret['render_height']
                    ap['adchart_name']=ret['blobname']
                    ap['adchart_checksum']=cksum
                    ap['adchart_url']=ret['url']                    
                except Exception,cause:
                    print "Couldn't get projection for airport %s (%s)"%(aname,cause)
            
            points.append(ap)            
예제 #9
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)