feat: add configurable max zoom level to prevent precision drifting
Pyxis/fieldnotes/pipeline/head This commit is unstable Details

see #16
This commit is contained in:
wpetit 2021-11-04 16:42:22 +01:00
parent 936b7fb38c
commit 26959540d1
5 changed files with 41 additions and 18 deletions

View File

@ -22,7 +22,8 @@ const styles = {
const transforms = {
bssidFilter: value => value.split(',').map(trim),
orionBaseURL: value => value.replace(/\/+$/, '').trim()
orionBaseURL: value => value.replace(/\/+$/, '').trim(),
maxZoomLevel: value=> parseInt(value.trim())
};
class SettingScreen extends React.Component {
@ -70,6 +71,13 @@ class SettingScreen extends React.Component {
name="autoFollow"
defaultValue={settings.autoFollow}
form={form} />
<TextField
label="Niveau de zoom maximum sur la carte (-1 pour désactiver)"
name="maxZoomLevel"
inputProps={{keyboardType: 'numeric'}}
defaultValue={settings.maxZoomLevel}
form={form}
/>
<CheckboxField
label="Utiliser le GPS du terminal (mode démo)"
name="useNotebookGPS"

View File

@ -18,9 +18,6 @@ import { FeatureCollectionCallout } from './FeatureCollectionCallout';
import * as Sentry from '@sentry/react-native';
import RNFS from 'react-native-fs';
import { Site, SitePlan } from '../../store/reducers/sites';
// @ts-ignore
import { Position } from '@turf/helpers';
import plan from '../../util/plan';
Mapbox.setAccessToken(MAPBOX_ACCESS_TOKEN);
@ -98,6 +95,7 @@ export interface CollectMapProps {
site: Site
autoFollow: boolean
mapStyle?: any
maxZoomLevel: number
}
export interface PressedFeaturesState {
@ -148,7 +146,7 @@ const useSiteBounds = (site: Site) => {
return bounds;
};
export const CollectMap:FunctionComponent<CollectMapProps> = ({ site, autoFollow, mapStyle }) => {
export const CollectMap:FunctionComponent<CollectMapProps> = ({ site, autoFollow, mapStyle, maxZoomLevel }) => {
const [, setDidInitialFocus ] = useState(false);
const [ pressedFeatures, setPressedFeatures ] = useState<PressedFeaturesState>({
featureCollection: null,
@ -296,9 +294,10 @@ export const CollectMap:FunctionComponent<CollectMapProps> = ({ site, autoFollow
rotateEnabled={false}
onPress={onPress as any}
onWillStartRenderingFrame={onWillStartRenderingFrame}
surfaceView={true}
pitchEnabled={false}>
<Mapbox.Images images={{module: moduleIcon}} />
<Mapbox.Camera ref={cameraRef} />
<Mapbox.Images images={{module: moduleIcon}} needsOffscreenAlphaCompositing={true} />
<Mapbox.Camera ref={cameraRef} needsOffscreenAlphaCompositing={true} maxZoomLevel={maxZoomLevel !== -1 ? maxZoomLevel : undefined} />
<PlanLayer plan={site.plan} />
<EntitiesLayer entities={state.entities} />
<MarkerLayer
@ -393,8 +392,8 @@ const MarkerLayer: FunctionComponent<MarkerLayerProps> = (props) => {
}
return (
<Mapbox.ShapeSource id="markerCollection" shape={{type:'FeatureCollection', features}}>
<Mapbox.SymbolLayer id="markerIcons" aboveLayerID={'entitiesLine'} style={styles.icon as any} />
<Mapbox.ShapeSource id="markerCollection" shape={{type:'FeatureCollection', features}} needsOffscreenAlphaCompositing={true}>
<Mapbox.SymbolLayer id="markerIcons" aboveLayerID={'entitiesLine'} style={styles.icon as any} needsOffscreenAlphaCompositing={true} />
</Mapbox.ShapeSource>
);
};
@ -432,9 +431,11 @@ const RasterPlan:FunctionComponent<RasterPlanProps> = ({ plan }) => {
<Mapbox.ImageSource
key="planSource"
id="planSource"
needsOffscreenAlphaCompositing={true}
coordinates={coordinates as any}
url={`file://${plan.path}`}>
<Mapbox.RasterLayer
needsOffscreenAlphaCompositing={true}
id="planLayer" sourceID="planSource" />
</Mapbox.ImageSource>
</Fragment>
@ -601,10 +602,10 @@ const EntitiesLayer:FunctionComponent<EntitiesLayerProps> = ({ entities }) => {
}, [entities.length]);
return (
<Mapbox.ShapeSource id="entitiesCollection" shape={featureCollection}>
<Mapbox.FillLayer id="entitiesRect" style={styles.vector as any} filter={["==", ["get", "type"], TypeRect]} />
<Mapbox.CircleLayer id="entitiesCircle" style={styles.vector as any} filter={["==", ["get", "type"], TypeCircle]} />
<Mapbox.LineLayer id="entitiesLine" style={styles.vector as any} filter={["any", ["==", ["get", "type"], TypeLine], ["==", ["get", "type"], TypeCurve]]} />
<Mapbox.ShapeSource id="entitiesCollection" shape={featureCollection} needsOffscreenAlphaCompositing={true}>
<Mapbox.FillLayer id="entitiesRect" style={styles.vector as any} filter={["==", ["get", "type"], TypeRect]} needsOffscreenAlphaCompositing={true}/>
<Mapbox.CircleLayer id="entitiesCircle" style={styles.vector as any} filter={["==", ["get", "type"], TypeCircle]} needsOffscreenAlphaCompositing={true}/>
<Mapbox.LineLayer id="entitiesLine" style={styles.vector as any} filter={["any", ["==", ["get", "type"], TypeLine], ["==", ["get", "type"], TypeCurve]]} needsOffscreenAlphaCompositing={true}/>
</Mapbox.ShapeSource>
);
};

View File

@ -93,6 +93,7 @@ export const CollectMapTab:FunctionComponent<CollectMapTabProps> = ({ site }) =>
roverPosition,
useNotebookGPS,
entities,
maxZoomLevel,
} = useSelector((state: RootState) => getCollectMapTabState(state, { siteUUID }))
const [ state, setState ] = useState({
@ -182,9 +183,12 @@ export const CollectMapTab:FunctionComponent<CollectMapTabProps> = ({ site }) =>
<React.Fragment>
<Content contentContainerStyle={{ flexGrow: 1 }}>
<View style={styles.mapContainer}>
<CollectMap mapStyle={styles.mapContainer}
<CollectMap
mapStyle={styles.mapContainer}
site={site}
autoFollow={autoFollow} />
autoFollow={autoFollow}
maxZoomLevel={maxZoomLevel}
/>
</View>
<CollectMode mode={mode} setCollect={c => collect.current = c} />
{

View File

@ -159,6 +159,10 @@ export const selectAutoFollow = (state:RootState) => {
return state.settings.autoFollow;
};
export const selectMaxZoomLevel = (state:RootState) => {
return state.settings.maxZoomLevel;
};
export const selectEntitiesBySite = (state:RootState, props: any) => {
const site: Site = state.sites.byUUID[props.siteUUID];
return selectSiteNomenclatures(state.nomenclatures, site);
@ -179,6 +183,7 @@ export const getCollectMapTabState = createSelector(
selectAutoFollow,
selectEntitiesBySite,
selectUseNotebookGPS,
selectMaxZoomLevel,
],
(
canCollect,
@ -193,6 +198,7 @@ export const getCollectMapTabState = createSelector(
autoFollow,
entities,
useNotebookGPS,
maxZoomLevel
) => {
return {
canCollect,
@ -211,7 +217,8 @@ export const getCollectMapTabState = createSelector(
},
autoFollow,
entities,
useNotebookGPS
useNotebookGPS,
maxZoomLevel
};
}
);

View File

@ -13,6 +13,7 @@ const defaultState = {
requiredPositioningStatus: 'fix',
preferredProjection: Projections[0],
apiKey: '',
maxZoomLevel: 20,
};
export default function settingsReducer(state = defaultState, action) {
@ -25,7 +26,8 @@ export default function settingsReducer(state = defaultState, action) {
orionBaseURL,
requiredPositioningStatus,
preferredProjection,
apiKey
apiKey,
maxZoomLevel
} = action.payload.settings;
return {
...state,
@ -35,8 +37,9 @@ export default function settingsReducer(state = defaultState, action) {
orionBaseURL,
requiredPositioningStatus,
bssidFilter: [...new Set([...state.bssidFilter ,...bssidFilter])],
preferredProjection,
preferredProjection: preferredProjection === undefined ? Projections[0] : preferredProjection,
apiKey,
maxZoomLevel: maxZoomLevel === undefined ? defaultState.maxZoomLevel : maxZoomLevel,
};
case UPDATE_SETTING:
return {