示例#1
0
        /*@Nonnull*/
        private static Point decodeNameless(string str, int firstrec, string extrapostfix, Data mapcoderData)
        {
            String result = str;
            if (mapcoderData.Codex == 22)
            {
                result = result.Substring(0, 3) + result.Substring(4);
            }
            else {
                result = result.Substring(0, 2) + result.Substring(3);
            }

            int a = Common.CountCityCoordinatesForCountry(mapcoderData.Codex, firstrec, firstrec);
            if (a < 2)
            {
                a = 1; // paranoia
            }

            int p = 31 / a;
            int r = 31 % a;
            int v = 0;
            int nrX;
            bool swapletters = false;

            if (mapcoderData.Codex != 21 && a <= 31)
            {
                int offset = decode_chars[(int) result[0]];

                if (offset < r * (p + 1))
                {
                    nrX = offset / (p + 1);
                }
                else
                {
                    swapletters = p == 1 && mapcoderData.Codex == 22;
                    nrX = r + (offset - r * (p + 1)) / p;
                }
            }
            else if (mapcoderData.Codex != 21 && a < 62)
            {
                nrX = decode_chars[(int) result[0]];
                if (nrX < (62 - a))
                {
                    swapletters = mapcoderData.Codex == 22;
                }
                else
                {
                    nrX = nrX + nrX - 62 + a;
                }
            }
            else
            {
                // codex==21 || A>=62
                int basePower = (mapcoderData.Codex == 21) ? 961 * 961 : 961 * 961 * 31;
                int basePowerA = basePower / a;
                if (a == 62)
                {
                    basePowerA++;
                }
                else
                {
                    basePowerA = 961 * (basePowerA / 961);
                }

                // decode and determine x
                v = fastDecode(result);
                nrX = v / basePowerA;
                v %= basePowerA;
            }

            if (swapletters && !Data.GetIsSpecialShape(firstrec + nrX))
            {
                result = result.Substring(0, 2) + result[3] + result[2] + result[4];
            }

            if (mapcoderData.Codex != 21 && a <= 31)
            {
                v = fastDecode(result);
                if (nrX > 0)
                {
                    v -= (nrX * p + (nrX < r ? nrX : r)) * 961 * 961;
                }
            }
            else if (mapcoderData.Codex != 21 && a < 62)
            {
                v = fastDecode(result.Substring(1));
                if (nrX >= (62 - a) && v >= (16 * 961 * 31))
                {
                    v -= 16 * 961 * 31;
                    nrX++;
                }
            }

            if (nrX > a)
            {
                return Point.undefined(); // return undefined (past end!)
            }
            mapcoderData.dataSetup(firstrec + nrX);

            int side = DataAccess.SmartDiv(firstrec + nrX);
            int xSIDE = side;

            int maxy = mapcoderData.MapcoderRect.getMaxY();
            int minx = mapcoderData.MapcoderRect.getMinX();
            int miny = mapcoderData.MapcoderRect.getMinY();

            int dx;
            int dy;

            if (mapcoderData.IsSpecialShape)
            {
                xSIDE *= side;
                side = 1 + (maxy - miny) / 90;
                xSIDE = xSIDE / side;

                Point d = decode6(v, xSIDE, side);
                dx = d.getLonMicroDeg();
                dy = side - 1 - d.getLatMicroDeg();
            }
            else
            {
                dy = v % side;
                dx = v / side;
            }

            if (dx >= xSIDE) // else out-of-range!
            {
                return Point.undefined(); // return undefined (out of range!)
            }

            int dividerx4 = Common.XDivider(miny, maxy); // 4 times too large!
            int dividery = 90;

            int cornerx = minx + (dx * dividerx4) / 4; // FIRST multiply, THEN
            // divide!
            int cornery = maxy - dy * dividery;
            return add2res(cornery, cornerx, dividerx4, dividery, -1, extrapostfix);
        }
示例#2
0
        /*@Nonnull*/
        private static Point decodeStarpipe(string input, int firstindex, string extrapostfix,
            /*@Nonnull*/ Data mapcoderData)
        {
            // returns Point.isUndefined() in case or error
            int storageStart = 0;
            int thiscodexlen = mapcoderData.CodexLen;

            int value = fastDecode(input); // decode top (before dot)
            value *= 961 * 31;
            Point triple = decodeTriple(input.Substring(input.Length - 3));
            // decode bottom 3 chars

            int i;
            for (i = firstindex; ; i++)
            {
                if (Data.CalcCodexLen(i) != thiscodexlen)
                {
                    return Point.undefined(); // return undefined
                }
                if (i > firstindex)
                {
                    mapcoderData.dataSetup(i);
                }

                int maxx = mapcoderData.MapcoderRect.getMaxX();
                int maxy = mapcoderData.MapcoderRect.getMaxY();
                int minx = mapcoderData.MapcoderRect.getMinX();
                int miny = mapcoderData.MapcoderRect.getMinY();

                int h = (maxy - miny + 89) / 90;
                int xdiv = Common.XDivider(miny, maxy);
                int w = ((maxx - minx) * 4 + xdiv - 1) / xdiv;

                h = 176 * ((h + 176 - 1) / 176);
                w = 168 * ((w + 168 - 1) / 168);

                int product = (w / 168) * (h / 176) * 961 * 31;

                int goodRounder = mapcoderData.Codex >= 23 ? 961 * 961 * 31 : 961 * 961;
                if (mapcoderData.PipeType == 8)
                {
                    // *+
                    product = ((storageStart + product + goodRounder - 1) / goodRounder) * goodRounder - storageStart;
                }

                if (value >= storageStart && value < storageStart + product)
                {
                    // code belongs here?
                    int dividerx = (maxx - minx + w - 1) / w;
                    int dividery = (maxy - miny + h - 1) / h;

                    value -= storageStart;
                    value = value / (961 * 31);
                    // PIPELETTER DECODE
                    int vx = value / (h / 176);
                    vx = vx * 168 + triple.getLonMicroDeg();
                    int vy = (value % (h / 176)) * 176 + triple.getLatMicroDeg();

                    int cornery = maxy - vy * dividery;
                    int cornerx = minx + vx * dividerx;

                    /*
                     * Sri Lanka Defect (v1.1)
                     * {
                     *   int c1 = (zonedata == 0) ? -1 : decode_chars[(int) input .charAt(input.length() - 3)];
                     *   Point zd = addzonedata(cornery + (triple.getY() - 176) dividery,
                     *     cornerx - triple.getX() * dividerx, 176 * dividery, 168 * dividerx, c1, dividerx,
                     *     dividery);
                     *   cornery = zd.getY();
                     *   cornerx = zd.getX();
                     * }
                     */

                    Point retval = add2res(cornery, cornerx, dividerx << 2, dividery, -1, extrapostfix);

                    return retval;
                }
                storageStart += product;
            }
            // unreachable
        }
示例#3
0
        // throws UnknownMapcodeException
        /*@Nonnull*/
        static Point decode(/*@Nonnull*/ string argMapcode, /*@Nonnull*/ Territory argTerritory)
        {
            Trace.TraceInformation("decode: mapcode={0}, territory={1}", argMapcode, argTerritory.ToString()); // JAVA name()

            string mapcode = argMapcode;
            Territory territory = argTerritory;

            // In case of error, result.isDefined() is false.
            Point result = Point.undefined();
            string extrapostfix = string.Empty;

            int minpos = mapcode.IndexOf('-');
            if (minpos > 0)
            {
            extrapostfix = mapcode.Substring(minpos + 1).Trim();
            if (extrapostfix.Contains("Z"))
            {
                throw new UnknownMapcodeException("Invalid character Z");
            }
            mapcode = mapcode.Substring(0, minpos);
            }

            mapcode = aeuUnpack(mapcode).Trim();
            if (string.IsNullOrEmpty(mapcode))
            {
            return result; // failed to decode!
            }

            int incodexlen = mapcode.Length - 1;

            // *** long codes in states are handled by the country
            if (incodexlen >= 9)
            {
            territory = Territory.territories[Territory.Territories.AAA];
            }
            else
            {
            Territory parentTerritory = territory.getParentTerritory();
            if (incodexlen >= 8 &&
                (parentTerritory == Territory.territories[Territory.Territories.USA] ||
                 parentTerritory == Territory.territories[Territory.Territories.CAN] ||
                 parentTerritory == Territory.territories[Territory.Territories.AUS] ||
                 parentTerritory == Territory.territories[Territory.Territories.BRA] ||
                 parentTerritory == Territory.territories[Territory.Territories.CHN] ||
                 parentTerritory == Territory.territories[Territory.Territories.RUS])
                || incodexlen >= 7 &&
                (parentTerritory == Territory.territories[Territory.Territories.IND] ||
                 parentTerritory == Territory.territories[Territory.Territories.MEX]))
            {
                territory = parentTerritory;
            }
            }

            int ccode = territory.getTerritoryCode();

            int from = DataAccess.DataFirstRecord(ccode);
            if (DataAccess.DataFlags(from) == 0)
            {
            return Point.undefined(); // this territory is not in the current data
            }
            int upto = DataAccess.DataLastRecord(ccode);

            int incodexhi = mapcode.IndexOf('.');

            Data mapcoderData = new Data();

            for (int i = from; i <= upto; i++)
            {
            mapcoderData.dataSetup(i);
            if (mapcoderData.PipeType == 0 && !mapcoderData.IsNameless
                && mapcoderData.CodexLen == incodexlen && mapcoderData.CodexHi == incodexhi)
            {
                result = decodeGrid(mapcode, mapcoderData.MapcoderRect.getMinX(), mapcoderData.MapcoderRect
                        .getMinY(), mapcoderData.MapcoderRect.getMaxX(), mapcoderData.MapcoderRect.getMaxY(),
                    i, extrapostfix);
                // RESTRICTUSELESS
                if (mapcoderData.IsUseless && result.isDefined())
                {
                    bool fitssomewhere = false;
                    int j;
                    for (j = upto - 1; j >= from; j--) { // look in previous
                        // rects
                        mapcoderData.dataSetup(j);
                        if (mapcoderData.IsUseless)
                        {
                            continue;
                        }
                        int xdiv8 = Common.XDivider(mapcoderData.MapcoderRect.getMinY(),
                            mapcoderData.MapcoderRect.getMaxY()) / 4;
                        if (mapcoderData.MapcoderRect.extendBounds(xdiv8, 60).containsPoint(result))
                        {
                            fitssomewhere = true;
                            break;
                        }
                    }
                    if (!fitssomewhere)
                    {
                        result.setUndefined();
                    }
                }
                break;
            }
            else if (mapcoderData.PipeType == 4 && mapcoderData.CodexLen + 1 == incodexlen
                && mapcoderData.CodexHi + 1 == incodexhi
                && mapcoderData.PipeLetter[0] == mapcode[0])
            {
                result = decodeGrid(mapcode.Substring(1), mapcoderData.MapcoderRect.getMinX(), mapcoderData
                    .MapcoderRect.getMinY(), mapcoderData.MapcoderRect.getMaxX(), mapcoderData
                    .MapcoderRect.getMaxY(), i, extrapostfix);
                break;
            }
            else if (mapcoderData.IsNameless && (mapcoderData.Codex == 21 && incodexlen == 4 && incodexhi == 2 ||
                mapcoderData.Codex == 22 && incodexlen == 5 && incodexhi == 3 ||
                mapcoderData.Codex == 13 && incodexlen == 5 && incodexhi == 2))
            {
                result = decodeNameless(mapcode, i, extrapostfix, mapcoderData);
                break;
            }
            else if (mapcoderData.PipeType > 4 && incodexlen == incodexhi + 3
                && mapcoderData.CodexLen + 1 == incodexlen)
            {
                result = decodeStarpipe(mapcode, i, extrapostfix, mapcoderData);
                break;
            }
            }

            if (result.isDefined())
            {
            if (result.getLonMicroDeg() > 180000000)
            {
                result = Point.fromMicroDeg(result.getLatMicroDeg(), result.getLonMicroDeg() - 360000000);
            }
            else if (result.getLonMicroDeg() < -180000000)
            {
                result = Point.fromMicroDeg(result.getLatMicroDeg(), result.getLonMicroDeg() + 360000000);
            }

            // LIMIT_TO_OUTRECT : make sure it fits the country
            if (ccode != CCODE_EARTH)
            {
                SubArea mapcoderRect = SubArea.GetArea(upto); // find
                // encompassing
                // rect
                int xdiv8 = Common.XDivider(mapcoderRect.getMinY(), mapcoderRect.getMaxY()) / 4;
                // should be /8 but there's some extra margin
                if (!mapcoderRect.extendBounds(xdiv8, 60).containsPoint(result))
                {
                    result.setUndefined(); // decodes outside the official territory
                    // limit
                }
            }
            }

            Trace.TraceInformation("decode: result=({0}, {1})",
            result.isDefined() ? result.getLatDeg() : Double.NaN,
            result.isDefined() ? result.getLonDeg() : Double.NaN);
            result = Point.restrictLatLon(result);
            return result;
        }