rotate and scale polygon geometry using Transform functions

Hey Benny,

See my response to your question in the previous thread. Hopefully that provides some background, but let me know if you’re still confused.

Thanks,

Gabby

Thank you so much Gabby for sharing the link, very intuitive and helpful. I will thoroughly investigate it in the coming few days.

Based on my understanding, there should be following steps ( please correct me if I am wrong):

1 .before applying the transform matrix, the polygon coordinates should be converted to a local reference frame (using the polygon’s centroid as the origin point),

  1. then do the matrix transformation (rotate, scale, translate) computation for each vertex of the polygon.

  2. after this step, the new polygon should be properly placed in the local reference frame,

  3. then we can translate it back to the cartesian frame (whose origin is defined as the center of earth globe )

  4. and eventually convert the coordinates as lat and lon in degrees.

Once I figure it out successfully, I will post my code here.

Cheers,

Benny

Yes, those steps should get you there, looking forward to your example!

Hi community,

I finally got a solution for rotating polygons properly. Thanks for Gabby’s hint!

The biggest catch is that Cartersian3 can NOT be used as a local reference frame for this sort of transformation, it yields distortions after the transform.

My solution is to convert WGS84 coordinates into a UTM coordinate reference system (CRS) first, then make a local reference frame with the origin sets as the polygon centroid (described in UTM). then apply the rotation transform for each vertex of the polygon and eventually reproject the coordinates back to WGS84 from UTM.

The well-known “proj4js” library is used for projection between WGS84 and UTM, and I also wrote a “geoUtils” helper function to do the trivial wrapups. Both are attached. Hope it saves some hairs of others :sunglasses:

Here is the result:

Here is the code for your reference.

// ===== start ================= copy and paste into Sandcastle

var viewer = new Cesium.Viewer(‘cesiumContainer’);

// degree to rotate about z-axis

var rotate_dg = 30;

// (1) define a matrix for rotation around z-axis: ref: http://web.cs.iastate.edu/~cs577/handouts/homogeneous-transform.pdf, section5

var sin = Math.sin(Cesium.Math.toRadians(rotate_dg));

var cos = Math.cos(Cesium.Math.toRadians(rotate_dg));

var rotation = new Cesium.Matrix4(

cos, -sin, 0, 0,

sin, cos, 0, 0,

0, 0, 1, 0,

0, 0, 0, 1

);

// coordinates of polygon geometry

var coords_wgs84 = [146.2, -37.1 , 146.8, -37.1, 146.8, -36.9, 146.2, -36.9];

// use geoUtils and proj4js libraries to project coordinates from WGS84 to UTM:

// (2)find a proper utm zone epsgcode based on the centroid of polygon

// epsgcode_utm = geoUtils.getUTMEPSGCode((coords_wgs84[0]+coords_wgs84[2])/2,(coords_wgs84[1]+coords_wgs84[3])/2);

// (3)project wgs84 to utm

// coords = geoUtils.projtransform_WGS84toUTM_pointarr(epsgcode_utm, coords_wgs84);

// (4)then use the projected utm coords for transform

var coords = [428911.83623035066, 5893734.833993502, 482228.10792489944, 5894015.500401434, 482181.4995000003, 5916202.188331464, 428725.38633551006, 5915922.086273929];

// get the ploygon center coordinate (utm: x, y)

var center_lon = (coords[0]+coords[2])/2;

var center_lat = (coords[3]+coords[5])/2;

var center = new Cesium.Cartesian3(center_lon,center_lat, 0);

var entities = viewer.entities;

// add the polygon without any rotation

entities.add({

polygon: {

hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(coords_wgs84)),

material: Cesium.Color.GREEN.withAlpha(0.5),

height:0,

outline : true

}

});

// (5)compute the coordinates of each vertex of the rotated polygon

var p1 = new Cesium.Cartesian3(coords[0],coords[1],0);

Cesium.Cartesian3.subtract(p1,center,p1);

Cesium.Matrix4.multiplyByPointAsVector(rotation,p1,p1);

Cesium.Cartesian3.add(p1,center,p1);

var p2 = new Cesium.Cartesian3(coords[2],coords[3],0);

Cesium.Cartesian3.subtract(p2,center,p2);

Cesium.Matrix4.multiplyByPointAsVector(rotation,p2,p2);

Cesium.Cartesian3.add(p2,center,p2);

var p3 = new Cesium.Cartesian3(coords[4],coords[5],0);

Cesium.Cartesian3.subtract(p3,center,p3);

Cesium.Matrix4.multiplyByPointAsVector(rotation,p3,p3);

Cesium.Cartesian3.add(p3,center,p3);

var p4 = new Cesium.Cartesian3(coords[6],coords[7],0);

Cesium.Cartesian3.subtract(p4,center,p4);

Cesium.Matrix4.multiplyByPointAsVector(rotation,p4,p4);

Cesium.Cartesian3.add(p4,center,p4);

//console.log([p1.x, p1.y,p2.x, p2.y,p3.x, p3.y,p4.x, p4.y]);

// (6) project from utm back to WGS84

//coords_wgs84_rotated = geoUtils.projtransform_UTMtoWGS84_pointarr(epsgcode_utm, [p1.x, p1.y,p2.x, p2.y,p3.x, p3.y,p4.x, p4.y]);

//30degree: [146.3032086500734, -37.20706399236928, 146.8225388113473, -36.96648537107382, 146.69814514730672, -36.79323616430305, 146.17824506887973, -37.03390193698665]

var coords_wgs84_rotated = [146.3032086500734, -37.20706399236928, 146.8225388113473, -36.96648537107382, 146.69814514730672, -36.79323616430305, 146.17824506887973, -37.03390193698665];

// add the rotated polygon

entities.add({

polygon: {

hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(coords_wgs84_rotated)),

material: Cesium.Color.RED,

height:0,

outline : true

}

});

viewer.zoomTo(viewer.entities);

// ===== end ================= copy and paste into Sandcastle

It seems js files cannot be accepted as attachments, I paste it here:

proj4js can be found here: http://download.osgeo.org/proj4js/proj4js-1.1.0.zip.

//================geoUtils.js start ===========================

//utm defs:

// utm N hemisphere

Proj4js.defs[“EPSG:32601”] = “+proj=utm +zone=1 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32602”] = “+proj=utm +zone=2 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32603”] = “+proj=utm +zone=3 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32604”] = “+proj=utm +zone=4 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32605”] = “+proj=utm +zone=5 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32606”] = “+proj=utm +zone=6 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32607”] = “+proj=utm +zone=7 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32608”] = “+proj=utm +zone=8 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32609”] = “+proj=utm +zone=9 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32610”] = “+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32611”] = “+proj=utm +zone=11 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32612”] = “+proj=utm +zone=12 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32613”] = “+proj=utm +zone=13 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32614”] = “+proj=utm +zone=14 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32615”] = “+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32616”] = “+proj=utm +zone=16 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32617”] = “+proj=utm +zone=17 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32618”] = “+proj=utm +zone=18 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32619”] = “+proj=utm +zone=19 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32620”] = “+proj=utm +zone=20 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32621”] = “+proj=utm +zone=21 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32622”] = “+proj=utm +zone=22 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32623”] = “+proj=utm +zone=23 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32624”] = “+proj=utm +zone=24 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32625”] = “+proj=utm +zone=25 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32626”] = “+proj=utm +zone=26 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32627”] = “+proj=utm +zone=27 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32628”] = “+proj=utm +zone=28 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32629”] = “+proj=utm +zone=29 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32630”] = “+proj=utm +zone=30 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32631”] = “+proj=utm +zone=31 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32632”] = “+proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32633”] = “+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32634”] = “+proj=utm +zone=34 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32635”] = “+proj=utm +zone=35 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32636”] = “+proj=utm +zone=36 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32637”] = “+proj=utm +zone=37 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32638”] = “+proj=utm +zone=38 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32639”] = “+proj=utm +zone=39 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32640”] = “+proj=utm +zone=40 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32641”] = “+proj=utm +zone=41 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32642”] = “+proj=utm +zone=42 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32643”] = “+proj=utm +zone=43 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32644”] = “+proj=utm +zone=44 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32645”] = “+proj=utm +zone=45 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32646”] = “+proj=utm +zone=46 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32647”] = “+proj=utm +zone=47 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32648”] = “+proj=utm +zone=48 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32649”] = “+proj=utm +zone=49 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32650”] = “+proj=utm +zone=50 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32651”] = “+proj=utm +zone=51 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32652”] = “+proj=utm +zone=52 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32653”] = “+proj=utm +zone=53 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32654”] = “+proj=utm +zone=54 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32655”] = “+proj=utm +zone=55 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32656”] = “+proj=utm +zone=56 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32657”] = “+proj=utm +zone=57 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32658”] = “+proj=utm +zone=58 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32659”] = “+proj=utm +zone=59 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32660”] = “+proj=utm +zone=60 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

//utm S hemisphere

Proj4js.defs[“EPSG:32701”] = “+proj=utm +zone=1 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32702”] = “+proj=utm +zone=2 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32703”] = “+proj=utm +zone=3 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32704”] = “+proj=utm +zone=4 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32705”] = “+proj=utm +zone=5 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32706”] = “+proj=utm +zone=6 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32707”] = “+proj=utm +zone=7 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32708”] = “+proj=utm +zone=8 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32709”] = “+proj=utm +zone=9 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32710”] = “+proj=utm +zone=10 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32711”] = “+proj=utm +zone=11 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32712”] = “+proj=utm +zone=12 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32713”] = “+proj=utm +zone=13 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32714”] = “+proj=utm +zone=14 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32715”] = “+proj=utm +zone=15 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32716”] = “+proj=utm +zone=16 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32717”] = “+proj=utm +zone=17 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32718”] = “+proj=utm +zone=18 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32719”] = “+proj=utm +zone=19 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32720”] = “+proj=utm +zone=20 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32721”] = “+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32722”] = “+proj=utm +zone=22 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32723”] = “+proj=utm +zone=23 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32724”] = “+proj=utm +zone=24 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32725”] = “+proj=utm +zone=25 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32726”] = “+proj=utm +zone=26 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32727”] = “+proj=utm +zone=27 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32728”] = “+proj=utm +zone=28 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32729”] = “+proj=utm +zone=29 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32730”] = “+proj=utm +zone=30 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32731”] = “+proj=utm +zone=31 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32732”] = “+proj=utm +zone=32 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32733”] = “+proj=utm +zone=33 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32734”] = “+proj=utm +zone=34 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32735”] = “+proj=utm +zone=35 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32736”] = “+proj=utm +zone=36 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32737”] = “+proj=utm +zone=37 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32738”] = “+proj=utm +zone=38 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32739”] = “+proj=utm +zone=39 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32740”] = “+proj=utm +zone=40 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32741”] = “+proj=utm +zone=41 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32742”] = “+proj=utm +zone=42 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32743”] = “+proj=utm +zone=43 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32744”] = “+proj=utm +zone=44 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32745”] = “+proj=utm +zone=45 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32746”] = “+proj=utm +zone=46 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32747”] = “+proj=utm +zone=47 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32748”] = “+proj=utm +zone=48 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32749”] = “+proj=utm +zone=49 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32750”] = “+proj=utm +zone=50 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32751”] = “+proj=utm +zone=51 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32752”] = “+proj=utm +zone=52 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32753”] = “+proj=utm +zone=53 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32754”] = “+proj=utm +zone=54 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32755”] = “+proj=utm +zone=55 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32756”] = “+proj=utm +zone=56 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32757”] = “+proj=utm +zone=57 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32758”] = “+proj=utm +zone=58 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32759”] = “+proj=utm +zone=59 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Proj4js.defs[“EPSG:32760”] = “+proj=utm +zone=60 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

var geoUtils = {

//sample usage: geoUtils.getUTMEPSGCode(147,-38);

getUTMEPSGCode : function(lon, lat){

var zonecode = (Math.floor((lon + 180)/6) % 60) + 1;

if(zonecode <10) zonecode = ‘0’+zonecode;

var EPSGCode = ‘EPSG:32’;

if(lat>0){

EPSGCode = EPSGCode+‘6’+zonecode;

}else{

EPSGCode = EPSGCode+‘7’+zonecode;

}

return EPSGCode;

},

//sample usage: geoUtils.projtransform_WGS84toUTM(geoUtils.getUTMEPSGCode(147,-38),“147,-38”);

projtransform_WGS84toUTM : function(projstrUTM, xy)

{

var pt = new Proj4js.Point(xy);

var srcpj = new Proj4js.Proj(“EPSG:4326”);

var tarpj = new Proj4js.Proj(projstrUTM);

var newpt = Proj4js.transform(srcpj, tarpj, pt);

return newpt.toShortString();

},

//sample usage: projtransform_WGS84toUTM_pointarr(“EPSG:32755”,[146.2, -37.1 , 146.8, -37.1, 146.8, -36.9, 146.2, -36.9])

projtransform_WGS84toUTM_pointarr: function(projstrUTM, pointarr)

{

//pointarr format: [lon1,lat1,lon2,lat2…]

var out = ;

var srcpj = new Proj4js.Proj(“EPSG:4326”);

var tarpj = new Proj4js.Proj(projstrUTM);

for(var i=0; i < pointarr.length; i++){

var pt = new Proj4js.Point(pointarr[i]+ “,” + pointarr[i+1]);

var xy_proj = Proj4js.transform(srcpj, tarpj, pt).toShortString();

i = i + 1;

var pt = xy_proj.split(",");

out.push(parseFloat(pt[0], 10));

out.push(parseFloat(pt[1], 10));

}

return out;

},

//sample usage: projtransform_UTMtoWGS84_pointarr(“EPSG:32755”,[428911.83623035066, 5893734.833993502, 482228.10792489944, 5894015.500401434, 482181.4995000003, 5916202.188331464, 428725.38633551006, 5915922.086273929])

projtransform_UTMtoWGS84_pointarr: function(projstrUTM, pointarr)

{

//pointarr format: [x0,y0,x1,y1,x2,y2…]

var out = ;

var srcpj = new Proj4js.Proj(projstrUTM);

var tarpj = new Proj4js.Proj(“EPSG:4326”);

for(var i=0; i < pointarr.length; i++){

var pt = new Proj4js.Point(pointarr[i]+ “,” + pointarr[i+1]);

var xy_proj = Proj4js.transform(srcpj, tarpj, pt).toShortString();

i = i + 1;

var pt = xy_proj.split(",");

out.push(parseFloat(pt[0], 10));

out.push(parseFloat(pt[1], 10));

}

return out;

}

};

//================== geoUtils.js end =========================