OpenLayers 3 reproject vector layer (v4.3.2)

1.5k views Asked by At

Greeting GIS enthusiasts and WEB makers. I have one question regarding projections, to be more precise reprojecting from EPSG:3765 to EPSG:3857 in Openlayers 4.

In code below I'm trying to reproject from EPSG:3765 to EPSG:3857 :

    proj4.defs(
        'EPSG:3765',
        '+proj=tmerc +lat_0=0 +lon_0=16.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'
    );

var map = new ol.Map({
    view: new ol.View({
        zoom: 6,
        center: ol.proj.transform([461152.65, 5108327.47], 'EPSG:3765', 'EPSG:3857')
    }),
    target: 'js-map',
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        }),
        new ol.layer.Vector({
            source: new ol.source.Vector({
                url: 'test_1.geojson',
                format: new ol.format.GeoJSON({
                    dataProjection: 'EPSG:3765',
                    featureProjection: 'EPSG:3857'
                })
            })

        })
    ]
});

Coordinates in geojson file are in meters and looks like this:

"coordinates": [ [ [ 461117.98, 5108379.85 ], [ 461124.53, 5108368.39 ], [ 461132.37, 5108354.26 ], [ 461141.13, 5108341.08 ...

I'm successfully rendering geojson but on a wrong location, like this: enter image description here

I want it to be here, like this: enter image description here

What I'm I doing it wrong? Is it problem in geojson coordinates format or i need to somehow reproject geojson to be like in second picture?

UPDATE

From here you can download geojson and test if u like https://www.dropbox.com/s/ih1bh8bj4zzgutc/test_1.geojson?dl=0

Using example of pavlos I edited couple of lines, or to be more precise; I'm trying to load local geojson using this block of code

var geojsonObject = $.ajax({
  dataType: "json",
  url: "test_1.geojson"
});

But I'm keep getting this type of error :

Uncaught TypeError: (0 , Tm[a.type]) is not a function

Code is below:

proj4.defs(
    'EPSG:3765',
    '+proj=tmerc +lat_0=0 +lon_0=16.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'
);

var geojsonObject = $.ajax({
    dataType: "json",
    url: "test_1.geojson"
  });
console.log(geojsonObject);

var styles = {
    'Polygon': new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'red',
            width: 5
        }),
        fill: new ol.style.Fill({
            color: 'rgba(255, 0, 0, 1)'
        })
    })
};

var styleFunction = function(feature) {
    return styles[feature.getGeometry().getType()];
};



var vectorSource = new ol.source.Vector({
    features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
        defaultDataProjection: ol.proj.get('EPSG:3765'),
        featureProjection: 'EPSG:3857'
    })
});
var vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    style: styleFunction
});
var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        }),
        vectorLayer
    ],
    target: 'map',
    controls: ol.control.defaults({
        attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
            collapsible: false
        })
    }),
    view: new ol.View({
        center: ol.proj.transform([461117.98, 5108379.85], 'EPSG:3765', 'EPSG:3857'),
        zoom: 12
    })
});

UPDATE 3

I believe that I'm one step closer but still no luck

I edited code a bit with jQuery and AJAX request and setting up function within loader property. Now code looks something like this:

var vectorLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
        loader: function() {
            $.ajax({
                type: 'GET',
                url:'test_1.geojson',
                context: this
            }).done(function(data){
                var format = new ol.format.GeoJSON();
                this.addFeatures(format.readFeatures(data, {
                    defaultDataProjection: ol.proj.get('EPSG:3765'),
                    featureProjection: 'EPSG:3857'
                }));

            });
        }
    })
});
map.addLayer(vectorLayer);

But now I can't see my GeoJSON feature, it seems to load but it doesn't render on the map.

I must point out that if I comment this two lines from readFeatures Method

defaultDataProjection: ol.proj.get('EPSG:3765'),
featureProjection: 'EPSG:3857'

geojson does render but on wrong location, just like in first picture. Please help....I really don't have any more tears left..

2

There are 2 answers

2
pavlos On BEST ANSWER

I am not sure what may your problem is, but maybe your geojson file does not include the the crs definition. Maybe the proj4js version is not the correct one.

Check this fiddle --> https://jsfiddle.net/p_tsagkis/s9vtoaak/. I am using your projection and seems to be within the correct position.

Update: You also need to change your geojson file a bit. The definition of projection, should be as follows:

{"type":"FeatureCollection",
"crs": {
          "type": "name",
          "properties": {
            "name": "EPSG:3765"
          }
        },
        "features":[..........

In case you can not edit your geojson file, one more option is to register the name exist within geojson to ol3 js section. Like this:

proj4.defs('urn:ogc:def:crs:EPSG::3765', proj4.defs('EPSG:3765'));

or replacing the projection definition js line to this:

proj4.defs("urn:ogc:def:crs:EPSG::3765","+proj=tmerc +lat_0=0 +lon_0=16.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");

I havent test it but it should work.

ol3 does not know about urn:ogc:def:crs:EPSG::3765 You just give proj4.defs("EPSG:3765","+proj=tmerc +lat_0=0 +lon_0=16.5 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"); so somehow you need to make it aware about the projection name exist within the file.

1
fradal83 On

I think your problem is with coordinates or with the source EPSG.

Look at https://epsg.io/3765 , the bounds of that projection are east of Italy, while you expect your geometries to be west of Italy.

With that projection, x coordinates should be negative.

My guess is that your geojson file is not using EPSG:3765