See Demo Scene 101
Starting V1.2 you can extend countries, provinces and cities metadata with your own set of attribures (same as Mount Points). We call this feature “Custom Attributes”.
Custom Attributes are stored in separated files in the same Geodata folder which contains countries, provicnes and cities borders data. The default file names are “countryAttrib”, “provincesAttrib” and “citiesAttrib”.
Assigning and retrieving your own attributes
Demo scene #101 covers all uses cases regarding Custom Attributes. For example, to add a few attributes to a country, like Canada you would do:
Country canada = map.GetCountry("Canada");
// Add language as a custom attribute
canada.attrib["Language"] = "French";
// Add the date of British North America Act, 1867
canada.attrib["ConstitutionDate"] = new DateTime(1867, 7, 1);
// Add the land area in km2
canada.attrib["AreaKm2"] = 9984670;
As you can see, a new property called “attrib” has been added to each country (same for provinces and cities). The attrib property is in fact a JSONObject capable or parsing and printing jSON-compliant data. It supports basic types like numbers and string, also dates and booleans, arrays and other JSON objects.
The attrib property is indexed so you can access the top-level fields of the JSONObject by its name or index number. To retrieve the values of the custom attributes added above, you’d do:
string language = canada.attrib["Language"]);
DateTime constitutionDate = canada.attrib["ConstitutionDate"].d; // Note the use of .d to force cast the internal number representation to DateTime
float countryArea = canada.attrib["AreaKm2"]);
Filtering by Custom Attributes
You can also launch a filtered seach of countries that match a predicate using Custom Attributes:
List<Country> countries = map.GetCountries( (attrib) => "French".Equals(attrib["Language"]) && attrib["AreaKm2"] > 1000000 );
Int matchesFound = countries.Count);
The expression in bold is the predicate, expressed in lambda syntax. The GetCountries method as been overloaded so when you pass a lambda expression as above, it will iterate through all countries and pass its attrib JSONObject to your code, so you can interrogate it and return true if it matches your condition or not.
In the example above, the lambda expression tests if the attributes passed contains a field Language which equals to “French” and also checks if the attribute “AreaKm2” is greater than 1000000.
Please note that you should check if the attributes list contains the field otherwise it will produce null exceptions in your predicate.
Importing / Exporting to JSON
The attrib object can parse a JSON-formatted string:
canada.attrib = new JSONObject(json); // Import from raw jSON string
int keyCount = canada.attrib.keys.Count; // Get the number of fields
And you can export current attributes of one country back to a JSON-formatted string:
string json = canada.attrib.Print();
To get the JSON-formatted string including all countries, you can call:
string jsonCountries = map.GetCountriesAttributes (true); // the true parameter will make the JSON string “pretty” (ie. adds tabs and end-of-line characters).
To get the JSON-formatted string including all countries, you can call:
string jsonCountries = map.GetCountriesAttributes (true); // the true parameter will make the JSON string “pretty” (ie. adds tabs and end-of-line characters).
To read all countries attributes from a custom string variable, call SetCountriesAttributes:
map.SetCountriesAttributes(jsonCountries);
The above method is called when you set the countryAttributeFile property.
Managing Custom Attributes
Custom Attributes added or modified will be lost if not persisted to file.
Using the Map Editor, you can manage custom attributes to countries, provinces, cities and mount points and save them to the Geodata folder (click “Save” button in the Map after making any change). Beware that running your application without Saving changes will result in losing your changes!
If you want to make changes to attributes and save them, you can get the JSON-formatted string as seen above for all attributes of all countries, provinces and ciites, and store it in your own database, file system, as user prefs, …
You can also have different custom attributes files. To reload the attributes file, just set the property countryAttributesFile (or provinceAttributesFile, cityAttributesFile) to a different name. The asset will try to find and load the data in the new file. This file needs to be located inside Geodata folder.