Showing posts with label web maps. Show all posts
Showing posts with label web maps. Show all posts

Monday, September 9, 2013

The ESRI API for JavaScript/Dojo Build System Saga Continues...

This is my third post on this topic. First, there was discard layers. Then AMD threw a curve ball. And now a little bird told me that, starting at version 3.4, there is a special build of ESRI's API for JavaScript that is straight up minified AMD modules with no layers files. I'm not sure why this hasn't been more publicized. It's just a little minification away from releasing their source coded. And, as I will outline below, it allows you to build an honest-to-goodness layer file without any of the superfluous code that past versions required. This means that you can build all of the JavaScript code for your application including Dojo, ESRI and your own modules into a single, minified file.

To load the new AMD build of the ESRI API for JavaScript you just append "amd" onto the end of the url. For example, js.arcgis.com/3.6amd (3.5 requires something different because something is messed up with their build: http://js.arcgis.com/3.5amd/js/dojo/dojo/dojo.js). You should be able to just make this one change in your app and it should still work. You may need to explicitly require a few more ESRI modules now that you are not getting a bunch up front with their layer file. With this build you have to load each module individually. So it's going to slow down your load time significantly. It took our boilerplate from 128 requests to 337 requests to load the unbuilt, source version of the app. Needless to say that you should never use this url in production! In fact, I don't even use it during development because it takes so long to load.

The real usefulness in the new AMD build happens when you feed it through the Dojo Build System. The first step is to scrape it to your machine. In order to do this, I needed a list of all of the ESRI modules and other resources like images and .html files. I started with their argument aliases doc and then filled in the gaps by hand. It was easy to see what files I was missing since the build system returns errors for missing dependencies. After I had a good list of files, I used a bash script to pull the files down to my local machine. Here's the script:

The files cannot be fed directly into the build system as is. You'll notice that, in the script above, I had to fix some artifacts from their build (e.g. define('dep1,dep2,dep3'.split(','))...) as well as some paths to the dojo directories. After running this script you have the entire ESRI JavaScript API as separate modules that are ready for the build system. This is so ridiculously close to having the actual source code (just a bit of minification), I wonder if they are just going to release it in the future.

After getting the ESRI modules onto your computer, it's just a matter of pointing to them in your build profile and you are good to go.

You can see the entire set up for this process in AGRC's JavaScript Project Boilerplate. Hopefully the next blog post is about how awesome it is that ESRI has finally released their source code. ;)

Monday, October 11, 2010

Vehicle Tracking With The JavaScript API

Recently, we have been investigating alternatives to our current AVL solution. The problems with our current solution are licensing costs (big $$ per workstation) and ease of use. I thought that I'd give it a try with ESRI's JavaScript API and this is what I came up with.


The vehicles are graphics that are refreshed from the server every 5 seconds using the JavaScript setTimeout() function. I was surprised at how quickly the browser could clear the graphics and reload them from the server. It looks like they are animated instead of reloaded. Here's a sample of the code that I used:

function AddVehicleGraphics(){ SANDY.qt.execute(SANDY.q, function(fSet){ function sortGraphics(a,b){ return (a.attributes.fleetID < b.attributes.fleetID) ? -1 : 1; } // record bread crumbs, if any dojo.forEach(SANDY.crumbsVehicles, function(key){ var crumbGraphic = dojo.filter(SANDY.avlGraphicsLayer.graphics, function(item){ return item.attributes.mapKey == key; })[0]; SANDY.avlGraphicsLayer.remove(crumbGraphic); // required to allow appropriate refresh on history graphics layer crumbGraphic.setInfoTemplate(SANDY.crumbsTipTemplate); crumbGraphic.setSymbol(SANDY.crumbSymbol); // get associate graphics layer var gLayer = SANDY.mapDij.map.getLayer(key); gLayer.add(crumbGraphic); }); // clear graphics layer SANDY.avlGraphicsLayer.clear(); SANDY.chartsDij.clearContent(); // sort the graphics alphabetically so they are sorted when adding to active vehicles table. fSet.features.sort(sortGraphics); dojo.forEach(fSet.features, function(g){ var symbol; switch (g.attributes.defaultIcon) { case "PLOW TRUCK": symbol = dojo.clone(SANDY.truckSymbol); break; case "SWEEPER": symbol = dojo.clone(SANDY.sweeperSymbol); break; case "SUV": symbol = dojo.clone(SANDY.puSymbol); break; } // rotate symbol symbol.setAngle(g.attributes.headingDegrees); g.setSymbol(symbol); // round mph g.attributes.speedMPH = Math.round(g.attributes.speedMPH); // add to graphics layer SANDY.avlGraphicsLayer.add(g); // add to vehicles list / bold all vehicles that have updated in the last 30 minutes var content; var activeCutOff = new Date().setMinutes(new Date().getMinutes() - 30); if (new Date(g.attributes.timeAtCoordinate) > activeCutOff){ content = "<b>" + g.attributes.fleetID + "</b>"; } else { content = g.attributes.fleetID; } SANDY.chartsDij._addContent(content); // update date updated text var now = new Date(); dojo.byId("update-date").innerHTML = now.toLocaleTimeString(); dojo.style("update-date-background", "backgroundColor", "white"); }); if (fSet.features.length === 0){ SANDY.chartsDij._addContent(SANDY.noVehiclesMsg); } }, function(error){ // change background to indicate error dojo.style("update-date-background", "backgroundColor", "red"); }); }


The other cool thing that I was able to do in this project was link to live UDOT traffic cameras. After getting permission from them, I was able to determine the unique URL for each of them from the CommuterLink website and build a feature class with their locations and urls. It was easy after that to publish them as a map service and load them as graphics onto my map. I used a custom infoTip window from ESRI's code gallery and some mouse events to show the camera images.




// camera graphics dojo.connect(SANDY.mapDij.map.graphics, "onMouseOver", function(evt){ // store old symbol to save for mouse out function SANDY.origSymbol = evt.graphic.symbol; // get orig color rgb's var r = SANDY.origSymbol.color.r; var g = SANDY.origSymbol.color.g; var b = SANDY.origSymbol.color.b; // highlight opacity var a = 0.5; // change symbol to highlight symbol var biggerSize = evt.graphic.symbol.size + 4; evt.graphic.setSymbol(dojo.clone(evt.graphic.symbol).setSize(biggerSize).setColor([r, g, b, a])); SANDY.iTip.setContent(evt.graphic.getContent()); SANDY.iTip.show(evt.screenPoint, SANDY.mapDij.map.height, SANDY.mapDij.map.width); }); dojo.connect(SANDY.mapDij.map.graphics, "onMouseOut", function(evt){ // change symbol back evt.graphic.setSymbol(SANDY.origSymbol); SANDY.iTip.hide(); }); dojo.connect(SANDY.mapDij.map.graphics, "onClick", function(evt){ // hide infowindow SANDY.mapDij.map.infoWindow.hide(); });


The next step after we upgrade to ArcGIS Server 10 is to use the new TimeSlider dijit to enable users to view historical data. Sadly, because I'm changing jobs, I will not be around to implement this cool functionality.  :(

Any other suggestions? Anyone else using the JavaScript API for vehicle tracking? I'd love to hear your experiences.

Thursday, September 16, 2010

Cool Census Data App From ESRI Applications Prototype Lab

Here's a cool Silverlight app from the ESRI folks that like to live on the cutting edge. I really like the idea of using the physics engine to reposition the graphics. Obviously the app needs refining (what's with the tool bar on the left that looks disabled until you hover?), but the concept is cool. You can check out their related blog post here, or go right to the app to try it out yourself.

Friday, August 27, 2010

Public Facing Road Construction Projects Web Map

I just updated my only real public facing JavaScript app. This app (which is embedded in the city's web site) shows all of the road construction projects in the city along with relevant information that appears in a custom info window (ESRI dev sample) when you hover over the graphics.

I've also added the UDOT traffic cameras in this latest update. I was able to determine the id number and URL for each of the camera images using the UDOT CommterLink website. With permission from UDOT, I used this information to build my own map service showing the cameras.

What do you think? Anyone have any suggestions on making it better?

Friday, August 20, 2010

Go Web Mapping API's!

Two interesting quotes from the Deprecation Plans document just released from ESRI:
ArcGIS Server 10.0 is the last ArcGIS Server release with support for local connections from Web ADF applications. The 10.1 Web ADF applications will only support local connections to Server versions prior to 10.1. We recommend developers using local connections for accessing fine-grained ArcObjects migrate their business logic to Server Object Extensions. For Web ADF based editing applications (all of which use Local connections), we urge users to look at alternative web editing tools based in the ArcGIS Web Mapping APIs.
ArcGIS Server 10.1 will be the last planned release for the ArcGIS Server Web ADFs (Application Developer Framework) for both Microsoft .NET and Java. ESRI will continue supporting the Web ADFs during the 10.1 release cycle but only fixes to critical issues will be addressed. No new functionality or enhancement requests will be addressed for the Web ADFs. Web application developers are encouraged to move to a web services based pattern with the ArcGIS Web Mapping APIs for JavaScript, Flex, or Silverlight.
Looks like all of you Web ADF people have only a few years left to transition to the future.

Wednesday, July 28, 2010

So That's What "The Cloud" Means

ArcGIS Server Blog : ArcGIS Server on Amazon EC2: The Basics

Cool! It would be so nice to not worry about server issues that invariably arise. Let Amazon worry about that. Then I can focus on GIS.

Anyone going to try it out?

Monday, July 12, 2010

ESRI UC Fun

I, sadly, am not in San Diego right now for the ESRI User Conference. I'm trying to keep up as best as I can through the magic of the internet. "The Fee" is live-blogging the plenary right now if you are interested.

For those who are there, I would recommend DTS Agile's UC Back Channel. Aside from the beautiful web design and interesting use of the JavaScript API, it looks like a lot of fun. The prizes look interesting although it doesn't look like they're going to get enough participation for iPad's. I like this tee:
#GEOGLOBALDOMINATION
I'M KIND OF A BIG DEAL
ON TWITTER #ESRIUC

Thursday, July 8, 2010

Another ESRI API Following The Dinosaurs

It seemed like only yesterday that the Web ADF was ESRI's next big thing. But after only a few years of existence it looks to be on the way out. If you are jumping up and down with joy right now, you are not alone. I'm feeling quite relieved that I could never wrap my head around it even after taking an ESRI class. Maybe I wasn't the only one?

Tuesday, June 22, 2010

One Var To Rule Them All

As I was watching a great Tech Session video from ESRI's last Developer Summit on the JavaScript API, I was introduced to the concept of global variables being evil. Further research confirmed that I needed to alter my coding patterns a little bit. Since then I have tried to keep global variables to a minimum. If I do need them I have started storing them within a single variable like this:
// global variable var g = {}; g.baseURL = "http://gis.sandy.utah.gov/ArcGIS/rest/services/"; g.googleBaseURL = g.baseURL + "Public_Works/Google_Basemap/MapServer"; g.bwURL = g.baseURL + "Public_Works/BulkWasteAreas/MapServer"; g.vectorQueryURL = g.baseURL + "Public_Works/Vector_Basemap/MapServer/6"; g.locatorURL = g.baseURL + "Sandy_Address_Locator/GeocodeServer"; g.fldBW_DATE = "BW_DATE"; g.fldAREA_NUM = "AREA_NUM";

This has kept my code a little cleaner and has made it far easier to find the evil things during run-time with FireBug. My latest project with bulk waste data was my first attempt at global variable redemption.

Monday, June 21, 2010

I [heart] ArcGIS API for JavaScript


Did you all notice which ArcGIS Server API ESRI chose to use on their fancy, new website? No third-party plugins required.

Have you also noticed that the AGRC seems to be focusing on this API as well? I was talking with Bert Granberg and he used the phrase, "pure web".

I'm not saying that Flash and Silverlight are going away, but I just keep seeing more and more of the JavaScript API. With the recent backing of HTML5 by all of the industry's major players (even Adobe), I think that a "pure web" solution is going to continue to be a great choice in the future.

What do you all think? Who else is there in the region that's working with this API? We need to start a support group. ;)