Remove graphic based on it's geometry

1170
6
Jump to solution
11-09-2012 12:49 PM
AndrewBrown1
Occasional Contributor II
Just to give you a heads up of what the viewer is doing:

Using identifyTask, a bunch of soil borings are queried and their attributes are displayed on a table at the bottom of a screen. Initially, all of the queried soil borings are highlighted on the map (symbols) and the records are selected (checked) in the table (dojox.grid.enhancedgrid with the indirectSelection plugin). What I need to have happen is, if the user deselects a row in the table, the corresponding soil boring needs to unselect itself.

For the code, since I have multiple layers, the soil borings are written to a specific array based on the queryResults.layerName
case "bore":                                         if (!arrayBore.displayFieldName) { arrayBore.displayFieldName = idResult.layerName };                                         arrayBore.geometryType = idResult.geometryType;                                         arrayBore.features.push(idResult.feature);                                         break;


And since the table contains tabs based on each layer selected, the "soil boring" tab is created with the results:
if (arrayBore.displayFieldName) {                                 newTab = new dijit.layout.ContentPane({ title: arrayBore.displayFieldName, content: layerTabContent(arrayBore, "arrayBore", type), closable: true, id: "tabBore", style: "overflow-y:auto" });                                 dijit.byId("tabs").addChild(newTab); //content is added to the table                             }


When the table is built, within function layerTabContent, I have two events: onSelected and onDeselected, which fire according to the user's interaction with the checkbox in the table.
Right now, this is what I have:
dojo.connect(resultGrid, 'onDeselected', function (rowId) {                 map.graphics.remove(layerResults.features[rowId]);             }); //connect


And it doesn't work. It doesn't throw any errors, but it just doesn't remove that specific graphic from the map. Could somebody help me figure out why a specific record's graphic isn't being removed from the map?

This is what the layerResults.features[rowId] object looks like within Chrome's debugger:

layerResults.features[rowId].geometry: Object spatialReference: Object type: "point" x: 468744.3380974941 y: 2011151.794075489 __proto__: Object


Sorry, I'm still new at Javascript, and I've been teaching myself everything thus far. I apologize for any ignorance.

Thanks,
Andrew
0 Kudos
1 Solution

Accepted Solutions
AndrewBrown1
Occasional Contributor II
I was actually able to fix this by using dojo.filter on my graphicsLayer.graphics, and by matching up the OBJECTIDs to the points. I found out about this through reading an older post in this forum.

Disregard layerName, as that's for something else.

My code is below:

function addRemoveFeature(feature, layerName) {             var t = dojo.filter(mapGraphics.graphics, function (item) {                 return item.attributes.OBJECTID == feature.attributes.OBJECTID;             });             if(t.length == 0){                 var symbol;                 var graphic;                 switch (feature.geometry.type) {                     case "point":                         symbol = new esri.symbol.SimpleMarkerSymbol();                         var pt = new esri.geometry.Point(feature.geometry.x, feature.geometry.y, map.spatialReference);                         break;                     case "polygon":                         symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([98, 194, 204]), 2), new dojo.Color([98, 194, 204, 0.5]));                         var pt = new esri.geometry.Polygon(map.spatialReference);                         pt = feature.geometry;                         break;                 }                 graphic = new esri.Graphic(pt, symbol, feature.attributes)                 graphic.layerName = layerName;                 mapGraphics.add(graphic);             }             else{                 var graphic = t[0];                 mapGraphics.remove(graphic);             }         }

View solution in original post

6 Replies
DouglasHall
New Contributor III
Hard to say what could be occurring, but a couple things to check --

1. You may have already done this, but in Chrome debugger, set a break point to see if you are actually getting to map.graphics.remove()

2. Make sure that you are disconnect 'ing when through with functionality and then reconnecting as this functionality is started and stopped.
//starting
var mySelectedEvent = dojo.connect(resultGrid, 'onDeselected', function (rowId) {...
//stopping
if (mySelectedEvent) { dojo.disconnect(mySelectedEvent); }

It does bring up the question to me, how does the graphics layer know which graphic to remove? How does it compare 2 graphics for equality? By reference? By spatial and then attribute  data both or one or the other other?

3. In your debugger, check out the map.graphics array to see what is in there, maybe you can loop through and find the graphic that way and pass it to remove(). <<< ---YOU KNOW WHAT -- I BET THIS IS ACTUALLY THE ANSWER. It's using an object reference to test for equality in the remove() function. When you are calling map.graphics.remove(layerResults.features[rowId]);, I bet it's not the same object reference as when added to graphics.

If you can't figure it out, you can always map.graphics.clear() and then add the features, minus the deleted feature, back to the map.

FYI, check out this snippet that for IdentifyTask that only returns layers in scale http://www.spatialexception.org/posts/arcgis-javascript-identifytask-returns-scale-dependent-layers
0 Kudos
AndrewBrown1
Occasional Contributor II
Doug, thanks for your help.

To answer your questions, I'm dynamically creating dojo tables (enhanced grids) and the rows in the tables represent the graphic on the map. For example, if the user "identifies" three different point layers, each point layer will be distinguished by tabbed tables, for each different point layer. Each row within the table in the tabs represents a point. All tabbed tables' rows are selected, "checked", upon initialization. Once the user "deselects" a row within a given tab, the graphic representing that feature within the table will be remove from the map. I was able to do this in a previous project, but my tables were static and things were set up a little different. This time, the tables are created depending on how many different layers were "identified" by the user, and I'm dealing with 8 layers (6 point, 2 polygon).

I've redesigned the way the graphics are added to the map; however,I cannot remove the graphics from the map even if I duplicate the same method used to add graphics!

I'm out of ideas and this has been bugging me for a while. Below is my entire code base, beginning with the identifyTask results through the onSelect/onDeselect events. Any help would be much appreciated!

        function selectQueryFunction(geometry) {
           identifyTask info goes here
            try {
                identifyTask.execute(identifyParams, _buildTable("identify"));
            }
            catch (e) {
                console.log("error in selectQueryFunction");
                console.log(e);
            }
        }
        function _buildTable(type) {
            try{
                return function (queryResults) {
                    try {
                        if (queryResults.length > 0) {
                            var panel = Ext.getCmp("southPanel"); //bottom panel
                            if (panel.collapsed) {
                                panel.expand(true);
                            }
                            var results = { displayFieldName: null, features: [], layerId: null };
                            var arraySurfaceWater = { displayFieldName: null, features: [], layerId: 2 };
                            var arraySediment = { displayFieldName: null, features: [], layerId: 3 };
                            var arrayHydropunch = { displayFieldName: null, features: [], layerId: 4 };
                            var arrayWell = { displayFieldName: null, features: [], layerId: 5 };
                            var arraySurfaceSoil = { displayFieldName: null, features: [], layerId: 6 };
                            var arrayBore = { displayFieldName: null, features: [], layerId: 7 };
                            var arrayOther = { displayFieldName: null, features: [], layerId: 8 };
                            var arrayBuildings = { displayFieldName: null, features: [], layerId: 10 };
                            var arraySites = { displayFieldName: null, features: [], layerId: 11 };

                            for (var i = 0, il = queryResults.length; i < il; i++) {
                                var idResult = queryResults; //pulls the individual result
                                switch (idResult.layerName) {
                                    case "Surface Water":
                                        if (!arraySurfaceWater.displayFieldName) { arraySurfaceWater.displayFieldName = idResult.layerName };
                                        arraySurfaceWater.features.push(idResult.feature);
                                        break;
                                    case "Sediment":
                                        if (!arraySediment.displayFieldName) { arraySediment.displayFieldName = idResult.layerName };
                                        arraySediment.features.push(idResult.feature);
                                        break;
                                    case "Hydropunch":
                                        if (!arrayHydropunch.displayFieldName) { arrayHydropunch.displayFieldName = idResult.layerName };
                                        arrayHydropunch.features.push(idResult.feature);
                                        break;
                                    case "Groundwater Well":
                                        if (!arrayWell.displayFieldName) { arrayWell.displayFieldName = idResult.layerName };
                                        arrayWell.features.push(idResult.feature);
                                        break;
                                    case "Surface Soil":
                                        if (!arraySurfaceSoil.displayFieldName) { arraySurfaceSoil.displayFieldName = idResult.layerName };
                                        arraySurfaceSoil.features.push(idResult.feature);
                                        break;
                                    case "Soil Boring":
                                        if (!arrayBore.displayFieldName) { arrayBore.displayFieldName = idResult.layerName };
                                        arrayBore.features.push(idResult.feature);
                                        break;
                                    case "Other":
                                        if (!arrayOther.displayFieldName) { arrayOther.displayFieldName = idResult.layerName };
                                        arrayOther.features.push(idResult.feature);
                                        break;
                                    case "Buildings":
                                        if (!arrayBuildings.displayFieldName) { arrayBuildings.displayFieldName = idResult.layerName };
                                        arrayBuildings.features.push(idResult.feature);
                                        break;
                                    case "Sites":
                                        if (!arraySites.displayFieldName) { arraySites.displayFieldName = idResult.layerName };
                                        arraySites.features.push(idResult.feature);
                                        break;
                                } //switch
                            } //for
                            var newTab;
                            if (arraySurfaceWater.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arraySurfaceWater.displayFieldName, content: layerTabContent(arraySurfaceWater, type), closable: true, id: "tabSurfaceWater", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arraySediment.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arraySediment.displayFieldName, content: layerTabContent(arraySediment, type), closable: true, id: "tabSediment", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arrayHydropunch.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arrayHydropunch.displayFieldName, content: layerTabContent(arrayHydropunch, type), closable: true, id: "tabHydropunch", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arrayWell.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arrayWell.displayFieldName, content: layerTabContent(arrayWell, type), closable: true, id: "tabWell", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arraySurfaceSoil.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arraySurfaceSoil.displayFieldName, content: layerTabContent(arraySurfaceSoil, type), closable: true, id: "tabSurfaceSoil", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arrayBore.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arrayBore.displayFieldName, content: layerTabContent(arrayBore, type), closable: true, id: "tabBore", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arrayOther.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arrayOther.displayFieldName, content: layerTabContent(arrayOther, type), closable: true, id: "tabOther", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arrayBuildings.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arrayBuildings.displayFieldName, content: layerTabContent(arrayBuildings, type), closable: true, id: "tabBuildings", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }
                            if (arraySites.displayFieldName) {
                                newTab = new dijit.layout.ContentPane({ title: arraySites.displayFieldName, content: layerTabContent(arraySites, type), closable: true, id: "tabSites", style: "overflow-y:auto" });
                                dijit.byId("tabs").addChild(newTab);
                            }

                        } //if
                    }
                    //for zoomTo
                };  //return
            }
        }
0 Kudos
AndrewBrown1
Occasional Contributor II
Here is the second part of my code since I had too much. This part is what really matters:

        function layerTabContent(layerResults, layerName,type) {
            var selectedLayers = [];
            var items = dojo.map(layerResults.features, function (result) {
                var symbol;
                switch (result.geometry.type) {
                    case "point":
                        symbol = new esri.symbol.SimpleMarkerSymbol();
                        var pt = new esri.geometry.Point(result.geometry.x, result.geometry.y, map.spatialReference);
                        break;
                    case "polygon":
                        symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([98, 194, 204]), 2), new dojo.Color([98, 194, 204, 0.5]));
                        var pt = new esri.geometry.Polygon(map.spatialReference);
                        pt = result.geometry;
                        break;
                }

                mapGraphics.add(new esri.Graphic(pt, symbol, result.attributes));
                //var graphic = new esri.Graphic(result.geometry)
                //graphic.setSymbol(symbol);
                selectedLayers.push(pt);
                //map.graphics.add(graphic);
                //                structure.push(layerResults.features.attributes);
                return result.attributes;
            });
            var data = {
                items: items
                //items: structure
            };//data
            var selectStore = new dojo.data.ItemFileReadStore({ data: data});
            //normally I use 'items'
            var fieldNameArr = createTableSchema(items);
            var resultGrid = new dojox.grid.EnhancedGrid({
                query: {
                    OBJECTID: '*'
                },
                //id: gridId,
                clientSort: true,
                structure: fieldNameArr,
                rowsPerPage: 50,
                height: "300px",
                autoWidth: true,
                autoHeight: true,
                plugins: {
                    indirectSelection: {
                        name: "Select",
                        field: "Select",
                        width: "50px",
                        styles: "text-align: center;"
                    }//indirect
                }//plugins
            });//resultGrid
            resultGrid.setStore(selectStore);
            resultGrid.startup();
            resultGrid.rowSelectCell.toggleAllSelection(true);
            resultGrid.update();
            resultGrid.resize();
            var disconnect = dojo.connect(resultGrid, 'onDeselected', function (rowId) {
                mapGraphics.remove(layerResults.features[rowId]);
                //map.graphics.remove(layerResults.features[rowId]);
            });     //connect
            if (disconnect) { dojo.disconnect(disconnect); } //disconnect
            var connect = dojo.connect(resultGrid, 'onSelected', function (rowId) {
                mapGraphics.add(layerResults.features[rowId]);
                //map.graphics.add(layerResults.features[rowId]);
            }); //connect
            if (connect) { dojo.disconnect(connect); } //disconnect
            return resultGrid;
        }
0 Kudos
AndrewBrown1
Occasional Contributor II
Looking into this a bit further, it appears that it does not remove the graphic even if the same add/remove function is used. I created a function that specifically creates a graphic and adds or removes it to the map, depending on an "add/remove" variable:

        function addFeature(feature, addRemove) {
            var symbol;
            switch (feature.geometry.type) {
                case "point":
                    symbol = new esri.symbol.SimpleMarkerSymbol();
                    var pt = new esri.geometry.Point(feature.geometry.x, feature.geometry.y, map.spatialReference);
                    break;
                case "polygon":
                    symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([98, 194, 204]), 2), new dojo.Color([98, 194, 204, 0.5]));
                    var pt = new esri.geometry.Polygon(map.spatialReference);
                    pt = feature.geometry;
                    break;
            }
            switch (addRemove) {
                case ("add"):
                    mapGraphics.add(new esri.Graphic(pt, symbol, feature.attributes));
                    break;
                case ("remove"):
                    mapGraphics.remove(new esri.Graphic(pt, symbol, feature.attributes));
                    break;
            }
        }


It initially adds the graphics to the map once the query is complete, but it still doesn't remove them when my row is deselected. It also adds the points to the map upon row SELECTION, after it has been deselected. So, something is wrong with the remove method.

No idea what it could be.
0 Kudos
AndrewBrown1
Occasional Contributor II
I was actually able to fix this by using dojo.filter on my graphicsLayer.graphics, and by matching up the OBJECTIDs to the points. I found out about this through reading an older post in this forum.

Disregard layerName, as that's for something else.

My code is below:

function addRemoveFeature(feature, layerName) {             var t = dojo.filter(mapGraphics.graphics, function (item) {                 return item.attributes.OBJECTID == feature.attributes.OBJECTID;             });             if(t.length == 0){                 var symbol;                 var graphic;                 switch (feature.geometry.type) {                     case "point":                         symbol = new esri.symbol.SimpleMarkerSymbol();                         var pt = new esri.geometry.Point(feature.geometry.x, feature.geometry.y, map.spatialReference);                         break;                     case "polygon":                         symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([98, 194, 204]), 2), new dojo.Color([98, 194, 204, 0.5]));                         var pt = new esri.geometry.Polygon(map.spatialReference);                         pt = feature.geometry;                         break;                 }                 graphic = new esri.Graphic(pt, symbol, feature.attributes)                 graphic.layerName = layerName;                 mapGraphics.add(graphic);             }             else{                 var graphic = t[0];                 mapGraphics.remove(graphic);             }         }
MiriamBrockmann
Occasional Contributor

Thank you! This Answer saved my day!

0 Kudos