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

Fix issue snapping to mvt #1171

Merged
merged 6 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
97 changes: 95 additions & 2 deletions lib/layer/format/mvt.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
/**
### mapp.layer.formats.mvt()

This module defines the MVT (MapBox Vector Tile) format for map layers.
@module /layer/formats/mvt
*/

/**
* Configures the MVT format for a map layer.
@function mvt
@param {Object} layer - The layer object.
@param {string} [layer.srid='3857'] - The spatial reference system identifier (SRID) for the layer.
@param {Object} [layer.style={}] - The style object for the layer.
@param {Object} [layer.params={}] - Additional parameters for the layer.
@param {boolean} [layer.mvt_cache] - Flag indicating whether to use MVT caching (deprecated).
@param {string[]} [layer.tables] - An array of table names for the layer.
@param {string[]} [layer.wkt_properties] - An array of properties to be retrieved as WKT (Well-Known Text) format.
@param {number} [layer.transition] - The transition duration for the layer.
@param {number} [layer.cacheSize] - The cache size for the layer.
@param {Object} layer.mapview - The mapview object.
@param {string} layer.mapview.host - The host URL for the API.
@param {Object} layer.mapview.locale - The locale object.
@param {string} layer.mapview.locale.key - The key for the locale.
@param {string} layer.mapview.srid - The SRID for the mapview.
@param {ol.Map} layer.mapview.Map - The OpenLayers map object.
@param {Object} layer.filter - The filter object for the layer.
@param {function} layer.filter.current - The current filter function for the layer.
@param {function} layer.tableCurrent - A function that returns the current table for the layer.
@param {function} layer.geomCurrent - A function that returns the current geometry for the layer.
@param {ol.layer.VectorTile} layer.L - The OpenLayers vector tile layer.
@returns {void}
*/
export default layer => {

// Assign default SRID if nullish.
Expand Down Expand Up @@ -72,7 +97,7 @@ export default layer => {
}),
transition: 0,
cacheSize: 0,
tileUrlFunction
tileUrlFunction: tileUrlFunction(layer)
})

// Define source for mvt layer.
Expand Down Expand Up @@ -102,6 +127,22 @@ export default layer => {
})
}

/**
* Returns a function that generates the tile URL for a WKT-based layer.
@function wktTileUrlFunction
@param {Object} layer - The layer object.
@param {string} layer.mapview.host - The host URL for the API.
@param {Object} layer.mapview.locale - The locale object.
@param {string} layer.mapview.locale.key - The key for the locale.
@param {string} layer.mapview.srid - The SRID for the mapview.
@param {string} layer.key - The key for the layer.
@param {function} layer.tableCurrent - A function that returns the current table for the layer.
@param {function} layer.geomCurrent - A function that returns the current geometry for the layer.
@param {boolean} layer.display - A flag indicating whether the layer is displayed.
@param {Set} [layer.clones] - A set of cloned layers.
@param {ol.source.VectorTile} layer.source - The OpenLayers vector tile source.
@returns {function} A function that generates the tile URL for the given tile coordinate.
*/
function wktTileUrlFunction(layer) {

return tileCoord => {
Expand Down Expand Up @@ -138,6 +179,30 @@ function wktTileUrlFunction(layer) {
}
}

/**
* Returns a function that generates the tile URL for an MVT layer.
@function tileUrlFunction
@param {Object} layer - The layer object.
@param {string} layer.mapview.host - The host URL for the API.
@param {Object} layer.mapview.locale - The locale object.
@param {string} layer.mapview.locale.key - The key for the locale.
@param {string} layer.key - The key for the layer.
@param {function} layer.tableCurrent - A function that returns the current table for the layer.
@param {function} layer.geomCurrent - A function that returns the current geometry for the layer.
@param {boolean} layer.display - A flag indicating whether the layer is displayed.
@param {Set} [layer.clones] - A set of cloned layers.
@param {Object} [layer.params] - Additional parameters for the layer.
@param {Object} [layer.style] - The style object for the layer.
@param {Object} [layer.style.theme] - The theme style object.
@param {string|string[]} [layer.style.theme.fields] - The field(s) for the theme style.
@param {string} [layer.style.theme.field] - The field for the theme style.
@param {Object} [layer.style.label] - The label style object.
@param {string} [layer.style.label.field] - The field for the label style.
@param {Object} [layer.filter] - The filter object for the layer.
@param {function} [layer.filter.current] - The current filter function for the layer.
@param {ol.source.VectorTile} layer.source - The OpenLayers vector tile source.
@returns {function} A function that generates the tile URL for the given tile coordinate.
*/
function tileUrlFunction(layer) {

return tileCoord => {
Expand Down Expand Up @@ -184,6 +249,34 @@ function tileUrlFunction(layer) {

}

/**
* Loads the layer features and updates the layer display on map view change.
@function changeEndLoad
@param {Object} layer - The layer object.
@param {XMLHttpRequest} [layer.xhr] - The XMLHttpRequest object used for fetching data.
@param {function} layer.tableCurrent - A function that returns the current table for the layer.
@param {boolean} layer.display - A flag indicating whether the layer is displayed.
@param {Set} [layer.clones] - A set of cloned layers.
@param {function} layer.geomCurrent - A function that returns the current geometry for the layer.
@param {Object} [layer.params] - Additional parameters for the layer.
@param {Object} [layer.style] - The style object for the layer.
@param {Object} [layer.style.theme] - The theme style object.
@param {string|string[]} [layer.style.theme.fields] - The field(s) for the theme style.
@param {string} [layer.style.theme.field] - The field for the theme style.
@param {Object} [layer.style.label] - The label style object.
@param {string} [layer.style.label.field] - The field for the label style.
@param {Object} layer.mapview - The mapview object.
@param {string} layer.mapview.host - The host URL for the API.
@param {Object} layer.mapview.locale - The locale object.
@param {string} layer.mapview.locale.key - The key for the locale.
@param {string} layer.mapview.srid - The SRID for the mapview.
@param {ol.Map} layer.mapview.Map - The OpenLayers map object.
@param {Object} layer.filter - The filter object for the layer.
@param {function} [layer.filter.current] - The current filter function for the layer.
@param {Object} [layer.featuresObject] - An object to store layer features.
@param {ol.layer.VectorTile} layer.L - The OpenLayers vector tile layer.
@returns {void}
*/
function changeEndLoad(layer) {

layer.xhr?.abort()
Expand Down
56 changes: 41 additions & 15 deletions lib/mapview/interactions/snap.mjs
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
/**
@module /mapview/interactions/snap
*/
* ### mapview.interactions.snap()
* This module sets up the snap interaction for the mapview.
* @module /mapview/interactions/snap
*/

/**
* Sets up the snap interaction for the mapview.
* @function snap
* @param {Object} mapview - The mapview object.
* @param {ol.Map} mapview.Map - The OpenLayers map object.
* @param {Object} mapview.interaction - The interaction object.
* @param {boolean|Object} mapview.interaction.snap - The snap interaction configuration.
* @param {string} [mapview.interaction.snap.layer] - The key of the layer to snap to.
* @param {ol.layer.Layer} mapview.interaction.layer - The interaction layer.
* @param {Object} mapview.layers - The map layers object.
*/
export default function(mapview) {

// The current draw/modify interaction doesn't snap.
if (!mapview.interaction.snap) return;

if (mapview.interaction.snap === true) {
// Assign the interaction layer as snap layer if snap is true.
mapview.interaction.snap = {
layer: mapview.interaction.layer.key
}
}

// Assign mapview and interaction to be _this.
mapview.interaction.snap = {
/**
* Removes the snap interaction and related resources.
*/
remove: ()=>{

if (mapview.interaction.layer.featureSource) {

// Detach tile load event,
mapview.interaction.layer.featureSource.un('tileloadend', tileloadend)

Expand All @@ -31,8 +51,8 @@ export default function(mapview) {

// Check if snap layer exists in mapview.layers.
if (!mapview.layers[mapview.interaction.snap.layer]) {
console.warn(`Unable to snap to layer:${mapview.interaction.snap.layer} as it is not found in mapview.layers.`)
return;
console.warn(`Unable to snap to layer:${mapview.interaction.snap.layer} as it is not found in mapview.layers.`)
return;
}

// Assign snap layer from key if defined.
Expand All @@ -41,15 +61,23 @@ export default function(mapview) {
// Assign interaction as snap layer if undefined.
mapview.interaction.snap.layer ??= mapview.interaction.layer

mapview.interaction.snap.layer.show()

/**
* Callback function for the `tileloadend event of the feature source.
* Adds features from the loaded tile to the snap source.
* @param {ol.TileLoadEvent} e - The tile load event.
*/
function tileloadend(e) {
const features = e.tile.getFeatures()

// Add features from tile to the snap.source.
mapview.interaction.snap.source.addFeatures(e.tile.getFeatures())
// Try adding features to prevent a crash adding the same feature twice.
try {
mapview.interaction.snap.source.addFeatures(features)
} catch {}
}

// Only MVT layer have a snapSource.
if (mapview.interaction.snap.layer.featureSource) {

// Create new Vector source for snap features.
mapview.interaction.snap.source = new ol.source.Vector()

Expand All @@ -60,12 +88,10 @@ export default function(mapview) {
source: mapview.interaction.snap.layer.featureSource,
opacity: 0
})

// Add invisible tile layer for the featureSource to trigger tile loads.
mapview.Map.addLayer(mapview.interaction.snap.vectorTileLayer)

} else {

// Assign vector source as snap source for vector layer.
mapview.interaction.snap.source = mapview.interaction.snap.layer.L.getSource()
}
Expand All @@ -74,7 +100,7 @@ export default function(mapview) {
mapview.interaction.snap.interaction = new ol.interaction.Snap({
source: mapview.interaction.snap.source
})

// Add snap.interaction to mapview.Map
mapview.Map.addInteraction(mapview.interaction.snap.interaction)
}
Loading