Select to view content in your preferred language

Buffer query results vary

355
1
10-27-2022 02:44 PM
GregoryBologna
Frequent Contributor

I'll follow this post up with more details and a jsbin, but right now I was wondering if there is something obvious with this issue and what I can do to troubleshoot it further. I have a layerView query that executes on a buffer. Sometimes, maybe 40% of the time, the query results excludes a few of the buffered parcels by not adding its graphic (as shown in image A), other times the parcel is completely excluded from the query results. My next troubleshooting is to perform the query directly in ArcGIS execute form and try to reproduce the results I'm seeing here.

image A

GregoryBologna_0-1666904236967.png

image B

GregoryBologna_1-1666904376768.png

The basic workflow here is to query geometry with a buffer size and units (like feet), then add graphics to view and update a table with the results of the query.

 

function queryLayerView() {
	const queryObject = mapLayerView.createQuery();
	queryObject.geometry = sketchGeometryMode();
	queryObject.units = unitType;
	queryObject.distance = bufferSize;
	queryObject.spatialRelationship = 'intersects'; // this is default
	//queryObject.returnGeometry = true;
	queryObject.outSpatialReference = view.spatialReference;
	//queryObject.returnQueryGeometry = true;
	//queryObject.returnTrueCurves = true;
	//queryObject.returnZ = false;
	//queryObject.returnM = false;
	queryObject.outFields = ['*']; // all required fields for dataTable export
	//queryObject.orderByFields = ['PAR_SUBDIVISION', 'TAXPARCELTYPE'];
	queryObject.orderByFields = ['TAXPARCELTYPE', 'PAR_SUBDIVISION'];
	//queryObject.returnExtentOnly = false;
	//queryObject.returnExceededLimitFeatures = true;
	//queryObject.quantizationParameters = {
	//	mode: "view",
	//	originPosition: "upper-left",
	// 	tolerance: 4820,
	// 	extent: mapLayerView.fullExtent
	// },

	// Negate query when user unselects all tax parcel types
	if (taxParcelTypesSelectedString != '') {
		queryObject.where = `TAXPARCELTYPE IN(${taxParcelTypesSelectedString})`;
	} else {
		queryObject.where = `TAXPARCELTYPE NOT IN(${taxParcelTypesDefaultString})`;
	}

	let el = document.getElementById('calcite-block-instruction');
	if (el) {
		el.heading =
			'Now use the Buffer selection slider to create ' +
			'a geodesic buffer around the parcel boundary of your point.' +
			'Highlighted parcels will be saved to a table for downloading.';
	}
	let sub_count = {};

	// If you query a layerView each time the view extent changes, 
	// then you must wait until the layerView's updating property 
	// becomes false to make sure the layerView finished fetching 
	// the features for that extent.
	bufferLayerViewUpdatingFlag = true;
	reactiveUtils.whenOnce(() => !mapLayerView.updating)
		.then(() => {
			bufferLayerViewUpdatingFlag = false;
		});

	bufferSymbolData = []; // reset
	let symbol_id = 0;
	return mapLayerView
		.queryFeatures(queryObject)
		.then((layerView) => {
			if (!bufferLayerViewUpdatingFlag) {
				view.graphics.removeAll();

				let newlayerView = layerView;

				layerView.features.forEach((feature) => {
					let p = feature.attributes.PAR_SUBDIVISION;
					sub_count[p] = (sub_count[p] || 0) + 1;
				});

				layerView.features.forEach((feature) => {
					let par = feature.attributes.PARID;
					let sub = feature.attributes.PAR_SUBDIVISION;
					let tax = feature.attributes.TAXPARCELTYPE;

					let isSubject = lookupSubjectParid(par);

					if (bufferSymbolData.find((n) => (n.sub === sub) & (n.tax != 'PARCEL')))
						if (sub_count[sub] > 1) return;

					let symbolColor = '';

					let taxParcelType = feature.attributes.TAXPARCELTYPE;
					let rgb = taxParcelTypeColors.filter((obj) => {
						if (obj)
							if (Object.keys(obj)[0] === taxParcelType)
								return obj[taxParcelType];
					});
					if (rgb && rgb.length > 0) symbolColor = rgb[0][taxParcelType];

					let symbol = {
						type: 'simple-fill',
						outline: { color: [11, 53, 51, 1] },
						color: !isSubject ? symbolColor : symbolColorSubject,
					};
					let g = new Graphic({
						geometry: feature.geometry,
						//attributes: feature.attributes, // not needed for coloring
						symbol: symbol,
					});
					view.graphics.add(g);

					if (showBufferMapIntersectsRank && !isSubject) {

						view.graphics.add(g);

					}
					bufferSymbolData.push({ par: par, sub: sub, tax: tax, symbol: symbol_id });
				});

				// Exlude the selected parcel address in data table
				if (newlayerView.features && newlayerView.features.length > 0) {
					updateDataTable(newlayerView, bufferSymbolData)
						.then(ScrollLastAccordionIntoView)
						.catch((error) => {
							console.error(error);
							throw new PaoException('queryLayerView', error);
						});
				}
			}
			return true;
			//}
		}, console.error)
		.then(() => {
			symbol_id = 0;
		});
} // end

// set the geometry query on the visible mapLayerView
let debouncedRunQuery = promiseUtils.debounce(function () {
	if (!sketchGeometry) {
		return;
	}
	updateBufferPolygon(bufferSize);

	// clear highlighting when shared parcel lines and distance = 0
	if (bufferSize === 0) {

		view.graphics.removeAll();
		clearDataTable();
		return;
	}
	return promiseUtils.eachAlways([queryLayerView()]);
}); // end

 

 

0 Kudos
1 Reply
GregoryBologna
Frequent Contributor

Update to this issue. I have identified the reason why some buffered parcels are not selected. The layerView.features.length is zero. Finding this info,

https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#returnGeo...

If true, the query geometry will be returned with the query results. It is useful for getting the buffer geometry generated when querying features by distance or getting the query geometry projected in the outSpatialReference of the query. The query geometry is returned only for client-side queries and hosted feature services and if the layer's capabilities.query.supportsQueryGeometry is true.

Setting returnQueryGeometry = true so far appears to resolve this issue.