Open Street Map

I just wanted to share the code that I use to use Open Street Map

You can do the following

  • Add a polygon
  • Add a Line
  • Add a Marker
  • Clear the Map
  • Center the Map

If you want to try it do the following in 5 steps.

  1. Create/Open a project and create a new page.
  2. Add the following code to the razor page
<RadzenRow Gap="5" RowGap="5">
    <RadzenColumn Size="12">
       <div id="MapContainer" style="height: 80vh; width: 100%"></div>
    </RadzenColumn>
</RadzenRow>
  1. In the cs file behind add the following code
        private IJSObjectReference? _mapInstance;

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                try
                {
             // Initialize the map library
            _mapInstance = await JSRuntime.InvokeAsync<IJSObjectReference>(
                 "MapLibrary.createMap",
                 "MapContainer", // ID of the div element for the map
                 -45.3959,       // Latitude
                 167.0766,       // Longitude
                 8              // Zoom level
             );
               
                    // Add a polygon using a string of coordinates

                    var polygonData = "[[-43.927404945001463,170.55992873676473 ],[-43.926483760815039,170.5598427881674 ],[-43.925772285102681,170.55920015319464 ],[-43.923986752490364,170.55869459511013 ],[-43.923213323940217,170.55818781316458 ],[-43.923028973148718,170.55794490704284 ],[-43.922818628052724,170.5574526264476 ],[-43.922542785710718,170.55705646695429 ],[-43.9222084107467,170.55636369067372 ],[-43.921984488886132,170.55595297493059 ],[-43.921479273263806,170.55531450011631 ],[-43.921108373616228,170.55464067477533 ],[-43.920803240044542,170.55384085030352 ],[-43.920550949576196,170.5535371763705 ],[-43.920029774350034,170.55333415912753 ],[-43.885367402631886,170.50566526272931 ],[-43.889197977576238,170.49905657235018 ],[-43.889415334504733,170.49888862707505 ],[-43.898287379739223,170.493738241481 ],[-43.898640990270813,170.49335363689281 ],[-43.89981880105762,170.49244399098805 ],[-43.900376244318124,170.4921156288448 ],[-43.900891833729013,170.49197456910616 ],[-43.901634227695986,170.49195106034878 ],[-43.902262763421042,170.49186880205821 ],[-43.902509089662693,170.49176761190679 ],[-43.9028606573443,170.49128964559745 ],[-43.902874536845779,170.49072863863427 ],[-43.902555742412964,170.49052150066569 ],[-43.902507556079257,170.49033546980911 ],[-43.933829879218656,170.55777143445613 ],[-43.933628055287549,170.55780829178806 ],[-43.932864492289141,170.55789415411149 ],[-43.932624191864974,170.5581119932998 ],[-43.931974890238983,170.55857572753519 ],[-43.93126044286366,170.55893991419808 ],[-43.929827177528075,170.55941924383532 ],[-43.92937789956283,170.55946366479461 ],[-43.927404945001463,170.55992873676473 ]]";

                    await JSRuntime.InvokeVoidAsync(
                       "MapLibrary.addPolygonToMap",
                       _mapInstance,   // Pass the map instance
                       polygonData,    // Polygon coordinates
                       "blue",         // Color
                        "Lake Tekapo" // Tooltip content
                   );
                    // Add a polygon using a double[][] array

                 double[][] polygon = new[]
                                    { new[] { -45.39592497991258, 167.07659537230924 },new[] { -45.39590827650059, 167.07655099444253 },new[] { -45.395898687484596, 167.07650460337624 },new[] { -45.395899035431206, 167.0764584693997 },new[] { -45.39590669313779, 167.07641414357593 },new[] { -45.39596471720561, 167.07626090936574 },new[] { -45.39598830479537, 167.07617524704057 },new[] { -45.396028872055396, 167.07599820023916 },new[] { -45.39603917112129, 167.07597024877035 },new[] { -45.39605159070104, 167.07594848141406 },new[] { -45.3960604856393, 167.07592835760053 },new[] { -45.39606776672311, 167.07589431441912 },new[] { -45.39607088623342, 167.07586710242498 },new[] { -45.396075554465995, 167.07585253598924 },new[] { -45.3961365804678, 167.07584625010927 },new[] { -45.39615043285817, 167.0758525063268 },new[] { -45.39617857917882, 167.0758560097147 },new[] { -45.39619326388126, 167.07586089969706 },new[] { -45.396212110146514, 167.0758589584692 },new[] { -45.39624782676778, 167.07586936517205 },new[] { -45.396269119200255, 167.07587997711082 },new[] { -45.39629277831374, 167.07588394271508 },new[] { -45.39632221284404, 167.07589499652158 },new[] { -45.39636953106962, 167.07590292775276 },new[] { -45.39592497991258, 167.07659537230924 }};
                    await JSRuntime.InvokeVoidAsync(
                       "MapLibrary.addPolygonToMap",
                       _mapInstance,   // Pass the map instance
                       polygon,    // Polygon coordinates
                       "Green",       // Color
                       "Lake Browne<p><b>South Island</b>" // Tooltip content
                   );

                    // Example: Add an icon
                    await JSRuntime.InvokeVoidAsync(
                        "MapLibrary.addIconToMap",
                        _mapInstance,       // Pass the map instance
                        -45.03282,           // Latitude
                        168.65907,           // Longitude
                        "http://maps.gstatic.com/intl/de_de/mapfiles/ms/micons/red-pushpin.png",// Icon URL
                        "<b>Queenstown</b><br>New Zealand"   // Tooltip content
                    );
                    


                    // Draw a line
                    var lineData = new[]
                    {
                    new[] { -45.020024, 168.734949 },
                    new[] { -45.018128, 168.747888 },
                    new[] {-45.016475, 168.758123 }
                };

                    await JSRuntime.InvokeVoidAsync(
                        "MapLibrary.addLineToMap",
                        _mapInstance, // Pass the map instance
                        lineData,     // Line coordinates
                        "red",      // Line color
                        "Airport<p>Queenstown<p><b>South Island</b>" // Tooltip content
                    );


                    // Centre the map after 5 seconds

                    Task.Factory.StartNew(async () =>
                    {
                        await Task.Delay(5000);
                        await JSRuntime.InvokeVoidAsync(
                            "MapLibrary.centerMap",
                            _mapInstance); // Pass the map instance
                    });



                    // Clear the map after 30 seconds

                    Task.Factory.StartNew(async () =>
                    {
                        await Task.Delay(30000);
                        await JSRuntime.InvokeVoidAsync(
                            "MapLibrary.clearMap",
                            _mapInstance); // Pass the map instance
                    });





                }
                catch (Exception ex)
                {
                    
                }
            }
        }
  1. Create a directory under wwwroot called js and create a file called map.js and paste the following code into it.
(function (global) {
    class Map {
        constructor(mapId, defaultLat, defaultLng, defaultZoom) {
            this.mapId = mapId;
            this.defaultLatLng = L.latLng(defaultLat, defaultLng);
            this.defaultZoom = defaultZoom;
            this.map = null;
            this.latLngs = [];
            this.polygons = [];
            this.markers = [];
            this.lines = [];
        }

        async initMap() {
            if (!this.map) {
                this.map = L.map(this.mapId).setView(this.defaultLatLng, this.defaultZoom);

                L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
                    maxZoom: 19,
                    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
                }).addTo(this.map);
            }
        }

        addPolygon(data, content, color) {
             
            const polygon = L.polygon(eval(data)).bindTooltip(content).addTo(this.map);
            polygon.setStyle({
                color: color,
                opacity: 0.8,
                fillColor: color,
                fillOpacity: 0.35,
            });
            this.polygons.push(polygon);
            this.latLngs.push(polygon.getBounds().getCenter());
        }

        addIcon(lat, lng,iconUrl,content) {
            const icon = L.icon({
                iconUrl: iconUrl,
                //iconSize: [38, 95],
                iconAnchor: [20, 50],
            });

            const marker = L.marker([lat, lng], { icon }).bindTooltip(content).addTo(this.map);
            this.markers.push(marker);
            this.latLngs.push(marker);
        }
        addLine(latLngs, color,content) {
            const line = L.polyline(latLngs, {
                color: color,
                weight: 4,
                opacity: 0.7,
            }).bindTooltip(content).addTo(this.map);
            this.lines.push(line);
            this.latLngs.push(line.getBounds().getCenter());
        }
        clearMap() {
            this.polygons.forEach((polygon) => polygon.remove());
            this.polygons = [];
            this.markers.forEach((marker) => marker.remove());
            this.markers = [];
            this.lines.forEach((line) => line.remove());
            this.lines = [];
            this.latLngs = [];
        }

        centerMap() {
            if (this.latLngs.length > 0) {
                const bounds = L.latLngBounds(this.latLngs);
                this.map.fitBounds(bounds);
            } else {
                this.map.setView(this.defaultLatLng, this.defaultZoom);
            }
        }
    }

    function loadLeaflet() {
        return new Promise((resolve, reject) => {
            const leafletCss = document.createElement('link');
            leafletCss.rel = 'stylesheet';
            leafletCss.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
            document.head.appendChild(leafletCss);

            const leafletScript = document.createElement('script');
            leafletScript.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
            leafletScript.async = true;
            document.body.appendChild(leafletScript);

            leafletScript.onload = () => resolve();
            leafletScript.onerror = () => reject(new Error("Failed to load Leaflet.js"));
        });
    }

    global.MapLibrary = {
        async createMap(mapId, lat, lng, zoom) {
            await loadLeaflet();
            const mapInstance = new Map(mapId, lat, lng, zoom);
            await mapInstance.initMap();
            return mapInstance;
        },
        addPolygonToMap(mapInstance, data, color, content="") {
            mapInstance.addPolygon(data, content, color);
        },
        addIconToMap(mapInstance, lat, lng, iconUrl, content = "") {
            mapInstance.addIcon(lat, lng, iconUrl, content);
        }
        ,
        addLineToMap(mapInstance, latLngs, color,content = "") {
            mapInstance.addLine(latLngs, color, content);
        },
        clearMap(mapInstance) {
            mapInstance.clearMap();
        },
        centerMap(mapInstance) {
            mapInstance.centerMap();
        },
    };
})(window);

  1. Next add this to App.razor
<script src="js/map.js"></script>

That's it. You should be able to run it.
The following should happen
2 polygons 1 line and a pin should be added to the map.
The map should centre after 5 seconds and then clear after 30 seconds

5 Likes