arnaudleclerc / AzureMapsControl.Components

Razor Components for azure-maps-control
MIT License
34 stars 12 forks source link

Trying to bind to the DrawingComplete eventcallback resulted in this error: System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'AzureMapsControl.Components.Atlas.Feature' #68

Closed abannsunny closed 2 years ago

abannsunny commented 2 years ago

First of all thank you for creating this library made my life so much easier.

Trying to bind to the DrawingComplete eventcallback resulted in this error:

Uncaught (in promise) Error: System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'AzureMapsControl.Components.Atlas.Feature'. Path: $.dat

I have created a PR to fix this issue.

67

Please let me know if you need any more help from me before the PR can be merged. I am using this package for a critical project and would love to help resolve this issue.

Here is the template I used to produce the error:

` <AzureMap Id="map" EventActivationFlags="MapEventActivationFlags.None().Enable(MapEventType.Ready, MapEventType.SourceAdded)" CameraOptions="new CameraOptions { Center= new AzureMapsControl.Components.Atlas.Position(-85.139236, 41.093842), Zoom= 8 }" DrawingToolbarOptions="new AzureMapsControl.Components.Drawing.DrawingToolbarOptions { Buttons = new [] { AzureMapsControl.Components.Drawing.DrawingButton.DrawCircle, AzureMapsControl.Components.Drawing.DrawingButton.DrawLine }, Position = AzureMapsControl.Components.Controls.ControlPosition.TopRight, Style = AzureMapsControl.Components.Drawing.DrawingToolbarStyle.Dark, Events = AzureMapsControl.Components.Drawing.DrawingToolbarEventActivationFlags.None().Enable(AzureMapsControl.Components.Drawing.DrawingToolbarEventType.DrawingComplete) }" OnReady="MapReady" OnSourceAdded="OnDatasourceAdded" StyleOptions="StyleOptions" OnDrawingModeChanged="OnDrawingModeChanged" OnDrawingComplete="OnDrawingComplete" />

@code { public Map Map { get; set; } public string DataUrl { get; set; } = "data/US_County_Boundaries.json"; string sourceId = "countydata"; public StyleOptions StyleOptions = new StyleOptions { Style = MapStyle.GrayscaleDark, ShowLogo = false, ShowFeedbackLink = false }; public async Task MapReady(MapEventArgs eventArgs) {

    var dataSource= new AzureMapsControl.Components.Data.DataSource(sourceId);
    await eventArgs.Map.AddSourceAsync(dataSource);
    await dataSource.ImportDataFromUrlAsync(DataUrl);
}

public async Task OnDrawingModeChanged(AzureMapsControl.Components.Drawing.DrawingToolbarModeEventArgs eventArgs)
{

    Console.WriteLine(eventArgs.NewMode);
}

public async Task OnDrawingComplete(AzureMapsControl.Components.Drawing.DrawingToolbarEventArgs eventArgs)
{

    Console.WriteLine(eventArgs.Data);
}

public async Task OnDatasourceAdded(MapSourceEventArgs sourceEventArgs)
{
    var polygonExpression = @"[""any"", [""=="", [""geometry-type""], ""Polygon""], [""=="", [""geometry-type""], ""MultiPolygon""]]";
    JsonDocument polygonDoc;
    polygonDoc = JsonDocument.Parse(polygonExpression);
    var LineExpression = @"[""any"", [""=="", [""geometry-type""], ""LineString""], [""=="", [""geometry-type""], ""MultiLineString""]]";
    var LinenDoc = JsonDocument.Parse(LineExpression);

    var bubbleExpression = @"[""any"", [""=="", [""geometry-type""], ""Polygon""], [""=="", [""geometry-type""], ""MultiPolygon""]]";
    var bubbleDoc = JsonDocument.Parse(bubbleExpression);

    var polygon = new AzureMapsControl.Components.Layers.PolygonLayer()
        {
            EventActivationFlags = AzureMapsControl.Components.Layers.LayerEventActivationFlags.None().Enable(AzureMapsControl.Components.Layers.LayerEventType.Click),
            Options = new AzureMapsControl.Components.Layers.PolygonLayerOptions()
            {
                Source = sourceId,
                Filter = new AzureMapsControl.Components.Atlas.Expression(polygonDoc),
                FillColor = new AzureMapsControl.Components.Atlas.ExpressionOrString("red")

            }
        };

    polygon.OnClick += async eventClickArgs =>
    {
        var firstShape = eventClickArgs.Shapes?.FirstOrDefault();

        var layer = eventClickArgs.Map.Layers.FirstOrDefault(l => l.Id == firstShape.Id);

        if (firstShape != null)
        {
            var bla = firstShape.Properties["NAME"]?.ToString();
            AzureMapsControl.Components.Atlas.Position cordinates = new AzureMapsControl.Components.Atlas.Position(0, 0);
            if (firstShape.Geometry is AzureMapsControl.Components.Atlas.Polygon polygon)
            {
                cordinates = polygon.Coordinates?.FirstOrDefault()?.FirstOrDefault();
                foreach (var positions in polygon.Coordinates)
                {
                    foreach (var position in positions)
                    {
                        Console.WriteLine(position.Longitude);
                        Console.WriteLine(position.Latitude);
                    }
                }
            }

            var template = new AzureMapsControl.Components.Popups.PopupTemplate
                {
                    Title = "County Data",
                    Content = new AzureMapsControl.Components.Atlas.Either<string, IEnumerable<AzureMapsControl.Components.Atlas.PropertyInfo>, IEnumerable<AzureMapsControl.Components.Atlas.Either<string, IEnumerable<AzureMapsControl.Components.Atlas.PropertyInfo>>>>
                                ("County Name = {value1}<br/><br/>"),
                    NumberFormat = new AzureMapsControl.Components.Atlas.FormatOptions.NumberFormatOptions
                    {
                        MaximumFractionDigits = 2
                    }
                };

            var properties = new Dictionary<string, object>
                           {
                        { "value1", bla}
                           };

            var popup = new AzureMapsControl.Components.Popups.Popup(new AzureMapsControl.Components.Popups.PopupOptions
                {
                    CloseButton = true,
                    Position = cordinates,
                    OpenOnAdd = true
                });

            await eventClickArgs.Map.AddPopupAsync(popup, template, properties);
            await popup.OpenAsync();
        }

        var firstFeature = eventClickArgs.Features?.FirstOrDefault();
        if (firstFeature != null)
        {
            if (firstFeature.Geometry is AzureMapsControl.Components.Atlas.Polygon polygon)
            {
                foreach (var positions in polygon.Coordinates)
                {
                    foreach (var position in positions)
                    {
                        Console.WriteLine(position.Longitude);
                        Console.WriteLine(position.Latitude);
                    }
                }
            }
        }

    };

    sourceEventArgs.Map.AddLayerAsync(polygon);
}

}

`

arnaudleclerc commented 2 years ago

The PR is through, thank you for that!

A version 1.12.0-alpha0011 has been generated with your changes. Do you mind verifying if this version fixes your issue before I generate a stable version ?

abannsunny commented 2 years ago

Just tested. Works Great! Thank you for taking the time to approve the PR!

ondrawing complete

abannsunny commented 2 years ago

I do want to point out that the "drawingcomplete" event behaves differently depending on the polygon that is drawn. If a circle is drawn then the object returned has an extra "circlePolygon" field and the data has a point polygon.

image

Other polygons do not have that extra parameter:

image

This could be a future task to parse that circlePolygon field or not depending on how important that field is.

abannsunny commented 2 years ago

I also wanted to add. I appreciate you creating this package. working on the PR I absolutely loved the way you set up the project with typrscript and rollup build. I was able to use this architecture in my project as well, I have been trying to figure out how to combine blazor and typescript. Thank you!

arnaudleclerc commented 2 years ago

Thanks for the nice words, I appreciate it :)

I published a v1.12.0 with your changes a couple of days ago. I will close this issue, but feel free to reopen it if there is any further problem.