Beispiel #1
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;
        }
Beispiel #2
0
        private static void addName(string name, Territory territory)
        {
            if (nameMap.ContainsKey(name))
            {
                List<Territory> territories = nameMap[name];

                // Add child territories in the order the parents are declared.
                // This results in consistent decoding of ambiguous territory names.
                Territory newTerritoryParent = territory.getParentTerritory();
                if ((newTerritoryParent == null) && name.CompareTo(territory.ToString()) == 0)
                {
                    // A primary identifier always takes priority.
                    territories.Clear();
                    territories.Add(territory);
                    return;
                }

                if (newTerritoryParent != null)
                {
                    for (int i = 0; i < territories.Count; i++)
                    {
                        Territory existingTerritoryParent = territories[i].getParentTerritory();
                        if (existingTerritoryParent == null && territories[i].ToString().CompareTo(name) == 0)
                        {
                            // A primary identifier always takes priority.
                            return;
                        }
                        if ((existingTerritoryParent == null) ||
                            (existingTerritoryParent.GetHashCode() > newTerritoryParent.GetHashCode()))
                        {
                            territories[i] = territory;
                            return;
                        }
                    }
                }
                territories.Add(territory);
            }
            else
            {
                List<Territory> arrayList = new List<Territory>();
                arrayList.Add(territory);
                nameMap[name] = arrayList;
            }
        }