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
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()
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)]))
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))]
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
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))
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
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))
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
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
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
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
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
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
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
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]
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]
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)
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
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)
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)]))
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
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
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))]
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))
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))]
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))]
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))]
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()
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)]))
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")
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()