diff --git a/packages/map-gl-native/src/components/Map.js b/packages/map-gl-native/src/components/Map.js
index 198de89..c224e72 100644
--- a/packages/map-gl-native/src/components/Map.js
+++ b/packages/map-gl-native/src/components/Map.js
@@ -1,20 +1,16 @@
-import React, { useMemo, useContext, useRef, useCallback } from "react";
+import React, { useMemo, useContext, useRef, useState, useEffect } from "react";
import { MapView, Camera } from "@maplibre/maplibre-react-native";
import { MapContext } from "./MapProvider.js";
import { withWQ } from "@wq/react";
import { useBasemapStyle } from "../hooks.js";
import PropTypes from "prop-types";
-function Map({
- name,
- initBounds,
- children,
- containerStyle,
- basemap,
- ...mapProps
-}) {
+function Map({ initBounds, children, containerStyle, basemap, ...mapProps }) {
const { setInstance } = useContext(MapContext),
fitBounds = useMemo(() => {
+ if (!initBounds) {
+ return null;
+ }
const [[xmin, ymin], [xmax, ymax]] = initBounds;
return { sw: [xmin, ymin], ne: [xmax, ymax] };
}, [initBounds]),
@@ -29,27 +25,12 @@ function Map({
const mapRef = useRef(),
cameraRef = useRef(),
- mapInstance = useMemo(() => createMapInstance(mapRef, cameraRef), []),
- onInit = useCallback(
- () => setInstance(mapInstance, name),
- [setInstance, mapInstance]
- ),
- onPress = useCallback(
- (e) => {
- if (mapInstance.handlers.click) {
- mapInstance.handlers.click(e);
- }
- },
- [mapInstance]
+ [cameraProps, setCameraProps] = useState({}),
+ mapInstance = useMemo(
+ () => createMapInstance(mapRef, cameraRef, setCameraProps),
+ []
),
- onMove = useCallback(
- (e) => {
- if (mapInstance.handlers.move) {
- mapInstance.handlers.move(e);
- }
- },
- [mapInstance]
- );
+ { handleClick, handleMove } = mapInstance;
let rotateEnabled, pitchEnabled;
if (mapProps.rotateEnabled !== undefined) {
@@ -67,6 +48,11 @@ function Map({
pitchEnabled = rotateEnabled;
}
+ useEffect(() => {
+ setInstance(mapInstance);
+ return () => setInstance(null);
+ }, [mapRef.current]);
+
return (
-
+
{children}
);
@@ -98,17 +89,36 @@ Map.propTypes = {
export default withWQ(Map);
// Mimic some functions from maplibre-gl-js & react-map-gl
-export function createMapInstance(mapRef, cameraRef) {
- return {
- handlers: {},
+export function createMapInstance(mapRef, cameraRef, setCameraProps) {
+ const instance = {
+ handlers: {
+ click: [],
+ move: [],
+ },
on(event, handler) {
- if (!["click", "move"].includes(event)) {
+ if (!(event in this.handlers)) {
console.warn("Unsupported event: " + event);
}
- this.handlers[event] = handler;
+ this.handlers[event].push(handler);
},
- off(event) {
- delete this.handlers[event];
+ off(event, handler) {
+ if (!(event in this.handlers)) {
+ console.warn("Unsupported event: " + event);
+ }
+ this.handlers[event] = this.handlers[event].filter(
+ (h) => h !== handler
+ );
+ },
+ _runHandlers(event, e) {
+ for (const handler of this.handlers[event]) {
+ handler(e);
+ }
+ },
+ handleClick(e) {
+ this._runHandlers("click", e);
+ },
+ handleMove(e) {
+ this._runHandlers("move", e);
},
flyTo({ center, zoom }) {
this.getCamera()?.flyTo(center, zoom);
@@ -130,5 +140,11 @@ export function createMapInstance(mapRef, cameraRef) {
getCamera() {
return cameraRef.current;
},
+ setCameraProps,
};
+
+ instance.handleClick = instance.handleClick.bind(instance);
+ instance.handleMove = instance.handleMove.bind(instance);
+
+ return instance;
}
diff --git a/packages/map-gl-web/src/components/MapProvider.js b/packages/map-gl-web/src/components/MapProvider.js
index 4e3b176..b90d477 100644
--- a/packages/map-gl-web/src/components/MapProvider.js
+++ b/packages/map-gl-web/src/components/MapProvider.js
@@ -1,4 +1,27 @@
import { MapProvider } from "react-map-gl/maplibre";
import { withWQ } from "@wq/react";
+import Map from "./Map.js";
+import MapInteraction from "./MapInteraction.js";
+import MapAutoZoom from "./MapAutoZoom.js";
+import MapIdentify from "./MapIdentify.js";
+import HighlightPopup from "./HighlightPopup.js";
+import Geojson from "../overlays/Geojson.js";
+import Tile from "../overlays/Tile.js";
+import VectorTile from "../overlays/VectorTile.js";
+import Highlight from "../overlays/Highlight.js";
-export default withWQ(MapProvider);
+const MapProviderDefaults = {
+ components: {
+ Map,
+ MapInteraction,
+ MapAutoZoom,
+ MapIdentify,
+ HighlightPopup,
+ Geojson,
+ Tile,
+ VectorTile,
+ Highlight,
+ },
+};
+
+export default withWQ(MapProvider, { defaults: MapProviderDefaults });
diff --git a/packages/map/src/components/AutoMap.js b/packages/map/src/components/AutoMap.js
index 7d84560..e44e2e7 100644
--- a/packages/map/src/components/AutoMap.js
+++ b/packages/map/src/components/AutoMap.js
@@ -61,11 +61,11 @@ export const AutoMapDefaults = {
function AutoMap({
name,
mapId,
- toolbar = true,
+ toolbar: Toolbar = true,
toolbarAnchor = "top-right",
containerStyle,
context = {},
- overlays: initialOverlays = [],
+ overlays: initialOverlays = null,
basemaps: initialBasemaps = null,
initBounds: initialInitBounds = null,
tiles: initialTiles = null,
@@ -104,8 +104,9 @@ function AutoMap({
onChangeBasemap,
onChangeOverlays
),
- [state, actions] = reducer,
- {
+ [state, actions] = reducer;
+
+ const {
MapContainer,
MapToolbar,
Map,
@@ -143,26 +144,31 @@ function AutoMap({
const identify = overlays.some((overlay) => !!overlay.popup);
- if (toolbar === true) {
- toolbar = (
-
- );
- } else if (!toolbar) {
- toolbar = false;
- }
+ const toolbar = (() => {
+ const toolbarProps = {
+ name,
+ mapId,
+ basemaps,
+ overlays,
+ showOverlay,
+ hideOverlay,
+ setBasemap,
+ context,
+ anchor: toolbarAnchor,
+ };
+ if (Toolbar === true) {
+ return ;
+ } else if (typeof Toolbar === "function") {
+ return ;
+ } else if (!Toolbar) {
+ return false;
+ } else {
+ return Toolbar;
+ }
+ })();
return (
-
+
{toolbarAnchor.endsWith("left") && toolbar}