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

Dynamic iconImage value in SymbolLayerStyle not showing icon

Open ErTurco opened this issue 11 months ago • 4 comments

Hi, I have an issue with Feature rendering on ShapeSource with SymbolLayer. There is the code:

import React, { useRef, useState } from 'react';
import {
  Dimensions,
  SafeAreaView,
  StyleProp,
  Text,
  TextStyle,
  View,
  ViewStyle,
  useColorScheme,
} from 'react-native';

import {
  Colors,
} from 'react-native/Libraries/NewAppScreen';

import MapLibreGL, { SymbolLayerStyle } from '@maplibre/maplibre-react-native';
import GeoJSON from 'geojson';

// Will be null for most users (only Mapbox authenticates this way).
// Required on Android. See Android installation notes.
MapLibreGL.setAccessToken(null);

const WIDTH = Dimensions.get('window').width;
const HEIGHT = Dimensions.get('window').height;

function getMaxHeight() {
    return HEIGHT < WIDTH ? HEIGHT : WIDTH;
}

interface CustomCalloutStyles {
  mapPinLayer: SymbolLayerStyle;
  customCalloutText: StyleProp<TextStyle>;
  calloutContainerStyle: StyleProp<ViewStyle>;
}

const styles: CustomCalloutStyles = {
  mapPinLayer: {
    iconAllowOverlap: true,
    iconAnchor: 'bottom',
    iconSize: 0.2,
    iconImage: ['get', 'icon'],
    // iconImage: 'https://www.pngall.com/wp-content/uploads/2017/05/Map-Marker-Free-Download-PNG.png',
  },
  customCalloutText: {
    color: 'black',
    fontSize: 16,
  },
  calloutContainerStyle: {
    backgroundColor: 'white',
    width: 60,
    height: 40,
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
  },
};

function App(): React.JSX.Element {
  const isDarkMode = useColorScheme() === 'dark';
  const map = useRef<MapLibreGL.MapView>(null);
  const camera = useRef<MapLibreGL.Camera>(null);
  const [selectedFeature, setSelectedFeature] = useState<GeoJSON.Feature>();

  const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
  };

  function onMapReady(): void {
    console.log('onMapReady');
  }

  const featureCollection: GeoJSON.FeatureCollection = {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        id: '9d10456e-bdda-4aa9-9269-04c1667d4552',
        properties: {
          icon: 'https://www.pngall.com/wp-content/uploads/2017/05/Map-Marker-Free-Download-PNG.png',
          message: 'Hello!',
        },
        geometry: {
          type: 'Point',
          coordinates: [12.33235962957478, 42.89990295270986],
        },
      },
    ],
  };

  const onPinPress = (e: any): void => {
    if (selectedFeature) {
      setSelectedFeature(undefined);
      return;
    }

    const feature = e?.features[0];
    setSelectedFeature(feature);
  };

  return (
    <SafeAreaView style={backgroundStyle}>
      <MapLibreGL.MapView
          ref={map}
          style={{
            width: WIDTH,
            height: getMaxHeight()
          }}
          logoEnabled={false}
          attributionEnabled={false}
          onDidFinishLoadingMap= {onMapReady}
      >
          <MapLibreGL.Camera 
              ref={camera}
              bounds={{ne: [6.5, 35.4], sw: [18.6, 47.3]}}
          />
          <MapLibreGL.ShapeSource
            id="mapPinsSource"
            shape={featureCollection}
            onPress={onPinPress}>
            <MapLibreGL.SymbolLayer
              id="mapPinsLayer"
              style={styles.mapPinLayer}
            />
          </MapLibreGL.ShapeSource>
          {selectedFeature && (
            <MapLibreGL.MarkerView
              id="selectedFeatureMarkerView"
              coordinate={(selectedFeature.geometry as GeoJSON.Point).coordinates}>
              <View style={styles.calloutContainerStyle}>
                <Text style={styles.customCalloutText}>{selectedFeature.properties?.message}</Text>
              </View>
            </MapLibreGL.MarkerView>
          )}
      </MapLibreGL.MapView>
    </SafeAreaView>
  );
}

export default App;

In the CustomCalloutStyles if I set the directly the value for iconImage I can see the marker icon, otherwise (passing the value from the Feature, the line commented) I can't see the marker on map. How can I set dinamically the value for the iconImage, setting it in the Feature object?

Version(s) affected

  • Platform: iOS
  • OS version: iOS 17.2
  • Device type: iPhone 15 Pro Max
  • Emulator/ Simulator: Yes
  • Development OS: macOS 14.3.1 Sonoma
  • maplibre-react-native Version 10.0.0-alpha.2
  • React Native Version 0.73.5

ErTurco avatar Mar 11 '24 12:03 ErTurco