[GIS] How to search and display features from WFS with search box

geojsonleafletsearchwfs

I’m building a web app to help people from a small island off the western coast of France locate their land parcels from the field. I did manage to deal with every map display, transparency. The key function of this web app is to be able to enter in a search box the reference of the parcel and have it displayed on the map.

I know how to send and receive request from the WFS server but have no idea on how to display it and pan the map to its position.

Parcels reference is in the format A23, B1240, F239, etc where letter (A to Q) is the section and following figure is the number.
The search box (which I don't know how to build) would let the user enter this reference but the code will have to process the reference to give it the form LNNNN (A23> A0023, B1240>B1240, F239>F0239) because this is how it is stored. This new reference would have to be attached to the string FR291550000 to match the complete reference of a parcel in the whole French territory.

Then request is sent to the WFS server in this format (request for parcel C24):
https://geobretagne.fr/geoserver/cadastre/wfs?request=GetFeature&service=WFS&version=2.0.0&typename=cadastre:CP.CadastralParcel&cql_filter=inspireid=%27FR291550000C0004%27&outputFormat=application/json&srsName=EPSG:4326

Request returns a GeoJSON file that can be displayed as it on the map:

{"type":"FeatureCollection","totalFeatures":1,"features":[{"type":"Feature","id":"CP.CadastralParcel.fid-69f356c1_16105f5a1c2_-64f8","geometry":{"type":"MultiPolygon","coordinates":[[[[-5.107811162186085,48.471312173890276],[-5.107773643847919,48.47119907500928],[-5.107759552719235,48.47115816794022],[-5.107528003348013,48.47119808944278],[-5.107546534768745,48.47126238691458],[-5.107580675995603,48.47137300409471],[-5.1076251960945935,48.47136452747779],[-5.107695140342036,48.47134897303584],[-5.107746991827471,48.471333392104526],[-5.107796292022977,48.471316267645875],[-5.107811162186085,48.471312173890276]]]]},"geometry_name":"geometry","properties":{"inspireid":"FR291550000C0004","geo_parcelle":"20152901550000C0004","label":"4","nationalcadastralreference":"1550000C0004","areavalue":344,"departement":"29","geo_section":"20151550000C","geo_subdsect":"20151550000C01","geo_indp":"01","beginlifespanversion":"septembre
2016","endlifespanversion":"septembre
2017","coar":null,"tex2":null,"codm":null,"creat_date":"2007-12-18Z","update_dat":"2015-08-12Z"}}],"crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG::4326"}}}

I’m not that bad explaining steps in doing things but I’m totally not able to develop this myself.

So far, here's my code so far:

<!doctype html>
<html>
  <head>
    <title>WMS GetFeatureInfo</title>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css" />
      <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>


    <!--[if lte IE 8]>
        <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.ie.css" />
    <![endif]-->

    <script src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js"></script>
    <style type="text/css">
      html, body, #map {
        margin: 0px;
        height: 80%;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>

    <h3>A demonstration of how to access a Text Field</h3>

<input type="text" id="myText" value="Parcel reference">

<p>Click the "locate this parcel" button to display requested parcel on the map.</p>

<button onclick="myFunction()">locate this parcel</button>

<p id="demo"></p>

    <script>
      var map = L.map('map', {
        center: [48.456469, -5.096704],
        zoom: 15
      });

       var options2 = {
            layers: 'ortho-29', // Layer to display from the global databas
            attribution: 'GeoBretagne', // Légende de la source
            minZoom: 10,
            maxZoom: 19,
            opacity: 1.0,
            tms: false
        };
        layer2 = L.tileLayer.wms('https://geobretagne.fr/geoserver/photo/ows?', options2).addTo(map); 

        var options4 = {
       layers: 'CP.CadastralParcel', // Layer to display from the global database
            style : 'inspire_common_DEFAULT', // display style
            attribution: 'GeoBretagne', // Map source
            minZoom: 9,
            maxZoom: 19,
            opacity: 1.0,
            format: 'image/png',
            transparent: true,
            tms: false
        };
        layer4 = L.tileLayer.wms('https://geobretagne.fr/geoserver/cadastre/ows?', options4).addTo(map);

           </script>

           <script>
function myFunction() {
    //var x = document.getElementById("myText").value;
    var searchInput = document.getElementById("myText").value;
    var baseInspireId = "FR291550000";
    var letter = searchInput.substring(0,1);
    var digits = searchInput.substring(1);
    // add the maximum possible numbers of zeros
    digits = "000"+digits;
    // take only the last four digits
    digits = digits.substring(digits.length-4);
    var result = baseInspireId + letter + digits;
    var adresseParcelle = "https://geobretagne.fr/geoserver/cadastre/wfs?request=GetFeature&service=WFS&version=2.0.0&typename=cadastre:CP.CadastralParcel&cql_filter=inspireid=%27"+result+"%27&outputFormat=application/json&srsName=EPSG:4326"
    document.getElementById("demo").innerHTML = adresseParcelle;


    //Parcel display-test

     var geojsonLayer = new L.GeoJSON();

      function getJson(data) {
          console.log(data)
          geojsonLayer.addData(data);
      }

      $.ajax({
          url: adresseParcelle,
          dataType: 'json',
          jsonpCallback: 'getJson',
          success: getJson
      });

      map.addLayer(geojsonLayer);
      map.fitBounds(geojsonLayer.getBounds());


    }
</script>

  </body>
</html>

Best Answer

Since your question changed and I misread the server answer somehow, it is much easier now and you can refer to the official Leaflet documentation and don't need to use Proj4Leaflet at all to do this task.

How to display the geojson result and zoom to it:

let parcelLayer = L.geoJSON(parcel).addTo(map);
map.fitBounds(parcelLayer.getBounds());

For the search box there are a couple of ways you can do it, but basically you need to get the value from a input field and then modify the input similar to the following example:

var searchInput = document.getElementById("search").value;
var baseInspireId = "FR291550000";
var letter = searchInput.substring(0,1);
var digits = searchInput.substring(1);
// add the maximum possible numbers of zeros
digits = "000"+digits;
// take only the last four digits
digits = digits.substring(digits.length-4);
var result = baseInspireId + letter + digits;