A Free and Open Source Library to convert between Lat/Lon and SVY21.
C# Java Ruby C++ Go JavaScript Other
Switch branches/tags
Nothing to show
Latest commit 4926dd1 Aug 17, 2017 @jonongjs jonongjs Merge pull request #6 from yi-jiayu/go
Ported to Go
Failed to load latest commit information.
C++ Added C++ test cases. Oct 25, 2014
Go Ported to Go Nov 15, 2016
Javascript Ported to Javascript Feb 26, 2013
Ruby Conforming to gem naming convention. (http://blog.segment7.net/2010/1… Apr 8, 2013
csharp Port SVY21 conversion. Mar 17, 2013
.gitignore Update .gitignore for Visual Studio files. Mar 15, 2013
.gitmodules Added gtest module Oct 25, 2014



A Free and Open Source Library to convert between Lat/Lon, and SVY21.

##Usage## ###Ruby### The Ruby version is packaged as a gem.

To install

gem "svy21", "~> 1.0.1"


require 'svy21'

# 570 Ang Mo Kio Avenue 10
# lat/lon
lat_lon = SVY21.svy21_to_lat_lon(39105.269, 30629.967)
puts "latitude: #{lat_long[0]}"
puts "longitude: #{lat_long[1]}"

# svy21
northing_easting = SVY21.lat_lon_to_svy21(1.3699278977737488, 103.85695034976467)
puts "northing: #{northing_easting[0]}"
puts "easting: #{northing_easting[1]}"

###Python### The Python script is a ready-to-use converter. Run with python -i SVY21.py.

# Initialization
>>> cv = SVY21()

# Computing SVY21 from Lat/Lon
>>> (lat, lon) = (1.2949192688485278, 103.77367436885834)
>>> (N, E) = cv.computeSVY21(lat, lon)
>>> (N, E)
(30811.26429645264, 21362.157043860374)

# Computing Lat/Lon from SVY21
>>> (lat, lon) = cv.computeLatLon(N, E)
>>> (lat, lon)
(1.2949192688483109, 103.77367436887495)

###Java### The package net.qxcg.svy21 contains all necessary files.

The static class SVY21 performs actual conversions. The classes SVY21Coordinate and LatLonCoordinate are immutable types that store SVY21 and Latitude/Longitude respectively. Conversions using SVY21 return new copies of either coordinate type.

// Required files are in this package.
import net.qxcg.svy21.*;

// Creating a latlon Coordinate.
LatLonCoordinate coord1 = new LatLonCoordinate(1.2949192688485278, 103.77367436885834);

// Conversion using coordinate method.
SVY21Coordinate result = coord1.asSVY21();

// Conversion using library.
result = SVY21.computeSVY21(coord1);

// It is also possible perform conversion directly using two plain 'double' types.
double lat = coord1.getLatitude();
double lon = coord1.getLongitude();
result = SVY21.computeSVY21(lat, lon);

// The reverse conversion also can be done using all three methods.
LatLonCoordinate reverseResult = result.asLatLon();

reverseResult = SVY21.computeLatLon(result);

double northing = result.getNorthing();
double easting = result.getEasting();
reverseResult = SVY21.computeLatLon(northing, easting);


// Initialization
var cv = new SVY21();

// Computing SVY21 from Lat/Lon
var lat = 1.2949192688485278;
var lon = 103.77367436885834;
var result = cv.computeSVY21(lat, lon);

// Computing Lat/Lon from SVY21
var resultLatLon = cv.computeLatLon(result.N, result.E);

###C# ### The C# implementation was ported from the Java implementation, and includes the same tests (executable in Visual Studio.) Unlike the Java implementation, however, LatLongCoordinate and Svy21Coordinate are mutable.

The included solution can be built to produce a class library (SVY21.dll) which can be included in any project. Alternatively, the three classes (LatLongCoordinate, Svy21Coordinate, and Svy21) can be included directly.

// Creating a Lat/Long Coordinate.
LatLongCoordinate latLong = new LatLongCoordinate(1.2949192688485278, 103.77367436885834);

// "Ask" the object to convert itself.
Svy21Coordinate converted = latLong.ToSvy21Coordinate();

// Conversion using library.
converted = Svy21.ComputeSvy21(latLong);

// Conversion can also be done directly using two doubles.
double latitude = latLong.Latitude;
double longitude = latLong.Longitude;
converted = Svy21.ComputeSvy21(latitude, longitude);

// Conversion from SVY21 to Latitude/Longitude can also be done using all three methods.
LatLongCoordinate reverse = converted.ToLatLongCoordinate();
reverse = Svy21.ComputeLatitudeLongitude(converted);

double northing = converted.Northing;
double easting = converted.Easting;
reverse = Svy21.ComputeLatitudeLongitude(northing, easting);

##C++## // Initialization SVY21 svy21;

// Computing SVY21 from Lat/Lon
double lat = 1.2949192688485278;
double lon = 103.77367436885834;
double northing, easting;
svy21.latLonToSVY21(lat, lon, &northing, &easting);
printf("%lf %lf\n", northing, easting);

// Computing Lat/Lon from SVY21
svy21.SVY21ToLatLon(northing, easting, &lat, &lon);
printf("%lf %lf\n", lat, lon);

##Testing## The "Protected Areas And Protected Places Act" found here lists some SVY21 points that correspond to vertices of hard-to-miss plots of land in Singapore.

You can try converting some of the Northing, Easting coordinates to Latitude and Longitude, and viewing the plot of land on Google Maps to verify their accuracy.

###Precision### Like all floating-point computations, converting back and forth between Lat/Lon and SVY21 will cause the loss of precision.

In the Python example above, note that the input Lat/Lon and output Lat/Lon are very slightly different. Repeating the process a few more times will compound this difference.

The useful precision of the output also depends on the precision of the inputs.

##Known Issues##

  1. Setting the origin's latitude and longitude, represented by oLat and oLon respectively, to the official SVY21 datum specified here results in computation being a bit off (when compared to a Google Maps satellite image) for the above sample points. However, the rounded values of (1.366666, 103.833333) give accurate results.

##Mathematics## This library makes use of the equations in the following page:
Transverse Mercator Transformation Formulae

##Other Languages## Feel free to port the code to other languages, and submit a pull request if you do!

##Future Direction##

  1. Code quality. This library was developed during a Hackathon, and needs to be brought up to production standard.
  2. Automated and/or more comprehensive tests.

##Acknowledgements## Isaac Low
Jonathan Ong
Chua Wei Kuan

If you used this library in your project and found it useful, let us know!

Created during Hack & Roll '13 by NUS Hackers