0

I’m writing a little app which will receive a country code (2 ISO letters) and a state code (also 2 letters ISO code).

I would like to highlight (And color) the region specified by these 2 information (So let’s say “CA, QC”, will highlight Quebec state in Canada)

I don’t need Anything else (Well, maybe FadeIn, FadeOut animation, but I’ll figure this one out later)

All zoom/tap/click/other actions are blocked.

The MapControl declaration is really easy :

<maps:MapControl Grid.Row="1" x:Name="myMap" ZoomLevel="0"/>

Thanks in advance

Edit: After a lot of research, the help from following answer, I’m astonished that a BASIC action is NOT a part of Microsoft’s platform. That’s insane. All back end was coded in less than 30 minutes (Including authentication, listing properties, checking access level, setting up SignalR callbacks), but on the visual side, welp, we have NOTHING from UWP platform. That’s just sad. /bye UWP, I’ve tried. multiple times.

Edit 2 : Made it work with some adjustements :

 if (feature != null && (feature.Geometry.Type == GeoJSONObjectType.Polygon) || (feature.Geometry.Type == GeoJSONObjectType.MultiPolygon))
                {
                    myMap.MapElements.Clear();
                    MapPolygon polygon = null;
                    if (feature.Geometry.Type == GeoJSONObjectType.Polygon)
                    {
                        var polygonGeometry = feature.Geometry as Polygon;
                        polygon = new MapPolygon
                        {
                            Path = new Geopath(polygonGeometry.Coordinates[0].Coordinates.Select(coord => new BasicGeoposition() { Latitude = coord.Latitude, Longitude = coord.Longitude })),
                            FillColor = Colors.DarkRed
                        };
                        myMap.MapElements.Add(polygon);
                    }
                    else
                    {
                        var ploy = (feature.Geometry as MultiPolygon);
                        foreach (var item in ploy.Coordinates)
                        {
                            var polygon1 = new MapPolygon
                            {
                                Path = new Geopath(item.Coordinates[0].Coordinates.Select(coord => new BasicGeoposition() { Latitude = coord.Latitude, Longitude = coord.Longitude })),
                                FillColor = Colors.DarkRed
                            };
                            myMap.MapElements.Add(polygon1);
                        }
                    }


                }
Jurion
  • 1,230
  • 11
  • 18

1 Answers1

2

There is no built-in way to achieve this, so you will have to do some additional steps to make this work.

First you need to download a geojson-based dataset with polygonial definitions of all countries. One lightweight and functional can be found here on GitHub.

Now you need to install the GeoJSON.NET package from NuGet into your project and include the downloaded .geojson file in your project, for example in the Assets folder. Make sure that its Build action is set to Content.

Now you can use code like this to highlight a country by creating a MapPolygon and placing it on the map:

private FeatureCollection _countryPolygons = null;

private async void HighlightClick(string country)
{
    if (_countryPolygons == null)
    {
        _countryPolygons = JsonConvert.DeserializeObject<FeatureCollection>(
            await FileIO.ReadTextAsync(
                await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/countries.geojson",
                    UriKind.Absolute))));
    }

    var feature = _countryPolygons.Features.FirstOrDefault(f =>
        f.Id.Equals(country, StringComparison.CurrentCultureIgnoreCase));

    if (feature != null && feature.Geometry.Type == GeoJSONObjectType.Polygon)
    {
        var polygonGeometry = feature.Geometry as Polygon;
        MapPolygon polygon = new MapPolygon();
        polygon.Path = new Geopath(polygonGeometry.Coordinates[0].Coordinates.Select(coord => new BasicGeoposition() { Latitude = coord.Latitude, Longitude = coord.Longitude }));
        polygon.FillColor = Colors.DeepSkyBlue;
        Map.MapElements.Clear();
        Map.MapElements.Add(polygon);
    }
}
Martin Zikmund
  • 38,440
  • 7
  • 70
  • 91
  • Thank you for the answer. I will try it. But wow, I thought in 2018 highlight a country on a map is a basic functionality. Apparently not. Well, I’ll implement this, and I think it will be my last app ever in UWP. – Jurion Mar 20 '18 at 00:43
  • I am sorry, but I don't think there is any Such API on iOS or Android built in either. – Martin Zikmund Mar 20 '18 at 00:45
  • No problems! At this point I’m pondering the solution of WebView with Google analytics and sending an event with country code/state. (Edit : and some custon css to hide everything except the map) – Jurion Mar 20 '18 at 00:52
  • Solution works ! You have a small typo for file names : it's .geo.json instead of .geojson but everything else works. Thank you again – Jurion Mar 20 '18 at 01:02
  • Glad it helped :-). Happy coding! – Martin Zikmund Mar 20 '18 at 01:03
  • Ty, I'll use this list : https://stackoverflow.com/questions/4884692/converting-country-codes-in-net to get from my 2 letters code to 3 required by .geo.json files – Jurion Mar 20 '18 at 01:06
  • After some more tests, it just doesn’t work. Most of the countries I’ve tested are in “MultiPolygon” state. Welp, I guess I’ll just write a normal WPF with normal map (Like literally .png of world map) with normal identification and stop trying Win10 apps. – Jurion Mar 20 '18 at 01:57
  • Well, in such case you could do a foreach over the multiple polygons and add them all to the MapElements collection. In any case - if you have a working solution in WPF, why couldn't the same thing be used in UWP? – Martin Zikmund Mar 20 '18 at 02:13
  • Thre is no foreach for MultiPolygon. var ploy = (feature.Geometry as MultiPolygon); foreach (var item in ploy) doesn't compile – Jurion Mar 20 '18 at 02:16
  • foreach (var item in ploy.Coordinates) { var polygon1 = new MapPolygon { Path = new Geopath(item.Coordinates[0].Coordinates.Select(coord => new BasicGeoposition() { Latitude = coord.Latitude, Longitude = coord.Longitude })), FillColor = Colors.DeepSkyBlue }; myMap.MapElements.Add(polygon1); } does compile, trying now – Jurion Mar 20 '18 at 02:18