Hello all,
I'm migrating a mapping application from Javascript API v3.x to Maps SDK v4. It displays a mosaic layer of an Image Service on our ArcGIS Server 10.9. The Identify feature using esri.tasks.ImageServiceIdentifyTask() worked fine with v3.
Now, the mosaic layer with SDK uses ImageryLayer and the Identify feature uses ImageryLayer's identify() method. But it returns a 'Identify error: can't assign to property "timeExtent" on [url to image service]: not an object' error. The Image Service is not time-enabled.
My simplified code is below. IdentifyTask function is executed upon user's click on the map. The error happens before a REST request is sent. So, the Image Service itself should be fine (the v3 code still works fine and the service returns correct pixel values.). The problem should be within SDK v4 or maybe the backward incompatibility between SDK4 and the Image Service served through ArcGIS Server 10.9? The Image Service was published using the ArcGIS Desktop (from ArcGIS Catalog) not from ArcGIS Pro.
I tried to set timeExtent attribute of ImageIdentifyParameters to null, undefined or even a dummy TimeExtent object. The same setting for timeExtent attribute for ImageryaLayer parameters. But none of them solved the problem.
Any help / tips are more than welcome!
const creatMosaicLayer = () => {
const mosaicId = "...";
const mosicUrl = "...";
const where = "...";
const mosaicRule = new MosaicRule({
method: "attribute",
ascending: true,
operation: "sum",
sortField: "OBJECTID",
where: where
});
const params = {id: mosaicId,
url: mosaicUrl,
pixelFilter: maskPixels,
mosaicRule: mosaicRule,
noData: -1,
interpolation: "nearest",
format: "jpgpng",
visible: true
};
let mosaicLayer = new ImageryLayer(params);
return mosaicLayer;
};
const IdentifyTask = () => {
try {
const params = new ImageIdentifyParameters({
geometry: point,
mosaicRule: layer.mosaicRule,
rasterFunction: layer.rasterFunction,
returnGeometry: false,
returnCatalogItems: true,
returnPixelValues: true,
timeExtent: null // The error happens with/without timeExtent attribute.
});
const response = await layer.identify(layer.url, params);
} catch (error) {
throw new Error(`Identify error: ${error.message}`);
}
};
Solved! Go to Solution.
I solved it myself.
layer.identify(layer.url, params);
should be
layer.identify(params);
Also, I don't need to specify mosaicRule, rasterFunction attributes of the parameter. So, the much simpler code like below works.
const params = new ImageIdentifyParameters({
geometry: point,
maxItemCount: 50
});
const result = await layer.identify(params);
Hi @efujioka, you may need to wait for the layer to load or for the LayerView to be ready before doing the identify.
await layer.load();
// or
await view.whenLayerView(layer);
https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryLayer.html#load
https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View.html#whenLayerView
Thanks for a tip. layer.identify() is kicked by a user action way after the ImageryLayer is rendered on the map. So, it should be loaded.
Actually, I develop this app with React.js and instantiate the ImageryLayer within useEffect() like:
useEffect(() => {
let map = new Map({...});
let mapView = new MapView({...});
mapView.when(() => {
const mosaicRule = new MosaicRule({...});
const params = {id: "...",
mosaicRule: mosaicRule,
interpolation: "nearest",
format: "lerc",
visible: true
};
let mosaicLayer = new ImageryLayer(params);
map.add(mosaicLayer);
mosaicLayer.when(() => {
console.log("mosaicLayer is ready");
});
}, []);
And I click on the map after the browser's console shows "mosaicLayer is ready" message.
Anyway, I modified the line of identity() like:
const params = new ImageIdentifyParameters({
geometry: point,
mosaicRule: layer.mosaicRule,
rasterFunction: layer.rasterFunction,
returnGeometry: true,
returnCatalogItems: true,
returnPixelValues: true,
timeExtent: null
});
await layer.load();
const response = await layer.identify(layer.url, params);
but still the same error.
I solved it myself.
layer.identify(layer.url, params);
should be
layer.identify(params);
Also, I don't need to specify mosaicRule, rasterFunction attributes of the parameter. So, the much simpler code like below works.
const params = new ImageIdentifyParameters({
geometry: point,
maxItemCount: 50
});
const result = await layer.identify(params);