|
POST
|
As I keep working on migrating my 3.X app to 4.X, I keep hitting issues. Now, it's print output. The same basic code block, adjusted for 4.X differences, produces a vastly different output. The final part of a custom report generating tool is to produce a JPEG map and insert it into a HTML report output. The output from 3.X produces this: The 4.X API output results in this: It's almost as if there's a "reference scale" setting that I haven't adjusted but, from looking over the API reference, I can't see any. Is there one? There really isn't much to the code side of things so I'm kinda flummoxed but this. FWIW, the relevant 3.X code: tractsShown = theTractLayer.visible;
bgsShown = theBlockgroupLayer.visible;
//Switch the labelling class for Tracts/Block Groups temporarily for proper print sizes
theTractLayer.setLabelingInfo([ app.tractPrintClass ]);
theBlockgroupLayer.setLabelingInfo([ app.bgPrintClass ]);
if (!tractsShown) {
theTractLayer.setVisibility(true);
}
if (!bgsShown) {
theBlockgroupLayer.setVisibility(true);
}
if (highlightGeom != null) {
highlightSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_FORWARD_DIAGONAL,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([255,255,0.1]), 4),new Color([255,255,0,0.1]));
highlightGraphic = new Graphic(highlightGeom, highlightSymbol,null,null);
app.map.graphics.add(highlightGraphic);
}
pTemplate = new PrintTemplate();
pTemplate.exportOptions = {
width: 600,
height: 400,
dpi: 150
};
pTemplate.format = "jpg";
pTemplate.layout = "MAP_ONLY";
pTemplate.preserveScale = false;
pTemplate.showAttribution = false;
var params = new PrintParameters();
params.map = app.map;
params.async = false;
params.template = pTemplate;
jpgMapDiv = theDocument.getElementById("jpegMap");
thePrintTask = new PrintTask(url);
window.setTimeout(function() {
thePrintTask.execute(params, function(result) {
jpgMapDiv.innerHTML = "<img src=\"" + result.url + "\" style=\"border:2px solid black;left:25%\"\>";
var oldExtent = app.preRptExtent;
app.map.setExtent(curExtent);
//Restore the screen-centric label sizes for Tracts/Block Groups
theTractLayer.setLabelingInfo([ app.tractScreenClass ]);
theBlockgroupLayer.setLabelingInfo([ app.bgScreenClass ]);
if (highlightGeom != null) {
app.map.graphics.remove(highlightGraphic);
highlightGraphic = null;
highlightGeometry = null;
}
}, function(err) {
//Print task failed
app.map.graphics.remove(highlightGraphic);
theTractLayer.setLabelingInfo([ app.tractScreenClass ]);
theBlockgroupLayer.setLabelingInfo([ app.bgScreenClass ]);
highlightGraphic = null;
highlightGeometry = null;
});
//Reset the current viewing status of the census tract / blockgroup layers
if (!tractsShown) {
theTractLayer.setVisibility(false);
}
if (!bgsShown) {
theBlockgroupLayer.setVisibility(false);
}
},1000); And the rewritten 4.X- var theTractLayer = app.map.findLayerById("censusTracts");
var tractsShown = theTractLayer.visible;
var theBlockgroupLayer = app.map.findLayerById("censusBlockGroups");
var bgsShown = theBlockgroupLayer.visible;
//Switch the labelling class for Tracts/Block Groups temporarily for proper print sizes
theTractLayer.labelingInfo = [ app.tractPrintClass ];
theBlockgroupLayer.labelingInfo = [ app.bgPrintClass ];
if (!tractsShown) {
theTractLayer.visible = true;
}
if (!bgsShown) {
theBlockgroupLayer.visible = true;
}
if (app.highlightGeom != null) {
var highlightSymbol = new SimpleFillSymbol({
color: new Color([255,255,0,1]),
outline: new SimpleLineSymbol({
cap: "round",
color: new Color([255,255,0,1]),
join: "round",
miterLimit: 1,
style: "solid",
width: 2
}),
style: "forward-diagonal"
});
var highlightGraphic = new Graphic({geometry: app.highlightGeom, symbol: highlightSymbol});
app.theView.graphics.add(highlightGraphic);
}
var pTemplate = new PrintTemplate();
pTemplate.exportOptions = {
width: 600,
height: 400,
dpi: 300
};
pTemplate.format = "jpg";
pTemplate.layout = "map-only";
pTemplate.scalePreserved = false;
pTemplate.attributionVisible = false;
var params = new PrintParameters();
params.view = app.theView;
params.template = pTemplate;
var jpgMapDiv = theDocument.getElementById("jpegMap");
var oldExtent = app.preRptExtent;
//app.theView.goTo(app.curExtent);
print.execute(app.printUrl, params).then(function(printResult) {
jpgMapDiv.innerHTML = "<img src=\"" + printResult.url + "\" style=\"border:2px solid black;left:25%\"\>";
//Restore the screen-centric label sizes for Tracts/Block Groups
theTractLayer.labelingInfo = [ app.tractScreenClass ];
theBlockgroupLayer.labelingInfo = [ app.bgScreenClass ];
if (app.highlightGeom != null) {
app.theView.graphics.remove(highlightGraphic);
highlightGraphic = null;
app.highlightGeom = null;
app.theView.goTo(oldExtent);
}
}).catch(function(printError) {
//Print task failed
app.theView.graphics.remove(highlightGraphic);
theTractLayer.labelingInfo = [ app.tractScreenClass ];
theBlockgroupLayer.labelingInfo = [ app.bgScreenClass ];
highlightGraphic = null;
app.highlightGeom = null;
app.theView.goTo(oldExtent);
});
... View more
09-04-2024
08:09 AM
|
0
|
8
|
2795
|
|
IDEA
|
One of my biggest pet peeves about ESRI is that it constantly takes existing functionality and removes it in subsequent versions. In the 3.X API, infoWindow.Resize(width,height) could be used to adjust the size of the popup according to need. From what I can tell, this isn't really possible in 4.X, except for trying to hack it by modifying the ESRI popup CSS classes (which has not worked for me). Not all maps must be mobile friendly. It's perfectly fine to have apps that are built for the sole purpose of using it with desktop PCs. Sometimes, it's better to have more room to present information back. Restore the resize.
... View more
08-27-2024
02:01 PM
|
3
|
0
|
665
|
|
POST
|
You can't, at least in the same way that QGIS implements this. In Pro, you could achieve the same functionality using a group layer. You would create multiple copies of your layer and use a layer definition query so that each copy only represents one of the possible symbol categories. Once you have all your needed symbol categories as individual layers, select them all, right-click, and chose the option to create a group layer. It's absolutely not as efficient as in QGIS but it should achieve the same result.
... View more
08-26-2024
08:12 AM
|
3
|
1
|
3119
|
|
BLOG
|
The old app I was referring to was created by ESRI (but unsupported) and had the URL of: landsatapp.s3-website-us-west-2.amazonaws.com The url is now dead but that app did have a panchromatic merge option in it. Anyways, thanks for at least confirming that it won't be showing up. Disappointing.
... View more
08-22-2024
09:08 AM
|
0
|
0
|
669
|
|
POST
|
I have some code that works, but not in the way I am intending. I'm using the Sketch widget with a GraphicsLayer and I'm also using the Calcite Color Picker to provide the option to change the color of the sketched graphics. In 3.X, when the dojo color picker would change, I was able to change the color of any new sketched graphics *and* the color of any existing graphics in the graphicsLayer. What I'm experiencing in 4.X is different, when the color is changed in the Calcite color picker, the change event is triggered and the code runs to change the color of the Sketch View Model graphics *and* loop through any graphics in the GraphicsLayer to change the color of those graphics. But visually there is no change. Only when the user draws another graphic will the new graphic and any previous graphic change its color. I want any existing graphic to change its color visually as soon as a color has been selected. Here's a Codepen to try. Draw a polygon. Unselect the graphic. Change the color in the color picker. The existing graphic will not change until you draw a second graphic. What am I missing?
... View more
08-22-2024
09:01 AM
|
0
|
2
|
1556
|
|
BLOG
|
The predecessor for this was the ESRI Landsat APP and it had an option to view a pan-sharpened natural color image. Any chance that this app will get a similar option? I like using this app (and the Sentinel Explorer) to monitor locations in real time and the pan sharpened option is essential for that.
... View more
08-21-2024
09:48 AM
|
0
|
0
|
719
|
|
POST
|
In 3.X, this was quite simple as there was the infoWindow.Resize() method but there seemingly is not an equivalent option in 4.X? The closest thing I found was this thread where someone was using CSS to resize the popup. Unfortunately, this hasn't been working for me and I need to adjust the popup's dimensions a number of times, depending on the layer that was clicked. In my attempt, I'm using reactiveUtil to watch for features being added to the popup: reactiveUtils.watch(()=>theView.popup.features, (event)=>{
// If the zoom-out action is clicked, fire the zoomOut() function
//Attempt to resize the popup based on the layer
if (event.length > 0) {
var theLayerName = theView.popup.features[0].layer.id;
switch(theLayerName) {
case "tipLine":
break;
case "tipPoint":
break;
case "swmCip":
break;
case "schools":
break;
case "parcels":
break;
case "raceTracts":
app.plmf.resizePopupWindow(925,500);
break;
case "raceBlockGroups":
break;
case "povertyTracts":
break;
case "povertyBlockGroups":
break;
case "lepTracts":
break;
case "lepBlockGroups":
break;
case "ageSexTracts":
break;
case "ageSexBlockGroups":
break;
case "disabilityTracts":
break;
case "disabilityBlockGroups":
break;
case "originTracts":
break;
default:
}
}
}); And then the function that is called to attempt to resize the popup is as follows: resizePopupWindow(theWidth,theHeight) {
var theCssWidth = theWidth + 'px !important';
var theCssHeight = theHeight + 'px !important';
var cols = document.querySelectorAll('.esri-view-width-xlarge .esri-popup__main-container, .esri-view-width-large .esri-popup__main-container, .esri-view-width-medium .esri-popup__main-container');
if (cols.length > 0) {
for(var i = 0; i < cols.length; i++) {
cols[i].style.height = theCssHeight;
cols[i].style.width = theCssWidth;
}
}
}
... View more
08-19-2024
08:09 AM
|
0
|
1
|
1182
|
|
POST
|
Wanted to post an update because I have found a way to push through my issues. While searching the forum for some information, I came across this post which, succinctly, laid out an example of how to incorporate your own modules along with the ESRI stuff. The short answer is to ditch AMD and use the ESM IMPORT method rather than dojo require. There were still some fine details in order to get it to work but the linked sample helped me visualize it. First big thing is that in the HTML header your main JS file should be identified as a module rather than just JS. It went from this: <script type="text/javascript" src="js/maing.js"></script> to this: <script type="module" src="js/main.js"></script> Within that JS file, all the require statements went away in favor of this: import postLoadMapFunctions from "./postLoadMapFunctions.js";
import esriConfig from "https://js.arcgis.com/4.30/@arcgis/core/config.js";
import Extent from "https://js.arcgis.com/4.30/@arcgis/core/geometry/Extent.js";
import SpatialReference from "https://js.arcgis.com/4.30/@arcgis/core/geometry/SpatialReference.js";
import esriId from "https://js.arcgis.com/4.30/@arcgis/core/identity/IdentityManager.js"; I'm still using the ESRI CDN so you'll see that the base URL to the CDN version has been inserted before the "@" character. This got things going quickly but there were still hiccups. For example, sometimes you may specify one of objects but you'll get an errror in the console like this one from reactiveUtils: The fix for this is actually quite easy. Change your import reference from this: import reactiveUtils from "https://js.arcgis.com/4.30/@arcgis/core/core/reactiveUtils.js"; to this: import * as reactiveUtils from "https://js.arcgis.com/4.30/@arcgis/core/core/reactiveUtils.js"; The layout/format of your custom modules will be different because, again, there are is no dojo require statement but mine is roughly this: import MapView from 'https://js.arcgis.com/4.29/@arcgis/core/views/MapView.js';
import Map from 'https://js.arcgis.com/4.29/@arcgis/core/Map.js';
import GraphicsLayer from 'https://js.arcgis.com/4.29/@arcgis/core/layers/GraphicsLayer.js';
import Graphic from 'https://js.arcgis.com/4.29/@arcgis/core/Graphic.js';
export default class myModule {
constructor(){
}
setView(view){
this.view = view;
}
connectedCallback() {
let goToButton = document.createElement("div");
goToButton.setAttribute("style", "background-color:#d9dde0;padding:2px 6px;cursor:pointer");
goToButton.textContent = "Add Graphic";
this.shadow.appendChild(goToButton);
goToButton.addEventListener("click", (function(){
this.addGraphic();
}).bind(this));
}
addGraphic(){
let point = {
type: "point",
longitude: -71.2643,
latitude: 42.0909
};
let markerSymbol = {
type: "simple-marker",
color: [226, 119, 40]
};
let graphic = new Graphic({
geometry: point,
symbol: markerSymbol
});
let graphicsLayer = new GraphicsLayer();
graphicsLayer.add(graphic);
this.view.map.add(graphicsLayer);
this.view.goTo(graphic);
}
} From that point, you're really onto just 3.X vs 4.X API changes in your code. Anyways, hope this makes sense and helps some others.
... View more
08-15-2024
12:22 PM
|
1
|
0
|
5045
|
|
POST
|
Thanks. That appears to be what I wanted. That works in my application. Until it does something else unintended. 😂
... View more
08-14-2024
01:32 PM
|
0
|
0
|
1633
|
|
POST
|
Hey Rene, thanks for responding. That sample works great for FeatureLayers but I'm dealing with a GraphicsLayer. Here's a CodePen using the Sketch Widget sample as a base: https://codepen.io/evtguy/pen/xxoPorp I've tried my best to modify the sample to reflect the code in my actual application. Once you open the CodePen, here's what to do: Use the Sketch tool to add a point. Click anywhere in the map to deselect the graphic. Now click on the added point graphic to display the popup. Close the popup. The graphic remains selected.
... View more
08-14-2024
11:05 AM
|
0
|
2
|
1639
|
|
POST
|
I've spent far too much time today trying to figure this out. In the 4.X API, how do you unselect a selected graphic? My specific issue is with a popup on a graphicsLayer where the graphic is not unselected when the popup is closed. FWIW, this would be my relevant code: // Search for graphics at the clicked location
theView.hitTest(screenPoint,{include:theGLayer}).then(function (response) {
if (response.results.length) {
var theContent = app.plmf.graphicsLayerContent(response.results[0].graphic);
var theTitle = "User Defined Project";
theView.openPopup({title:theTitle, content:theContent, location: event.mapPoint});
//}
}
});
});
//Unselect the interactive project when the popup is closed
reactiveUtils.watch(
// getValue function
() => theView.popup.visible,
// callback
(visible) => {
if (visible == true) {
//Do Nothing
} else {
console.log('The popup is closed');
theView.popup.clear();
}
});
... View more
08-13-2024
03:01 PM
|
0
|
4
|
1693
|
|
POST
|
Thanks, guys. I gave the nod to Tony since his post is how I would like to implement this in 4.x but I appreciate the context that GeoGalvanic provided. It is weird how the use of popupTemplate isn't documented in the GraphicsLayer Help Docs but at least it does work. My implementation is literally using one user generated feature so I don't think there's going to be any performance hit in using GraphicsLayer vs FeatureLayer. I also prefer the freedom of storying either a point, line, or polygon in one layer using GraphicsLayer. Cheers!
... View more
08-09-2024
08:55 AM
|
0
|
0
|
2526
|
|
POST
|
Can a 4.x GraphicsLayer have a popup? This was possible in 3.x but I'm not seeing it in 4.x. In my 3.x application, users primarily worked using a combo box picklist of mapped features but I used the GraphicsLayer and Draw toolbar to provide the option of manually drawing a graphic on the map but still take advantage of some reporting functionality that I have in the app. The report functionality could extract some of the information that a user provided when adding the graphic for use inside the final report product. I guess if GraphicsLayers can't have attributes I might have to use a FeatureLayer like one. Ugh. One step forward, two steps backwards..
... View more
08-08-2024
03:47 PM
|
0
|
3
|
2599
|
|
POST
|
THANK YOU! Your approach might be the least painful option for me so I'll see if I'm able to incorporate it.
... View more
08-06-2024
03:19 PM
|
0
|
0
|
5144
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-12-2026 01:43 PM | |
| 1 | 03-12-2026 08:41 AM | |
| 2 | 03-10-2026 10:10 AM | |
| 1 | 02-18-2026 09:20 AM | |
| 3 | 01-22-2026 02:03 PM |