示例#1
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
示例#2
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)
示例#3
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)
示例#4
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
示例#5
0
        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),)
示例#6
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