Adding docuri's and unit tests.
This commit is contained in:
parent
0b7de58a4e
commit
b3e1e4de73
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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;
|
|
@ -0,0 +1 @@
|
||||||
|
declare module 'docuri';
|
Loading…
Reference in New Issue