How to make a Vintage City style for Esri Vector Basemaps – Part 2

Prologue

In my previous blog post How to make a Vintage City style for Esri Vector Basemaps – Part 1 I described how I made a style for the Esri Vector Basemaps using ArcGIS Pro and the ArcGIS Vector Tile Style Editor. Not any coding skills required. Adequate understanding of the data structure of the basemaps, lots of imagination and the rest is just a matter of click-ology!

In Part 2 of these blog series I will describe how I dig deeper into the style using its JSON format and how I visualize it in Nuova Pianta Topografica, a custom WebMap I made with the ArcGIS API for JavaScript v4.

Basic skills of CSS and JavaScript are needed to follow along. In case you don’t have such proficiency, nor you want to acquire it only to read this article, I’ve got you covered! Just scroll to the last paragraph titled “The Lazy Solution” and you’ re done!

The ArcGIS API for JavaScript v4

The ArcGIS API for JavaScript v4 is a library containing objects, functions, modules etc that help me produce impressive, highly functional and user-friendly WebMaps and applications. Especially, the latest versions have significant advancements.

To start developing the WebMap and eventually to further edit my style, I firstly need to write an HTML document. To see the Nuova Pianta Topografica‘s HTML document, type Ctrl + U on the keyboard to open its view-source page. As you may see, in line 37 I call the CSS document from the API and in line 56 I call the JavaScript document from the API. In line 38 I call a custom CSS document, I have written to store my own style adjustments and in 56 I call a custom JavaScript document, where I store all the objects and functions of the WebMap.

At the first lines of the JavaScript I call all the necessary modules from the API. More specifically, I call the Map and the MapView objects, some handy widgets like Home, Zoom, ScaleBar, Expand and Search and I also call the VectorTileLayer object, which is needed in order to incorporate the vector basemap in my application (Snippet 1).

require([
  'esri/Map',
  'esri/views/MapView',
  'esri/widgets/Home',
  'esri/widgets/Zoom',
  'esri/widgets/ScaleBar',
  'esri/widgets/Expand',
  'esri/widgets/Search',
  'esri/layers/VectorTileLayer'
],
Snippet 1: Calling necessary modules from the ArcGIS API for JavaScript.

Immediately below the array of modules, I initiate the main function, where I declare the necessary modules as properties (Snippet 2).

function(
  Map,
  MapView,
  Home,
  Zoom,
  ScaleBar,
  Expand,
  Search,
  VectorTileLayer
) {
Snippet 2: The main function properties.

With this set-up I am now ready to start dealing with the custom style for the vector basemap.

Editing the Esri Vector Basemap

The vector basemap, which I created in my previous blog-post with the ArcGIS Vector Tile Style Editor has been stored in my ArcGIS Online account as an individual item here Nuova Pianta Topografica Esri Vector Basemap. From the item’s page I click on the VIEW STYLE button to open its root.json file in the browser.

This is my style! All the work I’ve done styling the basemap with the Editor, every single click here and there, has been stored in this huge JSON file.

If your are not familiar with JSON, this might appear Chinese to you (or, even worse, Greek!), so it may not be a bad idea to start learning JSON!

I download the root.json from the browser, I unminify it and I store it in a code editor. Any code editor would do, but I prefer working with the Visual Studio Code. I then pass the overall JSON in a variable called “style” and I save the document in JavaScript format, with the name “style.js” (Picture 1).

Picture 1: Saving the style for my Esri Vector Basemap in JSON format as a JavaScript file.
Picture 1: Saving the style for my Esri Vector Basemap in JSON format as a JavaScript file.

You may also see the style.js file directly here!

In order to have it working in my WebMap, I need to call the style.js file in my HTML document (line 57) and it is crucial to call it before the js.js file (line 58 of the HTML).

Back in the js.js file, I create a constant with the name “basemap”, where I assign a new VectorTileLayer object. The value for the style parameter is the style variable which holds the JSON (created in the style.js file), as you may see in Snippet 3.

const basemap = new VectorTileLayer({
  style: style,
  opacity: 1
});
Snippet 3: Creating a new VectorTileLayer object

Creating the Map and the Map View

Below the VectorTileLayer, I create a new Map object, where I pass the basemap in its layers array (Snippet 4).

const map = new Map({
  layers: [
    basemap
  ]
});
Snippet 4: Creating a new Map object

And just below the Map object I create a new MapView object. For the container parameter I define the viewDiv element (defined in the HTML document, line 41), for the map parameter I assign the Map object (as map constant) and I also define the initial center coordinates and zoom level (Snippet 5).

/* Map View */
const view = new MapView({
  container: 'viewDiv',
  map: map,
  center: [12.3283,45.4392],
  zoom: 16,
  ui: {
    components: ['attribution']
  }
});
Snippet 5: Creating a new MapView object

Having done all these, the WebMap should work on the browser and visualize the custom Esri Vector Basemap (Picture 2).

How to make a Vintage City style for Esri Vector Basemaps – Part 2
Picture 2: The WebMap with the custom Esri Vector Basemap.

The ArcGIS API for JavaScrip v4 documentation already has this nice example VectorTileLayer – update style layers where they do exactly what I have done so far. The only difference is that they include the JSON style within the main function (because it is short, I assume), whereas I have stored it in a separate JavaScript file (the style.js).

Having the entire style in a separate file, allows me to manually adjust any property of any feature of the vector basemap (provided I have the patience to work with 15,155 lines of code)!

Still, I can leverage all the capabilities of a code editor, such as find, replace etc, to rapidly and effectively make any adjustments in the style. Believe it or not, this was the only way to configure the Esri Vector Basemaps, when they firstly appeared (in 2015 or 2016, as far as I can remember).

Adding Paper texture with CSS

Since the style I created was inspired from an actual paper map, I want to make it look more papery. So, how can I do it simply in the browser? The answer is pure CSS!

In the HTML document I create an empty <div> element with the id=”paper” (line 42 in the HTML, Snippet 6 here)

<div id="paper"></div>
Snippet 6: Creating an HTML element to make the WebMap look like paper

Then, in the CSS file, I assign a few remarkable CSS properties for the paper element (Snippet 7). I want it to cover the whole screen, placed on top of the WebMap, but I want to be able to navigate the WebMap. For this I assign the properties pointer-events:none!important; and mix-blend-mode:multiply; The first allows for freely panning and zooming the map, and the second allows the paper element to blend with its background, which happens to be the WebMap!

The actual paper effect is achieved with the appropriate background properties and a seamless paper image, I found on Pinterest.

#paper {
  position:fixed;
  top:0;
  right:0;
  bottom:0;
  left:0;
  padding:0;
  margin:0;
  border:0;
  pointer-events:none!important;
  background-image:url('paper.jpg');
  background-repeat:repeat;
  background-size:20em;
  background-position:left top;
  filter: 
    brightness(1.1) 
    contrast(1.2) 
    hue-rotate(00deg)
    saturate(0.6);
  opacity:0.5;
  mix-blend-mode:multiply;
}
Snippet 7: The CSS properties of the paper element (where the magic happens)

The paper element sits on top of the WebMap and indeed looks really papery (Picture 3)!

Picture 3: The paper effect, achieved with pure CSS.
Picture 3: The paper effect, achieved with pure CSS.

Setting the CSS blend property of the paper element to “multiply”, reveals the underlying WebMap (Picture 4).

Picture 4: Blending the paper element with the underlying WebMap.
Picture 4: Blending the paper element with the underlying WebMap.

The Lazy Solution

When finished and deployed my WebMap Nuova Pianta Topografica I was feeling so gigantic for having achieved the paper effect with CSS on my custom style.

But only a few days later, John Nelson announced with this tweet the creation of five paper texture tile layers, which he had created and hosted on ArcGIS Online and he had also written an associated blog post (wow, thank you so much for this).

Of course, it was impossible to not try to incorporate these textures on my vector basemap. For this purpose, I decided to not deploy another WebMap, but to write a separate CodePen, based on the example VectorTileLayer from the ArcGIS API for JavaScript documentation page.

So, in my CodePen instead of passing the style in JSON format, I simply call it directly from my ArcGIS Online account via its item id (Snippet 8).

var item = '5966e5c11e2443e1b927e0209547582f';
const basemap = new VectorTileLayer({
  url:'https://staridasgeo.maps.arcgis.com/sharing/rest/content/items/' + 
       item + 
       '/resources/styles/root.json',
  opacity: 1
});
Snippet 8: Calling the styled vector basemap directly from ArcGIS Online

With the same way I call the five paper texture vector tile layers and I add them as layers in the Map object. The key here is to set an appropriate blend mode (Snippet 9).

const Watercolor_paper_texture= new VectorTileLayer({
url:'https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/Watercolor_paper_texture/VectorTileServer',
  blendMode: 'multiply',
  opacity: 1.0,
});
Snippet 9: Calling the texture tiles from ArcGIS Online and setting their blend mode.

Finally, I only allow a couple of these texture tiles to be visible on the WebMap. In my case, I combine two of them (Snippet 10).

const map = new Map({
  layers: [
    NuovaPiantaTopografica,
  //CrinkledPaperTexture,
  //PosterTexture
    FoldedPaperTexture,
    Watercolor_paper_texture,
  //ParchmentTexture
  ]
});
Snippet 10: Combining two of the texture tiles.

Combining the watercolor with the folded paper texture tiles, on top of my custom vector basemap, produces a stunning result (Picture 5).

Picture 5: Combining paper texture styles on top of the custom vector basemap (mind-blowing).
Picture 5: Combining paper texture styles on top of the custom vector basemap (mind-blowing).

Epilogue

Thank you for reaching so far. I think this is a good time for me to pause coding and experimenting and creating paper-looking vintage maps on the web and start dealing with some real client work, which has been left behind lately!

To recap:

  • Here is Part 1 of these blog post series on How to make a Vintage City style for Esri Vector Basemaps,
  • Here is the Vector Basemap on my ArcGIS Online,
  • Here is the custom WebMap I’ve made with the ArcGIS API for JavaScript, which consumes the Vector Basemap in JSON format,
  • Here is the CodePen, where the Vector Basemap is combined with the Texture Tiles, directly from ArcGIS Online.

Kindest regards from Crete, Greece

Spiros