Esempio n. 1
0
def test_remove_loops6():
    polya=Polygon(vvector([
        Vertex(15,15),Vertex(15,10),Vertex(0,10),Vertex(0,0),Vertex(10,0),Vertex(10,15)]))
    polyb=polya.remove_loops()
    print polyb
    assert polyb==Polygon(vvector([
        Vertex(10,10),Vertex(10,15),Vertex(15,15),Vertex(15,10)]))
Esempio n. 2
0
def test_is_ccw():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(1,1),Vertex(0,1)]))
    assert polya.is_ccw()
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(0,1),Vertex(1,1),Vertex(1,0)]))
    assert not polya.is_ccw()
Esempio n. 3
0
def test_calc_area():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(1,1),Vertex(0,1)]))
    assert abs(polya.calc_area()-1)<1e-5
    polyb=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(2,1),Vertex(0,1)]))
    assert abs(polyb.calc_area()-1.5)<1e-5
    polyc=Polygon(vvector([
        Vertex(0,0),Vertex(2,0),Vertex(2,2),Vertex(1,0),Vertex(0,2)]))
    assert abs(polyc.calc_area()-2)<1e-5
Esempio n. 4
0
def test_poly_eq():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(1,1),Vertex(0,1)]))
    polyb=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(1,1),Vertex(0,1)]))
    polyc=Polygon(vvector([
        Vertex(0,1),Vertex(0,0),Vertex(1,0),Vertex(1,1)]))
    polyd=Polygon(vvector([
        Vertex(0,1),Vertex(0,0),Vertex(1,0),Vertex(1,2)]))
    assert polya==polyb
    assert polya==polyc
    assert not (polya==polyd)
Esempio n. 5
0
def test_inside_poly3():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(10,0),Vertex(10,10),Vertex(5,5),Vertex(0,10)]))
    assert polya.is_inside(Vertex(7,5))
    assert polya.is_inside(Vertex(5,5)) #on edge
    assert polya.is_inside(Vertex(3,5))
    assert not polya.is_inside(Vertex(5,7))
Esempio n. 6
0
def test_polygon_intersect_line7():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(10,0),Vertex(10,10),Vertex(5,5),Vertex(0,10)]))
    ls=list(polya.intersect_line(Line(Vertex(-5,7),Vertex(15,7))))
    print ls
    assert ls==[Line(Vertex(0,7),Vertex(4,7)),
                Line(Vertex(6,7),Vertex(10,7))]
Esempio n. 7
0
def clean_up_polygon(poss):
    print "Clean poly:",poss
    def tov(merc):
        return Vertex(int(merc[0]),int(merc[1]))
    def fromv(v):
        return (v.get_x(),v.get_y())
    vertices=[]
    last=None
    for pos in poss:
        #print pos
        if pos==last: continue
        last=pos
        vertices.append(tov(mapper.latlon2merc(mapper.from_str(pos),13)))
    poly=Polygon(vvector(vertices))
    #print "calling tidy-up"
    shape=tidy_up_polygon(poly)
    ret=[]
    for poly in shape.get_polys():
        #print "Got poly"
        vs=poly.get_vertices()
        out=[]
        for v in vs:
            out.append(mapper.to_str(mapper.merc2latlon(fromv(v),13)))
        ret.append(out)
    return ret
Esempio n. 8
0
def clean_up_polygon(poss):
    print "Clean poly:", poss

    def tov(merc):
        return Vertex(int(merc[0]), int(merc[1]))

    def fromv(v):
        return (v.get_x(), v.get_y())

    vertices = []
    last = None
    for pos in poss:
        #print pos
        if pos == last: continue
        last = pos
        vertices.append(tov(mapper.latlon2merc(mapper.from_str(pos), 13)))
    poly = Polygon(vvector(vertices))
    #print "calling tidy-up"
    shape = tidy_up_polygon(poly)
    ret = []
    for poly in shape.get_polys():
        #print "Got poly"
        vs = poly.get_vertices()
        out = []
        for v in vs:
            out.append(mapper.to_str(mapper.merc2latlon(fromv(v), 13)))
        ret.append(out)
    return ret
Esempio n. 9
0
def pypoly(data,kind="solid",mapmulti=None):
    assert data.count("\t")==0
    xpos=1
    ypos=data.count("\n")
    chs=dict()
    for c in data:
        if c=='\t': raise Exception("tab not allowed")
        if c=='\n': 
            xpos=1
            ypos-=1
        else:
            if mapmulti:
                cs=mapmulti.get(c,[c])
            else:
                cs=[c]
            for c in cs:
                if c!=' ':
                    chs.setdefault(c,[]).append((xpos,ypos))
            xpos+=1
    lines=[]
    for c,poss in chs.items():
        endpoints=[]
        for pos in poss:
            cnt=0
            for aroundx in [-1,0,1]:
                for aroundy in [-1,0,1]:
                    if aroundx==0 and aroundy==0: continue
                    if (pos[0]+aroundx,pos[1]+aroundy) in poss:
                        cnt+=1
            if cnt==1 or cnt==0:
                endpoints.append(Vertex(*pos))
        if len(endpoints)==1:
            endpoints.append(endpoints[0])
        print len(endpoints)
        assert(len(endpoints)==2)
        lines.append((c,Line(endpoints[0],endpoints[1])))
    lines.sort()
    #print "C,poss: ",lines
    outv=[]
    last=None
    for (n1,line1),(n2,line2) in izip(lines,lines[1:]+lines[:1]):
        if not ((line1.get_v2()-line2.get_v1()).taxilength()==1 or (line1.get_v2()-line2.get_v2()).taxilength()==1):
            line1=Line(line1.get_v2(),line1.get_v1())            
        if (line1.get_v2()-line2.get_v1()).taxilength()==1:
            outline=Line(line1.get_v1(),line2.get_v1())
        elif (line1.get_v2()-line2.get_v2()).taxilength()==1:
            outline=Line(line1.get_v1(),line2.get_v2())
        else:
            raise Exception("Unexpected error - bad input-data?")
        #print "Line: %s:%s"%(n1,outline)
        outv.append(outline.get_v1())
    poly=Polygon(vvector(outv))
    #if not poly.is_ccw():
    #    raise Exception("shouldn't be cw")
    if kind=="hole":
        poly.set_kind(Polygon.HOLE)
    return poly
Esempio n. 10
0
def test_inside_poly1():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(10,0),Vertex(10,10),Vertex(0,10)]))
    assert not polya.is_inside(Vertex(5,11))
    
    assert polya.is_inside(Vertex(5,5))
    assert polya.is_inside(Vertex(0,5))
    assert polya.is_inside(Vertex(5,10))
    assert not polya.is_inside(Vertex(-1,5))
    assert not polya.is_inside(Vertex(11,5))
Esempio n. 11
0
def poly(points):
    last = None
    poly_coords = []
    for coord in points:
        merc = mapper.latlon2merc(mapper.from_str(coord), 13)
        if merc == last: continue
        last = merc
        poly_coords.append(Vertex(int(merc[0]), int(merc[1])))
    if len(poly_coords) >= 3:
        return Polygon(vvector(poly_coords))
    return None
Esempio n. 12
0
def poly(points): 
    last=None
    poly_coords=[]
    for coord in points:
        merc=mapper.latlon2merc(mapper.from_str(coord),13)
        if merc==last: continue
        last=merc
        poly_coords.append(Vertex(int(merc[0]),int(merc[1])))
    if len(poly_coords)>=3:
        return Polygon(vvector(poly_coords))
    return None
Esempio n. 13
0
def cleanup_poly(latlonpoints, name="?"):

    for minstep in [0, 10, 100, 1000, 10000, 100000]:
        mercpoints = []
        lastmerc = None
        for latlon in latlonpoints:
            merc = mapper.latlon2merc(latlon, 13)
            if lastmerc != None:
                dist = math.sqrt(
                    sum([(lastmerc[i] - merc[i])**2 for i in xrange(2)]))
                if dist < minstep:
                    continue
            if merc == lastmerc:
                continue
            lastmerc = merc
            mercpoints.append(Vertex(int(merc[0]), int(merc[1])))
        if len(mercpoints) < 50:
            break
    if len(mercpoints) <= 2: return None
    if mercpoints[0] == mercpoints[-1]:
        del mercpoints[-1]
    if len(mercpoints) <= 2: return None
    poly = Polygon(vvector(mercpoints))
    if len(mercpoints) == 4:
        swapped = [mercpoints[1], mercpoints[0]] + mercpoints[2:]
        swappedpoly = Polygon(vvector(swapped))
        #print "Found 4-corner area: ",name," areas:",swappedpoly.calc_area(),poly.calc_area()
        if abs(swappedpoly.calc_area()) > abs(1.1 * poly.calc_area()):
            print "Untwisting an area", name
            mercpoints = swapped
            poly = swappedpoly

    backtomerc = [
        mapper.merc2latlon((m.get_x(), m.get_y()), 13) for m in mercpoints
    ]
    if poly.is_ccw():
        return backtomerc
    else:
        #print "Reversed "+latlonpoints
        return reversed(backtomerc)
Esempio n. 14
0
def test_first_entrance():
    poly=Polygon(vvector([
        Vertex(0,0),Vertex(10,0),Vertex(10,10),Vertex(0,10)]))
    res=list(poly.first_entrance(Line(Vertex(-5,5),Vertex(15,5))))
    print "res:",res
    assert res[0]==Vertex(0,5)
    
    res=list(poly.first_entrance(Line(Vertex(15,5),Vertex(-5,5))))
    print "res:",res
    assert res[0]==Vertex(10,5)

    
    assert res[0].get_x()==10
Esempio n. 15
0
def cleanup_poly(latlonpoints,name="?"):
    
    for minstep in [0,10,100,1000,10000,100000]:
        mercpoints=[]
        lastmerc=None
        for latlon in latlonpoints:
            merc=mapper.latlon2merc(latlon,13)
            if lastmerc!=None:
                dist=math.sqrt(sum([(lastmerc[i]-merc[i])**2 for i in xrange(2)]))
                if dist<minstep:
                    continue
            if merc==lastmerc:
                continue
            lastmerc=merc
            mercpoints.append(Vertex(int(merc[0]),int(merc[1])))
        if len(mercpoints)<50:
            break
    if len(mercpoints)<=2: return None
    if mercpoints[0]==mercpoints[-1]:
        del mercpoints[-1]
    if len(mercpoints)<=2: return None
    poly=Polygon(vvector(mercpoints))
    if len(mercpoints)==4:
        swapped=[mercpoints[1],mercpoints[0]]+mercpoints[2:]
        swappedpoly=Polygon(vvector(swapped))
        #print "Found 4-corner area: ",name," areas:",swappedpoly.calc_area(),poly.calc_area()
        if abs(swappedpoly.calc_area())>abs(1.1*poly.calc_area()):
            print "Untwisting an area",name
            mercpoints=swapped
            poly=swappedpoly
            
    backtomerc=[mapper.merc2latlon((m.get_x(),m.get_y()),13) for m in mercpoints]
    if poly.is_ccw():
        return backtomerc
    else:    
        #print "Reversed "+latlonpoints
        return reversed(backtomerc)
Esempio n. 16
0
 def check_area(self,nr2tri):
     if len(self.triangles)==0:
         return
     totarea=0.0
     for trinr in self.triangles:
         tri=nr2tri[trinr]
         coords=[]
         for v in tri.vobjs:
             print "Pos: %s"%((int(v.merc[0]),int(v.merc[1])),)
             coords.append(pyshapemerge2d.Vertex(int(v.merc[0]),int(v.merc[1])))
         poly=Polygon(vvector(coords))
         assert not poly.is_ccw()
         area=-poly.calc_area()
         print "Tri:%s area = %s"%([x.nr for x in tri.vobjs],area)
         totarea+=area
     print "Area should be: %s (since size = %d)"%(self.size*self.size,self.size)
     print "Area is: %s"%(totarea)
     assert abs(totarea-(self.size*self.size))<10.0*10.0
Esempio n. 17
0
def get_weather(lat, lon):
    zoomlevel = 13
    px, py = mapper.latlon2merc((lat, lon), zoomlevel)
    w = Weather()
    areas = weather_chart_areas.get_areas()
    insides = []
    dists = []

    for name, area in areas.items():
        poly_coords = []
        centerx = 0.0
        centery = 0.0
        for coord in area:
            x, y = mapper.latlon2merc(coord, zoomlevel)
            centerx += x + 0.0
            centery += y + 0.0
            poly_coords.append(Vertex(int(x), int(y)))
        if len(poly_coords) < 3:
            print "Weather area %s has few points: %s " % (name, area)
            continue
        centerx /= len(poly_coords)
        centery /= len(poly_coords)
        cdist = (centerx - px)**2 + (centery - py)**2
        poly = Polygon(vvector(poly_coords))
        if poly.is_inside(Vertex(int(px), int(py))):
            cdist *= 1e-3
        insides.append((cdist, name, area))
    #print "insides:",insides
    insides.sort()
    dist, name, area = insides[0]
    if dist > 20000**2:
        return None
    w.weather_area = name

    mainarea, rest = name.split("_")
    part = rest[:-2]
    seg = rest[-2:]

    try:
        fc = get_parsed_weather()
    except Exception, cause:
        print "Couldn't fetch weather: ", cause  #there's no weather service at certain times.
        return None
Esempio n. 18
0
def get_weather(lat,lon):
    zoomlevel=13
    px,py=mapper.latlon2merc((lat,lon),zoomlevel)
    w=Weather()
    areas=weather_chart_areas.get_areas()
    insides=[]
    dists=[]
    
    for name,area in areas.items():
        poly_coords=[]
        centerx=0.0
        centery=0.0
        for coord in area:
            x,y=mapper.latlon2merc(coord,zoomlevel)
            centerx+=x+0.0
            centery+=y+0.0
            poly_coords.append(Vertex(int(x),int(y)))
        if len(poly_coords)<3:
            print "Weather area %s has few points: %s "%(name,area)
            continue
        centerx/=len(poly_coords)
        centery/=len(poly_coords)
        cdist=(centerx-px)**2+(centery-py)**2
        poly=Polygon(vvector(poly_coords))
        if poly.is_inside(Vertex(int(px),int(py))):
            cdist*=1e-3
        insides.append((cdist,name,area))
    #print "insides:",insides
    insides.sort()
    dist,name,area=insides[0]
    if dist>20000**2:        
        return None        
    w.weather_area=name
    
    mainarea,rest=name.split("_")
    part=rest[:-2]
    seg=rest[-2:]
    
    try:
        fc=get_parsed_weather()
    except Exception,cause:
        print "Couldn't fetch weather: ",cause #there's no weather service at certain times.
        return None
Esempio n. 19
0
def get_polygons_around(lat,lon,polys):
    zoomlevel=13
    px,py=mapper.latlon2merc((lat,lon),zoomlevel)
    insides=[]
    for space in polys:                
        poly_coords=[]
        for coord in space['points']:
            x,y=mapper.latlon2merc(mapper.from_str(coord),zoomlevel)
            poly_coords.append(Vertex(int(x),int(y)))
        if len(poly_coords)<3:
            #print "Space %s has few points: %s "%(space['name'],space['points'])
            continue
        poly=Polygon(vvector(poly_coords))
        #print "Checking if inside poly:",space
        if poly.is_inside(Vertex(int(px),int(py))):
            insides.append(space)
            #print "Is inside"
        else:
            pass#print "Is NOT inside"
    return insides
Esempio n. 20
0
def get_borders(pcountry):
    #print "Getting for",pcountry
    global borders
    if not borders:
        if not os.path.exists("fplan/extract/lands.bin"):
            if os.system("bunzip2 fplan/extract/lands.bin.bz2")!=0:
                raise Exception("Couldn't unbzip2 lands.bin.bz2")
        f=open("fplan/extract/lands.bin")
        tborders=pickle.load(f)
        f.close()
        out=dict()
        for country,parts in tborders.items():
            outparts=[]
            tot=0
            for part in parts:
                outpart=[]
                poly_coords=[]
                last=None
                for coord in part:
                    merc=mapper.latlon2merc(mapper.from_str(coord),13)
                    if merc==last: continue
                    last=merc
                    outpart.append(merc)
                    tot+=1
                    poly_coords.append(Vertex(int(merc[0]),int(merc[1])))
                assert len(outpart)>=3
                if outpart[0]==outpart[-1]:
                    outpart=outpart[:-1]
                    poly_coords=poly_coords[:-1]
                poly=Polygon(vvector(poly_coords))
                assert poly.is_ccw()

                outparts.append(outpart)
            #print "Parts in ",country,len(outparts),tot
            out[country]=outparts
        borders=out
    #if pcountry!="sweden":
    #    raise Exception("Debug, just allow sweden for now. just remove this after.")
    return borders[pcountry]
Esempio n. 21
0
def get_borders(pcountry):
    #print "Getting for",pcountry
    global borders
    if not borders:
        if not os.path.exists("fplan/extract/lands.bin"):
            if os.system("bunzip2 fplan/extract/lands.bin.bz2") != 0:
                raise Exception("Couldn't unbzip2 lands.bin.bz2")
        f = open("fplan/extract/lands.bin")
        tborders = pickle.load(f)
        f.close()
        out = dict()
        for country, parts in tborders.items():
            outparts = []
            tot = 0
            for part in parts:
                outpart = []
                poly_coords = []
                last = None
                for coord in part:
                    merc = mapper.latlon2merc(mapper.from_str(coord), 13)
                    if merc == last: continue
                    last = merc
                    outpart.append(merc)
                    tot += 1
                    poly_coords.append(Vertex(int(merc[0]), int(merc[1])))
                assert len(outpart) >= 3
                if outpart[0] == outpart[-1]:
                    outpart = outpart[:-1]
                    poly_coords = poly_coords[:-1]
                poly = Polygon(vvector(poly_coords))
                assert poly.is_ccw()

                outparts.append(outpart)
            #print "Parts in ",country,len(outparts),tot
            out[country] = outparts
        borders = out
    #if pcountry!="sweden":
    #    raise Exception("Debug, just allow sweden for now. just remove this after.")
    return borders[pcountry]
Esempio n. 22
0
def get_polygons_on_line(latlon1,latlon2,polys):
    zoomlevel=13
    px1,py1=mapper.latlon2merc(latlon1,zoomlevel)
    px2,py2=mapper.latlon2merc(latlon2,zoomlevel)
    line=Line(Vertex(int(px1),int(py1)),Vertex(int(px2),int(py2)))
    crosses=[]
    for space in polys:                
        poly_coords=[]
        for coord in space['points']:
            x,y=mapper.latlon2merc(mapper.from_str(coord),zoomlevel)
            poly_coords.append(Vertex(int(x),int(y)))
        if len(poly_coords)<3:
            #print "Space %s has few points: %s "%(space['name'],space['points'])
            continue
        poly=Polygon(vvector(poly_coords))
        #print "Checking if intersect poly:",space
        if len(poly.intersect_line(line))>0:
            crosses.append(space)
            #print "Is crossing"
        else:
            pass#print "Is NOT crossing"
    return crosses
Esempio n. 23
0
def test_shape_eq(): 
    assert 0
    polya1=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(1,1),Vertex(0,1)]))
    polya2=Polygon(vvector([
        Vertex(2,0),Vertex(3,0),Vertex(3,1),Vertex(2,1)]))
    polyb1=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(1,1),Vertex(0,1)]))
    polyb2=Polygon(vvector([
        Vertex(2,1),Vertex(2,0),Vertex(3,0),Vertex(3,1)]))
    polyc1=Polygon(vvector([
        Vertex(0,0),Vertex(1,0),Vertex(1,1),Vertex(0,1)]))
    polyc2=Polygon(vvector([
        Vertex(2,1),Vertex(2,0),Vertex(4,0),Vertex(3,1)]))
    
    shape_a=Shape("a",pvector([polya1,polya2]))
    shape_b=Shape("b",pvector([polyb1,polyb2]))
    shape_c=Shape("c",pvector([polyc1,polyc2]))

    assert shape_a==shape_b
    assert not (shape_a==shape_c)
Esempio n. 24
0
def parse_page(parser,pagenr,kind="TMA",last_sector=dict()):   
    if kind=="TMA":
        thirdcols=["ATC unit","AFIS unit"]
    elif kind=="sector":
        thirdcols=["FREQ"]
    elif kind=="R":
        thirdcols=["Remarks (nature of hazard,"]
    else:
        raise Exception("Bad kind")
    page=parser.parse_page_to_items(pagenr)
    items=page.items
    #print "Items:",pitems    

    #print "Possible Areas:"
    headings=[]
    for item in items:        
        if item.text==None: continue
        item.text=item.text.strip()
        if item.text=="": continue
        if item.text=="Name": continue
        if item.y1<25 and item.text in (["Lateral limits","Vertical limits"]+thirdcols):
            headings.append(item)  
    
    headings.sort(key=lambda x:x.x1)    
    #print "found candidates:",zone_candidates    
    if len(headings)==0:
        return []
    avg_heading_y=sum(h.y1 for h in headings)/float(len(headings))
    uprint("Found headings:",headings)
    zone_candidates=[]
    for item in items:        
        if item.text==None or item.text.strip()=="": continue
        if item.text.strip().startswith("AMDT"): continue
        if item.text.strip().startswith("The LFV Group"): continue
        if re.match(ur"\s*LFV\s*AIRAC\s*AMDT\s*\d+/\d+\s*",item.text): continue
        if item.text.strip()=="LFV": continue
        if item.text.count('Terminal Information Areas'): continue
        if item.text.strip().startswith("AIRAC"): continue        
        if kind=="R" and not is_r_or_danger_area_name(item.text.strip()):
            continue
        if item.y1>avg_heading_y+1 and item.x1<12 and not item.text in ["Name",'None',"LFV"]:
            if item.text.count("Established") or item.text.count(u'TROLLHÄTTAN TWR') or item.text.count(u'and/or SÅTENÄS') or item.text.count(u'TWR/TMC') or item.text.strip().endswith("TWR") or item.text.strip().endswith("TWR."):
                continue
            if item.text.count("operational hours") or item.text.count("See AIP DENMARK"):
                continue
            if item.text.count("hours of"):
                continue
            if item.text.count("Upper limit"):
                continue
            if item.text.count("that part") or item.text.count("coincides"):
                continue
            if item.text.count(u'Danger area EK D395 and') or item.text.count(u'D396 are situated within') or item.text.strip()=="TMA":
                continue
            if item.text.count(u'ÖSTGÖTA TMC is closed') or item.text.count(u'and SKAVSTA TWR is') or item.text.strip()=='open.':
                continue
            if item.text.count("SAT 0530"): 
                continue
            if item.text.strip()=='OPS': 
                continue
            if item.text.strip()==u'ÖSTGÖTA TMC:': 
                continue
            if item.text.count(u'is open') or item.text.count('is closed'):
                continue
            if item.text.count('MON-FRI') or item.text.count('2150'): 
                continue
            lines2=page.get_lines(page.get_partially_in_rect(12,item.y1+0.2,40,item.y2-0.2))
            if len(lines2):
                zone_candidates.append(item)
    
    uprint("Found cands:",zone_candidates)
    zone_candidates.sort(key=lambda x:x.y1)
    
    for zone in zone_candidates:
        #uprint("Zone:",zone)
        #assert not zone.text.count("AOR")
        assert not zone.text.count("FIR")
    
    uprint("Headings:",headings)        
    print "Pagenr:",pagenr
    assert len(headings)==3
    
    
    
    ret=[]
    for i in xrange(len(zone_candidates)):
        d=dict()
        cand=zone_candidates[i]
        if i<len(zone_candidates)-1:
            nextcand=zone_candidates[i+1]
        else:
            nextcand=None
        y1=cand.y1-0.25
        y2=100
        if nextcand: y2=nextcand.y1-0.75
        for j in xrange(len(headings)):
            head=headings[j]
            if j<len(headings)-1:
                nexthead=headings[j+1]
            else:
                nexthead=None
            x1=head.x1
            x2=head.x2
            if j==len(headings)-1:                
                x1=headings[j-1].x2+3
                x2=100
            lines=page.get_lines(page.get_partially_in_rect(x1,y1,x2,y2,xsort=True,ysort=True))
            #print ("Parsed %s y,%d-%d, %s: <%s>\n\n"%(cand.text,y1,y2,head.text,lines)).encode('utf8')
            d[head.text]=lines        
        
        if kind=="R":
            if y2==100: y2=y1+3
            d['name']=" ".join(x.strip() for x in filter_head_foot(page.get_lines(page.get_partially_in_rect(0,y1,10,y2,xsort=True,ysort=True))))
        else:
            d['name']=cand.text.strip()
        ret.append(d)  


    allow_head=2
    print "Doing fixups--------------------------------------------------"
    tret=[]
    for x in ret:
        #print "Fixing up",x,"allow:",allow_head
        area="".join(x['Lateral limits']).strip()
        if allow_head==2 and area!="" and x['name'].strip()!="":
            allow_head=1
            
        if allow_head!=1:
            if len(tret):
                tret[-1]['Lateral limits']+=x['Lateral limits']
                tret[-1]['Vertical limits']+=x['Vertical limits']
        else:
            tret.append(x)
        
        if allow_head==1:
            allow_head=0
                
        if not area.endswith('-') and area!="":
            allow_head=2
            
        #print "   Fixed up up",x
    ret=tret
    for line in ret:
        print "Fixed:",line['name']," = ",line['Lateral limits'],line['Vertical limits']
    out=[]
    for d in ret:
        pa=dict()
        curname=d['name']
        if curname.count(u'Förteckning över'): continue
        print "D:",d
        arealines=[l for l in d['Lateral limits'] if l.strip()!=""]
        last_coord_idx=None
        #uprint("D:<%s> (area:%s)"%(d,arealines))
        if 'FREQ' in d:
            freqs=[("SWEDEN CONTROL",float(x)) for x in re.findall(r"\d{3}\.\d{3}","\n".join(d['FREQ']))]
            #print "Parsed freqs:",freqs
            if freqs:
                last_sector['freqs']=freqs
            
        if kind=='sector':            
            m=re.match(r"ES[A-Z]{2}\s*ACC\s*sector\s*([0-9a-zA-Z]*)",d['name'])
            if m:
                last_sector['major']=d['name']
                last_sector['majorsector'],=m.groups()
            if len(arealines)==0:
                last_sector['name']=d['name']
                continue
            
            if d['name'].count("Control Area and Upper Control Area"): continue        
            if d['name'].count("SUECIA CTA"): continue        
            if d['name'].count("SUECIA UTA"): continue
            
            m=re.match(r"([0-9a-zA-Z]*)(:.*)",d['name'])
            if m and 'majorsector' in last_sector:
                sectorname,sub=m.groups()
                if sectorname==last_sector['majorsector']:
                    d['name']=last_sector['major']+sub
                    #uprint("Fixed up name: ",d['name'])
        #print "Arealines:",arealines
        assert len(arealines)
        if arealines[0].strip()=="Danger area EK D395 and D396 are":
            arealines=arealines[1:]
        if arealines[0].strip()=="situated within TMA":
            arealines=arealines[1:]
            
        if arealines==u'Förteckning över CTA / Lists of CTA' or arealines=='Lateral limits':
            continue

        for idx in xrange(len(arealines)):
            if arealines[idx].lower().startswith("established"):
                last_coord_idx=idx
                pa['established']=" ".join(l for l in arealines[idx:])   
                break
            if arealines[idx].lower().startswith("danger area"):
                last_coord_idx=idx
                break
            if arealines[idx].strip()=="LFV":
                last_coord_idx=idx
                break
        if last_coord_idx==None:
            last_coord_idx=len(arealines)
        #uprint("ARealines:",arealines)
        #uprint("Last coord:",arealines[last_coord_idx-1])
        if len(arealines)>last_coord_idx:
            if arealines[last_coord_idx-1:last_coord_idx+1]==[u'571324N 0161129E -', u'Established during operational hours of']:
                arealines[last_coord_idx-1]=arealines[last_coord_idx-1].strip("-")
        #uprint("Last fixed:",arealines[last_coord_idx-1])
        assert not arealines[last_coord_idx-1].strip().endswith("-")
        #for idx in xrange(last_coord_idx-1):
        #    print "arealine: <%s>"%(arealines[idx].strip(),)
        #    assert arealines[idx].strip().endswith("-") or arealines[idx].strip().endswith("to")
        
        vertlim=u" ".join(d['Vertical limits'])
        if vertlim.strip()=="":
            #print "Object with no vertical limits: %s"%(repr(d['name']),)
            continue
        
        if d['name']=='Control Area':
            continue

        uprint("Vertlim: ",vertlim)
        heightst=re.findall(r"(FL\s*\d{3})|(\d+\s*ft\s*(?:\s*/\s*\d+\s*.\s*GND)?(?:\s*GND)?)|(GND)|(UNL)",vertlim)
        uprint("Height candidates:",heightst)
        heights=[]
        for fl,ht,gnd,unl in heightst:
            if fl:
                heights.append(fl)
            if ht:
                heights.append(ht.strip())
            if gnd:
                heights.append(gnd.strip())
            if unl:
                heights.append(unl.strip())
        uprint("heights for ",d['name'],":",repr(heights))
        if len(heights)==0 and d['name']==u'GÖTEBORG TMA':
            heights=['GND','FL95']
        if len(heights)==1 and d['name']==u'Göteborg TMA':
            heights=['4500','FL95']
        assert len(heights)==2
        ceiling=heights[0].strip()
        floor=heights[1].strip()
                
        pa['name']=d['name']
        pa['floor']=floor
        pa['ceiling']=ceiling
        if mapper.parse_elev(floor)>=9500:
            continue
        #uprint("Arealines:\n================\n%s\n============\n"%(arealines[:last_coord_idx]))
        #print pa
        areacoords=" ".join(arealines[:last_coord_idx])
        pa['points']=parse_coord_str(areacoords)
        
        
        vs=[]
        for p in pa['points']:
            #print "from_str:",repr(p)
            x,y=mapper.latlon2merc(mapper.from_str(p),13)
            vs.append(Vertex(int(x),int(y)))

        p=Polygon(vvector(vs))
        if p.calc_area()<=30*30:
            pass#print pa
            #print "Area:",p.calc_area()
        assert p.calc_area()>30*30
        #print "Area: %f"%(p.calc_area(),)
        #print "Point-counts:",len(pa['points'])
        for p in pa['points']:
            assert p.count(",")==1 
        pa['type']=kind
        for thirdcol in thirdcols:
            if thirdcol in d:
                atc=d[thirdcol]
                break
        else:
            raise Exception("missing thirdcol")
        #print "ATc: <%s>"%(repr(atc),)
        freqs=[(y,float(x)) for x,y in re.findall(r"(\d{3}\.\d{3})\s*MHz\n(.*)","\n".join(atc))]
        if not freqs:
            freqs=last_sector.get('freqs',[])
        #print repr(freqs)
        pa['freqs']=freqs
        #uprint("Cleaning up ",pa['name'])
        for cleaned in clean_up_polygon(list(pa['points'])):
            d=dict(pa)
            #print "cleaned",cleaned
            for i,tup in enumerate(cleaned):
                assert type(tup)==str
                latlon=mapper.from_str(tup)
                lat,lon=latlon
                assert lat>=-85 and lat<=85
            d['points']=cleaned
            #uprint("cleaned:",pa['name'],len(cleaned),cleaned)
            #print "name:",d['name']
            #print "cleaned points:",d['points']
            #print "from:",areacoords
            #raise Exception()
            out.append(d)
        #if pa['name'].lower().count("esrange"):
        #    print "Exit esrange"
        #    sys.exit(1)
                    
    return out
Esempio n. 25
0
def gen_bsptree_lookup(data):
    r=dict()
    
    lookup_points=['obstacles',
             'airfields',
             'sig_points']
    for look in lookup_points:
        items=data.get(look,None)
        if True:
            bspitems=[]
            for item in items:
                try:
                    bspitems.append(BspTree.Item(                                           
                        mapper.latlon2merc(mapper.from_str(item['pos']),13),item) )
                except Exception:
                    print item
                    raise
            #print "Items for bsptree",items
            bsp=BspTree(bspitems)   
            #assert len(bsp.getall())==len(items)
            #after=sorted(set(x['name'] for x in bsp.getall()))
            #before=sorted(set(x['name'] for x in obsts))
            #print after,"\n-------------------\n\n",before
            #assert after==before
            #print "same before as after"
            r[look]=bsp
    del item
    del items
    del bspitems
    del bsp
    
    
    lookup_spaces=['airspaces','firs']
    for look in lookup_spaces:
        spaces=data.get(look,None)
        if spaces!=None:
            bbitems=[]
            zoomlevel=13
            for space in spaces:
                poly_coords=[]
                bb=BoundingBox(1e30,1e30,-1e30,-1e30)
                for coord in space['points']:
                    x,y=mapper.latlon2merc(mapper.from_str(coord),zoomlevel)
                    bb.x1=min(bb.x1,x)
                    bb.x2=max(bb.x2,x)
                    bb.y1=min(bb.y1,y)
                    bb.y2=max(bb.y2,y)
                    poly_coords.append(Vertex(int(x),int(y)))
                if len(set(poly_coords))<3:
                    continue
                print "Poly"
                poly=Polygon(vvector(poly_coords))
                print "polydone"
                #print "Item:",space
                bbitems.append(
                    BBTree.TItem(bb,(poly,space)))
                                
                #if poly.is_inside(Vertex(int(px),int(py))):
                #    insides.append(space)
            
            
            bbt=BBTree(bbitems,0.5)
            r[look]=bbt       
    
    return r
Esempio n. 26
0
def vistest_merge_shapes():    
    for x in xrange(10):
        x=5
        poly_a=Polygon(vvector([
            Vertex(0+x,0),Vertex(2+x,0),
            Vertex(2+x,2),Vertex(0+x,2)]))
        poly_b=Polygon(vvector([
            Vertex(1,1),Vertex(3,1),
            Vertex(3,4),Vertex(1,4)]))
        shape_a=Shape("shape_a",poly_a)
        shape_b=Shape("shape_b",poly_b)
        #   OOOO
        #   OOOO
        # OOOOOO
        # OOOO
        # OOOO
        bo=BooleanOp()
        #print "Shape_a,shape_b: ",shape_a,shape_b
        bo.step1_add_lines(shape_a,shape_b)
        bo.step2_intersect_lines()
        splitset=set([NondirLine(x.get_v1(),x.get_v2()) for x in bo.dbg_step2_get_split_lines()])
        #print "Split result: %s"%("\n".join(str(l) for l in splitset),)
        assert not NondirLine(Vertex(0,2),Vertex(2,2)) in splitset
                
            
        bo.step3_create_edges()
        edges=list(bo.dbg_step3_and_4_get_edges())
        nondiredges=list(NondirLine(x.get_v1(),x.get_v2()) for x in bo.dbg_step3_and_4_get_edges())
         
        sqs=[]
        cnt=0
        #print "Edges: %s"%(edges,)
        for edge in edges:
            line=Line(edge.get_v1(),edge.get_v2())
            r=(25*cnt)%128+128
            g=(128*cnt)%128+128
            b=(64*cnt)%128+128
            sqs.append(visualize.Line(
                line.get_v1().get_x(),
                line.get_v1().get_y(),
                line.get_v2().get_x(),
                line.get_v2().get_y(),                       
                (r,g,b)))
            sqs.append(visualize.Square(
                line.get_v1().get_x()-0.1,
                line.get_v1().get_y()-0.1,
                line.get_v1().get_x()+0.1,
                line.get_v1().get_y()+0.1,
                (r,g,b)))
            cnt+=1
        draw_things(sqs)
        assert not (NondirLine(Vertex(0,2),Vertex(2,2)) in nondiredges)
        
        bo.step4_eliminate_deadends()    
    
        bo.step5_create_cells()
        
        bo.step6_determine_cell_cover()    
        bas=BooleanOrStrategy()
        bo.step7_classify_cells(bas)
        for cell in list(bo.dbg_step5_get_cells()):
            sqs=[]
            for edge in list(cell.dbg_get_edges()):
                line=Line(edge.get_v1(),edge.get_v2())
                sqs.append(visualize.Line(
                    line.get_v1().get_x(),
                    line.get_v1().get_y(),
                    line.get_v2().get_x(),
                    line.get_v2().get_y(),                       
                    (255,0,0)))
            #print "Cell cover:",list(cell.get_shapes())
            #print "Cell type:",cell.get_classification()
            draw_things(sqs)
        
        bo.step8_merge_cells()
        bo.step9_calc_result()
        shape=bo.step9_get_result()
        polys=list(shape.get_polys())
        plines=set()
        for poly in polys:
            #print "Poly: %s %s"%(poly.get_kind_str(),list(poly.get_lines()))
            plines=plines.union(frozenset(poly.get_lines()))
        sqs=[]
        edges=set(bo.dbg_step3_and_4_get_edges())
        for line in plines:
            sqs.append(visualize.Line(
                line.get_v1().get_x(),
                line.get_v1().get_y(),
                line.get_v2().get_x(),
                line.get_v2().get_y(),                       
                (0,200,0)))
        draw_things(sqs)
Esempio n. 27
0
def vistest_add_lines():
    #print "Press any key when debugger ready"
    #raw_input()
    bo=BooleanOp()
    poly_a=Polygon(vvector([
        Vertex(0,0),Vertex(2,0),
        Vertex(2,2),Vertex(0,2)]))
    poly_b=Polygon(vvector([
        Vertex(1,1),Vertex(3,1),
        Vertex(3,3),Vertex(1,3)]))
    shape_a=Shape("shape_a",poly_a)
    shape_b=Shape("shape_b",poly_b)
    #print "Shape_a,shape_b: ",shape_a,shape_b
    bo.step1_add_lines(shape_a,shape_b)
    bo.step2_intersect_lines()
    lines=list(bo.dbg_step2_get_split_lines())
    #print "The found, split lines:"
    #print "\n".join(str(x) for x in lines)
    assert len(lines)==12
    assert Line(Vertex(0,0),Vertex(2,0)) in lines
    assert Line(Vertex(2,0),Vertex(2,1)) in lines
    assert Line(Vertex(2,1),Vertex(2,2)) in lines
    assert Line(Vertex(2,2),Vertex(1,2)) in lines
    assert Line(Vertex(1,2),Vertex(0,2)) in lines
    assert Line(Vertex(0,2),Vertex(0,0)) in lines
    assert Line(Vertex(1,1),Vertex(2,1)) in lines
    assert Line(Vertex(2,1),Vertex(3,1)) in lines    
    assert Line(Vertex(3,1),Vertex(3,3)) in lines
    assert Line(Vertex(3,3),Vertex(1,3)) in lines
    assert Line(Vertex(1,3),Vertex(1,2)) in lines
    assert Line(Vertex(1,2),Vertex(1,1)) in lines
    
    bo.step3_create_edges()
    edges=bo.dbg_step3_and_4_get_edges()    
    edgelines=dict((Line(edge.get_v1(),edge.get_v2()),edge) for edge in edges)
    
    assert set(edgelines.keys())==set(lines) 
    for key,edge in edgelines.items():
        if key.get_v1().get_y()==key.get_v2().get_y():
            assert edge.get_k_approx()==0.0
            assert edge.get_is_vertical()==False
        else:
            #vertical
            assert edge.get_k_approx()==0.0 #also for vertical but:
            assert edge.get_is_vertical()==True
    
    bo.step4_eliminate_deadends()
    edges=bo.dbg_step3_and_4_get_edges()    
    edgelines=dict((Line(edge.get_v1(),edge.get_v2()),edge) for edge in edges)
    
    assert set(edgelines.keys())==set(lines) 
    for key,edge in edgelines.items():
        if key.get_v1().get_y()==key.get_v2().get_y():
            assert edge.get_k_approx()==0.0
            assert edge.get_is_vertical()==False
        else:
            #vertical
            assert edge.get_k_approx()==0.0 #also for vertical but:
            assert edge.get_is_vertical()==True

            
    bo.step5_create_cells()
    cells=list(bo.dbg_step5_get_cells())
    #print "Cells:\n","\n".join(str(x) for x in cells)
    def lineset(*vertices):
        s=set()
        for v1,v2 in zip(vertices,vertices[1:]+vertices[:1]):
            s.add(NondirLine(v1,v2))
        return frozenset(s)
    def lineset2(*vertices):
        s=set()
        for v1,v2 in zip(vertices,vertices[1:]+vertices[:1]):
            s.add(Line(v1,v2))
        return frozenset(s)
            
    facit_cells={
                 lineset(Vertex(0,0),Vertex(2,0),Vertex(2,1),Vertex(3,1),
                         Vertex(3,3),Vertex(1,3),Vertex(1,2),Vertex(0,2)):"outline",
                 lineset(Vertex(1,1),Vertex(2,1),Vertex(2,2),Vertex(1,2)):"center",
                 lineset(Vertex(2,1),Vertex(3,1),Vertex(3,3),Vertex(1,3),
                         Vertex(1,2),Vertex(2,2)):"upper_right",
                 lineset(Vertex(0,0),Vertex(2,0),Vertex(2,1),Vertex(1,1),
                         Vertex(1,2),Vertex(0,2)):"lower_left"
                 }
    #print "Facit cells","\n".join(str(x) for x in facit_cells.keys())
    assert len(cells)==4
    
    for cell in cells:
        edges=cell.dbg_get_edges()
        edgelines=set(NondirLine(edge.get_v1(),edge.get_v2()) for edge in edges)
        
        if not (edgelines in facit_cells.keys()):
            
            
            sqs=[]
            for line in edgelines:
                sqs.append(visualize.Line(
                    line.get_v1().get_x(),
                    line.get_v1().get_y(),
                    line.get_v2().get_x(),
                    line.get_v2().get_y(),                       
                    (255,0,0)))
            draw_things(sqs)
    bo.step6_determine_cell_cover()

    cells=list(bo.dbg_step5_get_cells())
    for cell in cells:
        edges=cell.dbg_get_edges()
        edgelines=frozenset(NondirLine(edge.get_v1(),edge.get_v2()) for edge in edges)
        shapes=list(cell.get_shapes())
        realcellname=facit_cells[edgelines]
        facit_cell_shapes={
            'lower_left':('shape_a',),
            'center':('shape_a','shape_b'),
            'upper_right':('shape_b',),
            'outline':()
            }
        #print "Facit:",facit_cell_shapes[realcellname]
        #print "Actual:",tuple(shapes)
        assert facit_cell_shapes[realcellname]==tuple(shapes)
            
        #print "Cell: %s, shapes: %s"%(realcellname,", ".join(shapes))
    
    bas=BooleanOrStrategy()
    bo.step7_classify_cells(bas)
    cells=list(bo.dbg_step5_get_cells())
    for cell in cells:
        edges=cell.dbg_get_edges()
        edgelines=frozenset(NondirLine(edge.get_v1(),edge.get_v2()) for edge in edges)
        shapes=list(cell.get_shapes())
        realcellname=facit_cells[edgelines]
        facit_cell_kind={
            'lower_left':'SOLID',
            'center':'SOLID',
            'upper_right':'SOLID',
            'outline':'VOID'
            }
        #print "Cell %s classification: %s"%(realcellname,cell.get_classification())
        assert cell.get_classification()==facit_cell_kind[realcellname]
        
    bo.step8_merge_cells()
    cells=list(bo.dbg_step5_get_cells())
    def lookup_cellname(cell):
        edges=cell.dbg_get_edges()
        edgelines=frozenset(NondirLine(edge.get_v1(),edge.get_v2()) for edge in edges)
        shapes=list(cell.get_shapes())
        realcellname=facit_cells[edgelines]
        return realcellname
        
    for cell in cells:
        facit_cell_merged={
            'lower_left':0,
            'center':0,
            'upper_right':0,
            'outline':1
            }
        realcellname=lookup_cellname(cell)
        #print "Cell %s merged_poly: %s, class: %s"%(realcellname,cell.get_merged_poly(),cell.get_classification())
        #print "%s: Neighbors:"%realcellname," ".join(lookup_cellname(ce) for ce in cell.get_neighbors())
        assert cell.get_merged_poly()==facit_cell_merged[realcellname]
    
    bo.step9_calc_result()
    shape=bo.step9_get_result()
    polys=list(shape.get_polys())
    assert len(polys)==1
    poly,=polys
    
    "Poly: %s %s"%(poly.get_kind_str(),list(poly.get_lines()))
    assert poly.get_kind_str()=="SOLID"
    plines=frozenset(poly.get_lines())
    should=lineset2(Vertex(0,0),Vertex(2,0),Vertex(2,1),Vertex(3,1),
                         Vertex(3,3),Vertex(1,3),Vertex(1,2),Vertex(0,2))
    #print "Is: ",plines
    #print "Should: ",should
    assert plines==should
                            
    sqs=[]
    for line in plines:
        sqs.append(visualize.Line(
            line.get_v1().get_x(),
            line.get_v1().get_y(),
            line.get_v2().get_x(),
            line.get_v2().get_y(),                       
            (255,0,0)))
    draw_things(sqs)
Esempio n. 28
0
def test_polygon_intersect_line22():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(10,0),Vertex(10,5),Vertex(5,5),Vertex(5,10),Vertex(0,10)]))
    ls=list(polya.intersect_line(Line(Vertex(0,5),Vertex(10,6))))
    print ls
    assert ls==[Line(Vertex(0,5),Vertex(5,6))]
Esempio n. 29
0
def test_inside_poly2():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(0,5),Vertex(10,0),Vertex(10,10),Vertex(0,10)]))
    assert polya.is_inside(Vertex(5,5))
Esempio n. 30
0
        pa['floor'] = floor
        pa['ceiling'] = ceiling
        if mapper.parse_elev(floor) >= 9500:
            continue
        #uprint("Arealines:\n================\n%s\n============\n"%(arealines[:last_coord_idx]))
        #print pa
        areacoords = " ".join(arealines[:last_coord_idx])
        pa['points'] = parse_coord_str(areacoords)

        vs = []
        for p in pa['points']:
            #print "from_str:",repr(p)
            x, y = mapper.latlon2merc(mapper.from_str(p), 13)
            vs.append(Vertex(int(x), int(y)))

        p = Polygon(vvector(vs))
        if p.calc_area() <= 30 * 30:
            pass  #print pa
            #print "Area:",p.calc_area()
        assert p.calc_area() > 30 * 30
        #print "Area: %f"%(p.calc_area(),)
        #print "Point-counts:",len(pa['points'])
        for p in pa['points']:
            assert p.count(",") == 1
        pa['type'] = kind
        for thirdcol in thirdcols:
            if thirdcol in d:
                atc = d[thirdcol]
                break
        else:
            raise Exception("missing thirdcol")
Esempio n. 31
0
class UserData(object):
    def have_any(self):
        return not self.empty

    def __init__(self, user, orders=None):
        #print "Loading userdata for ",user
        self.user = user
        self.log = []
        self.points = dict()
        self.spaces = dict()
        self.pointslookup = dict()
        self.spaceslookup = dict()
        self.empty = True

        zoomlevel = 13
        pointtypes = ['obstacles', 'airfields', 'sigpoints']
        spacestypes = ['airspaces', 'firs']

        for pointtype in pointtypes:
            self.points[pointtype] = []
        for spacetype in spacestypes:
            self.spaces[spacetype] = []

        if orders == None:
            orders = []
            for csets in meta.Session.query(CustomSets).filter(
                    CustomSets.user == user).all():
                customs = list(
                    meta.Session.query(CustomSet).filter(
                        sa.and_(CustomSet.user == user,
                                CustomSet.setname == csets.setname,
                                CustomSet.version == csets.active)).all())
                orders.extend(customs)

        for custom in orders:
            try:
                #print "Found custom set:",custom.setname
                ##print "Found active custom set:",custom.setname,custom.version
                #print "Data:"
                #print "------------------"
                #print custom.data
                #print "Cont1"
                data = json.loads(u"".join([
                    x for x in custom.data.split("\n")
                    if not x.strip().startswith("#")
                ]).encode('utf8'))
                if type(data) != dict:
                    raise Exception(
                        "Top level must be object, that is, file must start with '{'"
                    )
                #print "Cont2"
                for pointtype in pointtypes:
                    if pointtype in data:
                        out = []
                        for point in data[pointtype]:
                            #print "val point"
                            if validate_point(point, pointtype, self.log):
                                out.append(point)
                            #print "aft val point"

                        if pointtype == 'airfields':
                            #print "val airf"
                            validate_airfield_space(point, self.log,
                                                    self.spaces['airspaces'])
                            #print "aft val airf"

                        self.points[pointtype].extend(out)
                        data.pop(pointtype)
                #print "Cont3"
                for spacetype in spacestypes:
                    if spacetype in data:
                        out = []
                        for space in data[spacetype]:
                            if validate_space(space, spacetype, self.log):
                                out.append(space)
                        self.spaces[spacetype].extend(out)
                        data.pop(spacetype)
                #print "Cont4"
                if len(data.keys()):
                    for key in data.keys():
                        self.log.append("Unknown top-level key: %s" % (key, ))

                #print "Cont5"
            except Exception, cause:
                print "Problem parsing custom", traceback.format_exc()
                self.log.append(traceback.format_exc())

        if len(self.log) == 0:
            #print "About to start bsptreein"
            for pointtype in pointtypes:
                bspitems = []
                for item in self.points[pointtype]:
                    #print "Adding BspTree item of type: ",pointtype,"item:",item
                    bspitems.append(
                        BspTree.Item(
                            mapper.latlon2merc(mapper.from_str(item['pos']),
                                               13), item))
                self.pointslookup[pointtype] = BspTree(bspitems)
                if bspitems:
                    self.empty = False

        airspaces = self.spaces.get('airspaces', [])
        firs = [space for space in airspaces if space['type'] == 'FIR']
        regular_airspaces = [
            space for space in airspaces if space['type'] != 'FIR'
        ]
        self.spaces['airspaces'] = regular_airspaces
        self.spaces['firs'] = firs

        if len(self.log) == 0:

            for spacetype in spacestypes:
                bbitems = []
                for space in self.spaces[spacetype]:
                    poly_coords = []
                    bb = BoundingBox(1e30, 1e30, -1e30, -1e30)
                    for coord in space['points']:
                        print "Coord:", coord
                        x, y = mapper.latlon2merc(mapper.from_str(coord),
                                                  zoomlevel)
                        bb.x1 = min(bb.x1, x)
                        bb.x2 = max(bb.x2, x)
                        bb.y1 = min(bb.y1, y)
                        bb.y2 = max(bb.y2, y)
                        poly_coords.append(Vertex(int(x), int(y)))
                    if len(poly_coords) < 3:
                        continue
                    poly = Polygon(vvector(poly_coords))
                    #print "Item:",space
                    bbitems.append(BBTree.TItem(bb, (poly, space)))
                self.spaceslookup[spacetype] = BBTree(bbitems, 0.5)
                if bbitems:
                    self.empty = False

        self.date = datetime.utcnow()
Esempio n. 32
0
def test_polygon_intersect_line4():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(5,0),Vertex(10,0),Vertex(5,0),Vertex(1,0),Vertex(0,1)]))
    ls=list(polya.intersect_line(Line(Vertex(-5,0),Vertex(15,0))))
    print ls
    assert ls==[Line(Vertex(0,0),Vertex(10,0))]
Esempio n. 33
0
def test_polygon_intersect_line15():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(10,0),Vertex(10,10),Vertex(0,10)]))
    ls=list(polya.intersect_line(Line(Vertex(10,-15),Vertex(10,25))))
    print ls
    assert ls==[Line(Vertex(10,0),Vertex(10,10))]
Esempio n. 34
0
def test_remove_loops5():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(80,0),Vertex(100,0),Vertex(80,0),Vertex(0,2)]))
    polyb=polya.remove_loops()
    assert polyb==Polygon(vvector([
        Vertex(0,0),Vertex(60,0),Vertex(0,2)]))
Esempio n. 35
0
def test_merge_straights():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(5,0),Vertex(10,0),Vertex(10,10),Vertex(0,10)]))
    polya.merge_straight_sections()
    assert polya==Polygon(vvector([
        Vertex(0,0),Vertex(10,0),Vertex(10,10),Vertex(0,10)]))
Esempio n. 36
0
def gen_bsptree_lookup(data):
    r = dict()

    lookup_points = ['obstacles', 'airfields', 'sig_points']
    for look in lookup_points:
        items = data.get(look, None)
        if True:
            bspitems = []
            for item in items:
                try:
                    bspitems.append(
                        BspTree.Item(
                            mapper.latlon2merc(mapper.from_str(item['pos']),
                                               13), item))
                except Exception:
                    print item
                    raise
            #print "Items for bsptree",items
            bsp = BspTree(bspitems)
            #assert len(bsp.getall())==len(items)
            #after=sorted(set(x['name'] for x in bsp.getall()))
            #before=sorted(set(x['name'] for x in obsts))
            #print after,"\n-------------------\n\n",before
            #assert after==before
            #print "same before as after"
            r[look] = bsp
    del item
    del items
    del bspitems
    del bsp

    lookup_spaces = ['airspaces', 'firs']
    for look in lookup_spaces:
        spaces = data.get(look, None)
        if spaces != None:
            bbitems = []
            zoomlevel = 13
            for space in spaces:
                poly_coords = []
                bb = BoundingBox(1e30, 1e30, -1e30, -1e30)
                for coord in space['points']:
                    x, y = mapper.latlon2merc(mapper.from_str(coord),
                                              zoomlevel)
                    bb.x1 = min(bb.x1, x)
                    bb.x2 = max(bb.x2, x)
                    bb.y1 = min(bb.y1, y)
                    bb.y2 = max(bb.y2, y)
                    poly_coords.append(Vertex(int(x), int(y)))
                if len(set(poly_coords)) < 3:
                    continue
                print "Poly"
                poly = Polygon(vvector(poly_coords))
                print "polydone"
                #print "Item:",space
                bbitems.append(BBTree.TItem(bb, (poly, space)))

                #if poly.is_inside(Vertex(int(px),int(py))):
                #    insides.append(space)

            bbt = BBTree(bbitems, 0.5)
            r[look] = bbt

    return r
Esempio n. 37
0
def extract_airfields(filtericao=lambda x:True,purge=True):
    #print getxml("/AIP/AD/AD 1/ES_AD_1_1_en.pdf")
    ads=[]
    p=Parser("/AIP/AD/AD 1/ES_AD_1_1_en.pdf")
    points=dict()
    startpage=None
    for pagenr in xrange(p.get_num_pages()):
        page=p.parse_page_to_items(pagenr)
        if page.count("Aerodrome directory"):
            startpage=pagenr
            break
    if startpage==None:
        raise Exception("Couldn't find aerodrome directory in file")
    #print "Startpage: %d"%(startpage,)
    #nochartf=open("nochart.txt","w")
    for pagenr in xrange(startpage,p.get_num_pages()):
        row_y=[]
        page=p.parse_page_to_items(pagenr)
        allines=[x for x in (page.get_lines(page.get_partially_in_rect(0,0,15,100))) if x.strip()]
        for item,next in zip(allines,allines[1:]+[""]):
            #print "item:",item
            
            m=re.match(ur"^\s*[A-ZÅÄÖ]{3,}(?:/.*)?\b.*",item)
            if m:
                #print "Candidate, next is:",next
                if re.match(r"^\s*[A-Z]{4}\b.*",next):
                    #print "Matched:",item
                    #print "y1:",item.y1                    
                    row_y.append(item.y1)
        for y1,y2 in zip(row_y,row_y[1:]+[100.0]):
            #print "Extacting from y-range: %f-%f"%(y1,y2)
            items=list(page.get_partially_in_rect(0,y1-0.25,5.0,y2+0.25,ysort=True))
            if len(items)>=2:
                #print "Extract items",items
                ad=dict(name=unicode(items[0].text).strip(),
                        icao=unicode(items[1].text).strip()                    
                        )
                #print "Icao:",ad['icao']
                assert re.match(r"[A-Z]{4}",ad['icao'])
                if not filtericao(ad): continue
                if len(items)>=3:
                    #print "Coord?:",items[2].text
                    m=re.match(r".*(\d{6}N)\s*(\d{7}E).*",items[2].text)
                    if m:
                        lat,lon=m.groups()
                        ad['pos']=parse_coords(lat,lon)           
                        #print "Items3:",items[3:]   
                        elev=re.findall(r"(\d{1,5})\s*ft"," ".join(t.text for t in items[3:]))
                        #print "Elev:",elev
                        assert len(elev)==1
                        ad['elev']=int(elev[0])                        
                                     
                ads.append(ad)

        
    big_ad=set()        
    for ad in ads:
        if not ad.has_key('pos'):
            big_ad.add(ad['icao'])
            
    for ad in ads:        
        icao=ad['icao']
        if icao in big_ad:            
            if icao in ['ESIB','ESNY','ESCM','ESPE']:
                continue                    
            
            try:
                p=Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_6_1_en.pdf"%(icao,icao))
            except:
                p=Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_6-1_en.pdf"%(icao,icao))

            ad['aipvacurl']=p.get_url()
            for pagenr in xrange(p.get_num_pages()):
                page=p.parse_page_to_items(pagenr)
                
                """
                for altline in exitlines:
                    m=re.match(r"(\w+)\s+(\d+N)\s*(\d+E.*)",altline)
                    if not m: continue
                    name,lat,lon=m.groups()
                    try:
                        coord=parse_coords(lat,lon)
                    except Exception:
                        continue
                    points.append(dict(name=name,pos=coord))
                """
                
                for kind in xrange(2):
                    if kind==0:
                        hits=page.get_by_regex(r"H[Oo][Ll][Dd][Ii][Nn][Gg]")
                        kind="holding point"
                    if kind==1:
                        hits=page.get_by_regex(r"[Ee]ntry.*[Ee]xit.*point")                    
                        kind="entry/exit point"
                    if len(hits)==0: continue
                    for holdingheading in hits:

                        items=sorted(page.get_partially_in_rect(holdingheading.x1+2.0,holdingheading.y2+0.1,holdingheading.x1+0.5,100),
                            key=lambda x:x.y1)
                        items=[x for x in items if not x.text.startswith(" ")]
                        #print "Holding items:",items
                        for idx,item in enumerate(items):
                            print "Holding item",item
                            y1=item.y1
                            if idx==len(items)-1:
                                y2=100
                            else:
                                y2=items[idx+1].y1
                            items2=[x for x in page.get_partially_in_rect(item.x1+1,y1+0.3,item.x1+40,y2-0.1) if x.x1>=item.x1-0.25 and x.y1>=y1-0.05 and x.y1<y2-0.05]
                            s=(" ".join(page.get_lines(items2))).strip()
                            print "Holding lines:",repr(page.get_lines(items2))
                            #if s.startswith("ft Left/3"): #Special case for ESOK
                            #    s,=re.match("ft Left/3.*?([A-Z]{4,}.*)",s).groups()
                            #m=re.match("ft Left/\d+.*?([A-Z]{4,}.*)",s)
                            #if m:
                            #    s,=m.groups()
                                
                            if s.startswith("LjUNG"): #Really strange problem with ESCF
                                s=s[0]+"J"+s[2:]
                            if s.lower().startswith("holding"):
                                sl=s.split(" ",1)
                                if len(sl)>1:
                                    s=sl[1]
                            s=s.strip()
                            if kind=="entry/exit point" and s.startswith("HOLDING"):
                                continue #reached HOLDING-part of VAC
                                
                            #Check for other headings
                            #Fixup strange formatting of points in some holding items: (whitespace between coord and 'E')                            
                            s=re.sub(ur"(\d+)\s*(N)\s*(\d+)\s*(E)",lambda x:"".join(x.groups()),s)

                            m=re.match(r"([A-Z]{2,}).*?(\d+N)\s*(\d+E).*",s)
                            if not m:                                
                                m=re.match(r".*?(\d+N)\s*(\d+E).*",s) 
                                if not m:
                                    continue
                                assert m
                                lat,lon=m.groups()
                                #skavsta
                                if icao=="ESKN":
                                    if s.startswith(u"Hold north of T"):
                                        name="NORTH"
                                    elif s.startswith(u"Hold south of B"):
                                        name="SOUTH"                     
                                    else:
                                        assert 0
                                #add more specials here            
                                else:
                                    continue
                            else:
                                name,lat,lon=m.groups()
                            try:
                                coord=parse_coords(lat,lon)
                            except Exception:
                                print "Couldn't parse:",lat,lon
                                continue
                            #print name,lat,lon,mapper.format_lfv(*mapper.from_str(coord))
                            
                            if name.count("REMARK") or len(name)<=2:
                                print "Suspicious name: ",name
                                #sys.exit(1)
                                continue
                            points[icao+' '+name]=dict(name=icao+' '+name,icao=icao,pos=coord,kind=kind)


    #for point in points.items():
    #    print point


    #sys.exit(1)

    def fixhex11(s):
        out=[]
        for c in s:
            i=ord(c)
            if i>=0x20:
                out.append(c)
                continue
            if i in [0x9,0xa,0xd]:
                out.append(c)
                continue
            out.append(' ')
            
        return "".join(out)
        
    for ad in ads:
        icao=ad['icao']
        if icao in big_ad:
            #print "Parsing ",icao
            p=Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_en.pdf"%(icao,icao),loadhook=fixhex11)
            ad['aiptexturl']=p.get_url()
            firstpage=p.parse_page_to_items(0)
            te="\n".join(firstpage.get_all_lines())                        
            #print te
            coords=re.findall(r"ARP.*(\d{6}N)\s*(\d{7}E)",te)
            if len(coords)>1:
                raise Exception("First page of airport info (%s) does not contain exactly ONE set of coordinates"%(icao,))
            if len(coords)==0:
                print "Couldn't find coords for ",icao
            #print "Coords:",coords
            ad['pos']=parse_coords(*coords[0])

            elev=re.findall(r"Elevation.*?(\d{1,5})\s*ft",te,re.DOTALL)
            if len(elev)>1:
                raise Exception("First page of airport info (%s) does not contain exactly ONE elevation in ft"%(icao,))
            if len(elev)==0:
                print "Couldn't find elev for ",icao                
            ad['elev']=int(elev[0])
            freqs=[]
            found=False
            thrs=[]
            #uprint("-------------------------------------")
            for pagenr in xrange(p.get_num_pages()):
                page=p.parse_page_to_items(pagenr)
                #uprint("Looking on page %d"%(pagenr,))
                if 0: #opening hours are no longer stored in a separate document for any airports. No need to detect which any more (since none are).
                    for item in page.get_by_regex(".*OPERATIONAL HOURS.*"):
                        lines=page.get_lines(page.get_partially_in_rect(0,item.y2+0.1,100,100))
                        for line in lines:
                            things=["ATS","Fuelling","Operating"]
                            if not line.count("AIP SUP"): continue
                            for thing in things:
                                if line.count(thing):
                                    ad['aipsup']=True
                        
                    
                for item in page.get_by_regex(".*\s*RUNWAY\s*PHYSICAL\s*CHARACTERISTICS\s*.*"):
                    #uprint("Physical char on page")
                    lines=page.get_lines(page.get_partially_in_rect(0,item.y2+0.1,100,100))
                    seen_end_rwy_text=False
                    for line,nextline in izip(lines,lines[1:]+[None]):
                        #uprint("MAtching: <%s>"%(line,))
                        if re.match(ur"AD\s+2.13",line): break
                        if line.count("Slope of"): break
                        if line.lower().count("end rwy:"): seen_end_rwy_text=True
                        if line.lower().count("bgn rwy:"): seen_end_rwy_text=True
                        m=re.match(ur".*(\d{6}\.\d+)[\s\(\)\*]*(N).*",line)
                        if not m:continue
                        m2=re.match(ur".*(\d{6,7}\.\d+)\s*[\s\(\)\*]*(E).*",nextline)                            
                        if not m2:continue
                        latd,n=m.groups()
                        lond,e=m2.groups()
                        assert n=="N"
                        assert e=="E"
                        lat=latd+n
                        lon=lond+e
                        rwytxts=page.get_lines(page.get_partially_in_rect(0,line.y1+0.05,12,nextline.y2-0.05))
                        uprint("Rwytxts:",rwytxts)
                        rwy=None
                        for rwytxt in rwytxts:
                            #uprint("lat,lon:%s,%s"%(lat,lon))
                            #uprint("rwytext:",rwytxt)
                            m=re.match(ur"\s*(\d{2}[LRCM]?)\b.*",rwytxt)
                            if m:
                                assert rwy==None
                                rwy=m.groups()[0]
                        if rwy==None and seen_end_rwy_text:
                            continue
                        print "Cur airport:",icao
                        already=False
                        assert rwy!=None
                        seen_end_rwy_text=False
                        for thr in thrs:
                            if thr['thr']==rwy:
                                raise Exception("Same runway twice on airfield:"+icao)
                        thrs.append(dict(pos=mapper.parse_coords(lat,lon),thr=rwy))
            assert len(thrs)>=2
            for pagenr in xrange(0,p.get_num_pages()):
                page=p.parse_page_to_items(pagenr)                                              
                
                matches=page.get_by_regex(r".*ATS\s+COMMUNICATION\s+FACILITIES.*")
                #print "Matches of ATS COMMUNICATION FACILITIES on page %d: %s"%(pagenr,matches)
                if len(matches)>0:
                    commitem=matches[0]
                    curname=None
                    
                    callsign=page.get_by_regex_in_rect(ur"Call\s*sign",0,commitem.y1,100,commitem.y2+8)[0]
                    
                    
                    for idx,item in enumerate(page.get_lines(page.get_partially_in_rect(callsign.x1-0.5,commitem.y1,100,100),fudge=0.3,order_fudge=15)):
                        if item.strip()=="":
                            curname=None
                        if re.match(".*RADIO\s+NAVIGATION\s+AND\s+LANDING\s+AIDS.*",item):
                            break
                        #print "Matching:",item
                        m=re.match(r"(.*?)\s*(\d{3}\.\d{1,3})\s*MHz.*",item)
                        #print "MHZ-match:",m
                        if not m: continue
                        #print "MHZ-match:",m.groups()
                        who,sfreq=m.groups()
                        freq=float(sfreq)
                        if abs(freq-121.5)<1e-4:
                            if who.strip():
                                curname=who
                            continue #Ignore emergency frequency, it is understood
                        if not who.strip():
                            if curname==None: continue
                        else:
                            curname=who
                        freqs.append((curname.strip().rstrip("/"),freq))


            for pagenr in xrange(0,p.get_num_pages()):
                page=p.parse_page_to_items(pagenr)                                              
                                
                matches=page.get_by_regex(r".*ATS\s*AIRSPACE.*")
                #print "Matches of ATS_AIRSPACE on page %d: %s"%(pagenr,matches)
                if len(matches)>0:
                    heading=matches[0]
                    desigitem,=page.get_by_regex("Designation and lateral limits")
                    vertitem,=page.get_by_regex("Vertical limits")
                    airspaceclass,=page.get_by_regex("Airspace classification")
                    
                    lastname=None
                    subspacelines=dict()
                    subspacealts=dict()
                    for idx,item in enumerate(page.get_lines(page.get_partially_in_rect(desigitem.x2+1,desigitem.y1,100,vertitem.y1-1))):
                        
                        if item.count("ATS airspace not established"):
                            assert idx==0
                            break
                            
                        if item.strip()=="": continue
                        m=re.match(r"(.*?)(\d{6}N\s+.*)",item)
                        if m:
                            name,coords=m.groups()                            
                            name=name.strip()
                        else:
                            name=item.strip()
                            coords=None
                        if name:
                            lastname=name
                        if coords:
                            subspacelines.setdefault(lastname,[]).append(coords)
                        assert lastname
                    lastname=None

                    #print "Spaces:",subspacelines
                    #print "ICAO",ad['icao']
                    #altlines=page.get_lines(page.get_partially_in_rect(vertitem.x2+1,vertitem.y1,100,airspaceclass.y1-0.2))
                    
                    #print "Altlines:",altlines
                    subspacealts=dict()
                    subspacekeys=subspacelines.keys()
                        
                    allaltlines=" ".join(page.get_lines(page.get_partially_in_rect(vertitem.x1+0.5,vertitem.y1+0.5,100,airspaceclass.y1-0.2)))
                    single_vertlim=False
                    totalts=list(mapper.parse_all_alts(allaltlines))
                    #print "totalts:",totalts 
                    if len(totalts)==2:
                        single_vertlim=True
                    
                    for subspacename in subspacekeys:
                        ceil=None
                        floor=None
                        subnames=[subspacename]
                        if subspacename.split(" ")[-1].strip() in ["TIA","TIZ","CTR","CTR/TIZ"]:
                            subnames.append(subspacename.split(" ")[-1].strip())
                        #print "Parsing alts for ",subspacename,subnames
                        try:                        
                            for nametry in subnames:
                                if single_vertlim: #there's only one subspace, parse all of vertical limits field for this single one.
                                    items=[vertitem]
                                else:
                                    items=page.get_by_regex_in_rect(nametry,vertitem.x2+1,vertitem.y1,100,airspaceclass.y1-0.2)
                                for item in items: 
                                    alts=[]
                                    for line in page.get_lines(page.get_partially_in_rect(item.x1+0.5,item.y1+0.5,100,airspaceclass.y1-0.2)):
                                        #print "Parsing:",line
                                        line=line.replace(nametry,"").lower().strip()
                                        parsed=list(mapper.parse_all_alts(line))
                                        if len(parsed):
                                            alts.append(mapper.altformat(*parsed[0]))
                                        if len(alts)==2: break
                                    if alts:
                                        #print "alts:",alts
                                        ceil,floor=alts
                                        raise StopIteration
                        except StopIteration:
                            pass
                        assert ceil and floor
                        subspacealts[subspacename]=dict(ceil=ceil,floor=floor)             
                        
                    spaces=[]                                        
                    for spacename in subspacelines.keys():
                        altspacename=spacename
                        #print "Altspacename: %s, subspacesalts: %s"%(altspacename,subspacealts)
                        space=dict(
                            name=spacename,
                            ceil=subspacealts[altspacename]['ceil'],
                            floor=subspacealts[altspacename]['floor'],
                            points=parse_coord_str(" ".join(subspacelines[spacename])),
                            freqs=list(set(freqs))
                            )
                        
                        if True:
                            vs=[]
                            for p in space['points']:
                                x,y=mapper.latlon2merc(mapper.from_str(p),13)
                                vs.append(Vertex(int(x),int(y)))                    
                            p=Polygon(vvector(vs))
                            if p.calc_area()<=30*30:
                                pass#print space
                                pass#print "Area:",p.calc_area()
                            assert p.calc_area()>30*30
                            #print "Area: %f"%(p.calc_area(),)
                        
                        spaces.append(space)
                        #print space
                    ad['spaces']=spaces
                    found=True
                if found:
                    break
            assert found                            
            ad['runways']=rwy_constructor.get_rwys(thrs)
                            
                            
            #Now find any ATS-airspace
    chartblobnames=[]
    for ad in ads:        
        icao=ad['icao']
        if icao in big_ad:          
            parse_landing_chart.help_plc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_2-1_en.pdf"%(icao,icao),
                            icao,ad['pos'],"se",variant="")
            parse_landing_chart.help_plc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_6-1_en.pdf"%(icao,icao),
                            icao,ad['pos'],"se",variant="vac")

            parse_landing_chart.help_plc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_2-3_en.pdf"%(icao,icao),
                            icao,ad['pos'],"se",variant="parking")
            
            
            #aip_text_documents.help_parse_doc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_6_1_en.pdf"%(icao,icao),
            #            icao,"se",title="General Information",category="general")
                                    
            
            aip_text_documents.help_parse_doc(ad,"/AIP/AD/AD 2/%s/ES_AD_2_%s_en.pdf"%(icao,icao),
                        icao,"se",title="General Information",category="general")
            
                  

    
    #if purge:
    #    parse_landing_chart.purge_old(chartblobnames,country="se")        
    
    #sys.exit(1)

    for extra in extra_airfields.extra_airfields:
        if filtericao(extra):
            ads.append(extra)
    print
    print
    for k,v in sorted(points.items()):
        print k,v,mapper.format_lfv(*mapper.from_str(v['pos']))
        
    #print "Num points:",len(points)
    
    origads=list(ads)    
    for flygkartan_id,name,lat,lon,dummy in csv.reader(open("fplan/extract/flygkartan.csv"),delimiter=";"):
        found=None
        lat=float(lat)
        lon=float(lon)
        if type(name)==str:
            name=unicode(name,'utf8')
        mercf=mapper.latlon2merc((lat,lon),13)
        for a in origads:
            merca=mapper.latlon2merc(mapper.from_str(a['pos']),13)
            dist=math.sqrt((merca[0]-mercf[0])**2+(merca[1]-mercf[1])**2)
            if dist<120:
                found=a
                break
        if found:
            found['flygkartan_id']=flygkartan_id
        else:
            d=dict(
                    icao='ZZZZ',
                    name=name,
                    pos=mapper.to_str((lat,lon)),
                    elev=int(get_terrain_elev((lat,lon))),
                    flygkartan_id=flygkartan_id)
            if filtericao(d):
                ads.append(d)
                    
    minor_ad_charts=extra_airfields.minor_ad_charts
        
                    
    for ad in ads:     
        if ad['name'].count(u"Långtora"):            
            ad['pos']=mapper.to_str(mapper.from_aviation_format("5944.83N01708.20E"))
            
        if ad['name'] in minor_ad_charts:
            charturl=minor_ad_charts[ad['name']]
            arp=ad['pos']
            if 'icao' in ad and ad['icao'].upper()!='ZZZZ':
                icao=ad['icao'].upper()
            else:
                icao=ad['fake_icao']
                
            parse_landing_chart.help_plc(ad,charturl,icao,arp,country='raw',variant="landing")
            """
            assert icao!=None
            lc=parse_landing_chart.parse_landing_chart(
                    charturl,
                    icao=icao,
                    arppos=arp,country="raw")
            assert lc
            if lc:
                ad['adcharturl']=lc['url']
                ad['adchart']=lc
            """
            
    #print ads
    for ad in ads:
        print "%s: %s - %s (%s ft) (%s)"%(ad['icao'],ad['name'],ad['pos'],ad['elev'],ad.get('flygkartan_id','inte i flygkartan'))
        for space in ad.get('spaces',[]):
            for freq in space.get('freqs',[]):
                print "   ",freq
        #if 'spaces' in ad:
        #    print "   spaces: %s"%(ad['spaces'],)
        #if 'aiptext' in ad:
        #    print "Aip texts:",ad['aiptext']
        #else:
        #    print "No aiptext"
    print "Points:"
    for point in sorted(points.values(),key=lambda x:x['name']):
        print point
        
    f=codecs.open("extract_airfields.regress.txt","w",'utf8')    
    for ad in ads:
        r=repr(ad)
        d=md5.md5(r).hexdigest()
        f.write("%s - %s - %s\n"%(ad['icao'],ad['name'],d))
    f.close()
    f=codecs.open("extract_airfields.regress-details.txt","w",'utf8')    
    for ad in ads:
        r=repr(ad)
        f.write(u"%s - %s - %s\n"%(ad['icao'],ad['name'],r))
    f.close()
    
    return ads,points.values()
Esempio n. 38
0
def test_polygon_intersect_line23():
    polya=Polygon(vvector([
        Vertex(0,0),Vertex(10000000,0),Vertex(10000000,10000000),Vertex(0,10000000)]))
    ls=list(polya.intersect_line(Line(Vertex(-5000000,5000000),Vertex(15000000,5000000))))
    print ls
    assert ls==[Line(Vertex(0,5000000),Vertex(10000000,5000000))]
Esempio n. 39
0
def extract_airfields(filtericao=lambda x: True, purge=True):
    # print getxml("/AIP/AD/AD 1/ES_AD_1_1_en.pdf")
    ads = []
    p = Parser("/AIP/AD/AD 1/ES_AD_1_1_en.pdf")
    points = dict()
    startpage = None
    for pagenr in xrange(p.get_num_pages()):
        page = p.parse_page_to_items(pagenr)
        if page.count("Aerodrome directory"):
            startpage = pagenr
            break
    if startpage == None:
        raise Exception("Couldn't find aerodrome directory in file")
    # print "Startpage: %d"%(startpage,)
    # nochartf=open("nochart.txt","w")
    for pagenr in xrange(startpage, p.get_num_pages()):
        row_y = []
        page = p.parse_page_to_items(pagenr)
        allines = [x for x in (page.get_lines(page.get_partially_in_rect(0, 0, 15, 100))) if x.strip()]
        for item, next in zip(allines, allines[1:] + [""]):
            # print "item:",item

            m = re.match(ur"^\s*[A-ZÅÄÖ]{3,}(?:/.*)?\b.*", item)
            if m:
                # print "Candidate, next is:",next
                if re.match(r"^\s*[A-Z]{4}\b.*", next):
                    # print "Matched:",item
                    # print "y1:",item.y1
                    row_y.append(item.y1)
        for y1, y2 in zip(row_y, row_y[1:] + [100.0]):
            # print "Extacting from y-range: %f-%f"%(y1,y2)
            items = list(page.get_partially_in_rect(0, y1 - 0.25, 5.0, y2 + 0.25, ysort=True))
            if len(items) >= 2:
                # print "Extract items",items
                ad = dict(name=unicode(items[0].text).strip(), icao=unicode(items[1].text).strip())
                # print "Icao:",ad['icao']
                assert re.match(r"[A-Z]{4}", ad["icao"])
                if not filtericao(ad):
                    continue
                if len(items) >= 3:
                    # print "Coord?:",items[2].text
                    m = re.match(r".*(\d{6}N)\s*(\d{7}E).*", items[2].text)
                    if m:
                        lat, lon = m.groups()
                        ad["pos"] = parse_coords(lat, lon)
                        # print "Items3:",items[3:]
                        elev = re.findall(r"(\d{1,5})\s*ft", " ".join(t.text for t in items[3:]))
                        # print "Elev:",elev
                        assert len(elev) == 1
                        ad["elev"] = int(elev[0])

                ads.append(ad)

    big_ad = set()
    for ad in ads:
        if not ad.has_key("pos"):
            big_ad.add(ad["icao"])

    for ad in ads:
        icao = ad["icao"]
        if icao in big_ad:
            if icao in ["ESIB", "ESNY", "ESCM", "ESPE"]:
                continue

            try:
                p = Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_6_1_en.pdf" % (icao, icao))
            except:
                p = Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_6-1_en.pdf" % (icao, icao))

            ad["aipvacurl"] = p.get_url()
            for pagenr in xrange(p.get_num_pages()):
                page = p.parse_page_to_items(pagenr)

                """
                for altline in exitlines:
                    m=re.match(r"(\w+)\s+(\d+N)\s*(\d+E.*)",altline)
                    if not m: continue
                    name,lat,lon=m.groups()
                    try:
                        coord=parse_coords(lat,lon)
                    except Exception:
                        continue
                    points.append(dict(name=name,pos=coord))
                """

                for kind in xrange(2):
                    if kind == 0:
                        hits = page.get_by_regex(r"H[Oo][Ll][Dd][Ii][Nn][Gg]")
                        kind = "holding point"
                    if kind == 1:
                        hits = page.get_by_regex(r"[Ee]ntry.*[Ee]xit.*point")
                        kind = "entry/exit point"
                    if len(hits) == 0:
                        continue
                    for holdingheading in hits:

                        items = sorted(
                            page.get_partially_in_rect(
                                holdingheading.x1 + 2.0, holdingheading.y2 + 0.1, holdingheading.x1 + 0.5, 100
                            ),
                            key=lambda x: x.y1,
                        )
                        items = [x for x in items if not x.text.startswith(" ")]
                        # print "Holding items:",items
                        for idx, item in enumerate(items):
                            print "Holding item", item
                            y1 = item.y1
                            if idx == len(items) - 1:
                                y2 = 100
                            else:
                                y2 = items[idx + 1].y1
                            items2 = [
                                x
                                for x in page.get_partially_in_rect(item.x1 + 1, y1 + 0.3, item.x1 + 40, y2 - 0.1)
                                if x.x1 >= item.x1 - 0.25 and x.y1 >= y1 - 0.05 and x.y1 < y2 - 0.05
                            ]
                            s = (" ".join(page.get_lines(items2))).strip()
                            print "Holding lines:", repr(page.get_lines(items2))
                            # if s.startswith("ft Left/3"): #Special case for ESOK
                            #    s,=re.match("ft Left/3.*?([A-Z]{4,}.*)",s).groups()
                            # m=re.match("ft Left/\d+.*?([A-Z]{4,}.*)",s)
                            # if m:
                            #    s,=m.groups()

                            if s.startswith("LjUNG"):  # Really strange problem with ESCF
                                s = s[0] + "J" + s[2:]
                            if s.lower().startswith("holding"):
                                sl = s.split(" ", 1)
                                if len(sl) > 1:
                                    s = sl[1]
                            s = s.strip()
                            if kind == "entry/exit point" and s.startswith("HOLDING"):
                                continue  # reached HOLDING-part of VAC

                            # Check for other headings
                            # Fixup strange formatting of points in some holding items: (whitespace between coord and 'E')
                            s = re.sub(ur"(\d+)\s*(N)\s*(\d+)\s*(E)", lambda x: "".join(x.groups()), s)

                            m = re.match(r"([A-Z]{2,}).*?(\d+N)\s*(\d+E).*", s)
                            if not m:
                                m = re.match(r".*?(\d+N)\s*(\d+E).*", s)
                                if not m:
                                    continue
                                assert m
                                lat, lon = m.groups()
                                # skavsta
                                if icao == "ESKN":
                                    if s.startswith(u"Hold north of T"):
                                        name = "NORTH"
                                    elif s.startswith(u"Hold south of B"):
                                        name = "SOUTH"
                                    else:
                                        assert 0
                                # add more specials here
                                else:
                                    continue
                            else:
                                name, lat, lon = m.groups()
                            try:
                                coord = parse_coords(lat, lon)
                            except Exception:
                                print "Couldn't parse:", lat, lon
                                continue
                            # print name,lat,lon,mapper.format_lfv(*mapper.from_str(coord))

                            if name.count("REMARK") or len(name) <= 2:
                                print "Suspicious name: ", name
                                # sys.exit(1)
                                continue
                            points[icao + " " + name] = dict(name=icao + " " + name, icao=icao, pos=coord, kind=kind)

    # for point in points.items():
    #    print point

    # sys.exit(1)

    def fixhex11(s):
        out = []
        for c in s:
            i = ord(c)
            if i >= 0x20:
                out.append(c)
                continue
            if i in [0x9, 0xA, 0xD]:
                out.append(c)
                continue
            out.append(" ")

        return "".join(out)

    for ad in ads:
        icao = ad["icao"]
        if icao in big_ad:
            # print "Parsing ",icao
            p = Parser("/AIP/AD/AD 2/%s/ES_AD_2_%s_en.pdf" % (icao, icao), loadhook=fixhex11)
            ad["aiptexturl"] = p.get_url()
            firstpage = p.parse_page_to_items(0)
            te = "\n".join(firstpage.get_all_lines())
            # print te
            coords = re.findall(r"ARP.*(\d{6}N)\s*(\d{7}E)", te)
            if len(coords) > 1:
                raise Exception(
                    "First page of airport info (%s) does not contain exactly ONE set of coordinates" % (icao,)
                )
            if len(coords) == 0:
                print "Couldn't find coords for ", icao
            # print "Coords:",coords
            ad["pos"] = parse_coords(*coords[0])

            elev = re.findall(r"Elevation.*?(\d{1,5})\s*ft", te, re.DOTALL)
            if len(elev) > 1:
                raise Exception(
                    "First page of airport info (%s) does not contain exactly ONE elevation in ft" % (icao,)
                )
            if len(elev) == 0:
                print "Couldn't find elev for ", icao
            ad["elev"] = int(elev[0])
            freqs = []
            found = False
            thrs = []
            # uprint("-------------------------------------")
            for pagenr in xrange(p.get_num_pages()):
                page = p.parse_page_to_items(pagenr)
                # uprint("Looking on page %d"%(pagenr,))
                if (
                    0
                ):  # opening hours are no longer stored in a separate document for any airports. No need to detect which any more (since none are).
                    for item in page.get_by_regex(".*OPERATIONAL HOURS.*"):
                        lines = page.get_lines(page.get_partially_in_rect(0, item.y2 + 0.1, 100, 100))
                        for line in lines:
                            things = ["ATS", "Fuelling", "Operating"]
                            if not line.count("AIP SUP"):
                                continue
                            for thing in things:
                                if line.count(thing):
                                    ad["aipsup"] = True

                for item in page.get_by_regex(".*\s*RUNWAY\s*PHYSICAL\s*CHARACTERISTICS\s*.*"):
                    # uprint("Physical char on page")
                    lines = page.get_lines(page.get_partially_in_rect(0, item.y2 + 0.1, 100, 100))
                    seen_end_rwy_text = False
                    for line, nextline in izip(lines, lines[1:] + [None]):
                        # uprint("MAtching: <%s>"%(line,))
                        if re.match(ur"AD\s+2.13", line):
                            break
                        if line.count("Slope of"):
                            break
                        if line.lower().count("end rwy:"):
                            seen_end_rwy_text = True
                        if line.lower().count("bgn rwy:"):
                            seen_end_rwy_text = True
                        m = re.match(ur".*(\d{6}\.\d+)[\s\(\)\*]*(N).*", line)
                        if not m:
                            continue
                        m2 = re.match(ur".*(\d{6,7}\.\d+)\s*[\s\(\)\*]*(E).*", nextline)
                        if not m2:
                            continue
                        latd, n = m.groups()
                        lond, e = m2.groups()
                        assert n == "N"
                        assert e == "E"
                        lat = latd + n
                        lon = lond + e
                        rwytxts = page.get_lines(page.get_partially_in_rect(0, line.y1 + 0.05, 12, nextline.y2 - 0.05))
                        uprint("Rwytxts:", rwytxts)
                        rwy = None
                        for rwytxt in rwytxts:
                            # uprint("lat,lon:%s,%s"%(lat,lon))
                            # uprint("rwytext:",rwytxt)
                            m = re.match(ur"\s*(\d{2}[LRCM]?)\b.*", rwytxt)
                            if m:
                                assert rwy == None
                                rwy = m.groups()[0]
                        if rwy == None and seen_end_rwy_text:
                            continue
                        print "Cur airport:", icao
                        already = False
                        assert rwy != None
                        seen_end_rwy_text = False
                        for thr in thrs:
                            if thr["thr"] == rwy:
                                raise Exception("Same runway twice on airfield:" + icao)
                        thrs.append(dict(pos=mapper.parse_coords(lat, lon), thr=rwy))
            assert len(thrs) >= 2
            for pagenr in xrange(0, p.get_num_pages()):
                page = p.parse_page_to_items(pagenr)

                matches = page.get_by_regex(r".*ATS\s+COMMUNICATION\s+FACILITIES.*")
                # print "Matches of ATS COMMUNICATION FACILITIES on page %d: %s"%(pagenr,matches)
                if len(matches) > 0:
                    commitem = matches[0]
                    curname = None

                    callsign = page.get_by_regex_in_rect(ur"Call\s*sign", 0, commitem.y1, 100, commitem.y2 + 8)[0]

                    for idx, item in enumerate(
                        page.get_lines(
                            page.get_partially_in_rect(callsign.x1 - 0.5, commitem.y1, 100, 100),
                            fudge=0.3,
                            order_fudge=15,
                        )
                    ):
                        if item.strip() == "":
                            curname = None
                        if re.match(".*RADIO\s+NAVIGATION\s+AND\s+LANDING\s+AIDS.*", item):
                            break
                        # print "Matching:",item
                        m = re.match(r"(.*?)\s*(\d{3}\.\d{1,3})\s*MHz.*", item)
                        # print "MHZ-match:",m
                        if not m:
                            continue
                        # print "MHZ-match:",m.groups()
                        who, sfreq = m.groups()
                        freq = float(sfreq)
                        if abs(freq - 121.5) < 1e-4:
                            if who.strip():
                                curname = who
                            continue  # Ignore emergency frequency, it is understood
                        if not who.strip():
                            if curname == None:
                                continue
                        else:
                            curname = who
                        freqs.append((curname.strip().rstrip("/"), freq))

            for pagenr in xrange(0, p.get_num_pages()):
                page = p.parse_page_to_items(pagenr)

                matches = page.get_by_regex(r".*ATS\s*AIRSPACE.*")
                # print "Matches of ATS_AIRSPACE on page %d: %s"%(pagenr,matches)
                if len(matches) > 0:
                    heading = matches[0]
                    desigitem, = page.get_by_regex("Designation and lateral limits")
                    vertitem, = page.get_by_regex("Vertical limits")
                    airspaceclass, = page.get_by_regex("Airspace classification")

                    lastname = None
                    subspacelines = dict()
                    subspacealts = dict()
                    for idx, item in enumerate(
                        page.get_lines(page.get_partially_in_rect(desigitem.x2 + 1, desigitem.y1, 100, vertitem.y1 - 1))
                    ):

                        if item.count("ATS airspace not established"):
                            assert idx == 0
                            break

                        if item.strip() == "":
                            continue
                        m = re.match(r"(.*?)(\d{6}N\s+.*)", item)
                        if m:
                            name, coords = m.groups()
                            name = name.strip()
                        else:
                            name = item.strip()
                            coords = None
                        if name:
                            lastname = name
                        if coords:
                            subspacelines.setdefault(lastname, []).append(coords)
                        assert lastname
                    lastname = None

                    # print "Spaces:",subspacelines
                    # print "ICAO",ad['icao']
                    # altlines=page.get_lines(page.get_partially_in_rect(vertitem.x2+1,vertitem.y1,100,airspaceclass.y1-0.2))

                    # print "Altlines:",altlines
                    subspacealts = dict()
                    subspacekeys = subspacelines.keys()

                    allaltlines = " ".join(
                        page.get_lines(
                            page.get_partially_in_rect(
                                vertitem.x1 + 0.5, vertitem.y1 + 0.5, 100, airspaceclass.y1 - 0.2
                            )
                        )
                    )
                    single_vertlim = False
                    totalts = list(mapper.parse_all_alts(allaltlines))
                    # print "totalts:",totalts
                    if len(totalts) == 2:
                        single_vertlim = True

                    for subspacename in subspacekeys:
                        ceil = None
                        floor = None
                        subnames = [subspacename]
                        if subspacename.split(" ")[-1].strip() in ["TIA", "TIZ", "CTR", "CTR/TIZ"]:
                            subnames.append(subspacename.split(" ")[-1].strip())
                        # print "Parsing alts for ",subspacename,subnames
                        try:
                            for nametry in subnames:
                                if (
                                    single_vertlim
                                ):  # there's only one subspace, parse all of vertical limits field for this single one.
                                    items = [vertitem]
                                else:
                                    items = page.get_by_regex_in_rect(
                                        nametry, vertitem.x2 + 1, vertitem.y1, 100, airspaceclass.y1 - 0.2
                                    )
                                for item in items:
                                    alts = []
                                    for line in page.get_lines(
                                        page.get_partially_in_rect(
                                            item.x1 + 0.5, item.y1 + 0.5, 100, airspaceclass.y1 - 0.2
                                        )
                                    ):
                                        # print "Parsing:",line
                                        line = line.replace(nametry, "").lower().strip()
                                        parsed = list(mapper.parse_all_alts(line))
                                        if len(parsed):
                                            alts.append(mapper.altformat(*parsed[0]))
                                        if len(alts) == 2:
                                            break
                                    if alts:
                                        # print "alts:",alts
                                        ceil, floor = alts
                                        raise StopIteration
                        except StopIteration:
                            pass
                        assert ceil and floor
                        subspacealts[subspacename] = dict(ceil=ceil, floor=floor)

                    spaces = []
                    for spacename in subspacelines.keys():
                        altspacename = spacename
                        # print "Altspacename: %s, subspacesalts: %s"%(altspacename,subspacealts)
                        space = dict(
                            name=spacename,
                            ceil=subspacealts[altspacename]["ceil"],
                            floor=subspacealts[altspacename]["floor"],
                            points=parse_coord_str(" ".join(subspacelines[spacename])),
                            freqs=list(set(freqs)),
                        )

                        if True:
                            vs = []
                            for p in space["points"]:
                                x, y = mapper.latlon2merc(mapper.from_str(p), 13)
                                vs.append(Vertex(int(x), int(y)))
                            p = Polygon(vvector(vs))
                            if p.calc_area() <= 30 * 30:
                                pass  # print space
                                pass  # print "Area:",p.calc_area()
                            assert p.calc_area() > 30 * 30
                            # print "Area: %f"%(p.calc_area(),)

                        spaces.append(space)
                        # print space
                    ad["spaces"] = spaces
                    found = True
                if found:
                    break
            assert found
            ad["runways"] = rwy_constructor.get_rwys(thrs)