{"id":61,"date":"2011-11-06T12:25:10","date_gmt":"2011-11-06T18:25:10","guid":{"rendered":"http:\/\/cartometric.com\/blog\/?p=61"},"modified":"2013-02-19T10:14:38","modified_gmt":"2013-02-19T16:14:38","slug":"openscales-coordinate-transformation-from-uncommon-projections","status":"publish","type":"post","link":"https:\/\/elrobis.com\/blog\/2011\/11\/06\/openscales-coordinate-transformation-from-uncommon-projections\/","title":{"rendered":"OpenScales: Coordinate Transformation from Uncommon Projections"},"content":{"rendered":"<p>&#8212;&#8212;&#8212;&#8212;<\/p>\n<p><strong>UPDATE 2.19.2013<\/strong>:<\/p>\n<p>It turns out you don&#8217;t have to rebuild OpenScales to apply uncommon projections, you can just assign the projection directly to ProjProjection.defs. (<a href=\"https:\/\/groups.google.com\/forum\/?hl=en&amp;fromgroups=#!topic\/openscales-dev\/ePCXBmhLS-U\">See Simon L.&#8217;s answer here in the OpenScales user group<\/a>.)<\/p>\n<p>So if I modify my example toward the bottom of the post (at #5), here is how I would apply the alternate, and arguably better, approach.<\/p>\n<p>(Fair warning, I haven&#8217;t compiled this and tested it yet, the only difference is the first line), but this is how I expect it should be. If it doesn&#8217;t work like this, it&#8217;s likely &#8216;cos an instance of ProjProjection needs to be created first, and the defs property of the instance needs to be appended. In other words, if this doesn&#8217;t work, follow the line instantiating moNADProj with moNADProj.defs[&#8216;EPSG:102697&#8217;] = &#8220;+title&#8230;. blah blah&#8221;; One of these days I&#8217;ll make super-sure this is correct. But I didn&#8217;t want to forget where I found this, hence updating the post.)<\/p>\n<pre>private function transformCoordinates():void\r\n{\r\n         \/\/ This single line is the only difference:\r\n         ProjProjection.defs['EPSG:102697']=\"+title=NAD_1983_StatePlane_Missouri_Central_FIPS_2402_Feet +proj=tmerc +lat_0=35.83333333333334 +lon_0=-92.5 +k=0.9999333333333333 +x_0=500000.0000000002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs\";\r\n\r\n         \/\/ Source point's projection, called using the KEY defined above..\r\n         var moNADProj:ProjProjection = new ProjProjection(\"EPSG:102697\");\r\n\r\n         \/\/ Destination projection (WGS84), which is already available in proj4as..\r\n\t var wgs84Proj:ProjProjection = new ProjProjection(\"EPSG:4326\");\r\n\r\n         \/\/ The source point, instantiated here using its easting (value along X-axis)\r\n         \/\/ and northing (value along the Y-axis) parameters..\r\n\t var projPt:ProjPoint = new ProjPoint(easting,northing);\r\n\r\n         \/\/ The Proj4as.transform() method returns a ProjPoint object in the new\r\n         \/\/ coordinate system; in this case, longitude and latitude.\r\n\t var lonLatPt:ProjPoint = Proj4as.transform(moNADProj, wgs84Proj, projPt);\r\n}<\/pre>\n<p>&#8212;&#8212;&#8212;&#8212;<\/p>\n<p><strong>Original Post:<\/strong><\/p>\n<p><strong><\/strong>In short, I wanted to transform projected\u00a0source coordinates from <a href=\"http:\/\/www.spatialreference.org\/ref\/esri\/102697\/\" target=\"_blank\">NAD_1983_StatePlane_Missouri_Central_FIPS_2402_Feet<\/a> to geodetic coordinates in WGS84. As expected, OpenScales didn&#8217;t recognize my relatively uncommon projection, but I had high-hopes I could implement its properties piece-meal, possibly through the <a href=\"http:\/\/openscales.org\/api\/proj4as\/org\/openscales\/proj4as\/proj\/ProjParams.html\" target=\"_blank\">ProjParams<\/a> class, or\u00a0in some similar fashion.<\/p>\n<p>At first I hoped I would find a static method on <a href=\"http:\/\/openscales.org\/api\/proj4as\/org\/openscales\/proj4as\/ProjProjection.html\" target=\"_blank\">ProjProjection<\/a>\u00a0like \u00a0&#8220;ProjProjection.fromProj4Def(String:proj4Def)&#8221; which would return an instance of ProjProjection for any valid\u00a0Proj4 expression, but such a method never emerged from the fog. I did, however, manage to &#8220;appened&#8221; my rogue projection into the proj4as source code, which ultimately solved my problem &#8212;-though admittedly, I still think a method like I described above would be a nice addition. \ud83d\ude42<\/p>\n<p>So getting to the point, if you need to add an uncommon projection to your OpenScales-derived\u00a0project, here&#8217;s what you can do:<\/p>\n<p>1) Remove openscales-proj4as-1.2.1.swc from your project (alternatively, you could mod these instructions and\u00a0just recompile the swc)\u00a0and copy the proj4as source package into your own project&#8217;s src directory. In other words,\u00a0relative to your\u00a0unpacked OpenScales download, you want to copy in the part I&#8217;m emphasizing in bold and underlined:<\/p>\n<pre>C:\\..\\openscales-1.2.1\\src\\openscales-proj4as\\src\\main\\flex\\<span style=\"text-decoration: underline;\"><strong>org\\openscales\\proj4as\\proj<\/strong><\/span><strong><\/strong><\/pre>\n<div id=\"attachment_62\" style=\"width: 155px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/cartometric.com\/blog\/wp-content\/uploads\/2011\/11\/adding_proj4as_package.png\"><img aria-describedby=\"caption-attachment-62\" loading=\"lazy\" class=\"size-medium wp-image-62\" title=\"Adding the proj4as Code to your Project\" src=\"http:\/\/cartometric.com\/blog\/wp-content\/uploads\/2011\/11\/adding_proj4as_package-145x300.png\" alt=\"\" width=\"145\" height=\"300\" srcset=\"https:\/\/elrobis.com\/blog\/wp-content\/uploads\/2011\/11\/adding_proj4as_package-145x300.png 145w, https:\/\/elrobis.com\/blog\/wp-content\/uploads\/2011\/11\/adding_proj4as_package.png 220w\" sizes=\"(max-width: 145px) 100vw, 145px\" \/><\/a><p id=\"caption-attachment-62\" class=\"wp-caption-text\">Adding the proj4as Code to your Project<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>2) Now open the file ProjProjection.as and scroll down to about line 20.\u00a0You should see something\u00a0like what follows; these are\u00a0the various projections available through proj4as right out-of-the-box:<\/p>\n<pre>static public const defs:Object={\r\n\t'EPSG:900913': \"+title=Google Mercator EPSG:900913 +proj=merc +ellps=WGS84 +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs\",\r\n\t'WGS84': \"+title=long\/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees\",\r\n\t'EPSG:4326': \"+title=long\/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees\",\r\n\t'EPSG:4269': \"+title=long\/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees\",\r\n\r\n\t[.. .. expect several lines of these .. ..]<\/pre>\n<p>&nbsp;<\/p>\n<p>3) At this point, you&#8217;ll add your projection&#8217;s Proj.4 text to the mix. If you don&#8217;t know the Proj.4 expression for your projection, drop by <a href=\"http:\/\/www.spatialreference.org\/\">http:\/\/www.spatialreference.org<\/a>, look up your projection, and select the Proj4 link. Once it loads just copy the definition text to your clipboard..<\/p>\n<div id=\"attachment_81\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/cartometric.com\/blog\/wp-content\/uploads\/2011\/11\/selecting_proj4_definition1.png\"><img aria-describedby=\"caption-attachment-81\" loading=\"lazy\" class=\"size-medium wp-image-81\" title=\"Getting the Proj4 Definition Expression for a Projection\" src=\"http:\/\/cartometric.com\/blog\/wp-content\/uploads\/2011\/11\/selecting_proj4_definition1-300x223.png\" alt=\"\" width=\"300\" height=\"223\" srcset=\"https:\/\/elrobis.com\/blog\/wp-content\/uploads\/2011\/11\/selecting_proj4_definition1-300x223.png 300w, https:\/\/elrobis.com\/blog\/wp-content\/uploads\/2011\/11\/selecting_proj4_definition1.png 972w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-81\" class=\"wp-caption-text\">Getting the Proj4 Definition Expression for a Projection<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>4) Now, add your projection&#8217;s Proj.4 expression to the defs object, shown in bold, below. You will need to add the underlined part yourself, and frankly, these values are somewhat arbitrary. On the left, &#8216;EPSG:102697&#8217; becomes the KEY you&#8217;ll use\u00a0 to reference the projection later in code; and the title is even less significant. I recommend keeping your entries relatively sane. Basically, &#8220;make it look like the neighboring expressions&#8221;. Oh.. and you can put it anywhere in the list, separated by line-breaks if you prefer.\u00a0I put mind right above the OSGB36\/British National Grid entry:<\/p>\n<pre>static public const defs:Object={\r\n\t'EPSG:900913': \"+title=Google Mercator EPSG:900913 +proj=merc +ellps=WGS84 +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs\",\r\n\t'WGS84': \"+title=long\/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees\",\r\n\t'EPSG:4326': \"+title=long\/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees\",\r\n\t'EPSG:4269': \"+title=long\/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees\",\r\n\r\n\t<strong><span style=\"text-decoration: underline;\">'EPSG:102697': \"+title=NAD_1983_StatePlane_Missouri_Central_FIPS_2402_Feet<\/span> +proj=tmerc +lat_0=35.83333333333334 +lon_0=-92.5 +k=0.9999333333333333 +x_0=500000.0000000002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs\",<\/strong>\r\n\r\n\t[.. .. expect several lines of these .. ..]<\/pre>\n<p>&nbsp;<\/p>\n<p>5) That handles adding your projection to proj4as, assuming you want to consume this somewhere in your Flex\/ActionScript application, a function like this one will perform your coordinate transformation (this is just to demonstrate the\u00a0idea &#8212;-I don&#8217;t actually recommend instantiating both projections each time you want to do a conversion):<\/p>\n<pre>private function transformCoordinates():void\r\n{\r\n         \/\/ Source point's projection, called using the KEY defined above..\r\n         var moNADProj:ProjProjection = new ProjProjection(\"EPSG:102697\");\r\n\r\n         \/\/ Destination projection (WGS84), which is already available in proj4as..\r\n\tvar wgs84Proj:ProjProjection = new ProjProjection(\"EPSG:4326\");\r\n\r\n         \/\/ The source point, instantiated here using its easting (value along X-axis)\r\n         \/\/ and northing (value along the Y-axis) parameters..\r\n\tvar projPt:ProjPoint = new ProjPoint(easting,northing);\r\n\r\n         \/\/ The Proj4as.transform() method returns a ProjPoint object in the new\r\n         \/\/ coordinate system; in this case, longitude and latitude. Just to emphasize,\r\n         \/\/ longitude is returned as X (i.e. x-intercept) and latitude as Y..\r\n\tvar lonLatPt:ProjPoint = Proj4as.transform(moNADProj, wgs84Proj, projPt);\r\n}<\/pre>\n<pre><\/pre>\n<p>6) Enfin,\u00a0and mostly for the sake of proving all this worked, here&#8217;s a screenshot of the application I&#8217;m working on (an AIR app that will integrate with a USB GPS device) showing the coordinate\u00a0transformation in action.<\/p>\n<p>The map, which is in Mo State Plane Central, tracks mouse movement as easting\/northing values (bottom-center), and at the time, my mouse was hovering over Bass Pro Shops, which is a significant Springfield landmark to say the least. The proj4as-transformed coordinates are at bottom-right:<\/p>\n<div id=\"attachment_68\" style=\"width: 299px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/cartometric.com\/blog\/wp-content\/uploads\/2011\/11\/gps_app_in_action.png\"><img aria-describedby=\"caption-attachment-68\" loading=\"lazy\" class=\"size-medium wp-image-68\" title=\"proj4as Coordinate Transformation in Action\" src=\"http:\/\/cartometric.com\/blog\/wp-content\/uploads\/2011\/11\/gps_app_in_action-289x300.png\" alt=\"\" width=\"289\" height=\"300\" srcset=\"https:\/\/elrobis.com\/blog\/wp-content\/uploads\/2011\/11\/gps_app_in_action-289x300.png 289w, https:\/\/elrobis.com\/blog\/wp-content\/uploads\/2011\/11\/gps_app_in_action.png 616w\" sizes=\"(max-width: 289px) 100vw, 289px\" \/><\/a><p id=\"caption-attachment-68\" class=\"wp-caption-text\">proj4as Coordinate Transformation in Action<\/p><\/div>\n<p>If you want to scruitinize the accuracy of the coordinate transformation, here&#8217;s that location in Google Maps: <a href=\"http:\/\/maps.google.com\/?ll=37.18069720,-93.29592962\">http:\/\/maps.google.com\/?ll=37.18069720,-93.29592962<\/a><\/p>\n<p>And for the curious among you, my USB GPS device (coords at bottom-left)\u00a0is cranking out quite accurately, too.. but that&#8217;s a\u00a0 post for another day..<\/p>\n<p>Cheers, Elijah<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8212;&#8212;&#8212;&#8212; UPDATE 2.19.2013: It turns out you don&#8217;t have to rebuild OpenScales to apply uncommon projections, you can just assign the projection directly to ProjProjection.defs. (See Simon L.&#8217;s answer here in the OpenScales user group.) So if I modify my example toward the bottom of the post (at #5), here is how I would apply [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[41],"tags":[12,6,11,10],"_links":{"self":[{"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/posts\/61"}],"collection":[{"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":35,"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/posts\/61\/revisions"}],"predecessor-version":[{"id":174,"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/posts\/61\/revisions\/174"}],"wp:attachment":[{"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/media?parent=61"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/categories?post=61"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/elrobis.com\/blog\/wp-json\/wp\/v2\/tags?post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}