Skip to content

Commit

Permalink
Merge pull request #715 from theduckylittle/feature/limit-buffer-feat…
Browse files Browse the repository at this point in the history
…ures

Limit the number of bufferable features
  • Loading branch information
klassenjs authored Mar 18, 2022
2 parents 8afefa0 + 0c9abed commit f9f6e3b
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 14 deletions.
5 changes: 3 additions & 2 deletions src/gm3/components/map/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ class Map extends React.Component {

// buffer those features.
bufferedFeature =
util.projectFeatures(
[jsts.union(util.projectFeatures(
wgs84Features.map(feature => {
const buffered = jsts.bufferFeature(feature, buffer);
buffered.properties = {
Expand All @@ -890,7 +890,8 @@ class Map extends React.Component {
}),
'EPSG:4326',
'EPSG:3857'
);
)
), ];
}

// the selection feature(s) are the original, as-drawn feature.
Expand Down
31 changes: 28 additions & 3 deletions src/gm3/components/serviceManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { getExtentForQuery } from '../util';
import { DEFAULT_RESULTS_CONFIG } from '../defaults';

import MeasureTool from './measure';
import Modal from './modal';

import ServiceForm from './serviceForm';

Expand Down Expand Up @@ -78,6 +79,7 @@ class ServiceManager extends React.Component {
lastService: null,
lastFeature: '',
values: {},
showTooManyFeatures: false,
};

this.fieldValues = {};
Expand Down Expand Up @@ -145,6 +147,8 @@ class ServiceManager extends React.Component {
}
}

const bufferEnabled = feature_count <= this.props.config.bufferMaxFeatures;

const info_header = (
<div className='results-info'>
{resultsConfig.showFeatureCount && (
Expand All @@ -162,9 +166,17 @@ class ServiceManager extends React.Component {
)}

{resultsConfig.showBufferAll && (
<div className='results-info-item buffer-all'>
<div
className='results-info-item buffer-all'
>
<div className='label'>{this.props.t('buffer-all')}</div>
<div className='value' onClick={() => { this.props.bufferAll(query); }}>
<div className='value' onClick={() => {
if (bufferEnabled) {
this.props.bufferAll(query);
} else {
this.setState({showTooManyFeatures: true});
}
}}>
<span className='icon buffer'></span>
</div>
</div>
Expand Down Expand Up @@ -351,6 +363,16 @@ class ServiceManager extends React.Component {
if(this.props.queries.order.length > 0) {
contents = (
<React.Fragment>
<Modal
open={this.state.showTooManyFeatures}
options={[{value: 'okay', label: this.props.t('Close')}]}
onClose={() => {
this.setState({showTooManyFeatures: false});
}}
title={this.props.t('too-many-features-title')}
>
{this.props.t('too-many-features-description')}
</Modal>
{ this.props.queries.order.map(this.renderQuery) }
</React.Fragment>
);
Expand All @@ -368,7 +390,6 @@ class ServiceManager extends React.Component {
<div className='info-box'>
{ this.props.t('start-service-help') }
</div>

<div className='clear-controls'>
<button
disabled={ !enable_clear }
Expand Down Expand Up @@ -399,6 +420,10 @@ const mapState = state => ({
map: state.map,
selectionFeatures: state.mapSources.selection ? state.mapSources.selection.features : [],
resultsConfig: {...DEFAULT_RESULTS_CONFIG, ...state.config.results},
config: {
bufferMaxFeatures: 100,
...state.config.query,
},
});

function mapDispatch(dispatch, ownProps) {
Expand Down
41 changes: 32 additions & 9 deletions src/gm3/jsts.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,24 @@ export function buffer(feature, meters) {
return bufferFeature(feature, meters).geometry;
}

export function bufferFeature(feature, meters) {
// Start on null island.
let pos_pt = [0, 0];

function getAnchorPoint(feature, empty = null) {
let anchorPoint = empty;
const gtype = feature.geometry.type;

if (gtype === 'Point') {
pos_pt = feature.geometry.coordinates;
anchorPoint = feature.geometry.coordinates;
} else if(gtype === 'MultiPoint' || gtype === 'LineString') {
pos_pt = feature.geometry.coordinates[0];
anchorPoint = feature.geometry.coordinates[0];
} else if(gtype === 'MultiLineString' || gtype === 'Polygon') {
pos_pt = feature.geometry.coordinates[0][0];
anchorPoint = feature.geometry.coordinates[0][0];
} else if(gtype === 'MuliPolygon') {
pos_pt = feature.geometry.cooredinates[0][0][0];
anchorPoint = feature.geometry.cooredinates[0][0][0];
}
return anchorPoint;
}

export function bufferFeature(feature, meters) {
// Start on null island.
const pos_pt = getAnchorPoint(feature, [0, 0]);

// find the feature's location in UTM space.
const utmZone = proj.get(getUtmZone(pos_pt));
Expand Down Expand Up @@ -114,3 +117,23 @@ export function bufferAndUnion(features, meters) {

return geometry.geometry;
}

export function union(features) {
const distance = pt => Math.sqrt(pt[0] * pt[0] + pt[1] * pt[1]);
// sort the features by their bounding boxes.
const sortedFeatures = features.sort((a, b) => {
const ptA = getAnchorPoint(a);
const ptB = getAnchorPoint(b);
if (ptA === null) {
return 1;
} else if (ptB === null) {
return -1;
}
return distance(ptA) < distance(ptB) ? -1 : 1;
});
let unionFeature = {...sortedFeatures[0]};
for (let i = 1, ii = sortedFeatures.length; i < ii; i++) {
unionFeature = turf_union(unionFeature, sortedFeatures[i]);
}
return unionFeature;
}
2 changes: 2 additions & 0 deletions src/gm3/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
"search-catalog" : "Search catalog",
"start-service-help" : "Nothing available to view. Please click a service to start in the toolbar.",
"toggle-legend-tip" : "Toggle legend visibility.",
"too-many-features-title": "Too many features",
"too-many-features-description": "Too many features to buffer. Please, select a smaller number of features on the map.",
"undo-changes" : "Undo Changes",
"unfade-tip" : "Unfade layer",
"units" : "Units",
Expand Down
8 changes: 8 additions & 0 deletions src/less/results.less
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@
}
}

&.disabled {
border-color: #eee;
color: #eee;
cursor: not-allowed;
.icon {
cursor: not-allowed;
}
}
}
}
}

0 comments on commit f9f6e3b

Please sign in to comment.