Пример #1
0
        private SubArea(int i, /*@Nonnull*/ Territory territory, /*@Nullable*/ SubArea territoryBounds)
        {
            minMaxSetup(i);
            parentTerritory = territory;
            subAreaID       = i;
            boundedLonRange = new List <Range <int> >();
            boundedLatRange = new List <Range <int> >();

            // Mapcode areas are inclusive for the minimum bounds and exclusive for the maximum bounds
            // Trim max by 1, to address boundary cases.
            Range <int> trimmedLonRange = trimRange(lonRange);
            Range <int> trimmedLatRange = latRange;

            // Special handling for latitude +90.0 which should not be trimmed, in order to produce
            // mapcode AAA Z0000.010G for lat: 90.0 lon:180.0.
            if (latRange.getMax() != 90000000)
            {
                trimmedLatRange = trimRange(latRange);
            }
            List <Range <int> > normalisedLonRange = normaliseRange(trimmedLonRange, lonBoundingRange);
            List <Range <int> > normalisedLatRange = normaliseRange(trimmedLatRange, latBoundingRange);

            if (territoryBounds == null)
            {
                boundedLonRange = normalisedLonRange;
                boundedLatRange = normalisedLatRange;
            }
            else
            {
                foreach (Range <int> normalisedRange in normalisedLonRange)
                {
                    List <Range <int> > boundedRange = normalisedRange.constrain(territoryBounds.boundedLonRange);
                    if (boundedRange != null)
                    {
                        boundedLonRange.AddRange(boundedRange);
                    }
                }
                foreach (Range <int> normalisedRange in normalisedLatRange)
                {
                    List <Range <int> > boundedRange = normalisedRange.constrain(territoryBounds.boundedLatRange);
                    if (boundedRange != null)
                    {
                        boundedLatRange.AddRange(boundedRange);
                    }
                }
            }
        }
Пример #2
0
        private SubArea(int i, /*@Nonnull*/ Territory territory, /*@Nullable*/ SubArea territoryBounds)
        {
            minMaxSetup(i);
            parentTerritory = territory;
            subAreaID = i;
            boundedLonRange = new List<Range<int>>();
            boundedLatRange = new List<Range<int>>();

            // Mapcode areas are inclusive for the minimum bounds and exclusive for the maximum bounds
            // Trim max by 1, to address boundary cases.
            Range<int> trimmedLonRange = trimRange(lonRange);
            Range<int> trimmedLatRange = latRange;
            // Special handling for latitude +90.0 which should not be trimmed, in order to produce
            // mapcode AAA Z0000.010G for lat: 90.0 lon:180.0.
            if (latRange.getMax() != 90000000)
            {
                trimmedLatRange = trimRange(latRange);
            }
            List<Range<int>> normalisedLonRange = normaliseRange(trimmedLonRange, lonBoundingRange);
            List<Range<int>> normalisedLatRange = normaliseRange(trimmedLatRange, latBoundingRange);
            if (territoryBounds == null)
            {
                boundedLonRange = normalisedLonRange;
                boundedLatRange = normalisedLatRange;
            }
            else
            {
                foreach (Range<int> normalisedRange in normalisedLonRange)
                {
                    List<Range<int>> boundedRange = normalisedRange.constrain(territoryBounds.boundedLonRange);
                    if (boundedRange != null)
                    {
                        boundedLonRange.AddRange(boundedRange);
                    }
                }
                foreach (Range<int> normalisedRange in normalisedLatRange)
                {
                    List<Range<int>> boundedRange = normalisedRange.constrain(territoryBounds.boundedLatRange);
                    if (boundedRange != null)
                    {
                        boundedLatRange.AddRange(boundedRange);
                    }
                }
            }
        }
Пример #3
0
 /*@Nonnull*/
 public SubArea extendBounds(int xExtension, int yExtension)
 {
     SubArea result = new SubArea();
     result.latRange = new Range<int>(this.getMinY() - yExtension, getMaxY() + yExtension);
     result.lonRange = new Range<int>(this.getMinX() - xExtension, getMaxX() + xExtension);
     return result;
 }
Пример #4
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;
 }
Пример #5
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);
        }