Adding docuri's and unit tests.

This commit is contained in:
Eric van der Vlist 2022-10-17 17:15:24 +02:00
parent 0b7de58a4e
commit b3e1e4de73
7 changed files with 135 additions and 6 deletions

27
package-lock.json generated
View File

@ -24,7 +24,9 @@
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@types/react-router": "^5.1.11", "@types/react-router": "^5.1.11",
"@types/react-router-dom": "^5.1.7", "@types/react-router-dom": "^5.1.7",
"docuri": "^4.2.2",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
"lodash": "^4.17.21",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router": "^5.2.0", "react-router": "^5.2.0",
@ -47,7 +49,8 @@
"workbox-streams": "^5.1.4" "workbox-streams": "^5.1.4"
}, },
"devDependencies": { "devDependencies": {
"@capacitor/cli": "4.3.0" "@capacitor/cli": "4.3.0",
"@types/lodash": "^4.14.186"
} }
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
@ -3775,6 +3778,12 @@
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
}, },
"node_modules/@types/lodash": {
"version": "4.14.186",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.186.tgz",
"integrity": "sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==",
"dev": true
},
"node_modules/@types/mime": { "node_modules/@types/mime": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
@ -6356,6 +6365,11 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/docuri": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/docuri/-/docuri-4.2.2.tgz",
"integrity": "sha512-eEtIB7SQAEVO1HC286DlnPnSiddAl+wFv+EeBBQ7VdTEMRplzG4qIhrNdyIecXfVVD9cIghikVVkls1O78EQqQ=="
},
"node_modules/dom-accessibility-api": { "node_modules/dom-accessibility-api": {
"version": "0.5.14", "version": "0.5.14",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz",
@ -18609,6 +18623,12 @@
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
}, },
"@types/lodash": {
"version": "4.14.186",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.186.tgz",
"integrity": "sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==",
"dev": true
},
"@types/mime": { "@types/mime": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
@ -20512,6 +20532,11 @@
"esutils": "^2.0.2" "esutils": "^2.0.2"
} }
}, },
"docuri": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/docuri/-/docuri-4.2.2.tgz",
"integrity": "sha512-eEtIB7SQAEVO1HC286DlnPnSiddAl+wFv+EeBBQ7VdTEMRplzG4qIhrNdyIecXfVVD9cIghikVVkls1O78EQqQ=="
},
"dom-accessibility-api": { "dom-accessibility-api": {
"version": "0.5.14", "version": "0.5.14",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz",

View File

@ -19,7 +19,9 @@
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@types/react-router": "^5.1.11", "@types/react-router": "^5.1.11",
"@types/react-router-dom": "^5.1.7", "@types/react-router-dom": "^5.1.7",
"docuri": "^4.2.2",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
"lodash": "^4.17.21",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router": "^5.2.0", "react-router": "^5.2.0",
@ -66,7 +68,8 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@capacitor/cli": "4.3.0" "@capacitor/cli": "4.3.0",
"@types/lodash": "^4.14.186"
}, },
"description": "An Ionic project" "description": "An Ionic project"
} }

View File

@ -0,0 +1,42 @@
import { render, screen } from '@testing-library/react';
import TiledLayer from './TiledLayer';
describe('The TiledLayer component ', () => {
test('', () => {
// const tiledLayer = renderer.create(
// <TiledLayer
// keyObject={{ provider: 'osm', zoomLevel: 10, x: 5, y: 8 }}
// viewPort={{ topLeft: { x: 1, y: 2 }, bottomRight: { x: 3, y: 2 } }}
// />
// );
// const tree = tiledLayer.toJSON();
// console.log(JSON.stringify(tree));
const { baseElement } = render(
<svg>
<TiledLayer
keyObject={{ provider: 'osm', zoomLevel: 10, x: 5, y: 8 }}
viewPort={{ topLeft: { x: 1, y: 2 }, bottomRight: { x: 3, y: 2 } }}
/>
</svg>
);
screen.debug();
expect(baseElement).toMatchInlineSnapshot(`
<body>
<div>
<svg>
<g
id="tile/osm/10/7/6"
/>
<g
id="tile/osm/10/7/7"
/>
<g
id="tile/osm/10/7/8"
/>
</svg>
</div>
</body>
`);
});
});

View File

@ -1,12 +1,12 @@
import react from 'react'; import react, { useRef } from 'react';
import { range } from 'lodash';
import { Rectangle, TileKeyObject } from './types'; import { Rectangle, TileKeyObject } from './types';
import tileUri from './uris';
export interface TiledLayerProperties { export interface TiledLayerProperties {
/** The key of the first (ie top/left) tile */ /** The key of the first (ie top/left) tile */
keyObject: TileKeyObject; keyObject: TileKeyObject;
/** Number of tiles (in each direction since TiledLayers are square)*/
nbTiles: number;
/** The current viewport expressed in tiles coordinates */ /** The current viewport expressed in tiles coordinates */
viewPort: Rectangle; viewPort: Rectangle;
} }
@ -22,7 +22,28 @@ export interface TiledLayerProperties {
export const TiledLayer: react.FC<TiledLayerProperties> = ( export const TiledLayer: react.FC<TiledLayerProperties> = (
props: TiledLayerProperties props: TiledLayerProperties
) => { ) => {
return <></>; console.log(`Rendering TiledLayer: ${JSON.stringify(props)}`);
const tiles = useRef<any>({});
range(props.viewPort.topLeft.y, props.viewPort.bottomRight.y + 1).map(
(row) => {
range(props.viewPort.topLeft.x, props.viewPort.bottomRight.x + 1).map(
(col) => {
const key = tileUri({
provider: props.keyObject.provider,
zoomLevel: props.keyObject.zoomLevel,
x: props.keyObject.x + row,
y: props.keyObject.x + col,
});
if (!Object.hasOwn(tiles.current, key)) {
tiles.current[key] = <g key={key} id={key} />;
}
}
);
}
);
return <>{Object.values(tiles.current)}</>;
}; };
export default TiledLayer; export default TiledLayer;

View File

@ -0,0 +1,16 @@
import tileUri from './uris';
describe('Test that', () => {
test('uri generation is working', () => {
expect(tileUri({ provider: 'osm', zoomLevel: 16, x: 25, y: 52 })).toEqual(
'tile/osm/16/25/52'
);
});
test('uri parsing works', () => {
expect(tileUri('tile/otm/5/28/3')).toEqual({
provider: 'otm',
zoomLevel: 5,
x: 28,
y: 3,
});
});
});

View File

@ -0,0 +1,21 @@
import { route } from 'docuri';
/**
* A [docuri](https://github.com/jo/docuri) route for {@link components/map/types!TileKeyObject}
*
* TODO: update docuri (or write a wrapper) to support datatyping (and formats).
*/
export const tileUri = (rte: any) => {
const r = route('tile/:provider/:zoomLevel/:x/:y')(rte);
if (typeof r === 'object') {
return {
provider: r.provider,
zoomLevel: parseInt(r.zoomLevel),
x: parseInt(r.x),
y: parseInt(r.y),
};
}
return r;
};
export default tileUri;

1
src/missing-typedefs/docuri.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare module 'docuri';