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); } } } }
private SubArea() { parentTerritory = null; subAreaID = 0; // JAVA null }
// 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; }
private ParentTerritory(Territory territory) { this.territory = territory; }
private static void addNameWithSeperatorVariants(string name, Territory territory) { addName(name, territory); // Tolerate a space character in place of a hyphen. // (e.g. "US CA" in addition to "US-CA") if (name.Contains("-")) { addName(name.Replace('-', ' '), territory); } }
/** * Private helper method to add names for a territory. * * @param name Name to add. * @param territory Territory. */ private static void addNameWithParentVariants(string name, Territory territory) { // Add the name as provided addNameWithSeperatorVariants(name, territory); if (name.Contains("-")) { string childTerritoryName = name.Substring(name.IndexOf('-') + 1); // Tolerate a child territory specified without the parent. // (e.g. "CA" rather than "US-CA") addName(childTerritoryName, territory); if (territory.ParentTerritory != null) { // Add the variant using the primary parent name. string nameVariant = (territory.ParentTerritory.ToString() + '-') + childTerritoryName; if (nameVariant.CompareTo(name) != 0) { addNameWithSeperatorVariants(nameVariant, territory); } // Add each variant using the parent alias names. foreach (string alias in territory.ParentTerritory.aliases) { nameVariant = alias + '-' + childTerritoryName; if (nameVariant.CompareTo(name) != 0) { addNameWithSeperatorVariants(nameVariant, territory); } } } } }
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; } }