ArcGIS JavaScript Maps SDK Blog - Page 7

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Latest Activity

(80 Posts)
JuliePowell
Esri Contributor

We recently published a series of blogs (with one more to go) aimed at helping JavaScript developers wanting to migrate from Google to ArcGIS come up to speed on the JS API:

Have you gone through the experience of migrating from Google or are you considering starting the process? This GeoNet post serves as a way in which you can provide feedback on the above blogs, as well as share your experience coming up to speed on ArcGIS. How can we help?

more
4 0 1,118
BjornSvensson
Esri Regular Contributor

Today we released versions 4.8 and 3.25 of the ArcGIS API for JavaScript. Read more about it in:

and more details in

more
3 0 1,970
BjornSvensson
Esri Regular Contributor

Today we released versions 4.7 and 3.24 of the ArcGIS API for JavaScript. Read more about it in:

and more details in

more
9 8 4,198
JuliePowell
Esri Contributor

New ArcGIS API for JavaScript releases are just around the corner! Here is a preview of some of the new capabilities coming in early July. 

(Note: These are some of the highlights; a full list of new capabilities and enhancements will be provided in the release notes.)

ArcGIS API 4.4 for JavaScript

New styles for points in city landscapes:

Styling the point data in city scenes can now be done more effectively. Point graphics can be configured to display above buildings with the new relative-to-scene elevation mode. Callout lines can be used to better understand point locations (a callout is essentially extended from the top of the scene).

 

Highlight in 3D:

The ability to highlight features in a 3D scene, with options to configure the color and opacity of the highlight effect.

 

Styling building data:

We added the option to remove building textures to better emphasize thematic mapping of buildings, and also the option to make textures grayscale (one example of when you might want to do this is if you want to draw attention away from the buildings, and highlight a particular set of interest).

 

Smart Mapping

You can now automatically generate renderers for SceneLayers using SmartMapping. Generating type renderers with smart mapping is new to both 2D and 3D views. Note: When we reference smart mapping/generating renderers, we mean that the API creates smart defaults for your map/scene styles on the fly. This capability is typically used in data exploration type apps (as opposed to defining the styling explicitly in code).

 

PointCloudLayer enhancements

Added the ability to add natural lighting conditions to a point cloud layer in order to better distinguish objects.

 

Better web map support

Added support for Map Notes, WMS, and WMTS layers.

 

OGC support

Added support for WMS and WMTS layers.

 

VectorTileLayer printing

This release of the JavaScript API includes a support for vector tile layer printing through client-side image.

 

Arcade support in popups

Arcade expressions can now be applied in the popup’s content. This is useful for situations when you want to display data that isn't present as an attribute value in your FeatureLayer instance. Web maps that have been created in Portal or Online that contain popups with Arcade expressions will be honored in apps built with the JS API, and developers can also write Arcade expressions directly in their code.

 

Widget standardization

In this release, the following widgets have been updated to the widget framework, initially introduced at 4.2: Legend, Popup and Search widgets.

Custom Layers

The SDK will include documentation and samples for creating your own custom layers. 

 

ArcGIS API 3.21 for JavaScript 

Arcade support in popups

As described above.

 

VectorTileLayer printing

As described above.

 

(...plus minor enhancements and bug fixes)

 

more
13 17 16.2K
BjornSvensson
Esri Regular Contributor

When the 4.0 version of the ArcGIS API for JavaScript was released, we also released a Bower compatible minified version of the API for users interested in doing their own custom local builds. This was a big step in our direction to help users integrate the ArcGIS API for JavaScript into their own workflows.

We have since had numerous requests to publish the ArcGIS API for JavaScript to NPM. One of the reasons we have not done this is that Bower provides us with some advantages when it comes to creating custom local builds. Publishing the API to NPM will not automatically make it compatible with build tools like Webpack. It actually adds a couple of steps to the Dojo build needed to compile the ArcGIS API for JavaScript.

With the upcoming release of 4.4 we will publish the ArcGIS API for JavaScript to NPM. We will also be providing some updated resources about how to do a Dojo build with the API.

Start using NPM today

However, you could start using NPM today to install the ArcGIS API for JavaScript locally.

Let's start with the sample application provided in the resources repo on github.

Take a look at the bower.json file provided with the ArcGIS API for JavaScript repo.

...
  "dependencies": {
    "dojo": "Esri/dojo#v1.12.1/esri-3.20.0",
    "dojox": "Esri/dojox#v1.12.1/esri-3.20.0",
    "dijit": "Esri/dijit#v1.12.1/esri-3.20.0",
    "util": "Esri/dojo-util#v1.12.1/esri-3.20.0",
    "dgrid": "Esri/dgrid#v1.1.0/esri-3.20.0",
    "dstore": "1.1.1",     "moment": "2.17.1"
  },
...

We can borrow most of this for our package.json of our custom application.

...
  "dependencies": {
    "dgrid": "Esri/dgrid#v1.1.0/esri-3.20.0",
    "dijit": "Esri/dijit#v1.12.1/esri-3.20.0",
    "dojo": "Esri/dojo#v1.12.1/esri-3.20.0",
    "dojo-dstore": "^1.1.1",
    "dojo-util": "^1.12.2",
    "dojox": "Esri/dojox#v1.12.1/esri-3.20.0",
    "arcgis-js-api": "Esri/arcgis-js-api#4.3.1",
    "moment": "2.17.1"
  },
...

You can see this looks very similar. Main difference is that util is now dojo-util and dstore is now dojo-dstore, because these are the names of the published packages on NPM. You may also notice that we can bring in the arcgis-js-api repo using Esri/arcgis-js-api#4.3.1. This tells NPM too look on github at the Esri org and install the arcgis-js-api repo using the 4.3.1 release.

At this point you can delete the bower.json and .bowerrc files from the project since they are not going to be used.

One disadvantage of using NPM instead of Bower is that NPM does not allow you to change the name of the folder the package is installed. Meaning that the JavaScript API will installed to node_modules/arcgis-js-api instead of node_modules/esri which would be ideal as far as how we typically use the Dojo build system.

Hint: If you use Yarn instead of NPM, it can install to custom named directories.

Once you NPM install these packages you will have a folder structure that should look something like this.

node_modules/
  arcgis-js-api/
  dgrid/
  dijit/
  dojo/
  dojo-dstore/
  dojo-util/
  dojox/
src/
  app/
    main.js

Now you need to tell Dojo where to locate the packages. You can do this by supplying a global dojoConfig object.

<!-- index.html -->
    <script>
      // point to node_modules folder
      window.dojoConfig = {
        baseUrl: '../node_modules/',
        packages: [
          'dijit',
          'dojo',
          'dojox',
          'dgrid',
          'moment',
          {
            name: 'app',
            location: '../src/app'
          },
          // alias for dstore package
          {
            name: 'dstore',
            location: 'dojo-dstore'
          },
          // alias for esri package
          {
            name: 'esri',
            location: 'arcgis-js-api'
          }
        ]
      };
    </script>
    <script src="../node_modules/dojo/dojo.js"></script>
    <script>require(["app/main"]);</script>

There is one more thing you will need to do your own code in order for this to work. The ArcGIS API for JavaScript uses Web Workers for Vector Tiles. You will need to let the workers know where the esri package is located in order for them to function. You can do this in the following manner using esri/config and dojo/has.

//app/main.js
if (!has("dojo-built")) {
  esriConfig.workers.loaderConfig = {
    paths: {
      "esri": "../arcgis-js-api"
    }
  };
}

The reason we use dojo/has is that once the application is built, the Dojo build system will install the esri package into an esri folder and not arcgis-js-api. So we only need this configuration during the development process.

Now you can develop your application using the JavaScript API installed in node_modules.

When you do your Dojo build, you will need to do something similar. However, the Dojo build is expecting the build tools to be located in a folder called util, but they are in fact installed in a folder called dojo-util. This requires you to create a dojoConfig for the build system in the root of your project.

// dojoconfig.js
dojoConfig = {
  baseUrl: './node_modules/',
  packages: [
    {
      name: 'dojo',
      location: 'dojo'
    },
    {
      name: 'build',
      location: 'dojo-util/build'
    }
  ]
};
require('./node_modules/dojo/dojo.js');

Then to run your Dojo build from the command line you can use node dojoconfig.js load=build --profile build.profile.js --releaseDir ../dist.

This will now tell Dojo where to find the build tools needed.

You will also need to update the build.profile.js to reflect the new locations of the packages.

// build.profile.js
  packages: [
    // "app" is a sample path for your application
    // set this accordingly
    "app",
     {
       name: 'dijit',
       location: '../node_modules/dijit',
       trees: [
           // don"t bother with .hidden, tests, min, src, and templates
          [".", ".", /(\/\.)|(~$)|(test|node_modules)/]
       ]
     },
     {
       name: 'dojo',
       location: '../node_modules/dojo',
       trees: [
           // don"t bother with .hidden, tests, min, src, and templates
          [".", ".", /(\/\.)|(~$)|(test|node_modules)/]
       ]
     },
     {
       name: 'dojox',
       location: '../node_modules/dojox'
     },
     {
       name: 'dstore',
       location: '../node_modules/dojo-dstore',
       trees: [
           // don"t bother with .hidden, tests, min, src, and templates
          [".", ".", /(\/\.)|(~$)|(test|txt|src|min|templates|node_modules)/]
       ]
     },
     {
       name: 'dgrid',
       location: '../node_modules/dgrid',
       trees: [
           // don"t bother with .hidden, tests, min, src, and templates
          [".", ".", /(\/\.)|(~$)|(test|node_modules)/]
       ]
     },
     {
       name: 'esri',
       location: '../node_modules/arcgis-js-api'
    },
     {
       name: "moment",
       location: "../node_modules/moment",
       main: "moment",
       trees: [
           // don"t bother with .hidden, tests, min, src, and templates
          [".", ".", /(\/\.)|(~$)|(test|txt|src|min|templates)/]       ],
       resourceTags: {
         amd: function(filename, mid){
           return /\.js$/.test(filename);
         }
       }
     }
   ],

Notice the addition of the trees array for each package. This lets the Dojo compiler know which files and folders to ignore so it doesn't try to include tests and documentation in the build process.

Summary

So if you are interested in using NPM to install the ArcGIS API for JavaScript locally today, these are the steps you would need to take. All this is still valid once we publish the JavaScript API to NPM, except you will only need to install the arcgis-js-api package by name and not need to install the other dependencies yourself. Bower does provide us with a distinct advantage when it comes naming the folders and locations that packages are installed, but NPM allows to keep all dependency code in a single location.

Please note, that if you want to use RequireJS and the RequireJS Optimizer to build the ArcGIS API for JavaScript, you should continue to use Bower as some of the required build tools cannot be installed via NPM.

Even once the API is published to NPM, we will continue to provide the Bower release for as long as it's sustainable since it's all the same codebase.

Contributed by Rene Rubalcava !

more
6 16 12.8K
JamesMilner1
Deactivated User

Esri Polymer

This is a quick post to talk a little bit about Esri Polymer! It's a project I've been working on for a little while (very intermittently) but never put on GeoNet, so thought I would make this post!

Before I begin to start talking about the project I would like to point out what Polymer is. Polymer is a library from Google for building web components. It allows developers to create custom compartmentalised HTML elements. In a way you can think of a web component similar to a 'widget'. Some contrived examples might be a an image carousel, a YouTube video, or a PayPal checkout, or rather a <image-carousel> , a <youtube-video> and a <paypal-checkout>

Polymer provides a light wrapper around some native/polyfilled web standards that make up web components, namely:

  • Custom Elements - for defining a unique custom element
  • HTML Imports - for importing HTML
  • Shadow Dom - for encapsulating sub trees of DOM
  • HTML Template - for reusable inert pieces of DOM

The necessary polyfills come curtsy of webcomponents.js​ which allow web components to run on all modern evergreen browsers.

Great stuff James, but why would I ever want to use web components?

The major reason is that it allows us to write markup and code an abstracted level. You can import a web component into your page and mark it up in your HTML page just like you would a div or a span, or any other element without having to worry about the underlying implementation.

This works great with things like basemaps, web maps, feature layers, and markers. Each one of those becomes its own element, and we can have feature layers as child elements of a map add them to it.

For example:

<esri-map basemap="dark-gray" centerLng="-0.122" centerLat="51.514" zoom="7">

  <esri-featurelayer

          featurelayer="http://services.arcgis.com/Qo2anKIAMzIEkIJB/arcgis/rest/services/TubeMap/FeatureServer/2">

  </esri-featurelayer>

  <esri-marker lng="-0.5" lat="51.3">

  <esri-marker-title>Hello World</esri-marker-title>

  <esri-marker-content>Some Content</esri-marker-content>

  </esri-marker>

  </esri-map>

will produce the following once rendered:

Caveats

  • Web components are only supported with polyfills on modern browsers
  • Polymer is a relatively early stage project
  • Some argue that you shouldn't use web components in production

If you can live with these things than they are great fun to experiment with!

GitHub

You can find the project here: JamesMilnerUK/esri-polymer · GitHub

The Latest Version

I've just updated the project, hopefully with some certain niceties:

  • Polymer 1.1.5
  • ArcGIS JS 3.14
  • Cleaner code
  • Less hacky hacks for element lifecycles and interacting with parent and child elements

more
0 0 1,967
JamesMilner1
Deactivated User

It's been a while since I've posted anything to GeoNet, but I thought I'd share some samples that I was working on this weekend at Hackference to show case how to do some basic functions In ArcGIS. The repo has examples of how to do the first steps with the API, with code samples such as:

  • Creating a map
  • Creating a map from a Web Map ID
  • Adding markers (AKA Graphics, Points) to the map
  • Adding a Feature Layer to a map
  • Adding a CSV file to a map
  • Adding a KML file to a map
  • Creating a basic heatmap

These samples are meant to compliment some of the samples available from the JavaScript samples page​. There focus is on simplicity, commenting and on the bare minimum amount of code to do a requirement ('add a point to a map'). This is mostly useful for things such as teaching, hackathons and coding sessions with people completely new to the ArcGIS JavaScript API.

You can see the repo on GitHub here:

               JamesMilnerUK/ArcGISHelloWorld · GitHub   

               The Zip File

Got some simple,  commented, single function examples to add? Why not make a pull request!

more
0 0 1,434
AndyGup
Esri Regular Contributor

If you haven't had a chance to read up on what's coming in the next major release of the ArcGIS API for JavaScript v4, then it's time to get your game on and brush up on some of the exciting changes that can be explored today in v4 beta1. For those of you who haven't heard of this API or ArcGIS, we provide a large selection of APIs, SDKs, services, content and applications for building commercial mapping/geo-spatial applications. You'll want to check out the following:

  • The 4.0 API is currently in beta, so give v4beta1 a spin. This version of the API is a rewrite and it is fundamentally based on using JavaScript Promises. With these promise-based coding patterns you will be adopting a new and powerful architectural change in how you do JS app development.
  • Get a quick overview of Working with Promises (and the ArcGIS API for JavaScript).
  • Read about promises as guarantees in ArcGIS JavaScript Promises.
  • And, here's a great intro article from HTML5 Rocks simply called JavaScript Promises.

I promise to...?

Promises bring a whole new level of application life-cycle control to building web applications for use on mobile devices. In particular, there are two aspects of promises that will change how you do mobile development, forever: the ability to look back in time to see if some process has completed, and the ability to easily manage multiple, asynchronous requests.

In part 1 of this series we'll chat about how promises will allow you to verify after-the-fact and in a stateful way if an asynchronous action has completed successfully or failed. This is such an important concept that I'll illustrate it in a variety of ways to help push home the basics. All the examples are written for the ArcGIS API for JavaScript v4.x.

Absolutely yes these ideas work just fine on desktop apps. But desktop apps, in general, are significantly less susceptible to life-cycle issues as compared to mobile apps. Desktop web apps are tapped into dedicated internet connections with fairly reliable up times and connection speeds. In comparison, mobile web apps oftentimes easily suffer from small connectivity interruptions, hiccups and slowdowns. This can play havoc on your app while it's in the process of downloading and parsing HTML, CSS, JS and images as well as going through the initialization process. Promises can go a long way to smoothing out these potential speed bumps and towards helping you build consistent and stable applications without bending, breaking or stretching the basic rules of JavaScript best practices and sensibilities.

Promises, promises: the .then() pattern

All this magic works because promises have a built-in .then() mechanism that is your ticket to getting access to an asynchronous processes' state at any time whether it is still pending, if its completed or even if it failed. Simple in concept, powerful in execution. So, let's dig in.

We mention this several times in the ArcGIS API for JavaScript v4 documentation, the basic structure and concept of a promise looks like this:

someAsyncFunction.then(callback, errback);

A related side note, until the ECMAScript 2015 Promise standard is fully adopted and integrated by the various browser vendors, some third party libraries may provide slightly different syntax than what is shown in this post, but the concepts should all generally lead to the same result.

Below is a slightly exaggerated code snippet of how the concept works, and for a fully working version check out this jsbin. In this sample, a timer forces the code to wait for 5 seconds before calling view.then(). If you run the jsbin with the developer console window open you'll see the map has already loaded and should be visible by the time "View is ready? true" gets written to the console. The point here is that the SceneView's promise did, in fact, let us query its state well after the map and view were initialized.

     map = new Map({
          basemap: "streets"
     });

     view = new SceneView({
          container: "viewDiv",
          map: map,
          scale: 240000000
     });
            
      // Let's wait for 5 seconds
      setTimeout(function() {
           view.then(function(viewEvt){
                console.log("View is ready? " + viewEvt.ready);
           });
      }, 5000);        

Huh, how does this benefit me? I still don't get it.

Hang in there, we have a few more examples to look at. The above example demonstrates that the promises pattern truly lets you de-couple the timing on when you execute various aspects of your code. It means you can access the state of an asynchronous process at any time and anywhere in your application, even after the process has long been completed. It gives you another excellent tool in your coding toolkit for going several steps beyond what's possible with using only event listeners and callbacks.

The most important benefit of this pattern for mobile development, or really for any JavaScript development, is you can delay asking for a promise if you need to wait for other asynchronous or synchronous processes to complete first. You can't delay an event listener and it's bad, bad practice to place timers in callbacks. Promises give you a scalpel for exerting significantly greater control over application logic flow than was ever possible before with simply using event listeners and stand-alone callbacks by themselves.

Okay, so how's this different than events and event listeners?

The promise-based .then() pattern offers a significant advantage over the tried-and-true, events-based coding pattern. JavaScript event messages are similar to bullets; once they are fired they are gone forever and you can't bring them back. Once an event has fired you can't get it back, and it only hangs around for a very short period of time as it bubbles its way up through various layers of JavaScript and then it's gone. Poof.

What this means is if you initialize an event listener in your app after an event has already occurred then the event listener will never fire. Period. It will simply wait faithfully for eternity and pretty much do nothing.

Here's a snippet to demonstrate the concept of an event listener created after-the-fact and will never fire. You can also check it out live in a jsbin version.


            map = new Map({
                basemap: "streets"
            });

            view = new SceneView({
                container: "viewDiv",
                map: map,
                scale: 240000000
            });            


            view.then(function(viewEvt){

                console.log("View is ready? " + viewEvt.ready);

                //Event listener is initialized after the event has occurred!
                map.on("load", function(){
                    // This will never fire!
                    console.log("Map loaded via event listener!");
                });

                console.log("The map already loaded? " + map.loaded);

            });           

Yes, this snippet is an oversimplification to help clarify how event listeners can easily cause life-cycle issues, and I'm definitely not implying that all event listeners are bad. The point is that it's very easy in large JavaScript applications to initialize an event listener too late in the life-cycle for it to ever fire properly. What's happens next is you troubleshoot and wonder for hours why your code isn't working properly, or why it may only work intermittently.

In mobile web applications, this simple concept is perhaps one of the most common reasons for intermittent failures!

What happens if you swap an event listener for a promise?

This next sample demonstrates swapping out the failed event listener pattern from the previous example with a promise-based pattern. Here's the jsbin for this sample. As you migrate existing applications, you'll be going through similar steps.

There is also an important twist in this sample that steps away from simply checking if the map.loaded boolean is true or false and then continuing with code execution. With the promises-based pattern we can inspect the promises' callback object and verify, among other things, if the process completed successful or if it failed and why.

We always have access to the promise associated with map, and we can access it at any time and anywhere in our application.


            map = new Map({
                basemap: "streets"
            });

            view = new SceneView({
                container: "viewDiv",
                map: map,
                scale: 240000000
            });

            view.then(function(viewEvt){
                console.log("View is ready? " + viewEvt.ready);

                   map.then(function(mapEvt) {
                        console.log("The map already loaded? " + mapEvt.loaded);
                    }, function(mapErr){
                        console.log("Was there any map load errors? " + mapErr);
                    });

                console.log("The map already loaded? " + map.loaded);
            });           

So, let's take this one step further and ask for the map.then() promise after a 5 second timer run. This is similar to what we did with the event listener above, and the purpose is to simulate asking for the promise at some point signfiicantly later in the application life-cycle than the process occurred. The big difference is this pattern will, in fact, be successful because the promise maintains state! Try modifying the above sample in jsbin and try it out yourself.


            map = new Map({
                basemap: "streets"
            });

            view = new SceneView({
                container: "viewDiv",
                map: map,
                scale: 240000000
            });

            view.then(function(viewEvt){
                console.log("View is ready? " + viewEvt.ready);

                setTimeout(function() {
                    map.then(function(mapEvt) {
                        console.log("The map already loaded? " + mapEvt.loaded);
                    }, function(mapErr){
                        console.log("Was there any map load errors? " + mapErr);
                    });
                }, 5000);

                console.log("The map already loaded? " + map.loaded);
            });           

Closing thoughts

There is a learning curve associated with promises, and they aren't perfect. However, hopefully this post has helped you understand just a little bit more about the value that promises can provide. As you consider the possibilities, you might start to rethink how you architect applications and that is a good start to continuously improve what we create!

Promises, callbacks and event listeners all still have important roles play depending on the unique requirements for the applications we build on a daily basis. In fact, many people overlook or ignore the fact that a promise does indeed include its very own callbacks to indicate if the process completed successfully or if it failed.

As you start to migrate existing applications to the promises pattern you may find yourself mixing-and-matching promises, callbacks and event listeners as you go through the process of reinventing your architecture. This is all part of the normal progression as new architectures gradually take over the old. And, as you build new applications from scratch you'll get to try your hand at a fresh approach.

Try these samples out, check out the ArcGIS API for JavaScript v4 samples and hopefully have fun learning the latest and greatest that is available in JavaScript!

[Minor edit - Aug 10, 2015 to read as 'any' async request!]

more
6 4 4,883
JamesMilner1
Deactivated User

Recently I came across an article that had used the GitHub API to scrape information regarding the number of users in major cities in the US. The article gave me the idea to take this a little further and see if we could map out the number of users in each city, or perhaps more importantly the percentage of people in that city with a GitHub accounts. Before we begin let met point out the obvious flaws with the methodology of this application:

  • Populations are estimations (plus the UK census is now 4 years old)
  • Populations for cities can be difficult to define (city, urban, metro area)
  • GitHub accounts can be owned by companies as well as people
  • Not everyone gives their location on their GitHub accounts, or people may lie/not update

Having said this, it's still interesting to explore the available data and try to see or explain any patterns. Plus it's fun!

Data Scraping

Firstly to get the data into a format that could be mapped, it was necessary to instantiate a list of cities that I was interested in, and assign these their populations (I used Wikipedia).

Then using Python and the GitHub API I scraped the number accounts that matched the town name. Here it was necessary to try multiple different matches to get an accurate data. For example, with London it was necessary to try "London, England", "London, Great Britain", "London, United Kingdom" and "London, UK" as these are all valid locations representing the same place. You will need a GitHub account and a token to avoid rate limiting.

The Results

    

CityGitHub AccountsCity PopulationRate
Cambridge, England13131285151.022
Brighton, England5881630000.361
Oxford, England5511713800.322
Bath, England231888590.260
Reading, England2911608250.181
Durham, England68480690.141
Bristol, England8376170000.136
York, England2602044390.127
Norwich, England1651404520.117
Edinburgh, Scotland8017820000.102
London, England929197874260.095
Glasgow, Scotland5585899000.095
Dundee, Scotland1331539900.086
Exeter, England981218000.080
Belfast, Northern-Ireland2162767050.078
Bangor, Wales11163580.067
Aberdeen, Scotland1251891200.066
Cardiff, Wales2834472870.063
Bournemouth, England1161834910.063
Sheffield, England3626407200.056
Nottingham, England3897299770.053
Liverpool, England2364664150.051
Manchester, England129125533790.051
Plymouth, England1222566000.048
Swansea, Wales1012390230.042
Newcastle, England3518799960.040
Southampton, England3128555690.036
Inverness, Scotland21579600.036
Leicester, England1435090000.028
Leeds, England49617779340.028
Gloucester, England291256490.023
Warwick, England291393960.021
Birmingham, England50324409860.021
Newport, Wales261457000.018
Derry, Northern-Ireland6836520.007
Aylesbury, England131845600.007
Lisburn, Northern-Ireland4714030.006

We can see highest on the list is Cambridge with over 1 % of the population having a GitHub account. Lowest on the list was Lisburn with 0.006 closely followed by Aylesbury (where I live ) and Derry with 0.007%. To put this into perspective the original Hirily analysis found 3% of San Francisco's population had a GitHub account!

Making the Map

The script outputs a CSV which was then uploaded into ArcGIS Online content pane using a developer account. When uploading the CSV we can set the city column to be geocoded. This allows us to take the address of the city and turn it into a latitude and longitude, in turn allowing us to map the data.

githubcsv.png

The process asks if you want to review (probably worth while as some points can end up astray). Once this was done, I gained a Feature Service of the data (a REST end point we can get our data from). From here I took this into a Esri Leaflet map (one of Esri's GitHub projects!). The main bulk of the mapping is outlined in the JavaScript code below:

    var map = L.map('map').setView([ 54.514, -2.122], 6);

    L.esri.basemapLayer("Gray").addTo(map);
    L.esri.basemapLayer("GrayLabels").addTo(map);


    var ukGitHub =
    "http://services1.arcgis.com/Q6SkXeZHDxVxhXA4/arcgis/rest/services/GitHub_Data/FeatureServer/0";
    var gh = L.esri.featureLayer(ukGitHub, {
        pointToLayer: function (geojson, latlng) {
            console.log(geojson);
            var rate = geojson.properties.Rate;
            var size;


            if (rate >= 0.361 && rate < 1.2 ) {
                size = [65, 63];
            }
            else if (rate >= 0.181 && rate < 0.361 ) {
                size = [55, 53];
            }
            else if  (rate >= 0.095 && rate < 0.181 ) {
                size = [45, 43];
            }
            else if  (rate >= 0.046 && rate < 0.095 ) {
                size = [35, 33];
            }
            else if  (rate >= 0 && rate < 0.046 )  {
                size = [25, 23];
            }


            return L.marker(latlng, {
                icon: L.icon({
                    iconUrl: 'imgs/github4.png',
                    iconSize: size,
                    iconAnchor: [size[0] / 2, size[1] / 2],
                    popupAnchor: [0, -11]
                })
            });
        }
    }).addTo(map);

Screenshot and Live Demo

A screenshot of the map can be seen below, a live demo can be seen here.

githubmap.png

Where's the code?

You can find the code on my GitHub account: JamesMilnerUK/github-mapping · GitHub 

set the city column to be geocoded. This allows us to take the address of the city and turn it into a latitude and longitude, in turn allowing us to map the data.

more
0 3 6,165
JamesMilner1
Deactivated User

What is it ?

A simple map that allows users to search for tweets referring to a specific keyword in a given view extent. Currently the Twitter search API only allows you to pull back a maximum of 100 tweets, but it gives you a flavour for what you might be able to do if you had/have access to the Twitter firehose! The application also demonstrates how to do common tasks you might do in jQuery via Dojo. For example DOM querying, styling and AJAX using the requests module. This allows us as developers to not have to import an extra library whilst using the ArcGIS JavaScript API, reducing page weight.

What does it look like?

Live Demo

You can see the live demo at by following the link here. The Twitter API is rate limited so there is some possibility that the auth credentials used may hit their allocated limit.

GitHub Repository

The project is available from: https://github.com/JamesMilnerUK/esri-twitter

The Twitter Search API

The Twitter search API is defined here. The API allows users to get hold of tweets although it is important to note:

"[the] Twitter’s search service and, by extension, the Search API is not meant to be an exhaustive source of Tweets. Not all Tweets will be indexed or made available via the search interface. "

So, not suitable if you are looking for a full picture, but still useful for a bit of fun mapping tweets. An alternative if you need an exhaustive list of tweets may be to examine companies with Twitter Firehose access; for example Gnip (recently bought by Twitter) and DataSift (although their access appears to be ending in August 2015).

The Twitter Search API requires authentication. You can register a new app which will provide you with the authentication credentials required at Twitter Application Management. Once you have registered you can get hold of four things:

  • Consumer Key (API Key)
  • Consumer Secret (API Secret)
  • Access Token
  • Access Token Secret

From here I found the easiest way to get going with the API without having to worry about authentication implementation details was to use a helper library. In this case I've used TwitterAPIExchange (PHP) by J7mbo, but it appears there is a node.js module and also a Ruby Gem depending on how you roll.

The Twitter Search API has a few parameters that we are specifically interested in, in this case, geocode and count. Geocode represents a latitude, longitude (note the order!) and radius that we are interested in returning tweets from (km or miles are accepted as units). In the case of this application we use the centre point of the map and then get the extent in kilometres divided by two as the radius. For the count we keep this capped at 100, as this is the maximum!

Frontend and ArcGIS JavaScript API

We firstly check if HTML5 geolocation, if so then we instantiate a map at that part of the the world using the provide coordinates. If not then we instantiate a map near the middle of the Earth (0, 30) at a reasonable zoom level (8).  We also provide the user with a box to provide the keyword we are looking for. We then do an AJAX request to the PHP script 'gettweets.php'. As mentioned we pass it the latitude, longitude, radius and the Twitter keyword we're interested. This is returned back to our map, and we create a graphic for each of the tweets at its geotagged location (from the geo object of the Twitter API JSON payload). We do this using a PictureMarkerSymbol and also a suitable InfoTemplate with the users avatar, the content of the tweet and the date (again from the payload). The layout uses Bootstrap to allow for a responsive design that is suitable for most devices. We also make use of the Search widget, to allow for simple location finding for users.

Where could this be taken?

You (or I for that matter!) could go on to compare how different tweets compare geographically, go on to use a heatmap renderer or cluster layer to explore distribution better (may be a little redundant with the 100 tweet limit however). Alternatively if you have Twitter firehose access it might be easy to switch out the API.

Other things that might interest you

more
2 0 5,543
247 Subscribers