react-native-mapsforge-vtm
Version:
React Native components to build vector maps using Mapsforges fork of vtm. Offline rendering of OpenStreetMap data. Android only
150 lines (148 loc) • 4.55 kB
JavaScript
;
/**
* External dependencies
*/
import { useEffect, useState } from 'react';
/**
* Internal dependencies
*/
import useRefState from "../compose/useRefState.js";
import promiseQueue from "../promiseQueue.js";
import { MapLayerPathModule } from "../nativeMapModules.js";
import { NativeEventEmitter } from 'react-native';
const Module = MapLayerPathModule;
;
;
// 0 never include in response.
// 1 include in response on create.
// 2 include in response on change.
const responseIncludeDefaults = {
coordinates: 0,
bounds: 0
};
const defaultStyle = {
strokeWidth: 4,
strokeColor: '#ff0000'
};
const LayerPath = ({
nativeNodeHandle,
positions = [],
filePath,
responseInclude = responseIncludeDefaults,
gestureScreenDistance = 20,
reactTreeIndex,
style = defaultStyle,
simplificationTolerance = 0,
onCreate,
onRemove,
onChange,
onError,
onPress,
onLongPress,
onDoubleTap,
onTrigger
}) => {
// @ts-ignore
const [random, setRandom] = useState(0);
const [uuid, setUuid] = useRefState(null);
const [triggerCreateNew, setTriggerCreateNew] = useState(null);
positions = positions || [];
responseInclude = {
...responseIncludeDefaults,
...responseInclude
};
style = {
...defaultStyle,
...style
};
const supportsGestures = !!onPress || !!onLongPress || !!onDoubleTap;
const createLayer = () => {
setUuid(false);
promiseQueue.enqueue(() => {
return Module.createLayer(nativeNodeHandle, positions, filePath, style, responseInclude, !!supportsGestures, gestureScreenDistance, simplificationTolerance, reactTreeIndex).then(response => {
setUuid(response.uuid);
setRandom(Math.random());
null === triggerCreateNew ? onCreate ? onCreate(response) : null : onChange ? onChange(response) : null;
}).catch(err => {
console.log('ERROR', err);
onError ? onError(err) : null;
});
});
};
useEffect(() => {
if (uuid === null && nativeNodeHandle && (filePath || positions.length > 0)) {
createLayer();
}
return () => {
if (uuid && nativeNodeHandle) {
promiseQueue.enqueue(() => {
return Module.removeLayer(nativeNodeHandle, uuid).then(removedUuid => {
onRemove ? onRemove({
uuid: removedUuid
}) : null;
}).catch(err => {
console.log('ERROR', err);
onError ? onError(err) : null;
});
});
}
};
}, [nativeNodeHandle, !!uuid, triggerCreateNew]);
useEffect(() => {
if (nativeNodeHandle && uuid) {
promiseQueue.enqueue(() => {
return Module.updateStyle(nativeNodeHandle, uuid, style, responseInclude).then(response => {
onChange ? onChange(response) : null;
}).catch(err => {
console.log('ERROR', err);
onError ? onError(err) : null;
});
});
}
}, [Object.values(style).join('')]);
useEffect(() => {
if (nativeNodeHandle) {
if (uuid) {
promiseQueue.enqueue(() => {
return Module.removeLayer(nativeNodeHandle, uuid).then(() => {
setUuid(null);
setTriggerCreateNew(Math.random());
}).catch(err => {
console.log('ERROR', err);
onError ? onError(err) : null;
});
});
} else if (uuid === null && (filePath || positions.length > 0)) {
setTriggerCreateNew(Math.random());
}
}
}, [positions.length > 0 ? [...positions].map(pos => pos.lng + pos.lat).join('') : null, simplificationTolerance, filePath, Object.keys(responseInclude).map(key => key + responseInclude[key]).join('')]);
useEffect(() => {
const eventEmitter = new NativeEventEmitter();
let eventListener = eventEmitter.addListener('PathGesture', response => {
if (response.uuid === uuid) {
switch (response.type) {
case 'doubleTap':
onDoubleTap ? onDoubleTap(response) : null;
break;
case 'LongPress':
onLongPress ? onLongPress(response) : null;
break;
case 'press':
onPress ? onPress(response) : null;
break;
case 'trigger':
onTrigger ? onTrigger(response) : null;
break;
}
}
});
return () => {
eventListener.remove();
};
}, [uuid, !!supportsGestures, onDoubleTap, onLongPress, onPress, onTrigger]);
return null;
};
LayerPath.isMapLayer = true;
export default LayerPath;
//# sourceMappingURL=LayerPath.js.map