skip to Main Content

I have a .json file of points to put on a Leaflet map, and I have used the proj4js to convert them from the EPSG 3946 projection into the WGS84 EPSG 4326 one. All worked, but the points are not located where they should be: they are about 8 degrees latitude more towards south and a little bit more towards east. The same points look fine on QGIS, they place where they should be.

This is the .js script:

var pTransfo;

$.getJSON('transfo.json',function(data){
    
    proj4.defs("EPSG:3946", "+proj=lcc +lat_1=43 +lat_2=49 +lat_0=46.5 +lon_0=6 +x_0=1700000 +y_0=6200000 +datum=RGF93 +units=m +no_defs +towgs84=0,0,0");

    var fromProj = proj4('EPSG:3946');
    var toProj = proj4('EPSG:4326');
    
    function convertCoordinates(coordinates) {
    
    var convertedCoords = proj4(fromProj, toProj, [coordinates[0], coordinates[1]]);
    console.log('Coordonnées originales :', coordinates);
    console.log('Coordonnées converties :', convertedCoords);
    return [convertedCoords[0], convertedCoords[1]];
}

    data.features.forEach(function(feature) {
        if (feature.geometry.type === "Point") {
            feature.geometry.coordinates = convertCoordinates(feature.geometry.coordinates);
        }
});

And I have already added this line in the html: <script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.0/proj4-src.js"></script> after the jquery and leaflet line.

Why this delay of location?

2

Answers


  1. Chosen as BEST ANSWER

    everybody! Because I had to finish this project very fast, I actually used the new columns I have created, filled with WGS84 data converted from the 3946 ones. All worked fine with WGS84 data. And Thomas, I thought of that too and I have tested the 3946 data. Nothing was out of order. Only after using the proj4js...


  2. The issue is most likely the order of your EPSG:3946 coordinates. Since I don’t have your data to test, I can only guess though. However, I wrote an example using 1124390.4605155424, 5490541.680680278 (x, y) for Le Conquet near Brest in Bretagne.

    The conversation output is -4.773869999999995, 48.36004666665183 (lng, lat). If I pass the EPSG:3946 coordinate in its reversed order (y, x), then I also get a coordinate that is way off.

    In addition, I am using the projection definition suggested by Jaromanda X in his comment.

    // x, y
    const leConquetEPSG3946 = [1124390.4605155424, 5490541.680680278];
    
    proj4.defs('EPSG:3946', '+proj=lcc +lat_0=46 +lon_0=3 +lat_1=45.25 +lat_2=46.75 +x_0=1700000 +y_0=5200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs');
    
    const proj3946 = proj4('EPSG:3946');
    const proj4326 = proj4('EPSG:4326');
    
    const result = proj4(proj3946, proj4326, leConquetEPSG3946);
    
    // -4.773869999999995, 48.36004666665183
    console.log(result);
    

    Here is a working example (with loading the projection definition for EPSG:3946 from spatialreference.org on the fly):

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>StackOverflow Question 79049517</title>
    
      <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    
      <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.12.1/proj4.js"></script>
      <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    
      <style>
        body {
          margin: 0;
        }
    
        #map {
          height: 100vh;
        }
    
        .reference-marker .circle {
          background-color: #f07819;
          border-radius: 50%;
          height: 20px; width: 20px;
        }
      </style>
    
    </head>
    
    <body>
    
      <div id="map"></div>
    
      <script>
    
        // x, y
        const leConquetEPSG3946 = [1124390.4605155424, 5490541.680680278];
    
        // lat, lng
        const leConquetEPSG4326 = [48.36004669356216, -4.773869943507622];
    
        const map = L.map('map')
              .setView(leConquetEPSG4326, 16);
    
        map.attributionControl
          .setPrefix('<a href="https://leafletjs.com/">Leaflet</a>');
    
        L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
          maxZoom: 19,
          // add link to attribution, omitted in this code example
          // due to width limit, i.e., avoid horizontal scrolling
          attribution: '&copy; OpenStreetMap',
        }).addTo(map);
    
        L.marker(leConquetEPSG4326, {
          icon: L.divIcon({
            className: 'reference-marker',
            iconSize: [20, 20],
            html: '<div class="circle"></div>',
          }),
        }).addTo(map);
    
        async function loadDefs(...epsgCodes) {
          const projs = {};
          for (const code of epsgCodes) {
            if (code != 4326) {
              const url = `https://spatialreference.org/ref/epsg/${code}/esriwkt.txt`;
              const response = await fetch(url);
              const wkt = await response.text();
              proj4.defs(`EPSG:${code}`, wkt);
            }
            projs[code] = proj4(`EPSG:${code}`);
          }
          return projs;
        }
    
        loadDefs(3946, 4326)
          .then(projs => {
          
            // lng, lat
            const conversionResult = proj4(projs[3946], projs[4326], leConquetEPSG3946);
          
            // lat, lng
            const result = conversionResult.reverse();
            
            console.log(leConquetEPSG4326);
            console.log(result);
          
            L.marker(result).addTo(map);
          
          });
    
      </script>
    
    </body>
    
    </html>
    

    DEMO

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search