1

I want to display maps in Leaflet that are only visible on the bounding box. The code works fine without the bounding box but the maps are too many so displaying the maps is very slow. Here is my implementation of the solution that is not working.

var owsrootUrl = 'https://localhost.com/geoserver/somemap/ows';

var defaultParameters = {
    service: 'WFS',
    version: '2.0',
    request: 'GetFeature',
    typeName: 'Shambamap:Kenya',
    outputFormat: 'text/javascript',
    format_options: 'callback:getJson',
    SrsName: 'EPSG:4326',
    maxFeatures: 3000
};

var customParams = {
    bbox: map.getBounds().toBBoxString(),
};

var parameters = L.Util.extend(defaultParameters, customParams);
var URL = owsrootUrl + L.Util.getParamString(parameters);

var WFSLayer = null;
var ajax = $.ajax({
    url: URL,
    dataType: 'jsonp',
    jsonpCallback: 'getJson',
    success: function (response) {
        WFSLayer = L.geoJson(response, {
            style: function (feature) {
                return {
                    stroke: true,
                    fillColor: 'FF0000',
                    fillOpacity: 0.2,
                    opacity: 0.5
                };
            },
            onEachFeature: function (feature, layer) {
                if (feature.properties) {
                    var content = "<table class='table table-striped table-bordered table-condensed'>" +
                                    "<tr><th>Plot No</th><td>" + feature.properties.plotno_1.toString() + "</td></tr>" +
                                    "<tr><th>FR Src</th><td>" + feature.properties.frsrcname + "</td></tr>" +
                                    "<tr><th>Locality</th><td>" + feature.properties.locality + "</td></tr>" +
                                    "<tr><td><a href= 'MoreDetails.html' target='_blank'>Details</a></td></tr>" +
                                    "<table>";
                    popupOptions = { maxWidth: 500 };
                    layer.bindPopup(content, popupOptions);
                }
            }
        }).addTo(map);
    }
});
  • Not working in what way? Any errors in the browser debugger console or network section? No results? Wrong results? – TomazicM Dec 30 '20 at 9:10
0

Apply fitBounds() after creating map. You have two options:

  1. Fit map to specific bounding box
  2. Fit map to extent of a geojson layer

var boundingBox = [...]
var vectorLayer = L.geoJSON(feactures, { ... });

var map = L.map('map', {
    center: [lat, long],
    zoom: zoomLevel,
    layers: [...]
});

//Map is ready => fit to specific BBX
map.on('load', () => {
    map.fitBounds(boundingBox);
});

//Map is ready => fit to a geojson layer
map.on('load', () => {
    map.fitBounds(vectorLayer.getBounds());
});
  • Should the vectorLayer be a layer from the map? – james Dec 30 '20 at 14:33
  • Not necessarily @james. You are able to fit the map to the vectorLayer's extent even though you've not added it to the map. – ArashMad Dec 30 '20 at 14:37
  • I have one more question. Is the "fitBounds" the area of the screen or the area of the entire map. I only want the bounds for the map as displayed on the screen without covering the entire map. Thanks in advance. – james Dec 30 '20 at 14:44
  • fitBound() automatically does zoom and/or pan on map until the view it covers the BBX regardless what size the screen has. This is exactly what you need. – ArashMad Dec 30 '20 at 14:47
  • Hi @ArashMad. Is it possible I send you the code. It is opensource to a level and it is developed in Visual Studio 2019. The data and the code is all open source to a level but it is OK I share it as I own the rights. Send me an email to info@shambamap.com and I can send you the code – james Dec 30 '20 at 15:10
0

I managed to solve a part of the problem. The ajax solution is a little dirty but I managed to load only the maps that are viewable (in the bounds). The map however reloads the same section over and over again as I pan across the map. I will try and find a solution for that later. Here is the script for anyone who is out there working on a similar problem. The memory costs are still high so I have to figure out a workaround for the ajax calls


<script>
            var map = L.map('map', {
                center: [-1.3328338, 36.8831222], // Nairobi, Kenya
                zoom: 15
            });

            //map.on('load', () => {
            //    map.fitBounds(vectorLayer.getBounds());
            //});



            

            var defaultBase = L.tileLayer.provider('Stamen.TonerLite').addTo(map);

            var baseLayers = {
                'Stamen Toner': defaultBase,
                'ESRI Imagery': L.tileLayer.provider('Esri.WorldImagery'),
                'ESRI Ocean Basemap': L.tileLayer.provider('Esri.OceanBasemap'),
                'OSM Topo': L.tileLayer.provider('OpenTopoMap')
            };

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

            var customParams;

            //setting properties first then add layers
            var options = {
                transparent: 'false',
                format: 'image/png',
                opacity: 0.4,
                tiled: 'true',
                info_format: 'text/html'
            };

            var owsrootUrl = 'https://shambamap.com/geoserver/Shambamap/ows';

            var defaultParameters = {
                service: 'WFS',
                version: '2.0',
                request: 'GetFeature',
                typeName: 'Shambamap:Kenya',
                outputFormat: 'text/javascript',
                format_options: 'callback:getJson',
                SrsName: 'EPSG:4326',
                maxFeatures: 3000

            };

                            
           

            map.on('moveend', function () {
                                
                var widthEast = map.getBounds().getEast()
                var widthWest = map.getBounds().getWest();
                var heightEast = map.getBounds().getNorth()
                var heightWest = map.getBounds().getSouth();

                customParams = {
                    bbox: heightWest + "," + widthWest + "," + heightEast + "," + widthEast
                };

                //alert(map.getBounds().toBBoxString());

                //alert(customParams);

                //alert(customParams.toString());
                var parameters = L.Util.extend(defaultParameters, customParams);
                var URL = owsrootUrl + L.Util.getParamString(parameters);

                var WFSLayer = null;
                var ajax = $.ajax({
                    url: URL,
                    dataType: 'jsonp',
                    jsonpCallback: 'getJson',
                    success: function (response) {
                        WFSLayer = L.geoJson(response, {
                            style: function (feature) {
                                return {
                                    stroke: true,
                                    fillColor: 'FF0000',
                                    fillOpacity: 0.2,
                                    opacity: 0.5
                                };
                            },

                            onEachFeature: function (feature, layer) {
                                if (feature.properties) {
                                    var content = "<table class='table table-striped table-bordered table-condensed'>" +
                                        "<tr><th>Plot No</th><td>" + feature.properties.plotno_1.toString() + "</td></tr>" +
                                        "<tr><th>FR Src</th><td>" + feature.properties.frsrcname + "</td></tr>" +
                                        "<tr><th>Locality</th><td>" + feature.properties.locality + "</td></tr>" +
                                        "<tr><td><a href= 'MoreDetails.html' target='_blank'>Details</a></td></tr>" +
                                        "<table>";
                                    popupOptions = { maxWidth: 500 };
                                    layer.bindPopup(content, popupOptions);

                                }


                            }

                        }).addTo(map);
                    }
                });
            });

            

            //map.on('moveend', function () {
            //    customParams = { bbox: map.getBounds().toBBoxString(), }

            //});

            //map.on('load', () => {
            //    map.fitBounds(customParams);
            //});


                



            function LoadInitialParcels() {

                var widthEast = map.getBounds().getEast()
                var widthWest = map.getBounds().getWest();
                var heightEast = map.getBounds().getNorth()
                var heightWest = map.getBounds().getSouth();

                

                customParams = {
                    bbox: heightWest + "," + widthWest + "," + heightEast + "," + widthEast 
                };
                var parameters = L.Util.extend(defaultParameters, customParams);
                var URL = owsrootUrl + L.Util.getParamString(parameters);

            var WFSLayer = null;
            var ajax = $.ajax({
                url: URL,
                dataType: 'jsonp',
                jsonpCallback: 'getJson',
                success: function (response) {
                    WFSLayer = L.geoJson(response, {
                        style: function (feature) {
                            return {
                                stroke: true,
                                fillColor: 'FF0000',
                                fillOpacity: 0.2,
                                opacity: 0.5
                            };
                        },

                        onEachFeature: function (feature, layer) {
                            if (feature.properties) {
                                var content = "<table class='table table-striped table-bordered table-condensed'>" +
                                    "<tr><th>Plot No</th><td>" + feature.properties.plotno_1.toString() + "</td></tr>" +
                                    "<tr><th>FR Src</th><td>" + feature.properties.frsrcname + "</td></tr>" +
                                    "<tr><th>Locality</th><td>" + feature.properties.locality + "</td></tr>" +
                                    "<tr><td><a href= 'MoreDetails.html' target='_blank'>Details</a></td></tr>" +
                                    "<table>";
                                popupOptions = { maxWidth: 500 };
                                layer.bindPopup(content, popupOptions);

                            }


                        }
                      
                    }).addTo(map);
                }
            });

            }


            //var map = L.map("map").setView([38.45, 70.6], 6);
            //var osm = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
            //    attribution:
            //        '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            //}).addTo(map);
            ////Geoserver Web Feature Service
            //$.ajax('https://shambamap.com/geoserver/Shambamap/ows', {
            //    type: 'GET',
            //    data: {
            //        service: 'WFS',
            //        version: '2.0',
            //        request: 'GetFeature',
            //        typename: 'Shambamap:Kenya',                    
            //        srsname: 'EPSG:4326',
            //        outputFormat: 'text/javascript',
            //    },
            //    dataType: 'jsonp',
            //    jsonpCallback: 'callback:handleJson',
            //    jsonp: 'format_options'
            //});
            ////Geojson style file
            //var myStyle = {
            //    'color': 'red'
            //}
            //// the ajax callback function
            //function handleJson(data) {
            //    selectedArea = L.geoJson(data, {
            //        style: myStyle,
            //        onEachFeature: function (feature, layer) {
            //            layer.bindPopup(`Plot No: ${feature.properties.plotno_1}`)
            //        }
            //    }).addTo(map);
            //    map.fitBounds(selectedArea.getBounds());
            //}

            



            //Load OSM Buildings then disable it on first load; can only be viewed at certain scales
            var osmb = new OSMBuildings(map).load();

            //Overlay grouped layers
            var groupOverLays = {

                "OSM Bldg Classic": {
                    "2.5D Buildings": osmb
                }
            };

            //add layer switch control
            L.control.groupedLayers(baseLayers, groupOverLays).addTo(map);




            //add scale bar to map
            L.control.scale({
                position: 'bottomleft'
            }).addTo(map);

            // Overview mini map
            var Esri_WorldTopoMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
                attribution: '&copy; Esri &mdash; Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
            });

            var miniMap = new L.Control.MiniMap(Esri_WorldTopoMap, {
                toggleDisplay: true,
                minimized: false,
                position: 'bottomleft'
            }).addTo(map);

            //define Drawing toolbar options
            var options = {
                position: 'topleft', // toolbar position, options are 'topleft', 'topright', 'bottomleft', 'bottomright'
                drawMarker: true, // adds button to draw markers
                drawPolyline: true, // adds button to draw a polyline
                drawRectangle: true, // adds button to draw a rectangle
                drawPolygon: true, // adds button to draw a polygon
                drawCircle: true, // adds button to draw a cricle
                cutPolygon: true, // adds button to cut a hole in a polygon
                editMode: true, // adds button to toggle edit mode for all layers
                removalMode: true, // adds a button to remove layers
            };

            // add leaflet.pm controls to the map
            map.pm.addControls(options);

            window.onload = function () {
                LoadInitialParcels();
            };
            
        </script>


Not the answer you're looking for? Browse other questions tagged or ask your own question.