Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CADENZA-36891: Extend API for geometry intersection #37

Merged
merged 4 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased
### Added
- `CadenzaClient#fetchAreaIntersections`
- `CadenzaClient#fetchObjectInfo`

## 2.11.0 - 2024-07-12
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Cadenza JS is a JavaScript library to use the [disy Cadenza](https://www.disy.net/en/products/disy-cadenza/) APIs conveniently without having to deal with technical details like parameter encoding or the `postMessage()` Web API.

Find the docs at https://disyinformationssysteme.github.io/cadenza.js/
jkissel marked this conversation as resolved.
Show resolved Hide resolved

4 changes: 2 additions & 2 deletions sandbox.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ const DEFAULT_CADENZA_URL = 'http://localhost:8080/cadenza';

const index = process.argv.indexOf(CADENZA_URL_PARAM);
const cadenzaUrlFromArgs = index !== -1
? process.argv[index + 1]
: process.argv.find(arg => arg.startsWith(CADENZA_URL_PARAM + '='))?.slice(CADENZA_URL_PARAM.length + 1);
? process.argv[index + 1]
: process.argv.find(arg => arg.startsWith(CADENZA_URL_PARAM + '=')).slice(CADENZA_URL_PARAM.length + 1);
jkissel marked this conversation as resolved.
Show resolved Hide resolved
const cadenzaUrl = new URL(cadenzaUrlFromArgs || process.env.CADENZA_URL || DEFAULT_CADENZA_URL);

execSync(`npx --yes http-server -a localhost -c-1 -d false --proxy ${cadenzaUrl.origin} --proxy-options.headers.Origin ${cadenzaUrl.origin} -o /sandbox.html${cadenzaUrl.pathname !== '/' ? `?contextPath=${cadenzaUrl.pathname}` : ''}`, { stdio: 'inherit' });
51 changes: 48 additions & 3 deletions sandbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,12 @@
fetchObjectInfo: data => {
console.log('Inspect the fetchObjectInfo() request in the devtools.');
cadenzaClient.fetchObjectInfo(data.embeddingTargetId, JSON.parse(data.layer), JSON.parse(data.objectIds), getOptions(data))
.then(oi => console.log(oi));
.then(console.log);
},
fetchAreaIntersections: data => {
console.log('Inspect the fetchAreaIntersections() request in the devtools.');
cadenzaClient.fetchAreaIntersections(data.embeddingTargetId, JSON.parse(data.layer), JSON.parse(data.geometry), getOptions(data))
.then(console.log);
},
downloadData: data => cadenzaClient.downloadData(data.embeddingTargetId, data.dataType, getOptions(data))
};
Expand Down Expand Up @@ -223,7 +228,9 @@
simplifiedOperationMode,
useMapSrs,
fullGeometries,
zoomToGeometry
zoomToGeometry,
distance,
lengthUnit
}) {
return {
disabledUiFeatures: disabledUiFeatures && disabledUiFeatures.split(','),
Expand All @@ -244,7 +251,8 @@
layers: layers ? JSON.parse(layers) : undefined,
useMapSrs: useMapSrs === 'on',
fullGeometries: fullGeometries === 'on',
zoomTarget: zoomToGeometry === 'on' ? { type: 'geometry' } : undefined
zoomTarget: zoomToGeometry === 'on' ? { type: 'geometry' } : undefined,
buffer: distance ? { value: Number(distance), lengthUnit: lengthUnit ? lengthUnit : 'm' } : undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Why not just "unit"? Imo the "length" doesn't add anything here.
  • The unit cannot be missing, because it's a that has a default value, right?

Copy link
Member Author

@AndreasWBartels AndreasWBartels Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lenghtUnit is just a little more precise for the current context, theoretically it could be also a degree unit

yes, 'm' (meters) is the default for the current context.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant that

lengthUnit: lengthUnit ? lengthUnit : 'm'

can be simplified to

lengthUnit

because the lengthUnit cannot be undefined.

};
}

Expand Down Expand Up @@ -294,6 +302,7 @@
<option value="downloadData">Download data</option>
<option value="fetchData">Fetch data</option>
<option value="fetchObjectInfo">Fetch Object Info</option>
jkissel marked this conversation as resolved.
Show resolved Hide resolved
<option value="fetchAreaIntersections">Fetch Area Intersections</option>
</optgroup>
</select>
</div>
Expand Down Expand Up @@ -611,6 +620,42 @@
</div>
</template>

<template data-action="fetchAreaIntersections" data-common="layer">
<div>
<label for="embeddingTargetId">Embedding target ID *</label>
<input name="embeddingTargetId" id="embeddingTargetId" required>
</div>
<div>
<label for="geometry">Intersection Geometry (GeoJSON) *</label>
<textarea name="geometry" id="geometry" rows="5" required></textarea>
<small>
<p>
The geometry must result in an area in combination with the buffer specification.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean if it's a point or line, then the buffer becomes required? Maybe we can add an assertion for that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want a assertion a geometry type validation would be necessary here.
Now you get an error response, if there is no buffer in the request.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far we try to assert things if possible before hitting the server.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in cadenza.js?

</p>
</small>
</div>
<div>
<label>
<input type="checkbox" name="useMapSrs">
Use map SRS
</label>
</div>
<div>
<label for="distance">Buffer size</label>
<input name="distance" id="distance" type="number" min="0">
<label for="lengthUnit">Length unit</label>
<select name="lengthUnit" id="lengthUnit">
<option>m</option>
<option>km</option>
</select>
<small>
<p>
A positive buffer size is needed for point or line intersection geometries.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an assertion for the distance to be positive?

Copy link
Member Author

@AndreasWBartels AndreasWBartels Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

polygons can have a negative distance, if we want a assertion a geometry type validation would be necessary.

Copy link
Member

@jkissel jkissel Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, why not? We have that info in the method.

Btw, how does buffering with a negative distance work?

</p>
</small>
</div>
</template>

<template data-action="getData">
<div>
<label for="dataType">Data type</label>
Expand Down
44 changes: 44 additions & 0 deletions src/cadenza.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ globalThis.cadenza = Object.assign(
* * `"workbook-view-management"` - Add/Edit/Remove workbook views (Is included in 'workbook-design'.)
* */

/**
* @typedef Distance
* @property {number} value
* @property {LengthUnit} lengthUnit
*/
/**
* @typedef {'m'|'km'} LengthUnit
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be "Buffer"?

/**
 * @typedef Buffer
 * @property {number} value
 * @property {'m'|'km'} unit
 */

Should we make the unit optional (assuming "m" as the default)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional is "* @Property {'m'|'km'} [unit] ", but how to set a default value on the property?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work:

 * @property {'m' | 'km'} [unit='m']


/**
* @typedef Geometry - A [GeoJSON](https://geojson.org/) geometry object
* @property {GeometryType} type - The type of the geometry
Expand Down Expand Up @@ -919,6 +928,41 @@ export class CadenzaClient {
).then((response) => response.json());
}

/**
* Fetch the intersection areas from a workbook map view layer in JSON format for a given area.
*
* @param {EmbeddingTargetId} source - The workbook view to fetch object info from.
* @param {(WorkbookLayerPath | string)[]} layerPath - Layer path to identify the layer
* (identified using layer paths or print names)
* @param {Geometry} geometry - The intersection geometry
* @param {object} [options] - Options
* @param {boolean} [options.useMapSrs] - The intersection geometry and the result geometries are in the map's SRS (otherwise EPSG:4326 is assumed)
* @param {Distance} [options.buffer] - Buffer size for geometry of the transition
* @param {AbortSignal} [options.signal] - A signal to abort the data fetching
* @return {Promise<FeatureCollection>} A `Promise` for the fetch response
* @server
*/
fetchAreaIntersections(
source,
layerPath,
geometry,
{ useMapSrs, buffer, signal} = {},
) {
this.#log('CadenzaClient#areaIntersections', ...arguments);
const params = createParams({});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposal: Rather make the "params" argument optional instead of passing a dummy value.

@type URLSearchParams | undefined

return this.#fetch(
resolvePath(source) + '/area-intersections',
params,
signal,
JSON.stringify({
layerPath: layerPath,
geometry: geometry,
useMapSrs: useMapSrs,
buffer: buffer,
}),
).then((response) => response.json());
}

async #fetch(
/** @type string */ path,
/** @type URLSearchParams */ params,
Expand Down
28 changes: 26 additions & 2 deletions src/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,15 +356,39 @@ const tableData = await response.json();

<small>API: [CadenzaClient#fetchObjectInfo(./classes/CadenzaClient.html#fetchObjectInfo)</small>

Download the object info from a workbook map view in JSON format. The result contains all information, that is shown in the object info within cadenza.
Fetch the object info from a workbook map view in JSON format. The result contains all information, that is shown in the object info within cadenza.

```javascript
const response = await cadenzaClient.fetchObjectInfo('embeddingTargetId', 'layerPrintName', [['objectId']], {
useMapSrs: false,
fullGeometries: true
});

const objectInfo = await response;
const objectInfo = response;
```

### Fetch the area intersection from a Workbook Map View Layer

<small>API: [CadenzaClient#fetchObjectInfo(./classes/CadenzaClient.html#fetchAreaIntersections)</small>

Fetch the intersection area from a workbook map view layer in JSON format for a given area. The result contains all intersecting objects of the layer, their object ID, if defined the object name and a geometry representing the intersection area, with area size and area perimeter.

```javascript
const geometry = {
type: 'Point',
coordinates: [328_627.563458, 5_921_296.662223],
};
const bufferSize = {
value: 100,
lengthUnit: 'm'
}

const response = await cadenzaClient.fetchAreaIntersections('embeddingTargetId', 'layerPrintName', geometry, {
useMapSrs: true,
bufferSize: bufferSize
});

const featureCollection = response;
```

### Download Data From a Workbook View
Expand Down
Loading