mapbox-unity-sdk icon indicating copy to clipboard operation
mapbox-unity-sdk copied to clipboard

Bug in LatLong conversion (Conversions.cs) on German language machines

Open Liquid-Bergmann opened this issue 4 years ago • 5 comments

Unity version: 2019.3.13 Scripting Runtime: .Net 4 Scripting Backend: IL2CPP/Mono API Compability: .Net 4.x/.Net 2 MapBox SDK: 2.11 Platform Windows/Android

When entering a new latLong string in the inspector or changing the zoom factor, the periods in the lat/long values get changed to commas. This happens due to me being on a german system. Due to this, I get the ArgumentException "Wrong number of arguments" from the Conversions.cs.

I create a work around for this, but maybe there should be some cleaner handling in the UI code (System.CultureInfo.InvariantCulture might be a place to look at). Anyhow my dirty work around looks like this:

/// <summary>
/// Convert a simple string to a latitude longitude.
/// Expects format: latitude, longitude
/// </summary>
/// <returns>The lat/lon as Vector2d.</returns>
/// <param name="s">string.</param>
public static Vector2d StringToLatLon(string s)
{
        // get a local work copy of the supplied string
	string replacedString = s;
	// get the amount of commas in the string, if more than one are found, replace the first and last in the string with a period before further handling
	int commaCount = System.Text.RegularExpressions.Regex.Matches(s, ",", System.Text.RegularExpressions.RegexOptions.IgnoreCase).Count;
	if(commaCount > 1){
		// create a char array and check from the beginning for the first comma, replace it with a period
		char[] charArrLatLon = replacedString.ToCharArray();				
		for(int i = 0; i < charArrLatLon.Length; i++){
			if(charArrLatLon[i] == ','){
				replacedString = replacedString.Substring(0, i) + "." + replacedString.Substring(i + 1);
				break;
			}
		}
		// check from the end for the last comma and replace it with a period
		charArrLatLon = replacedString.ToCharArray();
		for(int i = charArrLatLon.Length - 1; i > 0; i--){
			if(charArrLatLon[i] == ','){
				replacedString = replacedString.Substring(0, i) + "." + replacedString.Substring(i + 1);
				break;
			}
		}
	}
	var latLonSplit = replacedString.Split(',');
	if (latLonSplit.Length != 2)
	{
		throw new ArgumentException("Wrong number of arguments");
	}
	double latitude = 0;
	double longitude = 0;

	if (!double.TryParse(latLonSplit[0], NumberStyles.Any, NumberFormatInfo.InvariantInfo, out latitude))
	{
		throw new Exception(string.Format("Could not convert latitude to double: {0}", latLonSplit[0]));
	}

	if (!double.TryParse(latLonSplit[1], NumberStyles.Any, NumberFormatInfo.InvariantInfo, out longitude))
	{
	throw new Exception(string.Format("Could not convert longitude to double: {0}", latLonSplit[0]));
	}
	return new Vector2d(latitude, longitude);
}

Best regards, Leo Bergmann

Liquid-Bergmann avatar Aug 12 '20 16:08 Liquid-Bergmann

I ran into the same problem. Will check out your approach and thanks in advance!

Markovicho avatar Aug 20 '20 09:08 Markovicho

@Liquid-Bergmann Indeed a good solution would be using culture information but I think I don't understand how this exactly happens. You copy paste a lat lng formatted like this 37.7648, -122.463 , then it changes text automatically to German format or something? The file you changed operates on a string so I think the fix should be applied somewhere before that part altogether.

brnkhy avatar Aug 20 '20 20:08 brnkhy

@brnkhy Yes, you got it right. It happens after entering a lat/long string in the inspector window. It also happens, when you search for a location and let it enter the location itself. I think the culture info change should be made in the corresponding editor script, but I didn't have the time to check this out and needed a quick fix, so I came up with this ^^ solution.

Liquid-Bergmann avatar Aug 23 '20 09:08 Liquid-Bergmann

Simplest way for lat and lon variables: Convert.ToDouble(lat.ToString().Replace(',', '.')); Convert.ToDouble(lon.ToString().Replace(',', '.'));

panzmicier avatar Apr 12 '22 15:04 panzmicier

Alternatively, one can do this.

if (latLonSplit.Length == 4)
{
     /* l11n fix for Czech and other weird locales -Tomas */
     latLonSplit = new string[] {
          $"{latLonSplit[0]}.{latLonSplit[1]}",
          $"{latLonSplit[2]}.{latLonSplit[3]}"
     };
}

tomires avatar Nov 29 '22 14:11 tomires