manubb / Leaflet.PixiOverlay

Bring Pixi.js power to Leaflet maps
MIT License
478 stars 86 forks source link

Help with custom coordinates #92

Closed rogerhnn closed 1 year ago

rogerhnn commented 1 year ago

I am using custom coordinates, extending the CRS.Simple:

L.CRS.PixelPoint = L.extend({}, L.CRS.Simple, {
  transformation: new L.Transformation(1 / 8, 0, -1 / 8, 520);
});

let map = L.map('map', {
  maxNativeZoom: maxNativeZoom,
  minZoom: 0,
  maxZoom: mapMaxZoom,
  zoomControl: false,
  fullscreenControl: true,
  fullscreenControlOptions: {
    position: 'topright'
  },
  crs: L.CRS.PixelPoint,
  inertia: !1,
  boxZoom: !1,
  inertia: !0,
  zoomSnap: .5,
  zoomDelta: .5,
  wheelPxPerZoomLevel: 90,
  wheelDebounceTime: 0,
})

How can I convert the coordinates that I am using, back to the ones that Leaflet.PixiOverlay could read and render the markers in the correct place?

The unproject function doesn't return the correct values.

Thanks

manubb commented 1 year ago

Can you provide more details (e.g. the complete code including the pixi overlay layer) please? Why do you say that unproject does not return the correct value?

rogerhnn commented 1 year ago

Hello, made a replit of my code as an example, you can check it here:

code

Also on github here: https://github.com/rogerhnn/leaflet-pixi-markers

In my custom CRS, I set the 0,0 coordinates to be at the left bottom of the image/map. But when I add a marker with the 0,0 coordinates it doesn't match the bottom left corner, the marker is added on the top left corner, but not at the right place.

I tried using unproject but then it returns a more weird value, for example, converting the values [0,0] the result is {lat: 2064, lng: 2080}.

I didn't understand why it does like that.

If you look at my code you will see that I'm trying to render marker1 at position 0,0 (bottom left), but it's rendering on top left, and not in the edge.

marker2 is almost at the center using the coordinates [520, 524], (after a lot of trial and error), but when you zoom in only, if you zoom out the marker shifts it's position up.

And marker 3 I am using the coordinates 0,0 converted using the unproject function, which results in the marker to be outside the map on the bottom right of the screen. http://prntscr.com/7Z02MRrgAxBy

Another question, there's a better way of drawing multiple markers instead of doing like I am doing in my code, having to repeat the code everytime for a marker? And also, it's possible to toggle the markers visibility on the map just like I am doing with my other markers in the example?

Thanks

manubb commented 1 year ago

It seems to me that writing:

    if (firstDraw) {
      const markerCoords1 = project(marker1Coords);
      marker1.x = markerCoords1.x;
      marker1.y = markerCoords1.y;

      const markerCoords2 = project(marker2Coords);
      marker2.x = markerCoords2.x;
      marker2.y = markerCoords2.y;

      const markerCoords3 = project(marker3Coords);
      marker3.x = markerCoords3.x;
      marker3.y = markerCoords3.y;
    }

is working as expected. (Just like in https://github.com/manubb/Leaflet.PixiOverlay#draw-a-marker.)

rogerhnn commented 1 year ago

It seems to me that writing:

    if (firstDraw) {
      const markerCoords1 = project(marker1Coords);
      marker1.x = markerCoords1.x;
      marker1.y = markerCoords1.y;

      const markerCoords2 = project(marker2Coords);
      marker2.x = markerCoords2.x;
      marker2.y = markerCoords2.y;

      const markerCoords3 = project(marker3Coords);
      marker3.x = markerCoords3.x;
      marker3.y = markerCoords3.y;
    }

is working as expected. (Just like in https://github.com/manubb/Leaflet.PixiOverlay#draw-a-marker.)

Yes, the markers are being added to the map, but in the wrong coordinates. Compare the markers coordinates being added by the pixijs code and the ones in the map (green ones).

The marker1 should be on top of the pink marker of the Top Left Corner, but is misaligned.

The marker3, should be in the Bottom Right Corner, but is misaligned too, outside the map.

This is my problem, the markers are being added in a wrong position, and the conversion isn't working as intended. I need help placing the markers on the right coordinates.

manubb commented 1 year ago

Using the code above with:

  marker1.anchor.set(0.5, 0.5);
  const marker1Coords = [500, 0]; // y=500, x=0
  marker2.anchor.set(0.5, 0.5);
  const marker2Coords = [1000, 4160]; // y=1000, x=4160
  marker3.anchor.set(0.5, 0.5);
  const marker3Coords = [2000, 1000]; // y=2000, x=1000

we get: markers

which looks good to me.

(Note that the coordinates are (latitude, longitude) so x is y and y is x morally.)

rogerhnn commented 1 year ago

Using the code above with:

  marker1.anchor.set(0.5, 0.5);
  const marker1Coords = [500, 0]; // y=500, x=0
  marker2.anchor.set(0.5, 0.5);
  const marker2Coords = [1000, 4160]; // y=1000, x=4160
  marker3.anchor.set(0.5, 0.5);
  const marker3Coords = [2000, 1000]; // y=2000, x=1000

we get: markers

which looks good to me.

(Note that the coordinates are (latitude, longitude) so x is y and y is x morally.)

Weird that in my code it doesn't look like that.

Did you changed anything other than the coordinates? In the image that you sent they look in the correct place, can you share the code for me to look at that?

Because changing the coordinates in my code is not showing them in the same position.

manubb commented 1 year ago

Here the file content:

async function pixiTest() {

  function handleMarkerClick(e) {
    e.stopPropagation();
    console.log(e)
  };

  const markerTexture = await PIXI.Assets.load(`./files/debug_marker.png`);

  let scaleFactor = 0.7;

  const marker1Coords = [500, 0];
  const marker1 = new PIXI.Sprite(markerTexture);
  marker1.width = 128; // Does this works?
  marker1.height = 128; // I noticed the icon only change size if set through the scale
  marker1.anchor.set(0.5, 0.5);
  marker1.interactive = true;
  marker1.buttonMode = true;
  marker1.on("pointerup", handleMarkerClick);

  const marker2Coords = [1000, 4160];
  const marker2 = new PIXI.Sprite(markerTexture);
  marker2.width = 128;
  marker2.height = 128;
  marker2.anchor.set(0.5, 0.5);
  marker2.interactive = true;
  marker2.buttonMode = true;

  const marker3Coords = [2000, 1000];
  const marker3 = new PIXI.Sprite(markerTexture);
  marker3.width = 128;
  marker3.height = 128;
  marker3.anchor.set(0.5, 0.5);
  marker3.interactive = true;
  marker3.buttonMode = true;

  const pixiContainer = new PIXI.Container();
  pixiContainer.addChild(marker1);
  pixiContainer.addChild(marker2);
  pixiContainer.addChild(marker3);

  let firstDraw = true;
  let prevZoom;

  const pixiOverlay = L.pixiOverlay((utils) => {
    const zoom = utils.getMap().getZoom();
    const container = utils.getContainer();
    const renderer = utils.getRenderer();
    const project = utils.latLngToLayerPoint;
    const unproject = utils.layerPointToLatLng;
    const scale = utils.getScale();

    if (firstDraw) {
      const markerCoords1 = project(marker1Coords);
      marker1.x = markerCoords1.x;
      marker1.y = markerCoords1.y;

      const markerCoords2 = project(marker2Coords);
      marker2.x = markerCoords2.x;
      marker2.y = markerCoords2.y;

      const markerCoords3 = project(marker3Coords);
      marker3.x = markerCoords3.x;
      marker3.y = markerCoords3.y;
    }

    if (firstDraw || prevZoom !== zoom) {
      marker1.scale.set(scaleFactor / scale);
      marker2.scale.set(scaleFactor / scale);
      marker3.scale.set(scaleFactor / scale);
    }

    firstDraw = false;
    prevZoom = zoom;
    renderer.render(container);
  }, pixiContainer);

  pixiOverlay.addTo(map);
}
pixiTest()

(It's the only updated file i think.)

rogerhnn commented 1 year ago

Awesome, found the problem! I was not using project to convert the marker coordinates! Thank you very much!