Search code examples
javascriptjqueryleafletgeojson

Displaying jQuery Dynamic GeoJSON Content On LeafLet Map


I am looking to create a leaflet map site that:

  • Takes in parameters (a date range) and press a button
  • Performs an SQL Query
  • Builds a GeoJSON Extract of the Query Results
  • Displays the resulting markers on a leaflet map

I have the first three steps working, but am unable to add the results to an existing map (the basemap has a few kml layers and overlays using omnivore that i want available with or without the queried data).

Here is the HTML

<input id="txtStartDate" type="text" class="date-picker/>
<input id="txtEndDate" type="text" class="date-picker/>
<input type="button" id="btnMapIt" value="Map Values" class="btn"/>

<div id="map"></div>

Here is the jQuery / JavaScript

$(document).ready(function () {

    // Layer Groups
    var layerCityBoundary = new L.LayerGroup();
    var layerCityRoads = new L.LayerGroup();

    // All KML Layer Group (details not reallt important - it works!)
    loadKMLData(layerCityBoundary, 'kml/city_boundary.kml');
    loadKMLData(layerCityRoads , 'kml/city_roads.kml');

    // Map Layers
    var mbAttr = 'Map data &copy',
        mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw';

    var grayscale = L.tileLayer(mbUrl, { id: 'mapbox.light', attribution: mbAttr }),
        streets = L.tileLayer(mbUrl, { id: 'mapbox.streets', attribution: mbAttr });

    var map = L.map('map', {
            center: [45, -80],
            zoom: 12,
            layers: [streets]
        });

    var baseLayers = {
            "Streets": streets,
            "Grayscale": grayscale
        };

    var overlays = {
            "City Boundary": layerCityBoundary ,
            "City Streets": layerCityRoads 
        };

    L.control.layers(baseLayers, overlays).addTo(map);

    //******************************************************************
    // Search Button Press
    //******************************************************************
    $('#btnMapIt').click(function () {

        var startDate = $('#txtStartDate').val();
        var endDate = $('#txtEndDate').val();

        // Run Data Handler Query
        $.ajax({
            url: "queries/dhGetMapPoints.ashx",
            contentType: "application/json; charset=utf-8",
            cache: false,
            dataType: "json",
            data: { 
                dStartDate: startDate,
                dEndDate: endDate
            },
            responseType: "json",
            success: function (geojson) {

                L.geoJson(geojson, {
                    onEachFeature: function (feature, layer) {
                        layer.bindPopup(feature.properties.name);
                    }
                }).addTo(map);

            },
            error: function () {
                alert('ERROR.');
            },
        });

    });

});

However, it gives me issues saying the map has already been drawn. How can I add this (and remove any existing) layers from the existing map (but still keep the overlay layers)?


Solution

  • Here's my stab at it...I made changes with comments. I didn't test this, so it may not work first try.

    $(document).ready(function () {
    
    // Layer Groups
    var layerCityBoundary = new L.LayerGroup();
    var layerCityRoads = new L.LayerGroup();
    
    // All KML Layer Group (details not reallt important - it works!)
    loadKMLData(layerCityBoundary, 'kml/city_boundary.kml');
    loadKMLData(layerCityRoads , 'kml/city_roads.kml');
    
    // Map Layers
    var mbAttr = 'Map data &copy',
        mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw';
    
    var grayscale = L.tileLayer(mbUrl, { id: 'mapbox.light', attribution: mbAttr }),
        streets = L.tileLayer(mbUrl, { id: 'mapbox.streets', attribution: mbAttr });
    
    var map = L.map('map', {
            center: [45, -80],
            zoom: 12,
            layers: [streets]
        });
    
    var baseLayers = {
            "Streets": streets,
            "Grayscale": grayscale
        };
    
    //pre-create geoJson layer
    var geoJsonFeature;
    var existGeoJson = L.geoJson(geoJsonFeature, {
        onEachFeature: function (feature, layer) {
            layer.bindPopup(feature.properties.name);
        }
    });
    
    //include geoJson layer in overlays
    var overlays = {
            "City Boundary": layerCityBoundary ,
            "City Streets": layerCityRoads,
            "Existing GeoJSON": existGeoJson
        };
    
    L.control.layers(baseLayers, overlays).addTo(map);
    
    //******************************************************************
    // Search Button Press
    //******************************************************************
    $('#btnMapIt').click(function () {
    
        var startDate = $('#txtStartDate').val();
        var endDate = $('#txtEndDate').val();
    
        // Run Data Handler Query
        $.ajax({
            url: "queries/dhGetMapPoints.ashx",
            contentType: "application/json; charset=utf-8",
            cache: false,
            dataType: "json",
            data: { 
                dStartDate: startDate,
                dEndDate: endDate
            },
            responseType: "json",
            success: function (geojson) {
                //loop through your geoJson adding them to your existing layer.
                for (var i = 0; i < geoJson.length; i++) {
                var obj = geoJson[i];
                existGeoJson.addData(obj);
            }
    
    
            },
            error: function () {
                alert('ERROR.');
            },
        });
    
    });
    
    });