You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Moving to current location is handled by enabling isFollowingUserLocation
const isFollowingUserLocation = useRef(true);
/*
1. This state is forcefully rendering the moveCameraTo function while onUpdate is triggered
2. onUpdate doesn't update the value in currentPosition
3. To update it, the component needs to be rerendered
4. Its a quick-fix for now, we'll update the library to see if that
works fine with built-in follow location according to our requirements
*/
const [shouldRenderForcefullyOnUpdate, setShouldRenderForcefullyOnUpdate] =
useState(false);
// Function to handle modal confirm button press
const onPressOk = () => {
setPolygons([]);
hideModal();
};
// Runs when current field to edit is changed in edit field flow
useEffect(() => {
if (fieldDetail?.boundary_status === 'incomplete') {
setPolygons([fieldDetail?.boundaries?.coordinates[0][0]] || []);
}
setPolygons(fieldDetail?.boundaries?.coordinates[0] || []);
if (fieldDetail?.boundaries) {
setFieldArea(
helperFunctions.toFormattedArea(area(fieldDetail?.boundaries))
);
}
}, [fieldDetail?.id]);
/**
*
@param coordinates moves the camera to given coordinates
@param shouldStopFollowLocation This parameter stops follow location in cases
where we don't need to follow the location e.g. edit field or search location
Note: setCamera doesn't work while followLocation is true, so we have to
make it false before using setCamera. And we make it true again in default case
// This callback triggers when the map is moved manually by touch
// So we have to disable follow location
const onTouchMove = () => {
isFollowingUserLocation.current = false;
};
// This useEffect handles the movement of camera while following location
useEffect(() => {
if (isFollowingUserLocation.current && !fieldDetail?.id) {
moveCameraTo(currentPosition.current);
}
}, [currentPosition.current, shouldRenderForcefullyOnUpdate]);
I have made a follow location feature. The camera follows the user if he/she is moving.
During the movement, the onUpdate is triggered but it doesnot uPdates the value in "currentPosition.current".
Instead it passes some previous value in the function which came across the movement.
Expected behavior
"currentPosition.current" must be updated properly and should give the exact current value of "currentPosition.current" whenever the addPoint function is called.
Notes / preliminary analysis
I have also tried this on newer versions (10.1.1 to 10.1.15) and the latest version (10.1.27) but no luck.
When i hanged "minDisplacement" value to 5, it started updating the "curretPosition.current" after moving some meters. But i need that to add that point right where i clicked the button (means right where my current location was displayed)
Additional links and references
No response
The text was updated successfully, but these errors were encountered:
Mapbox Implementation
Mapbox
Mapbox Version
10.17.0
React Native Version
0.70.15
Platform
iOS, Android
@rnmapbox/maps
version10.0.15
Standalone component to reproduce
import { useEffect, useRef, useState } from 'react';
import { Platform } from 'react-native';
import MapboxGL, { UserLocationRenderMode } from '@rnmapbox/maps';
import { MapState } from '@rnmapbox/maps/lib/typescript/components/MapView';
import { area } from '@turf/turf';
import { isEmpty } from 'lodash';
import { useTranslation } from 'react-i18next';
import {
SearchIcon,
CurrentLocationIcon,
HelpCircleIcon,
ResetIcon,
OnePinIcon,
} from '@ricultx/assets';
import { ConfirmationModal } from '@ricultx/components/Farmer';
import { OutOfAreaModal, WhitePointer } from '@ricultx/components/Field';
import {
DistanceLabels,
NearbyFields,
PolygonDrawing,
PolygonJoints,
MAP_STYLE_SATELLITE,
} from '@ricultx/components/MapComponents';
import { drawFieldNearbyFieldFillLayerStyle } from '@ricultx/components/MapComponents/NearbyBoundaries/NearbyBoundaries.styled';
import {
SearchLocationsHandler,
SearchLocations,
} from '@ricultx/components/SearchLocations';
import { SVGImage } from '@ricultx/components/SVGImage';
import useOrgSpecificConfig from '@ricultx/pattern/ui/hooks/useOrgSpecificConfig';
import { getIsConnected } from '@ricultx/store/nodes/networking';
import {
useDeleteRecentUserSearchesMutation,
useSaveRecentUserSearchMutation,
} from '@ricultx/store/nodes/userSearch';
import { useSelector } from '@ricultx/store/root';
import { useCountryData } from '@ricultx/store/utils';
import { useModalVisible } from '@ricultx/utils/hooks';
import {
mapStyle,
OptionsContainer,
HelpTextContainer,
TopOptions,
TopOptionItem,
CustomControl,
HelpTextStyle,
AreaTextContainer,
} from './DrawFieldFeature.styled';
import { DrawFieldFeatureProps } from './DrawFieldFeature.types';
import { MapButtons } from './MapButtons';
import { useMapDrawing } from './useMapDrawing';
/**
*
*/
export const DrawFieldFeature = ({
onPressHelpIcon,
isModalVisible,
onModalCancel,
onModalConfirm,
...params
}: Required) => {
// Hooks
const {
polygons,
onPressAddPoint,
onDragPoint,
onPressUndo,
onPressFinish,
setPolygons,
isOutOFAreaModalVisible,
setIsOutOFAreaModalVisible,
isOverlapping,
isFinishDrawing,
fieldDetail,
isFetchingRecentFieldSearches,
recentFieldSearches,
setRecentFieldSearches,
nearbyFieldsCollection,
onRegionChange,
viewportCoordinates,
isFieldAreaInRange,
helpTextMessage,
isAddPointButtonDisable,
isPolygonInvalid,
onConfirmedReset,
isOnePinButtonDisabled,
onOnePinPress,
onePinFarmCreateConfig,
fieldArea,
setFieldArea,
} = useMapDrawing(params);
const {
country: {
fallbackCoordinates: { lat, lng },
},
helperFunctions,
} = useCountryData();
const isConnected = useSelector(getIsConnected);
const { field_draw_map_style } = useOrgSpecificConfig();
const { isResetModalVisible, showResetModal, hideResetModal } =
useModalVisible('reset');
const { isRedrawModalVisible, showRedrawModal, hideRedrawModal } =
useModalVisible('redraw');
const searchRef = useRef(null);
const { t } = useTranslation('translation', {
keyPrefix: 'portfolio_page.field.fields',
});
const mapViewRef = useRef<MapboxGL.MapView>(null);
const cameraRef = useRef<MapboxGL.Camera>(null);
const currentPosition = useRef<number[] | null>(null);
const currentSpeed = useRef(5);
const [isLocationFetched, setLocationFetched] = useState(false);
// Moving to current location is handled by enabling isFollowingUserLocation
const isFollowingUserLocation = useRef(true);
/*
1. This state is forcefully rendering the moveCameraTo function while onUpdate is triggered
2. onUpdate doesn't update the value in currentPosition
3. To update it, the component needs to be rerendered
4. Its a quick-fix for now, we'll update the library to see if that
works fine with built-in follow location according to our requirements
*/
const [shouldRenderForcefullyOnUpdate, setShouldRenderForcefullyOnUpdate] =
useState(false);
const [deleteRecentFieldSearches] = useDeleteRecentUserSearchesMutation();
const [saveRecentFieldSearch] = useSaveRecentUserSearchMutation();
// Function to open bottom sheet
const handleSearchSheet = () => {
isFollowingUserLocation.current = false;
searchRef?.current?.openBottomSheet?.();
};
const hideModal = () => {
setIsOutOFAreaModalVisible(false);
};
const onPressResetIcon = () => {
showResetModal();
};
const onPressRedrawFinish = () => {
showRedrawModal();
};
// Function to handle modal confirm button press
const onPressOk = () => {
setPolygons([]);
hideModal();
};
// Runs when current field to edit is changed in edit field flow
useEffect(() => {
if (fieldDetail?.boundary_status === 'incomplete') {
setPolygons([fieldDetail?.boundaries?.coordinates[0][0]] || []);
}
setPolygons(fieldDetail?.boundaries?.coordinates[0] || []);
if (fieldDetail?.boundaries) {
setFieldArea(
helperFunctions.toFormattedArea(area(fieldDetail?.boundaries))
);
}
}, [fieldDetail?.id]);
/**
*
*/
const moveCameraTo = (coordinates) => {
cameraRef.current?.setCamera({
centerCoordinate: coordinates,
zoomLevel: 17,
animationDuration: 1500,
});
};
/**
*/
async function getLocationPermission() {
if (Platform.OS === 'android') {
MapboxGL.requestAndroidLocationPermissions().then((isGranted) => {
if (isGranted && mapViewRef.current && currentPosition.current) {
setLocationFetched(true);
moveCameraTo(currentPosition.current);
} else {
moveCameraTo([lng, lat]);
}
});
} else if (
Platform.OS === 'ios' &&
mapViewRef.current &&
currentPosition.current
) {
setLocationFetched(true);
moveCameraTo(currentPosition.current);
}
}
const onPressDeleteRecentFieldSearch = async () => {
await deleteRecentFieldSearches({ search_feature_type: 'portfolio_field' });
setRecentFieldSearches([]);
};
const onRegionIsChanging = (state: MapState) => {
onRegionChange(state.properties.center);
};
const addPoint = () => {
onPressAddPoint(currentPosition.current ?? [0, 0]);
};
const saveRecentSearch = async (query) => {
const payload = {
search_query: query,
search_feature_type: 'portfolio_field',
};
};
const setSelectedCoordinates = ({ lat, lng, query }) => {
saveRecentSearch(query);
moveCameraTo([lng, lat]);
};
// This callback triggers when the map is moved manually by touch
// So we have to disable follow location
const onTouchMove = () => {
isFollowingUserLocation.current = false;
};
useEffect(() => {
if (isEmpty(fieldDetail)) {
getLocationPermission();
} else {
moveCameraTo(fieldDetail?.boundaries?.coordinates[0][0]);
}
}, [mapViewRef.current, fieldDetail?.id]);
// This useEffect handles the movement of camera while following location
useEffect(() => {
if (isFollowingUserLocation.current && !fieldDetail?.id) {
moveCameraTo(currentPosition.current);
}
}, [currentPosition.current, shouldRenderForcefullyOnUpdate]);
const onConfirmReset = () => {
onConfirmedReset();
hideResetModal();
};
const onConfirmRedraw = () => {
hideRedrawModal();
onPressFinish();
};
return (
<>
<MapboxGL.MapView
ref={mapViewRef}
style={mapStyle.default}
onCameraChanged={onRegionIsChanging}
logoEnabled={false}
attributionEnabled={false}
styleURL={isConnected ? field_draw_map_style : MAP_STYLE_SATELLITE}
onTouchMove={onTouchMove}
>
<MapboxGL.Camera
ref={cameraRef}
allowUpdates
animationMode="flyTo"
zoomLevel={17}
followZoomLevel={17}
defaultSettings={{
zoomLevel: 17,
centerCoordinate: currentPosition.current ?? [lng, lat],
}}
/>
<MapboxGL.UserLocation
minDisplacement={1}
animated
androidRenderMode="gps"
showsUserHeadingIndicator
renderMode={UserLocationRenderMode.Native}
onUpdate={({ coords: { longitude, latitude } }) => {
const newCords = [longitude, latitude];
if (!currentPosition.current) {
if (fieldDetail?.id) {
moveCameraTo(fieldDetail.center_point);
} else {
moveCameraTo(newCords);
}
}
currentPosition.current = newCords;
setShouldRenderForcefullyOnUpdate((prev) => !prev);
setLocationFetched(true);
}}
/>
</MapboxGL.MapView>
<HelpTextContainer
type={
isOutOFAreaModalVisible
? 'out_of_area'
: isOverlapping
? 'overlapping_boundary'
: !isFieldAreaInRange
? 'out_of_range'
: 'normal'
}
>
{t(helpTextMessage)}
{!isFinishDrawing && fieldArea && (
{t('field_area_message', {
fieldArea,
})}
)}
<TopOptionItem
onPress={() => {
isFollowingUserLocation.current = true;
moveCameraTo(currentPosition.current);
}}
>
{!fieldDetail?.id && onePinFarmCreateConfig.enabled && (
<SVGImage
SVG={OnePinIcon}
color={isOnePinButtonDisabled ? 'disabled' : 'primary'}
height={20}
width={20}
/>
)}
<TopOptionItem
onPress={onPressResetIcon}
disabled={polygons.length === 0 || isFinishDrawing}
>
0 && isFinishDrawing ? 'disabled' : 'primary'
}
/>
<MapButtons
polygons={polygons}
onPressFinish={
fieldDetail?.id && !isFinishDrawing
? onPressRedrawFinish
: onPressFinish
}
onPressAddPoint={addPoint}
onPressUndo={onPressUndo}
isFinishDrawing={isFinishDrawing}
isFinishButtonDisable={isPolygonInvalid || !isFieldAreaInRange}
isAddPointButtonDisable={isAddPointButtonDisable || !isLocationFetched}
/>
{!isFetchingRecentFieldSearches && (
<SearchLocations
ref={searchRef}
onBackDropCloseHandler={() => {
isFollowingUserLocation.current = true;
}}
searchedHistory={recentFieldSearches}
clearHistory={onPressDeleteRecentFieldSearch}
getSelectedLocationCoordinates={(latLngQuery) => {
setSelectedCoordinates(latLngQuery);
}}
/>
)}
<ConfirmationModal
isVisible={!!(fieldDetail?.id && isRedrawModalVisible)}
onCancelPress={hideRedrawModal}
onConfirmPress={onConfirmRedraw}
confirmButtonKey="proceed"
headingKey="redraw_confirmation"
descriptionKey="redraw_warning_text"
/>
</>
);
};
Observed behavior and steps to reproduce
I have made a follow location feature. The camera follows the user if he/she is moving.
During the movement, the onUpdate is triggered but it doesnot uPdates the value in "currentPosition.current".
Instead it passes some previous value in the function which came across the movement.
Expected behavior
"currentPosition.current" must be updated properly and should give the exact current value of "currentPosition.current" whenever the addPoint function is called.
Notes / preliminary analysis
I have also tried this on newer versions (10.1.1 to 10.1.15) and the latest version (10.1.27) but no luck.
When i hanged "minDisplacement" value to 5, it started updating the "curretPosition.current" after moving some meters. But i need that to add that point right where i clicked the button (means right where my current location was displayed)
Additional links and references
No response
The text was updated successfully, but these errors were encountered: