Search code examples
leafletgeojsonmap-projections

Show geojson featureCollection with Leaflet


with QGIS I´ve exported a polygon layer as geojson which I´d like to publish with leaflet. This is how the geojson looks like [exluded due to SO character limits]: https://gist.github.com/t-book/88806d12d7f05024b147715be82e6844

This is what I´ve tried:

Wrapped geojson as var:

var states = [{
    "type": "FeatureCollection",
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::31468" } },
    "features": [
       { "type": "Feature", "properties": ...
}];

Added as new Layer:

L.geoJSON(states, {
    style: function(feature) {
        switch (feature.properties.party) {
            case 'Euerbach': return {color: "#ff0000"};
            case 'Werneck':   return {color: "#0000ff"};
        }
    }
}).addTo(map);

Unfortunately nothing is rendered. How do I correctly add this geojson featureCollection to my map?


Solution

  • The problem is that your data is projected - Leaflet is expecting your data to be unprojected (composed of long/lat pairs, or "projected" in WGS84/EPSG 4326). There are a few solutions, two come to mind here:

    • In QGIS, export your data so that it is composed of long/lat coordinate pairs

    • Use proj4.js to reproject your coordinates when displaying the geojson.

    For number two, you'll need to set the coordsToLatLng option when adding the geojson as a layer:

    var geojson = L.geoJSON(states, {
        coordsToLatLng: function (p) {  
            // return get lat/lng point here.
    })
    

    The body of this function will take a coordinate in the geojson's coordinate reference system (CRS) and return it in WGS84 using proj4.

    Also, coordsToLatLng function expects you to return lat/long pairs. As your geojson and proj4 represent data that is [x,y], we need to swap our values before returning the new point.

    This could look like:

    var geojson = L.geoJSON(states, {
        coordsToLatLng: function (p) {
            p = proj4(fromProjection,toProjection,p);  // reproject each point
            p = [p[1],p[0]]    // swap the values
            return p;          // return the lat/lng pair
        }
    }).addTo(map);
    

    Of course, we need to define our CRSs. I looked up your CRS (it is specified in the geojson itself) on spatialreference.org and used the provided description for that CRS and EPSG4326 (WGS84) to set my fromProjection and toPojection:

    var fromProjection = '+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs ';
    var toProjection = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ";
    

    Altogether that gives us something like this. Keep in mind, that if you have large files, reprojecting them in javascript will take longer than if you export them in the proper CRS.