|
POST
|
Never mind, I figured out a work around. I'm using a deferred list to execute my identify tasks. In that code, I just checked to see if the layer had any visible layers. If it didn't , I don't create an identify task in the first place.
... View more
08-21-2013
11:17 AM
|
0
|
0
|
1680
|
|
POST
|
I found this thread very helpful and was able to get 99% of the way through my print issue. I'm trying to print not from just one grid, but several, created as a result of executing a series of querytasks on multiple layers. I decided it was acceptable to have one CSV file for all the grid output and I'll rely on the users ability to copy/paste the output into separate work sheets or separate files as needed. My problem is within the function that is supposed to format the data. Somewhere in this code, I'm introducing something that translates into a column shift in the output CSV (I assume a comma). Viewed in Excel, for the first grid the field names start in column A , but all the data that corresponds with it starts in column B, shifted over one column to the right. When I process all subsequent grids, both fields and data start in column B, with nothing in column A. At least for these the names and data line up! Have I taken a simple task and made it complicated? My output looks right, except for the shift in the columns.
function exportGridCSV() {
dataArray.length = 0;
var fieldValue;
var fieldNames = [];
//qTaskNameList created from query task that populated the grids
dojo.forEach(qTaskNameList, function(gridName) {
var gridData = dijit.byId(gridName+"_grid");
var gridLength = gridData.rowCount;
var fields = gridData.layout.cells;
var fieldNames.length = 0;
//populates an array with the field names used to find the values in the data store
dojo.forEach(fields, function (field) {
fieldNames.push(field.field);
dataArray.push(field.field);
});
dataArray.push("\r");//first line is the field names
if (gridLength > 0) {//don't try to export if there were not values in that grid
var gridStore = gridData.store._arrayOfAllItems;//the store of one grid
//for each record, populates the array with the values for the fields stored in the field array
for (var i=0; i< gridStore.length; i++) {
var gridRec = gridStore;
var j = 0;
dojo.forEach (fieldNames, function(fieldName) {
fieldValue = gridRec[fieldName];
if (isNaN(fieldValue)) {//for data containing slashes
if (fieldValue.indexOf('\'') != -1 || fieldValue.indexOf('\"') != -1 || fieldValue.indexOf(',') != -1) {
if (fieldValue.indexOf('\"') != -1) {
fieldValue = fieldValue.replace("\"", "\"\"");
}
fieldValue = "\"" + fieldValue + "\"";
}
}
dataArray.push(fieldValue);
j++;
});
dataArray.push("\r");
}//end of record
dataArray.push("\r"); //puts an empty row before the next set of records
}
});
submitCSVprint();
}
function submitCSVprint() {
//opens the data in a hidden form used for printing and allows the user to either open or save the file.
var url = "webservices/csv.ashx";
var data = dataArray.join();
var f = dojo.byId("downloadForm");
f.action = url;
dojo.byId("reportinput").value = data;
var distType = dijit.byId("distTypeSelect").value;
var distNum = dojo.byId("txtDistNumber").value;
dojo.byId("filename").value = distType+"_Dist_"+distNum+"_";
f.submit();
}
... View more
08-21-2013
11:15 AM
|
0
|
0
|
2216
|
|
POST
|
I have a similar situation, where I'm using the TOC widget and saw that my identify was returning everything. I added the current layer Ids in my IdentifyParameters and that made it stop identifying layers that weren't turned on, even though I had it set to esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE . I thought it was totally working, until I tried unchecking all the boxes associated with a layer in my TOC, while leaving the name of the layer checked (my district layer has 3 different districts within it for house, senate and congressional) . When I went to define my IdentifyParameters, the array of visible layers ended up as [-1]. That wasn't an acceptable input for layerIds. Neither is an empty array. So I changed it to
var visLayers = layer.visibleLayers;
if (visLayers !== -1) {
identifyParams.layerIds = layer.visibleLayers;
}
So only layers that have anything visible in them will have a layerIds parameter defined. My identifyParameters definition is now happy, but my identify still fails. Should I be digging into the TOC code? I noticed that if I uncheck the layer name too, I don't get the error. The default behavior in the TOC is if uncheck everything within a layer, the layer still stays checked as on.
... View more
08-21-2013
08:58 AM
|
0
|
0
|
1680
|
|
POST
|
That was it, thank you so much. I knew the order of the creation mattered, but I didn't realize that startup needed to come after it was added to the pane. In my mind, it needed to happen first.
... View more
08-14-2013
06:14 AM
|
0
|
0
|
2247
|
|
POST
|
Here's another spin on it. Apparently there is data in my datagrid, but I don't see it until I click on a column heading to sort. Then it appears. Maybe this is a style problem. Or maybe the store isn't getting read/loaded until I'm clicking a column because I have something out of sequence?
... View more
08-13-2013
01:27 PM
|
0
|
0
|
2247
|
|
POST
|
That's different enough from what I have that I don't think I want to pull apart what I have. It seems really close. I don't think I have the definition right on the itemfilereadstore. I changed what I had a bit, so I created the datagrid without parameters and then used setStore and setStructure. When I tried this, I could see that my field names were read correctly. I have an empty grid, just headers, but no content.
var grid = new dojox.grid.DataGrid();
grid.setStructure(currentLayout); //this gives me the headers I expect on my grid
grid.setStore(currentStore); //currentstore doesn't look right, I think it's empty
... View more
08-13-2013
01:07 PM
|
0
|
0
|
2247
|
|
POST
|
I have set of functions that will execute a series of querytasks based on the current layer visibility. Now I have a featureset from each querytask, all likely to have different field names, depending on which layer it's from. This means I need to create both the data source and grid on the fly from the results. Each queryTask should create one new titlePane in an existing floating pane, and each titlePane is the container for one datagrid. The title panes are getting added, but my datagrid isn't getting created properly, so the panes are just empty. I think I'm so close, but I'm having problems getting all the pieces I need pulled together to properly create and populate the grid. Elsewhere I created an array of the layer names from the query tasks, while those are getting set up. I'm using this to have a 'real' name to my titlePane, since I don't see that the original layer name is anywhere in the featureset. The div 'attributeDiv' existing already in my floatingPane. function queryGeometryResultsHandler_toGrid(results, idx) { var myDiv = dojo.byId("attributeDiv"); var currentLayerId = qTaskNameList[idx]; var paneTitle = (currentLayerId.split('_').join(' '));//earlier all spaces were replaced _, now I need spaces for the title var tp = new dijit.TitlePane({ id: 'gridPane_'+currentLayerId, title: paneTitle}); myDiv.appendChild(tp.domNode); var itemNames = []; var featureAttributes = dojo.map(results.features, function(feature){ return feature.attributes; }); var firstFeature = featureAttributes[0]; for(var fieldName in firstFeature) { itemNames.push(fieldName); } console.log(itemNames); //gets the field names from the first feature for the grid // for (fieldName in itemNames[0]) { var currentLayout = []; var addField; dojo.forEach(itemNames, function (fieldName) { /* if (fieldName == "FID" || fieldName == "OBJECTID" ) { addField = { field: fieldName, formatter: makeZoomButton }; currentLayout.push(addField); }*/ if (fieldName == "Shape" || fieldName == "FID" || fieldName == "OBJECTID") { addField = { field: fieldName, hidden: true }; currentLayout.push(addField); } else { //console.log("field Name is " + fieldName); addField = { field: fieldName, width: "120px" }; currentLayout.push(addField); } }); console.log(currentLayout); var data = { identifer: "OBJECTID", items: featureAttributes }; var currentStore = new dojo.data.ItemFileReadStore({ data: data }); // Create Grid var grid = new dojox.grid.DataGrid({ id: currentLayerId+"_grid", store: currentStore }, document.createElement('div')); grid.startup(); var currentPane = dojo.byId('gridPane_'+currentLayerId); currentPane.appendChild(grid.domNode); // tp.appendChild(grid.domName); // tp.set("content",grid); // } } 1 - I'm not sure the datagrid has the right input to be correct. Setting breakpoints, I see there is information in the variable 'currentStore'. 2- I'm not sure that appendChild is the correct command to add the grid to the newly created titlePane, so it might be failing there?
... View more
08-13-2013
11:42 AM
|
0
|
7
|
5876
|
|
POST
|
I get what you're saying about changing what is returned from the dojo.filter, but it didn't help. Is there a recommendation on which is the better way to run my queryGeometryResultsHandler_toGrid? I tried dojo.map first:
function cleanQueryResults (queryResults) {
var successResults = [];
queryResults = dojo.filter(queryResults, function (result) {
return results[0];
}); //filter out any failed tasks
for (i=0;i<queryResults.length;i++) {
successResults = successResults.concat(queryResults[1]);//these are all the successful querytasks, an array of featuresets
}
//then process each set of query results
dojo.map(successResults, function (results) {
queryGeometryResultsHandler_toGrid(results);
});
}
Then I switched to dojo.forEach. It seems like to like dojo.map is the better choice. I can see that queryGeometryResultsHandler_toGrid executes one time, but it doesn't ever come back to this to process the other feature sets. Should I be setting a variable for dojo.map and then returning something from that function? That function is still a work in progress. It is supposed to be creating individual titlePanes within an existing div. I commented nearly everything I had out (it was copied from another project and needed tweaking anyway). I expected this to execute for each one of my featureSets that are contained in successResults.
//output query results to grid sample function
function queryGeometryResultsHandler_toGrid(results){
//puts the results of the query into a grid
var tp;
var myDiv = dojo.byId("attributeDiv");
myDiv.innerHTML = "";
var resultsLength = results.features.length;
var grid;
var allItems = dojo.map(results.features, function(feature){
return feature.attributes;
});
for (var i = 0; i < resultsLength; i++) {
var items = allItems.slice(i, (i+1));
var data = {
items: items
};
var currentStore = new dojo.data.ItemFileReadStore({
data: data
});
var currentLayout = [];
var addField;
tp = new dijit.TitlePane({ id: 'gridPane_'+paneId, title: paneId});
myDiv.appendChild(tp.domNode);
/* for (fieldName in items[0]) {
if (fieldName == "FID" || fieldName == "OBJECTID" ) {
addField = { field: fieldName, formatter: makeZoomButton };
currentLayout.push(addField);
}
if (fieldName == "ROWGUID" || fieldName == "Shape" || fieldName == "CITY_NAME" || fieldName == "FID") {
// addField = { field: fieldName, hidden: true };
// currentLayout.push(addField);
} else {
addField = {
field: fieldName,
width: "120px"
};
currentLayout.push(addField);
}
} */
// Create Grid
/*
grid = new dojox.grid.DataGrid({
id: paneId+"_grid",
store: currentStore,
structure: currentLayout
}, document.createElement('div'));
dojo.byId(paneId+"_gridPane").appendChild(grid.domNode);
grid.startup();
grid.canSort = function(){
return false;
};
tp.set("content",grid);
*/
}
}
... View more
08-09-2013
10:30 AM
|
0
|
0
|
861
|
|
POST
|
My goal is to select a legislative district by number, using it's geometry as input to look up different features in that district. There will be lots of different layers the user can turn on/off (schools, nursing homes etc) and the query will select only those features that are currently visible within their district and create a list. The query tasks must therefore be generated on the fly. I am using a posted Fiddle example for a deferred list for identifytasks, modifying it for query tasks instead. (Thanks Brett for such a great example BTW) I have made good progress up to a point, I see that each of my queries are executing. But I'm getting bogged down in how to manage the multiple sets of results that are getting returned as output from each of the tasks. I have an empty array defined as qTaskList to hold all the query tasks needed for the current visibility.
qTaskList = [];
In previous functions I have defined a single Query, called multiQuery that will be used for all the queryTasks I execute. It is defined as:
multiQuery = new esri.tasks.Query();
multiQuery.outSpatialReference = map.spatialReference;
multiQuery.returnGeometry = false;
multiQuery.spatialRelationship = esri.tasks.Query.SPATIAL_REL_CONTAINS;
multiQuery.outFields = ["*"];
These are supposed to generate a set of querytasks, which as put in a deferredlist and then executed.
function runQueries(geometry) {
multiQuery.geometry = geometry;
//Create an array of all layers in the map
var layers = dojo.map(map.layerIds, function(layerId) {
return map.getLayer(layerId);
});
layers = dojo.filter(layers, function(layer) {
return layer.getImageUrl && layer.visible;
}); //Only dynamic layers have the getImageUrl function. Filter so you only query visible dynamic layers
var qtasks = generateQTasks(layers);
var defTasks = dojo.map(qtasks, function (task) {
return new dojo.Deferred();
}); //map each query task to a new dojo.Deferred
var dlTasks = new dojo.DeferredList(defTasks); //And use all of these Deferreds in a DeferredList
dlTasks.then(showQueryResults); //chain showQueryResults onto your DeferredList
for (i=0;i<qtasks.length;i++) { //Use 'for' instead of 'for...in' so you can sync tasks with defTasks
try {
qtasks.execute(multiQuery, defTasks.callback, defTasks.errback); //Execute each task
} catch (e) {
console.log("Error caught");
console.log(e);
defTasks.errback(e); //If you get an error for any task, execute the errback
}
}
}
//function used to determine which layer visibility of each ArcGISDynamicMapServiceLayer
function generateQTasks(layers) {
qTaskList.length = 0;
dojo.map(layers, function (layer){
if (layer.id !== "districtLayer") {//don't run querytasks against the layer used in the findtask, it's not needed
var visLayers = getVisibleLayers(layer);
dojo.forEach(visLayers, function (layerId){
var qTask = new esri.tasks.QueryTask(layer.url+"/"+layerId);
qTaskList.push(qTask);
});
}
});
return qTaskList;
}
function getVisibleLayers(myLayer) {
var visibleLayers = [];
var items = dojo.map(myLayer.layerInfos, function (info, index) {
layerID = info.id;
if (info.visible && !info.subLayerIds) {
visibleLayers.push(layerID)
}
});
return visibleLayers;
}
This is where I start to get lost. I've added break points and it does look that I have an array, successResults, each of which is a featureSet (I think!). But when I try to process these individually, it only seems to process the first featureSet, not all of them. I know I also have issues in the next function, queryGeometryResultsHandler_toGrid, which is supposed to generate a titlePane in a div for each out the ouput. Probably that will be a whole other thread! For now all I'm trying to do is properly deal with my array of featureSets.
function showQueryResults (queryResults) {
var successResults = [];
queryResults = dojo.filter(queryResults, function (result) {
return queryResults[0];
}); //filter out any failed tasks
for (i=0;i<queryResults.length;i++) {
successResults = successResults.concat(queryResults[1]);//these are all the successful querytasks
}
numberQueryTasks = successResults.length;
//need to process each set of query results
dojo.forEach(successResults, function(taskResults) {
console.log("within dojo foreach of successResults");
queryGeometryResultsHandler_toGrid(taskResults);
});
}
... View more
08-08-2013
12:38 PM
|
0
|
2
|
3653
|
|
POST
|
Since it sounds like you are using a featureLayer, you should just be able to do a clearSelection on it.
... View more
08-07-2013
01:34 PM
|
0
|
0
|
1084
|
|
POST
|
I am using a findTask to search for a district by it's ID number. I need the geometry of this polygon as the input to a queryTask. I figured this would be simple, but I'm having trouble with the syntax on the geometryservice.simplify. I have the reference to my geometryService defined and I have this code set up with proxy pages, in case the number of coordinates from the geometry was somehow the problem. This is the result handler function from my findTask:
function findDistResults(results) {
var result = results[0]; //there should only be unique district numbers found in each layer
// var distExtent = districtGeometry.getExtent();
var resultGeometry = result.feature.geometry;
geometryService.simplify([resultGeometry], function (simplifiedGeometries) {
districtGeometry = simplifiedGeometries[0];
});
runQueries(districtGeometry);
}
The first thing the function runQueries does is set districtGeometry as the geometry for my Query I've defined previously. The querytask looks to failing because it doesn't like the geometry I'm using as input. For grins, I captured the extent of my polygon instead and it uses that just fine as the query geometry input. I tried the polygon first without simplifying it and it didn't work, which is why I'm going through the extra step of trying to simplify it first. Hopefully this is a very basic syntax problem I'm just not seeing. Putting a breakpoint within the function of the geometryService, it doesn't look like it every goes into it.
... View more
08-07-2013
12:53 PM
|
0
|
0
|
1061
|
|
POST
|
Good luck with that. Once I finally got my proxy set up, the code was pretty straight forward. I didn't end up using the print digit, it didn't suit my needs. Instead I created a print task and made my own dialog. I thought the prompts to the user in the dijit, including the fact you had to click on a button to view the output, was a little cludgy.
... View more
07-22-2013
07:39 AM
|
0
|
0
|
1892
|
|
POST
|
Thanks, this helps. I don't quite get why I had to add a margin-top style to get this fixed, but that seems to be what it needed.
... View more
07-19-2013
07:45 AM
|
0
|
1
|
1901
|
|
POST
|
It seems like every time I struggle with making a call that doesn't go anywhere, it isn't in the code at all, it's a proxy page issue. I noticed in your example that you are using machine names as opposed to domain names. That could be part of your problem. A lot of the examples include a proxy subfolder relative to your project, but I have had no luck with that myself. Any time I have to use proxy pages, the only way I seem to get my code to work is to move it from my local machine to my test server. I have a proxy page configuration on it for all maps on that server. Other people don't seem to need to do this. I don't know if it has to do with our firewall settings or some other configuration.
... View more
07-19-2013
05:55 AM
|
0
|
0
|
1892
|
|
POST
|
None of the examples I'm working from with dGrid include startup. I'm not sure where that would happen the way I have this set up. The grids only get defined if the user makes a selection. I noticed this AM I was missing dgrid.css, and I thought that was the missing piece. No go, it didn't fix my problem. Here are the relevant functions. The variable userGeometry is defined by the user drawing a shape (polygon, extent or multiple point) with a drawing toolbar.
function queryFeaturesbyShape(userGeometry){
map.graphics.clear();
eezFeatureLayer.clearSelection();
var clearGrid_bg = dojo.byId('resultsSelectGrid').innerHTML = "";
var clearGridTable = dojo.byId('selectGridTable').innerHTML = "";
var query = new esri.tasks.Query();
query.outSpatialReference = {
wkid: 102100
};
query.returnGeometry = true;
query.outFields = ["*"];
query.geometry = userGeometry;
query.spatialRelationship = esri.tasks.Query.SPATIAL_REL_INTERSECTS;
query.returnGeometry = true;
fLayers = setFeatureLayers();
var bg2010Vis = fLayers.indexOf('eezFeatureLayer');
if (fLayers.indexOf('eezFeatureLayer') >= 0) {
eezFeatureLayer.selectFeatures(query, esri.layers.FeatureLayer.SELECTION_NEW);
var selectHandler = dojo.connect(eezFeatureLayer, "onSelectionComplete", populateBgGrid);
}
}
function populateBgGrid (results) {
var data = [];
if (dGridStacked) {
dGridStacked.refresh();
}
if (dGridTable) {
dGridTable.refresh();
}
data = dojo.map(results, function(feature){
return {
'censusid': feature.attributes['DE_MOEEZ.DEAPPMOEEZGISD.blockGroupCalculations.BlockGroupName'],
'population': formatThousandSeparator(feature.attributes['DE_MOEEZ.DEAPPMOEEZGISD.blockGroupCalculations.Population']),
'unemployment': formatPercentage(feature.attributes['DE_MOEEZ.DEAPPMOEEZGISD.blockGroupCalculations.Unemployment']),
'countypoverty': formatPercentage(feature.attributes['DE_MOEEZ.DEAPPMOEEZGISD.blockGroupCalculations.CountyPoverty']),
'statepoverty': formatPercentage(feature.attributes['DE_MOEEZ.DEAPPMOEEZGISD.blockGroupCalculations.StatePoverty']),
'zonecrosspct': formatOverlap(feature.attributes['DE_MOEEZ.DEAPPMOEEZGISD.blockGroupCalculations.ZoneCrossPct'])
};
});
dGridStacked = new dgrid.Grid({
renderRow: renderRowFunction,
showHeader: true
}, "resultsSelectGrid");
dGridStacked.renderArray(data);
dGridStacked.sort('censusid');
dGridTable = new dgrid.Grid({
id:'dGridTable',
showHeader: true,
bufferRows: Infinity,
columns: {
"censusid": "Block Group",
"population": "Population",
"unemployment": "Unemployment",
"countypoverty": "County Poverty",
"statepoverty": "State Poverty",
"zonecrosspct": "Percent Overlap"
}
}, "selectGridTable");
dGridTable.renderArray(data);
dGridTable.sort('censusid');
dGridStacked.on('.dgrid-row:click', function(event){
eezFeatureLayer.clearSelection();
var row = dGridStacked.row(event);
var query = new esri.tasks.Query();
var queryId = [row.data.censusid];
query.where = "SD_GIS.OGI.CENSUS_BLOCKGRP_2010.GEOID10 = '" + queryId + "'";
query.returnGeometry = true;
query.outFields = ["*"];
var deferred = eezFeatureLayer.selectFeatures(query, esri.layers.FeatureLayer.SELECTION_NEW, function(features){
if (features.length > 0) {
var feature = features[0];
var graphic = new esri.Graphic(feature.geometry, redFillSymbol);
map.graphics.add(graphic);
}
else {
console.log("No records by that ID");
}
});
deferred.addErrback(function(error){
console.log("Grid Select Error = " + error);
});
});
}
//data coming from the query needs to be formatted to look right in the grid
function formatThousandSeparator(checkNumber){
checkNumber += '';
x = checkNumber.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
function formatPercentage (checkNumber) {
var test1= checkNumber.toFixed(3);
var test2 = test1 * 100;
var formatPct = test2.toFixed(1) + "%";
return formatPct;
}
function formatOverlap (checkNumber) {
var test1 = checkNumber.toFixed(1);
var formatPct = test1 + "%";
return formatPct;
}
function renderRowFunction (obj,options) {
// var template = '<div class="title">${0}</div><div class="subtitle"><div class="details">${1}</div> <div class="details"> ${2}<br> ${3}</div>';
var template = '<div class="title">${0}</div><div class="details">Population: ${1}</div> <div class="details">Unemployment: ${2}</div><div class="details">County Poverty: ${3}</div><div class="details"> State Poverty: ${4}</div><div class="details"> Overlap Pct: ${5}</div>';
return dojo.create("div",{
innerHTML : dojo.string.substitute(template,[obj.censusid,obj.population,obj.unemployment,obj.countypoverty,obj.statepoverty,obj.zonecrosspct])
});
}
... View more
07-19-2013
05:39 AM
|
0
|
0
|
1901
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 06-02-2017 02:38 PM | |
| 2 | 03-18-2022 10:14 AM | |
| 2 | 02-18-2016 06:28 AM | |
| 1 | 03-18-2024 07:29 AM | |
| 4 | 08-02-2023 06:08 AM |
| Online Status |
Offline
|
| Date Last Visited |
02-25-2025
01:56 PM
|