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

Add support for using SDF template images

Open Buthrakaur opened this issue 9 months ago • 11 comments

style.addImages supports sdf flag on both Android and iOS but React Native didn't support it - this PR adds the support so it's possible to use SDF template images on the map by settings the sdf flag to true along with relevant icon re-coloring styles e.g. iconColor. Code sample:

const images = {  x: { uri: 'https://example.com/1.png', sdf: true } };
...
<Images images={images} />

Buthrakaur avatar Feb 11 '25 13:02 Buthrakaur

@Buthrakaur could you give an example here too? Thanks!

KiwiKilian avatar Feb 13 '25 17:02 KiwiKilian

@KiwiKilian

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

export function BugReport() {
  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: { uri: 'https://placehold.co/32/orange/white/png', sdf: true },
    }),
    []
  );

  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, iconColor: 'pink' }} />
      </ShapeSource>
    </MapView>
  );
}

Buthrakaur avatar Feb 14 '25 11:02 Buthrakaur

Thanks, I still have this on my radar. Hoping to have some time soon. Thanks for your patience!

KiwiKilian avatar Feb 20 '25 13:02 KiwiKilian

Here is an example with an actual SDF image:

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

export function BugReport() {
  return (
    <MapView style={{ flex: 1 }}>
      <Images
        images={{
          "example-icon": {
            uri: "https://docs.mapbox.com/help/demos/using-recolorable-images-in-mapbox-maps/shop-15.png",
            sdf: true,
          },
        }}
      />
      <ShapeSource id="ss-1" shape={{ type: "Point", coordinates: [0, 0] }}>
        <SymbolLayer
          id="sl-1"
          style={{
            iconImage: "example-icon",
            iconColor: "red",
          }}
        />
      </ShapeSource>
    </MapView>
  );
}

KiwiKilian avatar Mar 16 '25 17:03 KiwiKilian

Hello @KiwiKilian , could you please help us resolve the failing checks? We don't understand the build process completely thus don't understand what's wrong here.

Buthrakaur avatar Mar 26 '25 07:03 Buthrakaur

Hey @Buthrakaur, I could be wrong, but I think it may be because you committed changes to the yarn.lock without changes to a package.json?

tyrauber avatar Mar 26 '25 16:03 tyrauber

I was able to build and run this inside my project and my symbol layers are now functioning as expected with sdf: true... Big thanks to @Buthrakaur

Is there anything I can do to help get this PR merged in? Are we just waiting to run yarn codegen?

masonkieth avatar May 07 '25 22:05 masonkieth

Hi @masonkieth, I was not able to run yarn run codegen nor yarn install. I am getting Couldn't find package "@maplibre-react-native/examples@workspace:*" required by "[email protected]" on the "npm" registry. Can you help? Thx

jakub-oone avatar May 08 '25 07:05 jakub-oone

Hi @masonkieth, I was not able to run yarn run codegen nor yarn install. I am getting Couldn't find package "@maplibre-react-native/examples@workspace:*" required by "[email protected]" on the "npm" registry. Can you help? Thx

It depends on what you're trying to do... I followed the instructions here: https://github.com/maplibre/maplibre-react-native/blob/main/CONTRIBUTING.md to build MapLibre and add it to my project.

I'm not certain what all the codegen script does, but I didn't run it. Based on the context above it shouldn't be relevant to just getting the PR to build and compile locally.

Steps: Clone MapLibre -> pull PR changes -> corepack enable -> yarn install -> yarn pack -> cp to my-repo -> yarn add

masonkieth avatar May 08 '25 11:05 masonkieth

@jakub-oone are you using yarn v4 and try to run from the root of project?

KiwiKilian avatar May 08 '25 15:05 KiwiKilian

I forgot to mention, I was also having issues with Yarn due to some version mismatches.

error This project's package.json defines "packageManager": "[email protected]". However the current global version of Yarn is 1.22.22.

Presence of the "packageManager" field indicates that the project is meant to be used with Corepack, a tool included by default with all official Node.js distributions starting from 16.9 and 14.19.
Corepack must currently be enabled by running corepack enable in your terminal. For more information, check out `https://yarnpkg.com/corepack.

For some reason my terminal keeps defaulting to Yarn 1.22 - not sure where that's even installed, since my other repos use corepack and v4 with no issue... Anyways, I had to run corepack yarn install and I just tried corepack yarn codegen and both work fine, but if I don't prefix the yarn command with corepack it will default to a different version of Yarn that throws errors. FWIW

I'm not very familiar with Github PR's and how to commit. Is it possible for me to push commits to the PR or no?

masonkieth avatar May 08 '25 17:05 masonkieth

@KiwiKilian @masonkieth thx, did not know that I was using yarn v1. After upgrade to v4 everything started to work :-)

jakub-oone avatar May 08 '25 19:05 jakub-oone

@jakub-oone looks like the iOS code doesn't compile.

KiwiKilian avatar May 12 '25 04:05 KiwiKilian

The iOS compilation issue is in MLRNUtils.m on line 84, it should look like this. The sdf:sdf parameter is missing from the signature.

+ (void)fetchImage:(RCTBridge *)bridge
               url:(NSString *)url
             scale:(double)scale
             sdf:(Boolean)sdf
          callback:(RCTImageLoaderCompletionBlock)callback {
  [MLRNImageQueue.sharedInstance addImage:url scale:scale sdf:sdf bridge:bridge completionHandler:callback];
  }

I've got all tests are passing locally for iOS and Android, I also packaged it up and put it in my app and it's working as expected. I can open a new PR if that would be preferred @KiwiKilian

masonkieth avatar Sep 30 '25 14:09 masonkieth

@masonkieth Yes please do so. Closing here for no response from the author.

KiwiKilian avatar Oct 01 '25 04:10 KiwiKilian