Skip to content

Commit

Permalink
Merge pull request #15 from camptocamp/add-styling
Browse files Browse the repository at this point in the history
Support styling for vector layers
  • Loading branch information
jahow authored Sep 15, 2024
2 parents 45eafe3 + 1328f5a commit 87e3bcf
Show file tree
Hide file tree
Showing 14 changed files with 210 additions and 58 deletions.
15 changes: 9 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion packages/core/fixtures/map-context.fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const MAP_CTX_VIEW_FIXTURE: MapContextView = deepFreeze({
zoom: 9,
});

export const MAP_CTX_FIXTURE: MapContext = deepFreeze({
export const MAP_CTX_FIXTURE = deepFreeze({
layers: [
MAP_CTX_LAYER_XYZ_FIXTURE,
MAP_CTX_LAYER_WMS_FIXTURE,
Expand Down Expand Up @@ -115,6 +115,12 @@ export const SAMPLE_LAYER3: MapContextLayerGeojson = deepFreeze({
type: "geojson",
data: '{ "type": "Feature", "properties": {}}',
extras: { myField3: "000" },
style: [
{
"circle-radius": 3,
"circle-fill-color": "red",
},
],
});
export const SAMPLE_LAYER4: MapContextLayerWfs = deepFreeze({
type: "wfs",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/lib/model/map-context-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ export interface MapContextDiff {
layersReordered: MapContextLayerReordered[];
layersRemoved: MapContextLayerPositioned[];
layersAdded: MapContextLayerPositioned[];
viewChanges?: MapContextView;
viewChanges?: MapContextView | null;
}
6 changes: 5 additions & 1 deletion packages/core/lib/model/map-context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FeatureCollection, Geometry } from "geojson";
import { VectorStyle } from "./style";

export type LayerDimensions = Record<string, string>;

Expand Down Expand Up @@ -40,6 +41,7 @@ export interface MapContextLayerWfs extends MapContextBaseLayer {
type: "wfs";
url: string;
featureType: string;
style?: VectorStyle;
}

export interface MapContextLayerOgcApi extends MapContextBaseLayer {
Expand All @@ -49,6 +51,7 @@ export interface MapContextLayerOgcApi extends MapContextBaseLayer {
useTiles?: "vector" | "map";
tileMatrixSet?: string;
options?: Record<string, string>;
style?: VectorStyle;
}

// Layer pointing to a MapLibre Style spec, see https://maplibre.org/maplibre-style-spec/
Expand All @@ -65,6 +68,7 @@ export interface MapContextLayerXyz extends MapContextBaseLayer {

interface LayerGeojson extends MapContextBaseLayer {
type: "geojson";
style?: VectorStyle;
}
interface LayerGeojsonWithUrl extends LayerGeojson {
url: string;
Expand Down Expand Up @@ -133,5 +137,5 @@ export type MapContextView = (

export interface MapContext {
layers: MapContextLayer[];
view: MapContextView;
view: MapContextView | null; // a view of "null" means the map will show a default view;
}
3 changes: 3 additions & 0 deletions packages/core/lib/model/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { FlatStyleLike } from "ol/style/flat";

export type VectorStyle = FlatStyleLike;
10 changes: 10 additions & 0 deletions packages/core/lib/utils/hash.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,14 @@ describe("getHash", () => {
]);
expect(hashB).toEqual(hashA);
});
it("stable for null", () => {
const hashA = getHash(null);
const hashB = getHash(null);
expect(hashB).toEqual(hashA);
});
it("different when casting null to string", () => {
const hashA = getHash(null);
const hashB = getHash("null");
expect(hashB).not.toEqual(hashA);
});
});
103 changes: 79 additions & 24 deletions packages/core/lib/utils/map-context-diff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,32 +213,87 @@ describe("Context diff utils", () => {
});

describe("view changes", () => {
beforeEach(() => {
contextOld = {
...SAMPLE_CONTEXT,
view: {
center: [0, 0],
zoom: 1,
},
};
contextNew = {
...SAMPLE_CONTEXT,
view: {
center: [1, 1],
zoom: 2,
},
};
describe("both values", () => {
beforeEach(() => {
contextOld = {
...SAMPLE_CONTEXT,
view: {
center: [0, 0],
zoom: 1,
},
};
contextNew = {
...SAMPLE_CONTEXT,
view: {
center: [1, 1],
zoom: 2,
},
};
});
it("outputs the correct diff", () => {
diff = computeMapContextDiff(contextNew, contextOld);
expect(diff).toEqual({
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: { ...contextNew.view },
});
expect(diff.viewChanges).not.toBe(contextNew.view); // the object reference should be different
});
});
it("outputs the correct diff", () => {
diff = computeMapContextDiff(contextNew, contextOld);
expect(diff).toEqual({
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: { ...contextNew.view },
describe("value to null", () => {
beforeEach(() => {
contextOld = {
...SAMPLE_CONTEXT,
view: {
center: [0, 0],
zoom: 1,
},
};
contextNew = {
...SAMPLE_CONTEXT,
view: null,
};
});
it("outputs the correct diff", () => {
diff = computeMapContextDiff(contextNew, contextOld);
expect(diff).toEqual({
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: null,
});
});
});
describe("null to value", () => {
beforeEach(() => {
contextOld = {
...SAMPLE_CONTEXT,
view: null,
};
contextNew = {
...SAMPLE_CONTEXT,
view: {
center: [0, 0],
zoom: 1,
},
};
});
it("outputs the correct diff", () => {
diff = computeMapContextDiff(contextNew, contextOld);
expect(diff).toEqual({
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: {
center: [0, 0],
zoom: 1,
},
});
});
expect(diff.viewChanges).not.toBe(contextNew.view); // the object reference should be different
});
});

Expand Down
9 changes: 6 additions & 3 deletions packages/core/lib/utils/map-context-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,19 @@ export function computeMapContextDiff(
}
}

const viewChanges =
let viewChanges =
getHash(nextContext.view) !== getHash(previousContext.view)
? { ...nextContext.view }
? nextContext.view
: undefined;
if (viewChanges !== null && viewChanges !== undefined) {
viewChanges = { ...viewChanges }; // copy the view to avoid unexpected mutations
}

return {
layersAdded,
layersChanged,
layersRemoved,
layersReordered,
...(viewChanges && { viewChanges }),
...(viewChanges !== undefined && { viewChanges }),
};
}
5 changes: 4 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
},
"gitHead": "99dbb945a303b96e576a02a02bc0590785456bd3",
"dependencies": {
"@camptocamp/ogc-client": "1.1.1-dev.9671ef4",
"@camptocamp/ogc-client": "1.1.1-dev.c75dcba",
"proj4": "^2.9.2"
},
"devDependencies": {
"ol": "^8.2.0"
}
}
68 changes: 61 additions & 7 deletions packages/openlayers/lib/map/apply-context-diff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ describe("applyContextDiffToMap", () => {
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: {},
};
await applyContextDiffToMap(map, diff);
layersArray = map.getLayers().getArray();
Expand Down Expand Up @@ -81,7 +80,6 @@ describe("applyContextDiffToMap", () => {
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: {},
};
applyContextDiffToMap(map, diff);
layersArray = map.getLayers().getArray();
Expand Down Expand Up @@ -111,7 +109,6 @@ describe("applyContextDiffToMap", () => {
},
],
layersReordered: [],
viewChanges: {},
};
applyContextDiffToMap(map, diff);
});
Expand Down Expand Up @@ -145,7 +142,6 @@ describe("applyContextDiffToMap", () => {
],
layersRemoved: [],
layersReordered: [],
viewChanges: {},
};
applyContextDiffToMap(map, diff);
layersArray = map.getLayers().getArray();
Expand Down Expand Up @@ -181,7 +177,6 @@ describe("applyContextDiffToMap", () => {
previousPosition: 0,
},
],
viewChanges: {},
};
applyContextDiffToMap(map, diff);
layersArray = map.getLayers().getArray();
Expand Down Expand Up @@ -217,7 +212,67 @@ describe("applyContextDiffToMap", () => {
previousPosition: 0,
},
],
viewChanges: {},
};
applyContextDiffToMap(map, diff);
layersArray = map.getLayers().getArray();
});
it("moves the layers accordingly", () => {
expect(layersArray.length).toEqual(4);
assertEqualsToModel(layersArray[0], SAMPLE_LAYER4);
assertEqualsToModel(layersArray[1], SAMPLE_LAYER3);
assertEqualsToModel(layersArray[2], SAMPLE_LAYER1);
assertEqualsToModel(layersArray[3], SAMPLE_LAYER2);
});
});
});

describe("view change", () => {
describe("set to default view", () => {
beforeEach(async () => {
context = {
...SAMPLE_CONTEXT,
layers: [SAMPLE_LAYER1, SAMPLE_LAYER2, SAMPLE_LAYER3],
};
map = await createMapFromContext(context);
diff = {
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: null,
};
applyContextDiffToMap(map, diff);
});
it("set the view back to default", () => {
const view = map.getView();
expect(view.getCenter()).toEqual([0, 0]);
expect(view.getZoom()).toEqual(0);
});
});

describe("four layers reordered", () => {
beforeEach(async () => {
context = {
...SAMPLE_CONTEXT,
layers: [SAMPLE_LAYER1, SAMPLE_LAYER3, SAMPLE_LAYER4, SAMPLE_LAYER2],
};
map = await createMapFromContext(context);
diff = {
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [
{
layer: SAMPLE_LAYER4,
newPosition: 0,
previousPosition: 2,
},
{
layer: SAMPLE_LAYER1,
newPosition: 2,
previousPosition: 0,
},
],
};
applyContextDiffToMap(map, diff);
layersArray = map.getLayers().getArray();
Expand Down Expand Up @@ -276,7 +331,6 @@ describe("applyContextDiffToMap", () => {
previousPosition: 1,
},
],
viewChanges: {},
};
applyContextDiffToMap(map, diff);
layersArray = map.getLayers().getArray();
Expand Down
Loading

0 comments on commit 87e3bcf

Please sign in to comment.