rnmapbox / maps

A Mapbox react native module for creating custom maps
MIT License
2.26k stars 846 forks source link

[Bug]: queryRenderedFeaturesInRect is not returning properties in iOS. #2718

Closed somasekharkakarla closed 1 year ago

somasekharkakarla commented 1 year ago

Mapbox Implementation

Mapbox

Mapbox Version

default

Platform

iOS

@rnmapbox/maps version

@rnmapbox/maps#main

Standalone component to reproduce

https://github.com/somasekharkakarla/mbTest

Observed behavior and steps to reproduce

Hi @mfazekas , I updated the lib. Click is working fine now. But properties are getting empty in queryRenderedFeaturesInRect .

Shape value for MapboxGL.ShapeSource {"type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -76.57977345687516, 36.69512793531269 ], [ -76.57979889504533, 36.69512836586616 ], [ -76.57979560082207, 36.69525875203225 ], [ -76.57977016225729, 36.69525833536608 ], [ -76.57977345687516, 36.69512793531269 ] ] ] ] }, "properties": { "group": "T0jwSxz0jH", "featureTypeId": 456, "project": "jtBi3Wh64k", "extraProperties": { "Block": "B01", "project": "", "col_start": "1", "row_start": "1", "orientation": "NS", "tracker_type": "Short", "tracker_section": "1", "total_num_modules": "13", "num_modules_vertical": "13", "num_modules_horizontal": "1" }, "name": "B01 S01 R029 N", "featureType": "EAF3oKgiNZ1L", "dataProperties": null, "description": null, "workflow": null, "hierarchyProperties": null, "uid": "gvWcDiVrMYOE", "workflowProgress": {} } }]}

Output in android:

{"type":"Feature","id":"","geometry":{"type":"Polygon","coordinates":[[[-76.5797955,36.6952588],[-76.57977,36.6952582],[-76.5797734,36.6951278],[-76.5797989,36.6951284],[-76.5797955,36.6952588]]]},"properties":{"featureTypeId":456,"group":"T0jwSxz0jH","workflowProgress":{},"extraProperties":{"Block":"B01","col_start":"1","project":"","row_start":"1","orientation":"NS","tracker_type":"Short","num_modules_vertical":"13","tracker_section":"1","total_num_modules":"13","num_modules_horizontal":"1"},"name":"B01 S01 R029 N","project":"jtBi3Wh64k","featureType":"EAF3oKgiNZ1L","uid":"gvWcDiVrMYOE"}}

Output in ios: {"type":"Feature","geometry":{"coordinates":[[[-76.57979551702738,36.695258762020146],[-76.57977003604174,36.69525822435453],[-76.579773388803,36.69512784032909],[-76.57979886978865,36.695128377995616],[-76.57979551702738,36.695258762020146]]],"type":"Polygon"},"properties":{}}

properties are empty in ios

Expected behavior

properties should not be empty

Notes / preliminary analysis

No response

Additional links and references

No response

mfazekas commented 1 year ago

@somasekharkakarla thanks for the report, please include a single component, it's much easier for us to test in our test app, then building your project.

somasekharkakarla commented 1 year ago

Hi @mfazekas , i already a repo https://github.com/somasekharkakarla/mbTest

single component:

import React from 'react';
import { StyleSheet, View, SafeAreaView } from 'react-native';
import Mapbox from '@rnmapbox/maps';
Mapbox.setAccessToken('<MAPBOX TOKEN>');
Mapbox.setWellKnownTileServer('mapbox')

const featureLayerStyles = {
  fillStatusStyles: {
    fillColor: ['match', ['get', 'scanStatus', ['get', 'extraProperties']],
      'pending', 'rgb(204, 37, 53)',
      'inprogress', 'rgb(255, 231, 12)',
      'completed', 'rgb(99, 204, 35)',
      '#ccc'],
    fillOpacity: 1.0,
  },
  fillEmptyStyles: {
    fillOpacity: 1.0,
    fillColor: 'rgb(204, 37, 53)',
  },

  fillPolygonStyles: {
    fillColor: ['match', ['get', 'scanStatus', ['get', 'extraProperties']],
      'pending', 'rgb(204, 37, 53)',
      'inprogress', 'rgb(255, 231, 12)',
      'completed', 'rgb(99, 204, 35)',
      '#ccc'],
    fillOpacity: 1.0,
  },
  fillPolygonEmptyStyles: {
    fillOpacity: 1.0,
    fillColor: 'rgb(204, 37, 53)',
  },

  clickedFeatureStyle: {
    fillOpacity: 1.0,
    fillColor:"#0000FF",
  }
};

const getBoundingBox = (screenCoords:any) => {
  const maxX = Math.max(screenCoords[0][0], screenCoords[1][0]);
  const minX = Math.min(screenCoords[0][0], screenCoords[1][0]);
  const maxY = Math.max(screenCoords[0][1], screenCoords[1][1]);
  const minY = Math.min(screenCoords[0][1], screenCoords[1][1]);
  return [maxY, maxX, minY, minX];
};

function App(): JSX.Element {

 let mapComponentView:any=null

 const onMapPress = (layers:any) => {
  // noinspection JSUnresolvedVariable
  const boundingScreenBox = getBoundingBox([[layers.properties.screenPointX - 10,
    layers.properties.screenPointY - 10], [layers.properties.screenPointX + 10,
    layers.properties.screenPointY + 10]]);

  const featurePointOfVectorsWithinRect = mapComponentView.queryRenderedFeaturesInRect(
    boundingScreenBox, null, [
      'fillLineString', 'fillNoStatusLineString',
      'fillPolygon', 'fillNoStatusPolygon',
      'fillThermalNoStatusPolygon', 'fillThermalPolygon',
      'fillLineStringQueuedFeatures', 'fillNoStatusLineStringQueuedFeatures',
      'fillPolygonQueuedFeatures', 'fillNoStatusPolygonQueuedFeatures',
      'fillThermalNoStatusPolygonQueuedFeatures', 'fillThermalPolygonQueuedFeatures',
    ],
  );

  featurePointOfVectorsWithinRect.then((selectedVector:any) => {
    if (selectedVector.features.length > 0) {
      console.log("selectedVector.features", selectedVector.features)
      // center: layers.geometry.coordinates,
    }
    console.warn('selectedVector', selectedVector.features[0]);
  })
    .catch((err:any) => {
      console.warn(err);
    });
}

  return (
    <SafeAreaView style={{flex: 1}}>
    <View style={{flex: 1}}>
      <View style={{flex: 1}}>
        <Mapbox.MapView style={{flex:1}} ref={(component) => {
          mapComponentView = component;
        }} onPress={layers => onMapPress(layers)}>

    <Mapbox.ShapeSource
        id="featurePointShapeSource"
        shape={{"type": "FeatureCollection",
        "features": [
            {
                "type": "Feature",
                "geometry": {
                    "type": "MultiPolygon",
                    "coordinates": [
                        [
                            [
                                [
                                    -76.57977345687516,
                                    36.69512793531269
                                ],
                                [
                                    -76.57979889504533,
                                    36.69512836586616
                                ],
                                [
                                    -76.57979560082207,
                                    36.69525875203225
                                ],
                                [
                                    -76.57977016225729,
                                    36.69525833536608
                                ],
                                [
                                    -76.57977345687516,
                                    36.69512793531269
                                ]
                            ]
                        ]
                    ]
                },
                "properties": {
                    "group": "T0jwSxz0jH",
                    "featureTypeId": 456,
                    "workflowProgress": {},
                }
            }]}}>
        <Mapbox.FillLayer
          id="fillLineString"
          filter={['all', ['==', ['geometry-type'], 'LineString'],
          ]}
          style={featureLayerStyles.fillStatusStyles}
        />
        <Mapbox.FillLayer
          id="fillNoStatusLineString"
          filter={['all',
            ['==', ['geometry-type'], 'LineString'],
            // ['has', 'featureTypeId'],
          ]
          }
          style={featureLayerStyles.fillEmptyStyles}
        />
        <Mapbox.FillLayer
          id="fillPolygon"
          filter={['all', ['==', ['geometry-type'], 'Polygon']
          ]}
          style={featureLayerStyles.fillStatusStyles}
        />
        <Mapbox.FillLayer
          id="fillNoStatusPolygon"
          filter={['all',
            ['==', ['geometry-type'], 'Polygon']
          ]
          }
          style={featureLayerStyles.fillEmptyStyles}
        />

        <Mapbox.FillLayer
          id="fillThermalPolygon"
          filter={['all', ['==', ['geometry-type'], 'Polygon']]
          }
          style={featureLayerStyles.fillPolygonStyles}
        />
        <Mapbox.FillLayer
          id="fillThermalNoStatusPolygon"
          filter={['all',['==', ['geometry-type'], 'Polygon']]
          }
          style={featureLayerStyles.fillPolygonEmptyStyles}
        />
      </Mapbox.ShapeSource>
      <Mapbox.Camera
            // minZoomLevel={mapMetaData.minzoom}
            zoomLevel={18}
            centerCoordinate={[ -76.57977345687516,  36.69512793531269,18]}
            animationMode="flyTo"
          />

        </Mapbox.MapView>
      </View>
    </View>
    </SafeAreaView>
  );
}

export default App;
mfazekas commented 1 year ago

What is your @rnmapbox version? For me I do see properties.

2023-03-19 21:50:52.304620+0100 RNMapboxGLExample[88884:4735762] [javascript] 'selectedVector', { geometry: 
   { coordinates: 
      [ [ [ -76.57979551702738, 36.695258762020146 ],
          [ -76.5797702036798, 36.69525835877093 ],
          [ -76.579773388803, 36.695127974745745 ],
          [ -76.57979886978865, 36.695128377995616 ],
          [ -76.57979551702738, 36.695258762020146 ] ] ],
     type: 'Polygon' },
  type: 'Feature',
  properties: { featureTypeId: 456, workflowProgress: {}, group: 'T0jwSxz0jH' } }
somasekharkakarla commented 1 year ago

Hi @mfazekas ,

here is the versions and pod file. i also included the repo https://github.com/somasekharkakarla/mbTest. Please go through it and recommend me what is the correct version ASAP. i am unable figure out what is correct version

"dependencies": {
    "@rnmapbox/maps": "github:rnmapbox/maps#main",
    "react": "18.2.0",
    "react-native": "0.71.4"
  },

i am tested in iPhone 11 and iPhone 12 with iOS 16.0.2

and here is pod file:

$RNMapboxMapsImpl = 'mapbox'
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, min_ios_version_supported
prepare_react_native_project!

# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
#
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
# ```js
# module.exports = {
#   dependencies: {
#     ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'mbTest' do
  config = use_native_modules!

  # Flags change depending on the env values.
  flags = get_default_flags()

  use_react_native!(
    :path => config[:reactNativePath],
    # Hermes is now enabled by default. Disable by setting this flag to false.
    # Upcoming versions of React Native may rely on get_default_flags(), but
    # we make it explicit here to aid in the React Native upgrade process.
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    # Enables Flipper.
    #
    # Note that if you have use_frameworks! enabled, Flipper will not work and
    # you should disable the next line.
    :flipper_configuration => flipper_config,
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'mbTestTests' do
    inherit! :complete
    # Pods for testing
  end

  pre_install do |installer|
    $RNMapboxMaps.pre_install(installer)
  end

  post_install do |installer|
    $RNMapboxMaps.post_install(installer)
    react_native_post_install(
      installer,
      # Set `mac_catalyst_enabled` to `true` in order to apply patches
      # necessary for Mac Catalyst builds
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end
end
mfazekas commented 1 year ago

@somasekharkakarla sorry it's working in our example app. Can you try to reproduce the issue in our example env?

somasekharkakarla commented 1 year ago

Sure. And @mfazekas also please test my repo once

somasekharkakarla commented 1 year ago

Hi @mfazekas ,

i tried in rnmapbox/maps/example. the issue exists. Green box is android and Red box in ios

file i used for example

Screenshot 2023-03-21 at 12 56 12 PM Screenshot 2023-03-21 at 12 49 17 PM

video:

https://user-images.githubusercontent.com/65530762/226541151-6a037c96-1e09-4b3d-b1ad-1edf8284b58f.mov

somasekharkakarla commented 1 year ago

Hi @mfazekas , I am waiting for your response. This is causing so much trouble to our ios users.. Please send me feedback ASAP. Is there any other way of communication with mapbox tech team?

somasekharkakarla commented 1 year ago

@mfazekas, the problem is at ios File Name > RCTMGLMapViewManager.swift Line no:226 Method name > mapView.mapboxMap.queryRenderedFeatures on success, returned features doesn't have properties.

somasekharkakarla commented 1 year ago

What is your @rnmapbox version? For me I do see properties.

2023-03-19 21:50:52.304620+0100 RNMapboxGLExample[88884:4735762] [javascript] 'selectedVector', { geometry: 
   { coordinates: 
      [ [ [ -76.57979551702738, 36.695258762020146 ],
          [ -76.5797702036798, 36.69525835877093 ],
          [ -76.579773388803, 36.695127974745745 ],
          [ -76.57979886978865, 36.695128377995616 ],
          [ -76.57979551702738, 36.695258762020146 ] ] ],
     type: 'Polygon' },
  type: 'Feature',
  properties: { featureTypeId: 456, workflowProgress: {}, group: 'T0jwSxz0jH' } }

please add a null value to properties and check like { "group": "T0jwSxz0jH", "featureTypeId": 456, "workflowProgress": {}, "description":null } My mistake. i gave wrong feature(actual working feature). Actual issue with ios is when we use null values in properties like "description":null

mfazekas commented 1 year ago

@somasekharkakarla no problem. It's an upstream issue - https://github.com/mapbox/mapbox-maps-ios/issues/1914