@mapcomponents/react-maplibre 0.1.80 → 0.1.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Change Log
2
2
 
3
- ## [v0.1.8] - 2023-06-01
3
+ ## [v0.1.81] - 2023-06-12
4
+
5
+ ### Added
6
+
7
+ - 2ba02ba: add useAddProtocol hook
8
+ - 2ba02ba: add mbTilesProtocolHandler
9
+
10
+ ## [v0.1.80] - 2023-06-01
4
11
 
5
12
  ### Added
6
13
 
package/README.md CHANGED
@@ -20,7 +20,7 @@ Use our Codesandbox template to quickly try out this library without any setup r
20
20
 
21
21
  ### **... a new project**
22
22
 
23
- The easiest way to start a new project using this framework is to bootstrap a react application using our [create-react-app-template](https://github.com/mapcomponents/react-map-components-maplibre-cra-template).
23
+ The easiest way to start a new project using this framework is to bootstrap a react application using our [vite-template](https://github.com/mapcomponents/template).
24
24
 
25
25
  **Requirements:**
26
26
 
@@ -29,12 +29,12 @@ The easiest way to start a new project using this framework is to bootstrap a re
29
29
 
30
30
  Run the following commands in the terminal:
31
31
 
32
- 1. `npx create-react-app {your-app-name} --template @mapcomponents/cra-template`
32
+ 1. `npx degit mapcomponents/template {your-app-name}`
33
33
  2. `cd {your-app-name}`
34
34
  3. `yarn`
35
- 4. `yarn start`
35
+ 4. `yarn dev`
36
36
 
37
- This will start a development server that serves the mapcomponents app on port 3000 of your local machine as well as a browser tab with live reload enabled. This reloads the affected parts of the application if changes are detected to the corresponding files in the filesystem. Open the project folder in the IDE of your choice and start building your map client.
37
+ This will start a development server that serves the mapcomponents app on port 5174 of your local machine as well as a browser tab with live reload enabled. This reloads the affected parts of the application if changes are detected to the corresponding files in the filesystem. Open the project folder in the IDE of your choice and start building your map client.
38
38
 
39
39
  ### **... an existing react project**
40
40
 
@@ -0,0 +1,23 @@
1
+ import { Cancelable, RequestParameters, ResponseCallback } from 'maplibre-gl';
2
+ export interface useAddProtocolProps {
3
+ /**
4
+ * the protocol string, for example `mbtiles`
5
+ * In this example the handler function is called for all tile requests that start with the string `mbtiles://`
6
+ */
7
+ protocol: string;
8
+ /**
9
+ * Custom load tile function that will be called when using a source that starts with a custom url schema.
10
+ */
11
+ handler: (requestParameters: RequestParameters, callback: ResponseCallback<any>) => Cancelable;
12
+ }
13
+ /**
14
+ * Enables the use of custom protocols (basically custom tile load functions) in the maplibre-gl-js library.
15
+ *
16
+ */
17
+ declare const useAddProtocol: {
18
+ (props: useAddProtocolProps): {};
19
+ defaultProps: {
20
+ mapId: undefined;
21
+ };
22
+ };
23
+ export default useAddProtocol;
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ declare const storyoptions: {
3
+ title: string;
4
+ component: {
5
+ (props: import("./useAddProtocol").useAddProtocolProps): {};
6
+ defaultProps: {
7
+ mapId: undefined;
8
+ };
9
+ };
10
+ argTypes: {};
11
+ decorators: ((Story: any, context: any) => JSX.Element)[];
12
+ };
13
+ export default storyoptions;
14
+ export declare const ExampleConfig: any;
package/dist/index.d.ts CHANGED
@@ -49,6 +49,8 @@ export { default as useWms } from "./hooks/useWms";
49
49
  export { default as useFilterData } from "./components/MlTemporalController/utils/useFilterData";
50
50
  export { default as useLayerContext } from "./hooks/useLayerContext";
51
51
  export { default as useFeatureEditor } from "./hooks/useFeatureEditor";
52
+ export { default as useAddProtocol } from "./hooks/useAddProtocol/useAddProtocol";
53
+ export { mbTilesProtocolHandler } from "./protocol_handlers/mbtiles";
52
54
  export { MapComponentsProvider } from "./contexts/MapContext";
53
55
  export { default as MapContext } from "./contexts/MapContext";
54
56
  export { default as SimpleDataProvider } from "./contexts/SimpleDataProvider";
package/dist/index.esm.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var maplibreGl = require('maplibre-gl');
5
+ var maplibregl = require('maplibre-gl');
6
6
  var React = require('react');
7
7
  var styles = require('@mui/material/styles');
8
8
  var uuid = require('uuid');
@@ -46,6 +46,8 @@ var PauseIcon = require('@mui/icons-material/Pause');
46
46
  var StopIcon = require('@mui/icons-material/Stop');
47
47
  var FastForwardIcon = require('@mui/icons-material/FastForward');
48
48
  var FastRewindIcon = require('@mui/icons-material/FastRewind');
49
+ var initSqlJs = require('sql.js');
50
+ var pako = require('pako');
49
51
  var d3 = require('d3');
50
52
  var TuneIcon = require('@mui/icons-material/Tune');
51
53
  var reactColor = require('react-color');
@@ -90,6 +92,7 @@ function _interopNamespace(e) {
90
92
  return Object.freeze(n);
91
93
  }
92
94
 
95
+ var maplibregl__default = /*#__PURE__*/_interopDefaultLegacy(maplibregl);
93
96
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
94
97
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
95
98
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
@@ -126,6 +129,8 @@ var PauseIcon__default = /*#__PURE__*/_interopDefaultLegacy(PauseIcon);
126
129
  var StopIcon__default = /*#__PURE__*/_interopDefaultLegacy(StopIcon);
127
130
  var FastForwardIcon__default = /*#__PURE__*/_interopDefaultLegacy(FastForwardIcon);
128
131
  var FastRewindIcon__default = /*#__PURE__*/_interopDefaultLegacy(FastRewindIcon);
132
+ var initSqlJs__default = /*#__PURE__*/_interopDefaultLegacy(initSqlJs);
133
+ var pako__namespace = /*#__PURE__*/_interopNamespace(pako);
129
134
  var d3__namespace = /*#__PURE__*/_interopNamespace(d3);
130
135
  var TuneIcon__default = /*#__PURE__*/_interopDefaultLegacy(TuneIcon);
131
136
  var ArrowCircleDownIcon__default = /*#__PURE__*/_interopDefaultLegacy(ArrowCircleDownIcon);
@@ -738,7 +743,7 @@ var MapLibreGlWrapper = /** @class */ (function () {
738
743
  _a.sent();
739
744
  _a.label = 2;
740
745
  case 2:
741
- self.map = new maplibreGl.Map(props.mapOptions);
746
+ self.map = new maplibregl.Map(props.mapOptions);
742
747
  self.addNativeMaplibreFunctionsAndProps();
743
748
  self.wrapper.refreshViewport();
744
749
  self.wrapper.fire('viewportchange');
@@ -1439,7 +1444,7 @@ var createExport = function (options) {
1439
1444
  _loop_1(name_1);
1440
1445
  }
1441
1446
  // Create a new MapLibre-gl instance
1442
- var renderMap = new maplibreGl.Map({
1447
+ var renderMap = new maplibregl.Map({
1443
1448
  container: container,
1444
1449
  center: options.map.map.getCenter(),
1445
1450
  zoom: options.map.map.getZoom(),
@@ -4191,7 +4196,7 @@ var useLayerHoverPopup = function (props) {
4191
4196
  mapId: props.mapId,
4192
4197
  waitForLayer: props.layerId,
4193
4198
  });
4194
- var popup = React.useRef(new maplibreGl.Popup({
4199
+ var popup = React.useRef(new maplibregl.Popup({
4195
4200
  closeButton: false,
4196
4201
  closeOnClick: true,
4197
4202
  }));
@@ -6188,6 +6193,147 @@ var useLayerContext = function () {
6188
6193
  return layerContext;
6189
6194
  };
6190
6195
 
6196
+ /**
6197
+ * Enables the use of custom protocols (basically custom tile load functions) in the maplibre-gl-js library.
6198
+ *
6199
+ */
6200
+ var useAddProtocol = function (props) {
6201
+ React.useEffect(function () {
6202
+ if (!props.protocol || typeof props.handler !== 'function')
6203
+ return;
6204
+ maplibregl__default["default"].addProtocol(props.protocol, props.handler);
6205
+ return function () {
6206
+ maplibregl__default["default"].removeProtocol(props.protocol);
6207
+ };
6208
+ }, []);
6209
+ return {};
6210
+ };
6211
+ useAddProtocol.defaultProps = {
6212
+ mapId: undefined,
6213
+ };
6214
+
6215
+ var loadedMbtiles = {};
6216
+ var parseParams = function (url) {
6217
+ var urlParts = url.split('://');
6218
+ var mbtilesUrl = urlParts[1];
6219
+ var mbtilesParts = mbtilesUrl.split('/');
6220
+ var mbtilesPartsLength = mbtilesParts.length;
6221
+ var y = mbtilesParts.splice(mbtilesPartsLength - 1, 1)[0];
6222
+ var x = mbtilesParts.splice(mbtilesPartsLength - 2, 1)[0];
6223
+ var z = mbtilesParts.splice(mbtilesPartsLength - 3, 1)[0];
6224
+ var filename = mbtilesParts.join('/');
6225
+ return {
6226
+ filename: filename,
6227
+ z: z,
6228
+ x: x,
6229
+ y: y,
6230
+ };
6231
+ };
6232
+ // mbtiles files are sqlite databases. This function loads the database and returns a handler
6233
+ // to work with sqlite databases in javascript we need to use sql.js.
6234
+ // to make this work in your project make sure to copy sql-wasm.wasm to the file root of your public folder and
6235
+ // add the following config to the externals prop of your webpack config
6236
+ // {externals: { fs: 'fs' }};
6237
+ var getMbtilesDbHandler = function (_a) {
6238
+ var filename = _a.filename;
6239
+ return __awaiter(void 0, void 0, void 0, function () {
6240
+ var SQL, fetched, buf, db;
6241
+ return __generator(this, function (_b) {
6242
+ switch (_b.label) {
6243
+ case 0:
6244
+ if (!!loadedMbtiles[filename]) return [3 /*break*/, 4];
6245
+ return [4 /*yield*/, initSqlJs__default["default"]()];
6246
+ case 1:
6247
+ SQL = _b.sent();
6248
+ return [4 /*yield*/, fetch(filename)];
6249
+ case 2:
6250
+ fetched = _b.sent();
6251
+ return [4 /*yield*/, fetched.arrayBuffer()];
6252
+ case 3:
6253
+ buf = _b.sent();
6254
+ db = new SQL.Database(new Uint8Array(buf));
6255
+ loadedMbtiles[filename] = db;
6256
+ _b.label = 4;
6257
+ case 4: return [2 /*return*/, loadedMbtiles[filename]];
6258
+ }
6259
+ });
6260
+ });
6261
+ };
6262
+ /**
6263
+ * Example usage:
6264
+ * getBufferFromMbtiles({ filename: 'mbtiles/countries.mbtiles', z: '0', x: '0', y: '0' }).then(
6265
+ * (result) => {
6266
+ * console.log(result);
6267
+ * }
6268
+ * );
6269
+ */
6270
+ function getBufferFromMbtiles(params) {
6271
+ return __awaiter(this, void 0, void 0, function () {
6272
+ var db, query;
6273
+ return __generator(this, function (_a) {
6274
+ switch (_a.label) {
6275
+ case 0: return [4 /*yield*/, getMbtilesDbHandler(params)];
6276
+ case 1:
6277
+ db = _a.sent();
6278
+ query = 'SELECT tile_data FROM tiles WHERE zoom_level = ' +
6279
+ params.z +
6280
+ ' AND tile_column = ' +
6281
+ params.x +
6282
+ ' AND tile_row = ' +
6283
+ (Math.pow(2, parseInt(params.z)) - parseInt(params.y) - 1);
6284
+ return [2 /*return*/, new Promise(function (resolve, reject) {
6285
+ try {
6286
+ // some of the logic here was heavily inspired by
6287
+ // https://github.com/IsraelHikingMap/Site/blob/6aa2ec0cfb8891fa048b1d9e2a4fc7d4cbcc8c97/IsraelHiking.Web/src/application/services/database.service.ts
6288
+ var result = db.exec(query);
6289
+ if (result.length !== 1) {
6290
+ reject(new Error('Tile not found.'));
6291
+ return;
6292
+ }
6293
+ var resultData = result[0].values[0][0];
6294
+ var binData = void 0;
6295
+ var isGzipped = resultData[0] === 0x1f && resultData[1] === 0x8b;
6296
+ if (isGzipped) {
6297
+ binData = pako__namespace.inflate(resultData);
6298
+ }
6299
+ else {
6300
+ binData = resultData;
6301
+ }
6302
+ if (binData === null || binData === void 0 ? void 0 : binData.buffer) {
6303
+ resolve(binData.buffer);
6304
+ }
6305
+ else {
6306
+ reject(new Error('Tile not found.'));
6307
+ return;
6308
+ }
6309
+ }
6310
+ catch (error) {
6311
+ reject(error);
6312
+ }
6313
+ })];
6314
+ }
6315
+ });
6316
+ });
6317
+ }
6318
+ /**
6319
+ * Expects a tile url in the following format:
6320
+ *
6321
+ * 'mbtiles://mbtiles/countries.mbtiles/{z}/{x}/{y}'
6322
+ */
6323
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6324
+ var mbTilesProtocolHandler = function (params, callback) {
6325
+ var parsedParams = parseParams(params.url);
6326
+ getBufferFromMbtiles(parsedParams).then(function (result) {
6327
+ if (result) {
6328
+ callback(null, result, null, null);
6329
+ }
6330
+ else {
6331
+ callback(new Error('Tile not found'));
6332
+ }
6333
+ });
6334
+ return { cancel: function () { } };
6335
+ };
6336
+
6191
6337
  var SimpleDataContext = /*#__PURE__*/React__default["default"].createContext({});
6192
6338
  var SimpleDataContextProvider = SimpleDataContext.Provider;
6193
6339
 
@@ -19932,6 +20078,8 @@ exports.TopToolbar = TopToolbar;
19932
20078
  exports.UploadButton = UploadButton;
19933
20079
  exports.WmsLayerForm = WmsLayerForm;
19934
20080
  exports.getTheme = getTheme;
20081
+ exports.mbTilesProtocolHandler = mbTilesProtocolHandler;
20082
+ exports.useAddProtocol = useAddProtocol;
19935
20083
  exports.useCameraFollowPath = useCameraFollowPath;
19936
20084
  exports.useExportMap = useExportMap;
19937
20085
  exports.useFeatureEditor = useFeatureEditor;