maplibre-react-native icon indicating copy to clipboard operation
maplibre-react-native copied to clipboard

make it possible to change image for existing image ID on Android

Open Buthrakaur opened this issue 9 months ago • 11 comments
trafficstars

make it possible to change image for existing image ID on Android - port of the same fix in rnmapbox https://github.com/rnmapbox/maps/pull/3431

Buthrakaur avatar Jan 30 '25 13:01 Buthrakaur

Hey @Buthrakaur, thanks for this! Code looks good. Would it be possible to add an example or test?

tyrauber avatar Jan 30 '25 17:01 tyrauber

Hello @tyrauber , thanks for quick reaction. You can see example in the original PR here: https://github.com/rnmapbox/maps/pull/3431 - I believe it should be good enough as it was accepted by @mfazekas

Buthrakaur avatar Feb 03 '25 09:02 Buthrakaur

Hello @tyrauber , any update, please?

Buthrakaur avatar Feb 11 '25 13:02 Buthrakaur

@KiwiKilian, thoughts? Looks pretty straightforward.

tyrauber avatar Feb 11 '25 16:02 tyrauber

@Buthrakaur could you please provide a minimal example? It's not necessary to be committed, you can just add it as a comment here so we can copy-paste it and see what bug it should fix. You should start from this example and only add the code necessary so we can reproduce the issue and validate your fix.

KiwiKilian avatar Feb 12 '25 21:02 KiwiKilian

Hello @KiwiKilian , here is it:

import { Images, MapView, ShapeSource, SymbolLayer } from '@maplibre/maplibre-react-native';
import React, { useEffect, useMemo, useState } from 'react';

export function IconUrlChanging() {
  const [currentTime, setCurrentTime] = useState(new Date());

  useEffect(() => {
    const intervalId = setInterval(() => {
      setCurrentTime(new Date());
    }, 1000);

    return () => clearInterval(intervalId);
  }, []);

  const featuresCollection: GeoJSON.FeatureCollection = useMemo(() => {
    const features: GeoJSON.Feature[] = [];

    for (let i = 1; i <= 10; i++) {
      features.push({
        type: 'Feature',
        id: i,
        properties: {
          icon: 'icon1',
          title: `POI ${i}`,
        },
        geometry: {
          type: 'Point',
          coordinates: [14.4282 + i * 0.02, 50.0806125],
        },
      });
    }

    return { type: 'FeatureCollection', features };
  }, []);

  const images = useMemo(
    () => ({
      icon1: currentTime.getSeconds() % 2 === 0 ? 'https://placehold.co/32/orange/white/png' : 'https://placehold.co/32/blue/white/png',
    }),
    [currentTime]
  );

  return (
    <MapView style={{ flex: 1 }}>
      <Images images={images} />
      <ShapeSource id="ss-1" shape={featuresCollection}>
        <SymbolLayer id="sl-1" style={{ iconImage: ['get', 'icon'], iconSize: 1 / 2 }} />
      </ShapeSource>
    </MapView>
  );
}

Buthrakaur avatar Feb 13 '25 17:02 Buthrakaur

Thanks! Will try to have a look soon!

KiwiKilian avatar Feb 13 '25 17:02 KiwiKilian

Here is a reduced example:

import {
  MapView,
  Images,
  ShapeSource,
  SymbolLayer,
} from "@maplibre/maplibre-react-native";
import { useEffect, useMemo, useState } from "react";

import { FEATURE_COLLECTION } from "../constants/GEOMETRIES";

export function BugReport() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setCounter((prevState) => prevState + 1);
    }, 1000);

    return () => clearInterval(intervalId);
  }, []);

  const images = useMemo(
    () => ({
      "example-icon":
        counter % 2 === 0
          ? "https://placehold.co/32/orange/white/png"
          : "https://placehold.co/32/blue/white/png",
    }),
    [counter],
  );

  return (
    <MapView style={{ flex: 1 }}>
      <Images images={images} />
      <ShapeSource id="example" shape={FEATURE_COLLECTION}>
        <SymbolLayer
          id="example"
          style={{ iconImage: "example-icon", iconSize: 1 }}
        />
      </ShapeSource>
    </MapView>
  );
}

KiwiKilian avatar Feb 21 '25 23:02 KiwiKilian

@KiwiKilian yes - this already worked for us on iOS but wasn't working on Android

Buthrakaur avatar Feb 25 '25 14:02 Buthrakaur

I can't make it work on iOS. Please revalidate and make a video which shows it's working on iOS.

KiwiKilian avatar Feb 25 '25 14:02 KiwiKilian

I've validated again on main branch – currently both platforms behave the same with my example. It's not possible to change the image URL on both Android and iOS.

Could you elaborate on your use case? I struggle to understand, why you would want to change the image? Couldn't your style just switch to another image, if necessary? If you can make a valid point for such usage, we would need feature parity for Android and iOS.

KiwiKilian avatar Mar 16 '25 09:03 KiwiKilian

Closing for missing response to my feedback. Happy to discuss further if my questions/concerns are adressed.

KiwiKilian avatar Oct 01 '25 04:10 KiwiKilian