ESRI v4.27
I have an array of JSON I'm using to create an array of Graphics to add to my FeatureLayer. The basic structure looks like this:
{
"geometry": {
"x": -8174819.943309489,
"y": 5027492.84864396,
"spatialReference": {
"wkid": 102100,
"latestWkid": 3857
}
},
"attributes": {
"groupId": 16,
"Crash graphic": 17
},
"symbol": {
"angle": 0,
"xoffset": 0,
"yoffset": 0,
"type": "esriPMS",
"url": "https://crsms-dev.uconn.edu/collision-diagram-images/icons/CrashSymbols/Black/FrontToRear.png",
"width": 45,
"height": 45
}
}
I use this data to create a Graphic like so
private getGraphicFromLocal(graphic: any): Graphic {
const markerSymbol = new PictureMarkerSymbol({
width: graphic.symbol.width,
height: graphic.symbol.height,
url: graphic.symbol.url.replace('https://my-dev-server/collision-diagram-images/', '/assets/collision-diagram/'),
})
const localGraphic = {
...graphic,
geometry: {
...graphic.geometry,
type: 'point'
},
symbol: markerSymbol
};
return new Graphic(localGraphic);
}
The URLs resolve fine but for some reason I get a simple point symbol instead of the image stored at the URL. Any insight?
Some background context - I was initially creating a GraphicsLayer instead of a FeatureLayer but because the Editor class isn't compatible with GraphicsLayers I chose to switch.
When using graphics in a FeatureLayer, you can't apply symbology to the individual graphics, you need to use a renderer. More info in the Visualization guide.
https://developers.arcgis.com/javascript/latest/visualization/location-styles/#points
I also messed with this approach like so and get the following result:
const symbol = {
type: 'picture-marker',
url: '/assets/collision-diagram/icons/CrashSymbols/Black/SideswipeOppositeDirection.png',
width: '24px',
height: '24px'
};
const crashRenderer = {
type: 'unique-value',
field: 'groupId',
uniqueValueInfos: [{
value: '16',
symbol: symbol
}]
}
const featureLayerProperties: __esri.FeatureLayerProperties = {
source: graphicsArr,
id: 'groupLayer',
title: 'Group Layer',
objectIdField: 'Crash graphic',
renderer: crashRenderer as __esri.RendererProperties
};
this.collisionMap.addFeatureLayer(featureLayerProperties, mapView).catch((error: any) => console.error(error));
The symbol that's rendered is not the image the URL points to. Am I going about this wrong?
Should it be changing that little red dot under New Haven? Tough to tell, it could be a path issue. You might want to look at the network tab and see if there are any errors. You might need to normalize the url to point to the real path with location.href or maybe import.meta.url, depending on your tooling.
Sorry for the confusion, here's the map with the other layers removed:
The call to fetch the image is successful so that's working. I still can't figure out why the renderer isn't assigning the symbol to the feature. I modified my code a bit to create a new attribute that better describes each unique value.
public addCollisionGraphicLayer(mapView: __esri.MapView): void {
const graphicsArr = [];
const groupJsonArr = this.mapStateObj.groupJson;
console.log(groupJsonArr);
groupJsonArr.forEach((graphic: string) => {
const parsedGraphic = JSON.parse(graphic)
if (this.environment.production) {
graphicsArr.push(Graphic.fromJSON(parsedGraphic.shownGraphic));
} else {
const devGraphic = this.getGraphicFromLocal(parsedGraphic);
console.log('dev graphic', devGraphic);
graphicsArr.push(devGraphic);
}
});
const symbol: __esri.PictureMarkerSymbolProperties = {
url: '/assets/collision-diagram/icons/CrashSymbols/Black/FrontToRear.png',
width: '200px',
height: '200px'
};
const crashRenderer = {
type: 'unique-value',
field: 'symbolType',
uniqueValueInfos: [{
value: 'Front to Rear',
symbol: new PictureMarkerSymbol(symbol)
}]
}
const featureLayerProperties: __esri.FeatureLayerProperties = {
source: graphicsArr,
id: 'groupLayer',
title: 'Group Layer',
objectIdField: 'crashId',
renderer: crashRenderer as __esri.RendererProperties
};
this.collisionMap.addFeatureLayer(featureLayerProperties, mapView).catch((error: any) => console.error(error));
}
private getGraphicFromLocal(graphic: any): Graphic {
console.log('graphic symbol', graphic);
// Create a new Point geometry
const pointGeometry = new Point({
x: graphic.shownGraphic.geometry.x,
y: graphic.shownGraphic.geometry.y,
spatialReference: graphic.shownGraphic.geometry.spatialReference
});
// Create a new graphic object
const localGraphic = new Graphic({
geometry: pointGeometry,
// symbol: graphic.shownGraphic.symbol,
attributes: {
...graphic.shownGraphic.attributes,
symbolType: graphic.symbol
}
});
return localGraphic;
}