Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: App crash on calling ShapeSource getClusterLeaves #3468

Closed
g-sharat opened this issue Apr 29, 2024 · 1 comment
Closed

[Bug]: App crash on calling ShapeSource getClusterLeaves #3468

g-sharat opened this issue Apr 29, 2024 · 1 comment
Labels
bug 🪲 Something isn't working

Comments

@g-sharat
Copy link

g-sharat commented Apr 29, 2024

Mapbox Implementation

Mapbox

Mapbox Version

default

React Native Version

0.73.4

Platform

iOS, Android

@rnmapbox/maps version

10.1.10

Standalone component to reproduce

/* eslint-disable react/prop-types */
import {View, Text} from 'react-native';
import React, {useEffect, useRef, useState} from 'react';
import Mapbox, {
  Camera,
  CircleLayer,
  Image,
  Images,
  ShapeSource,
  SymbolLayer,
} from '@rnmapbox/maps';

export default function ProfilePage() {
  const SF_OFFICE_COORDINATE = [-122.400021, 37.789085];

  const layerStyles = {
    icon: {
      iconImage: ['get', 'icon'],

      iconSize: [
        'match',
        ['get', 'icon'],
        'example',
        1.2,
        'airport-15',
        1.2,
        /* default */ 1,
      ],
      iconAllowOverlap: true,
    },
    singlePoint: {
      circleColor: 'green',
      circleOpacity: 0.84,
      circleStrokeWidth: 2,
      circleStrokeColor: 'white',
      circleRadius: 5,
      circlePitchAlignment: 'map',
    },

    clusteredPoints: {
      circlePitchAlignment: 'map',
      circleColor: 'yellow',
      circleRadius: ['step', ['get', 'point_count'], 20, 100, 30, 750, 40],
      circleOpacity: 0.84,
      circleStrokeWidth: 2,
      circleStrokeColor: 'white',
    },

    clusterCount: {
      textField: ['get', 'point_count'],
      textSize: 12,
      textPitchAlignment: 'map',
    },
  };
  const [layerPoints, setLayerPoints] = useState();
  var shapeSourceRef = useRef();

  useEffect(() => {
    let temp = {
      type: 'FeatureCollection',
      features: [],
    };
    for (let index = 0; index < 10; index++) {
      temp.features.push({
        type: 'Feature',
        id: index,
        properties: {
          icon: index == 0 ? 'pin-rn' : 'test',
        },
        geometry: {
          type: 'Point',
          coordinates: [
            SF_OFFICE_COORDINATE[0] + index,
            SF_OFFICE_COORDINATE[1] + index,
          ],
        },
      });
    }
    setLayerPoints(temp);
  }, []);

  const handleClusterTap = async l => {
    if (l.features.length == 1) {
      //do something with single point
    } else {
      console.log(l.features);
      const collection = await shapeSourceRef.current.getClusterLeaves(
        5,
        999,
        0,
      );
      console.log(collection);
    }
  };

  return (
    <View style={{flex: 1}}>
      <Mapbox.MapView style={{flex: 1}}>
        <Camera
          defaultSettings={{
            centerCoordinate: SF_OFFICE_COORDINATE,
            zoomLevel: 3,
          }}
        />
        <Images>
          <Image name="pin-rn">
            <View>
              <View
                style={{
                  borderRadius: 10,
                  backgroundColor: 'gray',
                  padding: 8,
                  margin: 16,
                  width: 100,
                  shadowOffset: {width: 0, height: 8},
                  shadowOpacity: 0.2,
                }}>
                <Text style={{fontWeight: 'bold', color: 'white'}}>
                  RN Pin 2
                </Text>
              </View>
            </View>
          </Image>
          <Image name="test">
            <View>
              <View
                style={{
                  borderRadius: 10,
                  backgroundColor: 'gray',
                  padding: 8,
                  margin: 16,
                  width: 100,
                  shadowOffset: {width: 0, height: 8},
                  shadowOpacity: 0.2,
                }}>
                <Text style={{fontWeight: 'bold', color: 'white'}}>Test</Text>
              </View>
            </View>
          </Image>
        </Images>
        <ShapeSource
          id="earthquakes"
          cluster
          ref={shapeSourceRef}
          onPress={i => handleClusterTap(i)}
          clusterRadius={50}
          clusterMaxZoom={14}
          shape={layerPoints}>
          <SymbolLayer id="pointCount" style={layerStyles.clusterCount} />

          <CircleLayer
            id="clusteredPoints"
            belowLayerID="pointCount"
            filter={['has', 'point_count']}
            style={layerStyles.clusteredPoints}
          />

          <SymbolLayer id="exampleIconName" style={layerStyles.icon} />
        </ShapeSource>
      </Mapbox.MapView>
    </View>
  );
}

Observed behavior and steps to reproduce

  • Click on any cluster

Exception in native call
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 2 path $
at com.google.gson.Gson.fromJson(Gson.java:975)
at com.google.gson.Gson.fromJson(Gson.java:928)
at com.google.gson.Gson.fromJson(Gson.java:877)
at com.google.gson.Gson.fromJson(Gson.java:848)
at com.mapbox.geojson.Feature.fromJson(Feature.java:82)
at com.rnmapbox.rnmbx.components.styles.sources.RNMBXShapeSource.getClusterLeaves(RNMBXShapeSource.kt:280)
at com.rnmapbox.rnmbx.components.styles.sources.RNMBXShapeSourceModule$getClusterLeaves$1.invoke(RNMBXShapeSourceModule.kt:51)
at com.rnmapbox.rnmbx.components.styles.sources.RNMBXShapeSourceModule$getClusterLeaves$1.invoke(RNMBXShapeSourceModule.kt:50)
at com.rnmapbox.rnmbx.utils.ViewTagResolver.withViewResolved$lambda$4(ViewTagResolver.kt:63)
at com.rnmapbox.rnmbx.utils.ViewTagResolver.$r8$lambda$ZFXWzquiK28lSR5tbH0BihabahM(Unknown Source:0)
at com.rnmapbox.rnmbx.utils.ViewTagResolver$$ExternalSyntheticLambda0.run(Unknown Source:8)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:384)
at com.mapbox.geojson.Feature$GsonTypeAdapter.read(Feature.java:579)
at com.mapbox.geojson.Feature$GsonTypeAdapter.read(Feature.java:497)
at com.google.gson.Gson.fromJson(Gson.java:963)
... 19 more
Screenshot_1714376311

Expected behavior

App shouldn't crash and should return collection

Notes / preliminary analysis

No response

Additional links and references

No response

@g-sharat g-sharat added the bug 🪲 Something isn't working label Apr 29, 2024
@g-sharat g-sharat changed the title [Bug]: App crash on callng ShapeSource getClusterLeaves [Bug]: App crash on calling ShapeSource getClusterLeaves Apr 29, 2024
@g-sharat
Copy link
Author

Sorry for not checking more thoroughly. I need to pass the argument as const [cluster] = l.features;. Closing the issue as redundant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant