Skip to content Skip to sidebar Skip to footer

Zoom After Search Using Autocomplete

How to do after a search, zoom in on the value found on the map? My code is: $('#txtSearch').autocomplete({ source: setoresComerciais.features.map(function(d){ return d

Solution 1:

This line:

map.fitBounds(stComerciaisLayer.getBounds(ui.item.value));

won't work as intended. From the API documentation, getBounds() doesn't take any arguments, it just returns the bounds of they layer you are working with. As the layer includes all your geojson, this won't work.

Instead, we can get the selected feature's geojson from your geojson FeatureCollection, and from that make a layer (we don't need to add it to the map), so that we can find its bounds and update the map accordingly.

How do we get the proper feature in the geojson? There are a few approaches, we could use a dictionary, or we could add additional data to the autocomplete function source (as suggested in the other answer). I'll follow the lead in the other answer, but use the increment of the feature and continue to use .map() :

source: setoresComerciais.features.map(function(d,i){
    return {
      label: d.properties.sco_num_sc + " - " + d.properties.sco_dsc_loc, 
      id: i 
    };

Here .map takes two variables: d is the current item in the features array being processed, and i is the index of that feature. With the index, we can easily access the proper item in the features array, make a layer out of it, and fit the map bounds to that feature's layer:

select: function(event, ui){
    var feature = setoresComerciais.features[ui.item.id]; // get the geojsonvar featureLayer = L.geoJSON(feature)  // create a layer from it
    map.fitBounds(featureLayer.getBounds()); // resize the map
} 

Altogether, that gives us:

    $("#txtSearch").autocomplete({
        source: setoresComerciais.features.map(function(d,i){
            return {label: d.properties.sco_num_sc + " - " + d.properties.sco_dsc_loc, id: i };
        }),
        select: function(event, ui){
            var feature = setoresComerciais.features[ui.item.id];
            var featureLayer = L.geoJSON(feature)
            map.fitBounds(featureLayer.getBounds());
        } 
    });

Solution 2:

Not used this plugin, but going to take a stab at it anyway.

I would advise that you make a more complex source, making use of the source: function(request, response){} feature. See more.

$("#txtSearch").autocomplete({
  source: function(req, resp){
    var results = [];
    $.each(setoresComerciais.features.properties, function(k, p){
      if(p.sco_dsc_loc.toLowerCase().indexOf(req.term.toLowerCase()) == 0){
        results.push({
          label: p.sco_num_sc + " - " + p.sco_dsc_loc,
          value: p.sco_dsc_loc,
          properties: p
        });
      }
    });
    resp(results);
  },
  select: function(event, ui){
    map.fitBounds(stComerciaisLayer.getBounds(ui.item.value));
    returnfalse;
  } 
});

This will ensure that there is a { label, value } pair for each potential result. You can also access all the properties too via ui.item.properties in select if you like.

This will also mean that you are passing just "FORTALEZA" and not "1 - FORTALEZA" which may confuse the plugin if it does match a title in the map data.

If you had provided example data or a jsFiddle, I would have tested this solution.


Update

Did some more reading. I see:

fitBounds(<LatLngBounds> bounds, <fitBounds options> options?)

Sets a map view that contains the given geographical bounds with the maximum zoom level possible.

map.fitBounds([
    [40.712, -74.227],
    [40.774, -74.125]
]);

To me, it appears the function is expecting a array versus a String. This is something that is returned by .getBounds(). Yet nothing I read advises that .getBounds() does not accept input. So I do not think stComerciaisLayer.getBounds(ui.item.value) will return the value you want.


Note

You've selected a great answer, and just updating my code as an alternative.

$("#txtSearch").autocomplete({
  source: function(req, resp){
    var results = [];
    $.each(setoresComerciais.features, function(k, f){
      var props = f.properties;
        if(props.sco_dsc_loc.toLowerCase().indexOf(req.term.toLowerCase()) == 0){
        results.push({
          label: props.sco_num_sc + " - " + props.sco_dsc_loc,
          value: props.sco_dsc_loc,
          properties: props,
          id: k
        });
      }
    });
    resp(results);
  },
  select: function(event, ui){
    var feature = setoresComerciais.features[ui.item.id];
    var featureLayer = L.geoJSON(feature)
    map.fitBounds(featureLayer.getBounds());
  } 
});

Post a Comment for "Zoom After Search Using Autocomplete"