コード例 #1
0
ファイル: airportproj.py プロジェクト: dimme/SwFlightPlanner
    def invent_matrix(self, cksum, variant):
        print "Variant:", variant
        for ad in ec.get_airfields():
            if not 'adcharts' in ad: continue
            dbb = False
            for adchart in ad['adcharts'].values():
                if adchart['checksum'] == cksum:
                    lat, lon = mapper.from_str(ad['pos'])
                    w, h = adchart['render_width'], adchart['render_height']
                    print "adpos:", ad['pos'], lat, lon
                    dbb = True
                    break
            if dbb: break
        else:
            raise Exception("Can't find this chart in aipdata")

        if variant.lower().count('vac'):
            mercsizex = w
            mercsizey = h
            scale = 7
        else:
            mercsizex = w
            mercsizey = h
            scale = 1

        print "lat,lon", lat, lon
        m1 = mapper.latlon2merc((lat, lon), 13)
        print "corner merc", m1
        ns = []
        for offx, offy in [(0, 0), (mercsizex, 0), (0, mercsizey),
                           (mercsizex, mercsizey)]:
            merc2 = (m1[0] + (offx - mercsizex / 2) * scale,
                     m1[1] + (offy - mercsizey / 2) * scale)
            n = AirportMarker()
            n.latitude, n.longitude = mapper.merc2latlon(merc2, 13)
            n.x, n.y = (offx, offy)
            ns.append(n)
        error, A, T = customproj.solve(ns)
        matrix = list(A) + list(T)
        print "Fake projection:", matrix
        return matrix
コード例 #2
0
ファイル: airportproj.py プロジェクト: dimme/SwFlightPlanner
    def save(self):
        print request.params

        ad = request.params['ad']
        chartobj = None
        mapchecksum = request.params['mapchecksum']
        for adobj in ec.get_airfields():
            if adobj['name'] == ad:
                bb = False
                for adchart in adobj['adcharts'].values():
                    if adchart['checksum'] == mapchecksum:
                        chartobj = adchart
                        bb = True
                        break
                if bb: break
        else:
            self.error("No such airport" + ad)
        marks = dict()
        for param, val in request.params.items():
            if param in [
                    "save", "ad", 'mapchecksum', 'scroll_x', 'scroll_y',
                    'maptype', 'scale', 'north'
            ]:
                continue
            if param.startswith("del"):
                continue
            if param.startswith("set_"):
                x, y = [int(v) for v in param.split("_")[1:]]
                session['curadmarker'] = (x, y)
                session.save()
                continue
            if param == "add":
                xs = meta.Session.query(AirportMarker.x).filter(
                    sa.and_(AirportMarker.user == session['user'],
                            AirportMarker.airport == ad)).all()
                if xs:
                    maxx = max(xs)[0] + 1
                else:
                    maxx = 0
                marks[(maxx, 0)] = dict(latitude=None,
                                        longitude=None,
                                        x=maxx,
                                        y=0)
                session['curadmarker'] = (maxx, 0)
                session.save()
                continue

            sx, sy, attrib = re.match(ur"mark_(\d+)_(\d+)_(\w*)",
                                      param).groups()
            x = int(sx)
            y = int(sy)
            marks.setdefault((x, y), dict())[attrib] = val

        thresholds = dict()
        for rwy in adobj.get('runways', []):
            ends = rwy['ends']
            for end in ends:
                thresholds[end['thr']] = mapper.from_str(end['pos'])

        for param, val in request.params.items():
            if param.startswith("del_"):
                x, y = [int(v) for v in param.split("_")[1:]]
                marks.pop((x, y))
                continue

        meta.Session.query(AirportMarker).filter(
            sa.and_(AirportMarker.user == session['user'],
                    AirportMarker.airport == ad)).delete()
        ms = []
        arppos = mapper.from_str(adobj['pos'])

        for (x, y), val in marks.items():
            m = AirportMarker()
            m.user = session['user']
            m.airport = ad
            m.mapchecksum = str(mapchecksum)
            m.x = int(val['x'])
            m.y = int(val['y'])

            m.latitude, w1 = parselatlon(val['latitude'], arppos, thresholds,
                                         0)
            m.longitude, w2 = parselatlon(val['longitude'], arppos, thresholds,
                                          1)
            if w1 or w2:
                m.weight = w1 + w2
            else:
                m.weigth = 1

            meta.Session.add(m)
            ms.append(m)

        proj = meta.Session.query(AirportProjection).filter(
            sa.and_(AirportProjection.user == session['user'],
                    AirportProjection.airport == ad,
                    AirportProjection.mapchecksum == str(mapchecksum))).one()

        try:
            proj.scale = float(request.params['scale'].strip())
        except:
            proj.scale = None
        try:
            proj.north = float(request.params['north'].strip())
        except:
            proj.north = None

        def both_lat_lon(x):
            return x.latitude and x.longitude

        def neither_lat_lon(x):
            return not x.latitude and not x.longitude

        def just_lat(x):
            return x.latitude and not x.longitude

        def just_lon(x):
            return not x.latitude and x.longitude

        ms = [m for m in ms if not neither_lat_lon(m)]
        """
        if (len(ms)==4 and
            len([m for m in ms if just_lat(m)])==2 and
            len([m for m in ms if just_lon(m)])==2):
            extra=[]
            for m in ms:
                n=AirportMarker()
                n.x=m.x
                n.y=m.y                    
                if just_lat(m):
                    n.latitude=m.latitude
                    n.x+=1000
                    extra.append(n)
                if just_lon(m):
                    n.y+=1000                    
                    n.longitude=m.longitude
                    extra.append(n)
            ms.extend(extra)
        """

        if len(ms) == 1 and both_lat_lon(
                ms[0]) and proj.scale and proj.north != None:
            print "Scale/north triggered"
            print "Adchart:", chartobj
            if chartobj != None:
                render_height = chartobj['render_height']

                mark, = ms
                pixelpos = (mark.x, mark.y)
                mapsize = adchart.get('mapsize', (210, 297))
                mapheight_meter = mapsize[1] / 1000.0 * proj.scale
                mapheight_km = mapheight_meter / 1000.0

                merc = mapper.latlon2merc((mark.latitude, mark.longitude), 17)

                pixels = mapper.approx_scale(merc, 17, mapheight_km / 1.852)

                newmerc = (merc[0], merc[1] - pixels)
                northrad = proj.north / (180.0 / math.pi)
                newpixelpos = (pixelpos[0] +
                               render_height * math.sin(northrad),
                               pixelpos[1] -
                               render_height * math.cos(northrad))

                m = AirportMarker()
                m.x = newpixelpos[0]
                m.y = newpixelpos[1]
                latlon = mapper.merc2latlon(newmerc, 17)
                m.latitude = latlon[0]
                m.longitude = latlon[1]
                m.weight = 1
                ms.append(m)

        if len(ms) == 2 and all(both_lat_lon(x) for x in ms):
            print "Have exactly two marks now"
            mark1, mark2 = ms
            lm1, lm2 = [
                mapper.latlon2merc((mark.latitude, mark.longitude), 17)
                for mark in [mark1, mark2]
            ]
            ld = (lm2[0] - lm1[0], lm2[1] - lm1[1])
            pd = (mark2.x - mark1.x, mark2.y - mark1.y)
            lm3 = (lm1[0] - ld[1], lm1[1] + ld[0])
            pm3 = (mark1.x - pd[1], mark1.y + pd[0])
            llm3 = mapper.merc2latlon(lm3, 17)

            m = AirportMarker()
            m.x = pm3[0]
            m.y = pm3[1]
            m.latitude, w1 = llm3[0], 1
            m.longitude, w2 = llm3[1], 1
            ms.append(m)
            print "delta pixels", pd
            print "delta latlon", ld
            print "extra end pixels", m.x, m.y
            print "extra end latlon", m.latitude, m.longitude

        eqns = 0
        for m in ms:
            if both_lat_lon(m): eqns += 2
            elif just_lat(m): eqns += 1
            elif just_lon(m): eqns += 1

        try:
            if eqns < 4: raise Exception("Unsolvable")
            error, A, T = customproj.solve(ms)
            matrix = list(A) + list(T)
            if proj.matrix:
                oldmatrix = list(proj.matrix)
                newmatrix = list(A) + list(T)
                diff = sum(abs(a - b) for a, b in zip(oldmatrix, newmatrix))
            else:
                diff = 1e30  #enough to trigger update
            if diff > 1e-12:
                proj.matrix = tuple(newmatrix)
                proj.updated = datetime.utcnow().replace(microsecond=0)
        except Exception, cause:
            print "Couldn't solve projection equation %s" % (cause, )
            proj.matrix = [1, 0, 0, 1, 0, 0]
            proj.updated = datetime.utcnow().replace(microsecond=0)
            meta.Session.add(proj)