I want to print a map after buffer is completed and show all the highlighted parcels using print widget but I got error message:
Uncaught TypeError: Converting circular structure to JSON
The main code for buffer from here: https://community.esri.com/thread/121140?q=buffer%20results#463851
and use print widget from sample here: https://developers.arcgis.com/javascript/jssamples/widget_print_esri_request.html
Besides that, I also found this thread if you have graphics:
https://community.esri.com/thread/69239
with this solution
var graphic = new esri.Graphic(result.feature.toJson());
But how do you apply it with FeatureLayer or geometry?
Please share you options.
Thank you.
All my map services are secured services and not open to public. When I first click on print button without any search, I able to print a map . But after performed selected search with buffer or without buffer and text search with buffer will got error message, For text search part, I added this line " var graphic = new esri.Graphic(result.feature.toJson());" , so able to print.
I am not sure how to upload the zip file here. So put the codes together below:
Can you help me take a look and try to use your own map services, proxy server, & print task to see if you got those error message?
Thank you for your time.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Buffer</title>
<link rel="stylesheet" href=" http://js.arcgis.com/3.13/dijit/themes/claro/claro.css ">
<link rel="stylesheet" href=" http://js.arcgis.com/3.13/esri/css/esri.css ">
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#leftPane {
color: #000;
width: 250px;
padding-bottom: 15px;
}
#map {
padding: 0;
}
.details {
font-size: 14px;
font-weight: 600;
padding-bottom: 20px;
}
button {
margin: 2px;
cursor: pointer;
}
</style>
<script src=" http://js.arcgis.com/3.13/ "></script>
<script>
require([
"esri/map",
"esri/config", "esri/layers/ArcGISDynamicMapServiceLayer",
"esri/layers/FeatureLayer", "esri/dijit/Print", "esri/tasks/PrintTemplate", "esri/request",
"esri/tasks/FindTask",
"esri/tasks/FindParameters",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/SimpleLineSymbol",
"dojo/request/iframe",
"esri/toolbars/draw",
"esri/tasks/QueryTask",
"esri/tasks/query",
"esri/graphic",
"esri/graphicsUtils",
"esri/geometry/Geometry",
"esri/geometry/Extent",
"esri/SpatialReference",
"esri/geometry/geometryEngineAsync",
"esri/tasks/GeometryService",
"esri/Color",
"dojo/on",
"dojo/dom",
"dijit/registry",
"dojo/_base/array",
"dojox/grid/DataGrid",
"dojo/data/ItemFileReadStore",
"dijit/form/Button",
"dojo/parser",
"dojo/store/Memory",
"dojo/data/ItemFileWriteStore",
"dgrid/OnDemandGrid",
"dojox/grid/EnhancedGrid",
"dojox/grid/enhanced/plugins/exporter/CSVWriter",
"dojox/grid/enhanced/plugins/Printer",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dojo/domReady!"
], function (
Map, esriConfig, ArcGISDynamicMapServiceLayer, FeatureLayer, Print, PrintTemplate, esriRequest, FindTask, FindParameters, SimpleFillSymbol, SimpleLineSymbol, iframe, Draw, QueryTask, Query,
Graphic, graphicsUtils, Geometry, Extent, SpatialReference, geometryEngineAsync, GeometryService,
Color, on, dom, registry, arrayUtils, DataGrid, ItemFileReadStore, Button, parser, Memory,
ItemFileWriteStore, Grid, EnhancedGrid, CSVWriter, Printer) {
var map, center, zoom;
var graphic;
var bufferGra;
var symbol, sfs, symbolP;
var bufferGraF;
var selectionToolbar;
parser.parse();
var printUrl = " http://servername/ags/rest/services/PrintCustom/ExportWebMapSecure3/GPServer/Export%20Web%20Map ";
var initExtent = new esri.geometry.Extent({"xmin":,"ymin":,"xmax":,"ymax":,"spatialReference":{"wkid":}});
esri.config.defaults.io.proxyUrl = " http://servername/proxy/proxy.ashx ";
esri.config.defaults.io.alwaysUseProxy = true;
map = new Map("map",{
extent:initExtent
});
map.on("load", initSelectToolbar);
on(dom.byId("selectFieldsButton"), "click", function () {
selectionToolbar.activate(Draw.EXTENT);
});
var parcelsURL1 = " http://servername/ags/rest/services/Intranet/MapServer ";
map.addLayer(new ArcGISDynamicMapServiceLayer(parcelsURL1,
{ opacity: .95 }));
// get print templates from the export web map task ----------------------
var printInfo = esriRequest({
"url": printUrl,
"content": { "f": "json" }
});
printInfo.then(handlePrintInfo, handleError);
function handlePrintInfo(resp) {
var layoutTemplate, templateNames, mapOnlyIndex, templates;
layoutTemplate = arrayUtils.filter(resp.parameters, function(param, idx) {
return param.name === "Layout_Template";
});
if ( layoutTemplate.length == 0 ) {
console.log("print service parameters name for templates must be \"Layout_Template\"");
return;
}
templateNames = layoutTemplate[0].choiceList;
// remove the MAP_ONLY template then add it to the end of the list of templates
mapOnlyIndex = arrayUtils.indexOf(templateNames, "MAP_ONLY");
if ( mapOnlyIndex > -1 ) {
var mapOnly = templateNames.splice(mapOnlyIndex, mapOnlyIndex + 1)[0];
templateNames.push(mapOnly);
}
// create a print template for each choice
templates = arrayUtils.map(templateNames, function(ch) {
var plate = new PrintTemplate();
plate.layout = plate.label = ch;
plate.format = "PDF";
plate.layoutOptions = {
"authorText": "Made by: Esri's JS API Team",
"copyrightText": "<copyright info here>",
"legendLayers": [],
"titleText": "Pool Permits",
"scalebarUnit": "Miles"
};
return plate;
});
// create the print dijit
printer = new Print({
"map": map,
"templates": templates,
url: printUrl
}, dom.byId("print_button"));
printer.startup();
}
function handleError(err) {
console.log("Something broke: ", err);
}
//End Print Task --------------------------------------------
registry.byId("search").on("click", doFind);
registry.byId("applyBufferPF").on("click", doBuffer);
registry.byId("applyBufferPSel").on("click", applyBufferPSel);
registry.byId("clearParcelGrid").on("click", clearParcelGrid);
//set symbol --------------
symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NULL, new SimpleLineSymbol(SimpleFillSymbol.STYLE_SOLID, new Color([100, 100, 100]), 2), new Color([0, 0, 255, 0.20])); //Gray line
sfs = new SimpleFillSymbol(
SimpleFillSymbol.STYLE_SOLID,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([98, 194, 204]), 2),
new Color([98, 194, 204, 0.3])
); // blue solid
symbolP = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NONE,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_CROSS, new Color([98, 194, 204]), 2),
new Color([98, 194, 204, 0.5])); // symbol for buffer result ring - black solid
//Find Parcel -----------
//Create Find Task using the URL of the map service to search
findTask = new FindTask(" http://servername/ags/rest/services/Intranet/MapServer/ ");
var parcelUrl = " http://servername/ags/rest/services/Intranet/MapServer/12 ";
var featureLayerParcel = new FeatureLayer(parcelUrl, {
mode: FeatureLayer.MODE_SELECTION,
visible: true,
outFields: ["*"]
});
featureLayerParcel.setSelectionSymbol(symbolP);
map.addLayer(featureLayerParcel);
map.on("load", function () {
//Create the find parameters
findParams = new FindParameters();
findParams.returnGeometry = true;
findParams.layerIds = [12];
findParams.searchFields = ["parcelid"];
findParams.outSpatialReference = map.spatialReference;
});
function doFind() {
clearParcelGrid();
//Set the search text to the value in the box
findParams.searchText = dom.byId("Number").value;
findTask.execute(findParams, function (results) {
showResults(results);
});
}
function showResults(results) {
//This function works with an array of FindResult that the task returns
map.graphics.clear();
//create array of attributes
var items = arrayUtils.map(results, function (result) {
//var graphic = result.feature;
var graphic = new esri.Graphic(result.feature.toJson());
graphic.setSymbol(symbol);
map.graphics.add(graphic);
return result.feature.attributes;
});
//Create data object to be used in store
var data = {
identifier: "parcelid", //This field needs to have unique values
label: "parcelid", //Name field for display. Not pertinent to a grid but may be used elsewhere.
items: items
};
//Create data store and bind to grid.
var store = new ItemFileReadStore({
data: data
});
var gridP = registry.byId("gridP");
gridP.setStore(store);
var extent = esri.graphicsExtent(map.graphics.graphics);
map.setExtent(extent, true);
bufferGraF = map.graphics.graphics; // send graphic to buffer
}
function doBuffer(results) {
var graphics = bufferGraF;
var selectedGeoms = graphicsUtils.getGeometries(graphics);
var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([0, 0, 255, 0.65]), 2
),
new Color([0, 0, 255, 0.35])
);
geometryEngineAsync.buffer(selectedGeoms, [100], GeometryService.UNIT_FOOT, true).then(
function (geoms) {
arrayUtils.forEach(geoms, function (geometry) {
map.graphics.add(new Graphic(geometry, symbol));
});
bufferGra = geoms;
intersectParcelsF(); // combine buffer & intersect parcels
}
);
}
//query Parcel
function intersectParcelsF() {
geometryEngineAsync.union(bufferGra).then(
function (union) {
var queryNew = new Query();
queryNew.outFields = ["parcelid"];
queryNew.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
queryNew.geometry = union;
queryNew.returnGeometry = true;
featureLayerParcel.selectFeatures(queryNew, FeatureLayer.SELECTION_ADD, function (features, selectionMethod) {
var items = dojo.map(features, function (feature) {
return feature.attributes;
});
var data = {
identifier: "parcelid",
items: items
};
var store = new ItemFileReadStore({
data: data
});
var grid = registry.byId("parcelGrid");
grid.setStore(store);
symbolInt = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NULL, new SimpleLineSymbol(SimpleFillSymbol.STYLE_NULL, new Color([100, 100, 100]), 2), new Color([0, 0, 255, 0.20])); //Gray line
arrayUtils.forEach(features, function (feature) {
graphic = new Graphic(feature.geometry, symbolInt);
map.graphics.add(graphic);
});
});
}
);
}
//End Find Parcel ---------------
//Select parcel -------------------------
function initSelectToolbar (event) {
map.graphics.clear();
selectionToolbar = new Draw(event.map);
var query2 = new esri.tasks.Query();
on(selectionToolbar, "DrawEnd", function (geometry) {
selectionToolbar.deactivate();
query2.geometry = geometry;
featureLayerP.selectFeatures(query2, esri.layers.FeatureLayer.SELECTION_NEW, function(features, selectionMethod) {
var items30 = dojo.map(features, function(feature) {
return feature.attributes;
});
var data30 = {
identifier: "parcelid",
items: items30
};
var store30 = new dojo.data.ItemFileReadStore({
data: data30
});
var selGrid = registry.byId("gridP");
selGrid.setStore(store30);
selGrid.resize();
map.setExtent(graphicsUtils.graphicsExtent(featureLayerP.getSelectedFeatures()), true);
});
});
}
var featureLayerUrl = " http://servername/ags/rest/services/Intranet/MapServer/12 ";
var featureLayerP = new esri.layers.FeatureLayer(featureLayerUrl, {
mode: esri.layers.FeatureLayer.MODE_SELECTION,
visible: true,
outFields: ["*"]
});
featureLayerP.setSelectionSymbol(symbolP);
map.addLayer(featureLayerP);
//Select Parcel
function intersectParcelsSel() {
geometryEngineAsync.union(bufferGra).then(
function (union) {
var queryNew = new Query();
queryNew.outFields = ["parcelid"];
queryNew.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
queryNew.geometry = union;
queryNew.returnGeometry = true;
featureLayerP.selectFeatures(queryNew, FeatureLayer.SELECTION_ADD, function (features, selectionMethod) {
var items = dojo.map(features, function (feature) {
return feature.attributes;
});
var data = {
identifier: "parcelid",
items: items
};
var store = new ItemFileReadStore({
data: data
});
var grid = registry.byId("parcelGrid");
grid.setStore(store);
symbolInt = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NULL, new SimpleLineSymbol(SimpleFillSymbol.STYLE_NULL, new Color([100, 100, 100]), 2), new Color([0, 0, 255, 0.20])); //Gray line
arrayUtils.forEach(features, function (feature) {
graphic = new Graphic(feature.geometry, symbolInt);
map.graphics.add(graphic);
});
});
}
);
}
function applyBufferPSel() {
alert(featureLayerP.graphics.length);
//Select Parcel
var graphicsSel = featureLayerP.graphics;
var selectedGeomsSel = graphicsUtils.getGeometries(graphicsSel);
var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([0, 0, 255, 0.65]), 2
),
new Color([0, 0, 255, 0.35])
);
geometryEngineAsync.buffer(selectedGeomsSel, [100], GeometryService.UNIT_FOOT, true).then(
function (geoms) {
arrayUtils.forEach(geoms, function (geometry) {
map.graphics.add(new Graphic(geometry, symbol));
});
bufferGra = geoms;
intersectParcelsSel(); // combine buffer & intersect parcels
}
);
}
//End Select Parcel #2 -------------------------------------------------------------------------------------------------
function clearParcelGrid() {
var newStore = new ItemFileReadStore({
data: {
idenitifer: "",
items: []
}
});
var grid = registry.byId("gridP");
grid.setStore(newStore);
var gridParcel = registry.byId("parcelGrid");
gridParcel.setStore(newStore);
featureLayerParcel.clearSelection();
featureLayerP.clearSelection();
map.graphics.clear();
}
});
</script>
<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%;height:100%;margin:0;">
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'" style="height:200px;" title="Search">
Search by Parcel #:
<input type="text" id="Number" size="60"/>
<button id="search" data-dojo-type="dijit.form.Button" type="button" data-dojo-attach-point="button">Search</button>
<button id="applyBufferPF" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-point="button">Buffer</button>
<br>
<button id="selectFieldsButton" data-dojo-type="dijit/form/Button">Select Fields</button>
<button id="applyBufferPSel" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-point="button">Buffer by Selected Parcel</button>
<button id="clearParcelGrid" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-point="button">Clear</button>
<div id="print_button"></div>
<table data-dojo-type="dojox/grid/EnhancedGrid" data-dojo-id="gridP" id="gridP" data-dojo-props="rowsPerPage:'5', rowSelector:'20px', plugins:{printer: true, exporter: true}">
<thead>
<tr>
<th field="parcelid">Parcel ID</th>
</tr>
</thead>
</table>
<br>
<table data-dojo-type="dojox/grid/EnhancedGrid" data-dojo-id="parcelGrid" id="parcelGrid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px', plugins:{printer: true, exporter: true}">
<thead>
<tr>
<th field="parcelid">Parcel ID</th>
</tr>
</thead>
</table>
</div>
<div id="map" data-dojo-props="region:'center'" data-dojo-type="dijit/layout/ContentPane" style="border:1px solid #000;"></div>
</div>
</body>
Thank you so much. It works. Can I ask you last questions before I mark this thread or I need to open a new thread. Not sure. I try to add some functions inside showResults() to can zoom to selected parcels on datagrid record, mouseover to highlight parcel or mouseout. I didn't find any error message when adding those functions. Thanks again.
gridP.on("rowclick", onRowClickHandler);
gridP.on("mouseover", onMouseOverHandler);
gridP.on("mouseout", onMouseOutHandler);
function onRowClickHandler(evt) {
var clickedTaxLotId = evt.grid.getItem(evt.rowIndex).parcelid;
var selectedTaxLot = arrayUtils.filter(parcelGL.graphics, function (graphic) {
return ((graphic.attributes) && graphic.attributes.parcelid === clickedTaxLotId);
});
if ( selectedTaxLot.length ) {
map.setExtent(selectedTaxLot[0].geometry.getExtent(), true);
}
}
function onMouseOverHandler(evt){
if(evt.rowIndex == -1){
return;
}
var grid = registry.byId("gridP");
var rowId = grid.getItem(evt.rowIndex).parcelid;
arrayUtils.some(parcelGL.graphics,function(graphic){
if ((graphic.attributes) && graphic.attributes.parcelid === rowId) {
graphic.setSymbol(sfs);
return true;
}
});
}
function onMouseOutHandler(evt){
arrayUtils.some(parcelGL.graphics,function(graphic){
if (graphic.symbol == sfs) {
graphic.setSymbol(symbolP);
return true;
}
});
};
James,
You definitely need to close this thread by marking it as answered. Your problem is
I try to add some functions inside showResults()
Don't add those "on" event in the showResults() function just add them right after your other event handlers right after:
registry.byId("clearBuffer").on("click", clearBuffer);