|
POST
|
Ok. It's working now. I think my second try was still in the wrong place. Thanks. Do I need the time out? bufferLayer.graphics.on("after-add", (event) => {
console.log(event);
});
//setTimeout(() => {
bufferLayer.graphics.on("after-remove", (event) => {
console.log(event);
});
//}, 2000);
... View more
03-22-2023
11:40 AM
|
0
|
1
|
1589
|
|
POST
|
Thanks. I'm doing buffering and adding \ removing graphics from a GraphicsLayer as the buffer increases or decreases. The view.graphics.on in the sample fires dozens of times regardless of any buffer graphics, so that's not going to work. Also, I'm not facing any issues with my buffer. I just wanted to capture the remove event.
... View more
03-22-2023
10:02 AM
|
0
|
3
|
1597
|
|
POST
|
The location of the error is on line 1 below. const queryFeatureLayer = new FeatureLayer({ params here... } const queryObject = queryFeatureLayer.createQuery(); set the queryObject params run query 1. queryFeatureLayer.queryFeatures(queryObject) 2. .then((layerView) => { ... } My guess is that the server responded with zero results or did not complete the query at all. Running the query a second time often works, so my workaround is to run again. if(error.message.indexOf('featureResult') > -1) { setTimeout(() => { run the query again }, 350);
... View more
03-22-2023
09:18 AM
|
0
|
0
|
754
|
|
POST
|
Sorry, I should have made it clear that the after-remove fragment in my post is not in context. I did place the after-remove event before line 14.
... View more
03-22-2023
07:27 AM
|
0
|
5
|
1621
|
|
POST
|
I am adding buffer graphics to 2D MapView and would like to have an event on the add\remove to check for errors. The "on" event below doesn't report an event. const bufferLayer = new GraphicsLayer({
title: 'some-bufferLayer',
});
let geometry = sketchGeometry; // a polygon
const bufferGeometry = geometryEngine.geodesicBuffer(
geometry, // geometry, The buffer input geometry
buffer_size, // distance, The specified distance(s) for buffering
unitType, // unit, Measurement unit of the distance
false // unionResults, Default Value: false
);
if (bufferLayer.graphics?.length === 0) {
bufferLayer.add(
new Graphic({
geometry: bufferGeometry,
symbol: sketchViewModel.polygonSymbol,
})
);
} else {
bufferLayer.remove(bufferGeometry);
bufferLayer.graphics.getItemAt(0).geometry = bufferGeometry;
}
view.map.add(bufferLayer);
// ???
// No event happening here.
bufferLayer.graphics.on("after-remove", function(event){
});
... View more
03-22-2023
07:04 AM
|
0
|
7
|
1631
|
|
POST
|
Hi. Thank you for helping me. You can see it in action here or try it at the URL below. Also, I added the code below. Basically, the pick list item uses a very acceptible check icon. I could change the calcite-list-item icon in Chrome devtools, but I cannot find where to override it in code. It sounds like I may need to just go back to using the pick list until calcite-list supports more icons. https://www.manateepao.gov/parcel/?display=fullaerial&referer=search /***
* Checkable list of tax parcel types to filter buffer results.
*/
function buildTaxParcelTypesComponent() {
return new Promise((resolve) => {
getTaxParcelTypes()
.then((result) => {
let block = document.createElement('calcite-block');
block.setAttribute('id', 'pao-taxparceltypes-block');
block.setAttribute('heading', 'Filter by tax parcel type');
block.setAttribute('collapsible', '');
block.setAttribute('hidden', '');
block.setAttribute('description', 'Click to open'); // default is closed
block.addEventListener('calciteBlockToggle', (event) => {
setBlockDescription(
event.target.id,
event.target?.open,
'Click to open'
);
});
let slot = document.createElement('calcite-icon');
slot.setAttribute('scale', 's');
slot.setAttribute('slot', 'icon');
slot.setAttribute('icon', 'filter');
block.appendChild(slot);
let list = document.createElement('calcite-list');
let taxparcelTypes = document.createElement('calcite-list');
taxparcelTypes.setAttribute('id', 'pao-taxparceltypes-list');
taxparcelTypes.setAttribute('selection-mode', 'multiple');
taxparcelTypes.setAttribute('selection-appearance', 'icon');
taxparcelTypes.setAttribute('scale', 's');
taxparcelTypes.setAttribute('heading-level', '1');
// Skip event if resetting.
taxparcelTypes.addEventListener('click', (event) => {
if (!bufferWasReset) handleTaxParcelTypesChange(event);
});
Object.keys(result.features).forEach((key) => {
let tp = result.features[key].attributes['TAXPARCELTYPE'];
let item = document.createElement('calcite-list-item');
item.setAttribute('overlay-positioning', 'absolute');
item.setAttribute('selected', '');
item.setAttribute('label', tp);
item.setAttribute('value', tp);
let action = document.createElement('calcite-action');
action.setAttribute(
'id',
`${tp.replace(/ /g, '-').toLowerCase() + '-action'}`
);
action.setAttribute('slot', 'actions-start');
action.setAttribute('appearance','transparent');
let span = document.createElement('span');
span.style.width = '16px';
span.innerHTML = ' '; // color will not render without hard space
action.appendChild(span);
item.appendChild(action);
taxparcelTypes.appendChild(item);
list.appendChild(taxparcelTypes);
});
// Default Tax Parcel Types
if (taxParcelTypesDefaultString === '') {
let taxParcelTypesArray = [];
let children = Array.from(list.children[0].children);
children.forEach((item) => {
taxParcelTypesArray.push(item.value);
});
// Use qualitative colors.
// fifo
let ramp = {
[0]: { rgb: '63,0,125' },
[1]: { rgb: '251,154,153' },
[2]: { rgb: '153,52,4' },
[3]: { rgb: '31,120,180' },
[4]: { rgb: '26,26,26' },
[5]: { rgb: '227,26,28' },
[6]: { rgb: '10,247,199' },
[7]: { rgb: '166,206,227' },
[8]: { rgb: '202,178,214' },
[9]: { rgb: '106,61,154' },
[10]: { rgb: '255,255,153' },
[11]: { rgb: '177,89,40' },
[12]: { rgb: '231,225,239' },
[13]: { rgb: '201,148,199' },
[14]: { rgb: '221,28,119' },
[15]: { rgb: '241,238,246' },
};
// Create array of tax type colors
if (taxParcelTypesArray?.length > 0) {
let s = taxParcelTypesArray.map((v) => `'${v}'`);
taxParcelTypesDefaultString = s.join(',');
taxParcelTypesSelectedString = taxParcelTypesDefaultString;
taxParcelTypeColors = taxParcelTypesArray.reduce(
(acc, cur, idx) => {
if (idx > Object.keys(ramp).length) idx--;
let obj = {};
obj[cur] = `rgba(${ramp[idx].rgb},0.4)`;
acc.push(obj);
return acc;
},
[]
);
}
// Assign style to tax parcel type list item.
children.forEach((item) => {
item.childNodes.forEach((ch) => {
if (ch.nodeName.toLowerCase() === 'calcite-action') {
let id = `${
item.value.replace(/ /g, '-').toLowerCase() + '-action'
}`;
if (ch.id === id) {
ch.childNodes.forEach((n) => {
if (n.nodeName === 'SPAN') {
let rgb = taxParcelTypeColors.filter((obj) => {
if (obj)
if (Object.keys(obj)[0] === item.value)
return obj[item.value];
});
if (rgb && rgb.length > 0)
n.style.backgroundColor = rgb[0][item.value];
n.style.borderRadius = '50%';
}
});
}
}
});
});
}
block.appendChild(list);
let panel = document.getElementById('pao-buffer-container');
if (panel) panel.appendChild(block);
resolve(true);
})
.catch((error) => {doLogException('buildTaxParcelTypesComponent->getTaxParcelTypes', error);});
});
} // end
/**
* Query ArcGIS for tax parcel types.
* @returns
*/
function getTaxParcelTypes() {
return new Promise((resolve) => {
let queryObject = new Query({
outSpatialReference: view.spatialReference,
returnGeometry: false,
returnIdsOnly: false,
returnCountOnly: false,
returnZ: false,
returnM: false,
returnDistinctValues: true,
returnExtentOnly: false,
orderByFields: ['TAXPARCELTYPE'],
outFields: ['TAXPARCELTYPE'],
where: '1=1', // where is required.
});
query
.executeQueryJSON(parcelSearchUrl, queryObject)
.then((result) => {
resolve(result);
})
['catch']((error) => {
doLogException('getTaxParcelTypes', error);
});
});
} // end I am adding a custom action to get the color bullets.
... View more
03-14-2023
01:03 PM
|
0
|
2
|
2372
|
|
POST
|
I probably could reach it with the code below, but I'm not exactly sure where in the action icon is the shadowRoot to change. await customElements.whenDefined('calcite-list-item'); await delay(300); let node = document.querySelector(`#some-list-here`); if (node) { let el = node.shadowRoot.querySelectorAll('calcite-list-item'); if (el) { el.forEach((item) => { I'm not sure where the icon is in the shadowRoot // item.style.setProperty('icon', 'check'); }); } } From the website sample app. <html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<script type="module" src=https://js.arcgis.com/calcite-components/1.0.7/calcite.esm.js></script>
<link rel="stylesheet" type="text/css" href=https://js.arcgis.com/calcite-components/1.0.7/calcite.css />
</head>
<body>
<calcite-list selection-mode="multiple">
<calcite-list-item label="Hiking trails" value="hiking-trails">
<calcite-action slot="actions-start" icon="layer" text="Trails layer"></calcite-action>
</calcite-list-item>
<calcite-list-item label="Waterfalls" value="waterfalls">
<calcite-action slot="actions-start" icon="layer" text="Waterfalls layer"></calcite-action>
</calcite-list-item>
<calcite-list-item label="Rivers" value="rivers">
<calcite-action slot="actions-start" icon="layer" text="Rivers layer"></calcite-action>
</calcite-list-item>
</calcite-list>
</body>
</html>
... View more
03-14-2023
12:14 PM
|
0
|
0
|
2391
|
|
POST
|
Before replacing the deprecated pick list item with the calcite-list-item, the selection-appearance icon defaulted to a simple check. I think the calcite-list-item selection-appearance icon looks really bad, especially with my design. I would like to override it or not show it at all. (BAD) calcite-list-item (GOOD) calcite-pick-list-item How do I change the icon to 'check' in JS or CSS?
... View more
03-14-2023
11:33 AM
|
0
|
6
|
2409
|
|
POST
|
I was at first worried the mouse and keyboard would still zoom with constraints, but now I am using it and it works just right. Thanks.
... View more
03-13-2023
07:40 AM
|
1
|
0
|
832
|
|
POST
|
Thanks! I can check the size of the sketch, but not sure how to block drawing without destroying the sketch. I found this in community, but I'm not seeing a 'move'. There is a 'cursor-update'. no 'move'
if (event.toolEventInfo && event.toolEventInfo.type.includes("move")){
sketchViewModel.cancel();
} if(event.state === 'active') {
// console.log(`H ${event.graphic.geometry.extent.height} x W ${event.graphic.geometry.extent.width}`);
if(event.graphic.geometry.extent.width > 200) {
if (event.toolEventInfo && event.toolEventInfo.type.includes('cursor-update')) {
// cancel() completely destroying the sketch.
// how to just stop drawing the width without killing sketch?
sketchViewModel.cancel();
}
}
}
... View more
03-09-2023
10:39 AM
|
0
|
0
|
830
|
|
POST
|
I found this code to disable zoom. Any idea how restore or undo disable zooming, including removing the stepPropagation event? I checked the events in Chrome dev tools event listeners, but couldn't find it. function disableZooming() {
// Removes the zoom action on the popup
view.popup.actions = [];
// stops propagation of default behavior when an event fires
function stopEvtPropagation(event) {
event.stopPropagation();
}
// exlude the zoom widget from the default UI
view.ui.components = ["attribution"];
// disable mouse wheel scroll zooming on the view
view.on("mouse-wheel", stopEvtPropagation);
// disable zooming via double-click on the view
view.on("double-click", stopEvtPropagation);
// disable zooming out via double-click + Control on the view
view.on("double-click", ["Control"], stopEvtPropagation);
// disables pinch-zoom and panning on the view
view.on("drag", stopEvtPropagation);
// disable the view's zoom box to prevent the Shift + drag
// and Shift + Control + drag zoom gestures.
view.on("drag", ["Shift"], stopEvtPropagation);
view.on("drag", ["Shift", "Control"], stopEvtPropagation);
// prevents zooming with the + and - keys
view.on("key-down", (event) => {
const prohibitedKeys = ["+", "-", "Shift", "_", "=", "ArrowUp", "ArrowDown", "ArrowRight", "ArrowLeft"];
const keyPressed = event.key;
if (prohibitedKeys.indexOf(keyPressed) !== -1) {
event.stopPropagation();
}
});
}
... View more
03-09-2023
09:36 AM
|
0
|
2
|
874
|
|
POST
|
I'm looking to restrict the size of a polygon that a user can create with the sketch tool based on current extent. I can calculate the distance between lat and lon, but I will need an event that I can monitor while the polygon is being drawn. const sketchLayer = new GraphicsLayer();
sketchViewModel = new SketchViewModel({
view: view,
layer: sketchLayer,
pointSymbol: pointSymbol,
polylineSymbol: polylineSymbol,
polygonSymbol: polygonSymbol,
snappingOptions: {
enabled: true,
featureSources: [{ layer: sketchLayer, enabled: true }],
},
mode: 'click',
defaultCreateOptions: {
hasZ: false,
enableScaling: false,
enableRotation: false,
toggleToolOnClick: false,
shapeOperation: 'none',
},
updateOnGraphicClick: false,
});
sketchViewModel.on('create', (event) => {
if (event.state === 'complete') {
// know if the polygon dimensions are valid size before getting here.
}
});
... View more
03-06-2023
02:33 PM
|
0
|
2
|
860
|
|
POST
|
Thank you. Your answer indeed solves the drawback to client-side buffering. I made the change and it works well, performance is close to client-side with some minor noticeable delay in the buffer polygon. I also had enable returnGeometry and remove returnDistinctValues because it's not supported with it. I am curious to know why "queryFeatures" throws an error "TypeError: Cannot read properties of undefined (reading 'featureResult')" after several continuous queries are made. Basically, after a few queries, the response from ArgGIS server is empty and results in the error above. The error doesn't prevent subsequent queries, but I decided to handle the error by detecting it and continuing. Has to be a better way.
... View more
03-01-2023
02:33 PM
|
0
|
1
|
1468
|
|
POST
|
I have a buffer featureLayer query that does not return features if part of the buffered area in the view is off screen. How can I get buffer results in this situation? Thanks. What is meant by "available to or visible" here in the documentation? I always want to return available regardless of visibile. To query features/graphics available to or visible in the View on the client rather than making a server-side query, you must use the FeatureLayerView.queryFeatures() method. https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#queryFeatures Here's my procedural code fragment. Step 1. Create queryFeatureLayer
const queryFeatureLayer = new FeatureLayer({
url: url,
geometryType: 'polygon',
title: 'myfeatureLayer',
spatialReference: {
wkid: 102659,
},
outFields: [
'OBJECTID',
and others...
]
});
Step 2. Wait for global object mapLayerView to be ready then run queryLayerView()
reactiveUtils
.whenOnce(() => !mapLayerView.updating)
.then(() => {
queryLayerView();
Step 3. Execute the queryLayerView
const queryObject = mapLayerView.createQuery();
queryObject.geometry = sketchGeometryMode();
queryObject.units = unitType;
queryObject.distance = bufferSize;
queryObject.spatialRelationship = 'intersects';
queryObject.outSpatialReference = view.spatialReference;
queryObject.returnQueryGeometry = true;
queryObject.returnDistinctValues = true;
queryObject.outFields = ['*'];
Step 4. Get results
return mapLayerView
.queryFeatures(queryObject)
.then((layerView) => { ... }
... View more
02-28-2023
12:38 PM
|
0
|
3
|
1499
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 10-30-2024 01:32 PM | |
| 1 | 03-18-2024 08:18 AM | |
| 1 | 01-08-2024 07:24 AM | |
| 3 | 12-30-2022 11:36 AM | |
| 1 | 03-13-2023 07:40 AM |
| Online Status |
Offline
|
| Date Last Visited |
09-12-2025
08:55 AM
|