tag:blogger.com,1999:blog-23465919967499417352024-03-05T09:30:09.115-08:00Open design and architectureOpen source software used for building open enterprise solutionsawachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.comBlogger100125tag:blogger.com,1999:blog-2346591996749941735.post-24872279945528795082017-10-07T11:03:00.000-07:002017-10-07T11:03:20.776-07:00Enabling SSL on PostgreSQLIn this post, we are going to walk through the steps for enabling ssl on postgresql on your Mac OSX. Enabling SSL requires the following steps.<br />
<br />
1. Install openssl on your machine<br />
2. Creating a new server side certificate<br />
3. Update postgresql.conf to turn ssl on<br />
4. Restart the database and test the connection<br />
<br />
To install openssl simply type brew install openssl on your command prompt.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7B1YbIhrGWdej3FpOPAJEJD6pHqMAml92LkV_k6XhQdhxwk5X6hLH69F7B0FAnL8CNoF61lxuGvNd2PikFF_9t2Cina4tpz6286stskLKha0wvmZ5-tXQXMr5okul_0mgY47654hRz5M/s1600/Screen1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="585" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7B1YbIhrGWdej3FpOPAJEJD6pHqMAml92LkV_k6XhQdhxwk5X6hLH69F7B0FAnL8CNoF61lxuGvNd2PikFF_9t2Cina4tpz6286stskLKha0wvmZ5-tXQXMr5okul_0mgY47654hRz5M/s640/Screen1.png" width="640" /></a></div>
<br />
Once ssl is installed, create a new server key request<br />
<br />
$ openssl req -new -text -out server.req<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4p3FRVzjOXepKS1AGn83b-aoQacUCj4jF6aaoqL9FneG6TDykyBBOGKpKynTeWIx3j0RO0fJ6PdpThJEuINZDegAbmrqjhzaaD_mYNQPKxT9WENq0QKT4EWXMbnJHmf4wiW3R2gMCw6E/s1600/Screen3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="585" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4p3FRVzjOXepKS1AGn83b-aoQacUCj4jF6aaoqL9FneG6TDykyBBOGKpKynTeWIx3j0RO0fJ6PdpThJEuINZDegAbmrqjhzaaD_mYNQPKxT9WENq0QKT4EWXMbnJHmf4wiW3R2gMCw6E/s640/Screen3.png" width="640" /></a></div>
<br />
Enter a passphrase<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQnLvzwLg30heJVXz9Uhl-iVJrLFsGik2yLaRiywKIMQEKmW7sMWfCCiuvcfLYkwvLORrFgxy-uLAkWXeHh6YZsHYuarE_dGyiHvyjreeqhXWrb0kF-HTsVJ4b8vT4ZZNacROc0XPMb2Q/s1600/Screen4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="585" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQnLvzwLg30heJVXz9Uhl-iVJrLFsGik2yLaRiywKIMQEKmW7sMWfCCiuvcfLYkwvLORrFgxy-uLAkWXeHh6YZsHYuarE_dGyiHvyjreeqhXWrb0kF-HTsVJ4b8vT4ZZNacROc0XPMb2Q/s640/Screen4.png" width="640" /></a></div>
Follow the steps to create the private key.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Next use the private key to create a server.key<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGJ0rrz8Yxv6xAaPnEzGuLgF5MLmLZ6gHq3cT5TPOFqflVkmQS0y9PO8drXt4VpWBgCz_Ym-T183orDCf1L2rf0GPjppVVt7HVJan3g5E6-tdrnHzrG1EVr6GhRY44JL4z4CNAc9ORCkU/s1600/Screen6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="585" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGJ0rrz8Yxv6xAaPnEzGuLgF5MLmLZ6gHq3cT5TPOFqflVkmQS0y9PO8drXt4VpWBgCz_Ym-T183orDCf1L2rf0GPjppVVt7HVJan3g5E6-tdrnHzrG1EVr6GhRY44JL4z4CNAc9ORCkU/s640/Screen6.png" width="640" /></a></div>
Enter the passphrase to confirm generation of the server key<br />
<br />
<br />
Now delete the private key to prevent it from falling in the wrong hands.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj47MUb4IgU2rbgIu4dyaDlwv3XnCPCfRq_Dcwr8vDKpW5QMplgXcpsKOjHYGaHIIj2HaqpoUB5rMVsXc25kUEHV_3AlkF-bA2ca_iF3mZHAcNjhIcntqyNOlx0Yyc3J9UG_aC68m8orw/s1600/Screen7.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"><img border="0" data-original-height="366" data-original-width="585" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj47MUb4IgU2rbgIu4dyaDlwv3XnCPCfRq_Dcwr8vDKpW5QMplgXcpsKOjHYGaHIIj2HaqpoUB5rMVsXc25kUEHV_3AlkF-bA2ca_iF3mZHAcNjhIcntqyNOlx0Yyc3J9UG_aC68m8orw/s640/Screen7.png" width="640" /></a>Use the appropriate commands to create a server certificate<br />
<br />
openssl req -X509 -in server.req -text -key server.key -out server.cert<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTXVZv77G7KrFVAoAyFPiyl9nGIMl1g50taO-C76MZQJg3ZCyC560fgg2M1kFB-TfFt0KFX3NxdXX8H-ztaW3qRxVLO3k9s_oEtZnz7Nv1RnfC7j9LsxSw7IAtIRDLm-FzrU0Mt3q7PwE/s1600/Screen8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="585" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTXVZv77G7KrFVAoAyFPiyl9nGIMl1g50taO-C76MZQJg3ZCyC560fgg2M1kFB-TfFt0KFX3NxdXX8H-ztaW3qRxVLO3k9s_oEtZnz7Nv1RnfC7j9LsxSw7IAtIRDLm-FzrU0Mt3q7PwE/s640/Screen8.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Next edit the file postgresql.conf by typing<br />
<br />
$ sudo vi /usr/local/var/postgres/postgresql.conf<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1wmp2nz1kvbzW55F45yJwRiSRAMDplVXi32iQ1JrGYb7cN8Lk-i-ln4OKHbRY4AeG_rY0A_CdHupt9OfkQv6gYZ1W8vQYKv4FN2iSHRzAIi4PFpbxH-d_Qs6ym1ab3530hGn171gSQ2U/s1600/Screen10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="655" height="356" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1wmp2nz1kvbzW55F45yJwRiSRAMDplVXi32iQ1JrGYb7cN8Lk-i-ln4OKHbRY4AeG_rY0A_CdHupt9OfkQv6gYZ1W8vQYKv4FN2iSHRzAIi4PFpbxH-d_Qs6ym1ab3530hGn171gSQ2U/s640/Screen10.png" width="640" /></a></div>
Change ssl to on<br />
<br />
Next, copy the server.crt and server.key files to the $PG_DATA folder<br />
<br />
$ sudo mv server.{crt,key} /usr/local/var/postgres<br />
<br />
Make sure the database owner has ownership on the server.key file<br />
<br />
$ sudo chown arthgallowachs /usr/local/var/postgres/server.key<br />
<br />
<br />
Finally, restart the Postgresql database by entering the following command<br />
<br />
$ pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log restart<br />
<br />
Once the database has restarted, login by specifying localhost to make sure the database is being connected over TCP/IP<br />
<br />
$ psql -h localhost -U postgres<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVT-Q4o7QnBw5uSa7-N3HWa5nRs0QT8Ivq1rD9aI1vdblyVBs4WrpepLRARLwQ1XE6-lDTzv5xosxSmSnUiUxkuQs1Hvushw97W59S7qmH2iVJdcveRxNdQTvTqwsPcpFC5YRYv0cFc7M/s1600/Screen11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="655" height="356" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVT-Q4o7QnBw5uSa7-N3HWa5nRs0QT8Ivq1rD9aI1vdblyVBs4WrpepLRARLwQ1XE6-lDTzv5xosxSmSnUiUxkuQs1Hvushw97W59S7qmH2iVJdcveRxNdQTvTqwsPcpFC5YRYv0cFc7M/s640/Screen11.png" width="640" /></a></div>
<br />
That's it we have enabled SSL using a self signed certificate.<br />
<div>
<br /></div>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-24334901432580981752016-12-07T20:14:00.001-08:002016-12-10T11:50:59.519-08:00Installing and creating the first project with Nativescript and Angular2 on UbuntuNativescript is the new opensource language for cross platform development using Angular 2. The framework and language is new, so took a little time to get things going. This post looks at the following:<br />
<ol>
<li>Installing the development tools, </li>
<li>Creating a simple application </li>
<li>Running the application on emulator and physical device</li>
<li>Packaging the file for distribution.</li>
</ol>
<div>
Be aware that the application is not very sophisticated as the focus is on the development experience rather than the app.</div>
<br />
<h3>
Prereq Installation</h3>
Nativescript and Angular2 installation is a little more involved than other nodejs environments. This is primarily due to the Android environment dependencies. Here are the steps.<br />
<ul>
<li>Enable virtualization on your BIOS for the emulators</li>
<li>Install prerequisite libraries</li>
<li>Install JDK and Android Studio SDK</li>
<li>Install Nativescript</li>
</ul>
The detailed steps are listed in <a href="https://docs.nativescript.org/start/ns-setup-linux">https://docs.nativescript.org/start/ns-setup-linux</a>, but here is the process I followed. I actually created a script to do the whole thing end to end, even though you are better off running step by step. First step on my machine indicated that virtualization had to be enabled at the BIOS level, which I had to do.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV8QMB2yKZrwyOovdHddmiClcAC0XbCckR8o6a0MeQJ2DCz2OVGI9V2duEu3Hv4oLBb9UAuA-qM1bJz6TvAIIlD_XOrhkgmi6TXTTdoCqMkVrjAOoQO8y6prAC_ULJC-tP-bfwfkxeK-U/s1600/Selection_081.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV8QMB2yKZrwyOovdHddmiClcAC0XbCckR8o6a0MeQJ2DCz2OVGI9V2duEu3Hv4oLBb9UAuA-qM1bJz6TvAIIlD_XOrhkgmi6TXTTdoCqMkVrjAOoQO8y6prAC_ULJC-tP-bfwfkxeK-U/s640/Selection_081.png" width="640" /></a></div>
<br />
Here is the script for first 3 steps until the end of installing Android Studio and emulators..<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #0099ff; font-style: italic;"># Set the current directory to INSTALL_DIR as we will need to come back here</span>
<span style="color: #336666;">export </span><span style="color: #003333;">INSTALL_DIR</span><span style="color: #555555;">=</span><span style="color: #cc3300;">"$PWD"</span>
<span style="color: #0099ff; font-style: italic;"># kvm-ok is needed for the emulators to be installed. It checks if BIOS ..</span>
<span style="color: #0099ff; font-style: italic;"># supports hardware accelerated KVM virtual machines. You may need to turn on</span>
<span style="color: #0099ff; font-style: italic;"># hardware accelerated virtual machines in your BIOS</span>
sudo apt-get install cpu-checker
sudo kvm-ok
<span style="color: #0099ff; font-style: italic;"># sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils</span>
<span style="color: #0099ff; font-style: italic;"># Install pre-requisite libraries</span>
sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 libstdc++6:i386
sudo apt-get install g++
<span style="color: #0099ff; font-style: italic;"># Install JDK</span>
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer
sudo update-alternatives --config java
<span style="color: #336666;">export </span><span style="color: #003333;">JAVA_HOME</span><span style="color: #555555;">=</span><span style="color: #006699; font-weight: bold;">$(</span>update-alternatives --query javac | sed -n -e <span style="color: #cc3300;">'s/Best: *\(.*\)\/bin\/javac/\1/p'</span><span style="color: #006699; font-weight: bold;">)</span>
<span style="color: #0099ff; font-style: italic;"># Setup Android</span>
mkdir -p ~/android
<span style="color: #336666;">cd</span> ~/android
wget -nc https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
tar -xvf *.tgz
<span style="color: #336666;">export </span><span style="color: #003333;">ANDROID_HOME</span><span style="color: #555555;">=</span>~/android/android-sdk-linux
sudo <span style="color: #003333;">$ANDROID_HOME</span>/tools/android update sdk --filter tools,platform-tools,android-23,build-tools-23.0.3,extra-android-m2repository,extra-google-m2repository,extra-android-support --all --no-ui
</pre>
</div>
<br />
If for some reason, ANDROID_HOME is not added to your .bashrc path, we will also need to manually edit our .bashrc file to add the ANDROID_HOME and the Android tools permanently. For this, edit the .bashrc file in your root folder and add the following lines.<br />
<br />
To open the .bashrc file<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">gedit .bashrc
</pre>
</div>
<br />
Now add the following lines at the end.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #336666;">export </span><span style="color: #003333;">ANDROID_HOME</span><span style="color: #555555;">=</span><span style="color: #003333;">$HOME</span>/android/android-sdk-linux
<span style="color: #336666;">export </span><span style="color: #003333;">PATH</span><span style="color: #555555;">=</span><span style="color: #003333;">$PATH</span>:<span style="color: #003333;">$ANDROID_HOME</span>/tools
<span style="color: #336666;">export </span><span style="color: #003333;">PATH</span><span style="color: #555555;">=</span><span style="color: #003333;">$PATH</span>:<span style="color: #003333;">$ANDROID_HOME</span>/platform-tools
</pre>
</div>
<br />
In my execution, the setup could also not find lib32bz2-1.0. Replacing with libbz2-1.0:i386 worked, as shown below.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">sudo apt-get install lib32z1 lib32ncurses5 libbz2-1.0:i386 libstdc++6:i386
</pre>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxJcueqeHXf-S7APt0c0NtiCzbRQoVarkNR2I0sa-unMU6L6BW95Q1cvb1U4bNLtHoMozjERRE-eAQl9laBPf51A5Y1PrSjcHuurADoRJ2HsphrRkcglg8F4go7tsCQNwZiSWTlyBTtrQ/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E_022.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxJcueqeHXf-S7APt0c0NtiCzbRQoVarkNR2I0sa-unMU6L6BW95Q1cvb1U4bNLtHoMozjERRE-eAQl9laBPf51A5Y1PrSjcHuurADoRJ2HsphrRkcglg8F4go7tsCQNwZiSWTlyBTtrQ/s640/arthgallo%2540Ubuntu-GTX%253A+%257E_022.png" width="640" /></a></div>
<br />
Also, setting up Android Studio also requires setting up an emulator. Once the basic Android Studio is setup launch Android SDK manager and make sure that all components of your target API version are installed. To launch Android SDK Manager, enter<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #003333;">sudo $ANDROID_HOME</span>/tools/android
</pre>
</div>
<br />
The following screen shot was taken while installing the required API modules.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXU1QgCF_2oi-uB-p9eCVr3yt02GwGoB133VEs8C3EnCuSdKX1R8PzFATPrD1t2lfPb_Zu6f27ulQ2lzPaRXoWYGITyvlyU8zkuYWCGirYQattKQrdjJIReqJm7fZ55JhvSBVrjqIOvpA/s1600/Android+SDK+Manager+_076.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="442" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXU1QgCF_2oi-uB-p9eCVr3yt02GwGoB133VEs8C3EnCuSdKX1R8PzFATPrD1t2lfPb_Zu6f27ulQ2lzPaRXoWYGITyvlyU8zkuYWCGirYQattKQrdjJIReqJm7fZ55JhvSBVrjqIOvpA/s640/Android+SDK+Manager+_076.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Testing the environment requires you to setup an Android Virtual device (AVD). For my development, I chose Nexus 6 as the prototype device. Android virtual device Manager can be launched by the following command.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #003333;">$ANDROID_HOME</span>/tools/android avd
</pre>
</div>
<br />
Now we can create a new AVD.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrV-l3GqdavUjiNBinSSMCWtMsakk4-qAbtjREuYumZXewnA6Dw7WGfqhShemgbAp6R6OC0D-Y7SfGsdUYn_S1ih2-LlUzowqx7CAvphtYdwLK687r2tuBcmNAmdekMTeC9xGCtwVOQ-g/s1600/Android+Virtual+Device+%2528AVD%2529+Manager+_077.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="468" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrV-l3GqdavUjiNBinSSMCWtMsakk4-qAbtjREuYumZXewnA6Dw7WGfqhShemgbAp6R6OC0D-Y7SfGsdUYn_S1ih2-LlUzowqx7CAvphtYdwLK687r2tuBcmNAmdekMTeC9xGCtwVOQ-g/s640/Android+Virtual+Device+%2528AVD%2529+Manager+_077.png" width="640" /></a></div>
<br />
Clicking on Create AVD will show a dialog box similar to one below. This shows the options that I selected to create the AVD on my machine.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt-aY4cGLzXXM6IUpmEOMl5gczF1PJIloXFwj0eF4nMpcTsg2uD639s4YVP_dIZyLuDz2EpLGYCJ6TMa9Qb_b7t_bN1MxcD6Kh78D6ToVztiw_RnmeM16Vs74kf1scT36qha6C_h7pwmE/s1600/Edit+Android+Virtual+Device+%2528AVD%2529+_087.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt-aY4cGLzXXM6IUpmEOMl5gczF1PJIloXFwj0eF4nMpcTsg2uD639s4YVP_dIZyLuDz2EpLGYCJ6TMa9Qb_b7t_bN1MxcD6Kh78D6ToVztiw_RnmeM16Vs74kf1scT36qha6C_h7pwmE/s640/Edit+Android+Virtual+Device+%2528AVD%2529+_087.png" width="447" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Upon starting the AVD, I made sure the display is scaled to the correct size as well.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ41bFKVdCxrClnwycMFjjMlfSpOzvne7Af4-sqqyoQmWc-ZSvOkt8St9KWxkB0rRkw8-4HDW-ZhGD_58z15kJQWN_gq25HpjtLnr2sWvCNJe6KtyNY1GA6lTD4d5GBn3PXSZdkCgf6hw/s1600/Launch+Options+_088.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ41bFKVdCxrClnwycMFjjMlfSpOzvne7Af4-sqqyoQmWc-ZSvOkt8St9KWxkB0rRkw8-4HDW-ZhGD_58z15kJQWN_gq25HpjtLnr2sWvCNJe6KtyNY1GA6lTD4d5GBn3PXSZdkCgf6hw/s1600/Launch+Options+_088.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
This should start the emulator display as follows:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiILV5sYplGI2y1kMg86Cf-2D5MHnB9JFWnagqwxrsw9GgMn23iqc-j95yGHrcnrehZilD_GyizPwjYmIvv68E8GEqK-R5JvJ8KDDrsZTNad9_i8I3muDW67wcNOna5W5rQmbY17eOGeck/s1600/Selection_090.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiILV5sYplGI2y1kMg86Cf-2D5MHnB9JFWnagqwxrsw9GgMn23iqc-j95yGHrcnrehZilD_GyizPwjYmIvv68E8GEqK-R5JvJ8KDDrsZTNad9_i8I3muDW67wcNOna5W5rQmbY17eOGeck/s640/Selection_090.png" width="402" /></a></div>
<br />
<br />
<h3>
Nativescript installation</h3>
Nativescript installation is straightforward from this point on..<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #336666;">cd</span> <span style="color: #003333;">$INSTALL_DIR</span>
sudo npm install nativescript -g --unsafe-perm
<span style="color: #336666;">export </span><span style="color: #003333;">PATH</span><span style="color: #555555;">=</span><span style="color: #003333;">$PATH</span>:~/.node_modules_global/lib/node_modules/nativescript/bin</pre>
<pre style="line-height: 125%; margin: 0;">tns info
tns doctor</pre>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi_PLQ9fDAeEa8F8vD5-MtFukfNR7TDn_b9Dn54FUuPDd033LAIBUVzYZTENHcANvXLUQFlnmEMnWBjqimeN6rUOw9SxGsJTLoEWstt7Rsnu8M0dlsEghok9qtC7CdtxAq2egnCys5ARo/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-ns1_082.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi_PLQ9fDAeEa8F8vD5-MtFukfNR7TDn_b9Dn54FUuPDd033LAIBUVzYZTENHcANvXLUQFlnmEMnWBjqimeN6rUOw9SxGsJTLoEWstt7Rsnu8M0dlsEghok9qtC7CdtxAq2egnCys5ARo/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-ns1_082.png" width="640" /></a></div>
<br />
<h3>
Creating a new project</h3>
Now that everything is setup we can go ahead and create a new project. In the spirit of my previous posts on Angular2 and Typescript, I decided to name the project ng2-ns1. The following command creates a new project and adds android as one of the target platforms. Developing for iOS unfortunately is not possible on Ubuntu and other Linux variants.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">tns create ng2-ns1 --ng</pre>
<pre style="line-height: 125%; margin: 0;">cd ng2-ns1
tns platform add android
</pre>
</div>
<br />
This creates an empty typescript based nativescript project with a base app.component.ts and an app.component.html file. I wanted to extend this behaviour by adding two new components, one for a home and another for a login control.<br />
<br />
Unlike angular-cli, here the components have to be created by hand. So I did the following in my IDE<br />
<br />
<ul>
<li>Added a new folder called home and a folder called login under the app folder.</li>
<li>Added files home.component.ts, home.component.html under /home and login.component.ts and login.component.html under /login folders</li>
</ul>
<div>
You can see the folder structure in the following screenshot.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLECIl0MemrOcqNDLlAPa01jZNXcuUdKM6rnF8V_G-ZYCYjKNXZjQSIuqAqx458sATu1QpXWDPnJt5be-PSclXW87vP25aikkkzFUBCjFFDVGeM22TmTuYp6cHXT0MpNFwfWd5Z-cvdPs/s1600/login.component.ts+-+ng2-ns1+-+Visual+Studio+Code_083.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLECIl0MemrOcqNDLlAPa01jZNXcuUdKM6rnF8V_G-ZYCYjKNXZjQSIuqAqx458sATu1QpXWDPnJt5be-PSclXW87vP25aikkkzFUBCjFFDVGeM22TmTuYp6cHXT0MpNFwfWd5Z-cvdPs/s640/login.component.ts+-+ng2-ns1+-+Visual+Studio+Code_083.png" width="640" /></a></div>
<br />
Lets now go through each of these files one by one, starting with the login.component.<br />
<br />
<h4>
<u>login.component.html</u></h4>
Here is the code for the login.component utilizing nativescript UI elements. Notice that:<br />
<br />
<ul>
<li>Username and password both use the ngModel directive for two-way binding. This is way more chatty as each keystroke is submitted, but this is a native app, so ideally there is no round trip.</li>
<li>The message label uses one way binding</li>
<li>The submit button uses an event binding to call a login() function.</li>
<li>StackLayout functions like a div tag in html.</li>
</ul>
<br />
<div style="background: rgb(240, 243, 243); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 16.25px;"><span style="color: #330099; font-weight: bold;"><StackLayout></span>
<span style="color: #330099; font-weight: bold;"><Label</span> <span style="color: #330099;">text=</span><span style="color: #cc3300;">"login"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"h2 text-center"</span><span style="color: #330099; font-weight: bold;">></Label></span>
<span style="color: #330099; font-weight: bold;"><TextField</span> <span style="background-color: #ffaaaa; color: #aa0000;">[(</span><span style="color: #330099;">ngModel</span><span style="background-color: #ffaaaa; color: #aa0000;">)]="</span><span style="color: #330099;">username</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">""</span> <span style="color: #330099;">hint=</span><span style="color: #cc3300;">"Email Address"</span> <span style="color: #330099;">keyboardType=</span><span style="color: #cc3300;">"email"</span> <span style="color: #330099;">autocorrect=</span><span style="color: #cc3300;">"false"</span> <span style="color: #330099;">autocapitalizationType=</span><span style="color: #cc3300;">"none"</span><span style="color: #330099; font-weight: bold;">></TextField></span>
<span style="color: #330099; font-weight: bold;"><TextField</span> <span style="background-color: #ffaaaa; color: #aa0000;">[(</span><span style="color: #330099;">ngModel</span><span style="background-color: #ffaaaa; color: #aa0000;">)]="</span><span style="color: #330099;">password</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">""</span> <span style="color: #330099;">hint=</span><span style="color: #cc3300;">"Password"</span> <span style="color: #330099;">secure=</span><span style="color: #cc3300;">"true"</span><span style="color: #330099; font-weight: bold;">></TextField></span>
<span style="color: #330099; font-weight: bold;"><Label</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">text</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">message</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"h3 text-center"</span> <span style="color: #330099;">textWrap=</span><span style="color: #cc3300;">"true"</span><span style="color: #330099; font-weight: bold;">></Label></span>
<span style="color: #330099; font-weight: bold;"><Button</span> <span style="color: #330099;">text=</span><span style="color: #cc3300;">"Login"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"btn btn-primary btn-active"</span> <span style="background-color: #ffaaaa; color: #aa0000;">(</span><span style="color: #330099;">tap</span><span style="background-color: #ffaaaa; color: #aa0000;">)="</span><span style="color: #330099;">login</span><span style="background-color: #ffaaaa; color: #aa0000;">()"</span><span style="color: #330099; font-weight: bold;">></Button></span>
<span style="color: #330099; font-weight: bold;"><Button</span> <span style="color: #330099;">text=</span><span style="color: #cc3300;">"Sign-up"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"btn"</span><span style="color: #330099; font-weight: bold;">></Button></span>
<span style="color: #330099; font-weight: bold;"></StackLayout></span>
</pre>
</div>
<br />
<h4>
<u>login.component.ts</u></h4>
<div>
This file simply checks for a hard-coded username and password, entered by the user. Important to see a few differences from Angular2 + Typescript for web here.</div>
<div>
<ul>
<li>We don't need to decorate the properties as Input or Output properties.</li>
<li>We don't create a form element for username and password. Rather, Form submissions are handled through ngModel directive rather than implicit ngForm</li>
<li>We throw the loggedIn event using an event emitter once the login is successful.</li>
</ul>
</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> {Component, OnInit, EventEmitter} from <span style="color: #cc3300;">'@angular/core'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Component({
selector<span style="color: #555555;">:</span> <span style="color: #cc3300;">"login"</span>,
templateUrl<span style="color: #555555;">:</span> <span style="color: #cc3300;">"./login/login.component.html"</span>,
styleUrls<span style="color: #555555;">:</span>[<span style="color: #cc3300;">"./login/login.component.css"</span>]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> LoginComponent <span style="color: #006699; font-weight: bold;">implements</span> OnInit{
username:<span style="color: #007788; font-weight: bold;">string</span>;
password:<span style="color: #007788; font-weight: bold;">string</span>;
maxtries:<span style="color: #007788; font-weight: bold;">number</span> <span style="color: #555555;">=</span> <span style="color: #ff6600;">3</span>;
loggedIn <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">new</span> EventEmitter();
isLoggedIn:<span style="color: #007788; font-weight: bold;">boolean</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">false</span>;
loginAttempt: <span style="color: #007788; font-weight: bold;">number</span><span style="color: #555555;">=</span> <span style="color: #ff6600;">0</span>;
_valid_user:<span style="color: #007788; font-weight: bold;">string</span> <span style="color: #555555;">=</span> <span style="color: #cc3300;">"tom"</span>;
_valid_pwd:<span style="color: #007788; font-weight: bold;">string</span> <span style="color: #555555;">=</span> <span style="color: #cc3300;">"jerry"</span>;
<span style="color: #006699; font-weight: bold;">constructor</span>() {
}
ngOnInit() {
}
<span style="color: #006699; font-weight: bold;">public</span> counter: <span style="color: #007788; font-weight: bold;">number</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">this</span>.maxtries;
<span style="color: #006699; font-weight: bold;">public</span> get message()<span style="color: #555555;">:</span> <span style="color: #007788; font-weight: bold;">string</span> {
console.log(<span style="color: #cc3300;">"username="</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.username<span style="color: #555555;">+</span><span style="color: #cc3300;">", password="</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.password);
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>.counter <span style="color: #555555;">==</span> <span style="color: #ff6600;">0</span>)
{
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #cc3300;">"Enter username/ password. You have a maximum of "</span> <span style="color: #555555;">+</span> <span style="color: #006699; font-weight: bold;">this</span>.maxtries <span style="color: #555555;">+</span> <span style="color: #cc3300;">" attempts"</span>;
} <span style="color: #006699; font-weight: bold;">else</span> <span style="color: #006699; font-weight: bold;">if</span> (<span style="color: #006699; font-weight: bold;">this</span>.counter <span style="color: #555555;">></span> <span style="color: #ff6600;">0</span>
<span style="color: #555555;">&&</span> <span style="color: #006699; font-weight: bold;">this</span>.isLoggedIn) {
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #cc3300;">"Welcome!"</span>;
} <span style="color: #006699; font-weight: bold;">else</span> {
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #cc3300;">"Invalid username/ password. "</span><span style="color: #555555;">+</span> <span style="color: #cc3300;">"username="</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.username<span style="color: #555555;">+</span><span style="color: #cc3300;">", password="</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.password<span style="color: #555555;">+</span><span style="color: #cc3300;">". "</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.counter <span style="color: #555555;">+</span> <span style="color: #cc3300;">" attempts left"</span>;
}
}
<span style="color: #006699; font-weight: bold;">public</span> login() {
console.log(<span style="color: #cc3300;">"Login.login() pressed"</span>);
console.log(<span style="color: #cc3300;">"username="</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.username<span style="color: #555555;">+</span><span style="color: #cc3300;">", password="</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.password);
<span style="color: #006699; font-weight: bold;">if</span> ( (<span style="color: #006699; font-weight: bold;">this</span>.username <span style="color: #555555;">==</span> <span style="color: #006699; font-weight: bold;">this</span>._valid_user)
<span style="color: #555555;">&&</span> (<span style="color: #006699; font-weight: bold;">this</span>.password <span style="color: #555555;">==</span> <span style="color: #006699; font-weight: bold;">this</span>._valid_pwd)) {
<span style="color: #006699; font-weight: bold;">this</span>.isLoggedIn <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">true</span>;
<span style="color: #006699; font-weight: bold;">this</span>.loggedIn.emit();
} <span style="color: #006699; font-weight: bold;">else</span> {
<span style="color: #006699; font-weight: bold;">this</span>.counter<span style="color: #555555;">--</span>;
}
}
}</pre>
</div>
<h3>
Home component</h3>
Next, is the home component that simply is a container for the login component. My intention was to use the *ngIf directive to load or not load the login component, but the nativescript compiler did not like ngIf. I will research more and update this post as neccessary.<br />
<h4>
<u>home.component.html</u></h4>
This markup simply loads the login component. As mentioned previously, I wanted to include a *ngIf directive to control the display of login component if user was already logged in, but that did not work. I can catch the loggedIn event raised by the login component and set a property of the home component.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #330099; font-weight: bold;"><Label</span> <span style="color: #330099;">text=</span><span style="color: #cc3300;">"Version 0.03"</span><span style="color: #330099; font-weight: bold;">></Label></span>
<span style="color: #330099; font-weight: bold;"><login</span> <span style="background-color: #ffaaaa; color: #aa0000;">(</span><span style="color: #330099;">loggedIn</span><span style="background-color: #ffaaaa; color: #aa0000;">)="</span><span style="color: #330099;">onLogin</span><span style="background-color: #ffaaaa; color: #aa0000;">()"</span><span style="color: #330099; font-weight: bold;">></login></span>
</pre>
</div>
<br />
<h4>
<u>home.component.ts</u></h4>
The home.component.ts file simply has a property that is set once the loggedIn event raised by the login component is caught by the home component.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { Component, OnInit} from <span style="color: #cc3300;">'@angular/core'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Component({
selector<span style="color: #555555;">:</span> <span style="color: #cc3300;">"home"</span>,
templateUrl<span style="color: #555555;">:</span> <span style="color: #cc3300;">"./home/home.component.html"</span>,
styleUrls<span style="color: #555555;">:</span> [<span style="color: #cc3300;">"./home/home.component.css"</span>]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> HomeComponent <span style="color: #006699; font-weight: bold;">implements</span> OnInit{
unauthenticatedSession:<span style="color: #007788; font-weight: bold;">boolean</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">true</span>;
<span style="color: #006699; font-weight: bold;">constructor</span>() {
}
ngOnInit() {
}
onLogin() {
<span style="color: #006699; font-weight: bold;">this</span>.unauthenticatedSession<span style="color: #555555;">=</span><span style="color: #006699; font-weight: bold;">false</span>;
}
}
</pre>
</div>
<br />
<h3>
App Component</h3>
Finally, we get to the AppComponent. These are also simple.<br />
<h4>
<u>app.component.html</u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #330099; font-weight: bold;"><StackLayout</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"p-20"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><Label</span> <span style="color: #330099;">text=</span><span style="color: #cc3300;">"Hello Nativescript"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"h1 text-center"</span><span style="color: #330099; font-weight: bold;">></span> <span style="color: #330099; font-weight: bold;"></Label></span>
<span style="color: #330099; font-weight: bold;"><home></home></span>
<span style="color: #330099; font-weight: bold;"></StackLayout></span></pre>
</div>
<h4>
<u>app.component.ts</u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { Component } from <span style="color: #cc3300;">"@angular/core"</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Component({
selector<span style="color: #555555;">:</span> <span style="color: #cc3300;">"my-app"</span>,
templateUrl<span style="color: #555555;">:</span> <span style="color: #cc3300;">"app.component.html"</span>,
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> AppComponent {
}
</pre>
</div>
<br />
<h4>
<u>app.module.ts</u></h4>
Among the app classes, the app module is the only one that has some behaviour.<br />
<br />
<ul>
<li>We import NativeScriptFormsModule to allow ngModel directives to work. Without this module, the two way binding won't work.</li>
<li>We import the AppComponent, HomeComponent and LoginComponent as well.</li>
</ul>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { NgModule, NO_ERRORS_SCHEMA } from <span style="color: #cc3300;">"@angular/core"</span>;
<span style="color: #006699; font-weight: bold;">import</span> { NativeScriptModule } from <span style="color: #cc3300;">"nativescript-angular/platform"</span>;
<span style="color: #006699; font-weight: bold;">import</span> { NativeScriptFormsModule } from <span style="color: #cc3300;">"nativescript-angular/forms"</span>;
<span style="color: #006699; font-weight: bold;">import</span> { AppComponent } from <span style="color: #cc3300;">"./app.component"</span>;
<span style="color: #006699; font-weight: bold;">import</span> {HomeComponent} from <span style="color: #cc3300;">'./home/home.component'</span>;
<span style="color: #006699; font-weight: bold;">import</span> {LoginComponent} from <span style="color: #cc3300;">'./login/login.component'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>NgModule({
declarations<span style="color: #555555;">:</span> [AppComponent,
HomeComponent,
LoginComponent],
bootstrap<span style="color: #555555;">:</span> [AppComponent],
imports<span style="color: #555555;">:</span> [NativeScriptModule,
NativeScriptFormsModule],
schemas<span style="color: #555555;">:</span> [NO_ERRORS_SCHEMA]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> AppModule { }
</pre>
</div>
<br />
<h3>
Running the program</h3>
I ran the program on the emulator as well as a physical Samsung S5 connected via USB to my machine. Both cases the program ran successfully, and the physical phone is much faster for testing quickly. The commands are as follows:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #0099ff; font-style: italic;"># Run the program on emulator</span>
tns run android --emulator
<span style="color: #0099ff; font-style: italic;">#Run the program on emulator in livesync mode to allow app to refresh on code change</span>
tns livesync android --emulator --watch
<span style="color: #0099ff; font-style: italic;"># Run the program on physical device</span>
tns run android
<span style="color: #0099ff; font-style: italic;">#Run the program on physical device in livesync mode</span>
tns livesync android --watch
</pre>
</div>
<br />
Here is the application running on the Emulator<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0lTA5Fh7T91XZDdktPYTfut0Bw7TwX4DKSeLklKWFRflRwLz2K-Nt5gBpVOH4w8AhJTvm5FlsmYAKyFZOIIRuolN6WEQYS0O9g1tWGY4i373VDQ9JOHTpic7RnY2ADRAodjpDKJsk_NQ/s1600/Android+Emulator+-+GalaxyS6%253A5554_084.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0lTA5Fh7T91XZDdktPYTfut0Bw7TwX4DKSeLklKWFRflRwLz2K-Nt5gBpVOH4w8AhJTvm5FlsmYAKyFZOIIRuolN6WEQYS0O9g1tWGY4i373VDQ9JOHTpic7RnY2ADRAodjpDKJsk_NQ/s640/Android+Emulator+-+GalaxyS6%253A5554_084.png" width="346" /></a></div>
<br />
<br />
Here is the same app running on a Galaxy S5 physical device<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-T2_iA2on06V4YVDPuEn21yf2a11_oyJ18w81MS5bmYmu89TVk5Aw6uLcTfQKn4xGQj3qvvIx8qkMmJnEDZztlz_62Sdr_CA73qdYbbynB_6nkZWHgZPSiA7utmAfigkSyRbbLflzFnM/s1600/Screenshot_2016-12-07-22-52-08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="background-color: red; color: red;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-T2_iA2on06V4YVDPuEn21yf2a11_oyJ18w81MS5bmYmu89TVk5Aw6uLcTfQKn4xGQj3qvvIx8qkMmJnEDZztlz_62Sdr_CA73qdYbbynB_6nkZWHgZPSiA7utmAfigkSyRbbLflzFnM/s640/Screenshot_2016-12-07-22-52-08.png" width="360" /></span></a></div>
<br />
<h3>
Packaging and distribution</h3>
Finally, we come to the task of packaging file for distribution. It is done in 3 easy steps<br />
<ul>
<li>Prepare the environment</li>
<li>Generate a keystore</li>
<li>Build the final distribution</li>
</ul>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #0099ff; font-style: italic;">#Prepare the environment</span>
tns prepare android
<span style="color: #0099ff; font-style: italic;">#Generate a keystore</span>
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias some_alias
<span style="color: #0099ff; font-style: italic;"># Build</span>
tns build android --release --key-store-path <span style="color: #003333;">$PWD</span>/my-release-key.jks --key-store-password some_password --key-store-alias some_alias --key-store-alias-password some_password
</pre>
</div>
<br />
This creates a build as shown below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg__luvvBRe_5MQA4bg5SV3QHMpz63e5e9_F_eBePcH31JI7tfhOyn0ExsfW3rs3nyIuWOGaoVTePhVzWGh5SG1Mwn71_MfAfev6mAPexho4Tp-2yXhIS_7jM0y4XlXA8KbW4sjpg2Jv1w/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-ns1_085.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg__luvvBRe_5MQA4bg5SV3QHMpz63e5e9_F_eBePcH31JI7tfhOyn0ExsfW3rs3nyIuWOGaoVTePhVzWGh5SG1Mwn71_MfAfev6mAPexho4Tp-2yXhIS_7jM0y4XlXA8KbW4sjpg2Jv1w/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-ns1_085.png" width="640" /></a></div>
<br />
Finally, we can publish the app on Google Play, by signing in to <a href="https://play.google.com/apps/publish/signup/" target="_blank">https://play.google.com/apps/publish/signup/</a> and paying $25.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8KEYtaFhsRMZJ8uBoRNxZMCYhkQoTQ7SZ3pRMnoEBQifodGO5rVKwrgWM0QTO4YUzniNwWDZSltGs2rhbQyLJDoW6-1HIoFJ5OiTj4VYxuZxnPyotDH4ueGtJM4N-7ZB4T7_Y4y6Gll8/s1600/Google+Play+Developer+Console+-+Google+Chrome_086.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="486" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8KEYtaFhsRMZJ8uBoRNxZMCYhkQoTQ7SZ3pRMnoEBQifodGO5rVKwrgWM0QTO4YUzniNwWDZSltGs2rhbQyLJDoW6-1HIoFJ5OiTj4VYxuZxnPyotDH4ueGtJM4N-7ZB4T7_Y4y6Gll8/s640/Google+Play+Developer+Console+-+Google+Chrome_086.png" width="640" /></a></div>
<br />
That's it!<br />
<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-39578132870777875622016-12-04T22:09:00.000-08:002016-12-05T07:56:26.180-08:00Drag and Drop in Angular 2 with ng2-dragulaI wanted to implement a drag and drop scenario using Angular 2 and decided to put ng2-dragula through its paces. In this post, I will take this library for a spin. The post will follow the following steps<br />
<ol>
<li>Creating a new project to utilize ng2-dragula.</li>
<li>Configuring the project to use ng2-dragula</li>
<li>Implementing the dragula library</li>
<li>Adding more complex logic to the process to test dragula capabilities.</li>
</ol>
Lets go through these steps.<br />
<h3>
Creating a new project and install ng2-dragula</h3>
The first step had several tasks.. The high-level description of the tasks is as follows<br />
<ul>
<li>Create a new project using angular-cli. </li>
<li>Change into the root folder of the newly created directory</li>
<li>Install angular/material library using the node package manager (npm). Record this in the package.json using --save command.</li>
<li>Install the ng2-dragula and dragula libraries using npm. </li>
<li>Generate a new component - myeditor that will use the dragula library</li>
</ul>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">ng new ng2-4
<span style="color: #336666;">cd </span>ng2-4
npm install --save @angular/material
npm install --save ng2-dragula dragula
ng generate component myeditor
</pre>
</div>
<br />
The big issue is that as time of writing this post, ng2-dragula expected a previous version of angular2 that shows up as unmet peer dependencies. I could not resolve it, but code seemed to work for most part.<br />
<h3>
Configuring the project to use ng2-dragula</h3>
Now that the library is installed, we need to configure the project to use ng2-dragula. This implies the following steps<br />
<ul>
<li>Edit the app.module.ts file and import the DragulaModule from ng2-dragula/ng2-dragula</li>
<li>Indicate DragulaModule import in the module declarations so it is accessible to other components in the project. (Note that DragulaModule is a wrapper on a provider called DragulaService and a directive called DragulaDirective within the package).</li>
<li>Add a vendor.ts under the /src directory and add a css import</li>
<li><br /></li>
</ul>
<h4>
<u>app.module.ts</u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { FormsModule } from <span style="color: #cc3300;">'@angular/forms'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { HttpModule } from <span style="color: #cc3300;">'@angular/http'</span>;
<span style="color: #006699; font-weight: bold;">import</span> {MaterialModule} from <span style="color: #cc3300;">'@angular/material'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { AppComponent } from <span style="color: #cc3300;">'./app.component'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { MyeditorComponent } from <span style="color: #cc3300;">'./myeditor/myeditor.component'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { DragulaModule } from <span style="color: #cc3300;">'ng2-dragula/ng2-dragula'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>NgModule({
declarations<span style="color: #555555;">:</span> [
AppComponent,
MyeditorComponent
],
imports<span style="color: #555555;">:</span> [
BrowserModule,
FormsModule,
HttpModule,
MaterialModule.forRoot(),
DragulaModule
],
providers<span style="color: #555555;">:</span> [],
bootstrap<span style="color: #555555;">:</span> [AppComponent]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> AppModule { }
</pre>
</div>
<br />
Here is a screenshot from my environment<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_fCKlNHQI0EvRwhUXZHzWkY_I3JfZmqnYCBmAZa4CTwucxHyQLeta2jQqDa1RLIZeHf5zxmuB35Bynk_MI6DO6T0pdiqBhbHUPYr5AkFZgO3ZSfgIzgfBWcjDXYLvup4jV_B1zStCnA0/s1600/app.module.ts+-+ng2-4+-+Visual+Studio+Code_073.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_fCKlNHQI0EvRwhUXZHzWkY_I3JfZmqnYCBmAZa4CTwucxHyQLeta2jQqDa1RLIZeHf5zxmuB35Bynk_MI6DO6T0pdiqBhbHUPYr5AkFZgO3ZSfgIzgfBWcjDXYLvup4jV_B1zStCnA0/s640/app.module.ts+-+ng2-4+-+Visual+Studio+Code_073.png" width="640" /></a></div>
<br />
<div>
<br /></div>
<div>
This vendor.ts file only contains an import of a css class as per the documentation but the css import was the most erratic part of the whole process, and I am not sure I got it completely right. Still, I followed the steps in the documentation.</div>
<h4>
<u>vendor.ts</u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> <span style="color: #cc3300;">'dragula/dist/dragula.css'</span>;
</pre>
</div>
<br />
Here is the screenshot from my environment.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiF7x1sL9X9bGtqwWp56VEzWXraGotxXhbSLENxHOYH9BTSXpSEMAR0hP5qYcWq8tjzxXRumO92N1TS3EukAdRAA1g_rzhd5TsXRTMeXnx8G14Q8b8HQRsOwZEiQo9_dCghgVm5Xuvp4E/s1600/vendor.ts+-+ng2-4+-+Visual+Studio+Code_074.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiF7x1sL9X9bGtqwWp56VEzWXraGotxXhbSLENxHOYH9BTSXpSEMAR0hP5qYcWq8tjzxXRumO92N1TS3EukAdRAA1g_rzhd5TsXRTMeXnx8G14Q8b8HQRsOwZEiQo9_dCghgVm5Xuvp4E/s640/vendor.ts+-+ng2-4+-+Visual+Studio+Code_074.png" width="640" /></a></div>
<br />
<h3>
Implementing the dragula library</h3>
<div>
This is the fun part. Implementing dragula is fairly easy. It requires a some css classes to be added to the component css. In the html we simply define the div tags that will define the different boxes and add the dragula directive. The code takes it from there.</div>
<div>
<br /></div>
<div>
Here are the high level steps:</div>
<div>
<br />
<ul>
<li>In the component html file, we define a simple html that contains an outer div tag which has a class called "wrapper" and 4 inner divs each that have a css class called "container".</li>
<li>Each of the div.container elements implements the [dragula] directive with a specific name - "editor-bag" that indicates that their contents can be dragged within them or between other div.containers which implement the same directive with same bag name.</li>
</ul>
</div>
<div>
<h4>
<u>myeditor.component.html</u></h4>
</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"wrapper"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"container master"</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">dragula</span><span style="background-color: #ffaaaa; color: #aa0000;">]="'</span><span style="color: #330099;">editor-bag</span><span style="background-color: #ffaaaa; color: #aa0000;">'"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"A Z"</span><span style="color: #330099; font-weight: bold;">></span>A<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"B Z"</span><span style="color: #330099; font-weight: bold;">></span>B<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"C Z"</span><span style="color: #330099; font-weight: bold;">></span>C<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"D Z"</span><span style="color: #330099; font-weight: bold;">></span>D<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"E Z"</span><span style="color: #330099; font-weight: bold;">></span>E<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"container"</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">dragula</span><span style="background-color: #ffaaaa; color: #aa0000;">]="'</span><span style="color: #330099;">editor-bag</span><span style="background-color: #ffaaaa; color: #aa0000;">'"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"A Z"</span><span style="color: #330099; font-weight: bold;">></span>A<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"container"</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">dragula</span><span style="background-color: #ffaaaa; color: #aa0000;">]="'</span><span style="color: #330099;">editor-bag</span><span style="background-color: #ffaaaa; color: #aa0000;">'"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"container"</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">dragula</span><span style="background-color: #ffaaaa; color: #aa0000;">]="'</span><span style="color: #330099;">editor-bag</span><span style="background-color: #ffaaaa; color: #aa0000;">'"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"></div></span>
</pre>
</div>
<div>
<br />
The accompanying component css class adds some rendering logic including some of the behavior prescribed by the dragula folks. Important things to note are<br />
<br />
<ul>
<li>css classes "wrapper" and "container" both implement display:float</li>
<li>css class Z ensures that all boxes labeled A through E are rectangles of a certain size and can be dragged around.</li>
</ul>
<br />
<h4>
<u>myeditor.component.css</u></h4>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555;">*,</span> <span style="color: #555555;">*</span><span style="color: #9999ff;">:before</span><span style="color: #555555;">,</span> <span style="color: #555555;">*</span><span style="color: #9999ff;">:after</span> {
<span style="color: #555555;">-</span>webkit<span style="color: #555555;">-</span>box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">inherit</span>;
<span style="color: #555555;">-</span>moz<span style="color: #555555;">-</span>box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">inherit</span>;
box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">inherit</span>;
}
<span style="color: #00aa88; font-weight: bold;">.promo</span> {
<span style="color: #006699; font-weight: bold;">margin-bottom</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">font-style</span><span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">italic</span>;
<span style="color: #006699; font-weight: bold;">padding</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">10px</span>;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">#ff4020</span>;
<span style="color: #006699; font-weight: bold;">border-bottom</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">5px</span> <span style="color: #006699; font-weight: bold;">solid</span> <span style="color: #ff6600;">#c00</span>;
}
<span style="color: #00aa88; font-weight: bold;">.parent</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> rgba(<span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">.</span><span style="color: #ff6600;">2</span>);
<span style="color: #006699; font-weight: bold;">margin</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">50px</span> <span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">padding</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">20px</span>;
}
<span style="color: #00aa88; font-weight: bold;">.gh-fork</span> {
<span style="color: #006699; font-weight: bold;">position</span><span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">fixed</span>;
<span style="color: #006699; font-weight: bold;">top</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">right</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">border</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span>;
}
<span style="color: #00aa88; font-weight: bold;">.wrapper</span> {
<span style="color: #006699; font-weight: bold;">display</span><span style="color: #555555;">:</span> flex;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">#942A57</span>;
flex<span style="color: #555555;">-</span>flow<span style="color: #555555;">:</span> row wrap;
}
<span style="color: #00aa88; font-weight: bold;">.container</span> {
<span style="color: #006699; font-weight: bold;">display</span><span style="color: #555555;">:</span> flex;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> rgba(<span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">.</span><span style="color: #ff6600;">2</span>);
<span style="color: #006699; font-weight: bold;">width</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">100</span><span style="color: #555555;">%</span>;
<span style="color: #006699; font-weight: bold;">min-height</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">150px</span>;
<span style="color: #006699; font-weight: bold;">min-width</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">500px</span>;
<span style="color: #006699; font-weight: bold;">margin-left</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">50px</span>;
<span style="color: #006699; font-weight: bold;">margin-right</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">50px</span>;
<span style="color: #006699; font-weight: bold;">margin-top</span><span style="color: #555555;">:</span><span style="color: #ff6600;">20px</span>;
<span style="color: #006699; font-weight: bold;">margin-bottom</span><span style="color: #555555;">:</span><span style="color: #ff6600;">20px</span>;
}
<span style="color: #00aa88; font-weight: bold;">.container</span><span style="color: #9999ff;">:nth-child</span><span style="color: #555555;">(</span><span style="color: #330099; font-weight: bold;">odd</span><span style="color: #555555;">)</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> rgba(<span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">.</span><span style="color: #ff6600;">2</span>);
}
<span style="color: #00aa88; font-weight: bold;">.container</span> <span style="color: #330099; font-weight: bold;">div</span><span style="color: #555555;">,</span>
<span style="color: #00aa88; font-weight: bold;">.gu-mirror</span> {
<span style="color: #006699; font-weight: bold;">margin</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">10px</span>;
<span style="color: #006699; font-weight: bold;">padding</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">10px</span>;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> rgba(<span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">.</span><span style="color: #ff6600;">2</span>);
transition<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">opacity</span> <span style="color: #ff6600;">0.4s</span> ease<span style="color: #555555;">-</span>in<span style="color: #555555;">-</span>out;
}
<span style="color: #00aa88; font-weight: bold;">.container</span> <span style="color: #330099; font-weight: bold;">div</span> {
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> move;
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> grab;
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> <span style="color: #555555;">-</span>moz<span style="color: #555555;">-</span>grab;
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> <span style="color: #555555;">-</span>webkit<span style="color: #555555;">-</span>grab;
}
<span style="color: #00aa88; font-weight: bold;">.gu-mirror</span> {
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> grabbing;
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> <span style="color: #555555;">-</span>moz<span style="color: #555555;">-</span>grabbing;
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> <span style="color: #555555;">-</span>webkit<span style="color: #555555;">-</span>grabbing;
}
<span style="color: #00aa88; font-weight: bold;">.container</span> <span style="color: #00aa88; font-weight: bold;">.ex-moved</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">#e74c3c</span>;
}
<span style="color: #00aa88; font-weight: bold;">.container.ex-over</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> rgba(<span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">.</span><span style="color: #ff6600;">3</span>);
}
<span style="color: #00aa88; font-weight: bold;">.handle</span> {
<span style="color: #006699; font-weight: bold;">padding</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span> <span style="color: #ff6600;">5px</span>;
<span style="color: #006699; font-weight: bold;">margin-right</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">5px</span>;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> rgba(<span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">.</span><span style="color: #ff6600;">4</span>);
<span style="color: #006699; font-weight: bold;">cursor</span><span style="color: #555555;">:</span> move;
}
<span style="color: #330099; font-weight: bold;">nested-repeat-example</span> <span style="color: #00aa88; font-weight: bold;">.container</span> <span style="color: #330099; font-weight: bold;">span</span> {
<span style="color: #006699; font-weight: bold;">display</span><span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">block</span>;
<span style="color: #006699; font-weight: bold;">padding</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">8px</span>;
}
<span style="color: #00aa88; font-weight: bold;">.container.master</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span>rgba(<span style="color: #ff6600;">155</span><span style="color: #555555;">,</span><span style="color: #ff6600;">155</span><span style="color: #555555;">,</span><span style="color: #ff6600;">155</span><span style="color: #555555;">,</span><span style="color: #ff6600;">1</span>);
<span style="color: #006699; font-weight: bold;">color</span><span style="color: #555555;">:</span> <span style="color: #336666;">white</span>;
}
<span style="color: #00aa88; font-weight: bold;">.Z</span> {
<span style="color: #006699; font-weight: bold;">width</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">75px</span>;
<span style="color: #006699; font-weight: bold;">height</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">125px</span>;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="color: #336666;">floralwhite</span>;
}
</pre>
</div>
<br />
This allows the boxes located in the first row to be moved around to any of the rows in the screen and their relative position to each other can also be modified.<br />
<br />
The logic in the app.component.ts is fairly simple as its just the container for the myeditor component.<br />
<h4>
<u>app.component.ts</u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #330099; font-weight: bold;"><h1></span>
{{title}}
<span style="color: #330099; font-weight: bold;"></h1></span>
<span style="color: #330099; font-weight: bold;"><myeditor></myeditor></span>
</pre>
</div>
<br />
Finally, app.component.css includes remaining css classes.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #330099; font-weight: bold;">body</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">#FFF9C4</span>;
<span style="color: #006699; font-weight: bold;">margin</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span> <span style="color: #006699; font-weight: bold;">auto</span>;
}
<span style="color: #330099; font-weight: bold;">html</span><span style="color: #555555;">,</span> <span style="color: #330099; font-weight: bold;">body</span> {
<span style="color: #555555;">-</span>webkit<span style="color: #555555;">-</span>box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">border</span><span style="color: #555555;">-</span>box;
<span style="color: #555555;">-</span>moz<span style="color: #555555;">-</span>box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">border</span><span style="color: #555555;">-</span>box;
box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">border</span><span style="color: #555555;">-</span>box;
}
<span style="color: #555555;">*,</span> <span style="color: #555555;">*</span><span style="color: #9999ff;">:before</span><span style="color: #555555;">,</span> <span style="color: #555555;">*</span><span style="color: #9999ff;">:after</span> {
<span style="color: #555555;">-</span>webkit<span style="color: #555555;">-</span>box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">inherit</span>;
<span style="color: #555555;">-</span>moz<span style="color: #555555;">-</span>box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">inherit</span>;
box<span style="color: #555555;">-</span>sizing<span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">inherit</span>;
}
<span style="color: #330099; font-weight: bold;">body</span><span style="color: #555555;">,</span> <span style="color: #330099; font-weight: bold;">input</span><span style="color: #555555;">,</span> <span style="color: #330099; font-weight: bold;">button</span> {
<span style="color: #006699; font-weight: bold;">font-family</span><span style="color: #555555;">:</span> Georgia<span style="color: #555555;">,</span> Helvetica;
<span style="color: #006699; font-weight: bold;">font-size</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">17px</span>;
<span style="color: #006699; font-weight: bold;">color</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">#ecf0f1</span>;
}
<span style="color: #330099; font-weight: bold;">h1</span> {
<span style="color: #006699; font-weight: bold;">text-align</span><span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">center</span>;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">#AC5C7E</span>;
<span style="color: #006699; font-weight: bold;">margin-top</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">20px</span>;
<span style="color: #006699; font-weight: bold;">margin-bottom</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">padding</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">10px</span>;
}
<span style="color: #330099; font-weight: bold;">h3</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> rgba(<span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">255</span><span style="color: #555555;">,</span> <span style="color: #ff6600;">0</span><span style="color: #555555;">.</span><span style="color: #ff6600;">2</span>);
<span style="color: #006699; font-weight: bold;">border-bottom</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">5px</span> <span style="color: #006699; font-weight: bold;">solid</span> <span style="color: #ff6600;">#A13462</span>;
<span style="color: #006699; font-weight: bold;">text-align</span><span style="color: #555555;">:</span> <span style="color: #006699; font-weight: bold;">center</span>;
<span style="color: #006699; font-weight: bold;">padding</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">10px</span>;
}
<span style="color: #330099; font-weight: bold;">h3</span> <span style="color: #330099; font-weight: bold;">div</span> {
<span style="color: #006699; font-weight: bold;">margin-bottom</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">10px</span>;
}
</pre>
</div>
<br />
<h3>
Adding more complex logic</h3>
Naturally, this was not complex enough logic. I wanted to extend the logic to ensure..<br />
<ul>
<li>The boxes in the top row (that also implements the css class "master") can be cloned to any other rows, but boxes in top row can never be re-arranged.</li>
<li>Boxes in the bottom rows can be re-arranged among themselves but cannot be transferred back to the top row.</li>
<li>There are some rules that are followed in positioning the boxes relative to each other.</li>
<ul>
<li>Box A can only be one at the start of the row</li>
<li>Box B and D can be anywhere in the row, in any number or any sequence.</li>
<li>Box B or D cannot follow Box C.</li>
<li>Box C or E can be the last boxes in the row, but there can be no other box after box E.</li>
</ul>
</ul>
<div>
I decide to implement the logic using different events thrown by the dragula library. I translated the above rules to a setOptions method called within the constructor of the component class.</div>
<div>
<br /></div>
<div>
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { Component, OnInit, Input } from <span style="color: #cc3300;">'@angular/core'</span>;
<span style="color: #006699; font-weight: bold;">import</span> {DragulaService, DragulaDirective} from <span style="color: #cc3300;">'ng2-dragula/ng2-dragula'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Component({
selector<span style="color: #555555;">:</span> <span style="color: #cc3300;">'myeditor'</span>,
templateUrl<span style="color: #555555;">:</span> <span style="color: #cc3300;">'./myeditor.component.html'</span>,
styleUrls<span style="color: #555555;">:</span> [<span style="color: #cc3300;">'./myeditor.component.css'</span>]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> MyeditorComponent <span style="color: #006699; font-weight: bold;">implements</span> OnInit {
<span style="color: #006699; font-weight: bold;">static</span> _debug:<span style="color: #007788; font-weight: bold;">boolean</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">false</span>;
_debug:<span style="color: #007788; font-weight: bold;">boolean</span> <span style="color: #555555;">=</span> MyeditorComponent._debug;
<span style="color: #006699; font-weight: bold;">static</span> _siblingMap: <span style="color: #007788; font-weight: bold;">Map</span><span style="color: #555555;"><</span><span style="color: #007788; font-weight: bold;">string</span>, AllowedSiblings<span style="color: #555555;">></span> ;
A_prev: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [];
A_next: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"B"</span>,<span style="color: #cc3300;">"C"</span>,<span style="color: #cc3300;">"D"</span>,<span style="color: #cc3300;">"E"</span>];
B_prev: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"A"</span>,<span style="color: #cc3300;">"B"</span>,<span style="color: #cc3300;">"D"</span>];
B_next: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"B"</span>,<span style="color: #cc3300;">"C"</span>,<span style="color: #cc3300;">"D"</span>,<span style="color: #cc3300;">"E"</span>];
C_prev: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"A"</span>,<span style="color: #cc3300;">"B"</span>,<span style="color: #cc3300;">"D"</span>];
C_next: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"E"</span>];
D_prev <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"A"</span>,<span style="color: #cc3300;">"B"</span>,<span style="color: #cc3300;">"D"</span>];
D_next: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"B"</span>,<span style="color: #cc3300;">"C"</span>,<span style="color: #cc3300;">"D"</span>,<span style="color: #cc3300;">"E"</span>];
E_prev <span style="color: #555555;">=</span> [<span style="color: #cc3300;">"A"</span>,<span style="color: #cc3300;">"B"</span>,<span style="color: #cc3300;">"C"</span>,<span style="color: #cc3300;">"D"</span>];
E_next: <span style="color: #007788; font-weight: bold;">string</span>[] <span style="color: #555555;">=</span> [];
<span style="color: #006699; font-weight: bold;">constructor</span>(<span style="color: #006699; font-weight: bold;">private</span> dragulaService: <span style="color: #007788; font-weight: bold;">DragulaService</span>) {
<span style="color: #006699; font-weight: bold;">if</span>(MyeditorComponent._siblingMap <span style="color: #555555;">==</span> <span style="color: #006699; font-weight: bold;">null</span>)
{
<span style="color: #006699; font-weight: bold;">this</span>.setupSiblingMap();
}
dragulaService.setOptions(<span style="color: #cc3300;">'editor-bag'</span>,{
isContainer: <span style="color: #007788; font-weight: bold;">function</span>(el) {
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">false</span>;
},
moves: <span style="color: #007788; font-weight: bold;">function</span>(el, container, handle) {
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">true</span>;<span style="color: #0099ff; font-style: italic;">//handle.classList.contains('master');</span>
},
accepts: <span style="color: #007788; font-weight: bold;">function</span>(el, target, source, sibling) {
<span style="color: #006699; font-weight: bold;">var</span> fn_debug <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">true</span>;
<span style="color: #006699; font-weight: bold;">var</span> acceptAll <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">false</span>;
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #555555;">!</span>acceptAll)
{
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug <span style="color: #555555;">||</span> fn_debug) {
console.log(<span style="color: #cc3300;">"accepts() start el, target, source, sibling"</span>);
console.log({el,target,source,sibling});
}
<span style="color: #006699; font-weight: bold;">if</span>(target.classList.contains(<span style="color: #cc3300;">'master'</span>)){
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">false</span>;
}
<span style="color: #006699; font-weight: bold;">if</span>(sibling<span style="color: #555555;">==</span><span style="color: #006699; font-weight: bold;">null</span>) {
<span style="color: #006699; font-weight: bold;">return</span> (target.children.length <span style="color: #555555;">==</span> <span style="color: #ff6600;">0</span>);
}
<span style="color: #006699; font-weight: bold;">var</span> name:<span style="color: #007788; font-weight: bold;">string</span> <span style="color: #555555;">=</span> el.innerText;
<span style="color: #006699; font-weight: bold;">return</span> MyeditorComponent.areAllowedSiblings(name,sibling);
}
<span style="color: #006699; font-weight: bold;">return</span> acceptAll;
},
invalid: <span style="color: #007788; font-weight: bold;">function</span> (el, handle) {
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">false</span>; <span style="color: #0099ff; font-style: italic;">// don't prevent any drags from initiating by default</span>
},
direction<span style="color: #555555;">:</span> <span style="color: #cc3300;">'vertical'</span>, <span style="color: #0099ff; font-style: italic;">// Y axis is considered when determining where an element would be dropped</span>
copy: <span style="color: #007788; font-weight: bold;">function</span>(el,source) {
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug) {
console.log(<span style="color: #cc3300;">"copy() start"</span>);
console.log(el);
console.log(source);
console.log(<span style="color: #cc3300;">"copy() stop"</span>);
}
<span style="color: #006699; font-weight: bold;">return</span> source.classList.contains(<span style="color: #cc3300;">'master'</span>);
}, <span style="color: #0099ff; font-style: italic;">// elements are moved by default, not copied</span>
copySortSource: <span style="color: #007788; font-weight: bold;">false</span>, <span style="color: #0099ff; font-style: italic;">// elements in copy-source containers can be reordered</span>
revertOnSpill: <span style="color: #007788; font-weight: bold;">false</span>, <span style="color: #0099ff; font-style: italic;">// spilling will put the element back where it was dragged from, if this is true</span>
removeOnSpill: <span style="color: #007788; font-weight: bold;">true</span>, <span style="color: #0099ff; font-style: italic;">// spilling will `.remove` the element, if this is true</span>
mirrorContainer: <span style="color: #007788; font-weight: bold;">document.body</span>, <span style="color: #0099ff; font-style: italic;">// set the element that gets mirror elements appended</span>
ignoreInputTextSelection: <span style="color: #007788; font-weight: bold;">true</span> <span style="color: #0099ff; font-style: italic;">// allows users to select input text, see details below</span>
})
}
ngOnInit() {
<span style="color: #006699; font-weight: bold;">this</span>.dragulaService.drag.subscribe((value:<span style="color: #007788; font-weight: bold;">any</span>) <span style="color: #555555;">=></span> {
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug) {
console.log(<span style="color: #cc3300;">"drag start"</span>);
console.log(value);
console.log(<span style="color: #cc3300;">"drag stop"</span>);
console.log(<span style="background-color: #ffaaaa; color: #aa0000;">`</span>drag: <span style="color: #007788; font-weight: bold;">$</span>{value[<span style="color: #ff6600;">0</span>]}<span style="background-color: #ffaaaa; color: #aa0000;">`</span>);
}
<span style="color: #006699; font-weight: bold;">this</span>.onDrag(value.slice(<span style="color: #ff6600;">1</span>));
});
<span style="color: #006699; font-weight: bold;">this</span>.dragulaService.drop.subscribe((value:<span style="color: #007788; font-weight: bold;">any</span>) <span style="color: #555555;">=></span> {
console.log(<span style="background-color: #ffaaaa; color: #aa0000;">`</span>drop: <span style="color: #007788; font-weight: bold;">$</span>{value[<span style="color: #ff6600;">0</span>]}<span style="background-color: #ffaaaa; color: #aa0000;">`</span>);
<span style="color: #006699; font-weight: bold;">this</span>.onDrop(value.slice(<span style="color: #ff6600;">1</span>));
});
<span style="color: #006699; font-weight: bold;">this</span>.dragulaService.over.subscribe((value:<span style="color: #007788; font-weight: bold;">any</span>) <span style="color: #555555;">=></span> {
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug) { console.log(<span style="background-color: #ffaaaa; color: #aa0000;">`</span>over: <span style="color: #007788; font-weight: bold;">$</span>{value[<span style="color: #ff6600;">0</span>]}<span style="background-color: #ffaaaa; color: #aa0000;">`</span>);}
<span style="color: #006699; font-weight: bold;">this</span>.onOver(value.slice(<span style="color: #ff6600;">1</span>));
});
<span style="color: #006699; font-weight: bold;">this</span>.dragulaService.out.subscribe((value:<span style="color: #007788; font-weight: bold;">any</span>) <span style="color: #555555;">=></span> {
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug) {console.log(<span style="background-color: #ffaaaa; color: #aa0000;">`</span>out: <span style="color: #007788; font-weight: bold;">$</span>{value[<span style="color: #ff6600;">0</span>]}<span style="background-color: #ffaaaa; color: #aa0000;">`</span>);}
<span style="color: #006699; font-weight: bold;">this</span>.onOut(value.slice(<span style="color: #ff6600;">1</span>));
});
}
<span style="color: #006699; font-weight: bold;">private</span> hasClass(el:<span style="color: #007788; font-weight: bold;">any</span>, name:<span style="color: #007788; font-weight: bold;">string</span>)<span style="color: #555555;">:</span>any {
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">new</span> <span style="color: #336666;">RegExp</span>(<span style="color: #cc3300;">'(?:^|\\s+)'</span> <span style="color: #555555;">+</span> name <span style="color: #555555;">+</span> <span style="color: #cc3300;">'(?:\\s+|$)'</span>).test(el.className);
}
<span style="color: #006699; font-weight: bold;">private</span> addClass(el:<span style="color: #007788; font-weight: bold;">any</span>, name:<span style="color: #007788; font-weight: bold;">string</span>)<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">void</span> {
<span style="color: #006699; font-weight: bold;">if</span> (<span style="color: #555555;">!</span><span style="color: #006699; font-weight: bold;">this</span>.hasClass(el, name)) {
el.className <span style="color: #555555;">=</span> el.className <span style="color: #555555;">?</span> [el.className, name].join(<span style="color: #cc3300;">' '</span>) <span style="color: #555555;">:</span> name;
}
}
<span style="color: #006699; font-weight: bold;">private</span> removeClass(el:<span style="color: #007788; font-weight: bold;">any</span>, name:<span style="color: #007788; font-weight: bold;">string</span>)<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">void</span> {
<span style="color: #006699; font-weight: bold;">if</span> (<span style="color: #006699; font-weight: bold;">this</span>.hasClass(el, name)) {
el.className <span style="color: #555555;">=</span> el.className.replace(<span style="color: #006699; font-weight: bold;">new</span> <span style="color: #336666;">RegExp</span>(<span style="color: #cc3300;">'(?:^|\\s+)'</span> <span style="color: #555555;">+</span> name <span style="color: #555555;">+</span> <span style="color: #cc3300;">'(?:\\s+|$)'</span>, <span style="color: #cc3300;">'g'</span>), <span style="color: #cc3300;">' '</span>);
}
}
<span style="color: #006699; font-weight: bold;">private</span> onDrag(args:<span style="color: #007788; font-weight: bold;">any</span>)<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">void</span> {
<span style="color: #006699; font-weight: bold;">let</span> [e] <span style="color: #555555;">=</span> args;
<span style="color: #006699; font-weight: bold;">this</span>.removeClass(e, <span style="color: #cc3300;">'ex-moved'</span>);
}
<span style="color: #006699; font-weight: bold;">private</span> onDrop(args:<span style="color: #007788; font-weight: bold;">any</span>)<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">void</span> {
<span style="color: #006699; font-weight: bold;">let</span> [e] <span style="color: #555555;">=</span> args;
<span style="color: #006699; font-weight: bold;">this</span>.addClass(e, <span style="color: #cc3300;">'ex-moved'</span>);
}
<span style="color: #006699; font-weight: bold;">private</span> onOver(args:<span style="color: #007788; font-weight: bold;">any</span>)<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">void</span> {
<span style="color: #006699; font-weight: bold;">let</span> [el] <span style="color: #555555;">=</span> args;
<span style="color: #006699; font-weight: bold;">this</span>.addClass(el, <span style="color: #cc3300;">'ex-over'</span>);
}
<span style="color: #006699; font-weight: bold;">private</span> onOut(args:<span style="color: #007788; font-weight: bold;">any</span>)<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">void</span> {
<span style="color: #006699; font-weight: bold;">let</span> [el] <span style="color: #555555;">=</span> args;
<span style="color: #006699; font-weight: bold;">this</span>.removeClass(el, <span style="color: #cc3300;">'ex-over'</span>);
}
<span style="color: #006699; font-weight: bold;">private</span> <span style="color: #006699; font-weight: bold;">static</span> areAllowedSiblings(name:<span style="color: #007788; font-weight: bold;">string</span>,sibling:<span style="color: #007788; font-weight: bold;">any</span>)<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">boolean</span> {
<span style="color: #0099ff; font-style: italic;">// return true;</span>
<span style="color: #006699; font-weight: bold;">var</span> fn_debug: <span style="color: #007788; font-weight: bold;">boolean</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">false</span>;
<span style="color: #006699; font-weight: bold;">var</span> isValid:<span style="color: #007788; font-weight: bold;">boolean</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">true</span>;
<span style="color: #006699; font-weight: bold;">var</span> nextSibling <span style="color: #555555;">=</span> sibling.nextSibling;
<span style="color: #006699; font-weight: bold;">var</span> prevSibling <span style="color: #555555;">=</span> sibling.previousSibling;
<span style="color: #006699; font-weight: bold;">var</span> allowedSiblings: <span style="color: #007788; font-weight: bold;">AllowedSiblings</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">null</span>;
<span style="color: #006699; font-weight: bold;">var</span> debugMsg <span style="color: #555555;">=</span> <span style="color: #cc3300;">""</span>;
<span style="color: #006699; font-weight: bold;">if</span>( MyeditorComponent._siblingMap<span style="color: #555555;">!=</span><span style="color: #006699; font-weight: bold;">null</span>) {
debugMsg<span style="color: #555555;">+=</span>(<span style="color: #cc3300;">"1:"</span><span style="color: #555555;">+</span>isValid);
<span style="color: #006699; font-weight: bold;">if</span>(isValid) {
allowedSiblings <span style="color: #555555;">=</span> MyeditorComponent._siblingMap.get(name);
isValid <span style="color: #555555;">=</span> (allowedSiblings<span style="color: #555555;">!=</span><span style="color: #006699; font-weight: bold;">null</span>);
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug <span style="color: #555555;">||</span> fn_debug) {
console.log(<span style="color: #cc3300;">"allowedSiblings"</span>);
console.log(allowedSiblings);
}
debugMsg<span style="color: #555555;">+=</span>(<span style="color: #cc3300;">",2:"</span><span style="color: #555555;">+</span>isValid);
}
<span style="color: #006699; font-weight: bold;">if</span>(isValid) {
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug <span style="color: #555555;">||</span> fn_debug) {
console.log(<span style="color: #cc3300;">"nextSibling"</span>);
console.log(nextSibling);
}
isValid <span style="color: #555555;">=</span> MyeditorComponent.isAllowedSibling(nextSibling,allowedSiblings.nextSiblings);
debugMsg<span style="color: #555555;">+=</span>(<span style="color: #cc3300;">",3:"</span><span style="color: #555555;">+</span>isValid);
}
<span style="color: #006699; font-weight: bold;">if</span>(isValid) {
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug <span style="color: #555555;">||</span> fn_debug) {
console.log(<span style="color: #cc3300;">"prevSibling"</span>);
console.log(prevSibling);
}
isValid <span style="color: #555555;">=</span> MyeditorComponent.isAllowedSibling(prevSibling,allowedSiblings.prevSiblings);
debugMsg<span style="color: #555555;">+=</span>(<span style="color: #cc3300;">",4:"</span><span style="color: #555555;">+</span>isValid);
}
}
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">this</span>._debug <span style="color: #555555;">||</span> fn_debug) {
console.log(<span style="color: #cc3300;">"isValid:"</span><span style="color: #555555;">+</span> debugMsg);
}
fn_debug <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">false</span>;
<span style="color: #006699; font-weight: bold;">return</span> isValid;
}
<span style="color: #006699; font-weight: bold;">private</span> <span style="color: #006699; font-weight: bold;">static</span> isAllowedSibling(siblingNode, allowedSiblingArray: <span style="color: #007788; font-weight: bold;">string</span>[])<span style="color: #555555;">:</span><span style="color: #006699; font-weight: bold;">boolean</span> {
<span style="color: #006699; font-weight: bold;">var</span> isValid:<span style="color: #007788; font-weight: bold;">boolean</span> <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">false</span>;
<span style="color: #006699; font-weight: bold;">if</span>(siblingNode <span style="color: #555555;">==</span> <span style="color: #006699; font-weight: bold;">null</span>)
{
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">true</span>;
}
<span style="color: #006699; font-weight: bold;">if</span>(siblingNode.nodeName <span style="color: #555555;">==</span> <span style="color: #cc3300;">"#text"</span>)
{
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">true</span>;
}
<span style="color: #006699; font-weight: bold;">if</span> (allowedSiblingArray.indexOf(siblingNode.innerText)<span style="color: #555555;">>-</span><span style="color: #ff6600;">1</span>)
{
isValid<span style="color: #555555;">=</span><span style="color: #006699; font-weight: bold;">true</span>;
}
<span style="color: #006699; font-weight: bold;">return</span> isValid;
}
<span style="color: #006699; font-weight: bold;">private</span> setupSiblingMap() {
MyeditorComponent._siblingMap <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">new</span> Map<span style="color: #555555;"><</span><span style="color: #007788; font-weight: bold;">string</span>, AllowedSiblings<span style="color: #555555;">></span>();
MyeditorComponent._siblingMap.set(<span style="color: #cc3300;">"A"</span>, <span style="color: #006699; font-weight: bold;">new</span> AllowedSiblings(<span style="color: #cc3300;">"A"</span>,<span style="color: #006699; font-weight: bold;">this</span>.A_prev,<span style="color: #006699; font-weight: bold;">this</span>.A_next ));
MyeditorComponent._siblingMap.set(<span style="color: #cc3300;">"B"</span>, <span style="color: #006699; font-weight: bold;">new</span> AllowedSiblings(<span style="color: #cc3300;">"B"</span>,<span style="color: #006699; font-weight: bold;">this</span>.B_prev,<span style="color: #006699; font-weight: bold;">this</span>.B_next ));
MyeditorComponent._siblingMap.set(<span style="color: #cc3300;">"C"</span>, <span style="color: #006699; font-weight: bold;">new</span> AllowedSiblings(<span style="color: #cc3300;">"C"</span>,<span style="color: #006699; font-weight: bold;">this</span>.C_prev,<span style="color: #006699; font-weight: bold;">this</span>.C_next ));
MyeditorComponent._siblingMap.set(<span style="color: #cc3300;">"D"</span>, <span style="color: #006699; font-weight: bold;">new</span> AllowedSiblings(<span style="color: #cc3300;">"D"</span>,<span style="color: #006699; font-weight: bold;">this</span>.D_prev,<span style="color: #006699; font-weight: bold;">this</span>.D_next ));
MyeditorComponent._siblingMap.set(<span style="color: #cc3300;">"E"</span>, <span style="color: #006699; font-weight: bold;">new</span> AllowedSiblings(<span style="color: #cc3300;">"E"</span>,<span style="color: #006699; font-weight: bold;">this</span>.E_prev,<span style="color: #006699; font-weight: bold;">this</span>.E_next ));
<span style="color: #0099ff; font-style: italic;">// if(this._debug) {</span>
<span style="color: #006699; font-weight: bold;">if</span>(<span style="color: #006699; font-weight: bold;">true</span>) {
console.log(MyeditorComponent._siblingMap);
}
}
}
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> AllowedSiblings {
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() name:<span style="color: #007788; font-weight: bold;">string</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() prevSiblings: <span style="color: #007788; font-weight: bold;">string</span>[];
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() nextSiblings: <span style="color: #007788; font-weight: bold;">string</span>[];
<span style="color: #006699; font-weight: bold;">constructor</span>(name:<span style="color: #007788; font-weight: bold;">string</span>,
prevSiblings: <span style="color: #007788; font-weight: bold;">string</span>[],
nextSiblings: <span style="color: #007788; font-weight: bold;">string</span>[]) {
<span style="color: #006699; font-weight: bold;">this</span>.name<span style="color: #555555;">=</span>name;
<span style="color: #006699; font-weight: bold;">this</span>.prevSiblings<span style="color: #555555;">=</span>prevSiblings;
<span style="color: #006699; font-weight: bold;">this</span>.nextSiblings<span style="color: #555555;">=</span>nextSiblings;
}
}
</pre>
</div>
<br />
The behavior was only partly implemented correctly. Only the following rules seem to be working.<br />
<ul>
<li>The boxes in the top row (that also implements the css class "master") can be cloned to any other rows, but boxes in top row can never be re-arranged.</li>
<li>Boxes in the bottom rows can be re-arranged among themselves but cannot be transferred back to the top row.</li>
<li>There are some rules that are followed in positioning the boxes relative to each other.</li>
<ul>
<li>Box A can only be one at the start of the row</li>
<li>Box B and D can be anywhere in the row, in any number or any sequence.</li>
<li>Box C or E can be the last boxes in the row, but there can be no other box after box E.</li>
</ul>
</ul>
These are the errors in the code:<br />
<br />
<ul>
<li>No Box can be added after Box A in second row</li>
<li>Box C and E cannot be added to any row</li>
</ul>
<div>
Here is a screenshot of the application. The highlighted cells are the ones that were added/ moved.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT1PsjWM4hiTPPGR4joDImLn-PY0Mm-EJNLKWC4Wn3yTB1KFJbTFZ776i0F6Ty23pKRU8j3oLnHHtP5d1zuIZWH8BpiGupy9wD4zkP7Nq9TptlVE4AX5SpmFZMtc3HGb4pWwXSNzjqjj8/s1600/Ng24+-+Google+Chrome_075.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="536" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT1PsjWM4hiTPPGR4joDImLn-PY0Mm-EJNLKWC4Wn3yTB1KFJbTFZ776i0F6Ty23pKRU8j3oLnHHtP5d1zuIZWH8BpiGupy9wD4zkP7Nq9TptlVE4AX5SpmFZMtc3HGb4pWwXSNzjqjj8/s640/Ng24+-+Google+Chrome_075.png" width="640" /></a></div>
<div>
<br />
I will continue to tweak the code and post updates as I fix more errors, or add any explanation.<br />
<br /></div>
</div>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-70246267179154437932016-12-02T15:43:00.001-08:002016-12-02T15:43:48.763-08:00CSS Class selectorsIn this post, I wanted to document various CSS class selectors. These are as follows<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #0099ff; font-style: italic;">/*</span>
<span style="color: #0099ff; font-style: italic;">* CSS class</span>
<span style="color: #0099ff; font-style: italic;">* <div class="classname">Any HTML element having the css class</div></span>
<span style="color: #0099ff; font-style: italic;">* <a class="classname">Any HTML element having the css class</a></span>
<span style="color: #0099ff; font-style: italic;">*/</span>
<span style="color: #00aa88; font-weight: bold;">.class1</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="background-color: #ffaaaa; color: #aa0000;">#</span><span style="color: #ff6600;">#ecf0f1</span>;
}
<span style="color: #0099ff; font-style: italic;">/*</span>
<span style="color: #0099ff; font-style: italic;">* HTML Element</span>
<span style="color: #0099ff; font-style: italic;">* <div>Directly reference a specific HTML element in css</div></span>
<span style="color: #0099ff; font-style: italic;">*/</span>
<span style="color: #330099; font-weight: bold;">div</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="background-color: #ffaaaa; color: #aa0000;">#</span><span style="color: #ff6600;">#ecf0f1</span>;
}
<span style="color: #0099ff; font-style: italic;">/*</span>
<span style="color: #0099ff; font-style: italic;">* HTML Element</span>
<span style="color: #0099ff; font-style: italic;">* <div class="classname">Directly reference a specific HTML element in css with a specific class</div></span>
<span style="color: #0099ff; font-style: italic;">*/</span>
<span style="color: #330099; font-weight: bold;">div</span><span style="color: #00aa88; font-weight: bold;">.class1</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="background-color: #ffaaaa; color: #aa0000;">#</span><span style="color: #ff6600;">#ecf0f1</span>;
}
<span style="color: #0099ff; font-style: italic;">/*</span>
<span style="color: #0099ff; font-style: italic;">* Multiple classes</span>
<span style="color: #0099ff; font-style: italic;">* <div class="class1 class2"> </div></span>
<span style="color: #0099ff; font-style: italic;">*/</span>
<span style="color: #00aa88; font-weight: bold;">.class1.class2</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="background-color: #ffaaaa; color: #aa0000;">#</span><span style="color: #ff6600;">#ecf0f1</span>
}
<span style="color: #0099ff; font-style: italic;">/*</span>
<span style="color: #0099ff; font-style: italic;">* HTML Child</span>
<span style="color: #0099ff; font-style: italic;">* <div><span> Select direct child of specific html element</span></div></span>
<span style="color: #0099ff; font-style: italic;">*/</span>
<span style="color: #330099; font-weight: bold;">div</span> <span style="color: #555555;">></span> <span style="color: #330099; font-weight: bold;">span</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="background-color: #ffaaaa; color: #aa0000;">#</span><span style="color: #ff6600;">#ecf0f1</span>;
}
<span style="color: #0099ff; font-style: italic;">/*</span>
<span style="color: #0099ff; font-style: italic;">* HTML Descendent</span>
<span style="color: #0099ff; font-style: italic;">* <div><p><span> Select a descendent of specific html element</span></p></div></span>
<span style="color: #0099ff; font-style: italic;">*/</span>
<span style="color: #330099; font-weight: bold;">div</span> <span style="color: #330099; font-weight: bold;">span</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="background-color: #ffaaaa; color: #aa0000;">#</span><span style="color: #ff6600;">#ecf0f1</span>;
}
<span style="color: #0099ff; font-style: italic;">/*</span>
<span style="color: #0099ff; font-style: italic;">* HTML Sibling</span>
<span style="color: #0099ff; font-style: italic;">* <div></div><span> Select a sibling of specific html element</span></p></div></span>
<span style="color: #0099ff; font-style: italic;">*/</span>
<span style="color: #330099; font-weight: bold;">div</span> <span style="color: #555555;">+</span> <span style="color: #330099; font-weight: bold;">span</span> {
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span> <span style="background-color: #ffaaaa; color: #aa0000;">#</span><span style="color: #ff6600;">#ecf0f1</span>;
}
</pre>
</div>
<br />
More syntax is listed at <a href="http://www.w3schools.com/cssref/css_selectors.asp" target="_blank">http://www.w3schools.com/cssref/css_selectors.asp</a>awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-63895700358786268162016-11-29T20:11:00.001-08:002016-12-01T05:01:13.189-08:00Using an Angular 2 Material Design componentIn this post, we will utilize the material design library being developed as part of Angular 2 to build a simple set of cards. In previous posts, we already covered the following<br />
<br />
<ul>
<li><a href="http://opendesignarch.blogspot.com/2016/11/angular2-project-using-angular-cli-with.html" target="_blank">Angular2 project using angular-cli with property and event binding</a></li>
<li><a href="http://opendesignarch.blogspot.com/2016/11/bootstrap-and-two-way-binding-with.html" target="_blank">Bootstrap and Two-way binding with Angular2</a></li>
</ul>
<br />
We will build on past experiences to introduce ourselves to material design with Angular 2, which is still evolving. Overall process is as follows<br />
<ol>
<li>Start a new project and add the material design library to our project</li>
<li>Create a new component using angular-cli</li>
<li>Build a JSON REST service stub (we will simply emulate the service, not build it.)</li>
<li>Use some material design components within our component</li>
<li>Bind our component to the REST service</li>
<li>View the final result.</li>
</ol>
<div>
At the end we will build a simple set of cards that look like the following:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUfxzjlblunvllZwNaoFOBHngdshqxjcFJVoMRlHJJ85c4TBTwelvJz0rPB8cJXhoKpaQSIAgbYR8_pD8ZfDDt83D4LWT29vwfHQIBpShArIss_bHdG4Z3ylqF4YxHizhJ3XqoMJfL5CY/s1600/Ng23+-+Google+Chrome_054.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="462" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUfxzjlblunvllZwNaoFOBHngdshqxjcFJVoMRlHJJ85c4TBTwelvJz0rPB8cJXhoKpaQSIAgbYR8_pD8ZfDDt83D4LWT29vwfHQIBpShArIss_bHdG4Z3ylqF4YxHizhJ3XqoMJfL5CY/s640/Ng23+-+Google+Chrome_054.png" width="640" /></a></div>
<div>
<br /></div>
Let's get started.<br />
<h3>
Adding Material Design to our project</h3>
Adding material design to the project is simple. Since I needed to carry out a few steps, I did the following steps<br />
<ul>
<li>I first created a new project using "ng new"</li>
<li>Then added material design to the project node modules using the following command. </li>
<li>Next I generated a component called mycard.</li>
<li>Finally I created a service called CardService.</li>
</ul>
The following steps document the script.<br />
<br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">ng new ng2-3
<span style="color: #336666;">cd </span>ng2-3
npm install --save @angular/material
ng generate component mycard
ng generate service cards
</pre>
</div>
<br />
Next we need to import the material design module within our primary application module. Access the application.module.ts and add the following lines at appropriate places.<br />
<br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { MaterialModule } from <span style="color: #cc3300;">'@angular/material'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>NgModule({
imports<span style="color: #555555;">:</span> [
MaterialModule.forRoot(), ...
],
</pre>
</div>
<br />
We also need the component definition added to app.module.ts<br />
<br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { MycardComponent } from <span style="color: #cc3300;">'./mycard/mycard.component'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>NgModule({
declarations<span style="color: #555555;">:</span> [
MycardComponent...
</pre>
</div>
<br />
Here is how the updated app.module.ts looks in my editor
<br />
<h4>
<u>app.module.ts</u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { BrowserModule } from <span style="color: #cc3300;">'@angular/platform-browser'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { NgModule } from <span style="color: #cc3300;">'@angular/core'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { FormsModule } from <span style="color: #cc3300;">'@angular/forms'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { HttpModule } from <span style="color: #cc3300;">'@angular/http'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { MaterialModule } from <span style="color: #cc3300;">'@angular/material'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { AppComponent } from <span style="color: #cc3300;">'./app.component'</span>;
<span style="color: #006699; font-weight: bold;">import</span> { MycardComponent } from <span style="color: #cc3300;">'./mycard/mycard.component'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>NgModule({
declarations<span style="color: #555555;">:</span> [
AppComponent,
MycardComponent
],
imports<span style="color: #555555;">:</span> [
BrowserModule,
FormsModule,
HttpModule,
MaterialModule.forRoot()
],
providers<span style="color: #555555;">:</span> [],
bootstrap<span style="color: #555555;">:</span> [AppComponent]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> AppModule { }
</pre>
</div>
<br />
A screenshot of the same..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikIvnRn0VkCCe0os6qPr8iRMMSpJpLR5Hpptx1cGAVq1xIIo1xZW1iOadO6_qSkVzmtUDGdBXcDtlQJS27EGPr3pmzjew48s754jtDdvNN6CLSJXnpWG3pf7wdXZ52JQYWHOOwWXzx4ew/s1600/app.module.ts+-+ng2-3+-+Visual+Studio+Code_055.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikIvnRn0VkCCe0os6qPr8iRMMSpJpLR5Hpptx1cGAVq1xIIo1xZW1iOadO6_qSkVzmtUDGdBXcDtlQJS27EGPr3pmzjew48s754jtDdvNN6CLSJXnpWG3pf7wdXZ52JQYWHOOwWXzx4ew/s640/app.module.ts+-+ng2-3+-+Visual+Studio+Code_055.png" width="640" /></a></div>
<br />
<h3>
Building a Service Stub</h3>
Next step is to edit the card.service.ts file to return a set of cards. I used the following JSON structure and code to create the service stub.<br />
<h4>
<u>card.service.ts</u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { Injectable } from <span style="color: #cc3300;">'@angular/core'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Injectable()
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> CardService {
cards <span style="color: #555555;">=</span> [{
<span style="color: #cc3300;">"svc_cardid"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">1</span>,
<span style="color: #cc3300;">"svc_cardname"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Birds of Norfolk"</span>
,<span style="color: #cc3300;">"svc_cardlink"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"https://commons.wikimedia.org/wiki/Category:Decorative_papers#/media/File:The_birds_of_Norfolk_-_with_remarks_on_their_habits,_migration,_and_local_distribution_(1866)_(14750215905).jpg"</span>
,<span style="color: #cc3300;">"svc_cardimg"</span><span style="color: #555555;">:</span><span style="color: #cc3300;">"https://upload.wikimedia.org/wikipedia/commons/3/3f/The_birds_of_Norfolk_-_with_remarks_on_their_habits%2C_migration%2C_and_local_distribution_%281866%29_%2814750215905%29.jpg"</span>
,<span style="color: #cc3300;">"Identifier"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"birdsofnorfolkwi01stev"</span>
,<span style="color: #cc3300;">"Title"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"The birds of Norfolk : with remarks on their habits, migration, and local distribution"</span>
,<span style="color: #cc3300;">"Year"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">1866</span>
,<span style="color: #cc3300;">"Authors"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Stevenson, Henry, 1833-1888 Southwell, Thomas, 1831-1909"</span>
,<span style="color: #cc3300;">"Subjects"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Birds -- England Norfolk"</span>
,<span style="color: #cc3300;">"Publisher"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"London : J. Van Voorst"</span>
,<span style="color: #cc3300;">"Contributing_Library"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"American Museum of Natural History Library"</span>
,<span style="color: #cc3300;">"Digitizing_Sponsor"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Biodiversity Heritage Library"</span>
}, {
<span style="color: #cc3300;">"svc_cardid"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">2</span>,
<span style="color: #cc3300;">"svc_cardname"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"1902 Annual Report"</span>
,<span style="color: #cc3300;">"svc_cardlink"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"https://commons.wikimedia.org/wiki/Category:Decorative_papers#/media/File:Annual_report_(1906)_(14745691021).jpg"</span>
,<span style="color: #cc3300;">"svc_cardimg"</span><span style="color: #555555;">:</span><span style="color: #cc3300;">"https://upload.wikimedia.org/wikipedia/commons/7/7d/Annual_report_%281906%29_%2814745691021%29.jpg"</span>
,<span style="color: #cc3300;">"Identifier"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"annualreport131415190newy"</span>
,<span style="color: #cc3300;">"Title"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Annual report"</span>
,<span style="color: #cc3300;">"Year"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">1902</span>
,<span style="color: #cc3300;">"Authors"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Forest, Fish and Game Commission"</span>
,<span style="color: #cc3300;">"Subjects"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Forests and forestry Fisheries Game and game-birds"</span>
,<span style="color: #cc3300;">"Publisher"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"(Albany, N.Y. : The Commission)"</span>
,<span style="color: #cc3300;">"Contributing_Library"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Smithsonian Libraries"</span>
,<span style="color: #cc3300;">"Digitizing_Sponsor"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Biodiversity Heritage Library"</span>
}, {
<span style="color: #cc3300;">"svc_cardid"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">3</span>,
<span style="color: #cc3300;">"svc_cardname"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Cooperative economic insects"</span>
,<span style="color: #cc3300;">"svc_cardlink"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"https://commons.wikimedia.org/wiki/Category:Decorative_papers#/media/File:Cooperative_economic_insect_report_(1955)_(20671420826).jpg"</span>
,<span style="color: #cc3300;">"svc_cardimg"</span><span style="color: #555555;">:</span><span style="color: #cc3300;">"https://upload.wikimedia.org/wikipedia/commons/9/9e/Cooperative_economic_insect_report_%281955%29_%2820671420826%29.jpg"</span>
,<span style="color: #cc3300;">"Identifier"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"cooperativeecono51955unit"</span>
,<span style="color: #cc3300;">"Title"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Cooperative economic insect report"</span>
,<span style="color: #cc3300;">"Year"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">1951</span>
,<span style="color: #cc3300;">"Authors"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Animal and Plant Health Service."</span>
,<span style="color: #cc3300;">"Subjects"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Beneficial insects; Insect pests"</span>
,<span style="color: #cc3300;">"Publisher"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Hyattsville, MD. (etc. )"</span>
,<span style="color: #cc3300;">"Contributing_Library"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Smithsonian Libraries"</span>
,<span style="color: #cc3300;">"Digitizing_Sponsor"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Biodiversity Heritage Library"</span>
}, {
<span style="color: #cc3300;">"svc_cardid"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">4</span>,
<span style="color: #cc3300;">"svc_cardname"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Histoire de Quillembois soldat"</span>
,<span style="color: #cc3300;">"svc_cardlink"</span><span style="color: #555555;">:</span><span style="color: #cc3300;">"https://commons.wikimedia.org/wiki/File:Histoire_de_Quillembois_soldat_(1920)_(14750774484).jpg"</span>
,<span style="color: #cc3300;">"svc_cardimg"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"https://upload.wikimedia.org/wikipedia/commons/f/f3/Histoire_de_Quillembois_soldat_%281920%29_%2814750774484%29.jpg"</span>
,<span style="color: #cc3300;">"Identifier"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"histoiredequille001871"</span>
,<span style="color: #cc3300;">"Title"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Histoire de Quillembois soldat"</span>
,<span style="color: #cc3300;">"Year"</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">1920</span>
,<span style="color: #cc3300;">"Authors"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"1871-1935"</span>
,<span style="color: #cc3300;">"Subjects"</span><span style="color: #555555;">:</span><span style="color: #cc3300;">""</span>
,<span style="color: #cc3300;">"Publisher"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"Nancy, Paris (etc.) : Librairie Berger-Levrault"</span>
,<span style="color: #cc3300;">"Contributing_Library"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"New York Public Library"</span>
,<span style="color: #cc3300;">"Digitizing_Sponsor"</span><span style="color: #555555;">:</span> <span style="color: #cc3300;">"msn"</span>
}];
<span style="color: #006699; font-weight: bold;">constructor</span>() { }
getCards()<span style="color: #555555;">:</span> any {
console.log(<span style="color: #cc3300;">"CardService.getCards() called"</span>);
<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">this</span>.cards;
}
}
</pre>
</div>
<br />
Next, we want to add some behaviour to the cards, as follows<br />
<ul>
<li>When a card is clicked, it goes in expanded mode. </li>
<li>When it is clicked again, it resumes to its non-expanded mode.</li>
<li>We also want the card to raise an event that can be implemented by the host component if needed. For this we add an Output parameter that raises an event using EventEmitter. </li>
</ul>
How the expanded mode differs from non-expanded, we will define in our style sheet later.<br />
<h4>
<u>mycard.component.ts</u></h4>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { Component, OnInit, Input, Output, EventEmitter } from <span style="color: #cc3300;">'@angular/core'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Component({
selector<span style="color: #555555;">:</span> <span style="color: #cc3300;">'mycard'</span>,
templateUrl<span style="color: #555555;">:</span> <span style="color: #cc3300;">'./mycard.component.html'</span>,
styleUrls<span style="color: #555555;">:</span> [<span style="color: #cc3300;">'./mycard.component.css'</span>]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> MycardComponent <span style="color: #006699; font-weight: bold;">implements</span> OnInit {
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() cardid <span style="color: #555555;">=</span> <span style="color: #555555;">-</span><span style="color: #ff6600;">1</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() cardname<span style="color: #555555;">=</span><span style="color: #cc3300;">""</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() cardimage<span style="color: #555555;">=</span><span style="color: #cc3300;">""</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() cardyear;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() cardauthor;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() cardpublisher;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() cardlink;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Input() isExpanded <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">false</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Output() cardClicked <span style="color: #555555;">=</span> <span style="color: #006699; font-weight: bold;">new</span> EventEmitter();
<span style="color: #006699; font-weight: bold;">constructor</span>() {
console.log(<span style="color: #cc3300;">"MycardComponent.constructor() called"</span>);
}
ngOnInit() {
}
onDivClick()
{
<span style="color: #006699; font-weight: bold;">this</span>.isExpanded <span style="color: #555555;">=</span> <span style="color: #555555;">!</span><span style="color: #006699; font-weight: bold;">this</span>.isExpanded;
console.log(<span style="color: #cc3300;">"MycardComponent.onDivClick("</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.cardid<span style="color: #555555;">+</span><span style="color: #cc3300;">").isExpanded(): "</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.isExpanded);
<span style="color: #006699; font-weight: bold;">this</span>.cardClicked.emit(<span style="color: #006699; font-weight: bold;">this</span>.cardid);
}
onDivHover()
{
console.log(<span style="color: #cc3300;">"MycardComponent.onDivHover("</span><span style="color: #555555;">+</span><span style="color: #006699; font-weight: bold;">this</span>.cardid<span style="color: #555555;">+</span><span style="color: #cc3300;">") called"</span>);
}
}
</pre>
</div>
<br />
Here is a screenshot of my editor screen.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzd4-TlUAeN-Lsw_I4WV7gOJ7oqBc3Od-i8Eo1p-qrqTCZnDn6i_L_Fk0vNZXb7T1tqsh5U1DDn1GNQ8drky173Y073JVrKeC3tDYI6k_nEIvlkiApq-BdhcAsB9ICYt7dyaV0L04YhGc/s1600/mycard.component.ts+-+ng2-3+-+Visual+Studio+Code_068.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzd4-TlUAeN-Lsw_I4WV7gOJ7oqBc3Od-i8Eo1p-qrqTCZnDn6i_L_Fk0vNZXb7T1tqsh5U1DDn1GNQ8drky173Y073JVrKeC3tDYI6k_nEIvlkiApq-BdhcAsB9ICYt7dyaV0L04YhGc/s640/mycard.component.ts+-+ng2-3+-+Visual+Studio+Code_068.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Next, we add the edit the mycard.component.html to add the rendering logic as follows<br />
<br />
<ul>
<li>An outer div tag to capture click events that calls onDivClick() in the component class</li>
<li>A md-card that has a ternary operator for loading appropriate css class based on the component's state isExpanded. The md-card contains the following sub-elements.</li>
<ul>
<li>An image with md-card-image directive and an image sourced from a component property</li>
<li>A md-card-title based on the cardname property of the class</li>
<li>A md-card-content containing a description obtained by concatenating several properties of the card.</li>
<li>A md-raised-button with accent color. </li>
</ul>
</ul>
<h4>
<u>mycard.component.html </u></h4>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #330099; font-weight: bold;"><div</span> <span style="background-color: #ffaaaa; color: #aa0000;">(</span><span style="color: #330099;">click</span><span style="background-color: #ffaaaa; color: #aa0000;">)="</span><span style="color: #330099;">onDivClick</span><span style="background-color: #ffaaaa; color: #aa0000;">()"</span> <span style="background-color: #ffaaaa; color: #aa0000;">(</span><span style="color: #330099;">hover</span><span style="background-color: #ffaaaa; color: #aa0000;">)="</span><span style="color: #330099;">onDivHover</span><span style="background-color: #ffaaaa; color: #aa0000;">()"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><md</span><span style="color: #330099;">-card</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"my-card {{isExpanded?'my-card-expanded':''}}"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><img</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"md-card-image"</span> <span style="color: #330099;">src=</span><span style="color: #cc3300;">"{{cardimage}}"</span> <span style="color: #330099;">md-card-image</span><span style="color: #330099; font-weight: bold;">/></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><md</span><span style="color: #330099;">-card-title</span><span style="color: #330099; font-weight: bold;">></span>{{cardname}}<span style="background-color: #ffaaaa; color: #aa0000;"><</span>/md-card-title>
<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><md</span><span style="color: #330099;">-card-content</span><span style="color: #330099; font-weight: bold;">></span>Authors: {{cardauthor}}, Published: {{cardyear}} by {{cardpublisher}}<span style="background-color: #ffaaaa; color: #aa0000;"><</span>/md-card-content>
<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"><button</span> <span style="color: #330099;">md-raised-button</span> <span style="color: #330099;">color=</span><span style="color: #cc3300;">"accent"</span><span style="color: #330099; font-weight: bold;">></span>View<span style="color: #330099; font-weight: bold;"></button></span>
<span style="background-color: #ffaaaa; color: #aa0000;"><</span>/md-card>
<span style="color: #330099; font-weight: bold;"></div></span>
</pre>
</div>
<br />
Here is the screenshot of the same..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlyqeymizBzD3eI3JYha5fPn9D41sMOs1B6lI6ymNYPntE8xZmSlmY02UDYT2NYuYG4U2fGJPFEP1UogFOG5JNIy5D6HYyAV2gr9Vnv-qL4UadA_FkJ5epHC909HBKBAMRiAuzCVDORqY/s1600/mycard.component.html+-+ng2-3+-+Visual+Studio+Code_059.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlyqeymizBzD3eI3JYha5fPn9D41sMOs1B6lI6ymNYPntE8xZmSlmY02UDYT2NYuYG4U2fGJPFEP1UogFOG5JNIy5D6HYyAV2gr9Vnv-qL4UadA_FkJ5epHC909HBKBAMRiAuzCVDORqY/s640/mycard.component.html+-+ng2-3+-+Visual+Studio+Code_059.png" width="640" /></a></div>
<br />
<h4>
<u>mycard.component.css</u></h4>
The css contains the style definition for the cards. Here are some important observations<br />
<br />
<ul>
<li>The default css for my-card simply sets 300px as width and height, sets a background color and a top and bottom margin.</li>
<li>The expanded card increases the height to 600px.</li>
<li>md-card-image restricts the height of the image to 180px, and sets object-fit to cover. This ensures that image is cropped to fit the placeholder</li>
<li>Finally md-card-title overrides the default font size to 20px, to save some space.</li>
</ul>
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #00aa88; font-weight: bold;">.my-card</span> {
<span style="color: #006699; font-weight: bold;">width</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">300px</span>;
<span style="color: #006699; font-weight: bold;">height</span><span style="color: #555555;">:</span><span style="color: #ff6600;">300px</span>;
<span style="color: #006699; font-weight: bold;">margin-left</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">margin-right</span><span style="color: #555555;">:</span><span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span><span style="color: #ff6600;">#eaeaea</span>;
<span style="color: #006699; font-weight: bold;">margin-top</span><span style="color: #555555;">:</span><span style="color: #ff6600;">10px</span>;
<span style="color: #006699; font-weight: bold;">margin-bottom</span><span style="color: #555555;">:</span><span style="color: #ff6600;">10px</span>;
}
<span style="color: #00aa88; font-weight: bold;">.my-card-expanded</span> {
<span style="color: #006699; font-weight: bold;">width</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">300px</span>;
<span style="color: #006699; font-weight: bold;">height</span><span style="color: #555555;">:</span><span style="color: #ff6600;">600px</span>;
<span style="color: #006699; font-weight: bold;">margin-left</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">margin-right</span><span style="color: #555555;">:</span><span style="color: #ff6600;">0</span>;
<span style="color: #006699; font-weight: bold;">background-color</span><span style="color: #555555;">:</span><span style="color: #ff6600;">#eaeaea</span>;
<span style="color: #006699; font-weight: bold;">margin-top</span><span style="color: #555555;">:</span><span style="color: #ff6600;">10px</span>;
<span style="color: #006699; font-weight: bold;">margin-bottom</span><span style="color: #555555;">:</span><span style="color: #ff6600;">10px</span>;
}
<span style="color: #00aa88; font-weight: bold;">.md-card-image</span> {
<span style="color: #006699; font-weight: bold;">height</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">180px</span>;
object<span style="color: #555555;">-</span>fit<span style="color: #555555;">:</span> cover;
}
<span style="color: #00aa88; font-weight: bold;">.md-card-title</span> {
<span style="color: #006699; font-weight: bold;">font-size</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">20px</span>;
<span style="color: #006699; font-weight: bold;">font-weight</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">400</span>;
}
</pre>
</div>
<br />
Here is a screenshot of the same..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOB7SF1T0JJbrRfvadFyVzT1fUdlfFXeJseWrDR7kx3HGfwDza5mzWO4CIBBrs1JSVHAbxHrASx9q5XfO_sZE6gucGyRVw9_gzYCTgNta9LVdH5l7v7MRPFcb5yuZVBqCYqyFm36ivNww/s1600/mycard.component.css+-+ng2-3+-+Visual+Studio+Code_060.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOB7SF1T0JJbrRfvadFyVzT1fUdlfFXeJseWrDR7kx3HGfwDza5mzWO4CIBBrs1JSVHAbxHrASx9q5XfO_sZE6gucGyRVw9_gzYCTgNta9LVdH5l7v7MRPFcb5yuZVBqCYqyFm36ivNww/s640/mycard.component.css+-+ng2-3+-+Visual+Studio+Code_060.png" width="640" /></a></div>
<br />
<h3>
Binding the service to mycard component</h3>
<h3>
<div style="font-size: medium; font-weight: normal;">
Next step is to bind the data received from the CardService to mycard component. This is done by the component initialising the mycard component. We also need to add the component to our primary app component. This is done in app.component.ts</div>
</h3>
<h4>
<u>app.component.ts</u></h4>
Here we do a few things.<br />
<ul>
<li>We import the CardService that we had defined earlier</li>
<li>We define a variable called cards;</li>
<li>We add the cardService to the constructor using dependency injection. Here we also assign the return type from getCards to the AppComponent's cards variable</li>
<li>We also add an event handler for the component's click event, simply to log which card was clicked.</li>
</ul>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #006699; font-weight: bold;">import</span> { Component } from <span style="color: #cc3300;">'@angular/core'</span>;
<span style="color: #006699; font-weight: bold;">import</span> {CardService} from <span style="color: #cc3300;">'./card.service'</span>;
<span style="background-color: #ffaaaa; color: #aa0000;">@</span>Component({
selector<span style="color: #555555;">:</span> <span style="color: #cc3300;">'app-root'</span>,
templateUrl<span style="color: #555555;">:</span> <span style="color: #cc3300;">'./app.component.html'</span>,
styleUrls<span style="color: #555555;">:</span> [<span style="color: #cc3300;">'./app.component.css'</span>],
providers<span style="color: #555555;">:</span> [CardService]
})
<span style="color: #006699; font-weight: bold;">export</span> <span style="color: #006699; font-weight: bold;">class</span> AppComponent {
title <span style="color: #555555;">=</span> <span style="color: #cc3300;">'Material Design Tiles!'</span>;
cards;
<span style="color: #006699; font-weight: bold;">constructor</span>(cardService: <span style="color: #007788; font-weight: bold;">CardService</span>) {
console.log(<span style="color: #cc3300;">"app.component.constructor() called"</span>);
<span style="color: #006699; font-weight: bold;">this</span>.cards<span style="color: #555555;">=</span>cardService.getCards();
}
compCardClicked($event) {
console.log(<span style="color: #cc3300;">"app.component.compCardClicked() called for:"</span><span style="color: #555555;">+</span> $event);
}
}
</pre>
</div>
<br />
Here is a screenshot of the same:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJmOMY9jPw1KNOtDjYqWik0w49jg4hT34LvIo6_PZ_FdqCjOPhXbJrLH1aW8JULC375zbUrsQqvHz5yLbkmfoQLKcW8fXQNNLPLQMcfh54uv5IgpsFW1lo8v2ctFJWcIdzOKBdWvY2tKk/s1600/app.component.ts+-+ng2-3+-+Visual+Studio+Code_069.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJmOMY9jPw1KNOtDjYqWik0w49jg4hT34LvIo6_PZ_FdqCjOPhXbJrLH1aW8JULC375zbUrsQqvHz5yLbkmfoQLKcW8fXQNNLPLQMcfh54uv5IgpsFW1lo8v2ctFJWcIdzOKBdWvY2tKk/s640/app.component.ts+-+ng2-3+-+Visual+Studio+Code_069.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Finally, we need to add our component to the app.component.html.<br />
<h4>
<u>
app.component.html</u></h4>
Here we do the following things<br />
<ul>
<li>We check if cards is populated, then we instantiate a div container with class=container (we will discuss this part next).</li>
<li>Within the div container, we create a for loop using ngFor directive, that iterates over the cards property of the app.component class (app.component.ts), and puts it within a my-card tag. </li>
<li>The html code also sets various properties of the mycard component using data received from the service.</li>
<li>The html markup also looks for cardClicked event raised by each card and calls the compCardClicked() method in the app.component class.</li>
</ul>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #330099; font-weight: bold;"><h1></span>
<span style="color: #330099; font-weight: bold;"></h1></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="background-color: #ffaaaa; color: #aa0000;">*</span><span style="color: #330099;">ngIf=</span><span style="color: #cc3300;">"cards"</span> <span style="color: #330099;">class=</span><span style="color: #cc3300;">"container"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><div</span> <span style="background-color: #ffaaaa; color: #aa0000;">*</span><span style="color: #330099;">ngFor=</span><span style="color: #cc3300;">"let card of cards, let i = index"</span><span style="color: #330099; font-weight: bold;">></span>
<span style="color: #330099; font-weight: bold;"><mycard</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">cardname</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">card</span><span style="background-color: #ffaaaa; color: #aa0000;">.</span><span style="color: #330099;">svc_cardname</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">cardid</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">card</span><span style="background-color: #ffaaaa; color: #aa0000;">.</span><span style="color: #330099;">svc_cardid</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span>
<span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">cardimage</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">card</span><span style="background-color: #ffaaaa; color: #aa0000;">.</span><span style="color: #330099;">svc_cardimg</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">cardauthor</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">card</span><span style="background-color: #ffaaaa; color: #aa0000;">.</span><span style="color: #330099;">Authors</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span>
<span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">cardyear</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">card</span><span style="background-color: #ffaaaa; color: #aa0000;">.</span><span style="color: #330099;">Year</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span> <span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">cardpublisher</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">card</span><span style="background-color: #ffaaaa; color: #aa0000;">.</span><span style="color: #330099;">Publisher</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span>
<span style="background-color: #ffaaaa; color: #aa0000;">[</span><span style="color: #330099;">cardlink</span><span style="background-color: #ffaaaa; color: #aa0000;">]="</span><span style="color: #330099;">card</span><span style="background-color: #ffaaaa; color: #aa0000;">.</span><span style="color: #330099;">svc_cardlink</span><span style="background-color: #ffaaaa; color: #aa0000;">"</span>
<span style="background-color: #ffaaaa; color: #aa0000;">(</span><span style="color: #330099;">cardClicked</span><span style="background-color: #ffaaaa; color: #aa0000;">)="</span><span style="color: #330099;">compCardClicked</span><span style="background-color: #ffaaaa; color: #aa0000;">($</span><span style="color: #330099;">event</span><span style="background-color: #ffaaaa; color: #aa0000;">)"</span><span style="color: #330099; font-weight: bold;">></mycard></span>
<span style="color: #330099; font-weight: bold;"></div></span>
<span style="color: #330099; font-weight: bold;"></div></span>
</pre>
</div>
<br />
Here is the html markup on my screen editor..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdyLzr-A3Wl5euLO3cFUFsdYw-kAoI4lgthzkWQcoV8ufnl22sz3xuGOSVmTrDYNYxHLIquRjk7sxsIgpRkhIZdBDc5qmgewJ5HebxODnUT72oKn-eoGgfqe4GBVKKy3b1XssgsJ0vjFA/s1600/app.component.html+-+ng2-3+-+Visual+Studio+Code_071.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdyLzr-A3Wl5euLO3cFUFsdYw-kAoI4lgthzkWQcoV8ufnl22sz3xuGOSVmTrDYNYxHLIquRjk7sxsIgpRkhIZdBDc5qmgewJ5HebxODnUT72oKn-eoGgfqe4GBVKKy3b1XssgsJ0vjFA/s640/app.component.html+-+ng2-3+-+Visual+Studio+Code_071.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Finally, we tackle the styling within app.component.css.<br />
<h4>
<u>app.component.css</u></h4>
The only definition is for the container class that sets the following<br />
<br />
<ul>
<li>A flex layout oriented by rows with row wrap to ensure mycards are wrapped based on space available.</li>
<li>A justify content (based on rows) and across "align-content" based on space-around.</li>
</ul>
<br />
<div style="background: #f0f3f3; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #00aa88; font-weight: bold;">.container</span> {
<span style="color: #006699; font-weight: bold;">display</span><span style="color: #555555;">:</span> flex; <span style="color: #0099ff; font-style: italic;">/* or inline-flex */</span>
flex<span style="color: #555555;">-</span>flow<span style="color: #555555;">:</span> row wrap;
<span style="color: #006699; font-weight: bold;">justify</span><span style="color: #555555;">-</span><span style="color: #006699; font-weight: bold;">content</span><span style="color: #555555;">:</span> space<span style="color: #555555;">-</span>around;
align<span style="color: #555555;">-</span><span style="color: #006699; font-weight: bold;">content</span><span style="color: #555555;">:</span> space<span style="color: #555555;">-</span>around;
<span style="color: #006699; font-weight: bold;">min-height</span><span style="color: #555555;">:</span> <span style="color: #ff6600;">110</span><span style="color: #555555;">%</span>;
}
</pre>
</div>
<br />
Here is the screenshot, once again..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjTneWUnCc-LWwetuqEVlcf7-atmhfGYuKvdd_SCgzjaXR1OfsEFWPn5A1owxde9iAlzsT2z4XYv348J88iGj_ccpn3P4me8G_ao4BIjm27cmnXoOqD9UvWqFPirNhl9Q7B926RFSqujk/s1600/app.component.css+-+ng2-3+-+Visual+Studio+Code_064.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjTneWUnCc-LWwetuqEVlcf7-atmhfGYuKvdd_SCgzjaXR1OfsEFWPn5A1owxde9iAlzsT2z4XYv348J88iGj_ccpn3P4me8G_ao4BIjm27cmnXoOqD9UvWqFPirNhl9Q7B926RFSqujk/s640/app.component.css+-+ng2-3+-+Visual+Studio+Code_064.png" width="640" /></a></div>
<br />
<h3>
Running it</h3>
Finally we can use ng serve command to view the configured page on localhost:4200<br />
<br />
This is the normal mode<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtcMU6oJoeOmApPh4X6kFLkYV747LFC9pwtO4BUuL0Wi-UsyXxUgp4fSC_goVG9OEchjC8ILLE0unO1C89SFLcViRaU-Pk9KHvyd8f0rFoB1NrPMx_gIP35oxiy6ztVS8C_WMj8CLk9X8/s1600/Ng23+-+Google+Chrome_065.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtcMU6oJoeOmApPh4X6kFLkYV747LFC9pwtO4BUuL0Wi-UsyXxUgp4fSC_goVG9OEchjC8ILLE0unO1C89SFLcViRaU-Pk9KHvyd8f0rFoB1NrPMx_gIP35oxiy6ztVS8C_WMj8CLk9X8/s640/Ng23+-+Google+Chrome_065.png" width="640" /></a></div>
<br />
and now the expanded mode after clicking on the card..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgijg63dDNj5_sCpLXBV370ZQjqS_Hgvb5ErNbdXDs1ZIncTPIGUOwsFMsZX4cJQRd1Fh-162h3YKsrmLczkYNAKmPLVppODMoEH6fwAhnFhfRyOqF0iLxRkSS4iXACCKKb6Xd3_FOAr2Q/s1600/Ng23+-+Google+Chrome_067.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="536" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgijg63dDNj5_sCpLXBV370ZQjqS_Hgvb5ErNbdXDs1ZIncTPIGUOwsFMsZX4cJQRd1Fh-162h3YKsrmLczkYNAKmPLVppODMoEH6fwAhnFhfRyOqF0iLxRkSS4iXACCKKb6Xd3_FOAr2Q/s640/Ng23+-+Google+Chrome_067.png" width="640" /></a></div>
<br />
Here is the same site with console logs visible<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJvp6B_16CqBx7ZZJlfXX784V4-chQVC_OuILLcl0GXsRB_2dlf63WKm96-bv18U0OgUoKbGifYgpEhCppQHfTupVhIPMLAb1V1_hMr_Z8bRJSJwOIPzGGNR4_W4NRQnBECvMZD-bYiCo/s1600/Ng23+-+Google+Chrome_072.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="536" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJvp6B_16CqBx7ZZJlfXX784V4-chQVC_OuILLcl0GXsRB_2dlf63WKm96-bv18U0OgUoKbGifYgpEhCppQHfTupVhIPMLAb1V1_hMr_Z8bRJSJwOIPzGGNR4_W4NRQnBECvMZD-bYiCo/s640/Ng23+-+Google+Chrome_072.png" width="640" /></a></div>
<br />
That's it!<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-25502304890722647562016-11-27T09:26:00.001-08:002016-11-28T11:19:42.146-08:00Bootstrap and Two-way binding with Angular2In my <a href="http://opendesignarch.blogspot.com/2016/11/angular2-project-using-angular-cli-with.html" target="_blank">previous post, we had examined event and property binding</a> in Angular 2, along with setting up angular from scratch. In this post, we will add bootstrap 4 to our Angular2 environment, and then test a component to see some of the capabilities of the library. We will also examine two way binding using the bootstrap components..<br />
<br />
<h3>
Creating a new project</h3>
Since we already installed angular-cli in the <a href="http://opendesignarch.blogspot.com/2016/11/angular2-project-using-angular-cli-with.html" target="_blank">previous blog</a>, lets create a new project called ng2-2 using "ng new" command. Let us also cd into the newly created project directory..<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">ng new ng2-2</span>
<span style="color: #cccccc;">cd ng2-2</span>
</pre>
</div>
<br />
This creates the new project.<br />
<h3>
Installing bootstrap</h3>
First step is to install bootstrap. We will install angular2 compliant bootstrap version called ng2-bootstrap. ng2-bootstrap utilizes the new Angular2 concepts to provide a Typescript based bootstrap library. Importantly it does not directly access the DOM.<br />
<br />
This step requires the following commands to be run from within the ng2 folder on the command line.. Please note that we are deploying an alpha version of the bootstrap 4 library. Needless to say, it will have to be updated with the latest versions as they are released.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">npm install --save bootstrap@4.0.0-alpha.5</span>
<span style="color: #cccccc;">npm install --save @ng-bootstrap/ng-bootstrap</span>
</pre>
</div>
<br />
Results will be similar to screen below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXAYYz5fqPCc7aK7JTQEH83AgkbwzvEw-PmXkxY7qhGHtCoDVR56HILxBZ5ZjScd9bplR8N8DNkitYc1xPE3_qKq9wucYUMHYdnnv-N_3H43cL2Sg2Q2nRU-Wp1q0CgNplSU9n1n4Nu14/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2_041.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXAYYz5fqPCc7aK7JTQEH83AgkbwzvEw-PmXkxY7qhGHtCoDVR56HILxBZ5ZjScd9bplR8N8DNkitYc1xPE3_qKq9wucYUMHYdnnv-N_3H43cL2Sg2Q2nRU-Wp1q0CgNplSU9n1n4Nu14/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2_041.png" width="640" /></a></div>
<br />
<h3>
Making ng2-bootstrap available to the project</h3>
<div>
To make the newly added ng2-bootstrap library available to the entire project, we need to add it to the app.module.ts file.. We add the following the two lines to our file<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">import</span> {NgbModule} from <span style="background-color: #fff0f0; color: #dd2200;">'@ng-bootstrap/ng-bootstrap'</span>;
imports: [
NgbModule.forRoot(), ...
],
</pre>
</div>
<br />
The following content shows these two lines added to my app.module.ts file<br />
<br /></div>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">import</span> { BrowserModule } from <span style="background-color: #fff0f0; color: #dd2200;">'@angular/platform-browser'</span>;
<span style="color: #008800; font-weight: bold;">import</span> { NgModule } from <span style="background-color: #fff0f0; color: #dd2200;">'@angular/core'</span>;
<span style="color: #008800; font-weight: bold;">import</span> { FormsModule } from <span style="background-color: #fff0f0; color: #dd2200;">'@angular/forms'</span>;
<span style="color: #008800; font-weight: bold;">import</span> { HttpModule } from <span style="background-color: #fff0f0; color: #dd2200;">'@angular/http'</span>;
<span style="color: #008800; font-weight: bold;">import</span> {NgbModule} from <span style="background-color: #fff0f0; color: #dd2200;">'@ng-bootstrap/ng-bootstrap'</span>;
<span style="color: #008800; font-weight: bold;">import</span> { AppComponent } from <span style="background-color: #fff0f0; color: #dd2200;">'./app.component'</span>;
<span style="color: #008800; font-weight: bold;">import</span> { LikesComponent } from <span style="background-color: #fff0f0; color: #dd2200;">'./likes/likes.component'</span>;
<span style="background-color: #e3d2d2; color: #a61717;">@</span>NgModule({
declarations: [
AppComponent,
LikesComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
NgbModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
<span style="color: #008800; font-weight: bold;">export</span> <span style="color: #008800; font-weight: bold;">class</span> AppModule { }
</pre>
</div>
<div>
<br />
It looks as follows in my editor<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZu1eSsouEaQ9AXkWTafezDX2j9zeNREWOV7Rwd21nFaN_T7n36CmmcTvRQGq3OhN1iYNKhby6LEgf2MxR5po8OhH5DBDOcc6jbGb0PHL6wAk13SwqYdQav-NhCiSKniGKyM99IRy0O7w/s1600/app.module.ts+-+ng2-2+-+Visual+Studio+Code_052.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZu1eSsouEaQ9AXkWTafezDX2j9zeNREWOV7Rwd21nFaN_T7n36CmmcTvRQGq3OhN1iYNKhby6LEgf2MxR5po8OhH5DBDOcc6jbGb0PHL6wAk13SwqYdQav-NhCiSKniGKyM99IRy0O7w/s640/app.module.ts+-+ng2-2+-+Visual+Studio+Code_052.png" width="640" /></a></div>
<br /></div>
<h3>
Creating a new component</h3>
At this step, we will create a new component within our project called "likes". This is the component that will be used within our example. To create a new component using angular-cli, we just need to type the command ng generate component <path component="" to="">. I used the following command..</path><br />
<br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">ng generate component likes</span>
</pre>
</div>
<br />
This generated the component in our project, and we can open the project in vscode (or your preferred IDE). In my vscode, the newly created project with the new component looks like the following:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXiHSjE23rt52fCg1JUATIHlboZ6ZqR-aBywJnJw0duz-wpxN4-vFC0zTrin0cW5FiTi1X79NyCKGl5bD4gEbREQNFDc9iQ2NTQU4tmnhm2LmQ9LDM3B9VxOGXewvOc5JXB8BALjyGbF8/s1600/Selection_042.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXiHSjE23rt52fCg1JUATIHlboZ6ZqR-aBywJnJw0duz-wpxN4-vFC0zTrin0cW5FiTi1X79NyCKGl5bD4gEbREQNFDc9iQ2NTQU4tmnhm2LmQ9LDM3B9VxOGXewvOc5JXB8BALjyGbF8/s640/Selection_042.png" width="323" /></a></div>
<br />
In the next steps, we will make changes to the generated files to try two way binding in Angular2 as well as bootstrap components provided by ng-bootstrap.<br />
<h3>
<br />Overall logic</h3>
Overall logic is fairly straightforward. We want to use the a rating component in our test. We want the component to be initialized based on a value in our business logic. When the user changes the values on the ratings, we want the component's internal value to be updated.<br />
<br />
We would like to use angular2 two way binding. Angular2 provides an event and a property binding that would suffice to implement two-way binding. However, Angular2 also provides a short-hand way of implementing two-way binding. In this post, we shall try both. As we shall see separating the event binding also allows us to add additional behaviour. Here is the final screen..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR8J7oz8vRTnYmQsqpteg4WDA2g5co4uUpga-ueth26aZtjYTmETwzlYML7HFn-SW3nlbcOvnrKLI1a1pInxzHS6m90ZvE7J8UUb6fhZHr8l0UkjtgXq5vmcJZlWgkBfN1uIuMf4b5iGk/s1600/Ng22+-+Google+Chrome_043.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR8J7oz8vRTnYmQsqpteg4WDA2g5co4uUpga-ueth26aZtjYTmETwzlYML7HFn-SW3nlbcOvnrKLI1a1pInxzHS6m90ZvE7J8UUb6fhZHr8l0UkjtgXq5vmcJZlWgkBfN1uIuMf4b5iGk/s640/Ng22+-+Google+Chrome_043.png" width="640" /></a></div>
<br />
<br />
Let us first start with the component's presentation logic<br />
<br />
<h3>
Component Presentation logic</h3>
The component presentation logic requires changes to ./app/likes/likes.component.html. Here we want the following items displayed on the page..<br />
<br />
<ul>
<li>A label for implicit two way binding in Angular2</li>
<li>The ngb-rating component configured using Angular's shorthand two-way binding approach. Notice the square and regular brackets around the rate property of the rating component. In html components where two-way binding has not been built in, another way to implement implicit two way binding is to use [(ngModel)] directive. The ngb-rating component also contains a max property that controls number of stars displayed</li>
<li>Another ngb-rating component configured using a separate property and event binding, called through the onRate method in the component class. This allows us to program additional behaviour</li>
<li>An input text box that also implements explicit two way binding. Its value gets updated from the component, and any changed value updates the component as well using the updateRating() method in the component class. The implicit way to implement two-way binding would be to use the [(ngModel)] directive mentioned earlier.</li>
<li>A label showing number of ratings selected through the value of the ratings property.</li>
<li>A label for Total likes</li>
</ul>
<br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #bb0066; font-weight: bold;"><p></span>
likes works!
<span style="color: #bb0066; font-weight: bold;"></p></span>
<span style="color: #bb0066; font-weight: bold;"><p></span>Implicit two way binding<span style="color: #bb0066; font-weight: bold;"></p></span>
<span style="color: #bb0066; font-weight: bold;"><ngb</span><span style="color: #336699;">-rating</span> <span style="background-color: #e3d2d2; color: #a61717;">[</span><span style="color: #336699;">max</span><span style="background-color: #e3d2d2; color: #a61717;">]="</span><span style="color: #336699;">maxStars</span><span style="background-color: #e3d2d2; color: #a61717;">"</span> <span style="background-color: #e3d2d2; color: #a61717;">[(</span><span style="color: #336699;">rate</span><span style="background-color: #e3d2d2; color: #a61717;">)]="</span><span style="color: #336699;">ratings</span><span style="background-color: #e3d2d2; color: #a61717;">"</span><span style="color: #bb0066; font-weight: bold;">></span>
<span style="background-color: #e3d2d2; color: #a61717;"><</span>/ngb-rating>
<span style="color: #bb0066; font-weight: bold;"><p></span> Explicit Two way binding<span style="color: #bb0066; font-weight: bold;"></p></span>
<span style="color: #bb0066; font-weight: bold;"><br/></span>
<span style="color: #bb0066; font-weight: bold;"><ngb</span><span style="color: #336699;">-rating</span> <span style="background-color: #e3d2d2; color: #a61717;">[</span><span style="color: #336699;">max</span><span style="background-color: #e3d2d2; color: #a61717;">]="</span><span style="color: #336699;">maxStars</span><span style="background-color: #e3d2d2; color: #a61717;">"</span> <span style="background-color: #e3d2d2; color: #a61717;">[</span><span style="color: #336699;">rate</span><span style="background-color: #e3d2d2; color: #a61717;">]="</span><span style="color: #336699;">ratings</span><span style="background-color: #e3d2d2; color: #a61717;">"</span> <span style="background-color: #e3d2d2; color: #a61717;">(</span><span style="color: #336699;">rateChange</span><span style="background-color: #e3d2d2; color: #a61717;">)="</span><span style="color: #336699;">onRate</span><span style="background-color: #e3d2d2; color: #a61717;">($</span><span style="color: #336699;">event</span><span style="background-color: #e3d2d2; color: #a61717;">)"</span><span style="color: #bb0066; font-weight: bold;">></span>
<span style="background-color: #e3d2d2; color: #a61717;"><</span>/ngb-rating>
<span style="color: #bb0066; font-weight: bold;"><br/></span>
<span style="color: #bb0066; font-weight: bold;"><input</span> <span style="color: #336699;">type=</span><span style="background-color: #fff0f0; color: #dd2200;">"text"</span> <span style="background-color: #e3d2d2; color: #a61717;">[</span><span style="color: #336699;">value</span><span style="background-color: #e3d2d2; color: #a61717;">]="</span><span style="color: #336699;">ratings</span><span style="background-color: #e3d2d2; color: #a61717;">"</span> <span style="background-color: #e3d2d2; color: #a61717;">(</span><span style="color: #336699;">change</span><span style="background-color: #e3d2d2; color: #a61717;">)="</span><span style="color: #336699;">updateRating</span><span style="background-color: #e3d2d2; color: #a61717;">($</span><span style="color: #336699;">event</span><span style="background-color: #e3d2d2; color: #a61717;">)"</span><span style="color: #bb0066; font-weight: bold;">></span>
<span style="color: #bb0066; font-weight: bold;"><br/></span>
<span style="color: #bb0066; font-weight: bold;"><p></span> Current rate: {{ratings}}<span style="color: #bb0066; font-weight: bold;"></p></span>
<span style="color: #bb0066; font-weight: bold;"><br/></span>
<span style="color: #bb0066; font-weight: bold;"><span></span>Total likes: {{totalLikes}} <span style="color: #bb0066; font-weight: bold;"></span></span></pre>
</div>
<br />
Here is how the same code looks on my vscode screen.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixSrcWRE0ogs2O_CCIPTNeB9Hje38Zyap2czL3yWrc4cZDEHpUlm8aCN9L_JaaaUNRCvznNAxj6d5E7YjSQEBcTVwxctaWuphVY2BqHbEqpNbHnVTYDdkHFZAukMjfacuuGjHr1AhTYE0/s1600/likes.component.html+-+ng2-2+-+Visual+Studio+Code_044.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixSrcWRE0ogs2O_CCIPTNeB9Hje38Zyap2czL3yWrc4cZDEHpUlm8aCN9L_JaaaUNRCvznNAxj6d5E7YjSQEBcTVwxctaWuphVY2BqHbEqpNbHnVTYDdkHFZAukMjfacuuGjHr1AhTYE0/s640/likes.component.html+-+ng2-2+-+Visual+Studio+Code_044.png" width="640" /></a></div>
<br />
<h3>
The application logic</h3>
The application logic is also straightforward<br />
<br />
<ul>
<li>Our component decorator selects the "likes" tag and inserts our component's presentation code specified in the previous step within likes.component.html</li>
<li>We declare 3 component level properties for totalLikes, ratings and maxStars, each initialized appropriately</li>
<li>An updateRating() method, called when the text box is updated, updates the ratings property with the value entered in the text box.</li>
<li>An onRate() method, sets the value of the ratings property based on value selected in the second component.</li>
</ul>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">import</span> { Component, OnInit, Input } from <span style="background-color: #fff0f0; color: #dd2200;">'@angular/core'</span>;
<span style="background-color: #e3d2d2; color: #a61717;">@</span>Component({
selector: <span style="background-color: #fff0f0; color: #dd2200;">'likes'</span>,
templateUrl: <span style="background-color: #fff0f0; color: #dd2200;">'./likes.component.html'</span>,
styleUrls: [<span style="background-color: #fff0f0; color: #dd2200;">'./likes.component.css'</span>]
})
<span style="color: #008800; font-weight: bold;">export</span> <span style="color: #008800; font-weight: bold;">class</span> LikesComponent <span style="color: #008800; font-weight: bold;">implements</span> OnInit {
<span style="background-color: #e3d2d2; color: #a61717;">@</span>Input() totalLikes = <span style="color: #0000dd; font-weight: bold;">6</span>;
<span style="background-color: #e3d2d2; color: #a61717;">@</span>Input() ratings = <span style="color: #0000dd; font-weight: bold;">4</span>;
<span style="background-color: #e3d2d2; color: #a61717;">@</span>Input() maxStars = <span style="color: #0000dd; font-weight: bold;">7</span>;
<span style="color: #008800; font-weight: bold;">constructor</span>() { }
ngOnInit() {
}
onClick(){
}
updateRating($event) {
<span style="color: #008800; font-weight: bold;">this</span>.ratings = $event.target.value;
}
onRate(value) {
console.log(<span style="background-color: #fff0f0; color: #dd2200;">"Rate changed to "</span> + value);
<span style="color: #008800; font-weight: bold;">this</span>.ratings = value;
}
}
</pre>
</div>
<br />
This is how it looks on my vscode screen<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSFfacge6FT9FsTzntbe3nWwOz_V-1Hs1-9ter-Oon6gFn8L4UEUpSsKlbOc5EdWA0ot7aMnJzHVuRklz71Fv6zs2UzxrUF2SX7FdlxuylCw3JvS6H2qwfxK-2mCJOLyMoqJj8doHTn_I/s1600/likes.component.ts+-+ng2-2+-+Visual+Studio+Code_045.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSFfacge6FT9FsTzntbe3nWwOz_V-1Hs1-9ter-Oon6gFn8L4UEUpSsKlbOc5EdWA0ot7aMnJzHVuRklz71Fv6zs2UzxrUF2SX7FdlxuylCw3JvS6H2qwfxK-2mCJOLyMoqJj8doHTn_I/s640/likes.component.ts+-+ng2-2+-+Visual+Studio+Code_045.png" width="640" /></a></div>
<br />
<h3>
Putting it together</h3>
To put it together, we just need to update our app.component.ts to add the Likes command..<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #bb0066; font-weight: bold;"><h1></span>
{{title}}
<span style="color: #bb0066; font-weight: bold;"></h1></span>
<span style="color: #bb0066; font-weight: bold;"><likes></likes></span>
</pre>
</div>
<br />
On my vscode screen<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ2bxjAr668m6nLaj904-bUUu2uHy3x050qqLhI0G92OKo-qPSU_OCRc9V14V1iAs327ixrmqVzd0vZtRtiJnR9Jug6YUFvebzfgVX1MU41BBZ0SzUUP1RVQleUlKZeKou64njGbxU-zs/s1600/app.component.html+-+ng2-2+-+Visual+Studio+Code_046.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ2bxjAr668m6nLaj904-bUUu2uHy3x050qqLhI0G92OKo-qPSU_OCRc9V14V1iAs327ixrmqVzd0vZtRtiJnR9Jug6YUFvebzfgVX1MU41BBZ0SzUUP1RVQleUlKZeKou64njGbxU-zs/s640/app.component.html+-+ng2-2+-+Visual+Studio+Code_046.png" width="640" /></a></div>
<br />
<br />
<h3>
The behaviour</h3>
The behaviour is straightforward<br />
<br />
<ol>
<li>The page loads with the default settings for the page</li>
</ol>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd0UqdrEQW-LuEjE383WMUjQa8wCbcA9P2RVeCw2-S4lRiI7lJaH2JMEMUekE_TSpjebm1uFq7aZypdJpudkk7fbZWV5xKwPYtNBslrYGox3rcVtlBWs1u13Bec884FmHuM9UayeluE5Y/s1600/Ng22+-+Google+Chrome_047.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd0UqdrEQW-LuEjE383WMUjQa8wCbcA9P2RVeCw2-S4lRiI7lJaH2JMEMUekE_TSpjebm1uFq7aZypdJpudkk7fbZWV5xKwPYtNBslrYGox3rcVtlBWs1u13Bec884FmHuM9UayeluE5Y/s640/Ng22+-+Google+Chrome_047.png" width="640" /></a></div>
<div>
<br /></div>
2. Clicking the first component, updates values for all the other components. We increase the value to 6, as shown below:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiadPMpkfALmyYVwkVGcDeVyKscJFQTdNy5yTTSM7c85S11DM9rJQbCfKHGZJMtOGBRKr9tyHqsn2PjLmPXgujeOCTYyUvOAwQX0LzUpSmtPIF82D0EJO_zYviYxWVc9hVRSeHSniIFa8g/s1600/Ng22+-+Google+Chrome_048.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiadPMpkfALmyYVwkVGcDeVyKscJFQTdNy5yTTSM7c85S11DM9rJQbCfKHGZJMtOGBRKr9tyHqsn2PjLmPXgujeOCTYyUvOAwQX0LzUpSmtPIF82D0EJO_zYviYxWVc9hVRSeHSniIFa8g/s640/Ng22+-+Google+Chrome_048.png" width="640" /></a></div>
<br />
3. Now we click the second component and bring the value down to 2.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbcEd1BfgpnvYSBiCc_QVo_xJP1jK8ogi_T_3hrpXmBJ4gVgFi97gQNzFst-4ziQm_T3C2I6mOKKg6LsIMANXOIAZDExFv-H_X7UW6Jv8iTIvUoZo01RKXmW8ICD_Xt67oLqmLXHOk7oo/s1600/Ng22+-+Google+Chrome_050.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbcEd1BfgpnvYSBiCc_QVo_xJP1jK8ogi_T_3hrpXmBJ4gVgFi97gQNzFst-4ziQm_T3C2I6mOKKg6LsIMANXOIAZDExFv-H_X7UW6Jv8iTIvUoZo01RKXmW8ICD_Xt67oLqmLXHOk7oo/s640/Ng22+-+Google+Chrome_050.png" width="640" /></a></div>
<br />
4. Finally, we edit the value in the text box and that should update values for all components as well.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm-1DM7YS1nMgarKuDvv3M_wfdHIUJmIHN9iSte1ki2NyAtsLO480Y0Lku4Bb4SEThNqdd_p6QDu4-vVoHMBjpnQT7hy7hrLyMqK8HX_TZS7CkOKOtRAmMpGJ_03gSyZC7q9rU2QKVnaY/s1600/Ng22+-+Google+Chrome_051.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm-1DM7YS1nMgarKuDvv3M_wfdHIUJmIHN9iSte1ki2NyAtsLO480Y0Lku4Bb4SEThNqdd_p6QDu4-vVoHMBjpnQT7hy7hrLyMqK8HX_TZS7CkOKOtRAmMpGJ_03gSyZC7q9rU2QKVnaY/s640/Ng22+-+Google+Chrome_051.png" width="640" /></a></div>
<br />
I am sure more creative ways can be conjured to demonstrate the same, but this should explain how the two way binding works with Angular2 and bootstrap.<br />
<br />
<br /></div>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-19169966112565785572016-11-26T18:59:00.004-08:002016-11-26T19:31:20.617-08:00Angular2 project using angular-cli with property and event bindingIn this setup I am going to walk-through setting up an Angular2 project using angular-cli. We are then going to create a project and show some simple event and property binding using Angular2 and typescript.<br />
<br />
<h3>
The project</h3>
Our project is simple. We will create a simple page with a heading, a label and 3 inputs. These are<br />
<ol>
<li>A page heading showing application state and most recent event</li>
<li>A text label that shows value from the underlying component</li>
<li>An input text field that also shows an initial value from the underlying component.</li>
<li>An input clear button, that clears the value in the underlying component and also the label and input field</li>
<li>An input reset button that sets everything back.</li>
</ol>
To demonstrate, we will load the page, and cycle through the 2 events. Lets get started...<br />
<br />
<h3>
The steps</h3>
First lets setup angular-cli<br />
<br />
The step to do that is to run the following command in your target folder<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">sudo npm install -g angular-cli</span>
</pre>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha6Rm0S4DT45wthGs_IEcxbDzgGN0YHH6gTE_BkO69m0bmccoW3BStsKltQAblsSMPsJv4aoRM4kjGeg_oJCn6fcf57KWDFOEFiKEsheQJjKz8lrgnL6J-bTwA6-dEcI03lEmruFYE3_I/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-1_024.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha6Rm0S4DT45wthGs_IEcxbDzgGN0YHH6gTE_BkO69m0bmccoW3BStsKltQAblsSMPsJv4aoRM4kjGeg_oJCn6fcf57KWDFOEFiKEsheQJjKz8lrgnL6J-bTwA6-dEcI03lEmruFYE3_I/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-1_024.png" width="640" /></a></div>
<br />
<br />
This will create the appropriate setup ashown below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQa0G-TuasOexW_CsBPojo7hLDKmZHnw-3K7aSF277h84YViGzgOssPVwfgjAwbvvEy18b7Ya8LMhaK6QhChjm4Wux7UsMcx1oAnmchYTY4qYT1AcHcyb6ZaC0BaDgom_Ky16quJ-GRag/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-1_025.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQa0G-TuasOexW_CsBPojo7hLDKmZHnw-3K7aSF277h84YViGzgOssPVwfgjAwbvvEy18b7Ya8LMhaK6QhChjm4Wux7UsMcx1oAnmchYTY4qYT1AcHcyb6ZaC0BaDgom_Ky16quJ-GRag/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-1_025.png" width="640" /></a></div>
<br />
Next, we will create the project, I call mine "ng2-1". I will use the angular-cli directive "ng new" to create the new project..<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">ng new ng2-1</span>
</pre>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJYMJqwiCf5UbCja2bnUuQVXJqPLghKW3fQEcuCWydp643fKPwrq0taijn2JqZVxiD1zgOzPMZP5XVmu9nB9W1Lma1qYwl4IuKKSSCzKfc2Xczn8ur5Ipsjbd186mrzDBHuluB5A-2-NA/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2_026.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJYMJqwiCf5UbCja2bnUuQVXJqPLghKW3fQEcuCWydp643fKPwrq0taijn2JqZVxiD1zgOzPMZP5XVmu9nB9W1Lma1qYwl4IuKKSSCzKfc2Xczn8ur5Ipsjbd186mrzDBHuluB5A-2-NA/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2_026.png" width="640" /></a></div>
<br />
This command creates the necessary files needed for setting up the project, as we can see from the screenshot below..<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRfkHtAz79gPgUsecT8G6DKHI3_6SF0gSKWZ9q7AV5IQKqwVVTptNDNS-h3aJlC8MjTDq6A_rNyQ4ELvObQdhb3I8FiF6b5oAOB5FiOUja-_SpARoEjgb5DzP-Juqn-dhIuYqnFyhKM9c/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2_027.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRfkHtAz79gPgUsecT8G6DKHI3_6SF0gSKWZ9q7AV5IQKqwVVTptNDNS-h3aJlC8MjTDq6A_rNyQ4ELvObQdhb3I8FiF6b5oAOB5FiOUja-_SpARoEjgb5DzP-Juqn-dhIuYqnFyhKM9c/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2_027.png" width="640" /></a></div>
<br />
<br />
Now that the project is created, we will open the created files in our favourite code editor and take a look at the generated seed project. I use <a href="https://code.visualstudio.com/download" target="_blank">Vscode, an open source editor</a> from Microsoft that is also available for Ubuntu.<br />
<br />
We need to add the created project to our editor.. We can do that by Opening the folder we created at the start, using the Open folder command..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH-3vRFg6NM6Dt6mOoQ6xRPZWNHwo7HwIeNuNAqKxA71JojL-s3yjiwnUDdBikgatvGV3n1PIEEC9W_SulGb4aWUM8w0AKl-piOgznwXBNB4XI883wwSECSROcn3tKL5VANFwCr2hgu1M/s1600/Untitled-1+-+Visual+Studio+Code_029.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="406" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH-3vRFg6NM6Dt6mOoQ6xRPZWNHwo7HwIeNuNAqKxA71JojL-s3yjiwnUDdBikgatvGV3n1PIEEC9W_SulGb4aWUM8w0AKl-piOgznwXBNB4XI883wwSECSROcn3tKL5VANFwCr2hgu1M/s640/Untitled-1+-+Visual+Studio+Code_029.png" width="640" /></a></div>
<br />
Next I navigate to the root folder for the project, and click OK to start working...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhT0v019-W0JVKQu9nNo3vx-tBXdAHLuOIc274GmVyxw-gXPp2Ln1I712BMbSx1bZYaoaSebl4tnEQ9HZnkXsUBnQHtJ8uU7wu8SwLbXcC57e2GR7wdgtzaoNNd0ICynlQEfxQqAx5kirw/s1600/Untitled-1+-+Visual+Studio+Code_028.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhT0v019-W0JVKQu9nNo3vx-tBXdAHLuOIc274GmVyxw-gXPp2Ln1I712BMbSx1bZYaoaSebl4tnEQ9HZnkXsUBnQHtJ8uU7wu8SwLbXcC57e2GR7wdgtzaoNNd0ICynlQEfxQqAx5kirw/s640/Untitled-1+-+Visual+Studio+Code_028.png" width="640" /></a></div>
<br />
<br />
We will now navigate to the appropriate files within the created project. This should be within the ./app/src folder, and the two files we will use are called app.component.ts and app.component.html<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHxnBeUigLACzSuLcMj7EaEelmPZO-ce7AMLqo0hG1JiAZPCAvqyPXMDYV9MqByfxwl1M6yVuWKqmev3rKqhGts8GK3ln7LaTmazJ3jvT032aPSCRx7v2bypRzv9sLh9PH3ZwsXRmT3qs/s1600/Selection_032.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHxnBeUigLACzSuLcMj7EaEelmPZO-ce7AMLqo0hG1JiAZPCAvqyPXMDYV9MqByfxwl1M6yVuWKqmev3rKqhGts8GK3ln7LaTmazJ3jvT032aPSCRx7v2bypRzv9sLh9PH3ZwsXRmT3qs/s320/Selection_032.png" width="226" /></a></div>
<br />
<h3>
The presentation logic</h3>
The generated project created a app.component.html file which is our root component's html representation. The default setup just created a heading based on the root object's "title" property. We will add additional presentation logic in terms of the following<br />
<br />
<ul>
<li>A label text "My name is ..." using for the myname property defined in the root object.</li>
<li>An input text field that takes in its value from the "myname" property defined in the root object (same as the label defined above).</li>
<li>A Clear button that calls the clearClick() function in the component class when clicked.</li>
<li>A Reset button that calls the resetClick() function in the component class when clicked.</li>
</ul>
<br />
Let's modify the system generated .html file as follows..Notice how the property binding is done by boxing the attribute in square brackets. The onXXX event is called by surrounding the XXX with parentheses, and calling the method name of the component class.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007700;"><h1></span>
{{title}}
<span style="color: #007700;"></h1></span>
<span style="color: #007700;"><label></span>My name is {{myname}}<span style="color: #007700;"></label></span>
<span style="color: #007700;"><br/></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"txtName"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"text"</span> <span style="background-color: #ffaaaa; color: red;">[</span><span style="color: #0000cc;">value</span><span style="background-color: #ffaaaa; color: red;">]="</span><span style="color: #0000cc;">myname</span><span style="background-color: #ffaaaa; color: red;">"</span><span style="color: #007700;">/></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"btnClear"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"button"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"Clear"</span> <span style="background-color: #ffaaaa; color: red;">(</span><span style="color: #0000cc;">click</span><span style="background-color: #ffaaaa; color: red;">)="</span><span style="color: #0000cc;">clearClick</span><span style="background-color: #ffaaaa; color: red;">($</span><span style="color: #0000cc;">event</span><span style="background-color: #ffaaaa; color: red;">)"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"btnReset"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"button"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"Reset"</span> <span style="background-color: #ffaaaa; color: red;">(</span><span style="color: #0000cc;">click</span><span style="background-color: #ffaaaa; color: red;">)="</span><span style="color: #0000cc;">resetClick</span><span style="background-color: #ffaaaa; color: red;">($</span><span style="color: #0000cc;">event</span><span style="background-color: #ffaaaa; color: red;">)"</span><span style="color: #007700;">></span>
</pre>
</div>
<br />
The above code as shown in my editor<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBjiwaw7S0NBsYqu-c8A6eLEPXjmXJ5DPNA3c-0gSpUZMp6YCV82rjWbMICmAv3t02tJNQYe_o4qkmQc2sK-d5eQ3s5qi7SoyVRVwbeh51dbqLAYUEPy6_Er3_qNidF0lpnRHkIQrneTo/s1600/Selection_033.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBjiwaw7S0NBsYqu-c8A6eLEPXjmXJ5DPNA3c-0gSpUZMp6YCV82rjWbMICmAv3t02tJNQYe_o4qkmQc2sK-d5eQ3s5qi7SoyVRVwbeh51dbqLAYUEPy6_Er3_qNidF0lpnRHkIQrneTo/s640/Selection_033.png" width="640" /></a></div>
<br />
<h3>
The application logic</h3>
<div>
The application logic is contained in the file called app.component.ts. The system generated code only has a single property called title, but we will extend the logic as follows:</div>
<div>
<ul>
<li>A new property called myname</li>
<li>A constructor that simply logs an event</li>
<li>A clearClick() method that is called when Clear button is clicked. This logs on the console, sets the myname property to "", marks the clear button as disabled, as well as updates the title property to indicate that Clear button has been clicked.</li>
<li>A resetClick() method which called when reset button is clicked. This again logs on the console, resets the "myname" property to my name, and updates the title property to indicate that Reset button has been clicked.</li>
</ul>
</div>
<div>
<br /></div>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">import</span> { Component } from <span style="background-color: #fff0f0;">'@angular/core'</span>;
<span style="background-color: #ffaaaa; color: red;">@</span>Component({
selector<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'app-root'</span>,
templateUrl<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'./app.component.html'</span>,
styleUrls<span style="color: #333333;">:</span> [<span style="background-color: #fff0f0;">'./app.component.css'</span>]
})
<span style="color: #008800; font-weight: bold;">export</span> <span style="color: #008800; font-weight: bold;">class</span> AppComponent {
title <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">'app works!'</span>;
myname <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">'Arthgallo'</span>;
isActive<span style="color: #333333;">=</span><span style="color: #008800; font-weight: bold;">false</span>;
<span style="color: #008800; font-weight: bold;">constructor</span>() {
console.log(<span style="background-color: #fff0f0;">"Starting now"</span>);
}
clearClick($event) {
console.log(<span style="background-color: #fff0f0;">"Clear clicked"</span>);
<span style="color: #008800; font-weight: bold;">this</span>.myname <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">''</span>;
$event.target.disabled<span style="color: #333333;">=</span><span style="color: #008800; font-weight: bold;">true</span>;
<span style="color: #008800; font-weight: bold;">this</span>.title<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"Clear clicked!"</span>
}
resetClick($event) {
console.log(<span style="background-color: #fff0f0;">"Reset clicked"</span>);
<span style="color: #008800; font-weight: bold;">this</span>.myname<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">'Arthgallo'</span>;
<span style="color: #008800; font-weight: bold;">this</span>.title<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"Reset clicked!"</span>
}
}
</pre>
</div>
<br />
This is how the code appears on my screen..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCXTlt67X5gS5Jfhk9jy7mzNy75MZn_uHduidq3-K9tKitYmMFJC1U5aU_U9H2pV8JRbhV9ho1wdjC84XRhr2J-IoORl2_hf7WK-_maoymtxmhBTHgLdXROrh7cIXFDa_PYSd8QHkrwa4/s1600/Selection_037.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="568" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCXTlt67X5gS5Jfhk9jy7mzNy75MZn_uHduidq3-K9tKitYmMFJC1U5aU_U9H2pV8JRbhV9ho1wdjC84XRhr2J-IoORl2_hf7WK-_maoymtxmhBTHgLdXROrh7cIXFDa_PYSd8QHkrwa4/s640/Selection_037.png" width="640" /></a></div>
<br />
and finally the web page in action. This can be done by entering the command "ng serve" on the command line.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">ng serve</span>
</pre>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidhw962nCTRs9FU1_8uUrrfAa4FmwowXBe_6Jat8UqOGlrSvyOgGvALwQlS7U3PHlGO606Q93FzeBpGBXxpi4zBMHtjSqTtCa1Wv4UGwHC0Svyy9PpYlD6uSaunmuTc2kOuM9TN5n8WKQ/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-1_040.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidhw962nCTRs9FU1_8uUrrfAa4FmwowXBe_6Jat8UqOGlrSvyOgGvALwQlS7U3PHlGO606Q93FzeBpGBXxpi4zBMHtjSqTtCa1Wv4UGwHC0Svyy9PpYlD6uSaunmuTc2kOuM9TN5n8WKQ/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-ng2-1_040.png" width="640" /></a></div>
<br />
By default the webpage can be accessed at http://localhost:4200.. Lets test our property and event binding.<br />
<br />
1. Initial load<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVGifhlfURhUI-Q3heexWXCQ6NTk9zWaCUXmarkVUfQC0qTHPtQiEZ6U88R3sjh_EskoqTfOzlAuDwGPEea_pBWcQoHEriXCWCMU56o2BAJ2Aasb4_4T0wxfOsGa7FYCzBfZ_QqyNP7cs/s1600/Ng21+-+Google+Chrome_035.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVGifhlfURhUI-Q3heexWXCQ6NTk9zWaCUXmarkVUfQC0qTHPtQiEZ6U88R3sjh_EskoqTfOzlAuDwGPEea_pBWcQoHEriXCWCMU56o2BAJ2Aasb4_4T0wxfOsGa7FYCzBfZ_QqyNP7cs/s640/Ng21+-+Google+Chrome_035.png" width="640" /></a></div>
<br />
2. On clicking the clear button<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7QvEF3B1WrXOEkmjH_LUwhD9EN3PbbPOzOvebQUL2fZKGouGLsotLvRj1oSBGxD081zftRFYvIjohgam1p7d2g4w3B-T2aZOy0Fe-fj-6ADF_HymPf2V9ZSn_MKw98Un9Y7Tj9uYfWrk/s1600/Ng21+-+Google+Chrome_038.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7QvEF3B1WrXOEkmjH_LUwhD9EN3PbbPOzOvebQUL2fZKGouGLsotLvRj1oSBGxD081zftRFYvIjohgam1p7d2g4w3B-T2aZOy0Fe-fj-6ADF_HymPf2V9ZSn_MKw98Un9Y7Tj9uYfWrk/s640/Ng21+-+Google+Chrome_038.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
3. And finally the reset button clicked<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2L5Ufuq8UTxxWDHqf0Q7TIxOM8YhEzvATI3S7PLfH3dJCeTyjUEte30nhL8zHZFaVVbFW52IS0GDhQ-_ht89ikOghLedGUmT2vQxIT593kHIkwWTqjRNqJcbFze5aW31aCN4CvDS2m18/s1600/Ng21+-+Google+Chrome_039.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2L5Ufuq8UTxxWDHqf0Q7TIxOM8YhEzvATI3S7PLfH3dJCeTyjUEte30nhL8zHZFaVVbFW52IS0GDhQ-_ht89ikOghLedGUmT2vQxIT593kHIkwWTqjRNqJcbFze5aW31aCN4CvDS2m18/s640/Ng21+-+Google+Chrome_039.png" width="640" /></a></div>
<br />
That's it..<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-46262602587402995962016-10-24T08:35:00.002-07:002016-10-24T08:42:26.410-07:00Creating volatility smile in RIn this post, I try to use R to draw volatility curves. This is a draft version that I will be updating on a regular basis. I am using the Russell 2000 trade and option chain data for plotting these graphs.<br />
<br />
Here are the outputs (and the <a href="https://dl.dropboxusercontent.com/u/80757746/russell2000.pdf" target="_blank">PDF file</a>)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAtnLnLMg_WgiVmhCuh2kpUlXDeTXtMvgw3zSaSm2Zhzc9hYJKZNoBYEJ48k5dMzl5DrE_8ubOCplBrGaom-qQlrnnNGEJCm7qn10hRIlUkmydOTOWTfRsD4AJj7_EEVExjHCh-h8FDzE/s1600/Selection_020.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="492" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAtnLnLMg_WgiVmhCuh2kpUlXDeTXtMvgw3zSaSm2Zhzc9hYJKZNoBYEJ48k5dMzl5DrE_8ubOCplBrGaom-qQlrnnNGEJCm7qn10hRIlUkmydOTOWTfRsD4AJj7_EEVExjHCh-h8FDzE/s640/Selection_020.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimCTeLwEjxDoYIXxCfohLrHiBXQ4OrbLm_VIPbj8kCrGxGp75pJn4SKybOC9asKpCsZgsHVeHytK0Cot0k8Qoqc0BHaMXXeY4sE2RSD5wJg7nS77-YJqc-GzRQdKbqLzVDJiWF8w6LLjA/s1600/Selection_021.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimCTeLwEjxDoYIXxCfohLrHiBXQ4OrbLm_VIPbj8kCrGxGp75pJn4SKybOC9asKpCsZgsHVeHytK0Cot0k8Qoqc0BHaMXXeY4sE2RSD5wJg7nS77-YJqc-GzRQdKbqLzVDJiWF8w6LLjA/s640/Selection_021.png" width="640" /></a></div>
<br />
<br />
Here is my code<br />
<br />
<br />
<pre class="brush:bash">#!/usr/bin/Rscript
#!/usr/bin/Rscript
# russ2k_analysis.r
# source("russ2k_analysis.r")
library(RCurl)
library(e1071)
library(RQuantLib)
library(RcppBDT)
library(ggplot2)
home.folder <- '~/Work/finance/RUSS2K/'
#Load historic closing prices
today <- Sys.Date()
day <- as.numeric(format(today,'%d'))
month <- as.numeric(format(today,'%m'))
year <- as.numeric(format(today,'%Y'))
#Author: Arthgallo Wachs (arthgallo.wachs@gmail.com)
URL <- paste('http://real-chart.finance.yahoo.com/table.csv?s=%5ERUT&a=',(month-1),'&b=',(day),'&c=',(year-1),'&d=',(month-1),'&e=',day,'&f=',year,'&g=d&ignore=.csv',sep="")
URL
targetFileName <- paste(home.folder,"russ2k",today,".csv",sep="")
download.file(URL,targetFileName,quiet=FALSE,mode="w",cacheOK=TRUE)
russ2k <- read.csv(targetFileName, head=TRUE, sep=",")
russ2k$Date <- as.Date(russ2k$Date)
names(russ2k)
hist(russ2k$Close,breaks=50)
mean(russ2k$Close)
median(russ2k$Close)
mode(russ2k$Close)
kurtosis(russ2k$Close)
skewness(russ2k$Close)
moment(russ2k$Close, order=3, center=TRUE)
underlying <- as.numeric(russ2k$Close[1])
source(paste(home.folder,"cSplit.r",sep=""))
# Load option chain
# http://www.cboe.com/delayedquote/QuoteTableDownload.aspx
option_chain_file <- paste(home.folder,"russ2k_optionchain.dat",sep="")
# russ2k.opt <- read.csv(option_chain_file, head=TRUE, sep=",")
# Read the last closing from option chain
russ2k.opt <- read.table(option_chain_file,
header=FALSE,
sep=",",
skip = "3",
col.names=c("Calls","Last.Sale","Net","Bid","Ask","Vol",
"Open.Int","Puts","Last Sale.1","Net.1","Bid.1","Ask.1",
"Vol.1","Open.Int.1","X"))
names(russ2k.opt)
russ2k.opt <- cSplit(russ2k.opt, c("Calls","Puts"), sep=" ")
names(russ2k.opt)
names(russ2k.opt)[names(russ2k.opt)=="Calls_1"] <- "year"
names(russ2k.opt)[names(russ2k.opt)=="Calls_2"] <- "month"
names(russ2k.opt)[names(russ2k.opt)=="Calls_3"] <- "strike"
names(russ2k.opt)[names(russ2k.opt)=="Calls_4"] <- "call_name"
names(russ2k.opt)[names(russ2k.opt)=="Puts_4"] <- "put_name"
names(russ2k.opt)[names(russ2k.opt)=="Bid"] <- "CBid"
names(russ2k.opt)[names(russ2k.opt)=="Ask"] <- "CAsk"
names(russ2k.opt)[names(russ2k.opt)=="Bid.1"] <- "PBid"
names(russ2k.opt)[names(russ2k.opt)=="Ask.1"] <- "PAsk"
names(russ2k.opt)
today <- Sys.Date()
russ2k.opt$year <- paste("20",russ2k.opt$year,sep="")
# Read the option chain and convert each expiry mm/YYYY to first of that month.
# This is needed since source month is "Jun" which needs to be translated to 06
russ2k.opt$expdate <- as.Date(paste(russ2k.opt$year,russ2k.opt$month,"01", sep="-"),format="%Y-%b-%d")
russ2k.opt$month <- format(russ2k.opt$expdate,"%m")
# Convert expiration date to third Friday for that month
russ2k.opt$expdate <- apply(russ2k.opt, 1, function(x) {getNthDayOfWeek(third,Fri,as.numeric(x[["month"]]),as.numeric(x[["year"]]))} )
russ2k.opt$expdate <- as.Date(russ2k.opt$expdate,origin="1970-01-01")
# Now convert expiration date to expiration days and expiration fractional years
russ2k.opt$expdays <- as.numeric(russ2k.opt$expdate - today,units="days")
russ2k.opt$expyrs <- russ2k.opt$expdays/365
# Now calculate implied Volatility for each strike price based on value
russ2k.opt$call_iv <- apply(russ2k.opt, 1, function(x)
{
tryCatch(
EuropeanOptionImpliedVolatility(
type = "call",
value = as.numeric(x[["CBid"]])+(as.numeric(x[["CAsk"]])-as.numeric(x[["CBid"]])/2),
underlying = underlying,
strike = as.numeric(x[["strike"]]),
dividendYield = 0,
riskFreeRate = 0.0003,
maturity = as.numeric(x[["expyrs"]]),
volatility = .3
)[[1]],
error = function(cond) {return(NA)},
warning = function(cond) {return(NA)},
finally = {
#Do Nothing
})
})
# Plot the volatility smile
#Drop column X
russ2k.opt <- within(russ2k.opt, rm(X))
# Omit all rows with implied volatility as NA
russ2k.opt <- russ2k.opt[complete.cases(russ2k.opt),]
russ2k.opt$exprank <- rank(russ2k.opt$expdays, ties.method="max")
nextexpdays <- min(russ2k.opt$expdays)
russ2k_nextexp <- russ2k.opt[russ2k.opt$expdays==nextexpdays]
#Plot the implied volatility smiles on the graph
pdf("russell2000.pdf",width=10,height=8,paper="USr",pointsize=12)
russ2k.opt$strike <- as.numeric(russ2k.opt$strike)
xmin <- min(russ2k.opt$strike)
xmax <- max(russ2k.opt$strike)
ymin <- min(russ2k.opt$call_iv)
ymax <- max(russ2k.opt$call_iv)
ymin <- 0.1;ymax <- 0.3
plot(russ2k_nextexp$strike, russ2k_nextexp$call_iv, typ="l", col="green", xlim=c(xmin, xmax), ylim= c(ymin,ymax),
main=c("Russell 2000 Call", "Volatility Smile"), xlab="Strike", ylab="Implied Vol")
unk_expdays <- unique(russ2k.opt$expdays)
unk_expdates <- unique(as.Date(russ2k.opt$expdate))
numexp <- length(unk_expdays)
for(i in 2:numexp)
{
nextexpdays <- unk_expdays[i]
russ2k_nextexp <- russ2k.opt[russ2k.opt$expdays==nextexpdays]
lines(russ2k_nextexp$strike, russ2k_nextexp$call_iv, col=rainbow(16)[i])
}
legend("bottomleft", cex=0.9, legend=as.vector(as.character(unk_expdates)), lty=1, col=rainbow(16)[2:numexp])
abline(v=underlying, col="red",lty=2)
closest_strike <- russ2k.opt$strike[which.min(abs(russ2k.opt$strike-underlying))]
closest_exp <- min(russ2k.opt$expdays)
closest_iv <- russ2k.opt[russ2k.opt$strike == closest_strike & russ2k.opt$expdays == closest_exp][1]$call_iv
abline(h=closest_iv, col="black", lty=2)
#Function for calculating Greeks
FxCalcGreeks <- function (type,
value,
underlying,
strike,
dividendYield,
riskFreeRate,
maturity,
implied_volatility)
{
#Calculates the greeks when passed a set of arguments
tryCatch({
# Compute all the greeks
eurOp<-EuropeanOption(
type = type,
underlying = underlying,
strike = strike,
dividendYield = dividendYield,
riskFreeRate = riskFreeRate,
maturity = maturity,
volatility = implied_volatility
)
c(eurOp$bsmValue,eurOp$delta,eurOp$gamma,eurOp$vega,eurOp$theta,eurOp$rho,eurOp$divRho)
}
,
error=function(cond) {return(NA)},
warning=function(cond) {return(NA)},
finally =
{
#Do Nothing
})
}
#Calculate Greeks for each row of data in russ2k.opt
russ2k.opt[, c('c.bsm.value','c.delta','c.gamma','c.vega','c.theta','c.rho','c.divRho')] <- t(apply(russ2k.opt,1,
function(x)
FxCalcGreeks(
type="call",
underlying=underlying,
strike=as.numeric(x[["strike"]]),
dividendYield = 0,
riskFreeRate=0.0003,
maturity = as.numeric(x[["expyrs"]]),
implied_volatility = as.numeric(x[["call_iv"]])
)
))
#Identify the 16,50 & 80 delta points
list.delta.16 <- c()
list.delta.50 <- c()
list.delta.84 <- c()
unk.expdays <- unique(russ2k.opt$expdays)
unk.expdates <- unique(as.Date(russ2k.opt$expdate))
numexp <- length(unk_expdays)
for(i in 1:numexp)
{
nextexpdays <- unk.expdays[i]
russ2k.nextexp <- russ2k.opt[russ2k.opt$expdays == nextexpdays]
strike.16 <- russ2k.nextexp[which.min(abs(russ2k.nextexp$c.delta - 0.16))]$strike
strike.50 <- russ2k.nextexp[which.min(abs(russ2k.nextexp$c.delta - 0.5))]$strike
strike.84 <- russ2k.nextexp[which.min(abs(russ2k.nextexp$c.delta - 0.84))]$strike
list.delta.16 <- c(list.delta.16, list(strike.16))
list.delta.50 <- c(list.delta.50, list(strike.50))
list.delta.84 <- c(list.delta.84, list(strike.84))
}
xmin <- min(unk.expdates)
xmax <- max(unk.expdates)
ymin <- min(unlist(list.delta.84))
ymax <- max(unlist(list.delta.16))
plot(unk.expdates, list.delta.16, typ="l", col="green", xlim=c(xmin, xmax), ylim= c(0,ymax),
main=c("Russell 2000 Option Cone", "Option Cone"), xlab="Expiration Dates", ylab="Strike")
xticks <- as.character(unk.expdates,format='%m/%y')
tryCatch({
axis(side=1,at=xticks[seq(1,numexp,2)],tcl=0.4,lwd.ticks=1,mgp=c(0,0.25,0), las=2, cex.axis=0.35)
},
error= function(cond) {return(NA)},
warning= function(cond) {return(NA)}
)
lines(unk.expdates, list.delta.50, col="black")
lines(unk.expdates, list.delta.84, col="red")
dev.off()
</pre>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-47797782620060654152016-10-16T05:37:00.001-07:002016-10-16T05:37:20.660-07:00Making space on boot for UbuntuOften we need to create space on the Ubuntu's boot partition. The offending files are older versions of Ubuntu, still sitting on the boot partition. Deleting old versions of Ubuntu is straightforward. Simply, run the following command and boot drive will be cleaned of the old versions.<br />
<span style="color: #073763; font-family: Verdana, sans-serif; font-size: x-small;"><b><br /></b></span>
<span style="color: #0b5394; font-family: Verdana, sans-serif; font-size: x-small;"><b>sudo apt-get autoremove --purge</b></span><br />
<br />
The above command will delete all, but the current and previous version in the boot partition, allowing you to load new updates of the OS.<br />
<br />
However, sometimes deleting the old updates through the previous command is not enough. I ran across this myself when my software updater claimed that I needed to free up still more space. I found the following command on a blog that cleans out all but the current version. Use this only when the previous command is not adequate for your task..<br />
<br />
<strong style="background-color: white; color: #3366ff; font-family: verdana, tahoma, arial, sans-serif; font-size: 12.16px; margin: 0px; padding: 0px;">dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge</strong><br />
<strong style="background-color: white; color: #3366ff; font-family: verdana, tahoma, arial, sans-serif; font-size: 12.16px; margin: 0px; padding: 0px;"><br /></strong>
This did the trick for me, and I was able to install the latest updates.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXol6F0kCFNGq7Wt8rHqd59HQj-otFGDsFConomxqEZGmhZ2hc998tgN9Hs6H9QS15hyphenhyphenoNHuGeqUCTNJm21qLsAS8NTtxrG9dG_CKzyHhN08cPUJkmZATefIFFgvIoaY74wRmthniuwtU/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E_019.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXol6F0kCFNGq7Wt8rHqd59HQj-otFGDsFConomxqEZGmhZ2hc998tgN9Hs6H9QS15hyphenhyphenoNHuGeqUCTNJm21qLsAS8NTtxrG9dG_CKzyHhN08cPUJkmZATefIFFgvIoaY74wRmthniuwtU/s640/arthgallo%2540Ubuntu-GTX%253A+%257E_019.png" width="640" /></a></div>
<br />
All the best!awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-17981159792091240102016-09-19T14:44:00.001-07:002016-12-05T12:31:46.508-08:00Angular2 Quickstart errorsI was trying to setup Angular2 Quickstart application (<a href="https://angular.io/docs/ts/latest/quickstart.html">https://angular.io/docs/ts/latest/quickstart.html</a>) on my Ubuntu box and running npm install kept giving the user permission error. The logs revealed that the folder .npm and .config was not accessible to my user.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi29t2kMHT82H7NUN2T__YizqpVCAyO4oEOpTWKOeUDGws_YZVw99PDGcVluyJJ2e6GCyGpxNyCNF3UzaNa4rDYbSJFcbJCgPdjsiH5P_HbL0-4BETFPYgRNPG6X5xgqeOIX6WZgG2mrRE/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-angular2-quickstart_013.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi29t2kMHT82H7NUN2T__YizqpVCAyO4oEOpTWKOeUDGws_YZVw99PDGcVluyJJ2e6GCyGpxNyCNF3UzaNa4rDYbSJFcbJCgPdjsiH5P_HbL0-4BETFPYgRNPG6X5xgqeOIX6WZgG2mrRE/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-angular2-quickstart_013.png" width="640" /></a></div>
<br />
The issue was fixed by accessing the said folder and allowing current user to have permissions by entering the following commands<br />
<br />
sudo chown -R $USER:$GROUP ~/.npm<br />
sudo chown -R $USER:$GROUP ~/.config<br />
sudo chown -R $USER:$GROUP ~/.node_modules_global<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY3lqEy42-tDK3PxzYEBkyag3VG-QsuBTnWRemTfRDO6tXWR0JPqYRdLsP-QgGl5u8d5rKXxhsCbOL1pI8gU4QPHnFiptlF6bxofP1VY2mMNoqq7YxqW_f-ZT5ZGTallzZIr3N1idj0dg/s1600/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-angular2-quickstart_014.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY3lqEy42-tDK3PxzYEBkyag3VG-QsuBTnWRemTfRDO6tXWR0JPqYRdLsP-QgGl5u8d5rKXxhsCbOL1pI8gU4QPHnFiptlF6bxofP1VY2mMNoqq7YxqW_f-ZT5ZGTallzZIr3N1idj0dg/s640/arthgallo%2540Ubuntu-GTX%253A+%257E-Work-Angular2-angular2-quickstart_014.png" width="640" /></a></div>
<br />
That fixed the problem<br />
<br />
Entering the next two commands, started the demo and produced the output I was looking for.<br />
<br />
$ npm install<br />
<br />
$ npm start<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRPunqOdZInsOXyiocvxNIMVKcHJeA3_RHsNCdNj0gK3lKIJssVNv34j0EVihPYmGJQcZoLtHwh09P96JuxDR5qvJzcfP-2NGCjcS3DyW4jkpBKyxYOKqYrFCDCrQ322owpSBd6tJIDeI/s1600/Angular+2+QuickStart+-+Google+Chrome_015.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="406" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRPunqOdZInsOXyiocvxNIMVKcHJeA3_RHsNCdNj0gK3lKIJssVNv34j0EVihPYmGJQcZoLtHwh09P96JuxDR5qvJzcfP-2NGCjcS3DyW4jkpBKyxYOKqYrFCDCrQ322owpSBd6tJIDeI/s640/Angular+2+QuickStart+-+Google+Chrome_015.png" width="640" /></a></div>
<br />
<br />
That seems to have solved the problem!<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-75285664355436460592015-09-29T03:24:00.002-07:002015-09-29T03:24:32.824-07:00Re-projecting shapefile data during load in PostGISI recently came across the need to load data into PostGIS from Shape files. However, some data was in one projection and other data was in a different projection system. I needed to re-project the data at the time of loading the data.<br />
<br />
The process is fairly straightforward. The syntax is<br />
<br />
shp2pgsql -s <old_srid>:<new_srid></new_srid></old_srid><br />
<br />
Here is an example using real data..<br />
<br />
Let's look at the data<br />
<br />
<pre class="brush:bash">gdalsrsinfo nybbwi.prj
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8-VLp6sOxG7g9qogGvSjUmjb3D7QBhu4nSr_qKPmTV2fmR_qIImcwNjbYvdT7xwR7-Kdd1EBilx1q7XQnK5VodOfi3bkkimIalrdnodCr6CzGd5obWeY0GxkJmLSal342JJrs4HOW93Y/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_420.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="452" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8-VLp6sOxG7g9qogGvSjUmjb3D7QBhu4nSr_qKPmTV2fmR_qIImcwNjbYvdT7xwR7-Kdd1EBilx1q7XQnK5VodOfi3bkkimIalrdnodCr6CzGd5obWeY0GxkJmLSal342JJrs4HOW93Y/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_420.png" width="640" /></a></div>
<br />
As we can see, the projection is NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet, whose EPSG code is 2263. Since, I would like to load the data, I can use shp2pgsql command to create the load file.<br />
<br />
<pre class="brush:bash">shp2pgsql -d -s 2263 -g geom -e -I nybbwi nystaging.boroughs > $scriptdir/021_boroughs.sql
</pre>
The next file was in a different projection. Here I am using a different command ogrInfo to get the projection information.<br />
<br />
<pre class="brush:bash">ogrinfo -al -so fatality_yearly.shp</pre>
<br />
This reveals that projection is latlong, or EPSG code 4326<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq4wP1lzrCiYzY5Yk4AywGowP_AXO2cdXnfEmJKEl_1gfhzV3-VwL6Nfp-DZE58ppi1b8LsKqI4woApAh5uo3zAUiA0CWAPlPSQqQajTC8Rrf7Fw_uoWYRiJ5vWtymEjGOy7IZPkv39Qk/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_421.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq4wP1lzrCiYzY5Yk4AywGowP_AXO2cdXnfEmJKEl_1gfhzV3-VwL6Nfp-DZE58ppi1b8LsKqI4woApAh5uo3zAUiA0CWAPlPSQqQajTC8Rrf7Fw_uoWYRiJ5vWtymEjGOy7IZPkv39Qk/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_421.png" width="640" /></a></div>
<br />
As explained previously, we can use the -s option to re-project the data. The following is the command<br />
<br />
<pre class="brush:bash">shp2pgsql -d -s 4326:2263 -g geom -e -I fatality_yearly nystaging.fatality > $scriptdir/023_fatality_yearly.sql
shp2pgsql -d -s 4326:2263 -g geom -e -I injury_yearly nystaging.injury > $scriptdir/024_injury_yearly.sql
</pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4diJKHWCpt4OtVDZE_oMSy6SVGPAkab36fCwz6v77ZhLZ9AGTsy7VjScvj0e1HA4e_eErDKZiehnfQnJmjOXrG8Fw6HXABiTeIxWZoGTNU3282hxqzmlHjbhovJI7RSvEF7Iqv5JdItw/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_422.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4diJKHWCpt4OtVDZE_oMSy6SVGPAkab36fCwz6v77ZhLZ9AGTsy7VjScvj0e1HA4e_eErDKZiehnfQnJmjOXrG8Fw6HXABiTeIxWZoGTNU3282hxqzmlHjbhovJI7RSvEF7Iqv5JdItw/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_422.png" width="640" /></a></div>
<br />
That's it...<br />
<pre class="brush:bash">
</pre>
Here is the complete script...<br />
<br />
<pre class="brush:bash"># 04_load_spatial_nyc_data.sh
export datadir=../data/shpfiles
export scriptdir=../../scripts
export curdir=~/Work/Transportation/NYC/scripts
cd $curdir
export PGUSER=nyc
export PGPASSWORD=nyc
export PGDATABASE=nyc
echo $datadir
echo $scriptdir
cd $datadir
gdalsrsinfo nybbwi.prj
# EPSG code for NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet is 2263
shp2pgsql -d -s 2263 -g geom -e -I nybbwi nystaging.boroughs > $scriptdir/021_boroughs.sql
gdalsrsinfo PedCountLocationsMay2015.prj
ogrinfo -al -so PedCountLocationsMay2015.shp
shp2pgsql -d -s 2263 -g geom -e -I PedCountLocationsMay2015 nystaging.pedcounts > $scriptdir/022_pedcounts.sql
ogrinfo -al -so fatality_yearly.shp
shp2pgsql -d -s 4326:2263 -g geom -e -I fatality_yearly nystaging.fatality > $scriptdir/023_fatality_yearly.sql
shp2pgsql -d -s 4326:2263 -g geom -e -I injury_yearly nystaging.injury > $scriptdir/024_injury_yearly.sql
cd $scriptdir
psql -f 021_boroughs.sql
psql -f 022_pedcounts.sql
psql -f 023_fatality_yearly.sql
psql -f 024_injury_yearly.sql
</pre>
<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-14260810915214120002015-09-07T05:44:00.001-07:002015-09-07T05:44:34.301-07:00Connecting to PostGIS from RIn this post, we will connect to spatial datasets loaded in PostGIS from within R.<br />
<br />
First I have set environmental variables to connect to PostgreSQL in my environment. These are as follows<br />
<br />
<pre class="brush:bash">export PGUSER=nyc
export PGPASSWORD=nyc
export PGDATABASE=nyc
</pre>
<br />
Next, we will launch R, and load the required library, rgdal. If you don't have rgdal installed, please refer to<a href="http://opendesignarch.blogspot.com/2015/08/reading-shape-files-in-r.html"> initial steps of my earlier post.</a><br />
<br />
<br />
Now lets get started
<br />
<pre class="brush:bash"># 05a_connect_ped_postgis.r
# Load required library
library(rgdal)
</pre>
<br />
This loads the library<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCxU27a8qHgiBGSkQN6bssTJc6Y0CMoNzlMnBokOQO-5W2uQGOp7ochcvqdyT2IKTCER5AZ_bSFg_cZr0u3SRHKvefvYMVh2ql2HNYMz-PcplqDpvFFCGmCbW4XYo_cuDVndjTOLGZigw/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_412.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCxU27a8qHgiBGSkQN6bssTJc6Y0CMoNzlMnBokOQO-5W2uQGOp7ochcvqdyT2IKTCER5AZ_bSFg_cZr0u3SRHKvefvYMVh2ql2HNYMz-PcplqDpvFFCGmCbW4XYo_cuDVndjTOLGZigw/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_412.png" width="640" /></a></div>
<br />
Next we read the PostgreSQL connection parameters from the shell environment using Sys.getenv command<br />
<br />
<pre class="brush:bash">#Set PostgreSQL connection parameters from the environment
pguser<-Sys.getenv('PGUSER')
pgpassword<-Sys.getenv('PGPASSWORD')
pgdatabase<-Sys.getenv('PGDATABASE')
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoQ-ToZ4FlwKVMqUY-SkAnWu8ao4Tgq0a32a3WqF7A8TWDLAlp0Oz4LXvoq3rDvM9-7Ab5F1-Ix6H8_TwMit1hpMbFRkc7z4ysJ86qDH3Fyrm64GUjiqKhBblh88CzmEUZ-kUcL6V9iUc/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_413.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoQ-ToZ4FlwKVMqUY-SkAnWu8ao4Tgq0a32a3WqF7A8TWDLAlp0Oz4LXvoq3rDvM9-7Ab5F1-Ix6H8_TwMit1hpMbFRkc7z4ysJ86qDH3Fyrm64GUjiqKhBblh88CzmEUZ-kUcL6V9iUc/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_413.png" width="640" /></a></div>
<br />
Next we create the database connection by concatenating all variables into a connection string using the paste function in R , and we print to confirm we have it right.<br />
<br />
<pre class="brush:bash">#Make connection to PostGIS database
dsn<-paste("PG:dbname='",pgdatabase,"' user='",pguser,"' password='",pgpassword,"'",sep='')
dsn
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEVUiFxtGVR2E_fbDEG1Aoelp_z8HWTnsV6iBfca3JrzDOLp38oI1ZVEi-ynzw9DZyM8KoZj7AJZuLnldRKqFxMsUI7_9vkXxx0eQAOtxNLesHl93wjmMbqkIbw1DGrm2VEWLuFpMEk4/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_414.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEVUiFxtGVR2E_fbDEG1Aoelp_z8HWTnsV6iBfca3JrzDOLp38oI1ZVEi-ynzw9DZyM8KoZj7AJZuLnldRKqFxMsUI7_9vkXxx0eQAOtxNLesHl93wjmMbqkIbw1DGrm2VEWLuFpMEk4/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_414.png" width="640" /></a></div>
<br />
Now we can use the ogrListLayers command to make sure we can see our previously loaded data.<br />
<br />
<pre class="brush:bash">ogrListLayers(dsn)
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoxbnIqw-iq9OkfnAlsiIrmwuyqEtq9nnr0N5vosCoMMv7mGPePdtB-AVQYb6t1kdLEOchMjmE9jZRTc8BAA1gx94Vy00SKKvRfp0T0cjTorEZCgylWSrkEsl2JLGCWoL7qOEh5Jlb04k/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_415.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoxbnIqw-iq9OkfnAlsiIrmwuyqEtq9nnr0N5vosCoMMv7mGPePdtB-AVQYb6t1kdLEOchMjmE9jZRTc8BAA1gx94Vy00SKKvRfp0T0cjTorEZCgylWSrkEsl2JLGCWoL7qOEh5Jlb04k/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_415.png" width="640" /></a></div>
<br />
The command makes a connection to the database and lists all layers registered with PostGIS. Now we can also look up the details for a specific layer of our choice using ogrInfo function<br />
<br />
<pre class="brush:bash">ogrInfo(dsn, "nystaging.fatality")
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIFc9LsES-ChzIXzQozj5TSctdO05fQTUJSUoB9zQ6LD1iXPWa2lgSbdLsv4ockHCYPAVSvDq_SEXkQppLMSqdFy-d0HhIPQcrnkmfgUYSpwba7lAHhl_SC9EHK1odjAENL5I6Lqto_og/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_417.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIFc9LsES-ChzIXzQozj5TSctdO05fQTUJSUoB9zQ6LD1iXPWa2lgSbdLsv4ockHCYPAVSvDq_SEXkQppLMSqdFy-d0HhIPQcrnkmfgUYSpwba7lAHhl_SC9EHK1odjAENL5I6Lqto_og/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_417.png" width="640" /></a></div>
<br />
Here is the complete listing..<br />
<br />
<pre class="brush:bash"># 05a_connect_ped_postgis.r
# Load required library
library(rgdal)
#Set PostgreSQL connection parameters from the environment
pguser<-Sys.getenv('PGUSER')
pgpassword<-Sys.getenv('PGPASSWORD')
pgdatabase<-Sys.getenv('PGDATABASE')
#Make connection to PostGIS database
dsn<-paste("PG:dbname='",pgdatabase,"' user='",pguser,"' password='",pgpassword,"'",sep='')
dsn
ogrListLayers(dsn)
ogrInfo(dsn, "nystaging.fatality")
</pre>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-79299894569602382752015-09-05T06:36:00.002-07:002015-09-05T06:55:54.138-07:00Installing Tiger Geocoder on PostGIS 2.1 on Ubuntu using a single shell scriptIn this post, I am going to walk through the steps of installing Tiger Geocoder on Ubuntu. These are the steps that worked for me and are collated from multiple sources and forum postings. My intent was to create one script that did everything from start to finish (included at the end), that took a while to perfect.<br />
<br />
In this post, I will walk through the script, so you can modify it for your environment. Lets get started.<br />
<br />
First step is to set some environmental variables that we will use. This way we don't have to enter this over and over again. As you can see, I plan to install the database on a database called tiger. geocoder seems to be another popular alternative.<br />
<br />
<pre class="brush:bash">export PGUSER=arthgallo
export PGPASSWORD=*****
export PGDATABASE=tiger
</pre>
<br />
Next step is to enter the states you want to load data for. Please enter it here in the format below
<br />
<br />
<pre class="brush:bash">#Each state needs to be quoted with single quotes. The following construct
#preserves this arrangement
export geostates="'"NY"'","'"MA"'"
echo $geostates
</pre>
<br />
Next we create the database<br />
<br />
<pre class="brush:bash">createdb tiger
</pre>
<br />
Now lets install the appropriate extensions including PostGIS. If PostGIS is not installed or is not the latest version, please refer to <a href="http://opendesignarch.blogspot.com/2015/08/upgrading-postgresql-from-93-to-94.html">my previous posts</a>. Once we install the Postgis Tiger Geocoder extension, we will also validate if the address can be normalized. Running address normalization only validates that the extension is installed. We are still not done as setting up the actual geocoder involves downloading a lot of data and it takes a fair bit of time based on your internet connection and your processing speed.
<br />
<br />
<pre class="brush:bash">psql -c "CREATE EXTENSION postgis"
psql -c "CREATE EXTENSION postgis_topology"
psql -c "CREATE EXTENSION fuzzystrmatch"
psql -c "DROP EXTENSION postgis_tiger_geocoder CASCADE"
psql -c "CREATE EXTENSION postgis_tiger_geocoder"
psql -c "SELECT na.address, na.streetname,na.streettypeabbrev, na.zip
FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na"
</pre>
<br />
Next, we need to set up the automated process that will download the Tiger data from census website and deploy the appropriate geocoders. I have created a SQL script file that does some of the work. It makes the appropriate entries into a table for setting it up according to my environment.<br />
<br />
As you can see I have commented out the PGPORT, PGHOST, PGUSER and PGPASSWORD entries since I had already set the user at the beginning of the script, and I want to continue with the same.<br />
<br />
Please modify it to match your environment.
<br />
<br />
<pre class="brush:sql">-- tiger_loader_platform.sql
INSERT INTO tiger.loader_platform(os, declare_sect, pgbin, wget, unzip_command, psql, path_sep,
loader, environ_set_command, county_process_command)
SELECT 'trusty', 'TMPDIR="${staging_fold}/temp/"
UNZIPTOOL=unzip
WGETTOOL=/usr/bin/wget
export PGBIN=/usr/bin
# export PGPORT=5432
# export PGHOST=localhost
# export PGUSER=postgres
# export PGPASSWORD=yourpasswordhere
export PGDATABASE=tiger
PSQL=${PGBIN}/psql
SHP2PGSQL=${PGBIN}/shp2pgsql
cd ${staging_fold}', pgbin, wget, unzip_command, psql, path_sep,
loader, environ_set_command, county_process_command
FROM tiger.loader_platform
WHERE os = 'sh';
</pre>
<br />
Next we will execute the script to create appropriate entries.
<br />
<br />
<pre class="brush:bash">psql -f tiger_loader_platform.sql
</pre>
<br />
We can test that everything is inserted correctly..
<br />
<br />
<pre class="brush:bash">psql -c "select declare_sect from tiger.loader_platform where os='trusty'"
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir3j6NN7Yw8Txj-uibYdnyoaHVBgXwCtSzpJv9mxrK_eoO26Kl7cpcTd80ximioW4Ps_4TvX5H73pUDUkUC0v_ZtdbCMdZfrTWaKM8WJgQDuPo9YSAlldg7V6j0jvHjIbt06JJsluesvs/s1600/arthgallo%2540ub1204%253A+%257E_407.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir3j6NN7Yw8Txj-uibYdnyoaHVBgXwCtSzpJv9mxrK_eoO26Kl7cpcTd80ximioW4Ps_4TvX5H73pUDUkUC0v_ZtdbCMdZfrTWaKM8WJgQDuPo9YSAlldg7V6j0jvHjIbt06JJsluesvs/s640/arthgallo%2540ub1204%253A+%257E_407.png" width="640" /></a></div>
<br />
Next we will create a folder to stage the data downloaded from the census ftp site. Please make sure you have enough disk space on your machine. My thumb rule for the process is 1-2 GB per state that you want to setup.<br />
<br />
We create a folder called gisdata at root. This is important since the out of the box geocoder install scripts all point to this folder.<br />
<br />
<pre class="brush:bash"># script needs gisdata folder
sudo mkdir /gisdata
</pre>
<br />
We will also need a temp folder inside the gisdata folder.<br />
<br />
<pre class="brush:bash"># and a temp folder inside it
sudo mkdir /gisdata/temp
</pre>
<br />
Next we need to make this folder accessible to the postgres user.<br />
<br />
<pre class="brush:bash"># Need to make it accessible to the postgres user
sudo chmod -R 777 /gisdata
</pre>
<br />
Now lets restart postgres before the fun begins.<br />
<br />
<pre class="brush:bash">#Restart postgres service
sudo service postgresql restart
</pre>
<br />
First step is to generate a script called loader_generate_nation_script. I skipped this step and had to repeat the process multiple times (many wasted hours) before figuring it out. Since this is a SQL command we need to make sure the output is clean enough to be executed, hence some extra formatting commands on the SQL. The default SQL output puts the column name in the output. I renamed it to 'aaaaa' so that I could get rid of it later.<br />
<br />
<pre class="brush:bash"></pre>
<pre class="brush:bash">#Run the nation script
psql -c "SELECT loader_generate_nation_script('trusty') AS aaaaa" \
-t -x -A -F "" -q -o 02a_load_nation_tiger.sh
</pre>
<br />
Now that the script is generated, we need to replace aaaaa with blank to make it a proper shell script. We also need to make it executable. Then we need to execute it...<br />
<br />
<pre class="brush:bash">#Replace the text
sed -i 's/aaaaa//g' 02a_load_nation_tiger.sh
chmod a+x ./02a_load_nation_tiger.sh
sudo su postgres ./02a_load_nation_tiger.sh
</pre>
<br />
Next the actual script for loading specific states. I just needed data for New York and Massachusetts. You can modify this to match your criteria.<br />
<pre class="brush:bash"></pre>
<pre class="brush:bash"></pre>
<pre class="brush:bash">#Now generate the loader script
psql -c "SELECT loader_generate_script(ARRAY[$geostates], 'trusty') AS aaaaa" -t -x -A -F "" -q -o 02b_load_ny_tiger.sh
</pre>
<br />
Again, we need to replace the dummy text with blanks using sed<br />
<br />
<pre class="brush:bash">#Replace dummy text with blanks
sed -i 's/aaaaa//g' 02b_load_ny_tiger.sh
</pre>
<br />
We need to make the file executable followed by executing the file. Beware this process takes a while to run.<br />
<pre class="brush:bash"></pre>
<pre class="brush:bash">#Execute the load_ny_tiger file we generated
chmod a+x ./02b_load_ny_tiger.sh
sudo su postgres ./02b_load_ny_tiger.sh
</pre>
<br />
The previous step takes a few hours to run depending on the data that needs to be downloaded. We run the following command to install missing indexes.<br />
<br />
<pre class="brush:bash">psql -c "SELECT install_missing_indexes()"
</pre>
<br />
Now that everything is setup, we can run individual queries. First step is to normalize an address<br />
<br />
<pre class="brush:bash">psql -c "SELECT '30 Rock' As event, n.* FROM normalize_address('45 Rockefeller Plaza, New York, NY 10111') As n"
</pre>
<br />
Here is the output<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNd1lcUCAl2xR5ScTDHnhO4aYe4vjR8i1KgItdNaz1-4yGyFsAXJn7d0yujeNzo-iN8cWjzgmRRocGlqLCdGhlDXC7ehMftYgywHAtV73h6q8Dg7-YJ6BB_h8ni6aF7ErTJjTxUiEKmA/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_408.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNd1lcUCAl2xR5ScTDHnhO4aYe4vjR8i1KgItdNaz1-4yGyFsAXJn7d0yujeNzo-iN8cWjzgmRRocGlqLCdGhlDXC7ehMftYgywHAtV73h6q8Dg7-YJ6BB_h8ni6aF7ErTJjTxUiEKmA/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_408.png" width="640" /></a></div>
<br />
Next the real test... We try to geocode an address.<br />
<br />
<br />
<pre class="brush:bash">psql -c "SELECT g.rating, ST_X(g.geomout) As lon, ST_Y(g.geomout) As lat, (addy).address As stno, (addy).streetname As street,
(addy).streettypeabbrev As styp, (addy).location As city, (addy).stateabbrev As st,(addy).zip FROM geocode('45 Rockefeller Plaza, New York, NY 10111') As g"
</pre>
<br />
Perfect, we found some matches as shown in the screenshot below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRh5w1atB1Dti3s550XolT4AHS68-eo3fQXdW34uVlARaz-_mfCIq-SGjFYzeLkGLWasl2agEqnBgMUK8LiJoKPnt8aM2NY1Ivl3TSrb1GxK6NYvsGKxD7YfFdBJakHogqixvPSebfNuo/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_409.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRh5w1atB1Dti3s550XolT4AHS68-eo3fQXdW34uVlARaz-_mfCIq-SGjFYzeLkGLWasl2agEqnBgMUK8LiJoKPnt8aM2NY1Ivl3TSrb1GxK6NYvsGKxD7YfFdBJakHogqixvPSebfNuo/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_409.png" width="640" /></a></div>
<br />
<br />
Next an intersection geocode<br />
<br />
<pre class="brush:bash">psql -c "SELECT pprint_addy(addy), st_astext(geomout),rating FROM geocode_intersection( 'Fort Hamilton Pkwy','50th Street', 'NY', 'Brooklyn','11219',1)"
</pre>
<pre class="brush:bash"></pre>
<br />
Here is the result<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZpvgpGykR8-Tek1dJcqyJvz0kd-M0RH7B2hbY_AopppfDBzl8xrJkp0Yj-nqhSsfgYlcaiYP7uRJY4W433S3xM-EfWUVcxpueGDlApOjfWF8gAnwofD215D9jo4ILwIAzkWoLLzcYqOY/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_410.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZpvgpGykR8-Tek1dJcqyJvz0kd-M0RH7B2hbY_AopppfDBzl8xrJkp0Yj-nqhSsfgYlcaiYP7uRJY4W433S3xM-EfWUVcxpueGDlApOjfWF8gAnwofD215D9jo4ILwIAzkWoLLzcYqOY/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_410.png" width="640" /></a></div>
<br />
Next without the zipcode
<br />
<br />
<pre class="brush:bash">psql -c "SELECT pprint_addy(addy), st_astext(geomout),rating FROM geocode_intersection( 'Fort Hamilton Pkwy','50th Street', 'NY', 'Brooklyn')"
</pre>
<br />
Here is the result
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1CHAhsNHvi6MhUpanPRM3lRScVDk-Kky1yz8gBXeVTfDRxukwgSYba8J0CRqS487MjxgvdOQjIxZrju6RTcT4si7KoHnohMfDrMyg1EekNijfE5SxtQ29FdUbJDVcb7YcCI1W1r7R2XU/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_411.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1CHAhsNHvi6MhUpanPRM3lRScVDk-Kky1yz8gBXeVTfDRxukwgSYba8J0CRqS487MjxgvdOQjIxZrju6RTcT4si7KoHnohMfDrMyg1EekNijfE5SxtQ29FdUbJDVcb7YcCI1W1r7R2XU/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_411.png" width="640" /></a></div>
<br />
Not bad... Here is the complete script for the shell file and SQL script.<br />
<br />
First the SQL script<br />
<br />
<pre class="brush:sql">-- tiger_loader_platform.sql
INSERT INTO tiger.loader_platform(os, declare_sect, pgbin, wget, unzip_command, psql, path_sep,
loader, environ_set_command, county_process_command)
SELECT 'trusty', 'TMPDIR="${staging_fold}/temp/"
UNZIPTOOL=unzip
WGETTOOL=/usr/bin/wget
export PGBIN=/usr/bin
# export PGPORT=5432
# export PGHOST=localhost
# export PGUSER=postgres
# export PGPASSWORD=yourpasswordhere
export PGDATABASE=tiger
PSQL=${PGBIN}/psql
SHP2PGSQL=${PGBIN}/shp2pgsql
cd ${staging_fold}', pgbin, wget, unzip_command, psql, path_sep,
loader, environ_set_command, county_process_command
FROM tiger.loader_platform
WHERE os = 'sh';
</pre>
<br />
Next the shell script<br />
<br />
<br />
<pre class="brush:bash"># 02_install_tiger_geocoder.sh
export PGUSER=arthgallo
export PGPASSWORD=*****
export PGDATABASE=tiger
#Each state needs to be quoted with single quotes. The following construct
#preserves this arrangement
export geostates="'"NY"'","'"MA"'"
echo $geostates
createdb tiger
psql -c "CREATE EXTENSION postgis"
psql -c "CREATE EXTENSION postgis_topology"
psql -c "CREATE EXTENSION fuzzystrmatch"
psql -c "DROP EXTENSION postgis_tiger_geocoder CASCADE"
psql -c "CREATE EXTENSION postgis_tiger_geocoder"
psql -c "SELECT na.address, na.streetname,na.streettypeabbrev, na.zip
FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na"
psql -c "delete from tiger.loader_platform where os='trusty'"
psql -f tiger_loader_platform.sql
psql -c "select declare_sect from tiger.loader_platform where os='trusty'"
# script needs gisdata folder
sudo mkdir /gisdata
# and a temp folder inside it
sudo mkdir /gisdata/temp
# Need to make it accessible to the postgres user
sudo chmod -R 777 /gisdata
#Restart postgres service
sudo service postgresql restart
#Run the nation script
psql -c "SELECT loader_generate_nation_script('trusty') AS aaaaa" \
-t -x -A -F "" -q -o 02a_load_nation_tiger.sh
#Replace the text
sed -i 's/aaaaa//g' 02a_load_nation_tiger.sh
chmod a+x ./02a_load_nation_tiger.sh
sudo su postgres ./02a_load_nation_tiger.sh
#Now generate the loader script
psql -c "SELECT loader_generate_script(ARRAY[$geostates], 'trusty') AS aaaaa" -t -x -A -F "" -q -o 02b_load_ny_tiger.sh
#Replace dummy text with blanks
sed -i 's/aaaaa//g' 02b_load_ny_tiger.sh
#Execute the load_ny_tiger file we generated
chmod a+x ./02b_load_ny_tiger.sh
sudo su postgres ./02b_load_ny_tiger.sh
psql -c "SELECT install_missing_indexes()"
#Test address normalization
psql -c "SELECT '30 Rock' As event, n.* FROM normalize_address('45 Rockefeller Plaza, New York, NY 10111') As n"
#Test simple geocode
psql -c "SELECT g.rating, ST_X(g.geomout) As lon, ST_Y(g.geomout) As lat, (addy).address As stno, (addy).streetname As street,
(addy).streettypeabbrev As styp, (addy).location As city, (addy).stateabbrev As st,(addy).zip FROM geocode('45 Rockefeller Plaza, New York, NY 10111') As g"
#Test intersection geocode
psql -c "SELECT pprint_addy(addy), st_astext(geomout),rating FROM geocode_intersection( 'Fort Hamilton Pkwy','50th Street', 'NY', 'Brooklyn','11219',1)"
#Test intersection geocode without zip
psql -c "SELECT pprint_addy(addy), st_astext(geomout),rating FROM geocode_intersection( 'Fort Hamilton Pkwy','50th Street', 'NY', 'Brooklyn')"
</pre>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com3tag:blogger.com,1999:blog-2346591996749941735.post-26322314055908431822015-08-29T10:49:00.001-07:002015-08-30T04:53:04.484-07:00Upgrading PostgreSQL and PostGIS from 9.3 to 9.4In this post, we will walk through steps of upgrading from PostgreSQL 9.3 to 9.4. It all happened because my PostGIS version had got corrupted.<br />
<br />
When I executed the command to check for my PostGIS version, I got an error saying liblwgeom library could not be loaded<br />
<br />
<pre class="brush:bash">su - postgres -c "psql -c 'SELECT PostGIS_full_version()'"
</pre>
<br />
gave the following error<br />
<br />
<pre class="brush:bash">ERROR: could not load library "/usr/lib/postgresql/9.3/lib/postgis-2.1.so": liblwgeom-2.1.2.so: cannot open shared object file: No such file or directory
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnOt6W3RtRO54m6au7wa2Ex9x9coudiSDAyMAVPF-G5XMCvVJCp46NHWDwsvCshTK2ojAkaP6HvQ_RsRskvzOhyphenhyphenhYLPksL4MCAmf2qwM6EogAg3dPXOaOP-cWcjbqL5kG12JZgdjq8w4g/s1600/arthgallo%2540ub1204%253A+%257E_393.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnOt6W3RtRO54m6au7wa2Ex9x9coudiSDAyMAVPF-G5XMCvVJCp46NHWDwsvCshTK2ojAkaP6HvQ_RsRskvzOhyphenhyphenhYLPksL4MCAmf2qwM6EogAg3dPXOaOP-cWcjbqL5kG12JZgdjq8w4g/s640/arthgallo%2540ub1204%253A+%257E_393.png" width="640" /></a></div>
<br />
After much research and browsing through forums, I realized it was better to upgrade postgreSQL and PostGIS. I checked the postgres version with the following command to make sure I needed to do that.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilwUijNlLVNthQjtNAh9-gzj2UZKhbgXlud0PLSBJDLg_KBu_gixBMfrdJTcTIeCWJdJypM6oqEnVkPF7pprNbYJz9kAi_9M_W0_0v3r4dX4ZModUu8r13SoxJYSvs06fLlsQr29dcsPM/s1600/arthgallo%2540ub1204%253A+%257E_395.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilwUijNlLVNthQjtNAh9-gzj2UZKhbgXlud0PLSBJDLg_KBu_gixBMfrdJTcTIeCWJdJypM6oqEnVkPF7pprNbYJz9kAi_9M_W0_0v3r4dX4ZModUu8r13SoxJYSvs06fLlsQr29dcsPM/s640/arthgallo%2540ub1204%253A+%257E_395.png" width="640" /></a></div>
<br />
I found a great post on stackexchange from someone who had posted their script. With minor changes the script was good. Here is the modified script in its entirety<br />
<br />
I executed the following step by step to make sure I could see what was happening...
<br />
<br />
<pre class="brush:bash">su - postgres -c "psql -c 'SELECT PostGIS_full_version()'"
su - postgres -c "psql --version"
# Be sure to save your config files.
sudo cp /etc/postgresql/9.3/main/postgresql.conf ~
sudo cp /etc/postgresql/9.3/main/pg_hba.conf ~
# Package repo (for apt-get). I have 14.04 LTS, so I selected trusty-pgdg. Please change to match your version
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main" >> /etc/apt/sources.list.d/postgresql.list'
# Also probably optional but I like to update sources and upgrade
sudo apt-get update
sudo apt-get upgrade
# Install postgres 9.4
sudo apt-get install postgresql-9.4 postgresql-server-dev-9.4 postgresql-contrib-9.4
# Get latest postgis for 9.4 (optional)
sudo apt-get install postgresql-9.4-postgis
# dump your data
sudo su postgres
cd ./data/dumps
/usr/lib/postgresql/9.4/bin/pg_dumpall > pre_upgrade_from_9.3_to_9.4.dump
# I got this error:
# pg_dump: [archiver (db)] query failed: ERROR: could not load library "/usr/lib/postgresql/9.3/lib/postgis-2.1.so":
# liblwgeom-2.1.2.so: cannot open shared object file: No such file or directory
#This is the elusive fix to the problem
sudo apt-get install liblwgeom-2.1.3
# Then repeated
sudo su postgres
cd ./data/dumps
/usr/lib/postgresql/9.4/bin/pg_dumpall > pre_upgrade_from_9.3_to_9.4.dump
# Make a data dir for Postgres 9.4
sudo mkdir -p /data/postgres/9.4/main
sudo chown -R postgres:postgres /data/postgres
# Change the 9.4 conf file's data dir to point to /data/postgres/9.4/main
sudo gedit /etc/postgresql/9.4/main/postgresql.conf
# Install 9.4 cluster
sudo /etc/init.d/postgresql stop
# May need to restart machine if could not stop both postgreSQL processes
sudo pg_dropcluster 9.4 main
sudo pg_createcluster -d /data/postgres/9.4/main 9.4 main
# start 9.4 explicitly
sudo /etc/init.d/postgresql start 9.4
# Restore: Make sure to use the 9.4 version of psql
psql -d postgres -p 5433 -f ~/data/dumps/pre_upgrade_from_9.3_to_9.4.dump
# Change port back to 5432 (optional) and the confs back to what they were! (reference previously copied files)
sudo gedit /etc/postgresql/9.4/main/postgresql.conf
# Changed local all all peer -> local all all md5
sudo gedit /etc/postgresql/9.4/main/pg_hba.conf
sudo service postgresql restart 9.4
# Verify your data was properly imported
# Drop old cluster
sudo pg_dropcluster --stop 9.3 main
# Analyze
sudo service postgresql start
psql
>\c your_database
> ANALYZE;
</pre>
<br />
Now on starting I still got 2 postgres instances
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmNB_uGhGK7mIbw1DtLamlA258hzarjDWL_NTOYg5bJV7Ri4D7a6WMzkMdwxai8Av1pP5B2VghaKVG8F6nnOfLsCwpcN2WW3olb14BvSgHsrUEYWpFXE276SgGJA_VCtkuUilviuf90xc/s1600/arthgallo%2540ub1204%253A+%257E_396.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmNB_uGhGK7mIbw1DtLamlA258hzarjDWL_NTOYg5bJV7Ri4D7a6WMzkMdwxai8Av1pP5B2VghaKVG8F6nnOfLsCwpcN2WW3olb14BvSgHsrUEYWpFXE276SgGJA_VCtkuUilviuf90xc/s640/arthgallo%2540ub1204%253A+%257E_396.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We need to delete the old PostgreSQL version using commands below... </div>
<br />
<pre class="brush:bash">#Delete previous postgres
sudo apt-get purge postgresql-9.3
sudo service postgresql restart 9.4
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5CsyxKzPDP41OpU_VijpDDWpGcKIaFHEPFx5PsIbZXDOLmNhXddMKp0-yDt3T7sDeN-VPKuejDnSE0MFqAmYL2Z_Ghub59QGABzJEslVE5nRqna7XgvBPArpD-XDVV9nl8fOJbt64y6c/s1600/arthgallo%2540ub1204%253A+%257E_398.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5CsyxKzPDP41OpU_VijpDDWpGcKIaFHEPFx5PsIbZXDOLmNhXddMKp0-yDt3T7sDeN-VPKuejDnSE0MFqAmYL2Z_Ghub59QGABzJEslVE5nRqna7XgvBPArpD-XDVV9nl8fOJbt64y6c/s640/arthgallo%2540ub1204%253A+%257E_398.png" width="640" /></a></div>
<br />
After the restart, it shows only one service starting..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkVsFhoZxdzWTx1XAO2QrcsePzEwML0-NV2Zt8hjKD_Ku5M0vMP7iIrVC_2ws2t-iMIvCGBGpHOuvN6pM-bi87bBSB6W-afJg6mIgJAwgQbgjgZ2aig7fDoiSoMh22Q34tIg2-POUXvV8/s1600/arthgallo%2540ub1204%253A+%257E_399.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkVsFhoZxdzWTx1XAO2QrcsePzEwML0-NV2Zt8hjKD_Ku5M0vMP7iIrVC_2ws2t-iMIvCGBGpHOuvN6pM-bi87bBSB6W-afJg6mIgJAwgQbgjgZ2aig7fDoiSoMh22Q34tIg2-POUXvV8/s640/arthgallo%2540ub1204%253A+%257E_399.png" width="640" /></a></div>
<br />
Now, we can verify if PostGIS is correctly installed<br />
<br />
<pre class="brush:bash">su - postgres -c "psql -c 'SELECT PostGIS_full_version()'"</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUCzY96zGRDtiueEhxym41aTh6yrB8jA9Ctn1vv-Kl25sErJm3_IMpw_ZckzmlKcrvYsm3e06y2wwrUfmRPP2C5XZk86FFbnqgRfbqx74swvvLrehif-8JjD77qR2tepIT96-lMvsf1-Q/s1600/arthgallo%2540ub1204%253A+%257E_397.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUCzY96zGRDtiueEhxym41aTh6yrB8jA9Ctn1vv-Kl25sErJm3_IMpw_ZckzmlKcrvYsm3e06y2wwrUfmRPP2C5XZk86FFbnqgRfbqx74swvvLrehif-8JjD77qR2tepIT96-lMvsf1-Q/s640/arthgallo%2540ub1204%253A+%257E_397.png" width="640" /></a></div>
<br />
This shows the correct versions and everything should be fine. Finally to check the version of other extensions as well, we can use the following command<br />
<br />
<pre class="brush:bash">psql -c "SELECT name, default_version,installed_version FROM pg_available_extensions WHERE name LIKE 'postgis%'"
</pre>
<br/>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6L2we8y8xrRIZEyZOFIhePVdVP2QAw2zpD5ye88el9tWqKdy1nQKQMDr7W_x4zopyHxM4lH-2MkQQ608mTRxHif0keU_YXJmFimTi9s8MkpjJWQITNBKwkG1p5bPZ6yOow-vujo8_0l0/s1600/arthgallo%2540ub1204%253A+%257E_400.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6L2we8y8xrRIZEyZOFIhePVdVP2QAw2zpD5ye88el9tWqKdy1nQKQMDr7W_x4zopyHxM4lH-2MkQQ608mTRxHif0keU_YXJmFimTi9s8MkpjJWQITNBKwkG1p5bPZ6yOow-vujo8_0l0/s640/arthgallo%2540ub1204%253A+%257E_400.png" width="640" /></a></div>
<br />
Looks like everything has got upgraded correctly.awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-77420680557102617032015-08-25T06:01:00.004-07:002015-08-26T06:17:33.308-07:00Plotting R data on an Interactive Google mapIn this post, we will see how to plot data on an interactive map using R. We will use Google maps as the base map. Here is the output<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixfhAXN0sE8WB5k4TYg-LhJVVeM3OUvGwJ25lugecrqkRHgV-g2Mx2Ix6HfBPyyvgtxvA5_d81gd7-Ja025UFkaOsLWFz6jwtLqHNb_9jI9wtFxflH26FwX-Gwm5M6KUD_PLWeVXrl3Ms/s1600/MapID252e3c5fbf9b+-+Google+Chrome_387.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="380" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixfhAXN0sE8WB5k4TYg-LhJVVeM3OUvGwJ25lugecrqkRHgV-g2Mx2Ix6HfBPyyvgtxvA5_d81gd7-Ja025UFkaOsLWFz6jwtLqHNb_9jI9wtFxflH26FwX-Gwm5M6KUD_PLWeVXrl3Ms/s640/MapID252e3c5fbf9b+-+Google+Chrome_387.png" width="640" /></a></div>
<br />
<br />
You can also switch to street view<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNOVzNXNxcPcVfCGhLS_9W4MfkRFkrlBR5rar4x5oqjelufiDUhQaV9yxvyBBDLt8t47rQgGI1EjTNvWGgpTg-9rtfgDTOK50ZE_lS4mdXdf0vP2SyjHt_pdyhxPntsZFA-zRGiaE0qxs/s1600/MapID252e3c5fbf9b+-+Google+Chrome_388.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="380" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNOVzNXNxcPcVfCGhLS_9W4MfkRFkrlBR5rar4x5oqjelufiDUhQaV9yxvyBBDLt8t47rQgGI1EjTNvWGgpTg-9rtfgDTOK50ZE_lS4mdXdf0vP2SyjHt_pdyhxPntsZFA-zRGiaE0qxs/s640/MapID252e3c5fbf9b+-+Google+Chrome_388.png" width="640" /></a></div>
<br />
Let's get started. Make sure you have installed the required libraries. The new library needed is googleVis which can be installed by launching R in sudo mode and entering the following command<br />
<br />
<pre class="brush:bash">install.packages("googleVis")
q()
</pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEOemujLQDUrsTb1kA0J5ZhjImPrnMdK1gPYmY9NbMfMsDmZUWotK-L7ILmBEzY5MFpl3f3zn1kSpLg_AEpMxKpV0jFq_cf7iGS6V6tQ0uP5E9K-D2YyLqtrDbgPbuLNj2YwN8G_-1IP4/s1600/arthgallo%2540ub1204%253A+%257E_389.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEOemujLQDUrsTb1kA0J5ZhjImPrnMdK1gPYmY9NbMfMsDmZUWotK-L7ILmBEzY5MFpl3f3zn1kSpLg_AEpMxKpV0jFq_cf7iGS6V6tQ0uP5E9K-D2YyLqtrDbgPbuLNj2YwN8G_-1IP4/s640/arthgallo%2540ub1204%253A+%257E_389.png" width="640" /></a></div>
<br />
First step is to download the data. This previous post shows <a href="http://opendesignarch.blogspot.com/2015/08/obtaining-nyc-pedestrian-safety-data.html">how to obtain the spatial data</a> used in this example from the NYC website. Now launch R in regular mode and enter the following code to create the map.<br />
<br />
First we need to load the required libraries
<br/>
<pre class="brush:bash"># Load the needed libraries
library(sp) # classes for spatial data
library(maptools)
library(rgeos) # and their dependencies
library(rgdal)
library(ggplot2)
library(ggmap)
library(scales)
library(gmodels)
library(googleVis)
</pre>
<br/>
Next we need to set the working directory where our scripts are located and declare a variable to folder where our data is located.
<br/>
<pre class="brush:bash">
# Set default paths for data
setwd("~/Work/Transportation/NYC/scripts")
shpfilepath="../data/shpfiles"
</pre>
<br/>
Next we will read the shape files with data. We have two shape files from NYC. First contains only fatal accidents, and second contains injury accidents. We will later combine these files.
<br/>
<pre class="brush:bash">
# Read injury and fatality statistics
ogrInfo(shpfilepath,"fatality_yearly")
ogrInfo(shpfilepath,"injury_yearly")
ftlty<-readOGR(shpfilepath, "fatality_yearly")
injry<-readOGR(shpfilepath, "injury_yearly")
names(ftlty); dim(ftlty)
names(injry); dim(injry)
</pre>
<br/>
Next we need to rename the column names across the two datasets so that they are identical. Following step shows us how to do that. We also will add a new variable that classifies the incident as an injury or a fatality incident.
<br/>
<pre class="brush:bash">
#Classify severity and rename columns to be identical in fatalities and injury datasets
ftlty$Severity<-"Fatality"
names(ftlty)[names(ftlty)=="Fatalities"]<-"Total"
names(ftlty)[names(ftlty)=="PedFatalit"]<-"Ped"
names(ftlty)[names(ftlty)=="BikeFatali"]<-"Bike"
names(ftlty)[names(ftlty)=="MVOFatalit"]<-"MVO"
injry$Severity<-"Injury"
names(injry)[names(injry)=="Injuries"]<-"Total"
names(injry)[names(injry)=="PedInjurie"]<-"Ped"
names(injry)[names(injry)=="BikeInjuri"]<-"Bike"
names(injry)[names(injry)=="MVOInjurie"]<-"MVO"
names(injry);names(ftlty)
</pre>
<br/>
Now we can combine the two datasets to create one single dataset called acc.
<br/>
<pre class="brush:bash">
#Combine datasets
acc<- rbind(ftlty, injry)
dim(acc);names(acc);head(acc)
</pre>
<br/>
We need to use the fortify command to make sure the coordinate information can be accessed by spatial functions.
<br/>
<pre class="brush:bash">
#Now fortify the accident data
acc.f<-fortify(as.data.frame(acc))
dim(acc.f);names(acc.f);head(acc.f)
</pre>
<br/>
We only want to plot 2015 data. The following command shows us how to filter only 2015 records from the data.
<br/>
<pre class="brush:bash">
#Subsetting only 2015 accident records
acc_2015<-acc.f[which(acc.f$YR==2015),]
</pre>
<br/>
Now we are ready to plot this on the map. The gvisMap function expects a single field with latitude and longitude information in lat:long format, that is separated by a colon. We don't need more than 4 digit precision so we will round the lat long information and use the paste command to concatenate everything into a single string.
<br/>
<pre class="brush:bash">
#Add a single column "LatLong" that is of the format lat:long for the accident location
acc_2015$LatLong<-paste(round(acc_2015$coords.x2,4),round(acc_2015$coords.x1,4),sep=":")
</pre>
<br/>
The gVisMap function also expects a data field which will be displayed as a map tip. We need to concatenate all available fields with html break symbol to create one single field that can pop up when we hover or click on the icon.
<br/>
<pre class="brush:bash">
#Add a single column "Tip" for Accident descriptions separated by html breaks ("<br/>")
acc_2015$Tip<-paste("Type: ",acc_2015$Severity,"Total: ",acc_2015$Total,"Ped: ",acc_2015$Ped,"Bike: ",acc_2015$Bike,"MVO: ",acc_2015$MVO,sep="<br/>")
head(acc_2015)
</pre>
<br/>
Finally, we call the gVisMap function passing the dataset, name of concatenated lat long column, name of the Map tip column and set several defaults for the Google map. Calling the plot function launches an embedded http server and launches the default browser on your machine to display the generated html page.
<br/>
<pre class="brush:bash">
#Plot 2015 accidents on Google
map1<-gvisMap(acc_2015, "LatLong", "Tip",
options=list(showTip=TRUE, showLine=F, enableScrollWheel=TRUE,
mapType='roads', useMapTypeControl=TRUE, width=800,height=1024))
plot(map1)
</pre>
<br />
That's it... We are done. Here is the output<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTk2zv2ZVYejxJWMijWzuZ_Deo3ORT1rwMqlZbEgaLcplT5TcnzWc4yjNl9P6e0_F84p-aJ2wPQsX9s9q7EOMdZTZtq0aFe7i5FxNiGqCQSw1zUepE5pkKul4zRrRn-DJ2sIziTb5TGkE/s1600/MapID252e3c5fbf9b+-+Google+Chrome_387.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="380" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTk2zv2ZVYejxJWMijWzuZ_Deo3ORT1rwMqlZbEgaLcplT5TcnzWc4yjNl9P6e0_F84p-aJ2wPQsX9s9q7EOMdZTZtq0aFe7i5FxNiGqCQSw1zUepE5pkKul4zRrRn-DJ2sIziTb5TGkE/s640/MapID252e3c5fbf9b+-+Google+Chrome_387.png" width="640" /></a></div>
<br />
Here is the complete source code
<br/>
<pre class="brush:bash"># Load the needed libraries
library(sp) # classes for spatial data
library(maptools)
library(rgeos) # and their dependencies
library(rgdal)
library(ggplot2)
library(ggmap)
library(scales)
library(gmodels)
library(googleVis)
# Set default paths for data
setwd("~/Work/Transportation/NYC/scripts")
shpfilepath="../data/shpfiles"
# Read injury and fatality statistics
ogrInfo(shpfilepath,"fatality_yearly")
ogrInfo(shpfilepath,"injury_yearly")
ftlty<-readOGR(shpfilepath, "fatality_yearly")
injry<-readOGR(shpfilepath, "injury_yearly")
names(ftlty); dim(ftlty)
names(injry); dim(injry)
#Classify severity and rename columns to be identical in fatalities and injury datasets
ftlty$Severity<-"Fatality"
names(ftlty)[names(ftlty)=="Fatalities"]<-"Total"
names(ftlty)[names(ftlty)=="PedFatalit"]<-"Ped"
names(ftlty)[names(ftlty)=="BikeFatali"]<-"Bike"
names(ftlty)[names(ftlty)=="MVOFatalit"]<-"MVO"
injry$Severity<-"Injury"
names(injry)[names(injry)=="Injuries"]<-"Total"
names(injry)[names(injry)=="PedInjurie"]<-"Ped"
names(injry)[names(injry)=="BikeInjuri"]<-"Bike"
names(injry)[names(injry)=="MVOInjurie"]<-"MVO"
names(injry);names(ftlty)
#Combine datasets
acc<- rbind(ftlty, injry)
dim(acc);names(acc);head(acc)
#Now fortify the accident data
acc.f<-fortify(as.data.frame(acc))
dim(acc.f);names(acc.f);head(acc.f)
#Subsetting only 2015 accident records
acc_2015<-acc.f[which(acc.f$YR==2015),]
#Add a single column "LatLong" that is of the format lat:long for the accident location
acc_2015$LatLong<-paste(round(acc_2015$coords.x2,4),round(acc_2015$coords.x1,4),sep=":")
#Add a single column "Tip" for Accident descriptions separated by html breaks ("<br/>")
acc_2015$Tip<-paste("Type: ",acc_2015$Severity,"Total: ",acc_2015$Total,"Ped: ",acc_2015$Ped,"Bike: ",acc_2015$Bike,"MVO: ",acc_2015$MVO,sep="<br/>")
head(acc_2015)
#Plot 2015 accidents on Google
map1<-gvisMap(acc_2015, "LatLong", "Tip",
options=list(showTip=TRUE, showLine=F, enableScrollWheel=TRUE,
mapType='roads', useMapTypeControl=TRUE, width=800,height=1024))
plot(map1)
</pre>awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-21863602671096512112015-08-25T04:10:00.002-07:002015-08-25T04:10:10.695-07:00Steps for installing dismo in RSteps for installing dismo in your R distribution are fairly straight forward.<br />
<br />
First login to R using sudo, so your package can be installed to the shared repository<br />
<br />
<pre class="brush:bash">sudo R
</pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMgKFD4PEtHLGcHQEuRX8T4qt1V4tkuJTQh9i6J-y-EWDOh80RVgWaxhEQg2QsDmQSeqIkq59W4XDxy7Y8qLjlFSX6gOFWoWV50bBJQb6tVgW4krf3HZzX4euGsV4ppdWx7pUt7oJDWiQ/s1600/arthgallo%2540ub1204%253A+%257E_361.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMgKFD4PEtHLGcHQEuRX8T4qt1V4tkuJTQh9i6J-y-EWDOh80RVgWaxhEQg2QsDmQSeqIkq59W4XDxy7Y8qLjlFSX6gOFWoWV50bBJQb6tVgW4krf3HZzX4euGsV4ppdWx7pUt7oJDWiQ/s640/arthgallo%2540ub1204%253A+%257E_361.png" width="640" /></a></div>
<br />
<br />
Next, enter the following command in R prompt<br />
<br />
<pre class="brush:bash">install.packages("dismo")
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRnCV1hVg-Uo1XVLu9EcKvH7Uxhf065oa03tgibM86vAkZ0TlKiUeXsTf-CKTx3ss3X-lb2lHs28fFAAG40OzGAAaGRaT6bbmB0hj3nywfc2vQNxy_xlr3Hi56rG6oQZojkocfPk0TP4Y/s1600/arthgallo%2540ub1204%253A+%257E_382.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRnCV1hVg-Uo1XVLu9EcKvH7Uxhf065oa03tgibM86vAkZ0TlKiUeXsTf-CKTx3ss3X-lb2lHs28fFAAG40OzGAAaGRaT6bbmB0hj3nywfc2vQNxy_xlr3Hi56rG6oQZojkocfPk0TP4Y/s640/arthgallo%2540ub1204%253A+%257E_382.png" width="640" /></a></div>
<br />
<br />
By default, R prompts for https mirrors. For some reason, https mirrors gave me errors. For this reason select the option for HTTP mirrors at the bottom of the list, as shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNbxz944YOP46aYFMT_5Ua_Iwt4ZbBm2V1C7yMdd92fyBND1Ord47QPRRgXsLK12mP1A6t4KIru74bDc95H7i8ufLRu2fHASL8GmUtg7NRhxtBCMG-M_l50PqfW9AUrYXaY_OhUEGYUg0/s1600/HTTPS+CRAN+mirror_364.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNbxz944YOP46aYFMT_5Ua_Iwt4ZbBm2V1C7yMdd92fyBND1Ord47QPRRgXsLK12mP1A6t4KIru74bDc95H7i8ufLRu2fHASL8GmUtg7NRhxtBCMG-M_l50PqfW9AUrYXaY_OhUEGYUg0/s320/HTTPS+CRAN+mirror_364.png" width="148" /></a></div>
<br />
Next, choose your preferred mirror from the list of http mirrors, as shown below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNGJq73MlobBje27H87Asn6amvYvMTCDAJKvPTBDz_wBNk-6eftoZZoJlURcW79GPdC93bqzafwAyBs0_PWl-GHOjbKZeGbvLmRkl3IOgFGowNzmTogk4r0_gtcmrkmcqJVKGIqzcw0mo/s1600/HTTP+CRAN+mirror_365.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNGJq73MlobBje27H87Asn6amvYvMTCDAJKvPTBDz_wBNk-6eftoZZoJlURcW79GPdC93bqzafwAyBs0_PWl-GHOjbKZeGbvLmRkl3IOgFGowNzmTogk4r0_gtcmrkmcqJVKGIqzcw0mo/s640/HTTP+CRAN+mirror_365.png" width="152" /></a></div>
<br />
Click OK to install. R will download the packages and install as neccessary.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxQsiN_BnCPYZFWHG6o0W6Hp0pB67ya6kt7hmMUXlXBhc_P-FEnG5xsE-88kmit5qj2mFi2407vvPjcyHpOYXLcNsc2zTpL9OEWPG3F9OWao0sGG_GUnkiczbqexDZGkRorAeoSkxOjT8/s1600/arthgallo%2540ub1204%253A+%257E_385.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxQsiN_BnCPYZFWHG6o0W6Hp0pB67ya6kt7hmMUXlXBhc_P-FEnG5xsE-88kmit5qj2mFi2407vvPjcyHpOYXLcNsc2zTpL9OEWPG3F9OWao0sGG_GUnkiczbqexDZGkRorAeoSkxOjT8/s640/arthgallo%2540ub1204%253A+%257E_385.png" width="640" /></a></div>
<br />
<br />
Once the installation, has finished load the library using the following command and we are good to go.<br />
<br />
<pre class="brush:bash">library(dismo)
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ4jJFIjmNB6D6eTpFWyTwX3dghZthQZK3s-23ZIst1aNQxziaWvxlsTFPzZfDxpFKSi27CIkdyYU1E9Gt9HoAMu0ghrIvYDDlh3IqW9r94ZgbZB76SLZaHdRxAXnezWGfI377O0MGji8/s1600/arthgallo%2540ub1204%253A+%257E_386.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ4jJFIjmNB6D6eTpFWyTwX3dghZthQZK3s-23ZIst1aNQxziaWvxlsTFPzZfDxpFKSi27CIkdyYU1E9Gt9HoAMu0ghrIvYDDlh3IqW9r94ZgbZB76SLZaHdRxAXnezWGfI377O0MGji8/s640/arthgallo%2540ub1204%253A+%257E_386.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
That's it...<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-77679493758028387482015-08-22T08:44:00.003-07:002015-08-22T08:49:36.695-07:00Performing Spatial Overlay and CrossTab in RIn this post, we will look at spatial overlay in R using a simple example.<br />
<br />
Here are the results we will produce<br />
<br />
<table>
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2n9wca8tcho5_GPW6qPV41lTIV2fZ1R-T3BZeljdZVF_wqngJQ1jB813FYViYZ5ZlPbfPNID9Dz9IW1L_FChu5t_kLDsoqKCJiLtjYLREXgisivHqseXZ2Wvsa1zhv1y9GIHP5uKbJMA/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_376.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2n9wca8tcho5_GPW6qPV41lTIV2fZ1R-T3BZeljdZVF_wqngJQ1jB813FYViYZ5ZlPbfPNID9Dz9IW1L_FChu5t_kLDsoqKCJiLtjYLREXgisivHqseXZ2Wvsa1zhv1y9GIHP5uKbJMA/s320/R+Graphics%253A+Device+2+%2528ACTIVE%2529_376.png" width="307" /></a></div>
</td>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9p7e_TswHtgT7WdKovjStP0CkJ0dnhnmm7o53IpJyo9BRSCBiXuCZ2heCU6D6yhuyvoLvNbm4_d0mj03qpVfo9YesowIZDz2_aJOVfqtcnPmwpzAbQQTyTmDsMcDzFZVWhI39YkAWogQ/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_381.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9p7e_TswHtgT7WdKovjStP0CkJ0dnhnmm7o53IpJyo9BRSCBiXuCZ2heCU6D6yhuyvoLvNbm4_d0mj03qpVfo9YesowIZDz2_aJOVfqtcnPmwpzAbQQTyTmDsMcDzFZVWhI39YkAWogQ/s400/R+Graphics%253A+Device+2+%2528ACTIVE%2529_381.png" width="307" /></a></div>
</td>
</tr>
</tbody></table>
<br />
<br />
In previous posts, we had seen <a href="http://opendesignarch.blogspot.com/2015/08/building-multi-layer-map-in-r-using.html">how to render multiple layers in R using ggplot2</a>. This post will use the same dataset but for a different purpose.<br />
<br />
First step is to download the data. This previous post shows <a href="http://opendesignarch.blogspot.com/2015/08/obtaining-nyc-pedestrian-safety-data.html">how to obtain the spatial data</a> used in this example from the NYC website.<br />
<br />
Launch R in a terminal and load the required libraries. I have posted in previous posts on how to install these libraries. This post describes <a href="http://opendesignarch.blogspot.com/2015/08/reading-shape-files-in-r.html">rgdal and associated packages' installation</a>. This post describes <a href="http://opendesignarch.blogspot.com/2015/08/installing-gmodels-library-in-r.html">gmodels package installation</a>.<br />
<br />
<br />
<pre class="brush:bash"># Load required libraries
library(rgdal)
library(ggplot2)
library(ggmap)
library(rgeos)
library(maptools)
library(scales)
library(gmodels)
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr0mpHz3MmNQ3jh7jT6hO_Qjwq4QWNtM82E9Rjdf7BqCWo3Z4L5Ceje21NALcSRGY2Inm-zANnhwkGJ9hrdAChdSjDOTVedP0BSOvnkDp532u9Ggl-NJka1z7YDVaCzaRePmepj-jp3r4/s1600/arthgallo%2540ub1204%253A+%257E_368.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr0mpHz3MmNQ3jh7jT6hO_Qjwq4QWNtM82E9Rjdf7BqCWo3Z4L5Ceje21NALcSRGY2Inm-zANnhwkGJ9hrdAChdSjDOTVedP0BSOvnkDp532u9Ggl-NJka1z7YDVaCzaRePmepj-jp3r4/s640/arthgallo%2540ub1204%253A+%257E_368.png" width="640" /></a></div>
<br />
Next we set the default paths for the data. Please modify this accordingly for your environment<br />
<br />
<pre class="brush:bash"># Set default paths for data
setwd("~/Work/Transportation/NYC/scripts")
shpfilepath="../data/shpfiles"
</pre>
<br />
Now we can read the shapefiles into our workspace memory for analysis<br />
<br />
<pre class="brush:bash"># Read injury and fatality statistics
ogrInfo(shpfilepath,"fatality_yearly")
ogrInfo(shpfilepath,"injury_yearly")
ftlty_yr<-readOGR(shpfilepath, "fatality_yearly")
injry_yr<-readOGR(shpfilepath, "injury_yearly")
names(ftlty_yr); dim(ftlty_yr)
names(injry_yr); dim(injry_yr)
</pre>
<br />
Successful reading will show the following results.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFjzBrr5icN9DnFJkHUTiw_fd6tiESpYZ33HqSbeku6Pj1LXVySkYEufI_PFuU2XnFpnsMAxXHKppsnQYAyCNszLrPlurligZqb2IMnr7BSl9aSCnSr8hexy1PSSlYNezBCa3vMpHCjr8/s1600/arthgallo%2540ub1204%253A+%257E_369.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFjzBrr5icN9DnFJkHUTiw_fd6tiESpYZ33HqSbeku6Pj1LXVySkYEufI_PFuU2XnFpnsMAxXHKppsnQYAyCNszLrPlurligZqb2IMnr7BSl9aSCnSr8hexy1PSSlYNezBCa3vMpHCjr8/s640/arthgallo%2540ub1204%253A+%257E_369.png" width="640" /></a></div>
<br />
As we can see from the names description, the data does not have any spatial information attached. We need to use the fortify command to attach the spatial coordinates to the data we have.<br />
<br />
<pre class="brush:bash"># Add the spatial data to the data frame
ftlty.f <-fortify(as.data.frame(ftlty_yr))
names(ftlty.f);dim(ftlty.f)
</pre>
<pre class="brush:bash"></pre>
Using the fortify command attaches the spatial data to our previous structure as can be seen in the console output.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjajOnT7ddeVDZTFV4nyUpwx-8xGjhc3DAyB8l8i0Kc1Xa6bBLG4jJNdpSyoVS4MmI6rNd-nqx5vmW3amInsfDWxs9USQJ471X6P5GRB-sjh6xdsEz9NF54bBAfGwFOq9T0RnRJG8shocA/s1600/arthgallo%2540ub1204%253A+%257E_370.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjajOnT7ddeVDZTFV4nyUpwx-8xGjhc3DAyB8l8i0Kc1Xa6bBLG4jJNdpSyoVS4MmI6rNd-nqx5vmW3amInsfDWxs9USQJ471X6P5GRB-sjh6xdsEz9NF54bBAfGwFOq9T0RnRJG8shocA/s640/arthgallo%2540ub1204%253A+%257E_370.png" width="640" /></a></div>
<br />
<br />
Next we look at the New York City Borough boundaries that we need to use.<br />
<br />
<pre class="brush:bash">#Load boroughs data
ogrInfo(shpfilepath,"nybbwi")
bbnd <- readOGR(shpfilepath,"nybbwi")
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGvSbMTvQ1CFZistaALcFKkGCzlwpNiAnqNz0pqo8-WBNjQCWn01DaR5uKNzIL0JGGJrngPNKSPUZ4Fuu97qxuUuU6dwG6TbOAX1riLvTy2_TXDny0Nz_12dwUAsjLVYI0E75OhNqDuDI/s1600/arthgallo%2540ub1204%253A+%257E_371.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGvSbMTvQ1CFZistaALcFKkGCzlwpNiAnqNz0pqo8-WBNjQCWn01DaR5uKNzIL0JGGJrngPNKSPUZ4Fuu97qxuUuU6dwG6TbOAX1riLvTy2_TXDny0Nz_12dwUAsjLVYI0E75OhNqDuDI/s640/arthgallo%2540ub1204%253A+%257E_371.png" width="640" /></a></div>
<br />
As we can see the borough layer has lambert conformal conic coordinate reference system, which means that the fatality data and boundaries will not coincide. We will use the spTransform function to transform the boundaries from lambert conformal to lat long.<br />
<br />
<pre class="brush:bash">#Transform the coordinates from Lambert Conformal to Lat Long
CRS.latlong<-CRS("+proj=longlat +datum=WGS84 +no_defs")
bbnd<-spTransform(bbnd, CRS.latlong)
summary(bbnd)</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheisZ2_PN0-kbF5MnyTKDqh0LHm1uxBCWKonO_D-3DwPwYLtdZpewjO1g0Hp8KQVzlae90p3vepd7yXbMEsV4NuObHP4HaDlyMKkY5iEysxJFgfRyXShIAY5Hg-W4oYKRVBqFR9Ue6wXg/s1600/arthgallo%2540ub1204%253A+%257E_372.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheisZ2_PN0-kbF5MnyTKDqh0LHm1uxBCWKonO_D-3DwPwYLtdZpewjO1g0Hp8KQVzlae90p3vepd7yXbMEsV4NuObHP4HaDlyMKkY5iEysxJFgfRyXShIAY5Hg-W4oYKRVBqFR9Ue6wXg/s640/arthgallo%2540ub1204%253A+%257E_372.png" width="640" /></a></div>
<br />
As we can see the data has been transformed. We need to also fortify the boundary data to attach the spatial information.<br />
<br />
<pre class="brush:bash"># Add the spatial data back to the boundary data.frame
bbnd.f <-fortify(bbnd, region="BoroCode")
names(bbnd.f);head(bbnd.f);dim(bbnd.f)
</pre>
<pre class="brush:bash"></pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEkJlEY95LC5Dbr9hYEbi3Bw3AcDOC66sJo3RbELza6h9D8T8PxjOl62pxx_E9tpWU1B5ZXwjmPq7V-yaz2q72BifHcVwDkHkqPv2fuCje8zQPGFWWOUw5zeI6933rfKFgq57SvxOv5qs/s1600/arthgallo%2540ub1204%253A+%257E_373.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEkJlEY95LC5Dbr9hYEbi3Bw3AcDOC66sJo3RbELza6h9D8T8PxjOl62pxx_E9tpWU1B5ZXwjmPq7V-yaz2q72BifHcVwDkHkqPv2fuCje8zQPGFWWOUw5zeI6933rfKFgq57SvxOv5qs/s640/arthgallo%2540ub1204%253A+%257E_373.png" width="640" /></a></div>
<br />
Now that we have the geometric information attached, the number of rows increases to include each part of each geometric record. We need to re-attach the attribute information for each geometric part, using the merge command.<br />
<br />
<pre class="brush:bash"># Combine the geometry and data back together using common keys
bbnd.f<-merge(bbnd.f,bbnd@data, by.x="id", by.y="BoroCode")
names(bbnd.f);head(bbnd.f);dim(bbnd.f)
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibqy1P5OCF2UVqw3NSvKM2HzrzOKTRI2ufSZrwwg5xmqA5lBB73W5syzZjV7bCREy6eVYFc1kWWbdEgYKeE3WPvUxHDfjbuWVZmvTEHvcQus3JcnAg5-b7PNa_j-BEt1wfDWDltPbiAjU/s1600/arthgallo%2540ub1204%253A+%257E_374.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibqy1P5OCF2UVqw3NSvKM2HzrzOKTRI2ufSZrwwg5xmqA5lBB73W5syzZjV7bCREy6eVYFc1kWWbdEgYKeE3WPvUxHDfjbuWVZmvTEHvcQus3JcnAg5-b7PNa_j-BEt1wfDWDltPbiAjU/s640/arthgallo%2540ub1204%253A+%257E_374.png" width="640" /></a></div>
<br />
As we can see the information has been attached, and now we have 7+3 = 10 columns of data for the polygon dataset. Now the overlay. We will attach each fatality record the borough it falls in. The over() function allows that. We will also take this information and add it to two new variables in the ftlty.f data frame. R will take care of altering the structure of the table to accommodate the new data points.<br />
<br />
<pre class="brush:bash">#Code each record in fatality with the borough it falls under and add to new variable
ftlty.f$BoroCode <-as.data.frame(over(ftlty_yr, bbnd))$BoroCode
ftlty.f$BoroName <-as.data.frame(over(ftlty_yr, bbnd))$BoroName
names(ftlty.f);head(ftlty.f);dim(ftlty.f)
</pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgocOfd6FvUJn7_0UMxlTQtBkpRld4fpE1HBMy7p4IN8ffn1hQAa7dNY-b_9zi_5XvpEY4QQvToWRZYZNk44VXLMg3S_h4UIj_nswAiMECwIg4Y5xYP7nh1Y5grNa56e8LWXTr50IMIHV4/s1600/arthgallo%2540ub1204%253A+%257E_375.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgocOfd6FvUJn7_0UMxlTQtBkpRld4fpE1HBMy7p4IN8ffn1hQAa7dNY-b_9zi_5XvpEY4QQvToWRZYZNk44VXLMg3S_h4UIj_nswAiMECwIg4Y5xYP7nh1Y5grNa56e8LWXTr50IMIHV4/s640/arthgallo%2540ub1204%253A+%257E_375.png" width="640" /></a></div>
<br />
As we can see new information has been attached. Each accident record has been coded with the borough it falls in. We can infact use the following code to plot it to a map.<br />
<br />
<pre class="brush:bash">#Plot accidents coded by the borough they fall in
fx<-ftlty.f$coords.x1
fy<-ftlty.f$coords.x2
Map <- ggplot(data=ftlty.f, aes(fx,fy,colour=factor(BoroCode)))
Map <- Map + layer(geom="point")
Map
</pre>
<br />
The following map is generated<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhv55POXyWO-juFgA7dHIkDqw48cjPFf-xf-1tC5vGcsTx3WQLfUTJcDBAQk7tx2Qmrdzwtys781cMEGqgga6cs9tkWL6sfGF66Rfg0EqJgPJDrYIfxJVKEc3m5-kclYnD2PfYNaK8_OcY/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_376.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhv55POXyWO-juFgA7dHIkDqw48cjPFf-xf-1tC5vGcsTx3WQLfUTJcDBAQk7tx2Qmrdzwtys781cMEGqgga6cs9tkWL6sfGF66Rfg0EqJgPJDrYIfxJVKEc3m5-kclYnD2PfYNaK8_OcY/s640/R+Graphics%253A+Device+2+%2528ACTIVE%2529_376.png" width="614" /></a></div>
<br />
Next we will use the CrossTable function to look at number of accidents that involved one or more fatalities<br />
<div class="" style="clear: both; text-align: left;">
We can instead also build a table to summarize fatalities by borough and year.</div>
<br />
<pre class="brush:bash">#Build a cross table for Borough name and Year with count of fatal incidents
ftlctab<-CrossTable(ftlty.f$BoroName,ftlty.f$YR,expected=FALSE)
ftlctab$t
</pre>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh5Ex8Ie9nCXXDq-VEe_zI6cbrUdInNv3ZzVHqaWe2mefyyuUzmNdhG08luIHDaAug835W9-lOL84he-YSh6expJdjcC518bGGAjiQyPMC6480n7spVNwFa0-rKrvTbnhgnOeSpYGdb_M/s1600/arthgallo%2540ub1204%253A+%257E_377.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh5Ex8Ie9nCXXDq-VEe_zI6cbrUdInNv3ZzVHqaWe2mefyyuUzmNdhG08luIHDaAug835W9-lOL84he-YSh6expJdjcC518bGGAjiQyPMC6480n7spVNwFa0-rKrvTbnhgnOeSpYGdb_M/s640/arthgallo%2540ub1204%253A+%257E_377.png" width="640" /></a>We can also build a cross table to look at number of fatalities using the xtabs function.<br />
<br />
<pre class="brush:bash">#Build a cross table for Borough name and Year with fatalities
ftlctab2<-xtabs(ftlty.f$Fatalities ~ ftlty.f$BoroName+ftlty.f$YR,ftlty.f)
ftlctab2
</pre>
<br/>
We can actually compare the results in the output above to see the differences.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy93n0uuWjnL08GKafeJWLsIHbq2k3kuC6fDrdAd_ZQmO8AjFUFPmYZE9yoDWQCFbmXRBCUt2wvWAf1DnleELTrkKce1-aSoX5eet7trTlV9K9b-tORqvFoGxS1Lg-AAvdKZB1uTwapEs/s1600/arthgallo%2540ub1204%253A+%257E_378.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy93n0uuWjnL08GKafeJWLsIHbq2k3kuC6fDrdAd_ZQmO8AjFUFPmYZE9yoDWQCFbmXRBCUt2wvWAf1DnleELTrkKce1-aSoX5eet7trTlV9K9b-tORqvFoGxS1Lg-AAvdKZB1uTwapEs/s640/arthgallo%2540ub1204%253A+%257E_378.png" width="640" /></a></div>
<br />
We can also plot the above in barplots using the barplot command.<br />
<br />
<pre class="brush:bash">#Plot this on a barplot to see the trends for Incidents with fatalities
barplot(ftlctab$t
,col=c("red","orange","yellow","green","blue", "darkblue","grey")
,names.arg=levels(ftlty.f$YR)
,legend=rownames(ftlty.f$BoroName)
)
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBcz5QBqNxB_NluG0-CN7sPqPzleESyobAzcPA41aZjJhNs6auvPRtM4eB_QtCtGbGRrPoZslFWhag5dScprM2FR3MzlsE3IE9USiRMz45s9chENQTI9dJeNe2BNmumlGGzd2euVYaKSo/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_379.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBcz5QBqNxB_NluG0-CN7sPqPzleESyobAzcPA41aZjJhNs6auvPRtM4eB_QtCtGbGRrPoZslFWhag5dScprM2FR3MzlsE3IE9USiRMz45s9chENQTI9dJeNe2BNmumlGGzd2euVYaKSo/s640/R+Graphics%253A+Device+2+%2528ACTIVE%2529_379.png" width="614" /></a></div>
<br />
Now we could also plot the sum of fatalities instead of fatal incidents by using the ftlctab2 variable instead.<br />
<br />
<pre class="brush:bash">#Plot this on a barplot to see the trends for Fatalities
barplot(ftlctab2
,col=c("red","orange","yellow","green","blue", "darkblue","grey")
,names.arg=levels(ftlty.f$YR)
,legend=levels(ftlty.f$BoroName)
)
</pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5iqR46ttAwPQm6CIRKIZeeFnotqoA1IEi3bgPET1eaUIvyYxPCU-qulL9bSewEjgx4eVgljSNGw0ThwRTQRgcqTZ6DHKAlrYMnSE4HQ_BLZXeL9Mm-g2LEN1MhKRPqltby2vkUC-yWGY/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_381.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5iqR46ttAwPQm6CIRKIZeeFnotqoA1IEi3bgPET1eaUIvyYxPCU-qulL9bSewEjgx4eVgljSNGw0ThwRTQRgcqTZ6DHKAlrYMnSE4HQ_BLZXeL9Mm-g2LEN1MhKRPqltby2vkUC-yWGY/s640/R+Graphics%253A+Device+2+%2528ACTIVE%2529_381.png" width="614" /></a></div>
<br />
<br />
That's it. Here is the complete source code
<br />
<br />
<pre class="brush:bash"># Load required libraries
library(rgdal)
library(ggplot2)
library(ggmap)
library(rgeos)
library(maptools)
library(scales)
library(gmodels)
# Set default paths for data
setwd("~/Work/Transportation/NYC/scripts")
shpfilepath="../data/shpfiles"
# Read injury and fatality statistics
ogrInfo(shpfilepath,"fatality_yearly")
ogrInfo(shpfilepath,"injury_yearly")
ftlty_yr<-readOGR(shpfilepath, "fatality_yearly")
injry_yr<-readOGR(shpfilepath, "injury_yearly")
names(ftlty_yr); dim(ftlty_yr)
names(injry_yr); dim(injry_yr)
# Add the spatial data to the data frame
ftlty.f <-fortify(as.data.frame(ftlty_yr))
names(ftlty.f);dim(ftlty.f)
#Load boroughs data
ogrInfo(shpfilepath,"nybbwi")
bbnd <- readOGR(shpfilepath,"nybbwi")
#Transform the coordinates from Lambert Conformal to Lat Long
CRS.latlong<-CRS("+proj=longlat +datum=WGS84 +no_defs")
bbnd<-spTransform(bbnd, CRS.latlong)
# Add the spatial data back to the boundary data.frame
bbnd.f <-fortify(bbnd, region="BoroCode")
names(bbnd.f);head(bbnd.f);dim(bbnd.f)
# Combine the geometry and data back together using common keys
bbnd.f<-merge(bbnd.f,bbnd@data, by.x="id", by.y="BoroCode")
names(bbnd.f);head(bbnd.f);dim(bbnd.f)
#Code each record in fatality with the borough it falls under and add to new variable
ftlty.f$BoroCode <-as.data.frame(over(ftlty_yr, bbnd))$BoroCode
ftlty.f$BoroName <-as.data.frame(over(ftlty_yr, bbnd))$BoroName
names(ftlty.f);head(ftlty.f);dim(ftlty.f)
#Plot accidents coded by the borough they fall in
fx<-ftlty.f$coords.x1
fy<-ftlty.f$coords.x2
Map <- ggplot(data=ftlty.f, aes(fx,fy,colour=factor(BoroCode)))
Map <- Map + layer(geom="point")
Map
#Build a cross table for Borough name and Year with count of fatal incidents
ftlctab<-CrossTable(ftlty.f$BoroName,ftlty.f$YR,expected=FALSE)
ftlctab$t
#Build a cross table for Borough name and Year with fatalities
ftlctab2<-xtabs(ftlty.f$Fatalities ~ ftlty.f$BoroName+ftlty.f$YR,ftlty.f)
ftlctab2
#Plot this on a barplot to see the trends for Incidents with fatalities
barplot(ftlctab$t
,col=c("red","orange","yellow","green","blue", "darkblue","grey")
,names.arg=levels(ftlty.f$YR)
,legend=rownames(ftlty.f$BoroName)
)
#Plot this on a barplot to see the trends for Fatalities
barplot(ftlctab2
,col=c("red","orange","yellow","green","blue", "darkblue","grey")
,names.arg=levels(ftlty.f$YR)
,legend=levels(ftlty.f$BoroName)
)
</pre>awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-53786785521371638772015-08-22T04:26:00.002-07:002015-08-22T04:28:46.175-07:00Installing gmodels library in RSteps for installing gmodels in your R distribution are fairly straight forward.<br />
<br />
First login to R using sudo, so your package can be installed to the shared repository<br />
<br />
<pre class="brush:bash">
sudo R
</pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMgKFD4PEtHLGcHQEuRX8T4qt1V4tkuJTQh9i6J-y-EWDOh80RVgWaxhEQg2QsDmQSeqIkq59W4XDxy7Y8qLjlFSX6gOFWoWV50bBJQb6tVgW4krf3HZzX4euGsV4ppdWx7pUt7oJDWiQ/s1600/arthgallo%2540ub1204%253A+%257E_361.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMgKFD4PEtHLGcHQEuRX8T4qt1V4tkuJTQh9i6J-y-EWDOh80RVgWaxhEQg2QsDmQSeqIkq59W4XDxy7Y8qLjlFSX6gOFWoWV50bBJQb6tVgW4krf3HZzX4euGsV4ppdWx7pUt7oJDWiQ/s640/arthgallo%2540ub1204%253A+%257E_361.png" width="640" /></a></div>
<br />
<br />
Next, enter the following command in R prompt<br />
<br />
<pre class="brush:bash">
install.packages("gmodels")
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt5_k_wHVVXfmAxTzlNCn1iKfHTfSQDDIzC1sg0bFSSW6eq-pXwOhUSgoMx303j9-Y4yqC1WpZCwYhwflsjDIHFMToKjBndbwUtRZBngIo-iBxfselDX4LBlvoB2W95M3H4pDiFNuvSjk/s1600/arthgallo%2540ub1204%253A+%257E_362.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt5_k_wHVVXfmAxTzlNCn1iKfHTfSQDDIzC1sg0bFSSW6eq-pXwOhUSgoMx303j9-Y4yqC1WpZCwYhwflsjDIHFMToKjBndbwUtRZBngIo-iBxfselDX4LBlvoB2W95M3H4pDiFNuvSjk/s640/arthgallo%2540ub1204%253A+%257E_362.png" width="640" /></a></div>
<br />
<br />
By default, R prompts for https mirrors. For some reason, https mirrors gave me errors. For this reason select the option for HTTP mirrors at the bottom of the list, as shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNbxz944YOP46aYFMT_5Ua_Iwt4ZbBm2V1C7yMdd92fyBND1Ord47QPRRgXsLK12mP1A6t4KIru74bDc95H7i8ufLRu2fHASL8GmUtg7NRhxtBCMG-M_l50PqfW9AUrYXaY_OhUEGYUg0/s1600/HTTPS+CRAN+mirror_364.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNbxz944YOP46aYFMT_5Ua_Iwt4ZbBm2V1C7yMdd92fyBND1Ord47QPRRgXsLK12mP1A6t4KIru74bDc95H7i8ufLRu2fHASL8GmUtg7NRhxtBCMG-M_l50PqfW9AUrYXaY_OhUEGYUg0/s320/HTTPS+CRAN+mirror_364.png" width="148" /></a></div>
<br />
Next, choose your preferred mirror from the list of http mirrors, as shown below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNGJq73MlobBje27H87Asn6amvYvMTCDAJKvPTBDz_wBNk-6eftoZZoJlURcW79GPdC93bqzafwAyBs0_PWl-GHOjbKZeGbvLmRkl3IOgFGowNzmTogk4r0_gtcmrkmcqJVKGIqzcw0mo/s1600/HTTP+CRAN+mirror_365.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNGJq73MlobBje27H87Asn6amvYvMTCDAJKvPTBDz_wBNk-6eftoZZoJlURcW79GPdC93bqzafwAyBs0_PWl-GHOjbKZeGbvLmRkl3IOgFGowNzmTogk4r0_gtcmrkmcqJVKGIqzcw0mo/s640/HTTP+CRAN+mirror_365.png" width="152" /></a></div>
<br />
Click OK to install. R will download the packages and install as neccessary.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAN3XHhtIiL5h_UDWt8JuOZjAMBlNoomeBMhrdvkf4WStrvYmym5FixP179Tyf70SL46PgP1oT_q0j1TDdr1PAA_Z7XXg-cUHwB2lm-NZXeslPB4Phr2sdvKxwMqocZ-IDOgP_AGS9IVo/s1600/arthgallo%2540ub1204%253A+%257E_366.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAN3XHhtIiL5h_UDWt8JuOZjAMBlNoomeBMhrdvkf4WStrvYmym5FixP179Tyf70SL46PgP1oT_q0j1TDdr1PAA_Z7XXg-cUHwB2lm-NZXeslPB4Phr2sdvKxwMqocZ-IDOgP_AGS9IVo/s640/arthgallo%2540ub1204%253A+%257E_366.png" width="640" /></a></div>
<br />
<br />
Once the installation, has finished load the library using the following command and we are good to go.<br />
<br />
<pre class="brush:bash">
library(gmodels)
</pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwy-LJtrcidw-G8L5kAQ9zqlYpBtXv9bfwY3WttzNRT_jnNR7JoVEgw6kl_i7LMe962-X_okin9Ma0DB1OX_Tq0M9xVsRUo5pSbveClFRzmw5Qphtpkb2vub5pcufLg-Fx2aLN5ZLlYlk/s1600/arthgallo%2540ub1204%253A+%257E_367.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwy-LJtrcidw-G8L5kAQ9zqlYpBtXv9bfwY3WttzNRT_jnNR7JoVEgw6kl_i7LMe962-X_okin9Ma0DB1OX_Tq0M9xVsRUo5pSbveClFRzmw5Qphtpkb2vub5pcufLg-Fx2aLN5ZLlYlk/s640/arthgallo%2540ub1204%253A+%257E_367.png" width="640" /></a></div>
<br />
That's it...<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-69426922192752751142015-08-16T07:24:00.002-07:002015-08-16T07:37:38.397-07:00Building a multi-layer map in R using ggplot2 and spatial dataIn this post, we will render spatial point and polygon data on the same map (as separate layers). The finished sample is the following:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLn88sCyQY-NncmHo2yI3x2Zsr-u4WEaukDFw4y-y8mZI_YzNyRMDyd7b0kgTNRGtOzesgMUPSFCE_AMtaO3CQu1eEYRDWlDJEp_ozS8RjSxRM5BhfW7rga8abco49GGaUOQUQ-tyiroc/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_359.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLn88sCyQY-NncmHo2yI3x2Zsr-u4WEaukDFw4y-y8mZI_YzNyRMDyd7b0kgTNRGtOzesgMUPSFCE_AMtaO3CQu1eEYRDWlDJEp_ozS8RjSxRM5BhfW7rga8abco49GGaUOQUQ-tyiroc/s400/R+Graphics%253A+Device+2+%2528ACTIVE%2529_359.png" width="383" /></a></div>
<br />
<br />
This exercise involves using several libraries from R, as well as transforming data from one coordinate system to another. Here are the prerequisites<br />
<br />
1. Install required spatial libraries into R: Please <a href="http://opendesignarch.blogspot.com/2015/08/reading-shape-files-in-r.html">refer to this post</a>, on how to do so.<br />
2. Download spatial data for NYC pertaining to safety: Please<a href="http://opendesignarch.blogspot.com/2015/08/obtaining-nyc-pedestrian-safety-data.html"> refer to this post</a> on how to do so.<br />
<br />
So let's get started.<br />
<br />
First step is to load all the libraries<br />
<br />
<pre class="brush:bash"># Load required libraries
library(rgdal)
library(ggplot2)
library(ggmap)
library(rgeos)
library(maptools)
library(scales)
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSB7pUqaEfFFz0Sgj6urg3sndUkoVHfmLi8RM8PMsnt38x9bwsSCjCcPIKGXvz7VtwULKiGPvYiLsS09l1sd8pZg34mTI6g4CZZuo2kVVgIs-FCsDAwmDJkJ04RaLWKpydB_sw4XwXpNU/s1600/arthgallo%2540ub1204%253A+%257E_348.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSB7pUqaEfFFz0Sgj6urg3sndUkoVHfmLi8RM8PMsnt38x9bwsSCjCcPIKGXvz7VtwULKiGPvYiLsS09l1sd8pZg34mTI6g4CZZuo2kVVgIs-FCsDAwmDJkJ04RaLWKpydB_sw4XwXpNU/s640/arthgallo%2540ub1204%253A+%257E_348.png" width="640" /></a></div>
<br />
<br />
Each of the above have a specific function in the process.
Next step is to set the working directory for the data files. We use the setwd command for that and I have also set a variable for setting the shape file path.<br />
<br />
<pre class="brush:bash"># Set default paths for data
setwd("~/Work/Transportation/NYC/scripts")
shpfilepath="../data/shpfiles"
</pre>
<br />
Next we read the shape files that contain annual fatality and injury data as well as data on borough boundaries for New York
Let's start with the injury and fatality data. ogrInfo command provides high level summary of the data in each shape file.<br />
<br />
<pre class="brush:bash"># Read injury and fatality statistics
ogrInfo(shpfilepath,"fatality_yearly")
ogrInfo(shpfilepath,"injury_yearly")
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp6ab8eJgkVDZiEPAd0qrXyE69yMfME-owo_3IjuD-WvafwCSa4GLTcoZpyN_bbvjHhIwzuXcUx7b2wtrrxW-kIHdw4S73YDZqCX0UPq6LWTIGEGJYTKbx1AVTOrPl9gXgRn1pt8dssgk/s1600/arthgallo%2540ub1204%253A+%257E_349.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="508" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp6ab8eJgkVDZiEPAd0qrXyE69yMfME-owo_3IjuD-WvafwCSa4GLTcoZpyN_bbvjHhIwzuXcUx7b2wtrrxW-kIHdw4S73YDZqCX0UPq6LWTIGEGJYTKbx1AVTOrPl9gXgRn1pt8dssgk/s640/arthgallo%2540ub1204%253A+%257E_349.png" width="640" /></a></div>
<br />
Next, we read the shape file data into R and assign it to an R object variable.<br />
<br />
<pre class="brush:bash">ftlty_yr<-readOGR(shpfilepath, "fatality_yearly")
injry_yr<-readOGR(shpfilepath, "injury_yearly")
names(ftlty_yr); dim(ftlty_yr)
names(injry_yr); dim(injry_yr)
</pre>
<br />
At this point the geometric data is not bound to the data frame, as we can see.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0bpS6sLjHY3l1MsLVpyL2h6C5CEoKkOwtCko2AXh_plfVKgA_LQoKxS_iFjLJc4KjeEdXQUAX-QgA-JjaF4TbxukXo0OL70meflOLalnJ8n54FH-02NfPFVO2RsCDH3Vu2i2-zBjc93w/s1600/arthgallo%2540ub1204%253A+%257E_350.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="508" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0bpS6sLjHY3l1MsLVpyL2h6C5CEoKkOwtCko2AXh_plfVKgA_LQoKxS_iFjLJc4KjeEdXQUAX-QgA-JjaF4TbxukXo0OL70meflOLalnJ8n54FH-02NfPFVO2RsCDH3Vu2i2-zBjc93w/s640/arthgallo%2540ub1204%253A+%257E_350.png" width="640" /></a></div>
<br />
Also, lets create our first graph with ggplot. We read the data frame from the fatalities data. As we can see there is no geometry for us to plot at this point, so we will simply plot Fatalities against the year. GGPlot2 library distinguishes between data, aesthetics, from the graph. In the first example, we simply add the data to the base layer and ask ggplot to render it as a point.<br />
<br />
<pre class="brush:bash"># Extract the data frame and use ggplot
ftldata<-ftlty_yr@data
names(ftldata)
p<-ggplot(ftlty_yr@data, aes(Fatalities, YR))
p + geom_point()
p
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfZMsoVj9v7HjoTvHd6NGorQE__76WLNsk2UWAcMfXPY4Uik4esX1nbOI0jYlgv4tat1tFNewJobWyVYfktz2cL37ghGbT_vZf25BVpuiHCCeN-Sit0rR_NzoxRxhyphenhyphenrrAgAQ0MXwETKj4/s1600/arthgallo%2540ub1204%253A+%257E_351.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfZMsoVj9v7HjoTvHd6NGorQE__76WLNsk2UWAcMfXPY4Uik4esX1nbOI0jYlgv4tat1tFNewJobWyVYfktz2cL37ghGbT_vZf25BVpuiHCCeN-Sit0rR_NzoxRxhyphenhyphenrrAgAQ0MXwETKj4/s640/arthgallo%2540ub1204%253A+%257E_351.png" /></a></div>
<br />
This is the graph that was plotted...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHxyQRH6PcCBG3nZosO5lzXFxEJTrRJvn4DyRYtQRjFf95MsCO2l2tzUjSKvF63eSRVazkZi5tIbZ5C4omPerAetnRB08GlcGCs8dhvvdXia6EmCLXnmgmLhItzrytydBhyphenhyphenPZjPommbLA/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_352.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHxyQRH6PcCBG3nZosO5lzXFxEJTrRJvn4DyRYtQRjFf95MsCO2l2tzUjSKvF63eSRVazkZi5tIbZ5C4omPerAetnRB08GlcGCs8dhvvdXia6EmCLXnmgmLhItzrytydBhyphenhyphenPZjPommbLA/s640/R+Graphics%253A+Device+2+%2528ACTIVE%2529_352.png" /></a></div>
<br />
This is our first attempt at understanding ggplot, but not what we wanted. The problem is that when we read the shapefile, the spatial data was not brought along.<br />
<br />
We need to use the fortify command to add the spatial data. In the following steps, we can see how to do that. Once we fortify the data, we can extract the x and y coordinates as well.<br />
<br />
<pre class="brush:bash">ftlty.f <-fortify(as.data.frame(ftlty_yr))
names(ftlty.f);dim(ftlty.f)
fx<-ftlty.f$coords.x1
fy<-ftlty.f$coords.x2
</pre>
<br />
Now, since we have the x and y, we can plot this data using ggplot<br />
<br />
<pre class="brush:bash"># Plotting the data using ggplot
Map <- ggplot(data=ftlty.f, aes(fx,fy,colour=factor(Fatalities)))
Map <- Map + layer(geom="point")
Map
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1ME37ehZn7ELhNdvuaUSyRVFBOJ62PfaLslX0PPm0wrqDuIpYhpR17p7wl29RVlTzTrfAJ_fFpc_cW3Jmd-1-N5lentdO5UF-vN3_LOaJrVP9euz5E3zyFm9SPk66uAZau4COOn5Xifk/s1600/arthgallo%2540ub1204%253A+%257E_353.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1ME37ehZn7ELhNdvuaUSyRVFBOJ62PfaLslX0PPm0wrqDuIpYhpR17p7wl29RVlTzTrfAJ_fFpc_cW3Jmd-1-N5lentdO5UF-vN3_LOaJrVP9euz5E3zyFm9SPk66uAZau4COOn5Xifk/s640/arthgallo%2540ub1204%253A+%257E_353.png" /></a></div>
<br />
Here is the plot output
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCheVaBQBQk0eRs2-HpyuxsWBY8JJYd1oZ4Dk-fZgYNpuE7q99FDlTinZ24TD5bOSyMjLHLRy4ktlI1i9Lg7ONR7qONkC-gsAM7P8fpunBHzhIMbI8lVxnpfm4S6g2pEsWQ7_DIYVCKlA/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_354.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCheVaBQBQk0eRs2-HpyuxsWBY8JJYd1oZ4Dk-fZgYNpuE7q99FDlTinZ24TD5bOSyMjLHLRy4ktlI1i9Lg7ONR7qONkC-gsAM7P8fpunBHzhIMbI8lVxnpfm4S6g2pEsWQ7_DIYVCKlA/s640/R+Graphics%253A+Device+2+%2528ACTIVE%2529_354.png" /></a></div>
<br />
<br />
Next step is to read the boroughs data. We use the familiar ogrInfo and readOGR functions to read the shapefile data into R<br />
<pre class="brush:bash">#Load boroughs data
ogrInfo(shpfilepath,"nybbwi")
bbnd <- readOGR(shpfilepath,"nybbwi")
</pre>
The Boroughs data is in a different coordinate system than the accident data. While the accident data is in latitude longitude, the borough data is in Lambert conformal conic coordinate system. If we want to have the two map layers sit on top of one another, we need to have them in the same coordinate system. We use the spTransform function to transform the borough boundaries to latlong, as shown below...<br />
<pre class="brush:bash">
#Transform the coordinates from Lambert Conformal to Lat Long
CRS.latlong<-CRS("+proj=longlat +datum=WGS84 +no_defs")
bbnd<-spTransform(bbnd, CRS.latlong)
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6-AQmgrhoVRfRCFDXiWfScH4jUzuxcuopfuDwau1v7oWl2zjj6NAtS8OVMSdOkeIUio1j_rtk7cCcjVDs5hdf8cTg5ssahf6W98LkUMXL_Vwr6qo_999lBKLmPO3i8-y140dP7KzTLHA/s1600/arthgallo%2540ub1204%253A+%257E_356.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="508" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6-AQmgrhoVRfRCFDXiWfScH4jUzuxcuopfuDwau1v7oWl2zjj6NAtS8OVMSdOkeIUio1j_rtk7cCcjVDs5hdf8cTg5ssahf6W98LkUMXL_Vwr6qo_999lBKLmPO3i8-y140dP7KzTLHA/s640/arthgallo%2540ub1204%253A+%257E_356.png" width="640" /></a></div>
<br />
In this case, again the spatial data and non-spatial data is not together. We need one dataset with both, so we need to fortify and merge the spatial and non-spatial datasets.<br />
<br />
<pre class="brush:bash"># Add the spatial data back to the boundary data.frame
bbnd.f <-fortify(bbnd, region="BoroCode")
names(bbnd.f);fix(bbnd.f);dim(bbnd.f)
# Combine the geometry and data back together using common keys
bbnd.f<-merge(bbnd.f,bbnd@data, by.x="id", by.y="BoroCode")
names(bbnd.f);dim(bbnd.f)
</pre>
<br />
As we can see in the following window, using fortify alone brought in the 7 geometric attributes and merge brought the total to 10 attributes with attributes from the data frame. So, we need both fortify and merge commands to bring in the geometry and associated non-spatial attributes such as area and length together.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTj2C8oyIOnmfbYLu4nofmW4zcsW_KQRm5zDUhfz2lPeyWwSc75QDCtp7KQWcB6fbitT-4PbrQ-AWppzQV39O0DGc0DyWzHVJGyPs9fLTalSBBy-06fk3xsWb1T69KkZwtMxnuNWdHDkk/s1600/arthgallo%2540ub1204%253A+%257E_357.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="508" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTj2C8oyIOnmfbYLu4nofmW4zcsW_KQRm5zDUhfz2lPeyWwSc75QDCtp7KQWcB6fbitT-4PbrQ-AWppzQV39O0DGc0DyWzHVJGyPs9fLTalSBBy-06fk3xsWb1T69KkZwtMxnuNWdHDkk/s640/arthgallo%2540ub1204%253A+%257E_357.png" width="640" /></a></div>
<br />
Next step is to build the map one layer at a time.<br />
<br />
<pre class="brush:bash"># Plot a map of the boroughs and accidents
baes <-aes(x=long, y=lat, group = group ,alpha=1/50,fill=id) # Aesthetics for Boroughs
bblyr <-geom_polygon(data=bbnd.f, baes) # Polygon layer for Bouroughs
faes <-aes(x=fx, y=fy, colour=factor(Fatalities)) # Aesthetics for Fatalities
flyr <-geom_point(data=ftlty.f,faes) # Point layer for Fatalities
Map <- ggplot() # Initialize the map
Map <-Map + bblyr # Add the boroughs layer
Map <-Map + flyr # Add the Fatalities layer
Map <- Map + labs(x = "Longitude", y = "Latitude", fill = "NYC Boroughs") # Add the labels
Map <- Map + ggtitle("NYC Boroughs with Accidents")
Map # Display the Map
</pre>
<br />
Here is the console output.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBwB8zqQnBVOO5T7Yt_PAIg1danwqfiFXFKFYYwfmZrDhcAsL-htCdCaTiUpmwRNGqM-hiZ2d1zWGofrni3uNeikCR6LbyTNNksbcHnUg0GssffbcXzZsn9K1wMVInfxHLQnXp5L4KLwI/s1600/arthgallo%2540ub1204%253A+%257E_358.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="508" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBwB8zqQnBVOO5T7Yt_PAIg1danwqfiFXFKFYYwfmZrDhcAsL-htCdCaTiUpmwRNGqM-hiZ2d1zWGofrni3uNeikCR6LbyTNNksbcHnUg0GssffbcXzZsn9K1wMVInfxHLQnXp5L4KLwI/s640/arthgallo%2540ub1204%253A+%257E_358.png" width="640" /></a></div>
<br />
Here is the map<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH9VnQcOiR4ReleeV8V6yLXcjs4fInt6KnxKjEWSX8EWWFJaNXCNxlII3Mj6BP98Fo9QGhzhQQtI-v5LEC657tJqR0Wo1AAaYVrCxbcB2BOLQNQBqmylpNMIdCnS0UKe8k2uiBXiRjoOk/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_359.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH9VnQcOiR4ReleeV8V6yLXcjs4fInt6KnxKjEWSX8EWWFJaNXCNxlII3Mj6BP98Fo9QGhzhQQtI-v5LEC657tJqR0Wo1AAaYVrCxbcB2BOLQNQBqmylpNMIdCnS0UKe8k2uiBXiRjoOk/s640/R+Graphics%253A+Device+2+%2528ACTIVE%2529_359.png" width="614" /></a></div>
<br />
That's it... For those who are interested, here is the complete source listing..<br />
<br />
<pre class="brush:bash"># Load required libraries
library(rgdal)
library(ggplot2)
library(ggmap)
library(rgeos)
library(maptools)
library(scales)
# Set default paths for data
setwd("~/Work/Transportation/NYC/scripts")
shpfilepath="../data/shpfiles"
# Read injury and fatality statistics
ogrInfo(shpfilepath,"fatality_yearly")
ogrInfo(shpfilepath,"injury_yearly")
ftlty_yr<-readOGR(shpfilepath, "fatality_yearly")
injry_yr<-readOGR(shpfilepath, "injury_yearly")
names(ftlty_yr); dim(ftlty_yr)
names(injry_yr); dim(injry_yr)
# Extract the data frame and use ggplot
ftldata<-ftlty_yr@data
names(ftldata)
p<-ggplot(ftlty_yr@data, aes(Fatalities, YR))
p + geom_point()
p
# Add the spatial data to the data frame
ftlty.f <-fortify(as.data.frame(ftlty_yr))
names(ftlty.f);dim(ftlty.f)
fx<-ftlty.f$coords.x1
fy<-ftlty.f$coords.x2
# Plotting the data using qplot
qplot(fx,fy,data=ftlty.f)
qplot(fx,fy,data=ftlty.f,colour=factor(Fatalities))
qplot(fx,fy, data=ftlty.f,colour=factor(Fatalities), facets= . ~ YR) + geom_point()
# Plotting the data using ggplot
Map <- ggplot(data=ftlty.f, aes(fx,fy,colour=factor(Fatalities)))
Map <- Map + layer(geom="point")
Map
#Load boroughs data
ogrInfo(shpfilepath,"nybbwi")
bbnd <- readOGR(shpfilepath,"nybbwi")
#Transform the coordinates from Lambert Conformal to Lat Long
CRS.latlong<-CRS("+proj=longlat +datum=WGS84 +no_defs")
bbnd<-spTransform(bbnd, CRS.latlong)
#Examine the data
bbndata <-bbnd@data
names(bbndata);fix(bbndata);dim(bbndata)
# Add the spatial data back to the boundary data.frame
bbnd.f <-fortify(bbnd, region="BoroCode")
names(bbnd.f);fix(bbnd.f);dim(bbnd.f)
# Combine the geometry and data back together using common keys
bbnd.f<-merge(bbnd.f,bbnd@data, by.x="id", by.y="BoroCode")
names(bbnd.f);dim(bbnd.f)
# Plot a map of the boroughs and accidents
baes<-aes(x=long, y=lat, group = group ,alpha=1/50,fill=id) # Aesthetics for Boroughs
bblyr<-geom_polygon(data=bbnd.f, baes) # Polygon layer for Bouroughs
faes<-aes(x=fx, y=fy, colour=factor(Fatalities)) # Aesthetics for Fatalities
flyr<-geom_point(data=ftlty.f,faes) # Point layer for Fatalities
Map <- ggplot() # Initialize the map
Map<-Map + bblyr # Add the boroughs layer
Map<-Map + flyr # Add the Fatalities layer
Map <- Map + labs(x = "Longitude", y = "Latitude", fill = "NYC Boroughs") # Add the labels
Map <- Map + ggtitle("NYC Boroughs with Accidents")
Map # Display the Map
</pre>
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-58780132597544058262015-08-15T12:56:00.001-07:002015-08-15T12:56:43.205-07:00Obtaining NYC Pedestrian safety data for AnalysisIn this post, I wanted to obtain New York City Safety data for subsequent analysis using R and Hadoop. Even though the data may not be as substantial, I wanted to see what insights we could derive in the process. The first post is focused on downloading the relevant data from NYC websites.<br />
<br />
The overall process has the following steps<br />
<br />
1. Download the data for pedestrian safety and related data<br />
2. Download the data for other datasets that may be relevant to analyze different trends.<br />
<br />
Here is the script that I created to download the data<br />
<br />
<pre class="brush:bash">cd ../data
wget -nc http://www.nyc.gov/html/dot/downloads/misc/injury_yearly_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/injury_all_monthly_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/fatality_yearly_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/fatality_all_monthly_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/arterial_slow_zones_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/leading_pedestrian_intervals_signals_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/neighborhood_slow_zones_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/safe_streets_for_seniors_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/speed_bumps_2014_to_2015_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/street_improvement_projects_2013_to_2015_intersections_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/street_improvement_projects_2013_to_2015_corridors_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/hands_on_safety_demos_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/outreach_schools_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/senior_centers_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/street_team_flyers_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/taxi_and_car_service_trainings_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/town_hall_locations_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/workshops_shapefile.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/summary_city_council_districts.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/summary_community_districts.zip
wget -nc http://www.nyc.gov/html/dot/downloads/misc/summary_police_precincts.zip
# subway entrances
wget -nc "https://data.cityofnewyork.us/api/geospatial/drex-xx56?method=export&format=Shapefile" -O subway_entrances.zip
#bicycle parking
wget -nc "https://data.cityofnewyork.us/download/qpbf-g2yx/SHAPEFILE" -O bicycle_parking.zip
#street network changes
wget -nc "https://data.cityofnewyork.us/download/bymk-vktx/XML" -O street_network_changes.xml
#safe route to schools
wget -nc "https://data.cityofnewyork.us/api/views/pc34-d3sx/rows.csv?accessType=DOWNLOAD" -O safe_route_to_schools.csv
#through truck routes
wget -nc "https://data.cityofnewyork.us/download/qf28-yqqv/ZIP" -O through_truck_routes.zip
#local truck routes
wget -nc "https://data.cityofnewyork.us/download/wha9-m3tq/ZIP" -O local_truck_routes.zip
#realtime speed data
wget -nc "https://data.cityofnewyork.us/download/xsat-x5sa/TXT" -O realtime_speed_data.txt
#street pavement rating
wget -nc "https://data.cityofnewyork.us/api/geospatial/2cav-chmn?method=export&format=Shapefile" -O street_pavement_rating.zip
#state assembly districts
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nyad_15b.zip" -O stat_assmbly_dst.zip
#U.S. Congressional Districts
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nyadwi_15b.zip" -O us_cngrssnl_dstrcts.zip
#State Senate Districts
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nycgwi_15b.zip" -O st_snt_dstrcts.zip
#Municipal Court Districts
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nymcwi_15b.zip" -O mncpl_crt_dstrcts.zip
#City Council Districts
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nyccwi_15b.zip" -O cty_cncl_dstrcts.zip
#Election Districts
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nyedwi_15b.zip" -O elctn_dstrcts.zip
#Borough Boundaries
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nybbwi_15b.zip" -O brgh_bndrs.zip
#Community Districts
wget -nc "http://www.nyc.gov/html/dcp/download/bytes/nycd_15b.zip" -O cmmnty_dstrcts.zip
rm *.zip.*
ls .
mkdir shpfiles
unzip -nj injury_yearly_shapefile.zip -d ./shpfiles
unzip -nj injury_all_monthly_shapefile.zip -d ./shpfiles
unzip -nj fatality_yearly_shapefile.zip -d ./shpfiles
unzip -nj fatality_all_monthly_shapefile.zip -d ./shpfiles
unzip -nj arterial_slow_zones_shapefile.zip -d ./shpfiles
unzip -nj leading_pedestrian_intervals_signals_shapefile.zip -d ./shpfiles
unzip -nj neighborhood_slow_zones_shapefile.zip -d ./shpfiles
unzip -nj safe_streets_for_seniors_shapefile.zip -d ./shpfiles
unzip -nj speed_bumps_2014_to_2015_shapefile.zip -d ./shpfiles
unzip -nj street_improvement_projects_2013_to_2015_intersections_shapefile.zip -d ./shpfiles
unzip -nj street_improvement_projects_2013_to_2015_corridors_shapefile.zip -d ./shpfiles
unzip -nj hands_on_safety_demos_shapefile.zip -d ./shpfiles
unzip -nj outreach_schools_shapefile.zip -d ./shpfiles
unzip -nj senior_centers_shapefile.zip -d ./shpfiles
unzip -nj street_team_flyers_shapefile.zip -d ./shpfiles
unzip -nj taxi_and_car_service_trainings_shapefile.zip -d ./shpfiles
unzip -nj town_hall_locations_shapefile.zip -d ./shpfiles
unzip -nj workshops_shapefile.zip -d ./shpfiles
unzip -nj summary_city_council_districts.zip -d ./shpfiles
unzip -nj summary_community_districts.zip -d ./shpfiles
unzip -nj summary_police_precincts.zip -d ./shpfiles
unzip -nj subway_entrances.zip -d ./shpfiles
unzip -nj bicycle_parking.zip -d ./shpfiles
unzip -nj through_truck_routes.zip -d ./shpfiles
unzip -nj local_truck_routes.zip -d ./shpfiles
unzip -nj street_pavement_rating.zip -d ./shpfiles
unzip -nj stat_assmbly_dst.zip -d ./shpfiles
unzip -nj us_cngrssnl_dstrcts.zip -d ./shpfiles
unzip -nj st_snt_dstrcts.zip -d ./shpfiles
unzip -nj mncpl_crt_dstrcts.zip -d ./shpfiles
unzip -nj cty_cncl_dstrcts.zip -d ./shpfiles
unzip -nj cty_cncl_dstrcts.zip -d ./shpfiles
unzip -nj elctn_dstrcts.zip -d ./shpfiles
unzip -nj brgh_bndrs.zip -d ./shpfiles
unzip -nj cmmnty_dstrcts.zip -d ./shpfiles
</pre>
<br />
Here is my script in the editor<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVIpszsn7y1ZivnZzVYIJ-DSp9eVkVJjlQQIvX6o0CZ8rbnFABylOozlbtl16rO6HAknG3RwJfLGimLtOKH9_YDjAMWWdvo7j5DHjFf5H0BDOmidvXtQeE4aRDgalnooDOydqw0Ge9QO0/s1600/download_NYC_data.sh+%2528%257E-Work-Transportation-NYC-scripts%2529+-+gedit_336.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVIpszsn7y1ZivnZzVYIJ-DSp9eVkVJjlQQIvX6o0CZ8rbnFABylOozlbtl16rO6HAknG3RwJfLGimLtOKH9_YDjAMWWdvo7j5DHjFf5H0BDOmidvXtQeE4aRDgalnooDOydqw0Ge9QO0/s640/download_NYC_data.sh+%2528%257E-Work-Transportation-NYC-scripts%2529+-+gedit_336.png" width="640" /></a></div>
<br />
<br />
To execute, just save the file as download_NYC_data.sh in my scripts folder<br />
<br />
<pre class="brush:bash">
chmod a+x *.sh
./download_NYC_data.sh
</pre>
<br />
If the file is already downloaded and/or unarchived, the script does not do anything..<br />
<br />
Here is the screenshot from my terminal<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFlqDqckDSHr6y7QVVV-6TA1-1lz3ieyMzI6M_BNNYwJ_TmdWmbzAAyUT_yPf6z_qtldKCdgtKul0-Ygx1dX3DrRk_lb4MA315CvqJo1ZCtzb-CAC38AEPNQO-76besqPOLIQVUEqdIUw/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_347.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFlqDqckDSHr6y7QVVV-6TA1-1lz3ieyMzI6M_BNNYwJ_TmdWmbzAAyUT_yPf6z_qtldKCdgtKul0-Ygx1dX3DrRk_lb4MA315CvqJo1ZCtzb-CAC38AEPNQO-76besqPOLIQVUEqdIUw/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_347.png" width="640" /></a></div>
<br />
<br />
Just executed the script to download all data and unzip it on my local machine<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-38059685037401935192015-08-09T17:48:00.000-07:002015-09-07T04:43:59.655-07:00Reading shape files in RIn the previous post, we saw <a href="http://opendesignarch.blogspot.com/2015/08/reading-dbf-files-in-r.html">how to read dbf files in R</a>. I wanted to go a step further.<br />
<br />
I was looking at ways to read shape file data in R. It turns out there are various mechanisms for doing just that. However, for the library to be installed correctly, your environment needs to be setup correctly.<br />
<br />
Here are the steps I followed.<br />
<br />
1. Install libgdal<br />
2. Install libproj<br />
3. Install rgdal package<br />
4. Test loading a shape file<br />
<br />
The following script should install these packages correctly for you.<br />
<br />
<pre class="brush:bash">sudo apt-get install apt-file
sudo apt-get update
sudo apt-get install libgdal1h
sudo apt-get install libgdal1-dev libproj-dev
</pre>
<br />
Once these packages are setup correctly start R as sudo<br />
<br />
<pre class="brush:bash">sudo R</pre>
<br />
Enter the following commands on the R console<br />
<br />
<pre class="brush:bash">install.packages("rgdal")
install.packages("rgeos")
install.packages("ggmap")
install.packages("maptools")
q()
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhREJXrzF2WAsgzj9V6k6EWaIBLXkf7F6QgGCJLGS1nSJQ_mnuLL8o3VkNlGNfjLAOOhZggO-Va7XMmt-MYK_muczzTzhQPSX1pVvEOBkYjzZivzVw4oAY2gMn_g1LCQyCp5E7uILKAbEo/s1600/arthgallo%2540ub1204%253A+%257E_340.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhREJXrzF2WAsgzj9V6k6EWaIBLXkf7F6QgGCJLGS1nSJQ_mnuLL8o3VkNlGNfjLAOOhZggO-Va7XMmt-MYK_muczzTzhQPSX1pVvEOBkYjzZivzVw4oAY2gMn_g1LCQyCp5E7uILKAbEo/s640/arthgallo%2540ub1204%253A+%257E_340.png" width="640" /></a></div>
<br />
The following screen shows installation for rgeos
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLCcrJArgBP2-F9UT2hqERNETrlAlCBCPZ36I-7-FfoNl9qXtta59wd62dkTMBkLqiOETXwZDsp6CZj0ZT0zKENy-A7ZMC_AV0YYGfjnNoiCdmjAJKyACIA5yp3tZPVWZlIPM9ZNuM0e0/s1600/arthgallo%2540ub1204%253A+%257E_345.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLCcrJArgBP2-F9UT2hqERNETrlAlCBCPZ36I-7-FfoNl9qXtta59wd62dkTMBkLqiOETXwZDsp6CZj0ZT0zKENy-A7ZMC_AV0YYGfjnNoiCdmjAJKyACIA5yp3tZPVWZlIPM9ZNuM0e0/s640/arthgallo%2540ub1204%253A+%257E_345.png" /></a></div>
<br />
Next run the following commands in R (without sudo)<br />
<br />
<pre class="brush:bash">library(rgdal)
shpfilepath="../data/shpfiles"
ogrInfo(shpfilepath,"fatality_yearly")
ftlty_yr <-readOGR(shpfilepath, "fatality_yearly")
</pre>
This shows the following:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzWvqSLpa2KKmCzhsa2rwbB7kPcXKTWL0NBtVJg89t7bM5QglpgJre6v6dUol0mB2Bnlv3RcQ4DgdzHNUGnt9rFu3swK_NDjNcUCM-zv-K4yTVKhcTObH848LhARVdl-GvEQ4igP9nlcY/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_343.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzWvqSLpa2KKmCzhsa2rwbB7kPcXKTWL0NBtVJg89t7bM5QglpgJre6v6dUol0mB2Bnlv3RcQ4DgdzHNUGnt9rFu3swK_NDjNcUCM-zv-K4yTVKhcTObH848LhARVdl-GvEQ4igP9nlcY/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-scripts_343.png" width="640" /></a></div>
<br />
Now, enter the following command in R<br />
<br />
<pre class="brush:bash">plot(ftlty_yr, axes=TRUE, border="gray")</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhApGssjViZmOpms04bMwfUERBYo-uhhl_4aJZQIBVgoHS4WoCUbZs0W9DB-2WN8qHZ-mvZTkSSKLNP3FdJpHw312d_Gva9tWBSw0r_qajBv7ljaU2RSH34vVgL9kbvjrycG2Tvvv1ylI0/s1600/R+Graphics%253A+Device+2+%2528ACTIVE%2529_344.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhApGssjViZmOpms04bMwfUERBYo-uhhl_4aJZQIBVgoHS4WoCUbZs0W9DB-2WN8qHZ-mvZTkSSKLNP3FdJpHw312d_Gva9tWBSw0r_qajBv7ljaU2RSH34vVgL9kbvjrycG2Tvvv1ylI0/s640/R+Graphics%253A+Device+2+%2528ACTIVE%2529_344.png" width="614" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Our R environment can now read shapefiles correctly</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-22691678659609268932015-08-09T07:41:00.000-07:002015-08-09T07:45:40.060-07:00Reading dbf files in RIn this post, we will see how to load dbf tables in R.<br />
<br />
First item is to install the appropriate R library. In this case, it happens to be a library called foreign.<br />
<br />
Run R in administrative mode so that library can be installed in the universal library<br />
<br />
sudo R<br />
<br />
> install.packages("foreign")<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNiS5Q2ejZTlzCBO2Sx2TTTeG-re7rGHdp-w1gKoKNslFGRRVohuBssJi1IOxryRD5MVMM-7TVtc_X-ka9cd4CIZSuyPzqJObruFH7r2jEChs00GmiiKp800jxpEBDACvMiQUhrNBSDys/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_337.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNiS5Q2ejZTlzCBO2Sx2TTTeG-re7rGHdp-w1gKoKNslFGRRVohuBssJi1IOxryRD5MVMM-7TVtc_X-ka9cd4CIZSuyPzqJObruFH7r2jEChs00GmiiKp800jxpEBDACvMiQUhrNBSDys/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_337.png" width="640" /></a></div>
<br />
Quit R and re-enter R in non-administrative (non-sudo) mode<br />
<br />
At, the R prompt, enter the following commands<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirysmdmuw9s_Bcrw7HF7yNtiEtogtzVWREmCpIQ9ttQtlZC54fDhkhzSUhyphenhyphen0ZFGMvZ4JawdeupO4htQAJ3iQ65bzNBqWG4Ubxubo7KQhLZfLyTBXg_ZewVm0sK4GT6SVKFTglWmkMDJMiN/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> library(foreign)
fatal_yr <- read.dbf("~/Work/Transportation/NYC/data/shpfiles/fatality_yearly.dbf")
dim(fatal_yr)
</code></pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Y9_gp1dC3TgmjDn85U34wrKwS1oNDq_I6Z63ahT_Barr66DT-2DQDmrenEdH99Vvc9KbiO0iVbmpKNlZIsWthrAB39DI00Cp4wtVMtalm0elBcYARhG7xkALFGIc9XCVlYUBbTTlZdg/s1600/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_339.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Y9_gp1dC3TgmjDn85U34wrKwS1oNDq_I6Z63ahT_Barr66DT-2DQDmrenEdH99Vvc9KbiO0iVbmpKNlZIsWthrAB39DI00Cp4wtVMtalm0elBcYARhG7xkALFGIc9XCVlYUBbTTlZdg/s640/arthgallo%2540ub1204%253A+%257E-Work-Transportation-NYC-data-shpfiles_339.png" width="640" /></a></div>
<br />
That's it, we have loaded the dbf file.<br />
<br />
<br />
<br />
<!----->awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-9628253019434996912015-07-25T15:16:00.000-07:002015-07-25T16:27:41.135-07:00Installing RHadoop on UbuntuIn this post, we will install and configure RHadoop on Ubuntu. RHadoop is essentially R modules that can interact with a Hadoop environment and can issue map reduce commands. Pre-requisites to this of course are R and Hadoop.<br />
<br />
1. Installing Hadoop - If you don't have Hadoop installed on your machine, you can follow the steps listed in <a href="http://opendesignarch.blogspot.com/2015/07/install-hadoop-in-pseudo-node-cluster.html">my post to set up a pseudo-distributed cluster</a> on a single machine. You will also need to make sure HBase is setup on your machine to utilize hdfs. This <a href="http://opendesignarch.blogspot.com/2015/07/installing-hbase-on-pseudo-distributed.html">post walks through steps to set up HBase in a pseudo distributed mode</a> utilizing hdfs.<br />
<br />
<br />
2. Installing R - If you don't already have R set up on your machine, you can follow steps in <a href="http://opendesignarch.blogspot.com/2014/02/installing-r-statistical-package-on.html">this post</a> to set R up.<br />
<br />
or<br />
<br />
3. Upgrading R - If you don't have the latest version of R on your machine, it may be a good idea to upgrade it by <a href="http://opendesignarch.blogspot.com/2015/07/upgrading-r-to-latest-version-on-ubuntu.html">following these steps</a>.<br />
<br />
Next we set up RHadoop. Overall steps are as follows..<br />
<br />
1. Configuring R shell environment to access Hadoop<br />
<div>
2. Configuring R library paths<br />
3. Installing R libraries</div>
<br />
We will go these steps in the following post.<br />
<br />
<h3>
1. Configuring R shell environment to access Hadoop</h3>
The first step is to add some configuration to the bashrc environment.<br />
<br />
Lets open the configuration file.<br />
<br />
<pre>
$ sudo ~/.bashrc<br />
</pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio39JqdPRQYiywM8NqtWIyzTODAc2zGDdY_S-0mfyeuGRdsF5RsbOEipZjguhs1_o0BPehFNELd8CEelCfSsO4tu7-SlZpY6t_aE1GhsIzj25ByjlpaC47vL5VzhjWUoh6bW4_UFjO_PE/s1600/hadoop_admin%2540ub1204%253A+%257E_274.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio39JqdPRQYiywM8NqtWIyzTODAc2zGDdY_S-0mfyeuGRdsF5RsbOEipZjguhs1_o0BPehFNELd8CEelCfSsO4tu7-SlZpY6t_aE1GhsIzj25ByjlpaC47vL5VzhjWUoh6bW4_UFjO_PE/s640/hadoop_admin%2540ub1204%253A+%257E_274.png" width="640" /></a></div>
<br />
Next, add the following lines to the end of the file<br />
<br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">export HADOOP_PREFIX=$HADOOP_HOME</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">export HADOOP_CMD=$HADOOP_HOME/bin/hadoop</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">export HADOOP_STREAMING=$HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.7.1.jar</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVdyngahYHrROSlgoDxUmIFVjW7tYqb0zdxVYRkWDDwDK1OzFHMCMcwCRZXWXSln8qLbKZO1DdgRMUJjKHMJE2rqS8cXIDUyp0KZNVkUv556gbOZsDXKcJI0NePMUdBFaK-3i6zcOmhkI/s1600/bashrc+%2528%257E%2529+-+gedit_275.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="418" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVdyngahYHrROSlgoDxUmIFVjW7tYqb0zdxVYRkWDDwDK1OzFHMCMcwCRZXWXSln8qLbKZO1DdgRMUJjKHMJE2rqS8cXIDUyp0KZNVkUv556gbOZsDXKcJI0NePMUdBFaK-3i6zcOmhkI/s640/bashrc+%2528%257E%2529+-+gedit_275.png" width="640" /></a></div>
<br />
Next step is to apply these environment settings and see if the environment variables have been setup<br />
<br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">$ source ~/.bashrc</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">$ echo $HADOOP_STREAMING</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoX-W8pv9J35kneEaYkqKtN09Z8eYB-9w2Kl4Vt0sh82TFPSdtUzAAqVEuFaky820nhitxcuqIAbRUXAkTRNS2-la6cnShMWBewU9COeNH7GxXI2ShNf8lWrtdgx057zS7TR_al77h7Bs/s1600/hadoop_admin%2540ub1204%253A+%257E_277.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoX-W8pv9J35kneEaYkqKtN09Z8eYB-9w2Kl4Vt0sh82TFPSdtUzAAqVEuFaky820nhitxcuqIAbRUXAkTRNS2-la6cnShMWBewU9COeNH7GxXI2ShNf8lWrtdgx057zS7TR_al77h7Bs/s640/hadoop_admin%2540ub1204%253A+%257E_277.png" width="640" /></a></div>
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;"><br /></span></span><br />
<h3>
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;">2. Configuring R library paths</span></span></h3>
<span style="background-color: white; font-family: 'Courier New', Courier, monospace;">Next step is to make sure that the library path is setup correctly, so that any installed packages will be available to all users. Start R and enter the following command</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;"><br /></span></span>
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;">$ sudo R</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;">> .libPaths()</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;"><br /></span></span>
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;">Make sure the paths point to /usr/local or similar, else re-configure the paths to point to these folders, by setting a destination path in the install command. On my machine, I did not have to change anything.</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOx8kxN_im3uHZFbRsQkbhLv01qyx2BJtFV28nakOaMCmAoCc13mnEKe5O0TYUTL_r1XsAQg7hLS5tYsbELkQ8n3sYQBRg-5b9BpLSzZv-EVyHcxO-KwLdq2jsY38Dwa17ClPW9ZfSDGg/s1600/arthgallo%2540ub1204%253A+%257E_298.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOx8kxN_im3uHZFbRsQkbhLv01qyx2BJtFV28nakOaMCmAoCc13mnEKe5O0TYUTL_r1XsAQg7hLS5tYsbELkQ8n3sYQBRg-5b9BpLSzZv-EVyHcxO-KwLdq2jsY38Dwa17ClPW9ZfSDGg/s640/arthgallo%2540ub1204%253A+%257E_298.png" width="640" /></a></div>
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;"><br /></span></span>
<span style="font-family: 'Courier New', Courier, monospace;">Next, we need to download the needed packages from the RHadoop site.</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">I created a folder called rhadoop on my local account and downloaded the following packages from github using the wget command</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">wget http://cran.r-project.org/src/contrib/rJava_0.9-6.tar.gz</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">wget https://github.com/RevolutionAnalytics/rmr2/releases/download/3.3.1/rmr2_3.3.1.tar.gz</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">wget https://github.com/RevolutionAnalytics/rhdfs/blob/master/build/rhdfs_1.0.8.tar.gz?raw=true</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">wget https://github.com/RevolutionAnalytics/rhbase/blob/master/build/rhbase_1.2.1.tar.gz?raw=true</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">wget https://github.com/RevolutionAnalytics/ravro/blob/1.0.4/build/ravro_1.0.4.tar.gz?raw=true</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">wget https://github.com/RevolutionAnalytics/plyrmr/releases/download/0.6.0/plyrmr_0.6.0.tar.gz</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">mv rhdfs_1.0.8.tar.gz\?raw\=true rhdfs_1.0.8.tar.gz</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">mv rhbase_1.2.1.tar.gz\?raw\=true rhbase_1.2.1.tar.gz</span><br />
<span style="background-color: #cccccc; font-family: Courier New, Courier, monospace;">mv ravro_1.0.4.tar.gz\?raw\=true ravro_1.0.4.tar.gz</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1_d-6CRtuPFFhqZ4QRlzQTMHzytXdHXHCewj1YgtDgiSlbL87psN2rAzSgo4S5kqhrtFMgD2vW49Bp_G-W0hQ01yEs4Q6Wq0J8kocu3nhH3BPBK1nlUK2qpe2ccKipFxECAvTc3u6t-I/s1600/hadoop_admin%2540ub1204%253A+%257E-rhadoop_285.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1_d-6CRtuPFFhqZ4QRlzQTMHzytXdHXHCewj1YgtDgiSlbL87psN2rAzSgo4S5kqhrtFMgD2vW49Bp_G-W0hQ01yEs4Q6Wq0J8kocu3nhH3BPBK1nlUK2qpe2ccKipFxECAvTc3u6t-I/s640/hadoop_admin%2540ub1204%253A+%257E-rhadoop_285.png" width="640" /></a></div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">Next we need to update the JDK </span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$ sudo R CMD javareconf</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh14DPJeeT971ji8x4wtyu_OL_PZtKpT799zJNSo5YOTEzXZ9h9DpB255v99jQxBFXaO9KVhZ7Bj2kvEikdsL9ZJxLo1c6QhMGZoszqHkXlGtGDo-rLP5ggl2j4svIF4AIMXNSY5eazWcY/s1600/hadoop_admin%2540ub1204%253A+-usr-lib-jvm_302.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh14DPJeeT971ji8x4wtyu_OL_PZtKpT799zJNSo5YOTEzXZ9h9DpB255v99jQxBFXaO9KVhZ7Bj2kvEikdsL9ZJxLo1c6QhMGZoszqHkXlGtGDo-rLP5ggl2j4svIF4AIMXNSY5eazWcY/s640/hadoop_admin%2540ub1204%253A+-usr-lib-jvm_302.png" width="640" /></a></div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">Next, we will install rJava package that we downloaded</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">$ sudo R</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">install.packages("~/rhadoop/</span><span style="font-family: 'Courier New', Courier, monospace;">rJava_0.9-6.tar.gz</span><span style="font-family: 'Courier New', Courier, monospace;">", repos=NULL, type="source")</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;">Next step is to install some pre-requisite R packages</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white;"><br /></span></span><span style="font-family: Courier New, Courier, monospace;">> install.packages(c("Rcpp", "RJSONIO", "bitops", "digest", </span><span style="font-family: Courier New, Courier, monospace;">"functional", "stringr", "plyr", "reshape2", "dplyr", </span><span style="font-family: 'Courier New', Courier, monospace;">"R.methodsS3", "caTools", "Hmisc"))</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbvODGWjsDJw1mfBCMoofeNLimDPh66b2HojwS0oOkzp3X0LV-pQGnnOvNg7T9dRywu9IIzTa83wgNzdSV8EShGg8_-qaBzu2mtAuO1Qd6lHJxTzZoIvWgMlP3LM20kBc0OhIIIGTqoU0/s1600/arthgallo%2540ub1204%253A+%257E_299.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbvODGWjsDJw1mfBCMoofeNLimDPh66b2HojwS0oOkzp3X0LV-pQGnnOvNg7T9dRywu9IIzTa83wgNzdSV8EShGg8_-qaBzu2mtAuO1Qd6lHJxTzZoIvWgMlP3LM20kBc0OhIIIGTqoU0/s640/arthgallo%2540ub1204%253A+%257E_299.png" width="640" /></a></div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: 'Courier New', Courier, monospace;">Next, we install data.table package for handling large datasets.</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">> install.packages("data.table")</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9HE0RzdKzgp4jb3ue175s7SBCcE4kJ098FS4_exoCuuN2xBhZJOJf73C3gj4LmVf5ACvwVgsylQb9p5pSO3haTTithNlgWa1wWb5O61GW4v4GR4rTaWjmljCTyMv0UnXCR5KDHZjaelk/s1600/hadoop_admin%2540ub1204%253A+%257E_281.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9HE0RzdKzgp4jb3ue175s7SBCcE4kJ098FS4_exoCuuN2xBhZJOJf73C3gj4LmVf5ACvwVgsylQb9p5pSO3haTTithNlgWa1wWb5O61GW4v4GR4rTaWjmljCTyMv0UnXCR5KDHZjaelk/s640/hadoop_admin%2540ub1204%253A+%257E_281.png" width="640" /></a></div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<span style="font-family: Courier New, Courier, monospace;">We need to make sure that you have thrift installed on your machine. If you don't have <a href="http://opendesignarch.blogspot.com/2015/07/install-thrift-on-ubuntu.html">follow these steps in my post</a> to install thrift on your Ubuntu machine to install thrift. It was thrift installation that posed the biggest challenges for me.</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">Next we will deploy these packages in R. Enter the following commands on the R command prompt.</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">Sys.setenv("HADOOP_CMD"="/usr/local/hadoop/bin/hadoop")</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">install.packages("~/rhadoop/rmr2_3.3.1.tar.gz", repos=NULL, type="source")</span><br />
<span style="font-family: Courier New, Courier, monospace;">install.packages("~/rhadoop/rhdfs_1.0.8.tar.gz", repos=NULL, type="source")</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">install.packages("~/rhadoop/plyrmr_0.6.0.tar.gz", repos=NULL, type="source")</span><br />
<span style="font-family: Courier New, Courier, monospace;">install.packages("~/rhadoop/rhbase_1.2.1.tar.gz", repos=NULL, type="source")</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">install.packages("~/rhadoop/ravro_1.0.4.tar.gz", repos=NULL, type="source")</span><span style="font-family: Courier New, Courier, monospace;"></span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7jTt9HLwUFmd-XC5Y7h8wrxbax6ALWHS1FGAHh9b_y04xbeP6735uDE_DwE3WlHPYclXSmQYXQqPUeTebyGEZr4FLeE7txS9sRXQ5bIwqODh4kmX3OqEZqM8jYJ_yQVVic046N2h_TwU/s1600/hadoop_admin%2540ub1204%253A+%257E_286.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7jTt9HLwUFmd-XC5Y7h8wrxbax6ALWHS1FGAHh9b_y04xbeP6735uDE_DwE3WlHPYclXSmQYXQqPUeTebyGEZr4FLeE7txS9sRXQ5bIwqODh4kmX3OqEZqM8jYJ_yQVVic046N2h_TwU/s640/hadoop_admin%2540ub1204%253A+%257E_286.png" width="640" /></a></div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;">That's it rhadoop is installed. To make sure everything is working, start R in normal mode and issue the following commands</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">> Sys.setenv("HADOOP_CMD"="/usr/local/hadoop/bin/hadoop")</span><br />
<span style="font-family: Courier New, Courier, monospace;">> library(rmr2)</span><br />
<span style="font-family: Courier New, Courier, monospace;">> library(rhdfs)</span><br />
<span style="font-family: Courier New, Courier, monospace;">> hdfs.init()</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_XlyAMNT5IJj64tgjdKWlEe3srmgg6ysIe3BSU0-aGaP8JmYmvexXYgFqh6b2KUfWX8mvPNnp6nrNpOHNYZCvWg4_mg6OhiFqN1RhCFURSBA0yYl5ZSRV1sfAb7bT4pfwyoTDtclanqE/s1600/arthgallo%2540ub1204%253A+%257E_335.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_XlyAMNT5IJj64tgjdKWlEe3srmgg6ysIe3BSU0-aGaP8JmYmvexXYgFqh6b2KUfWX8mvPNnp6nrNpOHNYZCvWg4_mg6OhiFqN1RhCFURSBA0yYl5ZSRV1sfAb7bT4pfwyoTDtclanqE/s640/arthgallo%2540ub1204%253A+%257E_335.png" width="640" /></a></div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">Now the R environment is ready to use the HDFS environment.</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-90926463438552956712015-07-25T10:42:00.000-07:002015-07-25T13:51:12.393-07:00Install Thrift on Ubuntu<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 18px;">Apache Thrift is a software project spanning a variety of programming languages and use cases. The goal is to make reliable, performant communication and data serialization across languages as efficient and seamless as possible.</span><br />
<br />
Here are the steps to install thrift on your Ubuntu machine<br />
<br />
$ <span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">sudo</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">apt</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">get</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">install</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libboost</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">dev</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libboost</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">test</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">dev</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libboost</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">program</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">options</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">dev</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libboost</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">system</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">dev</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libboost</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">filesystem</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">dev</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libevent</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">dev</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">automake</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libtool</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">flex</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">bison</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">pkg</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">config</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">g</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">++</span><span style="background-color: whitesmoke; color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"> </span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">libssl</span><span class="o" style="color: #666666; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">-</span><span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;">dev</span><br />
<span class="n" style="color: #333333; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 18px; white-space: pre-wrap;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN6A0egIA7KbMuiuXikSn7hIi2ZI0VkhvCOGfwuexpz9QDv7Ms8qplXtgrJ_oFRf6xOK8D1SdujLYwuxogjweB1rLnMvKpZDNe89jAAbpCkLihNi_ioFZ4OfR8w7zVGZ7PvGfCkxfTn58/s1600/arthgallo%2540ub1204%253A+%257E_328.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN6A0egIA7KbMuiuXikSn7hIi2ZI0VkhvCOGfwuexpz9QDv7Ms8qplXtgrJ_oFRf6xOK8D1SdujLYwuxogjweB1rLnMvKpZDNe89jAAbpCkLihNi_ioFZ4OfR8w7zVGZ7PvGfCkxfTn58/s640/arthgallo%2540ub1204%253A+%257E_328.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Next I created a folder where to download thrift as follows</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
$ cd ~/Work/Servers</div>
<div class="separator" style="clear: both; text-align: left;">
$ mkdir thrift</div>
<div class="separator" style="clear: both; text-align: left;">
$ cd thrift</div>
<div class="separator" style="clear: both; text-align: left;">
$ wget http://apache.mirror.vexxhost.com/thrift/0.9.2/thrift-0.9.2.tar.gz</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_glKoZY34tZ42OQ1GtNhyphenhyphen5EA6Y1bhqyr9abRWAbns-57Fc4ZZQ2ekOYt5C1pgQnBjHRNcF8FsCEHi_xN02n5JZV3eNXQ6rZ74GHDqGnxpw4eK9MwX1khHvmONNcY3gdO4eYJ-P-0K8VM/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-thrift_329.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_glKoZY34tZ42OQ1GtNhyphenhyphen5EA6Y1bhqyr9abRWAbns-57Fc4ZZQ2ekOYt5C1pgQnBjHRNcF8FsCEHi_xN02n5JZV3eNXQ6rZ74GHDqGnxpw4eK9MwX1khHvmONNcY3gdO4eYJ-P-0K8VM/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-thrift_329.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
$ tar -xvzf thrift-0.9.2.tar.gz</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbivwvyQSG0ilC0IHfoNNFaVF2PvHEFuloupSo13_RC_DwXFefeSfiiUaKtYW-L1nVOrAxpd_Z4pAEZsFztXB0FogAWZ2gnHCoMywdlliUDkgbuI0pG2CgSNuHWeafl2SXO3Q97sLeEi4/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-thrift_331.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbivwvyQSG0ilC0IHfoNNFaVF2PvHEFuloupSo13_RC_DwXFefeSfiiUaKtYW-L1nVOrAxpd_Z4pAEZsFztXB0FogAWZ2gnHCoMywdlliUDkgbuI0pG2CgSNuHWeafl2SXO3Q97sLeEi4/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-thrift_331.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Next we put the commands to build thrift</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both;">
$ ./configure </div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
After configure, we need to make some minor changes to one of the files.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
$ cd thrift-0.9.2</div>
<div class="separator" style="clear: both;">
$ cd lib/cpp</div>
<div class="separator" style="clear: both;">
$ gedit thrift.pc</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Modify the following line to the version below</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
includedir=${prefix}/include</div>
<div class="separator" style="clear: both;">
to</div>
<div class="separator" style="clear: both;">
includedir=${prefix}/include/thrift</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfPjpfTAtvpTTULy4-DlHheZl8uqHQiwzdraKVEw_oDJuEHJV409quRuFG-iA3JZ-PKNImfWfvf2cpV5XMW1wTMwmykuP6JYuiwOCMWR_Nsi42aieqtMoZjZA1mFbVXE-WbmzfyyLYizY/s1600/thrift.pc+%2528%257E-Work-Servers-thrift-thrift-0.9.2-lib-cpp%2529+-+gedit_334.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="418" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfPjpfTAtvpTTULy4-DlHheZl8uqHQiwzdraKVEw_oDJuEHJV409quRuFG-iA3JZ-PKNImfWfvf2cpV5XMW1wTMwmykuP6JYuiwOCMWR_Nsi42aieqtMoZjZA1mFbVXE-WbmzfyyLYizY/s640/thrift.pc+%2528%257E-Work-Servers-thrift-thrift-0.9.2-lib-cpp%2529+-+gedit_334.png" width="640" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
$ make </div>
<div class="separator" style="clear: both;">
$ sudo make install </div>
<div class="separator" style="clear: both;">
$ thrift --help </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEher8W1otVzw9eM8A5TJDjzmsG0jxlF5rwtWW8WuhK7-mLqd_AwDHnAWf1z7bZDR1UGWxEsZnqOzZuRjJycy7_elv8UetQL9BPDvXNaoIheLtp4YnNc8TSqWvgX5e1Q52b1QEelOBapmv8/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-thrift-thrift-0.9.2_332.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEher8W1otVzw9eM8A5TJDjzmsG0jxlF5rwtWW8WuhK7-mLqd_AwDHnAWf1z7bZDR1UGWxEsZnqOzZuRjJycy7_elv8UetQL9BPDvXNaoIheLtp4YnNc8TSqWvgX5e1Q52b1QEelOBapmv8/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-thrift-thrift-0.9.2_332.png" width="640" /></a></div>
<div>
<br /></div>
<div>
Now that thrift is compiled, we need to make it accessible to all programs by entering the following command<br />
<br />
$ sudo cp /usr/local/lib/libthrift-0.9.2.so /usr/lib/<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiowACVYDQ-ELObZWTwEbYaQ2uI-Ay6MJbI_xTXOumksidGm7E-041VUUjtgA0L-0_HvRvHELzKU87dTUsDYl9aQr6dDg8IGgfzE_gb_5_0WqHINUghoxkqzsBlL5AB_mzLqLYTCdZjOBo/s1600/arthgallo%2540ub1204%253A+%257E_333.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiowACVYDQ-ELObZWTwEbYaQ2uI-Ay6MJbI_xTXOumksidGm7E-041VUUjtgA0L-0_HvRvHELzKU87dTUsDYl9aQr6dDg8IGgfzE_gb_5_0WqHINUghoxkqzsBlL5AB_mzLqLYTCdZjOBo/s640/arthgallo%2540ub1204%253A+%257E_333.png" width="640" /></a></div>
<br />
<br />
Now thrift is installed</div>
<div>
<br /></div>
awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0tag:blogger.com,1999:blog-2346591996749941735.post-83301344564085230682015-07-25T07:55:00.000-07:002015-07-25T12:20:48.676-07:00Installing HBase on pseudo-distributed modeIn this post, we will install HBase in a pseudo-distributed mode on Ubuntu. In a <a href="http://opendesignarch.blogspot.com/2015/07/install-hadoop-in-pseudo-node-cluster.html">previous post</a>, we setup Hadoop (HDFS) in a pseudo distributed mode.<br />
<br />
To get started, first lets get the latest version of HBase from http://hbase.apache.org/<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjKVQbDHOKQh9jCwbX8aOhmxk6bDemLL4hhCtiuw8vrha3D179w58mDE1pxDfbSzD2huWz7oUzNGS7qhOlxX6Mhk-ENE4xiL5bt_Cl-zHOIRi3Z7_kide-pTZsUQMKAFwghJAGZnDoTVs/s1600/HBase+%25E2%2580%2593+Apache+HBase%25E2%2584%25A2+Home+-+Google+Chrome_303.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjKVQbDHOKQh9jCwbX8aOhmxk6bDemLL4hhCtiuw8vrha3D179w58mDE1pxDfbSzD2huWz7oUzNGS7qhOlxX6Mhk-ENE4xiL5bt_Cl-zHOIRi3Z7_kide-pTZsUQMKAFwghJAGZnDoTVs/s640/HBase+%25E2%2580%2593+Apache+HBase%25E2%2584%25A2+Home+-+Google+Chrome_303.png" width="640" /></a></div>
<br />
Next we download the hbase distribution to our local file system and extract the contents..<br />
<br />
I downloaded hbase 1.1.0.1 from the Apache mirror and saved it my local folder. To extract the tar file use the following command...<br />
<br />
$ tar -xzvf hbase-1.1.0.1-bin.tar.gz<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZWDxuaONNkZ-1138sUVn8anb47Nq9tIVJ3Kgh_lbw_YOiWxIju9mrPeV8FWqlR5QoLapD0WmeB50xFTTnj6hSxQ2VREbediS9Uos97L1GhCPSzDbD9NWV1P3zKADL-LosL7EaAtfgQKg/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase_305.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZWDxuaONNkZ-1138sUVn8anb47Nq9tIVJ3Kgh_lbw_YOiWxIju9mrPeV8FWqlR5QoLapD0WmeB50xFTTnj6hSxQ2VREbediS9Uos97L1GhCPSzDbD9NWV1P3zKADL-LosL7EaAtfgQKg/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase_305.png" width="640" /></a></div>
<br />
After extracting the contents, we need to make some configuration changes. We start by opening the following file.<br />
<br />
$ cd hbase-1.1.0.1<br />
$ cd conf<br />
$ sudo gedit hbase-site.xml<br />
<br />
You will see a near empty file with an empty configuration XML node. Enter following configuration for hbase root directory as well as the zookeeper process.<br />
<br />
<configuration><br />
<property><br />
<name>hbase.rootdir</name><br />
<value>file:///home/arthgallo/hbase</value><br />
</property><br />
<property><br />
<name>hbase.zookeeper.property.dataDir</name><br />
<value>/home/arthgallo/zookeeper</value><br />
</property><br />
</configuration><br />
<br />
Here is a screenshot of the updated file.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJtFOYJ7LD1SIOHmXbJ7vjc-w1f2Dw56FRTrljAtEBKv4KUrjhKcvhomKGcwsrQGT5LmdcWxekNbCQJimYmoqPnrzFNHTAAILJhxLac4YIPT1QVXD5bib7GkFkFcnXuRuPQ5MGjoUiJEk/s1600/hbase-site.xml+%2528%257E-Work-Servers-HBase-hbase-1.1.0.1-conf%2529+-+gedit_307.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="418" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJtFOYJ7LD1SIOHmXbJ7vjc-w1f2Dw56FRTrljAtEBKv4KUrjhKcvhomKGcwsrQGT5LmdcWxekNbCQJimYmoqPnrzFNHTAAILJhxLac4YIPT1QVXD5bib7GkFkFcnXuRuPQ5MGjoUiJEk/s640/hbase-site.xml+%2528%257E-Work-Servers-HBase-hbase-1.1.0.1-conf%2529+-+gedit_307.png" width="640" /></a></div>
<br />
<br />
Next we need to make sure JAVA_HOME is set properly. Open the environment file to set it<br />
<br />
$ sudo gedit /usr/local/hbase/conf/hbase-env.sh<br />
<br />
Uncomment the JAVA_HOME line and point it to the path where JDK is installed. In case you have trouble determining the best way to set up JAVA_HOME, refer to <a href="http://opendesignarch.blogspot.com/2015/07/setting-up-javahome-on-ubuntu.html">this post</a> for how to do so.<br />
<br />
This entry to be made in the hbase-env file is shown as below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQS4U_gn0PsBzojQ5SxSt3g9Hh_DP5wslA3dxXsV-jTW0Fj8PkJ9tqWQi-miRy4r24RTqjlhfohzJtHwWbtyKxiw0SuhsM4RcYClZIwwxm9X2SDQdsOG4jG9mi1uM_XMzZaEF5cmMJuW4/s1600/hbase-env.sh+%2528-usr-local-hbase-conf%2529+-+gedit_320.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="418" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQS4U_gn0PsBzojQ5SxSt3g9Hh_DP5wslA3dxXsV-jTW0Fj8PkJ9tqWQi-miRy4r24RTqjlhfohzJtHwWbtyKxiw0SuhsM4RcYClZIwwxm9X2SDQdsOG4jG9mi1uM_XMzZaEF5cmMJuW4/s640/hbase-env.sh+%2528-usr-local-hbase-conf%2529+-+gedit_320.png" width="640" /></a></div>
<br />
<br />
Now in the terminal shell cd to the folder where HBase was extracted.<br />
<br />
$ cd ~/Work/Servers/HBase/hbase-1.1.0.1<br />
$ cd bin<br />
$ ./start-hbase.sh<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdODZixY5sRWxN35X8dao0dcfMbPAOzh30C18hHO0HVPbFDB9jWtQNZGJ5LoHzLTAXswcJgjSqR7ag5G0SC32mSaovIahzooo_PMOAvSKoQ7a33o-vKilgXcMsHZRbGXEzW7pKJo1WR8U/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_308.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdODZixY5sRWxN35X8dao0dcfMbPAOzh30C18hHO0HVPbFDB9jWtQNZGJ5LoHzLTAXswcJgjSqR7ag5G0SC32mSaovIahzooo_PMOAvSKoQ7a33o-vKilgXcMsHZRbGXEzW7pKJo1WR8U/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_308.png" width="640" /></a></div>
<br />
Now enter jps to make sure that HBase started correctly.<br />
<br />
$ jps<br />
<br />
We can see the Master processes, to tell us that jps started correctly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSjVzQrh6YTChF-hqzg0QedIQrgjh8A4pOvaloK7X71f34dlvNBPWWvVatN_k0Jk2Hpk97UOYbxFu9LfwRb4qiU01LZkt8rouelqgaEKnEIHFOVhkhmv8MaQ5RH1iSuvZyVKYkrrjQ8Ro/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_309.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSjVzQrh6YTChF-hqzg0QedIQrgjh8A4pOvaloK7X71f34dlvNBPWWvVatN_k0Jk2Hpk97UOYbxFu9LfwRb4qiU01LZkt8rouelqgaEKnEIHFOVhkhmv8MaQ5RH1iSuvZyVKYkrrjQ8Ro/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_309.png" width="640" /></a></div>
<br />
Next we will connect to the HBase instance and run a few commands to make sure everything is working correctly.<br />
<br />
In the bin folder, enter the following command<br />
<br />
$ ./hbase shell<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-ROvYwv6X495_gAnNrTcK0ZycDBz0gFgQa58jV_Dq0V6IV0jaCrF9Q3beom2aFSkqrqNjHVuUKmmH9Z6GybIISqgNngwF52qcA3mF5NYOFSh15N-qRWt5LPfjz1oYTV3PYUcl7QfH8zY/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_310.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-ROvYwv6X495_gAnNrTcK0ZycDBz0gFgQa58jV_Dq0V6IV0jaCrF9Q3beom2aFSkqrqNjHVuUKmmH9Z6GybIISqgNngwF52qcA3mF5NYOFSh15N-qRWt5LPfjz1oYTV3PYUcl7QfH8zY/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_310.png" width="640" /></a></div>
<br />
<br />
This will connect to the HBase shell client. Enter the following commands on the hbase shell to make sure everything is working correctly.<br />
<br />
> create 'test', 'cf'<br />
> list 'test'<br />
> put 'test', 'row1', 'cf:a', 'value1'<br />
> put 'test', 'row2', 'cf:b', 'value2'<br />
> put 'test', 'row3', 'cf:c', 'value3'<br />
> scan 'test'<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi8jWBRn4Y56My1nRrT7UJnhIBwOs7GMHYLRqT8VuatBBA1EBjmHW_Km6Rt19iLZLhIr9LbH_tcDddHho7Td2SbtdSOqZd42W_sWenclKYrGtTD9b0_GlRg4SlPDHb7TJ4DMk_-948mSo/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_311.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi8jWBRn4Y56My1nRrT7UJnhIBwOs7GMHYLRqT8VuatBBA1EBjmHW_Km6Rt19iLZLhIr9LbH_tcDddHho7Td2SbtdSOqZd42W_sWenclKYrGtTD9b0_GlRg4SlPDHb7TJ4DMk_-948mSo/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_311.png" width="640" /></a></div>
<br />
Now that we have verified that everything is working, it is time to clean up and switch to the pseudo-distributed mode.<br />
<br />
Enter the following commands on the hbase shell prompt<br />
<br />
> disable 'test'<br />
> drop 'test'<br />
> quit<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqqTJAQCTqFvDiDCuTQXVFD-464BW7QJ3Mpu7AwuTpeHCtdDp4TLexkj33Ln5VzPj7RnRMG_I-SehGfqufqweSCU8ifn8wmACAIzSHAKyvj3Vvm4EQua8cNOaUU8gc4BRGXOakRz8E4Ck/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_312.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqqTJAQCTqFvDiDCuTQXVFD-464BW7QJ3Mpu7AwuTpeHCtdDp4TLexkj33Ln5VzPj7RnRMG_I-SehGfqufqweSCU8ifn8wmACAIzSHAKyvj3Vvm4EQua8cNOaUU8gc4BRGXOakRz8E4Ck/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_312.png" width="640" /></a></div>
<br />
<br />
Next step is to stop hbase<br />
<br />
$ ./stop-hbase.sh<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ578B4thHEU8tTs9Izr2dQGgtuYQ7OkSX5g1lLnPVYVk0QkrkgIY2NGjjk_nb_TYQhTTNGemkHa0rJwDdd-AK2WjEwKQF3Y_0RDrNJBHtdh_Iz-Dm57y6u6cwFga_xl82e8kv-k9VSy8/s1600/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_313.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ578B4thHEU8tTs9Izr2dQGgtuYQ7OkSX5g1lLnPVYVk0QkrkgIY2NGjjk_nb_TYQhTTNGemkHa0rJwDdd-AK2WjEwKQF3Y_0RDrNJBHtdh_Iz-Dm57y6u6cwFga_xl82e8kv-k9VSy8/s640/arthgallo%2540ub1204%253A+%257E-Work-Servers-HBase-hbase-1.1.0.1-bin_313.png" width="640" /></a></div>
<br />
Next we need to edit the hbase configuration file to run it in the pseduo distributed mode<br />
<br />
Edit the hbase conf file, and make the following entries<br />
<br />
<configuration><br />
<property><br />
<name>hbase.cluster.distributed</name><br />
<value>true</value><br />
</property><br />
<property><br />
<name>hbase.rootdir</name><br />
<value>hdfs://localhost:9000/hbase</value><br />
</property><br />
<property><br />
<name>hbase.zookeeper.property.dataDir</name><br />
<value>/usr/local/zookeeper</value><br />
</property><br />
</configuration><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTPfji28d-qIzfsMwGF4fPjFyP25D6StT7pS4i3P_icbd9Cz-TXiO93xUUnwGijAShB8WDiNEf2H3mOxOR8vVga2QtCGc44QpXiUqE4RiDzyTq-wzx-09M9B5BOlS-PCTJKT-_F8gVVwk/s1600/hbase-site.xml+%2528%257E-Work-Servers-HBase-hbase-1.1.0.1-conf%2529+-+gedit_315.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTPfji28d-qIzfsMwGF4fPjFyP25D6StT7pS4i3P_icbd9Cz-TXiO93xUUnwGijAShB8WDiNEf2H3mOxOR8vVga2QtCGc44QpXiUqE4RiDzyTq-wzx-09M9B5BOlS-PCTJKT-_F8gVVwk/s640/hbase-site.xml+%2528%257E-Work-Servers-HBase-hbase-1.1.0.1-conf%2529+-+gedit_315.png" width="640" /></a></div>
<br />
Save the file and close it.<br />
<br />
Make sure the zookeeper folder is created and the zookeeper and hbase directories are accessible to the user.<br />
<br />
$ mkdir /usr/local/zookeeper<br />
$ sudo chown -R hadoop_admin /usr/local/zookeeper<br />
$ sudo chown -R hadoop_admin /usr/local/hbase<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9Mm-8HN1BwFqe08jP0tEPmVgbu8AwmQY3f_MbfxeaPkdDvohO5XfHHWD2Z5Kbb0hmSeCaj70u_04Z08CGNrJMuQK1MEq__ZfVhz9Npq5GNM_0HxS1tgELwpwh7ybtD8zjluSwkbIR2DU/s1600/hadoop_admin%2540ub1204%253A+%257E_323.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9Mm-8HN1BwFqe08jP0tEPmVgbu8AwmQY3f_MbfxeaPkdDvohO5XfHHWD2Z5Kbb0hmSeCaj70u_04Z08CGNrJMuQK1MEq__ZfVhz9Npq5GNM_0HxS1tgELwpwh7ybtD8zjluSwkbIR2DU/s640/hadoop_admin%2540ub1204%253A+%257E_323.png" width="640" /></a></div>
<br />
<br />
Make sure HDFS (Hadoop Distributed File System) is installed and running. To check if HDFS is running enter the following command on the terminal window<br />
<br />
$ hdfs dfsadmin -report<br />
<br />
It will show a report as follows<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4P9wlalv60SEaoWJfX9UZcOLIJPqnKpgcA6Uo_Ba7tpxwQiwQyOhYltCrYL9udzjxDdI00zvygYEOAYFPTWaI0j8Q5ez9eG7lJXIcyc1h78akIQD0fWK0i3poDWLeEvjpnECe4EaDt3s/s1600/hadoop_admin%2540ub1204%253A+-usr-local-hbase-conf_319.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4P9wlalv60SEaoWJfX9UZcOLIJPqnKpgcA6Uo_Ba7tpxwQiwQyOhYltCrYL9udzjxDdI00zvygYEOAYFPTWaI0j8Q5ez9eG7lJXIcyc1h78akIQD0fWK0i3poDWLeEvjpnECe4EaDt3s/s640/hadoop_admin%2540ub1204%253A+-usr-local-hbase-conf_319.png" width="640" /></a></div>
<br />
<br />
run the command to start hbase<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLkFniP3_l-6N93wGRiOxM-4sRnLvsRNavbRp6nvhjImQqOWoO820e1AqFID0aw96qQBuOOZzRwPE7ZsIPVj5dmzyiFFQj_GPSugHC-dBwHvScju2FkSTvezPr3V7IXhOicFw-o5J-0kw/s1600/hadoop_admin%2540ub1204%253A+%257E_324.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLkFniP3_l-6N93wGRiOxM-4sRnLvsRNavbRp6nvhjImQqOWoO820e1AqFID0aw96qQBuOOZzRwPE7ZsIPVj5dmzyiFFQj_GPSugHC-dBwHvScju2FkSTvezPr3V7IXhOicFw-o5J-0kw/s640/hadoop_admin%2540ub1204%253A+%257E_324.png" width="640" /></a></div>
<br />
Once it is started, you should see the following<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTjHkC6eR2pNUIc3MINjJl5IRit0CfzSf7NCUJ2WP6kmoPQ86_5X70VZ_w_sQ5Fd7uXvXZTxjhe0iMm18tOvFjU1rSvMHQJheNf4Jeaa3KUomSwFpBZMuRa6q1B4OI7u8ahjg3YK6ITlM/s1600/hadoop_admin%2540ub1204%253A+%257E_325.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTjHkC6eR2pNUIc3MINjJl5IRit0CfzSf7NCUJ2WP6kmoPQ86_5X70VZ_w_sQ5Fd7uXvXZTxjhe0iMm18tOvFjU1rSvMHQJheNf4Jeaa3KUomSwFpBZMuRa6q1B4OI7u8ahjg3YK6ITlM/s640/hadoop_admin%2540ub1204%253A+%257E_325.png" width="640" /></a></div>
<br />
Run jps command to see the running processes<br />
<br />
$ jps<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI5dWOZp8JiRDDa_WAehhXn016kNiX4kNij1e-QOt1FZrZKX619FUpTpSt3jqCqflpE2dTnaopPq_Sa6_DVCZJjiq45o7w8OnXTgxVS21ILgIdkclBoaTIoobTXKJEV1Tdw16Iw68C_gY/s1600/hadoop_admin%2540ub1204%253A+%257E_326.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI5dWOZp8JiRDDa_WAehhXn016kNiX4kNij1e-QOt1FZrZKX619FUpTpSt3jqCqflpE2dTnaopPq_Sa6_DVCZJjiq45o7w8OnXTgxVS21ILgIdkclBoaTIoobTXKJEV1Tdw16Iw68C_gY/s640/hadoop_admin%2540ub1204%253A+%257E_326.png" width="640" /></a></div>
<br />
<br />
Next we can again open a new terminal to start hbase shell, and run the same commands again<br />
<br />
> create 'test', 'cf'<br />
> list 'test'<br />
> put 'test', 'row1', 'cf:a', 'value1'<br />
> put 'test', 'row2', 'cf:b', 'value1'<br />
> put 'test', 'row3', 'cf:c', 'value3'<br />
> scan 'test'<br />
<br />
We can see if everything executed correctly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Efoy_y0U3uP_wYOWZRwfzzrn31RDCuksrev_DKO-L7fqSyMm3NzIy2RHoTXyNtXSO3_dPBTgrkyo_5ZGywsS-Cw_eRQh0Gg509quw788BERDGOub8se5ULa89GmTVzi8w1IW2cBt72k/s1600/arthgallo%2540ub1204%253A+-usr-local-hbase-bin_327.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Efoy_y0U3uP_wYOWZRwfzzrn31RDCuksrev_DKO-L7fqSyMm3NzIy2RHoTXyNtXSO3_dPBTgrkyo_5ZGywsS-Cw_eRQh0Gg509quw788BERDGOub8se5ULa89GmTVzi8w1IW2cBt72k/s640/arthgallo%2540ub1204%253A+-usr-local-hbase-bin_327.png" width="640" /></a></div>
<br />
<br />
That's it folks hbase is set up correctly.<br />
<br />
Also, if you have set up thrift on your machine you can start the hbase thrift server with the following command<br />
<br />
$ /usr/local/hbase/bin/hbase-daemon.sh start thrift<br />
<br />
<br />awachshttp://www.blogger.com/profile/08595316907100242542noreply@blogger.com0