So far in the course, you've spent the bulk of your time learning about the various web technologies that are involved in the creation of even the simplest web map applications. The last project deliverables were fairly basic, and you're probably itching to create apps that involve layers of your own data. In Lesson 5, we'll see how to create apps that incorporate web maps configured in ArcGIS Online and how to add various types of data layers to a map using Esri's JS API. We'll finish with a discussion of some coding tips now that you've gotten your feet wet with web app development.
At the successful completion of this lesson, students should be able to:
If you have any questions now or at any point during this week, please feel free to post them to the Lesson 5 Discussion Forum. (That forum can be accessed at any time by clicking on the Discussions tab.)
Lesson 5 is one week in length. (See the Calendar in Canvas for specific due dates.) To finish this lesson, you must complete the activities listed below. You may find it useful to print this page out first so that you can follow along with the directions.
Step | Activity | Access/Directions |
---|---|---|
1 | Work through Lesson 5. | Lesson 5 |
2 | Complete the three-part project on the last page of the lesson.
|
Follow the directions throughout the lesson and on the Assignment page. |
3 | Take Quiz 5 after you read the online content. |
Click on "Lesson 5 Quiz" to begin the quiz. |
Back in Lesson 1, you created a web map of the Jen & Barry’s scenario data in ArcGIS Online, then incorporated that web map into an app using Esri’s three app building options that require no coding: embedding within a website, using a configurable app template, and using the Web AppBuilder. It turns out that even if you are coding your app, it’s quite easy to incorporate web maps like the one from Lesson 1 into your app. In fact, while the API provides the ability to configure your app programmatically (adding layers, symbolizing them, configuring popups, etc.), even the best coder is likely to find it helpful to use the ArcGIS Online GUI to reduce their coding burden.
In Lesson 1, we saw that it's possible to use the GUI-based tools in ArcGIS Online to author web maps that can then be easily incorporated into apps created using a configurable app template or the Web AppBuilder. It's also quite easy to do the same for apps developed using the JS API. Here's how:
Two important points to keep in mind about consuming web maps:
We saw in the previous lesson that a Map can be associated with a MapView to produce a 2D app or with a SceneView to produce a 3D app. Likewise, a WebMap can be used as the basis for a 2D or 3D app.
Create a copy of your jen_and_barry_2d app and modify it so that your web map is displayed as a 3D app.
Thus far in the course, we’ve seen how to drape 2D data over a 3D globe, but we haven’t really taken advantage of the 3D environment yet. Web scenes are basically the 3D analog to web maps, in which the scene features have a Z component.
Web scenes can be either global, for situations where the earth’s spherical nature comes into play, or local, where it does not. Global scenes are displayed in the Web Mercator coordinate system, whereas local scenes can be displayed in a local, planar coordinate system.
This example showing earthquakes [1]is an example of a global scene. And this detailed model of a building and its interior [2] provides an example of a local scene.
As with web maps, web scenes are published and discoverable through ArcGIS Online or through local implementations of ArcGIS Portal. This search will provide a list of scenes owned by Esri’s 3D team [3], including models of many world cities.
Have a look at the Load a basic web scene sample [4] in the SDK.
Note that the only difference from the jen_and_barry_3d app you created earlier is in the use of the WebScene class in place of the WebMap class.
In looking at the Load a basic web scene sample (or perhaps earlier samples), you may have noticed a comment “autocasts as new PortalItem().” So what does that mean? Certain properties in the API have been coded behind the scenes by Esri so that our jobs are made a bit easier. Like all properties, the ones that support autocasting are written expecting to be set to a particular data type (e.g., string, number, object). Where these properties differ is that they can also be set to a JavaScript object that “looks like” the required object type. This is a concept that’s much easier to explain by example, so let’s work through what the Load a basic web scene code would look like if autocasting was not built into the API.
No autocasting used | Autocasting used |
---|---|
require([ "esri/views/SceneView", "esri/WebScene", "esri/portal/PortalItem" ], ( SceneView, WebScene, PortalItem ) => { const myPortalItem = new PortalItem({ id: "3a9976baef9240ab8645ee25c7e9c096" }); const scene = new WebScene({ portalItem: myPortalItem }); const view = new SceneView({ map: scene, container: "viewDiv", padding: { top: 40 } }); }); |
require([ "esri/views/SceneView", "esri/WebScene" ], ( SceneView, WebScene ) => { const scene = new WebScene({ portalItem: { id: "3a9976baef9240ab8645ee25c7e9c096" } }); const view = new SceneView({ map: scene, container: "viewDiv", padding: { top: 40 } }); }); |
So autocasting makes it a bit easier to set certain properties. The way to tell which properties behave this way is to look for the word autocast next to the property’s data type in the class’s documentation.
Here’s a second example to drive the point home. In the previous lesson, we worked with the MapView class in creating simple 2D apps. In the samples we dealt with, the MapView center property was set using a syntax like this:
center: [-112, 38]
However, the documentation of the center property tells us that its data type is Point. Thus, if the property didn’t support autocasting, we’d need to add the Point class to the require() declaration and create a Point object using the class’s constructor. Here are three alternative versions of the Get started with MapView sample:
No Autocasting used | Autocasting used | Autocasting used (with lon/lat array) |
---|---|---|
require([ "esri/Map", "esri/geometry/Point", "esri/views/MapView" ], (Map, Point, MapView) => { const map = new Map({ basemap: "streets" }); const pt = new Point({ latitude: 65, longitude: 15 }) const view = new MapView({ container: "viewDiv", map: map, zoom: 4, center: pt }); }); |
require([ "esri/Map", "esri/views/MapView" ], (Map, MapView) => { const map = new Map({ basemap: "streets" }); const view = new MapView({ container: "viewDiv", map: map, zoom: 4, center: { latitude: 65, longitude: 15 } }); }); |
require([ "esri/Map", "esri/views/MapView" ], (Map, MapView) => { const map = new Map({ basemap: "streets" }); const view = new MapView({ container: "viewDiv", map: map, zoom: 4, center: [15, 65] }); }); |
The first version is the syntax we’d need if autocasting was not available on the center property. The second uses autocasting as we saw in the PortalItem example above. The third is how the sample is actually written in the SDK. Unlike the PortalItem example, the property is set to a JavaScript array rather than a JavaScript object. This appears to be a special case supported by the MapView center property. In general, you should use an object, not an array, when working with an autocast property.
Thus far in the course, the apps we’ve built have consumed map services hosted by Esri on their ArcGIS Online platform. Another common source for map services is ArcGIS Server. Many organizations, in both the private and public sectors, implement their own instances of ArcGIS Server as a means of publishing their geographic data. The JS apps built by these organizations typically consume their own services.
Esri makes it possible to consume their web services through the two primary architectural styles employed by web developers today: SOAP (Simple Object Access Protocol) and REST (REpresentational State Transfer). The SOAP protocol was developed by Microsoft in the 1990s and can be thought of as object-oriented programming in which the objects live on some web server and the programming code that manipulates them lives on some client machine. REST came later and has overtaken SOAP in popularity because of its ease of use. RESTful web services, as they are sometimes called, progressively expose their functionality through URLs that can be invoked almost like properties and methods. They send responses to the client applications in the form of XML or JSON.
One important aspect of using this framework is that information on the various REST web services published through an ArcGIS Server instance can be discovered through a series of pages called the Services Directory. This directory can be viewed in a web browser using a URL of the form <server name>/arcgis/rest/services.
Developers working with services published through ArcGIS Server do so using Esri’s REST API. Esri had their own short (3-hour) web course that did a nice job of explaining how to use the REST API. They retired that course, but I did manage to capture the written lesson content from it -- Esri Training: Introduction to the ArcGIS for Server REST API (as PDF) [5]. Please work through this document, paying particular attention to the parts of the course dealing with layer services, as that is what we’ll be focusing on in this lesson.
You should also be sure to consult the documentation -- ArcGIS Resources: REST API [6].
ArcGIS Server publishes data layers of several different types, depending on whether the underlying data source is vector or raster, the amount of data being served, the needs of the apps consuming them, etc. In this part of the lesson, we’re going to walk through the most commonly used types, describing how they differ from one another, how they can be distinguished from layers of other types, under what circumstances they’re intended to be used, and how they are incorporated into an app.
In a moment, we'll take a detailed look at the most useful layer types one by one. Before doing so, here are some important properties that are defined under the abstract Layer class [7] that is the parent to all of the layer sub-classes:
We'll end this lesson with some content that will hopefully make you a bit more successful as a coder. We’ll talk about development environments (where you write your code) and debugging tools. But first, here are a few tips that apply regardless of the kind of programming you're doing:
Plain text editors like Notepad are OK for beginners getting to know web-publishing languages, but there are more advanced tools out there that make the developer's job easier. Integrated Development Environments (IDEs) are software applications that allow developers to write, test, and debug source code all in one application. IDEs also frequently provide auto-completion (i.e., a list of valid properties and methods available through an object) and syntax highlighting (i.e., different language elements shown in different colors/styles). Examples of popular IDEs include Microsoft Visual Studio and Eclipse. CodePen can be thought of as an online web programming IDE (as opposed to one installed on your own computer).
There are lots of IDEs suited for web development, as a web search for "web development ide" [25] will show you. For the purpose of continuing on through this course, I'm going to recommend Notepad++ [26]. As its name implies, it's a step (or two) up from Notepad. My main reasons for pointing you to it are that it is free, it's easy to use, and it provides line numbers and syntax highlighting. Notepad++ is arguably not a true IDE since it's not possible to view your pages directly within the same application, but it does allow you to easily launch them in various web browsers, so I think that's a rather pointless debate.
Let's walk through a short set of steps to familiarize you with Notepad++.
Now that we've worked with a more fully-featured source code editor, let's discuss some tips for working out the kinks in pages that aren't giving you the results you expect.
So, what do you do when you load your page in a browser and get...nothing? Thankfully, there are tools that can help pinpoint problems in your code without having to manually search line by line. Let's have a look at a couple of broken pages and how we can determine why they're broken.
While checking for errors in this way can often be a big help, there are likely to be times when you're unable to identify the problem in your code. Another method for pinpointing problems is to produce some output at strategic points in your code. This could be as simple as an alert() statement that confirms that code execution reached a certain point, like
alert("Finished adding overlays");
You might also use an alert() box to display the contents of a variable or the property of some object:
alert("The coords are: " + pt.latitude() + ", " + pt.longitude());
An alternative to using alert() in this way is to write messages to the JavaScript console. This is especially preferable when you want to diagnose a problem with a loop and would rather not have to dismiss alert() boxes repeatedly. Writing messages to the console can be done as follows:
console.log("The value of i is " + i);
Over years of web development, I have found that these simple debugging strategies usually lead me to finding and fixing my errors.
One strategy for avoiding errors when you test your apps in a browser is to catch those errors in your development environment. A linter is a tool that is used to analyze code for potential errors before execution. Linters exist for many programming languages, but in a JavaScript context, JSLint is perhaps the best known. You can use JSLint online by navigating to JSLint [30], pasting your JS code into the big text box and clicking the JSLint button.
JSLint was developed by Doug Crockford in 2002 and the standards his linter enforces are described on the JSLint website. Many have found some of the JSLint rules to be overly strict (e.g., statements within a function are required to be indented exactly 4 spaces). For this reason, a more flexible alternative was developed as a community-driven open-source project: JSHint.
Many IDEs come equipped with one or both of these tools. Others can have the tools added through a plugin. Notepad++ had a JSLint plugin, but it does not work with the 64-bit version of the IDE (which you're likely to have installed). CodePen provides an Analyze JavaScript option on the JS editor panel's dropdown menu that is based on JSHint.
Pay attention to the availability and implementation of JSLint/JSHint in the IDE review portion of this week's assignment.
Especially when cobbling together snippets of code from various samples, it’s common for your code to become messy (e.g., indented inconsistently, varying amounts of whitespace, etc.). IDEs typically provide ways to indent or unindent blocks of code. In Notepad++, this can be done by highlighting the incorrectly indented code and hitting Tab or Shift-Tab, respectively. However, there are also beautifying tools available both online and within IDEs that can correct multiple kinds of errors across an entire document in seconds.
Here is a messy version of the Hello_Map JS code:
require([ "esri/Map", "esri/views/MapView" ], (Map, MapView) => { const map = new Map({ basemap: "streets" }); const view = new MapView({ container: "viewDiv", map: map, zoom: 4, center: [15, 65] }); });
This code, while perfectly valid as seen by browsers, is difficult for people to read because of the inconsistent indentation and large block of whitespace.
There are several settings in the upper right of the page that you can use to tweak how the beautifier tidies your code. The first four dropdown lists are probably of the most interest:
I encourage you to experiment with these options to see how they affect the formatting of your code.
As with the linting tools, IDEs sometimes include a built-in beautifying tool or can have one added as a plugin. The only tool that I’m aware of for Notepad++ is JSToolNpp [32]. I’m not going to walk you through the use of this tool since I’m not crazy about how it formats object definitions. For example, it formats an object like this:
const map = new Map({ basemap: "streets" });
whereas I’d prefer it to be formatted like this:
const map = new Map({ basemap: "streets" });
However, you are welcome to install and play with the tool if you like.
Finally, you should note that CodePen offers a beautifier on the JS editor panel's dropdown menu (Format JavaScript).
In the previous sections, we saw that both linting and beautifying tools can be customized based on personal preference. Application development often involves multiple coders contributing pieces to the end product. Editing application code, whether fixing bugs or adding additional functionality, is much easier when all of the code is formatted in the same way. When code jumps between different formats (i.e., style rules), the person trying to interpret the code is forced to waste valuable time adjusting his/her mindset to the different formats. And even in organizations in which team coding is not employed, it is rare that an application will only ever be modified by the original author. Coders go on vacation, leave the company, etc. For these reasons, many organizations go to the trouble of constructing a style guide – a set of rules that all of their coders will follow. Here is a JavaScript style guide used at Google:
Google JavaScript Style Guide [33]
Many of these rules are fairly advanced, but there should be at least a few you can grasp. For example, the guide's authors specify that all statements must be ended in a semi-colon even though you might be able to get by with omitting them. Multiline string literals should be constructed using string concatenation rather than the line continuation character. Under the Code formatting heading, you’ll find some of the personal preference items we discussed in the beautifying section. Opening braces should be found on the same line as what they’re opening, property settings in an object definition should be indented two spaces, etc.
If you work in an organization that already does JS development and you’re going to be joining a development team, you should look into whether there is a style guide you should be following. If you’re just starting a new team, it might be a good idea to put some thought into creating a guide.
The coding assignment for this lesson is in three parts. Here are some instructions for completing the assignment.
Although we learned about adding WebMaps and WebScenes to our apps, for full credit on Parts I and II you will need to add layers to the Map as discussed in 5.4 Layer Types. This will be useful in the next lessons where we need to access layers for custom symbology, queries, and features.
The Transportation Planning and Programming (TPP) division of the Texas Department of Transportation has published vector tile basemaps for Texas as services through ArcGIS Online. Find one of these services and create an app that displays its data in a 3D scene, zoomed in to the City of Houston.
Hint: You can narrow down your search in ArcGIS Online to different content types like Maps, Layers, Scenes, etc. Some content types are broken into sub-categories as well. Use the ability to search by content type along with appropriate search terms to identify the correct service. (Make sure you're not searching only the Penn State group content!)
If you're unable to find the described service, create a 3D app that displays data from some other vector tile service for partial credit.
One of Esri's sample ArcGIS Server instances hosts a map service that contains U.S. cities, interstates, and state/county boundaries:
USA (MapServer) [34]
Build an app that displays just the county boundaries on a 2D map. In your solution, you should be taking a snapshot of the data on the server and passing that to the client rather than passing the features themselves. Be sure to read the documentation carefully for how to display just the county sublayer. It might be a good idea to display all of the sublayers first before attempting to filter out some of them.
In this lesson, you began using a relatively basic IDE, Notepad++. For the last part of this week's assignment, I'd like you to download and experiment with a different IDE (Visual Studio Code [35], Sublime [36], WebStorm [37], Eclipse [38], Netbeans [39], Komodo [40]), then share your thoughts on it in a recorded video. Here are some detailed instructions:
This project is one week in length. Please refer to the Canvas course Calendar for the due date.
NOTE: You'll need to zip the files to upload to the Canvas dropbox.
In this lesson, you saw how to incorporate a web map you created using ArcGIS Online tools into a JavaScript API app and how Esri's REST API can be used to interact with services published through ArcGIS Server. You also learned about the various layer types built into the API and the circumstances under which each type might be used. Finally, you learned about some more generic web development topics, including Integrated Development Environments (IDEs) and debugging strategies.
Knowing the different layer types found in Esri's API and how to add them to a map is an important first step. However, chances are you'll want to customize the symbology of your map's layers so that they convey the desired information more effectively. That will be the focus of Lesson 6.
Links
[1] https://developers.arcgis.com/javascript/latest/visualization/3d-visualization/globes-and-local-scenes/
[2] http://arcg.is/11GLu0
[3] http://www.arcgis.com/home/search.html?q=owner%3Aesri_3d&t=content&focus=scenes
[4] https://developers.arcgis.com/javascript/latest/sample-code/webscene-basic/index.html
[5] https://www.e-education.psu.edu/geog863/sites/www.e-education.psu.edu.geog863/files/REST_API_training.pdf
[6] https://developers.arcgis.com/rest/
[7] https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-Layer.html
[8] http://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html#basemap
[9] https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-TileLayer.html
[10] https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer
[11] https://developers.arcgis.com/javascript/latest/sample-code/get-started-layers/index.html
[12] https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-VectorTileLayer.html
[13] http://www.arcgis.com/home/group.html?id=30de8da907d240a0bccd5ad3ff25ef4a&focus=layers
[14] https://developers.arcgis.com/javascript/latest/sample-code/sandbox/index.html?sample=layers-vectortilelayer
[15] https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-VectorTileLayer.html#url
[16] https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html
[17] http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/2
[18] https://developers.arcgis.com/javascript/latest/sample-code/layers-featurelayer/index.html
[19] https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-MapImageLayer.html
[20] http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer
[21] https://developers.arcgis.com/javascript/latest/sample-code/layers-mapimagelayer/index.html
[22] https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryLayer.html
[23] https://sampleserver6.arcgisonline.com/arcgis/rest/services/ScientificData/SeaTemperature/ImageServer
[24] https://developers.arcgis.com/javascript/latest/sample-code/layers-imagerylayer/index.html
[25] https://www.google.com/search?q=web+development+ide]
[26] http://notepad-plus-plus.org/
[27] https://notepad-plus-plus.org/downloads/v7.8.4/
[28] https://codepen.io/obrienja/pen/dywzMwE
[29] https://codepen.io/obrienja/pen/ExGvKrd
[30] http://www.jslint.com/
[31] http://jsbeautifier.org/
[32] https://sourceforge.net/projects/jsminnpp/
[33] https://google.github.io/styleguide/javascriptguide.xml
[34] http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer
[35] https://code.visualstudio.com/
[36] https://www.sublimetext.com/
[37] https://www.jetbrains.com/webstorm/
[38] https://eclipseide.org/
[39] https://netbeans.apache.org/
[40] https://www.activestate.com/products/komodo-ide/