Skip to content

Commit

Permalink
Merge pull request #16 from camptocamp/fix-view-extent
Browse files Browse the repository at this point in the history
Fix view computation based on geometry
  • Loading branch information
jahow authored Sep 18, 2024
2 parents 87e3bcf + 83c1f7c commit 89507d8
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 33 deletions.
66 changes: 66 additions & 0 deletions packages/core/lib/utils/hash.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,70 @@ describe("getHash", () => {
const hashB = getHash("null");
expect(hashB).not.toEqual(hashA);
});
it("stable with identical GeoJSON geometry", () => {
const hashA = getHash({
geometry: {
type: "Polygon",
properties: {},
coordinates: [
[
[-10, -10],
[-10, 20],
[10, 20],
[10, -10],
[-10, -10],
],
],
},
});
const hashB = getHash({
geometry: {
type: "Polygon",
properties: {},
coordinates: [
[
[-10, -10],
[-10, 20],
[10, 20],
[10, -10],
[-10, -10],
],
],
},
});
expect(hashB).toEqual(hashA);
});
it("different if GeoJSON geometry properties are not in the same order", () => {
const hashA = getHash({
geometry: {
coordinates: [
[
[-10, -10],
[-10, 20],
[10, 20],
[10, -10],
[-10, -10],
],
],
type: "Polygon",
properties: {},
},
});
const hashB = getHash({
geometry: {
type: "Polygon",
properties: {},
coordinates: [
[
[-10, -10],
[-10, 20],
[10, 20],
[10, -10],
[-10, -10],
],
],
},
});
expect(hashB).not.toEqual(hashA);
});
});
8 changes: 7 additions & 1 deletion packages/core/lib/utils/hash.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
function isGeoJsonGeometry(object: object) {
return "type" in object && "coordinates" in object;
}

export function getHash(input: unknown, ignoreKeys: string[] = []): string {
if (input instanceof Object) {
if (input instanceof Object && isGeoJsonGeometry(input)) {
return JSON.stringify(input); // do not compute an actual hash as it will take too long
} else if (input instanceof Object) {
const obj: Record<string, string> = {};
const keys = Object.keys(input).sort();
for (const key of keys) {
Expand Down
69 changes: 41 additions & 28 deletions packages/openlayers/lib/map/apply-context-diff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,7 @@ describe("applyContextDiffToMap", () => {
describe("view change", () => {
describe("set to default view", () => {
beforeEach(async () => {
context = {
...SAMPLE_CONTEXT,
layers: [SAMPLE_LAYER1, SAMPLE_LAYER2, SAMPLE_LAYER3],
};
map = await createMapFromContext(context);
map = await createMapFromContext(SAMPLE_CONTEXT);
diff = {
layersAdded: [],
layersChanged: [],
Expand All @@ -250,39 +246,56 @@ describe("applyContextDiffToMap", () => {
});
});

describe("four layers reordered", () => {
describe("set to view with extent", () => {
beforeEach(async () => {
context = {
...SAMPLE_CONTEXT,
layers: [SAMPLE_LAYER1, SAMPLE_LAYER3, SAMPLE_LAYER4, SAMPLE_LAYER2],
map = await createMapFromContext(SAMPLE_CONTEXT);
diff = {
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [],
viewChanges: {
extent: [-10, -10, 20, 20],
},
};
map = await createMapFromContext(context);
applyContextDiffToMap(map, diff);
});
it("set the view to the given extent, transformed to the view projection", () => {
const view = map.getView();
expect(view.getCenter()).toEqual([
556597.4539663679, 577070.4760648644,
]);
expect(view.getZoom()).toEqual(2);
});
});

describe("set to view with geometry", () => {
beforeEach(async () => {
map = await createMapFromContext(SAMPLE_CONTEXT);
diff = {
layersAdded: [],
layersChanged: [],
layersRemoved: [],
layersReordered: [
{
layer: SAMPLE_LAYER4,
newPosition: 0,
previousPosition: 2,
},
{
layer: SAMPLE_LAYER1,
newPosition: 2,
previousPosition: 0,
layersReordered: [],
viewChanges: {
geometry: {
type: "LineString",
coordinates: [
[0, 0],
[10, 10],
[40, 10],
],
},
],
},
};
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);
it("set the view to the given extent, transformed to the view projection", () => {
const view = map.getView();
expect(view.getCenter()).toEqual([
2226389.8158654715, 559444.9874289795,
]);
expect(view.getZoom()).toEqual(1);
});
});
});
Expand Down
11 changes: 7 additions & 4 deletions packages/openlayers/lib/map/apply-context-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,14 @@ export async function applyContextDiffToMap(
map.setView(createView(viewChanges, map));
return map;
}
if (viewChanges.maxZoom) {
view.setMaxZoom(viewChanges.maxZoom);
}
if ("geometry" in viewChanges) {
const geom = GEOJSON.readGeometry(viewChanges.geometry);
const geom = GEOJSON.readGeometry(viewChanges.geometry, {
dataProjection: "EPSG:4326",
featureProjection: projection,
});
view.fit(geom as SimpleGeometry, {
size: map.getSize(),
});
Expand All @@ -90,9 +96,6 @@ export async function applyContextDiffToMap(
: [0, 0];
view.setCenter(center);
view.setZoom(zoom);
if (viewChanges.maxZoom) {
view.setMaxZoom(viewChanges.maxZoom);
}
// TODO: factorize this better
// if (viewChanges.maxExtent) {
// map.setView(new View({
Expand Down

0 comments on commit 89507d8

Please sign in to comment.