Thursday, February 18, 2016

Android Programming for Beginners - Especially Useful

Android Programming for Beginners - This book, though for beginner programmers that may not be familiar with Java, can be used as a refresher for job interviews or for a personal refresh.  I was surprised at how the author took some complex topics and made them understandable to someone who might not know anything about programming.  You get to building apps right away.  The environment is typical Windows and Android Studio, but if all you have is a Mac you should be fine too if you are intuitive about installing things.  If you are really wanting to be a programmer, you're going to have to learn to figure out problems all the time, so following this on a Mac should not be any issue.  But if you've really never programmed, then I'd recommend sticking with Windows and following along exactly.

You get to build quite a few apps from the basic setup all the way to publishing the app and marketing it.  The meat of the book is really about understanding the Android environment with a programmers mind.  Don't worry, it goes over Java language as well with some great analagies that I see would help even the newbie of noobs.  But we were all noobs at some point, and this book is a great start at it.  I wish I had this book when I started programming native Android.  Highly recommended.

Mastering RStudio - Develop, Communicate, and Collaborate with R - Pretty Sweet with a Slice of Awesome

Mastering RStudio - Develop, Communicate, and Collaborate with R - Tons of information and in-depth walk-throughs on how to create and present calculated data sets using all sorts of statistical analysis. I love that it helps me generate interactive websites and reports that look good. What's an analysis worth if you don't know how to present your findings? Don't get me wrong; this book is not all about how to present your findings. There are heaps of analysis tools to use which are powerful, but having the ability to generate more than just an in-application graph is a valuable asset.  Plus once they are generated, you can simply copy-paste them into your own environment.

I really like the way this book presents the data, principles, and solutions.  Good work!!!

Thursday, February 4, 2016

Custom Kendo UI Map Tips - A General Walk Through

QGIS

Find maps

First thing you need to do is find the maps you want to use.  There are many places where you can find shape file maps, but the main resource I ended up using is http://www.naturalearthdata.com/downloads/50m-cultural-vectors/.  The data comes in various scale.  For our purpose I used the 1:50m (medium scale) maps.  There are 3 type of data, Cultural, Physical, and Raster.  You want Cultural data.  I picked the Admin 0 – Countries in order to get a world map of the countries.  I then needed to merge the countries by deleting the USA and replacing it with the USA Counties.  So for the US Counties map, I went to https://www.census.gov/geo/maps-data/data/cbf/cbf_counties.html.

Download QGIS

The merge of the 2 files is best performed in a program called QGIS LTR (long term release) available for free here: http://www.qgis.org/en/site/forusers/download.html
Note I tried to use the merge function in the non LTR version, which was newer, but it seemed broken.  So I used the LTR version and the merge worked fine.

Load Layers into QGIS

Open QGIS Desktop, which ever version you have.
Unzip the map files you downloaded as well.  The files will contain many files, but you are looking for the files with the extension .shp and .dbf.
For QGIS, you don’t need the dbf file, but just be aware of its existence for further instructions.
You can now just drag the .shp files you want into the layers section of QGIS.  You’ll want to add all the files you have into the layer browser.
You should now have something like this:

Edit the layers

Now you need to edit the layers, by removing the overlapping shapes.  Play around with the “x” next to the layers to hide and show the layer you want to edit.  What we need to do is delete the USA from the admin map.  So we’ll hide the counties map by unselecting the x next to the counties layer.  Click on the admin layer to highlight it.  Then press the “edit” button to allow editing of the shapes:
Once edit is turned on you can now use the selection tool to click and highlight the USA.  It should turn a different color, in my case it was yellow:
Notice that you don’t have to highlight Alaska and Hawaii separately when you clicked on the USA.  Those get highlighted as well.  However, Puerto Rico does not get highlighted, which the county map contains the counties for as well, so we need to highlight that shape as well by holding the CTRL key and clicking on Puerto Rico shape:
Now that you have all the shapes selected where the two layers generally overlap, you can now delete the yellow highlighted shapes by pressing the DELETE key on your keyboard.  You should be left with the following:
If you want to pan around the map, press the hand button to switch to panning.  You may now turn off the editing button for this layer by pressing the editing button again: .  You want to save the changes.  Note that the admin (countries) file you loaded is now changed.
Now turn back on the counties layer and you’ll end up with the following:
We are now done editing the files and are ready to merge them into one file for use with Kendo UI Maps.

Merge Layers Into a single file

I never found an easy way to merge the visible layers from QGIS into a single file, but rather there is a processing tool you use to do the merge and then it’s loaded back into the layers as a third layer for you the check.
Open the file merge tool by going to: Vector >> Data Management Tools >> Merge Shapefiles to One…
Now select the checkbox indicated and select the 2 .shp files as input.  I had to move the shape files into the same folder so I could select both files by holding the CTRL key.
NOTE: on the export of the file, you must select the encoding as UTF-8.  This is critical in order for the Kendo UI Maps to read the file properly.
You should end up with this (once the merge is done, you can press cancel on the merge tool):
Now you want to right click on the new layer and select “Save As…”.
Make sure you select Format as GeoJSON, and Encoding as UTF-8.  It’s up to you if you want the saved file added to the map or not.  Once you have saved that, you now can take that GeoJSON file into mapshaper.org and simplify it.

MapShaper.org

Load the Map

Notice that the saved GeoJSON file is way too big to using in the website:
>
We need to shrink the file.  We do this with mapshaper.org.
Open http://mapshaper.org/  website and select the GeoJSON file you just saved.  Note if you are working with .shp files, you’ll need to load the corresponding .dbf file as well.  Just drag the GeoJSON file onto the website.
Press the simplify button: .  Then make sure that “prevent shape removal” is selected as well.  This will help from removing the small shapes, but if you simplify it too much it will anyway.
I’ve had good luck with simplifying it down to about 0.41%.  This makes the counties not too distorted, but it makes the file size a ton smaller.  When you’ve played with the simplify feature to your liking, then press the Export button.
You may need to enter “encryption=utf8” in the command line options if you are importing a non utf-8 file (say like a shape file you got from the internet somewhere that does not have utf-8 encoding already).
Select GeoJSON and there you have it, a smaller merged file:

Kendo UI Maps

The Code

I’m going to gloss over this part as there are tons of resources on how to setup and implement Kendo UI Maps.  Just google that term for the API (http://lmgtfy.com/?q=kendo+ui+maps).  You’ll need to workout your own event logic for the map, but here is my createMap function (it’s in angularJS) that creates the layers and sets up the callbacks to the appropriate event methods:
 $scope.createMap = function () {  
 // insert the markers into the $scope.kendoMapMarkers object  
 $scope.insertMapMarkers(null);  
 var colors = ["#104E8B", "#1874CD", "#1C86EE", "#2385E6", "#509EEA", "#60AAF3", "#86BCF1", "#9CC8F3", "#A4CEF8", "#B9DCFF"];  
 // create the map with the markers  
 $("#kendoMap").kendoMap({  
      center: [30.268107, -97.744821],  
      zoom: 3,  
      controls: {  
           attribution: false,  
           navigator: false  
      },  
      wraparound: false,  
      layers: [  
      //{  
      //  type: "tile",  
      //  urlTemplate: "http://#= subdomain #.tile.openstreetmap.org/#= zoom #/#= x #/#= y #.png",  
      //  subdomains: ["a", "b", "c"],  
      //  attribution: "© OpenStreetMap contributors"  
      //},  
      {  
           type: "shape",  
           dataSource: {  
                type: "geojson",  
                transport: {  
                     read: "/Resources/kendoui/GeoJSON/countries_and_counties_3.json"  
                }  
           }  
      },  
      {  
           type: "shape",  
           //autoBind: false,  
           dataSource: {  
                type: "geojson",  
                transport: {  
                     read: "/Resources/kendoui/GeoJSON/world_countries_and_states_provinces_lakes.json"  
                }  
           }  
      },  
      {  
           type: "marker",  
           dataSource: {  
                data: $scope.kendoMapMarkers  
           },  
           locationField: "latlng",  
           titleField: "name"  
      }],  
      shapeCreated: function (e) {  
           e.shape.fill("#104E8B");          
      },  
      markerCreated: function (e) {  
           // Draw a shape (circle) instead of a marker  
           e.preventDefault();  
      },  
      click: onClick,  
      reset: onReset,  
      pan: onPan,  
      panEnd: onPanEnd,  
      shapeClick: onShapeClick,  
      shapeMouseEnter: onShapeMouseEnter,  
      shapeMouseLeave: onShapeMouseLeave,  
      zoomStart: onZoomStart,  
      zoomEnd: onZoomEnd,  
      shapeClick: shapeClick  
 });  
Notice that in the “shapeCreated” and “markerCreated” functions I’m running them in-line while all the other functions refer to a reference to their respective methods.  You don’t need to do that and make them all reference calls.  It’s just a convenience thing.