Using SfMaps component in offline PWA app

Is it possible to programatically cache SfMaps data for offline use? Specifically, I do not know what files to cache.

In some of your example I can see this code:
 <MapsLayer ShapeData='new {dataOptions ="https://cdn.syncfusion.com/maps/map-data/usa.json"}'>

Q1: Is there a complete list of all those CDN-ed shape JSON files?

Q2: In Maps_GeoJSON.zip I can see \files All Countries with States\United States of America.json, but no usa.json.

9 Replies

SA Sabari Anand Senthamarai Kannan Syncfusion Team August 3, 2020 02:28 PM UTC

Hi Pavel, 
 
Thank you for contacting Syncfusion support. 
 
We have checked your query and came to know that you are trying to use Maps shape data in offline. We cannot use cache memory for storing the shape data for offline purpose because we need to keep the application running for maintaining the cache memory. However, as workaround, we can store the shape data in a local file for offline purpose. We have created a simple Blazor application to demonstrate the same and it can be downloaded from the following link. 
 
 
In the above sample, we have rendered simple world map using the "ShapeData" property in the "MapsLayer" class. Using HttpClient we have received the JSON data of world-map from the CDN link and stored it under the “wwwroot” folder for offline usage. 
 
Please find the details for your queries from the below table. 
 
Queries 
Details 
Is there a complete list of all of those CDN-ed shape JSON files? 
We do not update the GeoJSON files in the CDN. The files available in our CDN domain are used for demo purpose only. You cannot find updated GeoJSON files in our CDN. We would suggest you to check the online map vendors to get the maps data and you can render it in our Maps component. 
In Maps_GeoJSON.zip I can see \files All Countries with States\United States of America.json, but no usa.json. 
Can you please let us where did you get the Maps_GeoJSON.zip folder? However, you can download the USA shape data from the below link. 
  
 
Please let us know if you need any further assistance. 
 
Regards, 
Sabari Anand 



PZ Pavel Zika August 4, 2020 09:18 AM UTC

In this page:
I can see this link:
https://s3.amazonaws.com/files2.syncfusion.com/dtsupport/uploads/user/uploads/Maps_GeoJSON.zip

Why PWA service worker cannot cache the geoJSON files during |PWA| installation? I cannot understant zour explanatin "we need to keep the application running for maintaining the cache memory."

Thanks a lot for info

Pavel



SA Sabari Anand Senthamarai Kannan Syncfusion Team August 5, 2020 03:55 PM UTC

Hi Pavel, 

Thank you for your update. 

Please find the details for your queries from the following table. 

Queries 
Details 
In this page: 
https://blazor.syncfusion.com/documentation/maps/populate-data/ 
I can see this link: 
https://s3.amazonaws.com/files2.syncfusion.com/dtsupport/ 
uploads/user/uploads/Maps_GeoJSON.zip 
We have added few GeoJSON files as example in our documentation. However, you need to get updated and new GeoJSON files from the maps vendors. 
Why PWA service worker cannot cache the geoJSON files during |PWA| installation? I cannot understant zour explanatin "we need to keep the application running for maintaining the cache memory." 
After further analysis, we came to know that we can store the GeoJSON data in a database or local location. You can store the map shape data in a database with a key and GeoJSON data as value or save the file in a local location in your environment for further uses. 
 

Please let us know if you need any further assistance. 

Regards, 
Sabari Anand 



DU Duncan replied to Sabari Anand Senthamarai Kannan October 27, 2022 04:56 PM UTC

Hello,

I can build and run the original MapsBlazor-429271996 project using (18.2.0.47)

However, when I update the library to (20.3.0.52) I get Errors in Visual Studio

Error (active) CS0411 The type arguments for method 'TypeInference.CreateMapsLayer_0(RenderTreeBuilder, int, int, object)' cannot be inferred from the usage. Try specifying the type arguments explicitly. c:\Users\philp\Downloads\MapsBlazor-429271996\MapsData\Pages\Index.razor 1

I can get them to go by adding a TValue="string" to the MapLayer, but I get runtime exceptions thrown on the deserialization of the .json layer

please can you update this example to (20.3.0.52) and make it available?


ultimately if you could make the following work code below work that would be helpful too.

____________________________________________________________________________________________

@if (MapData == null)

{

Loading Map Layers...

}

else

{

        <div class="control-section">

        <SfMaps>

            <MapsZoomSettings Enable="true" ZoomFactor="12" MaxZoom="20" />

            <MapsLayers>

                <MapsLayer UrlTemplate="@UrlTemplate" TValue="string"></MapsLayer>

                <MapsLayer ShapeData="@MapData" Type="Syncfusion.Blazor.Maps.Type.SubLayer" TValue="string"></MapsLayer>

                <MapsLayer ShapeData="@MapData2" Type="Syncfusion.Blazor.Maps.Type.SubLayer" TValue="string"></MapsLayer>

            </MapsLayers>

        </SfMaps>

    </div>

}

@code {


[Parameter]

public Job job { get; set; }


[Parameter]

public Customer customer { get; set; }


string MapData;

string MapData2;

public string UrlTemplate { get; set; }

public double Latitude { get; set; }

public double Longitude { get; set; }


protected override async Task OnInitializedAsync()

{

//OSM

UrlTemplate = "https://a.tile.openstreetmap.org/level/tileX/tileY.png";


using (HttpClient httpClient = new HttpClient())

{

//remote geoJson

HttpResponseMessage response = httpClient.GetAsync("https://cdn.syncfusion.com/maps/map-data/africa.json").GetAwaiter().GetResult();

MapData = await response.Content.ReadAsStringAsync();

}

// local geoJson

MapData2 = GeoHelper.GetFeatureCollection(job);

}

}

__________________________________________________________________________________________

Thanks Duncan



IR Indumathi Ravi Syncfusion Team October 28, 2022 04:46 PM UTC

Hi Duncan,


We have updated the provided code to the latest version of the Maps component. The code for receiving GeoJSON data from an online source has also been updated. Please see the code snippet below.


Code Snippet:

@if (MapShapeData == null || MapShapeData2 == null)

{

<h3> Loading Map Layers.....</h3>

}

else

{

    <div class="control-section">

        <SfMaps>

            <MapsLayers>

                <MapsLayer UrlTemplate="@UrlTemplate" TValue="string"></MapsLayer>

                <MapsLayer ShapeData="@MapShapeData" Type="Syncfusion.Blazor.Maps.Type.SubLayer" TValue="string">

                    <MapsShapeSettings Fill="lightgreen"></MapsShapeSettings>

                </MapsLayer>

                <MapsLayer ShapeData="@MapShapeData2" Type="Syncfusion.Blazor.Maps.Type.SubLayer" TValue="string">

                    <MapsShapeSettings Fill="skyblue"></MapsShapeSettings>

                </MapsLayer>

            </MapsLayers>

        </SfMaps>

    </div>

}

@code {

    object MapShapeData;

    object MapShapeData2;

    public string UrlTemplate { get; set; }

 

    protected override async Task OnInitializedAsync()

    {

          string MapData;

          string MapData2;

          // OSM

          UrlTemplate = https://a.tile.openstreetmap.org/level/tileX/tileY.png;

          using (HttpClient httpClient = new HttpClient())

          {

              // Remote GeoJSON

              HttpResponseMessage response = httpClient.GetAsync(https://cdn.syncfusion.com/maps/map-data/africa.json).GetAwaiter().GetResult();

              MapData = await response.Content.ReadAsStringAsync();

              HttpResponseMessage responseone = httpClient.GetAsync(https://cdn.syncfusion.com/maps/map-data/australia.json).GetAwaiter().GetResult();

              MapData2 = await responseone.Content.ReadAsStringAsync();

          }

          MapShapeData = JsonConvert.DeserializeObject(MapData);

          MapShapeData2 = JsonConvert.DeserializeObject(MapData2);

    }

}


We have created a sample to demonstrate the same and it can be downloaded from the below link.

https://www.syncfusion.com/downloads/support/directtrac/general/ze/MapsApp-1690483312


Please let us know if you need any further assistance.


Regards,

Indumathi R.



DU Duncan October 28, 2022 05:58 PM UTC

Hello, Thanks for the quick response...  Yes I can get your example to work.

However when its a Wasm version something errors. I have dropped your sample code into the attached zip file to illustrate.

click on the map nav...... Thanks Duncan

blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]

      Unhandled exception rendering component: Cannot wait on monitors on this runtime.

System.PlatformNotSupportedException: Cannot wait on monitors on this runtime.

   at System.Threading.Monitor.ObjWait(Int32 millisecondsTimeout, Object obj)

   at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout)

   at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)

   at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)

   at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)

   at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)

   at SyncfusionBlazorApp2.Client.Pages.MapsFeatures.OnInitializedAsync() in D:\Projects\SyncfusionBlazorApp2\Client\Pages\MapsFeatures.razor:line 44

   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

window.Module.s.printErr @ blazor.webassembly.js:1

Te._internal.dotNetCriticalError @ blazor.webassembly.js:1

Rt @ blazor.webassembly.js:1

_mono_wasm_invoke_js_blazor @ dotnet.6.0.10.rirup5mwuf.js:1

$func219 @ 00971d2a:0x1a492

$func167 @ 00971d2a:0xce60

$func166 @ 00971d2a:0xbd73

$func2815 @ 00971d2a:0xabebf

$func1619 @ 00971d2a:0x6fc80

$func1617 @ 00971d2a:0x6fbf2

$func970 @ 00971d2a:0x50643

$func219 @ 00971d2a:0x1a44b

$func167 @ 00971d2a:0xce60

$func166 @ 00971d2a:0xbd73

$func2815 @ 00971d2a:0xabebf

$func1619 @ 00971d2a:0x6fc80

$func1623 @ 00971d2a:0x702ed

$mono_wasm_invoke_method @ 00971d2a:0x969f

Module._mono_wasm_invoke_method @ dotnet.6.0.10.rirup5mwuf.js:1

managed__Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_BeginInvokeDotNet @ managed__Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_BeginInvokeDotNet:19

beginInvokeDotNetFromJS @ blazor.webassembly.js:1

b @ blazor.webassembly.js:1

e.invokeMethodAsync @ blazor.webassembly.js:1

(anonymous) @ blazor.webassembly.js:1

Ee @ blazor.webassembly.js:1

ve @ blazor.webassembly.js:1

(anonymous) @ blazor.webassembly.js:1

(anonymous) @ blazor.webassembly.js:1

onGlobalEvent @ blazor.webassembly.js:1

 


Attachment: SyncfusionBlazorApp2_422a85d4.zip


DU Duncan October 28, 2022 06:09 PM UTC

if i change to 

using (HttpClient httpClient = new HttpClient())

        {

            //remote geoJson

            HttpResponseMessage response = await httpClient.GetAsync("https://cdn.syncfusion.com/maps/map-data/africa.json");

            MapData = await response.Content.ReadAsStringAsync();

            HttpResponseMessage responseone = await httpClient.GetAsync("https://cdn.syncfusion.com/maps/map-data/australia.json");

            MapData2 = await responseone.Content.ReadAsStringAsync();

        }


no error but nothing returns and app locks 








IR Indumathi Ravi Syncfusion Team October 31, 2022 03:17 PM UTC

Hi Duncan,

  

We are currently analyzing the reported scenario in Blazor WASM application. We will update you with further details on November 1, 2022.


Regards,

Indumathi R.



IR Indumathi Ravi Syncfusion Team November 1, 2022 03:00 PM UTC

Hi Duncan,


Thank you for the update.


Maps component loads the Africa and Australia shape maps in the WASM application with the code snippet provided by us on October 28, 2022. But it takes some time to render in the application. This is due to the fact that the Maps component takes some time in processing the GeoJSON data to render in the WASM application. In the server-side application, the Maps will be rendering the shapes fast when compared with WASM application. We have already analyzed this slowness and found that the same code used for processing the GeoJSON in the server side is slow in the WASM application. This is a limitation in the Blazor WASM framework. Please see the link below for more information on our component performance analysis.

https://www.syncfusion.com/downloads/support/directtrac/general/ze/ANALYS~1-1190907599


We have also raised a query to the Blazor team. Please find the link below.

https://docs.microsoft.com/en-us/answers/questions/906847/performance-isssues-in-systemtextjson-methods.html


Once we receive an appropriate solution from the team, we will fix and improve the performance of the GeoJSON map rendering in the Maps component in the WASM application.


Please let us know if you need any further assistance.


Regards,

Indumathi R.


Loader.
Up arrow icon