예제 #1
0
 public void dataSetup(int i)
 {
     flags        = DataAccess.DataFlags(i);
     codexHi      = CalcCodexHi(flags);
     codexLo      = CalcCodexLo(flags);
     codexLen     = CalcCodexLen(codexHi, codexLo);
     codex        = CalcCodex(codexHi, codexLo);
     nameless     = GetIsNameless(i);
     useless      = (flags & 512) != 0;
     specialShape = GetIsSpecialShape(i);
     pipeType     = (flags >> 5) & 12; // 4=pipe 8=plus 12=star
     if (pipeType == 4)
     {
         pipeLetter = (ENCODE_CHARS[(flags >> 11) & 31]).ToString();
     }
     else
     {
         pipeLetter = string.Empty;
     }
     if ((codex == 21) && !nameless)
     {
         codex++;
         codexLo++;
         codexLen++;
     }
     starPipe     = CalcStarPipe(i);
     mapcoderRect = SubArea.GetArea(i);
     initialized  = true;
 }
예제 #2
0
        /*@Nonnull*/
        static Point decode(/*@Nonnull*/ string argMapcode, /*@Nonnull*/ Territory argTerritory)
        // throws UnknownMapcodeException
        {
            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);
        }