0
votes

I need to convert the some functionality of google maps into Leaflet and OSM. What I have is an indoor visitor tracking application that uses google maps with custom tiles (Indoor floor plan image). It plot markers on the locations of visitors (indoor) by converting X Y coordinates into Lat Lng. Its done through

function findLatLangFromImagePixel(imgPixel) {
    var scalingRatio = ImageWidth / 256;
    var pixel = { x: ((imgPixel.X) / scalingRatio), y: ((imgPixel.Y) / scalingRatio) };

    var point = new google.maps.Point(pixel.x + 0.5, pixel.y + 0.5);
    return map.getProjection().fromPointToLatLng(point);
}

enter image description here

In Leaflet maps I am trying the following code to achieve same results (using the same image/tiles):

var x = ImageXYLocation.X;
            var y = ImageXYLocation.Y;
            var scalingRatio = ImageWidth / 256;
            var pixel = { x: ((x) / scalingRatio), y: ((y) / scalingRatio) };
var pointXY = L.point(pixel.x + 0.5, pixel.y +0.5);

            latlng = map.layerPointToLatLng(pointXY);
latlng.lng += 180;

But I am getting different results. Also, I observed that as the marker switches its location on the indoor map upon changing the resolution of my screen . It seems that the marker position is dependent on my screen resolution or at zoom level. enter image description here

And second zoom level enter image description here

Update: Map initialization code is below:

 if (map != null) {
            map.remove();
        }
        $("#map_canvas").html("");

        map = L.map('map_canvas', {
            minZoom: 1,
            maxZoom: 4,
            center: [0, 0],
            zoom: 1,
            crs: L.CRS.Simple,
        });
        var w = 6095,
            h = 3410;
        var southWest = map.unproject([0, h], map.getMaxZoom() - 1);
        var northEast = map.unproject([w, 0], map.getMaxZoom() - 1);
        var bounds = new L.LatLngBounds(southWest, northEast);
        L.tileLayer('./tiles/{z}/{x}/{y}.png', {
            maxZoom: 16,
            minZoom: 0,
            continuousWorld: false,
            bounds: bounds,
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);

        map.setZoom(5);
        map.setMaxBounds(bounds);

        map.zoomControl.setPosition('bottomright');

Update 2:

enter image description here

2

2 Answers

0
votes

It seems that the marker position is dependent on my screen resolution or at zoom level.

Indeed. You're using layerPointToLatLng(), which according to the documentation (emphasis mine)...

Given a pixel coordinate relative to the origin pixel, returns the corresponding geographical coordinate (for the current zoom level).

Leaflet has a curious way of hiding the complexities of CRSs and projections. Without seeing more of the code you're using for defining the map's CRS, or the bounds of your indoor map image, it's impossible to offer any advice other than "pay attention to what your coordinates mean".

0
votes

Thanks for your guidance. I have been able to figure out the solution. I used the following code to get the correct LatLng

var x = ImageXYLocation.X;
var y = ImageXYLocation.Y;
var scalingRatio = ImageWidth / 256;
var pixel = { x: ((x / scalingRatio) * Math.pow(2, map.getZoom())), y: ((y / scalingRatio) * Math.pow(2, map.getZoom())) };

var pointXY = L.point(pixel.x + 0.5, pixel.y +0.5);

latlng = map.unproject(L.point(pixel.x, pixel.y));