Monday, March 16, 2015

Optical Illusions Why The Notion of Overnight Success is a Lie


Overview :



“Timing, perseverance, and ten years of trying will eventually make you look like an overnight success.” -Biz Stone, Co-founder of Twitter

5 years, 3 months.

That’s how long it takes Chinese Bamboo to grow to maturity. At its peak, this tree will stretch above the canopy, reaching heights of 80 feet or more. But for the first 1,825 days of its life, it appears to be nothing more than a stubby green shoot protruding from the soil.


That’s because the real growth is happening underground. For 60 months, that green shoot is fighting in an invisible battle, struggling day and night to establish a network of roots strong enough to support what will be a full-fledged tree. Once the root system is stable, the shoot grows rapidly in just 90 days to reach its full potential.


It would be foolish to assume that this bamboo tree matured overnight, when in truth, it is the culmination of over 5 years of struggle. And it is equally foolish to assume that any business or product can be successful without doing the same.


Yet people do just that. In my 20+ years of experience in the software industry, I’ve mentored countless young people. Whether they’re seeking advice on development, design, or entrepreneurship in general, I most commonly find myself having to dispel one misconception in particular: the notion of overnight success.


If there’s one thing nature teaches us, it is this: There is absolutely, unequivocally, no such thing as overnight success.


There may be the appearance of instant success, but that is illusory. True success is always the result of preparation and diligence.


In an age where videos and Tweets can go “viral” overnight, it’s no surprise that instant success seems to be a real phenomenon to many. But what many fail to consider are the months, years, or even decades of toil that made that moment possible.


We must look below the surface, beyond what things seem to be, to see the struggle, the sacrifice, and the failures that made that moment possible.


The universe demands that we all pay our dues. Nothing is for free– least of all success.



Naga is a Chairman & Director at Span Technology Services

Read More »

Monday, February 2, 2015

How To Use UIPageControl with UIScrollView in iOS


Overview :

A UIPageControl presents that set of horizontal dots representing pages. The current page representing the white dots (default color for dots). We can go to the next page or to the previous page.


Steps :
  1. Open Xcode 6.
  2. Create new project.
  3. Select: iOS ⇒ Application ⇒ Single View Application.
  4. Give the project name as PageControl, iPhone as target device and click Finish.
  5. Here, I have Customized the UIPageControl and UIScrollView with UIImageView.
  6. First we add UIScrollView delegate in .h file and declare PageControl, ScrollView and ImageView .h file.
  7. Import the FXPageControl.h and FXPageControl.m class file to the project from
    https://github.com/nicklockwood/FXPageControl
  8. Here, we add Class File for Page Control to give image for the indicator and set space and size for the indicator (dot size and dot space).


  9. In ViewDidLoad Method


- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
images=[[NSArray alloc]initWithObjects:@"image1.png", @"image2.png", @"image3.png", @"image4.png", nil];
///UIScrollView
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 467)];
scrollView.backgroundColor = [UIColor clearColor];
scrollView.delegate = self;
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;
[scrollView setContentSize:CGSizeMake(scrollView.frame.size.width*images.count, scrollView.frame.size.height)];
/// PageControl
pageControl = [[FXPageControl alloc]init ];
[pageControl setFrame:CGRectMake(110, 540, 100, 36)];
pageControl.defersCurrentPageDisplay = NO;
pageControl.selectedDotColor = [UIColor redColor];
pageControl.backgroundColor = [UIColor clearColor];
pageControl.selectedDotSize = 15.0;
pageControl.dotSize = 11.0;
pageControl.dotColor = [UIColor blueColor];
pageControl.dotSpacing = 10.0;
pageControl.wrapEnabled = YES;
pageControl.selectedDotImage = [UIImage imageNamed:@"selectedslider.png"];
pageControl.dotImage = [UIImage imageNamed:@"unselectedslider.png"];
[pageControl addTarget:self action:@selector(pageChanged) forControlEvents:UIControlEventValueChanged];
UIImageView *dottedImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 434, 320, 27)];
[dottedImage setImage:[UIImage imageNamed:@"dottedline.png"]];
for (int i = 0; i <[images count]; i++)
{
CGRect frame;
frame.origin.x = scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = [UIImage imageNamed:[images objectAtIndex:i]];
imageView.frame = frame;
[scrollView addSubview:imageView];
}
pageControl.numberOfPages = images.count;
pageControl.currentPage = 0;
[self.view addSubview:scrollView];
[self.view addSubview:pageControl];
}
10.This Method to change the Page
- (void)pageChanged
{
// pageControl.currentPage=PageIndicator.currentPage;
CGRect frame;
frame.origin.x = scrollView.frame.size.width * pageControl.currentPage;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
[scrollView scrollRectToVisible:frame animated:NO];
}
11.We implement the ScrollView Delegate Method.
- (void)scrollViewDidScroll:(UIScrollView *)_scrollView
{
CGFloat viewWidth = scrollView.frame.size.width;
// content offset - tells by how much the scroll view has scrolled.
int pageNumber = floor((scrollView.contentOffset.x - viewWidth/50) / viewWidth) +1;
pageControl.currentPage = pageNumber;
}



Screenshot :









Udayapandi Mariappan is a Junior Software Engineer at Span Technology Services

Read More »

Wednesday, January 28, 2015

jQuery UI Datepicker Customization


Overview :

The jQuery UI Datepicker is a highly configurable plugin that adds datepicker functionality to our web pages. As we all know, we can customize the style, date format and language, restrict the selectable date ranges and add in buttons and other navigation options easily.

We came across a scenario where we needed the order of the years in the datepicker needs to be descending.

Example :

For a datepicker of the DOB its better if we have the year starting from current year and end in the least value we declare during initialization. i.e. from 2015 to 1955. Where as the original datepicker will have the years staring from the least value we assign i.e. from 1955 to 2015.

This change can be done by making a slight alteration in the base jquery UI script file. The changes are as follows.

There will be a section to generate the month and year header for the datepicker, a function named ‘_generateMonthYearHeader’:


Step 1 :

Find the ‘year selection’ section in that method





Step 2 :

Here the year list generated to display will initially be sorted ascending by default. We are now going to re-sort in descending order.





Step 3 :

We have added a new ‘for’ loop before the list is being created. Here, if the ‘reverseYearRange’ variable is ‘true’ the list will be sorted in descending order and ‘false’ gets a list in ascending i.e. the default order.


Step 4 :

Usage: The reverseYearRange variable should be assigned true where the datepicker is initialized for a textbox.





Note: The above change is made in jquery.ui version 1.8.24. The code snippet we discussed may have to be changed accordingly in the previous or newer versions.


Meyyappan M is a Junior Software Engineer at Span Technology Services

Read More »

Tuesday, January 27, 2015

Google Maps Android Marker Clustering


Overview

By clustering your markers, you can put a large number of markers on a map without making the map hard to read. The marker clustering utility helps you manage multiple markers at different zoom levels. To be precise, the 'markers' are actually 'items' at this point, and only become 'Markers' when they're rendered. But for the sake of clarity, this document will name them 'markers' throughout. When a user views the map at a high zoom level, the individual markers show on the map. When the user zooms out, the markers gather together into clusters, to make viewing the map easier. The marker clustering utility is part of the Google Maps Android API Utility Library. If you haven't yet set up the library, follow the setup guide before reading the rest of this page.

Step1:

In Eclipse goto File ⇒ New ⇒ Android Application Project

Step2:Downloading Google Maps Android API Utility Library.

https://developers.google.com/maps/documentation/android/utility/

Step3: Add a simple marker clusterer.

Here is a summary of the steps required:

  1. Implement ClusterItem to represent a marker on the map. The cluster item returns the position of the marker as a LatLng object.
  2. Add a new ClusterManager to group the cluster items (markers) based on zoom level.
  3. Set the map's OnCameraChangeListener() to the ClusterManager, since ClusterManager implements the listener.
  4. If you want to add specific functionality in response to a marker click event, set the map's OnMarkerClickListener() to the ClusterManager, since ClusterManager implements the listener.
  5. Feed the markers into the ClusterManager.

MyItem.java



package com.example.clustering;
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterItem;
public class MyItem implements ClusterItem {
private final LatLng mPosition;
public MyItem(double lat, double lng) {
mPosition = new LatLng(lat, lng);
}
@Override
public LatLng getPosition() {
return mPosition;
}
}


MyItemReader.java



package com.example.clustering;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class MyItemReader {
private static final String REGEX_INPUT_BOUNDARY_BEGINNING = "\\A";
public List read(InputStream inputStream) throws JSONException {

List items = new ArrayList();
String json = new Scanner(inputStream).useDelimiter(REGEX_INPUT_BOUNDARY_BEGINNING).next();
JSONArray array = new JSONArray(json);
for (int i = 0; i < array.length(); i++) {

JSONObject object = array.getJSONObject(i);
double lat = object.getDouble("lat");
double lng = object.getDouble("lng");
items.add(new MyItem(lat, lng));
}
return items;

}
}


Step4:

MainActivity.java


package com.example.clustering;
import java.io.InputStream;
import java.util.List;
import org.json.JSONException;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import com.example.googlemapclustering.R;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterManager;
public class MainActivity extends Activity {
GoogleMap map;
private ClusterManager mClusterManager;
@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMyLocationEnabled(true);
map.getUiSettings().setZoomGesturesEnabled(true);
map.moveCamera(CameraUpdateFactory.zoomTo(13.2f));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10));
mClusterManager = new ClusterManager(this, map);
mClusterManager = new ClusterManager(MainActivity.this, map);
map.setOnCameraChangeListener(mClusterManager);
map.setOnInfoWindowClickListener(mClusterManager);
map.setInfoWindowAdapter(mClusterManager.getMarkerManager());
map.setOnMarkerClickListener(mClusterManager);
try {

readItems();
} catch (JSONException e) {
Toast.makeText(this, "Problem reading list of markers.", Toast.LENGTH_LONG).show();
}
}
private void readItems() throws JSONException {
InputStream inputStream = getResources().openRawResource(R.raw.radar_search);
List items = new MyItemReader().read(inputStream);
mClusterManager.addItems(items);
}
}



Step5:

activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout >



Step6:


res -> raw ->radar_search.json
Sample lat,lng
[
{ "lat" : 51.5145160, "lng" : -0.1270060 },
{ "lat" : 51.5064490, "lng" : -0.1244260 },
{ "lat" : 51.5097080, "lng" : -0.1200450 },
{ "lat" : 51.5090680, "lng" : -0.1421420 },
{ "lat" : 51.4976080, "lng" : -0.1456320 },
{ "lat" : 51.5046150, "lng" : -0.1473780 },
]


Step7:

AndroidManifest.xml


Declare google play service in manifest.xml


<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />

<meta¬data
android:name="com.google.android.maps.v2.API_KEY"
android:value="API Key" />

Map permission


<permission
android:name="com.google.maps.android.utils.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />

uses permission:


<uses-permission android:name="com.google.maps.android.utils.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />




Screenshot:




Devarajan M is a Software Engineer at Span Technology Services

Read More »

Monday, January 19, 2015

How To Efficiently Display Annotation Pins on the Same Coordinate on iOS Maps


Overview :

This tutorial will demonstrate how to handle and display Same Coordinate of points of data on an iOS map in a way people understand and enjoy. We are going to make an iOS app which Shopping Center with 100 km areas, each with a coordinate, a name and a phone number and Profile Image. This app will update the map as the user pans and zooms, allowing the user to freely explore the data.


Framework : MKMapKit

Steps :
  1. Open Xcode 6.
  2. Create new project.
  3. Select: iOS, Application, Single View Application.
  4. Give the project a proper name. In the example, I’ve used the following:
    • Product Name: MapAnnotationCircle
    • Organization Name: XXXX
    • Class Prefix: XXX
  5. To keep stuff simple, I’ve selected iPad as target device.
    • Click Next.
  6. Now in project navigator you will find “Main.Storyboard”.
  7. Drag and drop MKMapView and add MKMapKit framework.
  8. Just Control-drag your map to the MapViewController.h file and create an IBOutlet. Let’s name our outlet iMapView.
  9. Import in your header file.
  10. First we group the annotations by coordinate.


for (int i=0; [latitude_MutableArray count]>i; i++)
{
NSString *latStr=[latitude_MutableArray objectAtIndex:i];
NSString *longStr=[longtitude_MutableArray objectAtIndex:i];
double lat=[latStr doubleValue];
double lan=[longStr doubleValue];
customAnnotation = [[BasicMapAnnotation alloc] initWithLatitude:lat andLongitude:lan];
customAnnotation.title =[centerName_MutableArray objectAtIndex:i];
[pinPointAnnotations addObject:customAnnotation];
}
[AnnotationCoordinateUtility mutateCoordinatesOfClashingAnnotations:pinPointAnnotations];
[self.iMapView addAnnotations:pinPointAnnotations];


11. The value of a entry in the dictionary is a NSArray of annotations at that coordinate. You can see this only matches on exactly equal coordinates, but it would be relatively straightforward to group on coordinates that were close by calculating the distance between them. Next we enumerate the NSArray looking for locations that have more than one annotation. When we find one, we reposition the annotations.


+ (void)mutateCoordinatesOfClashingAnnotations:(NSArray *)annotations {
NSDictionary *coordinateValuesToAnnotations = [self groupAnnotationsByLocationValue:annotations]; for (NSValue *coordinateValue in coordinateValuesToAnnotations.allKeys) {
NSMutableArray *outletsAtLocation = coordinateValuesToAnnotations[coordinateValue];
if (outletsAtLocation.count > 1) {
CLLocationCoordinate2D coordinate;
[coordinateValue getValue:&coordinate];
[self repositionAnnotations:outletsAtLocation toAvoidClashAtCoordination:coordinate];
}
}
}
+ (NSDictionary *)groupAnnotationsByLocationValue:(NSArray *)annotations {
NSMutableDictionary *result = [NSMutableDictionary dictionary];
for (id pin in annotations) {
CLLocationCoordinate2D coordinate = pin.coordinate;
NSValue *coordinateValue = [NSValue valueWithBytes:&coordinate objCType:@encode(CLLocationCoordinate2D)];
NSMutableArray *annotationsAtLocation = result[coordinateValue];
if (!annotationsAtLocation) {
annotationsAtLocation = [NSMutableArray array];
result[coordinateValue] = annotationsAtLocation;
}
[annotationsAtLocation addObject:pin];
}
return result;
}
+ (void)repositionAnnotations:(NSMutableArray *)annotations toAvoidClashAtCoordination:(CLLocationCoordinate2D)coordinate {
double distance = 3 * annotations.count / 2.0;
double radiansBetweenAnnotations = (M_PI * 2) / annotations.count;
for (int i = 0; i < annotations.count; i++) {
double heading = radiansBetweenAnnotations * i;
CLLocationCoordinate2D newCoordinate = [self calculateCoordinateFrom:coordinate onBearing:heading atDistance:distance];
id annotation = annotations[i];
annotation.coordinate = newCoordinate;
}
}


12. The pins are arranged in a circle around the contested point by dividing the circle by the number of contesting annotations. You can see that the distance from the contested coordinate to the new coordinate is a function of the number of annotations contesting – if there are few pins contesting the coordinate, then we have space to place the pins close to the coordinate.

Finally, the new coordinate is calculated using an implementation of the function from this excellent resource: Destination point given distance and bearing from start point


+ (CLLocationCoordinate2D)calculateCoordinateFrom:(CLLocationCoordinate2D)coordinate onBearing:(double)bearingInRadians atDistance:(double)distanceInMetres {
double coordinateLatitudeInRadians = coordinate.latitude * M_PI / 180;
double coordinateLongitudeInRadians = coordinate.longitude * M_PI / 180;
double distanceComparedToEarth = distanceInMetres / 6378100;
double resultLatitudeInRadians = asin(sin(coordinateLatitudeInRadians) * cos(distanceComparedToEarth) + cos(coordinateLatitudeInRadians) * sin(distanceComparedToEarth) *
cos(bearingInRadians));
double resultLongitudeInRadians = coordinateLongitudeInRadians + atan2(sin(bearingInRadians) * sin(distanceComparedToEarth) * cos(coordinateLatitudeInRadians),
cos(distanceComparedToEarth) - sin(coordinateLatitudeInRadians) * sin(resultLatitudeInRadians));
CLLocationCoordinate2D result;
result.latitude = resultLatitudeInRadians * 180 / M_PI;
result.longitude = resultLongitudeInRadians * 180 / M_PI;
return result;
}

Output :

1. Pins with inside the rectangle





2. After Zooming





Bharathimohan K is a Software Engineer at Span Technology Services

Read More »