<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Mrclay's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 17 May 2008 13:38:18 GMT</pubDate>
    <description>DZone Snippets: Mrclay's Code Snippets</description>
    <item>
      <title>GPS distance and initial bearing between points (MySQL)</title>
      <link>http://snippets.dzone.com/posts/show/4991</link>
      <description>Assume you have a table of locations with Latitude and Longitude for each one. In my case the table is "station" and the primary key is "LocID".&lt;br /&gt;&lt;br /&gt;First we create a view to help with the 3D geometry (6378 = Earth's radius in km):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;CREATE VIEW gpsGlb AS&lt;br /&gt;    SELECT &lt;br /&gt;        LocID&lt;br /&gt;        ,6378 * COS(RADIANS(Latitude)) * COS(RADIANS(Longitude)) AS x&lt;br /&gt;        ,6378 * COS(RADIANS(Latitude)) * SIN(RADIANS(Longitude)) AS y&lt;br /&gt;        ,6378 * SIN(RADIANS(Latitude)) AS z&lt;br /&gt;    FROM station;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here I query for distances to all my locations that are NOT LocID = 405 (rounded miles in my case):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;SELECT &lt;br /&gt;    LocID&lt;br /&gt;    ,ROUND((2 * 6378 * ASIN(d / 2 / 6378)) * 0.621371192) AS dist_mi&lt;br /&gt;FROM&lt;br /&gt;    (SELECT&lt;br /&gt;        SQRT(dx * dx + dy * dy + dz * dz) AS d&lt;br /&gt;        ,LocID&lt;br /&gt;     FROM&lt;br /&gt;        (SELECT&lt;br /&gt;            p1.x - p2.x AS dx&lt;br /&gt;            ,p1.y - p2.y AS dy&lt;br /&gt;            ,p1.z - p2.z AS dz&lt;br /&gt;            ,p2.LocID&lt;br /&gt;        FROM gpsGlb p1&lt;br /&gt;        JOIN gpsGlb p2 ON (p1.LocID = 405 AND p2.LocID != 405)&lt;br /&gt;       ) t1&lt;br /&gt;    ) t2&lt;br /&gt;ORDER BY dist_mi&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here I get the initial bearing to the locations. The "boxed" calculation will come in handy later.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;SELECT&lt;br /&gt;    LocID&lt;br /&gt;    ,(360 + DEGREES(ATAN2(y, x))) % 360 AS initBearing_deg&lt;br /&gt;    ,ROUND(((360 + DEGREES(ATAN2(y, x))) % 360) / 22.5) * 22.5 &lt;br /&gt;     AS initBearingBoxed_deg&lt;br /&gt;FROM&lt;br /&gt;    (SELECT&lt;br /&gt;        SIN(RADIANS(s2.Longitude - s1.Longitude)) * COS(RADIANS(s2.Latitude)) &lt;br /&gt;        AS y&lt;br /&gt;        ,COS(RADIANS(s1.Latitude)) * SIN(RADIANS(s2.Latitude))&lt;br /&gt;            - SIN(RADIANS(s1.Latitude)) * COS(RADIANS(s2.Latitude))&lt;br /&gt;               * COS(RADIANS(s2.Longitude - s1.Longitude)) &lt;br /&gt;        AS x&lt;br /&gt;        ,s2.LocID&lt;br /&gt;    FROM station s1&lt;br /&gt;    JOIN station s2 ON (s1.LocID = 405 AND s2.LocID != 405)&lt;br /&gt;    ) q1&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here's the combined query plus boxed degrees converted to 'NNE', etc. I've also added a limit for the distance in the qq1 subquery.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;SELECT&lt;br /&gt;    qq2.LocID&lt;br /&gt;    ,dist_mi&lt;br /&gt;    ,CASE initBearingBoxed_deg&lt;br /&gt;        WHEN 22.5 THEN 'NNE'   WHEN 45 THEN 'NE'&lt;br /&gt;        WHEN 67.5 THEN 'ENE'   WHEN 90 THEN 'E'&lt;br /&gt;        WHEN 112.5 THEN 'ESE'  WHEN 135 THEN 'SE'&lt;br /&gt;        WHEN 157.5 THEN 'SSE'  WHEN 180 THEN 'S'&lt;br /&gt;        WHEN 202.5 THEN 'SSW'  WHEN 225 THEN 'SW'&lt;br /&gt;        WHEN 247.5 THEN 'WSW'  WHEN 270 THEN 'W'&lt;br /&gt;        WHEN 292.5 THEN 'WNW'  WHEN 315 THEN 'NW'&lt;br /&gt;        WHEN 337.5 THEN 'NNW'  ELSE 'N'&lt;br /&gt;     END AS bearing&lt;br /&gt;FROM (&lt;br /&gt;    SELECT &lt;br /&gt;        LocID&lt;br /&gt;        ,ROUND((2 * 6378 * ASIN(d / 2 / 6378)) * 0.621371192) AS dist_mi&lt;br /&gt;    FROM&lt;br /&gt;        (SELECT&lt;br /&gt;            SQRT(dx * dx + dy * dy + dz * dz) AS d&lt;br /&gt;            ,LocID&lt;br /&gt;         FROM&lt;br /&gt;            (SELECT&lt;br /&gt;                p1.x - p2.x AS dx&lt;br /&gt;                ,p1.y - p2.y AS dy&lt;br /&gt;                ,p1.z - p2.z AS dz&lt;br /&gt;                ,p2.LocID&lt;br /&gt;            FROM gpsGlb p1&lt;br /&gt;            JOIN gpsGlb p2 ON (p1.LocID = 405 AND p2.LocID != 405)&lt;br /&gt;           ) t1&lt;br /&gt;        ) t2&lt;br /&gt;    ) qq1&lt;br /&gt;JOIN (&lt;br /&gt;    SELECT&lt;br /&gt;        LocID&lt;br /&gt;        ,(360 + DEGREES(ATAN2(y, x))) % 360 AS initBearing_deg&lt;br /&gt;        ,(360 + ROUND((DEGREES(ATAN2(y, x))) / 22.5) * 22.5) % 360 &lt;br /&gt;         AS initBearingBoxed_deg&lt;br /&gt;    FROM&lt;br /&gt;        (SELECT&lt;br /&gt;            SIN(RADIANS(s2.Longitude - s1.Longitude)) * COS(RADIANS(s2.Latitude)) &lt;br /&gt;             AS y&lt;br /&gt;            ,COS(RADIANS(s1.Latitude)) * SIN(RADIANS(s2.Latitude))&lt;br /&gt;                - SIN(RADIANS(s1.Latitude)) * COS(RADIANS(s2.Latitude))&lt;br /&gt;                   * COS(RADIANS(s2.Longitude - s1.Longitude)) &lt;br /&gt;             AS x&lt;br /&gt;            ,s2.LocID&lt;br /&gt;        FROM station s1&lt;br /&gt;        JOIN station s2 ON (s1.LocID = 405 AND s2.LocID != 405)&lt;br /&gt;        ) q1&lt;br /&gt;    ) qq2 ON (qq1.LocID = qq2.LocID&lt;br /&gt;              AND qq1.dist_mi &lt;= 60)&lt;br /&gt;ORDER BY dist_mi&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 16 Jan 2008 21:14:20 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4991</guid>
      <author>mrclay (Steve Clay)</author>
    </item>
    <item>
      <title>Detect Daylight Saving Time on a MySQL server in the America/New_York timezone.</title>
      <link>http://snippets.dzone.com/posts/show/4986</link>
      <description>&lt;code&gt;&lt;br /&gt;SELECT -5 - CAST(REPLACE(TIMEDIFF(NOW(), UTC_TIMESTAMP()), ':00:00', '') AS SIGNED) AS isDst&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;To test in other timezones, replace -5 with your local standard time GMT offset.</description>
      <pubDate>Tue, 15 Jan 2008 19:21:42 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4986</guid>
      <author>mrclay (Steve Clay)</author>
    </item>
    <item>
      <title>RecordSet to tab-separated values</title>
      <link>http://snippets.dzone.com/posts/show/3644</link>
      <description>&lt;code&gt;&lt;br /&gt;Function TSV(rs)&lt;br /&gt;	Dim field&lt;br /&gt;	For Each field In rs.Fields&lt;br /&gt;		TSV = TSV &amp; field.Name &amp; VBTab&lt;br /&gt;	Next&lt;br /&gt;	TSV = Left(TSV, Len(TSV) - 1) &amp; vbCr &amp; rs.GetString()&lt;br /&gt;End Function&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The rows are separated by vbCr ("\r" in most languages).&lt;br /&gt;The first row is the field names.</description>
      <pubDate>Wed, 07 Mar 2007 21:51:49 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3644</guid>
      <author>mrclay (Steve Clay)</author>
    </item>
    <item>
      <title>Unix time</title>
      <link>http://snippets.dzone.com/posts/show/3643</link>
      <description>&lt;code&gt;&lt;br /&gt;Function UnixTime(gmtHrsOffset)&lt;br /&gt;	UnixTime = DateDiff("s", "1/1/1970 00:00:00", Now()) - (3600 * gmtHrsOffset)&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Repsonse.Write(UnixTime(-5)) 'E.S.T.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Adding in the GMT offset allowed this to match PHP's time() function on a separate server.</description>
      <pubDate>Wed, 07 Mar 2007 21:43:08 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3643</guid>
      <author>mrclay (Steve Clay)</author>
    </item>
    <item>
      <title>Style a collection of elements quickly</title>
      <link>http://snippets.dzone.com/posts/show/1774</link>
      <description>Quickly set multiple style properties to single elements or arrays/nodeLists of elements.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function setStyles(el, css) {&lt;br /&gt;	var l = el.length;&lt;br /&gt;	if (typeof l == 'undefined') {el = [el]; l = 1;}&lt;br /&gt;	for (var i=0; i&lt;l; i++) {&lt;br /&gt;		for (var s in css) el[i].style[s] = css[s];&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Usage:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;window.onload = function() {&lt;br /&gt;	// single element&lt;br /&gt;	setStyles(document.body, {background:'yellow'});&lt;br /&gt;	// nodeList&lt;br /&gt;	setStyles(document.getElementsByTagName('div'), {&lt;br /&gt;		background: '#def',&lt;br /&gt;		color: 'red'&lt;br /&gt;	});&lt;br /&gt;	// array&lt;br /&gt;	var a = [document.body, document.getElementsByTagName('div')[0]];&lt;br /&gt;	setStyles(a, {border: '1px black dotted'});&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 26 Mar 2006 07:24:30 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1774</guid>
      <author>mrclay (Steve Clay)</author>
    </item>
    <item>
      <title>Empty a DOM node</title>
      <link>http://snippets.dzone.com/posts/show/1757</link>
      <description>&lt;code&gt;&lt;br /&gt;while (node.hasChildNodes()) {node.removeChild(node.firstChild);}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 24 Mar 2006 21:09:53 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1757</guid>
      <author>mrclay (Steve Clay)</author>
    </item>
    <item>
      <title>Faster looping over DOMCollections</title>
      <link>http://snippets.dzone.com/posts/show/1756</link>
      <description>&lt;code&gt;&lt;br /&gt;var i=0, el;&lt;br /&gt;while (el = document.getElementsByTagName('div').item(i++)) {&lt;br /&gt;    // use el here&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Calling document.getElementsByTagName('div').item() directly saves the browser from having to return a whole DOMCollection. Using the while loop prevents the browser from ever having to calculate a DOMCollection's length, and gives us a syntactically nicer reference to the current node.&lt;br /&gt;&lt;br /&gt;Source: David "liorean" Andersson. Here's an e-mail excerpt:&lt;br /&gt;&lt;br /&gt;&gt; DOM implementations are optimised for single element access, and DOMCollections &lt;b&gt;[like document.getElementsByTagName()]&lt;/b&gt; are particularly badly optimised since they are dynamic, which means they need to be either polled at regular intervals, event controlled or recollected at each access. So, instead of caching the DOMCollection, you can make the script never have to create a DOMCollection at all. A perfomance win that will be considerable, and that can actually be felt if you're doing DHTML. ... &lt;b&gt;[calling item() directly, the browser]&lt;/b&gt; never has to create a dynamic collection, it just searches for the element with the given order, and discards the created list. Browsers do optimise for accessing collection members this way.</description>
      <pubDate>Fri, 24 Mar 2006 20:59:35 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1756</guid>
      <author>mrclay (Steve Clay)</author>
    </item>
  </channel>
</rss>
